77
88import { existsSync } from "fs/mod.ts" ;
99
10- import { dirname , isAbsolute , join , relative } from "path/mod.ts" ;
10+ import { basename , dirname , isAbsolute , join , relative } from "path/mod.ts" ;
1111
1212import { Document , parseHtml } from "../../core/deno-dom.ts" ;
1313
1414import { mergeConfigs } from "../../core/config.ts" ;
15- import { resourcePath } from "../../core/resources.ts" ;
15+ import {
16+ formatResourcePath ,
17+ pandocBinaryPath ,
18+ resourcePath ,
19+ } from "../../core/resources.ts" ;
1620import { inputFilesDir } from "../../core/render.ts" ;
1721import { pathWithForwardSlashes } from "../../core/path.ts" ;
1822
@@ -38,6 +42,7 @@ import { Metadata } from "../../config/types.ts";
3842import { isHtmlFileOutput } from "../../config/format.ts" ;
3943
4044import { isSelfContainedOutput } from "./render-info.ts" ;
45+ import { execProcess } from "../../core/process.ts" ;
4146
4247export async function renderPandoc (
4348 file : ExecutedFile ,
@@ -151,11 +156,13 @@ export async function renderPandoc(
151156 htmlFinalizers ,
152157 ) ;
153158
159+ // Compute the path to the output file
160+ const outputFile = isAbsolute ( pandocOptions . output )
161+ ? pandocOptions . output
162+ : join ( dirname ( pandocOptions . source ) , pandocOptions . output ) ;
163+
154164 // run generic postprocessors
155165 if ( pandocResult . postprocessors ) {
156- const outputFile = isAbsolute ( pandocOptions . output )
157- ? pandocOptions . output
158- : join ( dirname ( pandocOptions . source ) , pandocOptions . output ) ;
159166 for ( const postprocessor of pandocResult . postprocessors ) {
160167 await postprocessor ( outputFile ) ;
161168 }
@@ -174,6 +181,12 @@ export async function renderPandoc(
174181 finalOutput ,
175182 ) ;
176183
184+ // If this is self-contained, run pandoc to 'suck in' the dependencies
185+ // which may have been added in the post processor
186+ if ( selfContained && isHtmlFileOutput ( format . pandoc ) ) {
187+ await pandocIngestSelfContainedContent ( outputFile ) ;
188+ }
189+
177190 // compute the relative path to the files dir
178191 let filesDir : string | undefined = inputFilesDir ( context . target . source ) ;
179192 // undefine it if it doesn't exist
@@ -369,3 +382,41 @@ async function runHtmlPostprocessors(
369382 }
370383 return postProcessResult ;
371384}
385+
386+ const pandocIngestSelfContainedContent = async ( file : string ) => {
387+ const filename = basename ( file ) ;
388+ const workingDir = dirname ( file ) ;
389+
390+ // The template
391+ const template = formatResourcePath (
392+ "html" ,
393+ "pandoc-selfcontained/selfcontained.html" ,
394+ ) ;
395+
396+ // The raw html contents
397+ const contents = Deno . readTextFileSync ( file ) ;
398+ const input : string [ ] = [ ] ;
399+ input . push ( "````````{=html}" ) ;
400+ input . push ( contents ) ;
401+ input . push ( "````````" ) ;
402+
403+ // Run pandoc to suck in dependencies
404+ const cmd = [ pandocBinaryPath ( ) ] ;
405+ cmd . push ( "--to" , "html" ) ;
406+ cmd . push ( "--from" , "markdown" ) ;
407+ cmd . push ( "--template" , template ) ;
408+ cmd . push ( "--output" , filename ) ;
409+ cmd . push ( "--metadata" , "title=placeholder" ) ;
410+ cmd . push ( "--self-contained" ) ;
411+ const result = await execProcess ( {
412+ cmd,
413+ stdout : "piped" ,
414+ cwd : workingDir ,
415+ } , input . join ( "\n" ) ) ;
416+
417+ if ( result . success ) {
418+ return result . stdout ;
419+ } else {
420+ throw new Error ( ) ;
421+ }
422+ } ;
0 commit comments