Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse nodeIDs #92

Merged
merged 2 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<!--\\s*?notecardId\\s*?\\[:=\\]\\s*?(\\d+)\\s*?-->",
"description": "Text to match match the commented notecard ID."
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this to be configurable? I have a feeling if people change this it could become messy.
I'd start off with it being hardcoded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, yes I guess it could result in lots of questions/mis-configured regexes (and thus lots of github issues).

I'm going making this value just exist in code, I'll add it to a constants file if there is one, or just leave it by the parsing logic if there isn't.

}
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/markdown/parsers/__tests__/cardParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe("CardParser", () => {
afterAll(() => {
jest.resetAllMocks();
});
describe("Good Input", () => {
describe("Good Input", () => {
it("constructs without erroring", () => {
assert.doesNotThrow(() => {
new CardParser();
Expand Down Expand Up @@ -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<!-- notecardId: 123 -->\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("<p>This text will be on the back</p>\n");
});
});

describe("Bad Input", () => {
Expand Down
24 changes: 21 additions & 3 deletions src/markdown/parsers/cardParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface ParsedCardLine {
back: string[];
tags: string[];
isCloze: boolean;
noteId: number;
}

/**
Expand All @@ -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 });
Expand All @@ -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(
"<!--\\s*?notecardId\\s*?[:=]\\s*?(\\d+)\\s*?-->"
);
}

/**
Expand All @@ -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
Expand All @@ -54,20 +60,22 @@ export class CardParser extends BaseParser {
front.join().replace("## ", ""),
back.join(),
tags,
noteId,
"Cloze"
);
}

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) => {
Expand All @@ -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) {
Expand Down Expand Up @@ -112,6 +129,7 @@ export class CardParser extends BaseParser {
back: trimArray(back),
tags: trimArray(tags),
isCloze,
noteId,
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/models/Card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down