@@ -41,6 +41,7 @@ import {
4141} from "./widgets.ts" ;
4242import { globalTempContext } from "../temp.ts" ;
4343import { isAbsolute } from "path/mod.ts" ;
44+ import { partitionMarkdown } from "../pandoc/pandoc-partition.ts" ;
4445
4546export interface JupyterNotebookAddress {
4647 path : string ;
@@ -58,7 +59,7 @@ export interface JupyterMarkdownOptions
5859interface JupyterNotebookOutputCache extends ObjectWithLifetime {
5960 cache : Record <
6061 string ,
61- { outputs : JupyterCellOutput [ ] }
62+ { outputs : JupyterCellOutput [ ] ; title ?: string }
6263 > ;
6364}
6465
@@ -213,7 +214,7 @@ async function notebookMarkdown(
213214 options ?: JupyterMarkdownOptions ,
214215) {
215216 // Get the cell outputs for this notebook
216- const cellOutputs = await getCellOutputs (
217+ const notebookInfo = await getCachedNotebookInfo (
217218 nbAddress ,
218219 assets ,
219220 context ,
@@ -223,8 +224,13 @@ async function notebookMarkdown(
223224
224225 // Wrap any injected cells with a div that includes a back link to
225226 // the notebook that originated the cells
226- const notebookMarkdown = ( cells : JupyterCellOutput [ ] ) => {
227- const markdown = [ "" , `:::{notebook="${ nbAddress . path } "}` ] ;
227+ const notebookMarkdown = ( cells : JupyterCellOutput [ ] , title ?: string ) => {
228+ const markdown = [
229+ "" ,
230+ `:::{notebook="${ nbAddress . path } " ${
231+ title ? `notebook-title="${ title } "` : ""
232+ } }`,
233+ ] ;
228234 markdown . push ( "" ) ;
229235 markdown . push ( cells . map ( ( cell ) => cell . markdown ) . join ( "" ) ) ;
230236 markdown . push ( "" ) ;
@@ -237,7 +243,7 @@ async function notebookMarkdown(
237243 // those cells (cellIds can eiher be an explicitly set cellId, a label in the
238244 // cell metadata, or a tag on a cell that matches an id)
239245 const theCells = nbAddress . ids . map ( ( id ) => {
240- const cell = cellForId ( id , cellOutputs ) ;
246+ const cell = cellForId ( id , notebookInfo . outputs ) ;
241247 if ( cell === undefined ) {
242248 throw new Error (
243249 `The cell ${ id } does not exist in notebook` ,
@@ -246,26 +252,26 @@ async function notebookMarkdown(
246252 return cell ;
247253 }
248254 } ) ;
249- return notebookMarkdown ( theCells ) ;
255+ return notebookMarkdown ( theCells , notebookInfo . title ) ;
250256 } else if ( nbAddress . indexes ) {
251257 // Filter and sort based upon cell indexes
252258 const theCells = nbAddress . indexes . map ( ( idx ) => {
253- if ( idx < 0 || idx >= cellOutputs . length ) {
259+ if ( idx < 0 || idx >= notebookInfo . outputs . length ) {
254260 throw new Error (
255261 `The cell index ${ idx } isn't within the range of cells` ,
256262 ) ;
257263 }
258- return cellOutputs [ idx ] ;
264+ return notebookInfo . outputs [ idx ] ;
259265 } ) ;
260- return notebookMarkdown ( theCells ) ;
266+ return notebookMarkdown ( theCells , notebookInfo . title ) ;
261267 } else {
262268 // Return all the cell outputs as there is no addtional
263269 // specification of cells
264- return notebookMarkdown ( cellOutputs ) ;
270+ return notebookMarkdown ( notebookInfo . outputs , notebookInfo . title ) ;
265271 }
266272}
267273
268- async function getCellOutputs (
274+ async function getCachedNotebookInfo (
269275 nbAddress : JupyterNotebookAddress ,
270276 assets : JupyterAssets ,
271277 context : RenderContext ,
@@ -347,11 +353,26 @@ async function getCellOutputs(
347353 } ,
348354 ) ;
349355
356+ // Compute the notebook title
357+ const title = findTitle ( result . cellOutputs ) ;
358+
350359 // Place the outputs in the cache
351- nbCache . cache [ cacheKey ] = { outputs : result . cellOutputs } ;
360+ nbCache . cache [ cacheKey ] = { outputs : result . cellOutputs , title } ;
352361 lifetime . attach ( nbCache , kNotebookCache ) ;
353362 }
354- return nbCache . cache [ cacheKey ] . outputs ;
363+ return nbCache . cache [ cacheKey ] ;
364+ }
365+
366+ function findTitle ( cells : JupyterCellOutput [ ] ) {
367+ for ( const cell of cells ) {
368+ const partitioned = partitionMarkdown ( cell . markdown ) ;
369+ if ( partitioned . yaml ?. title ) {
370+ return partitioned . yaml . title as string ;
371+ } else if ( partitioned . headingText ) {
372+ return partitioned . headingText ;
373+ }
374+ }
375+ return undefined ;
355376}
356377
357378function notebookCacheKey (
0 commit comments