70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import * as marked from "npm:marked";
|
|
|
|
if (!Deno.args[0]) throw new Error("needs a file as cli arg");
|
|
|
|
const filename = Deno.args[0];
|
|
const input = Deno.readTextFileSync(filename);
|
|
const rendered = marked.lexer(input).map(renderBlock).filter(i => i);
|
|
console.log(JSON.stringify({ doc: rendered, name: filename }));
|
|
// console.log(rendered);
|
|
|
|
interface Token {
|
|
type: string,
|
|
text: string,
|
|
tokens?: Array<Token>,
|
|
[key: string]: any,
|
|
}
|
|
|
|
function renderBlock(token: Token): any {
|
|
switch (token.type) {
|
|
case "paragraph": {
|
|
return renderInline(token);
|
|
}
|
|
case "heading": {
|
|
return { type: "header", level: token.depth, content: renderInline(token) };
|
|
}
|
|
case "list": {
|
|
return {
|
|
type: token.ordered ? "ol" : "ul",
|
|
items: token.items.map(i => {
|
|
if (i.tokens.length === 1) renderBlock(i.tokens[0]);
|
|
return i.tokens.map(renderBlock);
|
|
}),
|
|
};
|
|
}
|
|
case "code": {
|
|
return {
|
|
type: "code",
|
|
lang: token.lang,
|
|
content: renderInline(token),
|
|
};
|
|
}
|
|
case "space": {
|
|
return null;
|
|
}
|
|
case "text": {
|
|
return renderInline(token);
|
|
}
|
|
case "table": {
|
|
return {
|
|
type: "table",
|
|
headers: token.header.map(renderInline),
|
|
rows: token.rows.map(row => row.map(renderInline)),
|
|
}
|
|
}
|
|
default: {
|
|
return token;
|
|
}
|
|
}
|
|
}
|
|
|
|
function renderInline(token: Token): string {
|
|
const text = token.tokens ? token.tokens.map(renderInline).join("") : token.text;
|
|
switch (token.type) {
|
|
case "em": return `~italic{${text}}`;
|
|
case "strong": return `~bold{${text}}`;
|
|
case "link": return `~link{${text}}{${token.href}}`;
|
|
case "codespan": return `~code{${text}}`;
|
|
default: return `${text}`;
|
|
}
|
|
}
|