myst-cli
Version:
Command line tools for MyST
101 lines (100 loc) • 4.38 kB
JavaScript
import { getFrontmatter } from 'myst-transforms';
import { validateExportsList, fillPageFrontmatter, simplifyLicenses, unnestKernelSpec, validatePageFrontmatter, } from 'myst-frontmatter';
import { fileError, fileWarn, normalizeLabel, RuleId } from 'myst-common';
import { VFile } from 'vfile';
import { selectors, watch } from './store/index.js';
import { logMessagesFromVFile } from './utils/logging.js';
import { castSession } from './session/cache.js';
export function frontmatterValidationOpts(vfile, opts) {
return {
property: opts?.property ?? 'frontmatter',
file: vfile.path,
messages: {},
errorLogFn: (message) => {
fileError(vfile, message, { ruleId: opts?.ruleId ?? RuleId.validPageFrontmatter });
},
warningLogFn: (message) => {
fileWarn(vfile, message, { ruleId: opts?.ruleId ?? RuleId.validPageFrontmatter });
},
};
}
/**
* Get page frontmatter from mdast tree
*
* @param session
* @param tree - mdast tree already loaded
* @param vfile - vfile used for logging
* @param preFrontmatter - incoming frontmatter for the page that is not from the project or in the tree
* @param keepTitleNode - do not remove leading H1 even if it is lifted as title
*/
export function getPageFrontmatter(session, tree, vfile, preFrontmatter, keepTitleNode) {
const { frontmatter: rawPageFrontmatter, identifiers } = getFrontmatter(vfile, tree, {
propagateTargets: true,
preFrontmatter,
keepTitleNode,
});
unnestKernelSpec(rawPageFrontmatter);
const pageFrontmatter = validatePageFrontmatter(rawPageFrontmatter, frontmatterValidationOpts(vfile));
if (pageFrontmatter.label) {
const { identifier } = normalizeLabel(pageFrontmatter.label) ?? {};
if (identifier)
identifiers.push(identifier);
}
logMessagesFromVFile(session, vfile);
return { frontmatter: pageFrontmatter, identifiers };
}
export function processPageFrontmatter(session, pageFrontmatter, validationOpts, path) {
const cache = castSession(session);
const state = session.store.getState();
const siteFrontmatter = selectors.selectCurrentSiteConfig(state) ?? {};
const projectFrontmatter = path ? (selectors.selectLocalProjectConfig(state, path) ?? {}) : {};
const frontmatter = fillPageFrontmatter(pageFrontmatter, projectFrontmatter, validationOpts);
const siteTemplate = cache.$siteTemplate;
if (siteTemplate) {
const siteOptions = siteTemplate.validateOptions(pageFrontmatter.site ?? {}, path, {
// The property is different on the page vs the myst.yml
property: 'site',
// Passing in the log files ensures this isn't prefixed with `myst.yml`.
warningLogFn: session.log.warn,
errorLogFn: session.log.error,
});
if (siteOptions && Object.keys(siteOptions).length > 0)
frontmatter.site = siteOptions;
}
else {
// The options are still there, they are just not validated
session.log.debug(`Site template not available to validate site frontmatter in ${path}`);
}
return frontmatter;
}
export function prepareToWrite(frontmatter) {
if (!frontmatter.license)
return { ...frontmatter };
return { ...frontmatter, license: simplifyLicenses(frontmatter.license) };
}
export function getExportListFromRawFrontmatter(session, rawFrontmatter, file) {
const vfile = new VFile();
vfile.path = file;
const exports = validateExportsList(rawFrontmatter?.exports ?? rawFrontmatter?.export, frontmatterValidationOpts(vfile, {
property: 'exports',
ruleId: RuleId.validFrontmatterExportList,
}));
logMessagesFromVFile(session, vfile);
return exports ?? [];
}
export function updateFileInfoFromFrontmatter(session, file, frontmatter, url, dataUrl) {
session.store.dispatch(watch.actions.updateFileInfo({
path: file,
title: frontmatter.title,
short_title: frontmatter.short_title,
description: frontmatter.description,
date: frontmatter.date,
thumbnail: frontmatter.thumbnail,
thumbnailOptimized: frontmatter.thumbnailOptimized,
banner: frontmatter.banner,
bannerOptimized: frontmatter.bannerOptimized,
tags: frontmatter.tags,
url,
dataUrl,
}));
}