diff --git a/package-lock.json b/package-lock.json index c592d13..092d623 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14810,8 +14810,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -21387,6 +21386,16 @@ } } }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/package.json b/package.json index 2050bc8..d66075a 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,11 @@ "type": "boolean", "default": true, "description": "When you run 'Send To Deck' the title (h1) of the markdown file is stored as a tag. This is useful if you have 'daily' notes, you can use the same deck but separate cards by title" + }, + "anki.md.card.notecardIdPattern": { + "type": "string", + "default": "", + "description": "Text to match match the commented notecard ID." } } } diff --git a/src/markdown/parsers/__tests__/cardParser.test.ts b/src/markdown/parsers/__tests__/cardParser.test.ts index c30c7f4..f0c4d20 100644 --- a/src/markdown/parsers/__tests__/cardParser.test.ts +++ b/src/markdown/parsers/__tests__/cardParser.test.ts @@ -9,7 +9,7 @@ describe("CardParser", () => { afterAll(() => { jest.resetAllMocks(); }); - describe("Good Input", () => { + describe("Good Input", () => { it("constructs without erroring", () => { assert.doesNotThrow(() => { new CardParser(); @@ -71,6 +71,17 @@ describe("CardParser", () => { expect(card.tags).toContain("myTag"); }); + + // Should parse the note ID properly + it("should parse the note ID properly", async () => { + const input = + "## Some text that should be on the front\n\n\nThis text will be on the back\n\n[#myTag]()"; + const parser = new CardParser(); + const card = await parser.parse(input); + + expect(card.noteId).toBe(123); + expect(card.answer).toBe("

This text will be on the back

\n"); + }); }); describe("Bad Input", () => { diff --git a/src/markdown/parsers/cardParser.ts b/src/markdown/parsers/cardParser.ts index 565b146..0e4c594 100644 --- a/src/markdown/parsers/cardParser.ts +++ b/src/markdown/parsers/cardParser.ts @@ -10,6 +10,7 @@ interface ParsedCardLine { back: string[]; tags: string[]; isCloze: boolean; + noteId: number; } /** @@ -20,6 +21,7 @@ export class CardParser extends BaseParser { private splitRe: RegExp; private tagRe: RegExp; private clozeRe: RegExp; + private noteIdRe: RegExp; constructor({ convertToHtml = true, convertMath = true } = {}) { super({ convertToHtml, convertMath }); @@ -29,6 +31,9 @@ export class CardParser extends BaseParser { ); this.tagRe = new RegExp(this.getConfig("card.tagPattern") as string); this.clozeRe = new RegExp("{{c\\w+::"); + this.noteIdRe = new RegExp( + "" + ); } /** @@ -42,10 +47,11 @@ export class CardParser extends BaseParser { .map((item) => item.split("\n")) .map((arr) => arr.map((str) => str.trimRight())); - const { front, back, tags, isCloze } = this.parseCardLines(cardLines); + const { front, back, tags, isCloze, noteId } = + this.parseCardLines(cardLines); if (!this.options.convertToHtml) { - return new Card(front.join(), back.join(), tags); + return new Card(front.join(), back.join(), tags, noteId); } // If card is a Cloze card we need to use a different note type @@ -54,6 +60,7 @@ export class CardParser extends BaseParser { front.join().replace("## ", ""), back.join(), tags, + noteId, "Cloze" ); } @@ -61,13 +68,14 @@ export class CardParser extends BaseParser { const frontHtml = await this.linesToHtml(front); const backHtml = await this.linesToHtml(back); - return new Card(frontHtml, backHtml, tags); + return new Card(frontHtml, backHtml, tags, noteId); } private parseCardLines(cardLines: string[][]): ParsedCardLine { const front: string[] = []; const back: string[] = []; const tags: string[] = []; + let noteId = 0; let isCloze = false; const fillBackAndTags = (line: string) => { @@ -77,6 +85,15 @@ export class CardParser extends BaseParser { return; } + // set note ID + if (this.noteIdRe.test(line)) { + let match = line.match(this.noteIdRe); + if (match && match.length == 2) { + noteId = parseInt(match[1]); + return; + } + } + // set back // skip first blank lines if (back.length === 0 && !line) { @@ -112,6 +129,7 @@ export class CardParser extends BaseParser { back: trimArray(back), tags: trimArray(tags), isCloze, + noteId, }; } diff --git a/src/models/Card.ts b/src/models/Card.ts index e8fccd6..a6da033 100644 --- a/src/models/Card.ts +++ b/src/models/Card.ts @@ -16,12 +16,14 @@ export class Card { question: string, answer: string, tags: string[] = [], + noteId: number = 0, model: string = CONSTANTS.defaultTemplateName ) { this.question = question; this.answer = answer; this.tags = tags; this.modelName = model; + this.noteId = noteId // The fields need to match the template, cloze has different fields if (this.modelName === CONSTANTS.defaultTemplateName) {