Skip to content

Commit f452562

Browse files
committed
ui : card-component,whats-next,get-docker
1 parent 2f2c2cf commit f452562

2 files changed

Lines changed: 24 additions & 15 deletions

File tree

src/scripts/load_md.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ marked.setOptions({
66
breaks: true,
77
});
88

9-
//card-component를 블록 태그로 처리하는 커스텀 토크나이저 추가
10-
const blockTagNames = ['card-component'];
11-
const blockTagRegex = new RegExp(
12-
`^<(${blockTagNames.join('|')})([\\s\\S]*?)>([\\s\\S]*?)<\\/\\1>`,
13-
'i'
14-
);
9+
// card-component를 블록 태그 및 셀프 클로징 태그로 처리하는 커스텀 토크나이저 추가
10+
// 템플릿 리터럴에서 역참조(\1) 사용 불가하므로 정규식 리터럴로 하드코딩
11+
const blockTagRegex = /^<(card-component)([\s\S]*?)(?:>([\s\S]*?)<\/card-component>|\s*\/)>/i;
1512

1613
const customBlockTokenizer = {
1714
name: 'custom-block-tag',
@@ -35,23 +32,35 @@ const customBlockTokenizer = {
3532
marked.use({ extensions: [customBlockTokenizer] });
3633

3734
/**
38-
* mdText를 웹 컴포넌트 태그(<box-component>, <button-component>) 기준으로 분할하여
39-
* 마크다운은 파싱하고, 웹 컴포넌트는 그대로 삽입하는 함수
35+
* 커스텀 파서: <div ...>...</div> 블록을 마크다운 파싱 없이 그대로 삽입
36+
* 나머지 마크다운만 기존 파서로 처리
4037
*/
4138
export async function renderMarkdownWithComponents(
4239
mdText: string,
4340
contentElement: HTMLElement
4441
) {
45-
const tokens = mdText
46-
.split(/(<\/?card-component[^>]*>|<\/?button-component[^>]*>)/gi)
47-
.filter(Boolean);
42+
// <div ...>...</div> 블록 추출 (빈 줄 포함, 중첩 X)
43+
const divBlockRegex = /(<div[\s\S]*?>[\s\S]*?<\/div>)/gi;
44+
const tokens = mdText.split(divBlockRegex).filter(Boolean);
4845

4946
for (const token of tokens) {
50-
if (/^<\/?(card-component|button-component)[^>]*>$/.test(token)) {
47+
if (/^<div[\s\S]*?>[\s\S]*?<\/div>$/.test(token)) {
48+
// div 블록은 그대로 삽입
5149
contentElement.innerHTML += token;
5250
} else if (token.trim()) {
53-
const html = await marked.parse(token);
54-
contentElement.innerHTML += html;
51+
// 나머지는 기존 방식대로 웹 컴포넌트 분리 후 마크다운 파싱
52+
const innerTokens = token
53+
.split(/(<card-component[\s\S]*?<\/card-component>|<card-component[\s\S]*?\/>|<button-component[\s\S]*?<\/button-component>|<button-component[\s\S]*?\/>)/gi)
54+
.filter(Boolean);
55+
for (const innerToken of innerTokens) {
56+
if (/^<\/?(card-component|button-component)[^>]*?>.*?<\/(card-component|button-component)>$/.test(innerToken) ||
57+
/^<(card-component|button-component)[^>]*?\/>$/.test(innerToken)) {
58+
contentElement.innerHTML += innerToken;
59+
} else if (innerToken.trim()) {
60+
const html = await marked.parse(innerToken);
61+
contentElement.innerHTML += html;
62+
}
63+
}
5564
}
5665
}
5766
}

src/styles/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
/* 카드 컴포넌트 스타일 */
2828
@layer components {
2929
.card {
30-
@apply min-w-0 bg-white rounded-md border border-gray-200 px-4 py-3 mb-4 transition duration-200 hover:border-gray-300 hover:shadow;
30+
@apply min-w-0 bg-white rounded-md border border-gray-200 px-4 py-3 mb-4 transition duration-200 hover:border-gray-300 hover:shadow h-full flex flex-col;
3131
}
3232

3333

0 commit comments

Comments
 (0)