Skip to content

Commit 247e7a0

Browse files
authored
feat: add metadata and TOC to PDF generated with --per-slide (#1220)
1 parent 993b754 commit 247e7a0

File tree

1 file changed

+42
-28
lines changed

1 file changed

+42
-28
lines changed

packages/slidev/node/export.ts

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ export async function exportSlides({
270270
progress.update(++idx)
271271
}
272272

273-
const mergedPdf = await PDFDocument.create({})
273+
let mergedPdf = await PDFDocument.create({})
274274
for (const pdfBytes of buffers) {
275275
const pdf = await PDFDocument.load(pdfBytes)
276276
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices())
@@ -279,13 +279,18 @@ export async function exportSlides({
279279
})
280280
}
281281

282+
// Edit generated PDF: add metadata and (optionally) TOC
283+
addPdfMetadata(mergedPdf)
284+
285+
if (withToc)
286+
mergedPdf = await addTocToPdf(mergedPdf)
287+
282288
const buffer = await mergedPdf.save()
283289
await fs.writeFile(output, buffer)
284290
}
285291

286292
async function genPagePdfOnePiece() {
287293
await go('print')
288-
const slideIndexes = await getSlidesIndex()
289294
await page.pdf({
290295
path: output,
291296
width,
@@ -304,33 +309,10 @@ export async function exportSlides({
304309
let pdfData = await fs.readFile(output)
305310
let pdf = await PDFDocument.load(pdfData)
306311

307-
const titleSlide = slides[0]
308-
if (titleSlide?.title)
309-
pdf.setTitle(titleSlide.title)
310-
if (titleSlide?.frontmatter?.info)
311-
pdf.setSubject(titleSlide.frontmatter.info)
312-
if (titleSlide?.frontmatter?.author)
313-
pdf.setAuthor(titleSlide.frontmatter.author)
314-
if (titleSlide?.frontmatter?.keywords) {
315-
if (Array.isArray(titleSlide?.frontmatter?.keywords))
316-
pdf.setKeywords(titleSlide?.frontmatter?.keywords)
317-
else
318-
pdf.setKeywords(titleSlide?.frontmatter?.keywords.split(','))
319-
}
320-
321-
if (withToc) {
322-
const outlinePdf = outlinePdfFactory(pdfLib)
323-
324-
const tocTree = slides.filter(slide => slide.title)
325-
.reduce((acc: TocItem[], slide) => {
326-
addToTree(acc, slide, slideIndexes)
327-
return acc
328-
}, [])
312+
addPdfMetadata(pdf)
329313

330-
const outline = makeOutline(tocTree)
331-
332-
pdf = await outlinePdf({ outline, pdf })
333-
}
314+
if (withToc)
315+
pdf = await addTocToPdf(pdf)
334316

335317
pdfData = Buffer.from(await pdf.save())
336318
await fs.writeFile(output, pdfData)
@@ -399,6 +381,38 @@ export async function exportSlides({
399381
return Number(slideId) - 1
400382
}
401383

384+
// Adds metadata (title, author, keywords) to PDF document, mutating it
385+
function addPdfMetadata(pdf: PDFDocument): void {
386+
const titleSlide = slides[0]
387+
if (titleSlide?.title)
388+
pdf.setTitle(titleSlide.title)
389+
if (titleSlide?.frontmatter?.info)
390+
pdf.setSubject(titleSlide.frontmatter.info)
391+
if (titleSlide?.frontmatter?.author)
392+
pdf.setAuthor(titleSlide.frontmatter.author)
393+
if (titleSlide?.frontmatter?.keywords) {
394+
if (Array.isArray(titleSlide?.frontmatter?.keywords))
395+
pdf.setKeywords(titleSlide?.frontmatter?.keywords)
396+
else
397+
pdf.setKeywords(titleSlide?.frontmatter?.keywords.split(','))
398+
}
399+
}
400+
401+
async function addTocToPdf(pdf: PDFDocument): Promise<PDFDocument> {
402+
const outlinePdf = outlinePdfFactory(pdfLib)
403+
const slideIndexes = await getSlidesIndex()
404+
405+
const tocTree = slides.filter(slide => slide.title)
406+
.reduce((acc: TocItem[], slide) => {
407+
addToTree(acc, slide, slideIndexes)
408+
return acc
409+
}, [])
410+
411+
const outline = makeOutline(tocTree)
412+
413+
return await outlinePdf({ outline, pdf })
414+
}
415+
402416
progress.start(pages.length)
403417

404418
if (format === 'pdf') {

0 commit comments

Comments
 (0)