UNPKG

myst-cli

Version:
73 lines (72 loc) 2.87 kB
import path from 'node:path'; import fs from 'node:fs'; import { RuleId, fileError } from 'myst-common'; import { SourceFileKind } from 'myst-spec-ext'; import { includeDirectiveTransform } from 'myst-transforms'; import { watch } from '../store/reducers.js'; import { loadMdFile, loadNotebookFile, loadTexFile } from '../process/file.js'; import { getSourceFolder } from './links.js'; /** * Return resolveFile function * * If `sourceFile` is format .tex, `relativeFile` will be resolved relative to the * original baseFile; otherwise, it will be resolved relative to `sourceFile`. * * The returned function will resolve the file as described above, and return it if * it exists or log an error and return undefined otherwise. */ export const makeFileResolver = (baseFile) => (relativeFile, sourceFile, sourcePath, vfile) => { const base = sourceFile.toLowerCase().endsWith('.tex') ? baseFile : sourceFile; const sourceFolder = getSourceFolder(relativeFile, base, sourcePath); const fullFile = path.resolve(path.join(sourceFolder, relativeFile)); if (!fs.existsSync(fullFile)) { fileError(vfile, `Include Directive: Could not find "${relativeFile}" relative to "${base}"`, { ruleId: RuleId.includeContentLoads, }); return; } return fullFile; }; /** * Return loadFile function * * Loaded file is added to original baseFile's dependencies. */ export const makeFileLoader = (session, baseFile) => (fullFile) => { session.store.dispatch(watch.actions.addLocalDependency({ path: baseFile, dependency: fullFile, })); return fs.readFileSync(fullFile).toString(); }; /** * Return paresContent function * * Handles html and tex files separately; all other files are treated as MyST md. */ export const makeContentParser = (session, file) => async (filename, content) => { if (filename.toLowerCase().endsWith('.html')) { const mdast = { type: 'root', children: [{ type: 'html', value: content }] }; return { mdast, kind: SourceFileKind.Article }; } const opts = { keepTitleNode: true }; if (filename.toLowerCase().endsWith('.tex')) { return loadTexFile(session, content, file, opts); } if (filename.toLowerCase().endsWith('.ipynb')) { return loadNotebookFile(session, content, file, opts); } return loadMdFile(session, content, file, opts); }; export async function includeFilesTransform(session, baseFile, tree, frontmatter, vfile) { const parseContent = makeContentParser(session, baseFile); const loadFile = makeFileLoader(session, baseFile); const resolveFile = makeFileResolver(baseFile); await includeDirectiveTransform(tree, frontmatter, vfile, { resolveFile, loadFile, parseContent, sourceFile: baseFile, sourcePath: session.sourcePath(), }); }