@@ -313,16 +313,20 @@ function sanitizeHTMLToString(
313313 div : HTMLDivElement ,
314314 serializer : XMLSerializer ,
315315) : string {
316+ const styleTags = div . querySelectorAll ( "style" ) ;
317+
316318 // Let Obsidian handle the sanitization
317319 const sanitizedHtml = sanitizeHTMLToDom ( div . innerHTML ) ;
318320
319321 let container = document . createElement ( "div" ) ;
320322 container . appendChild ( sanitizedHtml ) ;
321323
322- removeUnwantedElements ( container , "script, style, link, meta, title" ) ;
324+ removeUnwantedElements ( container , "script, link, meta, title" ) ;
323325
324326 // Remove unwanted attributes from internal links
325- const internalLinks = container . querySelectorAll ( "a.internal-link, a.tag" ) ;
327+ const internalLinks = container . querySelectorAll (
328+ "a.internal-link, a.tag, a:not(.external-link):not(.internal-link):not(.tag)" ,
329+ ) ;
326330
327331 if ( internalLinks . length > 0 ) {
328332 cleanAnchorLinks ( container ) ;
@@ -372,12 +376,38 @@ function sanitizeHTMLToString(
372376 return cleanQueryResult ( result ) ;
373377 }
374378
379+ styleTags . forEach ( ( styleTag ) => {
380+ container . append ( styleTag ) ;
381+ } ) ;
382+
383+ cleanDatacoreAttributes ( container ) ;
384+
375385 // Serialize the sanitized HTML back to a string
376386 const serializedHtml = serializer . serializeToString ( container ) ;
377387
378388 return serializedHtml . replace ( ' xmlns="http://www.w3.org/1999/xhtml"' , "" ) ;
379389}
380390
391+ /**
392+ * Cleans datacore attributes from the container.
393+ * This is useful for removing Obsidian-specific attributes that are not needed in Quartz.
394+ *
395+ * @param container - The HTMLDivElement containing the HTML content to clean.
396+ */
397+ function cleanDatacoreAttributes ( container : HTMLDivElement ) : void {
398+ const datacoreAttributes = [ "__source" , "__self" ] ;
399+
400+ const elements = container . querySelectorAll (
401+ `${ datacoreAttributes . map ( ( attr ) => `[${ attr } ]` ) . join ( ", " ) } ` ,
402+ ) ;
403+
404+ elements . forEach ( ( element ) => {
405+ datacoreAttributes . forEach ( ( attr ) => {
406+ element . removeAttribute ( attr ) ;
407+ } ) ;
408+ } ) ;
409+ }
410+
381411/**
382412 * Converts callouts in the container to a Quartz-compatible format.
383413 * This function replaces the callout elements with a Quartz-compatible blockquote format.
@@ -480,12 +510,22 @@ function convertCallouts(container: HTMLDivElement): HTMLDivElement {
480510 * @param container - The HTMLDivElement containing the anchor links to clean.
481511 */
482512function cleanAnchorLinks ( container : HTMLDivElement ) : void {
483- const internalLinks = container . querySelectorAll ( "a.internal-link, a.tag" ) ;
513+ const internalLinks = container . querySelectorAll (
514+ "a.internal-link, a.tag, a:not(.external-link):not(.internal-link):not(.tag)" ,
515+ ) ;
484516
485517 internalLinks . forEach ( ( link ) => {
486518 link . removeAttribute ( "target" ) ;
487519 link . removeAttribute ( "rel" ) ;
488520 link . removeAttribute ( "data-href" ) ;
521+
522+ if ( link . hasAttribute ( "href" ) ) {
523+ if ( link . getAttribute ( "href" ) ?. startsWith ( "http" ) ) {
524+ link . classList . add ( "external-link" ) ;
525+ } else {
526+ link . classList . add ( "internal-link" ) ;
527+ }
528+ }
489529 } ) ;
490530}
491531
0 commit comments