@docusaurus/core
Version:
Easy to Maintain Open Source Documentation Websites
84 lines (83 loc) • 3.92 kB
JavaScript
;
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeHeadingIds = writeHeadingIds;
const tslib_1 = require("tslib");
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
const utils_1 = require("@docusaurus/utils");
const site_1 = require("../server/site");
const init_1 = require("../server/plugins/init");
function inferFallbackSyntax(_filepath) {
// TODO Docusaurus v4 - infer the syntax based on the file extensions?
// This is not ideal because we have many ways to define the syntax
// (front matter "format", siteConfig.markdown.format etc...)
// but probably good enough for now
// Until then, we default to the classic syntax
// The mdx-comment syntax is opt-in
return 'classic';
}
function getHeadingIdSyntax(filepath, options) {
return options?.syntax ?? inferFallbackSyntax(filepath);
}
async function transformMarkdownFile(filepath, options) {
const content = await fs_extra_1.default.readFile(filepath, 'utf8');
const syntax = getHeadingIdSyntax(filepath, options);
const updatedContent = (0, utils_1.writeMarkdownHeadingId)(content, {
...options,
syntax,
});
if (content !== updatedContent) {
await fs_extra_1.default.writeFile(filepath, updatedContent);
return filepath;
}
return undefined;
}
/**
* We only handle the "paths to watch" because these are the paths where the
* markdown files are. Also we don't want to transform the site md docs that do
* not belong to a content plugin. For example ./README.md should not be
* transformed
*/
async function getPathsToWatch(siteDir) {
const context = await (0, site_1.loadContext)({ siteDir });
const plugins = await (0, init_1.initPlugins)(context);
return plugins.flatMap((plugin) => plugin.getPathsToWatch?.() ?? []);
}
// TODO Docusaurus v4 - Upgrade commander, use choices() API?
function validateOptions(options) {
const validSyntaxValues = ['classic', 'mdx-comment'];
if (options.syntax && !validSyntaxValues.includes(options.syntax)) {
throw new Error(`Invalid --syntax value "${options.syntax}". Valid values: ${validSyntaxValues.join(', ')}`);
}
if (options.overwrite && options.migrate) {
throw new Error("Options --overwrite and --migrate cannot be used together.\nThe --overwrite already re-generates IDs in the target syntax, so the --migrate option wouldn't have any effect.");
}
}
async function writeHeadingIds(siteDirParam = '.', files = [], options = {}) {
validateOptions(options);
const siteDir = await fs_extra_1.default.realpath(siteDirParam);
const patterns = files.length ? files : await getPathsToWatch(siteDir);
const markdownFiles = await (0, utils_1.safeGlobby)(patterns, {
expandDirectories: ['**/*.{md,mdx}'],
});
if (markdownFiles.length === 0) {
logger_1.default.warn `No markdown files found in siteDir path=${siteDir} for patterns: ${patterns}`;
return;
}
const result = await Promise.all(markdownFiles.map((p) => transformMarkdownFile(p, options)));
const pathsModified = result.filter(Boolean);
if (pathsModified.length) {
logger_1.default.success `Heading ids added to Markdown files (number=${`${pathsModified.length}/${markdownFiles.length}`} files): ${pathsModified}`;
}
else {
logger_1.default.warn `number=${markdownFiles.length} Markdown files already have explicit heading IDs.
If you intend to overwrite the existing heading IDs, use the code=${'--overwrite'} option.
If you intend to change their heading ID syntax, use the code=${'--migrate'} option.`;
}
}