@@ -17,6 +17,7 @@ import {
1717 kIncludeInHeader ,
1818 kLinkCitations ,
1919 kQuartoTemplateParams ,
20+ kRelatedFormatsTitle ,
2021 kSectionDivs ,
2122 kTitle ,
2223 kTocDepth ,
@@ -66,6 +67,14 @@ import {
6667import { kTemplatePartials } from "../../command/render/template.ts" ;
6768import { TempContext } from "../../core/temp-types.ts" ;
6869import { isHtmlOutput } from "../../config/format.ts" ;
70+ import {
71+ isDocxOutput ,
72+ isHtmlOutput ,
73+ isIpynbOutput ,
74+ isMarkdownOutput ,
75+ isPdfOutput ,
76+ isPresentationOutput ,
77+ } from "../../config/format.ts" ;
6978import { basename } from "path/mod.ts" ;
7079
7180export function formatPageLayout ( format : Format ) {
@@ -312,24 +321,69 @@ function bootstrapHtmlPostprocessor(
312321 }
313322
314323 if ( dlLinkTarget ) {
324+ const bsIcon = ( format : Format ) => {
325+ if ( isDocxOutput ( format . pandoc ) ) {
326+ return "file-word" ;
327+ } else if ( isPdfOutput ( format . pandoc ) ) {
328+ return "file-pdf" ;
329+ } else if ( isIpynbOutput ( format . pandoc ) ) {
330+ return "journal-arrow-down" ;
331+ } else if ( isMarkdownOutput ( format . pandoc ) ) {
332+ return "file-code" ;
333+ } else if ( isPresentationOutput ( format . pandoc ) ) {
334+ return "file-slides" ;
335+ } else {
336+ return "file" ;
337+ }
338+ } ;
339+
340+ const dlName = ( format : Format , path : string ) => {
341+ if ( isIpynbOutput ( format . pandoc ) ) {
342+ return basename ( path ) ;
343+ } else {
344+ return undefined ;
345+ }
346+ } ;
347+
348+ const containerEl = doc . createElement ( "div" ) ;
349+ containerEl . classList . add ( "quarto-alternate-formats" ) ;
350+
315351 const heading = doc . createElement ( "h2" ) ;
316- heading . innerText = "Related" ;
317- dlLinkTarget . appendChild ( heading ) ;
352+ if ( format . language [ kRelatedFormatsTitle ] ) {
353+ heading . innerText = format . language [ kRelatedFormatsTitle ] ;
354+ }
355+ containerEl . appendChild ( heading ) ;
318356
319357 const formatList = doc . createElement ( "ul" ) ;
320358
321359 for ( const renderedFormat of options . renderedFormats ) {
322360 if ( ! isHtmlOutput ( renderedFormat . format . pandoc , true ) ) {
323361 const li = doc . createElement ( "li" ) ;
362+
324363 const link = doc . createElement ( "a" ) ;
325364 link . setAttribute ( "href" , renderedFormat . path ) ;
326- link . setAttribute ( "download" , basename ( renderedFormat . path ) ) ;
327- link . innerHTML = `${ renderedFormat . format . pandoc . to } ` ;
365+ const dlAttrValue = dlName (
366+ renderedFormat . format ,
367+ renderedFormat . path ,
368+ ) ;
369+ if ( dlAttrValue ) {
370+ link . setAttribute ( "download" , dlAttrValue ) ;
371+ }
372+
373+ const icon = doc . createElement ( "i" ) ;
374+ icon . classList . add ( "bi" ) ;
375+ icon . classList . add ( `bi-${ bsIcon ( renderedFormat . format ) } ` ) ;
376+ link . appendChild ( icon ) ;
377+ link . appendChild (
378+ doc . createTextNode ( `${ renderedFormat . format . pandoc . to } ` ) ,
379+ ) ;
380+
328381 li . appendChild ( link ) ;
329382 formatList . appendChild ( li ) ;
330383 }
331384 }
332- dlLinkTarget . appendChild ( formatList ) ;
385+ containerEl . appendChild ( formatList ) ;
386+ dlLinkTarget . appendChild ( containerEl ) ;
333387 }
334388 }
335389
0 commit comments