@brngdsn/unmd
Version:
A CLI tool to unpack code fences from Markdown into files.
68 lines (53 loc) • 1.89 kB
JavaScript
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import MarkdownIt from 'markdown-it';
async function main() {
const [,, ...args] = process.argv;
if (args.length < 1) {
console.error("Usage: unmd <markdown-file>");
process.exit(1);
}
const markdownFile = args[0];
let mdContent;
try {
mdContent = await readFile(markdownFile, 'utf8');
} catch (err) {
console.error(`Error reading file "${markdownFile}": ${err.message}`);
process.exit(1);
}
const mdParser = new MarkdownIt();
const tokens = mdParser.parse(mdContent, {});
for (const token of tokens) {
// We're only interested in fenced code blocks
if (token.type === 'fence') {
const fenceContent = token.content.trimEnd();
// Split by new lines
const lines = fenceContent.split('\n');
if (lines.length === 0) continue;
// We expect the first line to contain the file path in a comment, e.g. "// src/index.js"
const firstLine = lines[0].trim();
if (!firstLine.startsWith('// ')) continue;
// Extract the file path from that comment
const filePath = firstLine.replace('// ', '').trim();
// The rest of the lines after the first line is our actual code
const code = lines.slice(1).join('\n');
try {
const fullPath = path.join(process.cwd(), filePath);
await mkdir(path.dirname(fullPath), { recursive: true });
await writeFile(fullPath, code, 'utf8');
console.log(`Created file: ${fullPath}`);
} catch (err) {
console.error(`Error writing file "${filePath}": ${err.message}`);
}
}
}
}
try {
// Top-level await is allowed in ES2024 / Node.js v20.8.0 with "type":"module"
await main();
} catch (err) {
console.error(err);
process.exit(1);
}