UNPKG

@autoanki/plugin-source-markdown

Version:

Extract Anki cards from Markdown files

76 lines (75 loc) 3.2 kB
import { unified } from 'unified'; import remarkParse from 'remark-parse'; import remarkStringify from 'remark-stringify'; import { visit } from 'unist-util-visit'; import yamlPlugin from '@autoanki/plugin-source-yaml'; const mdProcessor = unified().use(remarkParse); const mdStringifyProcessor = unified().use(remarkStringify); const encoder = new TextEncoder(); const decoder = new TextDecoder('utf8'); export class MarkdownSourcePlugin { async writeBackToInput(inputKey, originalInputContent, notes) { const thisFileCache = this.markdownParseCache[inputKey]; const notesPerYamlBlock = notes.reduce((group, note)=>{ const metadata = note.metadata; (group[metadata.index] = group[metadata.index] || []).push(note); return group; }, {}); const modifiedMarkdownBlocks = await Promise.all(Object.entries(notesPerYamlBlock).map(async ([i, notesOfThisYamlBlock])=>{ const ithBlock = Number.parseInt(i, 10); const newContent = await this.yamlPlugin.writeBackToInput(`${inputKey}-${i}`, encoder.encode(thisFileCache.yamlBlocks[ithBlock].value), notesOfThisYamlBlock.map((note)=>{ return { note: note.note, metadata: note.metadata.yamlMetadata }; })); return { ithBlock, newContent }; })); for (const block of modifiedMarkdownBlocks){ thisFileCache.yamlBlocks[block.ithBlock].value = decoder.decode(block.newContent); } return encoder.encode(mdStringifyProcessor.stringify(thisFileCache.ast)); } async parseFromInput(inputKey, inputContent) { const enc = new TextDecoder('utf8'); const input = enc.decode(inputContent); if (!this.markdownParseCache[inputKey]) { this.markdownParseCache[inputKey] = { ast: mdProcessor.parse(input), yamlBlocks: [] }; visit(this.markdownParseCache[inputKey].ast, 'code', (node, _)=>{ if (node.lang === 'autoanki') { this.markdownParseCache[inputKey].yamlBlocks.push(node); } }); const result = await Promise.all(this.markdownParseCache[inputKey].yamlBlocks.map((yaml, i)=>{ return this.yamlPlugin.parseFromInput(`${inputKey}-${i}`, encoder.encode(yaml.value)); })); return result.flatMap((outputs, ithYamlBlock)=>{ return outputs.map((output)=>{ return { note: output.note, metadata: { index: ithYamlBlock, yamlMetadata: output.metadata } }; }); }); } return []; } constructor(api){ this.markdownParseCache = {}; this.yamlPlugin = new yamlPlugin.source(api); } } MarkdownSourcePlugin.pluginName = '@autoanki/plugin-source-markdown'; export default { source: MarkdownSourcePlugin }; //# sourceMappingURL=index.js.map