@@ -24,7 +24,9 @@ import { jatsContributor } from "./notebook-contributor-jats.ts";
2424import { htmlNotebookContributor } from "./notebook-contributor-html.ts" ;
2525import { outputNotebookContributor } from "./notebook-contributor-ipynb.ts" ;
2626import { Format } from "../../config/types.ts" ;
27- import { safeRemoveIfExists } from "../../core/path.ts" ;
27+ import { safeExistsSync , safeRemoveIfExists } from "../../core/path.ts" ;
28+ import { relative } from "path/mod.ts" ;
29+ import { projectOutputDir } from "../../project/project-shared.ts" ;
2830
2931const contributors : Record < RenderType , NotebookContributor | undefined > = {
3032 [ kJatsSubarticle ] : jatsContributor ,
@@ -50,6 +52,7 @@ export function notebookContext(): NotebookContext {
5052 } ;
5153 } ;
5254
55+ // Adds a rendering of a notebook to the notebook context
5356 const addRendering = (
5457 nbAbsPath : string ,
5558 renderType : RenderType ,
@@ -66,6 +69,11 @@ export function notebookContext(): NotebookContext {
6669 nb [ renderType ] . output = output ;
6770 notebooks [ nbAbsPath ] = nb ;
6871 } ;
72+
73+ // Removes a rendering of a notebook from the notebook context
74+ // which includes cleaning up the files. This should only be
75+ // used when the caller knows other callers will not need the
76+ // notebook.
6977 const removeRendering = (
7078 nbAbsPath : string ,
7179 renderType : RenderType ,
@@ -97,6 +105,7 @@ export function notebookContext(): NotebookContext {
97105 }
98106 } ;
99107
108+ // Get a contribute for a render type
100109 function contributor ( renderType : RenderType ) {
101110 const contributor = contributors [ renderType ] ;
102111 if ( contributor ) {
@@ -108,6 +117,7 @@ export function notebookContext(): NotebookContext {
108117 }
109118 }
110119
120+ // Add metadata to a given notebook rendering
111121 function addMetadata (
112122 nbAbsPath : string ,
113123 renderType : RenderType ,
@@ -120,8 +130,60 @@ export function notebookContext(): NotebookContext {
120130 notebooks [ nbAbsPath ] = nb ;
121131 }
122132
133+ function reviveOutput (
134+ nbAbsPath : string ,
135+ renderType : RenderType ,
136+ nbOutputDir : string ,
137+ ) {
138+ const contrib = contributor ( renderType ) ;
139+ const outFile = contrib . outputFile ( nbAbsPath ) ;
140+ const outPath = join ( nbOutputDir , outFile ) ;
141+ if ( safeExistsSync ( outPath ) ) {
142+ const inputTime = Deno . statSync ( nbAbsPath ) . mtime ?. valueOf ( ) || 0 ;
143+ const outputTime = Deno . statSync ( outPath ) . mtime ?. valueOf ( ) || 0 ;
144+ if ( inputTime <= outputTime ) {
145+ addRendering ( nbAbsPath , renderType , {
146+ file : outPath ,
147+ supporting : [ ] ,
148+ resourceFiles : {
149+ globs : [ ] ,
150+ files : [ ] ,
151+ } ,
152+ } ) ;
153+ }
154+ }
155+ }
156+
123157 return {
124- get : ( nbAbsPath : string ) => {
158+ get : ( nbAbsPath : string , context ?: ProjectContext ) => {
159+ const notebook = notebooks [ nbAbsPath ] ;
160+ const reviveRenders : RenderType [ ] = [ ] ;
161+ if ( notebook ) {
162+ // We already have a notebook, try to complete its renderings
163+ // by reviving any outputs that are valid
164+ [ kJatsSubarticle , kHtmlPreview , kRenderedIPynb ] . forEach (
165+ ( renderTypeStr ) => {
166+ const renderType = renderTypeStr as RenderType ;
167+ if ( ! notebook [ renderType ] . output ) {
168+ reviveRenders . push ( renderType ) ;
169+ }
170+ } ,
171+ ) ;
172+ } else {
173+ reviveRenders . push ( kHtmlPreview ) ;
174+ reviveRenders . push ( kJatsSubarticle ) ;
175+ reviveRenders . push ( kRenderedIPynb ) ;
176+ }
177+
178+ if ( context ) {
179+ const nbRelative = relative ( context . dir , dirname ( nbAbsPath ) ) ;
180+ const nbOutputDir = join ( projectOutputDir ( context ) , nbRelative ) ;
181+
182+ // See if an up to date rendered result exists for each contributor
183+ for ( const renderType of reviveRenders ) {
184+ reviveOutput ( nbAbsPath , renderType , nbOutputDir ) ;
185+ }
186+ }
125187 return notebooks [ nbAbsPath ] ;
126188 } ,
127189 resolve : (
0 commit comments