@@ -37,6 +37,57 @@ export function createStyleSheet(path, { media, base = hljsURL } = {}) {
3737 return link ;
3838}
3939
40+ export function parse ( input , {
41+ gfm = true ,
42+ breaks = false ,
43+ silent = false ,
44+ langPrefix = 'hljs language-' ,
45+ fallbackLang = 'plaintext' ,
46+ addHeadingIDs = true ,
47+ idPrefix = null ,
48+ allowElements,
49+ allowAttributes,
50+ allowCustomElements,
51+ allowUnknownMarkup,
52+ allowComments,
53+ } = { } ) {
54+ const marked = new Marked (
55+ markedHighlight ( {
56+ langPrefix,
57+ highlight ( code , lang ) {
58+ const language = hljs . getLanguage ( lang ) ? lang : fallbackLang ;
59+ return hljs . highlight ( code , { language } ) . value ;
60+ }
61+ } )
62+ ) ;
63+
64+ const frag = document . createDocumentFragment ( ) ;
65+ let raw = input . replaceAll ( / \\ ` / g, '`' ) ;
66+
67+ if ( String . dedent instanceof Function && raw . startsWith ( '\n' ) && / \n \t * $ / . test ( raw ) ) {
68+ const tmp = [ raw ] ;
69+ tmp . raw = [ raw ] ;
70+ Object . freeze ( tmp ) ;
71+ raw = String . dedent ( tmp ) ;
72+ }
73+
74+ const parsed = marked . parse ( raw , { gfm, breaks, silent } ) ;
75+ const doc = Document . parseHTML ( parsed , {
76+ allowElements, allowAttributes, allowCustomElements, allowUnknownMarkup,
77+ allowComments,
78+ } ) ;
79+
80+ frag . append ( ...doc . body . childNodes ) ;
81+
82+ if ( addHeadingIDs ) {
83+ frag . querySelectorAll ( 'h1, h2, h3, h4, h5, h6' ) . forEach ( heading => {
84+ heading . id = typeof idPrefix === 'string' ? `${ idPrefix } -${ sluggify ( heading . textContent ) } ` : sluggify ( heading . textContent ) ;
85+ } ) ;
86+ }
87+
88+ return frag ;
89+ }
90+
4091export function createMDParser ( {
4192 gfm = true ,
4293 breaks = false ,
@@ -77,11 +128,14 @@ export function createMDParser({
77128 raw = String . dedent ( tmp ) ;
78129 }
79130
80- frag . setHTML ( marked . parse ( raw , { gfm, breaks, silent } ) , {
131+ const parsed = marked . parse ( raw , { gfm, breaks, silent } ) ;
132+ const doc = Document . parseHTML ( parsed , {
81133 allowElements, allowAttributes, allowCustomElements, allowUnknownMarkup,
82134 allowComments,
83135 } ) ;
84136
137+ frag . append ( ...doc . body . childNodes ) ;
138+
85139 if ( addHeadingIDs ) {
86140 frag . querySelectorAll ( 'h1, h2, h3, h4, h5, h6' ) . forEach ( heading => {
87141 heading . id = typeof idPrefix === 'string' ? `${ idPrefix } -${ sluggify ( heading . textContent ) } ` : sluggify ( heading . textContent ) ;
@@ -107,10 +161,10 @@ export async function getMarkdown(url, {
107161 headers . set ( 'Accept' , 'text/markdown' ) ;
108162 }
109163
110- const resp = await fetch ( url , { mode, referrerPolicy, headers, ...rest } ) ;
164+ const resp = await fetch ( url , { mode, referrerPolicy, headers, ...rest } ) . catch ( ( ) => Response . error ( ) ) ;
111165
112166 if ( ! resp . ok ) {
113- throw new DOMException ( `${ resp . url } [${ resp . status } ${ resp . statusText } ]` , 'NetworkError' ) ;
167+ throw new DOMException ( `${ resp . url } [${ resp . status } ]` , 'NetworkError' ) ;
114168 } else if ( ! resp . headers . get ( 'Content-Type' ) . startsWith ( 'text/markdown' ) ) {
115169 throw new TypeError ( `Invalid Content-Type: ${ resp . headers . get ( 'Content-Type' ) } .` ) ;
116170 } else {
0 commit comments