@autoanki/plugin-source-markdown
Version:
Extract Anki cards from Markdown files
76 lines (75 loc) • 3.2 kB
JavaScript
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