Skip to content

Commit

Permalink
Automatically generate parser
Browse files Browse the repository at this point in the history
  • Loading branch information
alberti42 committed Aug 15, 2024
1 parent 41f90c1 commit 0e35b5b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 43 deletions.
15 changes: 15 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { QuestionPostponementList } from "./QuestionPostponementList";
import { TextDirection } from "./util/TextDirection";
import { convertToStringOrEmpty } from "./util/utils";
import { isEqualOrSubPath } from "./util/utils";
import { generateParser } from "./generateParser";

interface PluginData {
settings: SRSettings;
Expand Down Expand Up @@ -92,6 +93,8 @@ export default class SRPlugin extends Plugin {
private remainingDeckTree: Deck;
public cardStats: Stats;

private debouncedGenerateParserTimeout: number | null = null;

async onload(): Promise<void> {
await this.loadPluginData();
this.easeByPath = new NoteEaseList(this.data.settings);
Expand Down Expand Up @@ -811,6 +814,18 @@ export default class SRPlugin extends Plugin {
await this.saveData(this.data);
}

async debouncedGenerateParser(timeout_ms = 250) {

if (this.debouncedGenerateParserTimeout) {
clearTimeout(this.debouncedGenerateParserTimeout);
}

this.debouncedGenerateParserTimeout = window.setTimeout(async () => {
generateParser(this.data.settings);
this.debouncedGenerateParserTimeout = null;
}, timeout_ms);
}

private getActiveLeaf(type: string): WorkspaceLeaf | null {
const leaves = this.app.workspace.getLeavesOfType(type);
if (leaves.length == 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ export class ParsedQuestionInfo {
export function parseEx(
text: string,
settings: SRSettings,
force_parser_generation = false
): ParsedQuestionInfo[] {
// let cardText = "";
let cards: ParsedQuestionInfo[] = [];

if(parser === null) {
if(force_parser_generation || parser === null) {
generateParser(settings);
}

Expand Down
13 changes: 13 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ export class SRSettingTab extends PluginSettingTab {
.setValue(this.plugin.data.settings.convertHighlightsToClozes)
.onChange(async (value) => {
this.plugin.data.settings.convertHighlightsToClozes = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
}),
);
Expand All @@ -317,6 +318,7 @@ export class SRSettingTab extends PluginSettingTab {
.setValue(this.plugin.data.settings.convertBoldTextToClozes)
.onChange(async (value) => {
this.plugin.data.settings.convertBoldTextToClozes = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
}),
);
Expand All @@ -328,6 +330,7 @@ export class SRSettingTab extends PluginSettingTab {
.setValue(this.plugin.data.settings.convertCurlyBracketsToClozes)
.onChange(async (value) => {
this.plugin.data.settings.convertCurlyBracketsToClozes = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
}),
);
Expand All @@ -341,6 +344,7 @@ export class SRSettingTab extends PluginSettingTab {
.onChange((value) => {
applySettingsUpdate(async () => {
this.plugin.data.settings.singleLineCardSeparator = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
});
}),
Expand All @@ -352,6 +356,7 @@ export class SRSettingTab extends PluginSettingTab {
.onClick(async () => {
this.plugin.data.settings.singleLineCardSeparator =
DEFAULT_SETTINGS.singleLineCardSeparator;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
this.display();
});
Expand All @@ -366,6 +371,7 @@ export class SRSettingTab extends PluginSettingTab {
.onChange((value) => {
applySettingsUpdate(async () => {
this.plugin.data.settings.singleLineReversedCardSeparator = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
});
}),
Expand All @@ -377,6 +383,7 @@ export class SRSettingTab extends PluginSettingTab {
.onClick(async () => {
this.plugin.data.settings.singleLineReversedCardSeparator =
DEFAULT_SETTINGS.singleLineReversedCardSeparator;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
this.display();
});
Expand All @@ -391,6 +398,7 @@ export class SRSettingTab extends PluginSettingTab {
.onChange((value) => {
applySettingsUpdate(async () => {
this.plugin.data.settings.multilineCardSeparator = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
});
}),
Expand All @@ -402,6 +410,7 @@ export class SRSettingTab extends PluginSettingTab {
.onClick(async () => {
this.plugin.data.settings.multilineCardSeparator =
DEFAULT_SETTINGS.multilineCardSeparator;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
this.display();
});
Expand All @@ -416,6 +425,7 @@ export class SRSettingTab extends PluginSettingTab {
.onChange((value) => {
applySettingsUpdate(async () => {
this.plugin.data.settings.multilineReversedCardSeparator = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
});
}),
Expand All @@ -427,6 +437,7 @@ export class SRSettingTab extends PluginSettingTab {
.onClick(async () => {
this.plugin.data.settings.multilineReversedCardSeparator =
DEFAULT_SETTINGS.multilineReversedCardSeparator;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
this.display();
});
Expand All @@ -441,6 +452,7 @@ export class SRSettingTab extends PluginSettingTab {
.onChange((value) => {
applySettingsUpdate(async () => {
this.plugin.data.settings.multilineCardEndMarker = value;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
});
}),
Expand All @@ -452,6 +464,7 @@ export class SRSettingTab extends PluginSettingTab {
.onClick(async () => {
this.plugin.data.settings.multilineCardEndMarker =
DEFAULT_SETTINGS.multilineCardEndMarker;
this.plugin.debouncedGenerateParser();
await this.plugin.savePluginData();
this.display();
});
Expand Down
86 changes: 44 additions & 42 deletions tests/unit/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ const defaultSettings = { ...DEFAULT_SETTINGS,
function parse(
text: string,
settings: SRSettings,
force_parser_generation = false,
): [CardType, string, number, number][] {
const list: ParsedQuestionInfo[] = parseEx(
text,
settings,
force_parser_generation,
);
const result: [CardType, string, number, number][] = [];
for (const item of list) {
Expand All @@ -34,60 +36,60 @@ function parse(
}

test("Test parsing of single line basic cards", () => {
expect(parse("Question::Answer", defaultSettings)).toEqual([
expect(parse("Question::Answer", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "Question::Answer", 0, 0],
]);
expect(parse("Question::Answer\n<!--SR:!2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("Question::Answer\n<!--SR:!2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "Question::Answer\n<!--SR:!2021-08-11,4,270-->", 0, 1],
]);
expect(parse("Question::Answer <!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("Question::Answer <!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "Question::Answer <!--SR:2021-08-11,4,270-->", 0, 0],
]);
expect(parse("Some text before\nQuestion ::Answer", defaultSettings)).toEqual([
expect(parse("Some text before\nQuestion ::Answer", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "Question ::Answer", 1, 1],
]);
expect(parse("#Title\n\nQ1::A1\nQ2:: A2", defaultSettings)).toEqual([
expect(parse("#Title\n\nQ1::A1\nQ2:: A2", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "Q1::A1", 2, 2],
[CardType.SingleLineBasic, "Q2:: A2", 3, 3],
]);
expect(parse("#flashcards/science Question ::Answer", defaultSettings)).toEqual([
expect(parse("#flashcards/science Question ::Answer", defaultSettings, true)).toEqual([
[CardType.SingleLineBasic, "#flashcards/science Question ::Answer", 0, 0],
]);
});

test("Test parsing of single line reversed cards", () => {
expect(parse("Question:::Answer", defaultSettings)).toEqual([
expect(parse("Question:::Answer", defaultSettings, true)).toEqual([
[CardType.SingleLineReversed, "Question:::Answer", 0, 0],
]);
expect(parse("Some text before\nQuestion :::Answer", defaultSettings)).toEqual([
expect(parse("Some text before\nQuestion :::Answer", defaultSettings, true)).toEqual([
[CardType.SingleLineReversed, "Question :::Answer", 1, 1],
]);
expect(parse("#Title\n\nQ1:::A1\nQ2::: A2", defaultSettings)).toEqual([
expect(parse("#Title\n\nQ1:::A1\nQ2::: A2", defaultSettings, true)).toEqual([
[CardType.SingleLineReversed, "Q1:::A1", 2, 2],
[CardType.SingleLineReversed, "Q2::: A2", 3, 3],
]);
});

test("Test parsing of multi line basic cards", () => {
expect(parse("Question\n?\nAnswer", defaultSettings)).toEqual([
expect(parse("Question\n?\nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question\n?\nAnswer", 0, 2],
]);
expect(parse("Question\n? \nAnswer", defaultSettings)).toEqual([
expect(parse("Question\n? \nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question\n?\nAnswer", 0, 2],
]);
expect(parse("Question\n?\nAnswer <!--SR:!2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("Question\n?\nAnswer <!--SR:!2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question\n?\nAnswer <!--SR:!2021-08-11,4,270-->", 0, 2],
]);
expect(parse("Question\n?\nAnswer\n<!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("Question\n?\nAnswer\n<!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question\n?\nAnswer\n<!--SR:2021-08-11,4,270-->", 0, 3],
]);
expect(parse("Question line 1\nQuestion line 2\n?\nAnswer", defaultSettings)).toEqual([
expect(parse("Question line 1\nQuestion line 2\n?\nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question line 1\nQuestion line 2\n?\nAnswer", 0, 3],
]);
expect(parse("Question\n?\nAnswer line 1\nAnswer line 2", defaultSettings)).toEqual([
expect(parse("Question\n?\nAnswer line 1\nAnswer line 2", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "Question\n?\nAnswer line 1\nAnswer line 2", 0, 3],
]);
expect(parse("#Title\n\nLine0\nQ1\n?\nA1\nAnswerExtra\n\nQ2\n?\nA2", defaultSettings)).toEqual([
expect(parse("#Title\n\nLine0\nQ1\n?\nA1\nAnswerExtra\n\nQ2\n?\nA2", defaultSettings, true)).toEqual([
[
CardType.MultiLineBasic,
"Line0\nQ1\n?\nA1\nAnswerExtra",
Expand All @@ -96,22 +98,22 @@ test("Test parsing of multi line basic cards", () => {
],
[CardType.MultiLineBasic, "Q2\n?\nA2", 8, 10],
]);
expect(parse("#flashcards/tag-on-previous-line\nQuestion\n?\nAnswer", defaultSettings)).toEqual([
expect(parse("#flashcards/tag-on-previous-line\nQuestion\n?\nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineBasic, "#flashcards/tag-on-previous-line\nQuestion\n?\nAnswer", 0, 3],
]);
});

test("Test parsing of multi line reversed cards", () => {
expect(parse("Question\n??\nAnswer", defaultSettings)).toEqual([
expect(parse("Question\n??\nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineReversed, "Question\n??\nAnswer", 0, 2],
]);
expect(parse("Question line 1\nQuestion line 2\n??\nAnswer", defaultSettings)).toEqual([
expect(parse("Question line 1\nQuestion line 2\n??\nAnswer", defaultSettings, true)).toEqual([
[CardType.MultiLineReversed, "Question line 1\nQuestion line 2\n??\nAnswer", 0, 3],
]);
expect(parse("Question\n??\nAnswer line 1\nAnswer line 2", defaultSettings)).toEqual([
expect(parse("Question\n??\nAnswer line 1\nAnswer line 2", defaultSettings, true)).toEqual([
[CardType.MultiLineReversed, "Question\n??\nAnswer line 1\nAnswer line 2", 0, 3],
]);
expect(parse("#Title\n\nLine0\nQ1\n??\nA1\nAnswerExtra\n\nQ2\n??\nA2", defaultSettings)).toEqual(
expect(parse("#Title\n\nLine0\nQ1\n??\nA1\nAnswerExtra\n\nQ2\n??\nA2", defaultSettings, true)).toEqual(
[
[
CardType.MultiLineReversed,
Expand All @@ -126,16 +128,16 @@ test("Test parsing of multi line reversed cards", () => {

test("Test parsing of cloze cards", () => {
// ==highlights==
expect(parse("cloze ==deletion== test", defaultSettings)).toEqual([
expect(parse("cloze ==deletion== test", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze ==deletion== test", 0, 0],
]);
expect(parse("cloze ==deletion== test\n<!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("cloze ==deletion== test\n<!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze ==deletion== test\n<!--SR:2021-08-11,4,270-->", 0, 1],
]);
expect(parse("cloze ==deletion== test <!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("cloze ==deletion== test <!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze ==deletion== test <!--SR:2021-08-11,4,270-->", 0, 0],
]);
expect(parse("==this== is a ==deletion==\n", defaultSettings)).toEqual([
expect(parse("==this== is a ==deletion==\n", defaultSettings, true)).toEqual([
[CardType.Cloze, "==this== is a ==deletion==", 0, 0],
]);
expect(
Expand All @@ -148,9 +150,9 @@ test("Test parsing of cloze cards", () => {
[CardType.Cloze, "a deletion on\nsuch ==wow==", 2, 3],
[CardType.Cloze, "many text\nsuch surprise ==wow== more ==text==\nsome text after", 5, 7],
]);
expect(parse("srdf ==", defaultSettings)).toEqual([]);
expect(parse("lorem ipsum ==p\ndolor won==", defaultSettings)).toEqual([]);
expect(parse("lorem ipsum ==dolor won=", defaultSettings)).toEqual([]);
expect(parse("srdf ==", defaultSettings, true)).toEqual([]);
expect(parse("lorem ipsum ==p\ndolor won==", defaultSettings, true)).toEqual([]);
expect(parse("lorem ipsum ==dolor won=", defaultSettings, true)).toEqual([]);
// ==highlights== turned off
expect(parse("cloze ==deletion== test",
{ ...DEFAULT_SETTINGS,
Expand All @@ -162,21 +164,21 @@ test("Test parsing of cloze cards", () => {
convertHighlightsToClozes: false,
convertBoldTextToClozes: true,
convertCurlyBracketsToClozes: false,
})).toEqual(
},true)).toEqual(
[],
);

// **bolded**
expect(parse("cloze **deletion** test", defaultSettings)).toEqual([
expect(parse("cloze **deletion** test", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze **deletion** test", 0, 0],
]);
expect(parse("cloze **deletion** test\n<!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("cloze **deletion** test\n<!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze **deletion** test\n<!--SR:2021-08-11,4,270-->", 0, 1],
]);
expect(parse("cloze **deletion** test <!--SR:2021-08-11,4,270-->", defaultSettings)).toEqual([
expect(parse("cloze **deletion** test <!--SR:2021-08-11,4,270-->", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze **deletion** test <!--SR:2021-08-11,4,270-->", 0, 0],
]);
expect(parse("**this** is a **deletion**\n", defaultSettings)).toEqual([
expect(parse("**this** is a **deletion**\n", defaultSettings, true)).toEqual([
[CardType.Cloze, "**this** is a **deletion**", 0, 0],
]);
expect(
Expand All @@ -189,9 +191,9 @@ test("Test parsing of cloze cards", () => {
[CardType.Cloze, "a deletion on\nsuch **wow**", 2, 3],
[CardType.Cloze, "many text\nsuch surprise **wow** more **text**\nsome text after", 5, 7],
]);
expect(parse("srdf **", defaultSettings)).toEqual([]);
expect(parse("lorem ipsum **p\ndolor won**", defaultSettings)).toEqual([]);
expect(parse("lorem ipsum **dolor won*", defaultSettings)).toEqual([]);
expect(parse("srdf **", defaultSettings, true)).toEqual([]);
expect(parse("lorem ipsum **p\ndolor won**", defaultSettings, true)).toEqual([]);
expect(parse("lorem ipsum **dolor won*", defaultSettings, true)).toEqual([]);
// **bolded** turned off
expect(parse("cloze **deletion** test", { ...DEFAULT_SETTINGS,
singleLineCardSeparator: "::",
Expand All @@ -202,12 +204,12 @@ test("Test parsing of cloze cards", () => {
convertHighlightsToClozes: true,
convertBoldTextToClozes: false,
convertCurlyBracketsToClozes: false,
})).toEqual(
},true)).toEqual(
[],
);

// both
expect(parse("cloze **deletion** test ==another deletion==!", defaultSettings)).toEqual([
expect(parse("cloze **deletion** test ==another deletion==!", defaultSettings, true)).toEqual([
[CardType.Cloze, "cloze **deletion** test ==another deletion==!", 0, 0],
]);
});
Expand Down Expand Up @@ -311,14 +313,14 @@ test("Test codeblocks", () => {

test("Test not parsing cards in HTML comments", () => {
expect(
parse("<!--\nQuestion\n?\nAnswer <!--SR:!2021-08-11,4,270-->\n-->", defaultSettings),
parse("<!--\nQuestion\n?\nAnswer <!--SR:!2021-08-11,4,270-->\n-->", defaultSettings, true),
).toEqual([]);
expect(
parse(
"<!--\nQuestion\n?\nAnswer <!--SR:!2021-08-11,4,270-->\n\n<!--cloze ==deletion== test-->-->",
defaultSettings,
),
).toEqual([]);
expect(parse("<!--cloze ==deletion== test-->", defaultSettings)).toEqual([]);
expect(parse("<!--cloze **deletion** test-->", defaultSettings)).toEqual([]);
expect(parse("<!--cloze ==deletion== test-->", defaultSettings, true)).toEqual([]);
expect(parse("<!--cloze **deletion** test-->", defaultSettings, true)).toEqual([]);
});

0 comments on commit 0e35b5b

Please sign in to comment.