mod.tsimport {
CodeBlock,
Line,
Node,
parse,
Table,
} from "../scrapbox-parser/mod.ts";
export const convert = (text: string): string => {
const blocks = parse(text, { hasTitle: false });
return blocks.flatMap((block) => {
switch (block.type) {
case "title":
return [];
case "codeBlock":
return convertCodeBlock(block);
case "table":
return convertTable(block);
case "line":
return convertLine(block);
}
})
.map((line) => line).join("\n");
};
const convertCodeBlock = (
{ fileName, content, indent }: CodeBlock,
) => {
const tag = " ".repeat(indent);
return [
`${tag}code:${fileName}`,
...content.split("\n").map((line) => `${tag} ${line}`),
];
};
const convertTable = ({ fileName, cells, indent }: Table) => {
const tag = " ".repeat(indent);
return [
`${tag}table:${fileName}`,
...cells.map((cell) =>
`${tag} ${
cell.map((nodes) => nodes.map((node) => node.raw).join("")).join("\t")
}`
),
];
};
const convertLine = ({ nodes, indent }: Line) => [
`${" ".repeat(indent)}${
nodes.map((node) => `${convertNode(node)}`).join(
"",
)
}`,
];
const convertNode = (node: Node): string => {
switch (node.type) {
case "quote":
return `> ${node.nodes.map((node) => convertNode(node)).join("")}`;
case "helpfeel":
return `[-? ${node.text}]`;
case "commandLine":
return `[-${node.symbol} ${node.text}]`;
case "icon":
case "strongIcon":
case "image":
case "strongImage":
case "formula":
case "code":
case "googleMap":
return node.raw;
case "strong":
return `[[${node.nodes.map((node) => convertNode(node)).join("")}]]`;
case "decoration": {
if (!node.decos.includes("-")) node.decos.push("-");
const deco = node.decos.map((deco) => {
const num = parseInt(deco.match(/\*-(\d)/)?.[1] ?? "0");
return num > 0 ? "*".repeat(num) : deco;
}).join("");
return `[${deco ? `${deco} ` : ""}${
node.nodes.map((node) => convertNode(node)).join("")
}]`;
}
// linterのバグで、何故か警告が出る
// deno-lint-ignore no-fallthrough
case "link": {
switch (node.pathType) {
case "root":
case "relative":
return `[- [${node.href}]]`;
case "absolute":
return `[- ${node.content ? `${node.content} ` : ""}${node.href}]]`;
}
}
case "hashTag":
return `[- #${node.href}]`;
case "numberList":
return `${node.number}. ${node.nodes.map((node) => convertNode(node)).join("")}`;
case "blank":
case "plain":
return `[- ${node.text}]`;
}
};