@@ -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 = / ^ < ( c a r d - c o m p o n e n t ) ( [ \s \S ] * ?) (?: > ( [ \s \S ] * ?) < \/ c a r d - c o m p o n e n t > | \s * \/ ) > / i;
1512
1613const customBlockTokenizer = {
1714 name : 'custom-block-tag' ,
@@ -35,23 +32,35 @@ const customBlockTokenizer = {
3532marked . use ( { extensions : [ customBlockTokenizer ] } ) ;
3633
3734/**
38- * mdText를 웹 컴포넌트 태그(<box-component>, <button-component>) 기준으로 분할하여
39- * 마크다운은 파싱하고, 웹 컴포넌트는 그대로 삽입하는 함수
35+ * 커스텀 파서: <div ...>...</div> 블록을 마크다운 파싱 없이 그대로 삽입
36+ * 나머지 마크다운만 기존 파서로 처리
4037 */
4138export async function renderMarkdownWithComponents (
4239 mdText : string ,
4340 contentElement : HTMLElement
4441) {
45- const tokens = mdText
46- . split ( / ( < \/ ? c a r d - c o m p o n e n t [ ^ > ] * > | < \/ ? b u t t o n - c o m p o n e n t [ ^ > ] * > ) / gi)
47- . filter ( Boolean ) ;
42+ // <div ...>...</div> 블록 추출 (빈 줄 포함, 중첩 X)
43+ const divBlockRegex = / ( < d i v [ \s \S ] * ? > [ \s \S ] * ? < \/ d i v > ) / gi;
44+ const tokens = mdText . split ( divBlockRegex ) . filter ( Boolean ) ;
4845
4946 for ( const token of tokens ) {
50- if ( / ^ < \/ ? ( c a r d - c o m p o n e n t | b u t t o n - c o m p o n e n t ) [ ^ > ] * > $ / . test ( token ) ) {
47+ if ( / ^ < d i v [ \s \S ] * ?> [ \s \S ] * ?< \/ d i v > $ / . 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 ( / ( < c a r d - c o m p o n e n t [ \s \S ] * ?< \/ c a r d - c o m p o n e n t > | < c a r d - c o m p o n e n t [ \s \S ] * ?\/ > | < b u t t o n - c o m p o n e n t [ \s \S ] * ?< \/ b u t t o n - c o m p o n e n t > | < b u t t o n - c o m p o n e n t [ \s \S ] * ?\/ > ) / gi)
54+ . filter ( Boolean ) ;
55+ for ( const innerToken of innerTokens ) {
56+ if ( / ^ < \/ ? ( c a r d - c o m p o n e n t | b u t t o n - c o m p o n e n t ) [ ^ > ] * ?> .* ?< \/ ( c a r d - c o m p o n e n t | b u t t o n - c o m p o n e n t ) > $ / . test ( innerToken ) ||
57+ / ^ < ( c a r d - c o m p o n e n t | b u t t o n - c o m p o n e n t ) [ ^ > ] * ?\/ > $ / . 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}
0 commit comments