mirror of
https://github.com/jj-vcs/jj.git
synced 2026-07-03 14:02:54 +08:00
This change adds a new docs deployment to /starlight/, and that's rendering the documentation via Starlight: https://starlight.astro.build/ mkdocs is no longer being maintained, and we'd like to move away from it for that reason. We've chosen starlight for two main reasons: first, it has a goal of minimizing JavaScript on the front end, and that aligns with our priorities. Second, it is based on Astro.js, which would also be a good tool for writing a basic marketing site. The overall sentiment from community in the Discord was leaning towards Astro when we were talking about this. After a few days of checking out the new docs and making sure that things are good, we can move to making this the default. Part of #7959.
82 lines
2.5 KiB
JavaScript
82 lines
2.5 KiB
JavaScript
/**
|
|
* Remark plugin to include markdown from external files.
|
|
*
|
|
* Usage in markdown:
|
|
* ::include{file="../path/to/file.md" start="<!-- BEGIN MARKDOWN-->"}
|
|
*
|
|
* Options:
|
|
* - file: Path to the file to include (relative to the markdown file)
|
|
* - start: Optional marker to start including from (content after this marker)
|
|
* - end: Optional marker to stop including at (content before this marker)
|
|
*/
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { visit } from 'unist-util-visit';
|
|
import { fromMarkdown } from 'mdast-util-from-markdown';
|
|
import { gfm } from 'micromark-extension-gfm';
|
|
import { gfmFromMarkdown } from 'mdast-util-gfm';
|
|
|
|
export default function remarkIncludeMarkdown(options = {}) {
|
|
const { basePath = process.cwd() } = options;
|
|
|
|
return (tree, file) => {
|
|
const includes = [];
|
|
|
|
// Find all ::include directives
|
|
visit(tree, 'leafDirective', (node, index, parent) => {
|
|
if (node.name !== 'include') return;
|
|
|
|
const filePath = node.attributes?.file;
|
|
if (!filePath) {
|
|
console.warn('::include directive missing "file" attribute');
|
|
return;
|
|
}
|
|
|
|
// Resolve the file path relative to the docs directory
|
|
const resolvedPath = path.resolve(basePath, filePath);
|
|
|
|
if (!fs.existsSync(resolvedPath)) {
|
|
console.warn(`Include file not found: ${resolvedPath}`);
|
|
return;
|
|
}
|
|
|
|
let content = fs.readFileSync(resolvedPath, 'utf-8');
|
|
|
|
// Handle start marker
|
|
const startMarker = node.attributes?.start;
|
|
if (startMarker) {
|
|
const startIndex = content.indexOf(startMarker);
|
|
if (startIndex !== -1) {
|
|
content = content.slice(startIndex + startMarker.length);
|
|
}
|
|
}
|
|
|
|
// Handle end marker
|
|
const endMarker = node.attributes?.end;
|
|
if (endMarker) {
|
|
const endIndex = content.indexOf(endMarker);
|
|
if (endIndex !== -1) {
|
|
content = content.slice(0, endIndex);
|
|
}
|
|
}
|
|
|
|
content = content.trim();
|
|
|
|
// Parse the included markdown into AST nodes with GFM support
|
|
const includedTree = fromMarkdown(content, {
|
|
extensions: [gfm()],
|
|
mdastExtensions: [gfmFromMarkdown()],
|
|
});
|
|
|
|
// Store for later replacement (can't modify during visit)
|
|
includes.push({ index, parent, nodes: includedTree.children });
|
|
});
|
|
|
|
// Replace directives with included content (in reverse to maintain indices)
|
|
for (const { index, parent, nodes } of includes.reverse()) {
|
|
parent.children.splice(index, 1, ...nodes);
|
|
}
|
|
};
|
|
}
|