mirror of https://github.com/lukechilds/docs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.1 KiB
55 lines
2.1 KiB
const path = require('path');
|
|
const remark = require('remark');
|
|
const flatMap = require('unist-util-flatmap');
|
|
const { readSync } = require('to-vfile');
|
|
|
|
module.exports = function includeMarkdownPlugin({ resolveFrom } = {}) {
|
|
return function transformer(tree, file) {
|
|
return flatMap(tree, node => {
|
|
if (node.type !== 'paragraph') return [node];
|
|
|
|
// detect an `@include` statement
|
|
const includeMatch =
|
|
node.children[0].value && node.children[0].value.match(/^@include\s['"](.*)['"]$/);
|
|
if (!includeMatch) return [node];
|
|
|
|
// read the file contents
|
|
const includePath = path.join(resolveFrom || file.dirname, includeMatch[1]);
|
|
let includeContents;
|
|
try {
|
|
includeContents = readSync(includePath, 'utf8');
|
|
} catch (err) {
|
|
console.log(err);
|
|
throw new Error(
|
|
`The @include file path at ${includePath} was not found.\n\nInclude Location: ${file.path}:${node.position.start.line}:${node.position.start.column}`
|
|
);
|
|
}
|
|
|
|
const mdregex = /\.md(?:x)?$/;
|
|
// if we are including a ".md" or ".mdx" file, we add the contents as processed markdown
|
|
// if any other file type, they are embedded into a code block
|
|
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
|
if (includePath.match(mdregex)) {
|
|
// return the file contents in place of the @include
|
|
// this takes a couple steps because we allow recursive includes
|
|
const processor = remark().use(includeMarkdownPlugin, { resolveFrom });
|
|
const ast = processor.parse(includeContents);
|
|
return processor.runSync(ast, includeContents).children;
|
|
} else {
|
|
// trim trailing newline
|
|
includeContents.contents = includeContents.contents.trim();
|
|
|
|
const codecheckregex = /\.(\w+)$/;
|
|
// return contents wrapped inside a "code" node
|
|
return [
|
|
{
|
|
type: 'code',
|
|
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
|
lang: includePath.match(codecheckregex)[1],
|
|
value: includeContents,
|
|
},
|
|
];
|
|
}
|
|
});
|
|
};
|
|
};
|
|
|