UNPKG

@argdown/pandoc-filter

Version:

Turns Argdown code fences into svg, png, jpg, webp or web-component argument maps

190 lines 7.31 kB
#!/usr/bin/env node "use strict"; import path from "path"; import { stdio, Para, RawBlock, Image, Str } from "pandoc-filter"; import { argdown } from "@argdown/node"; import defaultsDeep from "lodash.defaultsdeep"; import { mergeDefaults } from "@argdown/core"; import { tryToInstallImageExport } from "./tryToInstallImageExport.js"; let imageCounter = 1; let webComponentCount = 0; let loadedConfig; let settings; const getFilterSettings = (meta) => { if (!settings) { settings = {}; const argdownMeta = meta["argdown"]; if (argdownMeta && argdownMeta.t === "MetaMap") { for (const entry of Object.entries(argdownMeta.c)) { const value = entry[1]; if (value.t === "MetaInlines" && Array.isArray(value.c) && typeof value.c[0].c === "string") { settings[entry[0]] = value.c[0].c; } } } settings = mergeDefaults(settings, { caption: "", mode: "inline", format: "svg" }); } return settings; }; const getArgdownConfig = async (configPath) => { if (!loadedConfig) { let pathToConfig; if (configPath) { pathToConfig = path.resolve(process.cwd(), configPath); } else { pathToConfig = path.resolve(process.cwd(), "argdown.config.json"); } loadedConfig = await argdown.loadConfig(pathToConfig); if (!loadedConfig) { loadedConfig = {}; } } return loadedConfig; }; void stdio(async (ele, _format, meta) => { if (ele.t === `CodeBlock`) { const [headers, content] = ele.c; const [, [language]] = headers; if (language === "argdown-map") { const settings = { ...getFilterSettings(meta) }; headers[2].map((item) => { settings[item[0]] = item[1]; }); const config = await getArgdownConfig(settings.config); const id = headers[0]; const process = getProcess(settings); if (settings.format != "svg") { const imageExportInstalled = await tryToInstallImageExport(argdown); if (!imageExportInstalled) { throw new Error(`You are trying to export an Argdown map to ${settings.format}. Please run "npm install -g @argdown/image-export" to install the Ardown image export plugin.`); } } switch (settings.mode) { case "web-component": { const request = defaultsDeep({ input: content, process }, config, { webComponent: { figureCaption: settings.caption, addGlobalStyles: webComponentCount == 0, addWebComponentPolyfill: webComponentCount == 0, addWebComponentScript: webComponentCount == 0 } }); webComponentCount++; const response = await argdown.runAsync(request); return RawBlock("html", response.webComponent || ""); } case "inline": { const request = defaultsDeep({ input: content, process }, config); const response = await argdown.runAsync(request); settings.caption = request.webComponent?.figureCaption || settings.caption; const inlineImage = getInlineImage(response, settings.format); return getPandocImage(settings, inlineImage, id); } case "file": { let fileName = id; if (!fileName || fileName == "") { fileName = `map-${imageCounter}`; imageCounter++; } const request = defaultsDeep({ input: content, process, saveAs: { fileName } }, config); const response = await argdown.runAsync(request); settings.caption = request.webComponent?.figureCaption || settings.caption; return getPandocImage(settings, response.outputPath, id); } } } else if (language === "argdown") { const settings = { ...getFilterSettings(meta) }; let sourceMode = settings.sourceHighlighter; headers[2].map((item) => { if (item[0] === "mode") { sourceMode = item[1]; } settings[item[0]] = item[1]; }); if (sourceMode === "web-component") { const config = await getArgdownConfig(settings.config); const process = getProcess(settings); const request = defaultsDeep({ input: content, process }, config, { webComponent: { initialView: "source", figureCaption: settings.caption, addGlobalStyles: webComponentCount == 0, addWebComponentPolyfill: webComponentCount == 0, addWebComponentScript: webComponentCount == 0 } }); webComponentCount++; const response = await argdown.runAsync(request); return RawBlock("html", response.webComponent || ""); } } } return; }); const getInlineImage = (response, format) => { const inlineFormat = format == "svg" ? "svg+xml" : format; let result = response[format]; if (typeof result === "string" || result instanceof String) { result = Buffer.from(result); } return `data:image/${inlineFormat};base64,${result.toString("base64")}`; }; const getProcess = (settings) => { const process = [ "parse-input", "build-model", "build-map", "transform-closed-groups", "colorize", "export-dot", "export-svg" ]; if (settings.format !== "svg") { process.push(`export-${settings.format}`); } if (settings.mode == "file") { process.push(`save-as-${settings.format}`); } else if (settings.mode == "web-component") { process.push("highlight-source", "export-web-component"); } return process; }; const getPandocImage = (settings, imagePath, id) => { const caption = settings.caption || ""; const attr = []; if (settings.width) { attr.push(["width", settings.width.toString()]); } if (settings.height) { attr.push(["height", settings.height.toString()]); } const fig = `fig:${settings.caption}`; return Para([Image([id, [], attr], [Str(caption)], [imagePath, fig])]); }; //# sourceMappingURL=index.js.map