UNPKG

@docusaurus/core

Version:

Easy to Maintain Open Source Documentation Websites

84 lines (83 loc) 3.92 kB
"use strict"; /** * 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.`; } }