Skip to content

Commit

Permalink
[Fix] 마크다운에서 code block에 line break가 적용되지 않는다
Browse files Browse the repository at this point in the history
  • Loading branch information
junhyeok-clap committed Dec 21, 2024
1 parent 5af61b3 commit d1c6632
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"css.customData": [".vscode/tailwind.json"]
}
55 changes: 55 additions & 0 deletions .vscode/tailwind.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"version": 1.1,
"atDirectives": [
{
"name": "@tailwind",
"description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
"references": [
{
"name": "Tailwind Documentation",
"url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
}
]
},
{
"name": "@apply",
"description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
"references": [
{
"name": "Tailwind Documentation",
"url": "https://tailwindcss.com/docs/functions-and-directives#apply"
}
]
},
{
"name": "@responsive",
"description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n",
"references": [
{
"name": "Tailwind Documentation",
"url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
}
]
},
{
"name": "@screen",
"description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n",
"references": [
{
"name": "Tailwind Documentation",
"url": "https://tailwindcss.com/docs/functions-and-directives#screen"
}
]
},
{
"name": "@variants",
"description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n",
"references": [
{
"name": "Tailwind Documentation",
"url": "https://tailwindcss.com/docs/functions-and-directives#variants"
}
]
}
]
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"classnames": "^2.5.1",
"date-fns": "^3.6.0",
"gray-matter": "^4.0.3",
"highlight.js": "^11.11.0",
"marked": "^15.0.4",
"marked-highlight": "^2.2.1",
"next": "15.0.2",
"react": "19.0.0-rc-02c0e824-20241028",
"react-dom": "19.0.0-rc-02c0e824-20241028",
Expand Down
23 changes: 20 additions & 3 deletions src/app/posts/[slug]/_components/post-body/PostBody.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import markdownStyles from "./markdown-styles.module.css";
import { Marked } from "marked";
import { markedHighlight } from "marked-highlight";
import hljs from "highlight.js";

import "./index.css";

type Props = {
content: string;
};

const marked = new Marked(
markedHighlight({
emptyLangClass: "hljs",
langPrefix: "hljs language-",
highlight(code, lang) {
const language = hljs.getLanguage(lang) ? lang : "plaintext";
return hljs.highlight(code, { language }).value;
},
})
);

export function PostBody({ content }: Props) {
return (
<div className="max-w-2xl mx-auto">
<div
className={markdownStyles["markdown"]}
dangerouslySetInnerHTML={{ __html: content }}
className="post-content"
dangerouslySetInnerHTML={{
__html: marked.parse(content),
}}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,72 +1,68 @@
.markdown {
.post-content {
@apply text-lg leading-relaxed w-full text-content;
}

.markdown ul,
.markdown ol,
.markdown p {
.post-content ul,
.post-content ol,
.post-content p {
@apply my-6;
}

.markdown pre {
.post-content pre {
@apply bg-gray-100 text-gray-800 p-4 rounded-lg my-4;
}
.markdown pre > code {
@apply text-gray-800;
.post-content pre code {
@apply text-gray-800 overflow-auto w-full inline-block;
}

.markdown code {
.post-content code {
@apply bg-gray-100 text-success rounded-md text-sm leading-6 p-1;
}

.markdown h2 {
.post-content h2 {
@apply text-3xl mt-12 mb-4 leading-snug font-bold;
}

.markdown h3 {
.post-content h3 {
@apply text-2xl mt-8 mb-4 leading-snug font-bold;
}

.markdown img {
.post-content img {
@apply rounded-md shadow-sm mx-auto my-7;
}

.markdown figure {
.post-content figure {
@apply text-center my-8;
}

.markdown figcaption {
.post-content figcaption {
@apply text-sm text-gray-600 mt-2;
}

.markdown a {
.post-content a {
@apply text-blue-600 underline;
}

.markdown a:hover {
.post-content a:hover {
@apply text-blue-800 underline;
}

.markdown ul {
.post-content ul {
@apply pl-6 list-disc;
}

.markdown ol {
.post-content ol {
@apply pl-6 list-decimal;
}

.markdown li {
.post-content li {
@apply mb-2;
}

.markdown blockquote {
.post-content blockquote {
@apply bg-gray-50 border-l-4 border-success text-gray-700 pl-6 py-4 my-4 text-base;
}

.markdown blockquote > p {
.post-content blockquote p {
@apply p-0 m-0;
}

.markdown pre > code {
white-space: normal;
}
5 changes: 1 addition & 4 deletions src/app/posts/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { notFound } from "next/navigation";
import { getPostBySlug } from "@/lib/api";
import markdownToHtml from "@/lib/markdownToHtml";
import Container from "@/components/container";
import Header from "@/components/header";

Expand All @@ -22,16 +21,14 @@ export default async function Post(props: Params) {
return notFound();
}

const content = await markdownToHtml(post.content || "");

return (
<main>
<PostAlert slug={params.slug} />
<Container>
<Header />
<article className="mb-32">
<PostHeader {...post} />
<PostBody content={content} />
<PostBody content={post.content} />
</article>
</Container>
</main>
Expand Down
7 changes: 0 additions & 7 deletions src/lib/markdownToHtml.ts

This file was deleted.

15 changes: 15 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,11 @@ hast-util-whitespace@^3.0.0:
dependencies:
"@types/hast" "^3.0.0"

highlight.js@^11.11.0:
version "11.11.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.11.0.tgz#91b15082ca8cdbe22424e0a000449d7d8a5c74c6"
integrity sha512-6ErL7JlGu2CNFHyRQEuDogOyGPNiqcuWdt4iSSFUPyferNTGlNTPFqeV36Y/XwA4V/TJ8l0sxp6FTnxud/mf8g==

html-void-elements@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7"
Expand Down Expand Up @@ -866,6 +871,16 @@ lru-cache@^10.2.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==

marked-highlight@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/marked-highlight/-/marked-highlight-2.2.1.tgz#33b7fcac24088c0e0213229b7d01044a2974670d"
integrity sha512-SiCIeEiQbs9TxGwle9/OwbOejHCZsohQRaNTY2u8euEXYt2rYUFoiImUirThU3Gd/o6Q1gHGtH9qloHlbJpNIA==

marked@^15.0.4:
version "15.0.4"
resolved "https://registry.yarnpkg.com/marked/-/marked-15.0.4.tgz#864dbf50227b6507646c771c2ef5f0de2924833e"
integrity sha512-TCHvDqmb3ZJ4PWG7VEGVgtefA5/euFmsIhxtD0XsBxI39gUSKL81mIRFdt0AiNQozUahd4ke98ZdirExd/vSEw==

mdast-util-from-markdown@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a"
Expand Down

0 comments on commit d1c6632

Please sign in to comment.