Path: blob/main/package/src/common/update-pandoc.ts
6450 views
/*1* update-pandoc.ts2*3* Copyright (C) 2020-2022 Posit Software, PBC4*5*/6import { Command } from "cliffy/command/mod.ts";7import { join } from "../../../src/deno_ral/path.ts";8import { ensureDirSync } from "../../../src/deno_ral/fs.ts";9import { info } from "../../../src/deno_ral/log.ts";1011import {12Configuration,13readConfiguration,14withWorkingDir,15} from "../common/config.ts";16import { lines } from "../../../src/core/text.ts";17import { pandoc } from "./dependencies/pandoc.ts";18import { archiveBinaryDependency } from "./archive-binary-dependencies.ts";1920import { configureDependency } from "./dependencies/dependencies.ts";21import { download, unzip } from "../util/utils.ts";22import {23pandocListFormatDefaultExtensions,24pandocListFormats,25} from "../../../src/core/pandoc/pandoc-formats.ts";2627import {28bgBlack,29bold,30brightWhite,31} from "../../../src/core/lib/external/colors.ts";3233import * as ld from "../../../src/core/lodash.ts";3435export function updatePandoc() {36return new Command()37.name("update-pandoc")38.arguments("<version:string>")39.description("Updates Pandoc to the specified version")40.action(async (_args, version: string) => {41info(`Updating Pandoc to ${version}`);4243const configuration = readConfiguration();4445// Update the configuration file46info(" updating configuration file.");47const configFilePath = join(48configuration.directoryInfo.root,49"configuration",50);51const configText = Deno.readTextFileSync(configFilePath);52const configLines = lines(configText);53const outputLines: string[] = [];54for (const line of configLines) {55if (line.startsWith("export PANDOC=")) {56outputLines.push(`export PANDOC=${version}`);57} else {58outputLines.push(line);59}60}61Deno.writeTextFileSync(configFilePath, outputLines.join("\n"));6263const pandocDependency = pandoc(version);6465// Call archive-bin-deps for this file66await withWorkingDir(async (workingDir) => {67await archiveBinaryDependency(pandocDependency, workingDir);6869// Configure this version of pandoc70await configureDependency(71pandocDependency,72join(configuration.directoryInfo.bin, "tools"),73configuration,74);7576// Generate templates77await writePandocTemplates(configuration, version, workingDir);7879// Generate variants80await writeVariants(configuration);81});8283// print the warning to complete the checklist84console.log(bgBlack(brightWhite(bold(85"\n** Remember to complete the checklist in /dev-docs/update-pandoc-checklist.md! **",86))));87});88}8990// Starting in Pandoc 3, we saw a number of variants that appear to be supported91// disappear from the --list-extensions command, so for the time being we're just92// hard adding them here93const kExtendedVariants: string[] = [94"amuse",95"attributes",96"element_citations",97"empty_paragraphs",98"epub_html_exts",99"native_numbering",100"ntb",101"raw_markdown",102"sourcepos",103"styles",104"xrefs_name",105"xrefs_number",106];107108async function writeVariants(109config: Configuration,110) {111info("Generating Pandoc extensions source file...");112info("Reading pandoc formats and extensions");113const formats = await pandocListFormats();114const extensions: Set<string> = new Set();115for (const format of formats) {116const formatExtensions = await pandocListFormatDefaultExtensions(format);117formatExtensions.forEach((ext) => {118const bareExtension = ext.replace(/^[\+\-]/, "");119extensions.add(bareExtension);120});121}122const extArr = Array.from(extensions.values());123info(` Pandoc Alone Reporting:`);124info(` ${formats.length} formats.`);125info(` ${extArr.length} extensions.`);126127extArr.push(...kExtendedVariants);128const extended = ld.uniq(extArr);129info(` ${extended.length} extensions (after adding extended).`);130131const extArrExpanded = extended.toSorted().flatMap((ext: string) => {132return [`"+${ext}"`, `"-${ext}"`];133});134135const extensionFile = join(136config.directoryInfo.src,137"core",138"pandoc",139"format-extension.ts",140);141142// Generate the extension list143const tsContents = `144/*145* pandoc-extensions.ts146*147* Copyright (C) 2020-2022 Posit Software, PBC148*149*/150//151// THIS FILE IS GENERATED BY update-pandoc.ts. DO NOT EDIT MANUALLY152//153154export const kPandocExtensions = [155${extArrExpanded.join(",\n ")}156];157`;158159// Write the file160Deno.writeTextFileSync(extensionFile, tsContents);161}162163async function writePandocTemplates(164config: Configuration,165version: string,166workingDir: string,167) {168info("Reading pandoc templates...");169const formatSrcDir = join(170config.directoryInfo.src,171"resources",172"formats",173);174175const srcZipUrl =176`https://github.com/jgm/pandoc/archive/refs/tags/${version}.zip`;177178const pandocDir = `pandoc-${version}`;179const zipFile = join(workingDir, "pandoc");180await download(srcZipUrl, zipFile);181await unzip(zipFile, workingDir);182183// Jats templates are multi-part templates that184// are not properly emitted by pandoc itself, so download185// them from source instead186const templateDir = join(workingDir, pandocDir, "data", "templates");187const jatsOutDir = join(188formatSrcDir,189"jats",190"pandoc",191"default-templates",192);193const htmlOutdir = join(194formatSrcDir,195"html",196"pandoc",197);198const latexOutdir = join(formatSrcDir, "pdf", "pandoc");199const revealOutdir = join(formatSrcDir, "revealjs", "pandoc");200const beamerOutdir = join(formatSrcDir, "beamer", "pandoc");201const asciidocOutdir = join(formatSrcDir, "asciidoc", "pandoc");202const typstOutdir = join(formatSrcDir, "typst", "pandoc");203204const templateDirFiles: Record<string, Array<{ from: string; to?: string }>> =205{206[jatsOutDir]: [207{ from: "affiliations.jats" },208{ from: "article.jats_publishing" },209{ from: "default.jats_archiving" },210{ from: "default.jats_articleauthoring" },211{ from: "default.jats_publishing" },212],213[htmlOutdir]: [214{ from: "default.html5", to: "html.template" },215{ from: "styles.html", to: "html.styles" },216],217[revealOutdir]: [218{ from: "default.revealjs", to: "revealjs.template" },219],220[latexOutdir]: [221{ from: "default.latex", to: "latex.template" },222// Template we need to tweak223{ from: "common.latex", to: "latex.common" },224// Template kept unchanged225{ from: "after-header-includes.latex" },226{ from: "hypersetup.latex" },227{ from: "font-settings.latex" },228{ from: "fonts.latex" },229{ from: "passoptions.latex" },230],231[beamerOutdir]: [232{ from: "default.beamer", to: "beamer.template" },233// Template we need to tweak234{ from: "common.latex", to: "latex.common" },235// Template kept unchanged236{ from: "after-header-includes.latex" },237{ from: "hypersetup.latex" },238{ from: "font-settings.latex" },239{ from: "fonts.latex" },240{ from: "passoptions.latex" },241],242[asciidocOutdir]: [243{ from: "default.asciidoc", to: "asciidoc.template" },244],245[typstOutdir]: [246{ from: "default.typst", to: "typst.template" },247{ from: "template.typst" }248]249};250251// Move templates252for (const outDir of Object.keys(templateDirFiles)) {253ensureDirSync(outDir);254for (const file of templateDirFiles[outDir]) {255info(`> ${file.from}`);256Deno.copyFileSync(257join(templateDir, file.from),258join(outDir, file.to || file.from),259);260}261}262263info("done.");264info("");265}266267268