@@ -431,7 +431,7 @@ const fileBsIconName = (format: Format) => {
431431 } else if ( isPdfOutput ( format . pandoc ) ) {
432432 return "file-pdf" ;
433433 } else if ( isIpynbOutput ( format . pandoc ) ) {
434- return "journal-arrow-down " ;
434+ return "journal-code " ;
435435 } else if ( isMarkdownOutput ( format . pandoc ) ) {
436436 return "file-code" ;
437437 } else if ( isPresentationOutput ( format . pandoc ) ) {
@@ -518,15 +518,47 @@ function processNotebookEmbeds(
518518) {
519519 const notebookDivNodes = doc . querySelectorAll ( "[data-notebook]" ) ;
520520 if ( notebookDivNodes . length > 0 ) {
521- const nbPaths : { path : string ; title : string | null } [ ] = [ ] ;
521+ const nbPaths : { path : string ; title : string ; filename : string } [ ] = [ ] ;
522+ let count = 1 ;
522523 notebookDivNodes . forEach ( ( nbDivNode ) => {
523524 const nbDivEl = nbDivNode as Element ;
524- const nbPath = nbDivEl . getAttribute ( "data-notebook" ) ;
525- if ( nbPath ) {
526- nbPaths . push ( {
527- path : nbPath ,
528- title : nbDivEl . getAttribute ( "data-notebook-title" ) ,
529- } ) ;
525+ nbDivEl . classList . add ( "quarto-notebook" ) ;
526+ const notebookPath = nbDivEl . getAttribute ( "data-notebook" ) ;
527+ if ( notebookPath ) {
528+ const title = nbDivEl . getAttribute ( "data-notebook-title" ) ;
529+ const filename = basename ( notebookPath ) ;
530+
531+ const nbPath = {
532+ path : notebookPath ,
533+ title : title || filename ,
534+ filename,
535+ } ;
536+ nbPaths . push ( nbPath ) ;
537+
538+ // Add a decoration to this div node
539+ const id = "nblink-" + count ++ ;
540+
541+ const nbLinkEl = doc . createElement ( "a" ) ;
542+ nbLinkEl . classList . add ( "quarto-notebook-link" ) ;
543+ nbLinkEl . setAttribute ( "id" , `${ id } ` ) ;
544+ nbLinkEl . setAttribute ( "href" , nbPath . path ) ;
545+ nbLinkEl . setAttribute ( "download" , nbPath . filename ) ;
546+ nbLinkEl . appendChild ( doc . createTextNode ( `Source: ${ nbPath . title } ` ) ) ;
547+
548+ const nbParentEl = nbDivEl . parentElement ;
549+ if ( nbParentEl ?. tagName . toLocaleLowerCase ( ) === "figure" ) {
550+ const figCapEl = nbDivEl . parentElement ?. querySelector ( "figcaption" ) ;
551+ if ( figCapEl ) {
552+ figCapEl . after ( nbLinkEl ) ;
553+ } else {
554+ nbDivEl . appendChild ( nbLinkEl ) ;
555+ }
556+ } else {
557+ nbDivEl . appendChild ( nbLinkEl ) ;
558+ }
559+
560+ // Try to place it after the figure caption, if possible
561+ // For tables, place after the table caption if they are on the bottom
530562 }
531563 } ) ;
532564
@@ -544,19 +576,18 @@ function processNotebookEmbeds(
544576 ld . uniqBy ( nbPaths , ( nbPath : { path : string ; title ?: string } ) => {
545577 return nbPath . path ;
546578 } ) . forEach ( ( nbPath ) => {
547- const filename = basename ( nbPath . path ) ;
548579 const li = doc . createElement ( "li" ) ;
549580
550581 const link = doc . createElement ( "a" ) ;
551582 link . setAttribute ( "href" , nbPath . path ) ;
552- link . setAttribute ( "download" , filename ) ;
583+ link . setAttribute ( "download" , nbPath . filename ) ;
553584
554585 const icon = doc . createElement ( "i" ) ;
555586 icon . classList . add ( "bi" ) ;
556- icon . classList . add ( `bi-journal-arrow-down ` ) ;
587+ icon . classList . add ( `bi-journal-code ` ) ;
557588 link . appendChild ( icon ) ;
558589 link . appendChild (
559- doc . createTextNode ( ` ${ nbPath . title || filename } ` ) ,
590+ doc . createTextNode ( nbPath . title ) ,
560591 ) ;
561592
562593 li . appendChild ( link ) ;
0 commit comments