@@ -87,58 +87,65 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
8787
8888 // Fix malformed HTML entities early in the process
8989 let preprocessedMarkdown = markdownWithSubstitutedCodeFences ;
90- preprocessedMarkdown = preprocessedMarkdown . replace ( / & n b s p ( [ ^ ; ] ) / g, ' $1' ) . replace ( / & a m p ; n b s p ; / g, ' ' ) ;
90+ preprocessedMarkdown = preprocessedMarkdown
91+ . replace ( / & n b s p ( [ ^ ; ] ) / g, ' $1' )
92+ . replace ( / & a m p ; n b s p ; / g, ' ' ) ;
9193 preprocessedMarkdown = preprocessedMarkdown . replace ( / & n b s p (? ! [ ; ] ) / g, ' ' ) ;
9294
9395 // Process content in segments to ensure markdown parsing continues after HTML blocks
94- const htmlBlockRegex = / ( < (?: d e t a i l s | d i v | s e c t i o n | a r t i c l e ) [ ^ > ] * > [ \s \S ] * ?< \/ (?: d e t a i l s | d i v | s e c t i o n | a r t i c l e ) > ) / g;
95-
96+ const htmlBlockRegex =
97+ / ( < (?: d e t a i l s | d i v | s e c t i o n | a r t i c l e ) [ ^ > ] * > [ \s \S ] * ?< \/ (?: d e t a i l s | d i v | s e c t i o n | a r t i c l e ) > ) / g;
98+
9699 let parsedMarkdown = '' ;
97-
100+
98101 // Check if there are any HTML blocks
99102 if ( htmlBlockRegex . test ( preprocessedMarkdown ) ) {
100103 // Reset regex for actual processing
101104 htmlBlockRegex . lastIndex = 0 ;
102-
105+
103106 let lastIndex = 0 ;
104107 let match ;
105-
108+
106109 while ( ( match = htmlBlockRegex . exec ( preprocessedMarkdown ) ) !== null ) {
107110 // Process markdown before the HTML block
108111 const markdownBefore = preprocessedMarkdown . slice ( lastIndex , match . index ) . trim ( ) ;
109112 if ( markdownBefore ) {
110113 const parsed = await marked . parse ( markdownBefore ) ;
111114 parsedMarkdown += parsed ;
112115 }
113-
116+
114117 // Process the HTML block: parse markdown content inside while preserving HTML structure
115118 let htmlBlock = match [ 1 ] ;
116-
119+
117120 // Find and process markdown content inside HTML tags
118121 const contentRegex = / > ( \s * [ \s \S ] * ?) \s * < / g;
119122 const contentMatches = [ ] ;
120123 let contentMatch ;
121-
122- while ( ( contentMatch = contentRegex . exec ( htmlBlock ) ) !== null ) {
123- const content = contentMatch [ 1 ] ;
124- // Only process content that has markdown formatting but no extension syntax
125- if ( content . trim ( ) && ! content . includes ( '{{' ) && ( content . includes ( '**' ) || content . includes ( '- ' ) || content . includes ( '\n' ) ) ) {
126- // This looks like markdown content without extensions - parse it as block content
127- const parsedContent = await marked . parse ( content . trim ( ) ) ;
128- // Remove wrapping <p> tags if they exist since we're inside HTML already
129- const cleanedContent = parsedContent . replace ( / ^ < p [ ^ > ] * > ( [ \s \S ] * ) < \/ p > [ \s ] * $ / g, '$1' ) ;
130- contentMatches . push ( {
131- original : contentMatch [ 0 ] ,
132- replacement : `>${ cleanedContent } <`
133- } ) ;
134- }
135- }
136-
124+
125+ while ( ( contentMatch = contentRegex . exec ( htmlBlock ) ) !== null ) {
126+ const content = contentMatch [ 1 ] ;
127+ // Only process content that has markdown formatting but no extension syntax
128+ if (
129+ content . trim ( ) &&
130+ ! content . includes ( '{{' ) &&
131+ ( content . includes ( '**' ) || content . includes ( '- ' ) || content . includes ( '\n' ) )
132+ ) {
133+ // This looks like markdown content without extensions - parse it as block content
134+ const parsedContent = await marked . parse ( content . trim ( ) ) ;
135+ // Remove wrapping <p> tags if they exist since we're inside HTML already
136+ const cleanedContent = parsedContent . replace ( / ^ < p [ ^ > ] * > ( [ \s \S ] * ) < \/ p > [ \s ] * $ / g, '$1' ) ;
137+ contentMatches . push ( {
138+ original : contentMatch [ 0 ] ,
139+ replacement : `>${ cleanedContent } <` ,
140+ } ) ;
141+ }
142+ }
143+
137144 // Apply the content replacements
138145 contentMatches . forEach ( ( { original, replacement } ) => {
139146 htmlBlock = htmlBlock . replace ( original , replacement ) ;
140147 } ) ;
141-
148+
142149 // Apply extensions (like admonitions) to the processed HTML block
143150 if ( extensions ) {
144151 extensions . forEach ( ( { regex, replace } ) => {
@@ -147,11 +154,11 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
147154 }
148155 } ) ;
149156 }
150-
157+
151158 parsedMarkdown += htmlBlock ;
152159 lastIndex = htmlBlockRegex . lastIndex ;
153160 }
154-
161+
155162 // Process any remaining markdown after the last HTML block
156163 const markdownAfter = preprocessedMarkdown . slice ( lastIndex ) . trim ( ) ;
157164 if ( markdownAfter ) {
@@ -169,16 +176,16 @@ export const markdownConvert = async (markdown: string, extensions?: ShowdownExt
169176 // Convert code spans back to md format before we run the custom extension regexes
170177 md = md . replace ( / < c o d e > ( .* ) < \/ c o d e > / g, '`$1`' ) ;
171178
172- extensions . forEach ( ( { regex, replace } , index ) => {
179+ extensions . forEach ( ( { regex, replace } , _index ) => {
173180 if ( regex ) {
174181 md = md . replace ( regex , replace ) ;
175182 }
176183 } ) ;
177184
178185 // Convert any remaining backticks back into code spans
179186 md = md . replace ( / ` ( .* ) ` / g, '<code>$1</code>' ) ;
180- }
181-
187+ }
188+
182189 return DOMPurify . sanitize ( md ) ;
183190} ;
184191
@@ -287,7 +294,10 @@ const InlineMarkdownView: FC<InnerSyncMarkdownProps> = ({
287294 const id = useMemo ( ( ) => uniqueId ( 'markdown' ) , [ ] ) ;
288295 return (
289296 < div className = { css ( { 'is-empty' : isEmpty } as any , className ) } id = { id } >
290- < div style = { { marginBlockEnd : 'var(--pf-t-global--spacer--md)' } } dangerouslySetInnerHTML = { { __html : markup } } />
297+ < div
298+ style = { { marginBlockEnd : 'var(--pf-t-global--spacer--md)' } }
299+ dangerouslySetInnerHTML = { { __html : markup } }
300+ />
291301 { renderExtension && (
292302 < RenderExtension renderExtension = { renderExtension } selector = { `#${ id } ` } markup = { markup } />
293303 ) }
@@ -376,6 +386,7 @@ const IFrameMarkdownView: FC<InnerSyncMarkdownProps> = ({
376386 return (
377387 < >
378388 < iframe
389+ title = "Markdown content preview"
379390 sandbox = "allow-popups allow-popups-to-escape-sandbox allow-same-origin"
380391 srcDoc = { contents }
381392 style = { { border : '0px' , display : 'block' , width : '100%' , height : '0' } }
0 commit comments