mirror of
https://github.com/gosticks/flashcards-obsidian.git
synced 2025-10-16 12:05:33 +00:00
Add support for custom inline separators #61
This commit is contained in:
parent
efad21d7d7
commit
90a54a1aa9
15
main.ts
15
main.ts
@ -3,8 +3,7 @@ import { ISettings } from 'src/settings';
|
||||
import { SettingsTab } from 'src/gui/settings-tab';
|
||||
import { CardsService } from 'src/services/cards';
|
||||
import { Anki } from 'src/services/anki';
|
||||
import { noticeTimeout } from 'src/constants'
|
||||
import { flashcardsIcon } from 'src/constants'
|
||||
import { noticeTimeout, flashcardsIcon } from 'src/constants';
|
||||
|
||||
export default class ObsidianFlashcard extends Plugin {
|
||||
private settings: ISettings
|
||||
@ -14,17 +13,17 @@ export default class ObsidianFlashcard extends Plugin {
|
||||
addIcon("flashcards", flashcardsIcon)
|
||||
|
||||
// TODO test when file did not insert flashcards, but one of them is in Anki already
|
||||
let anki = new Anki()
|
||||
const anki = new Anki()
|
||||
this.settings = await this.loadData() || this.getDefaultSettings()
|
||||
this.cardsService = new CardsService(this.app, this.settings)
|
||||
|
||||
let statusBar = this.addStatusBarItem()
|
||||
const statusBar = this.addStatusBarItem()
|
||||
|
||||
this.addCommand({
|
||||
id: 'generate-flashcard-current-file',
|
||||
name: 'Generate for the current file',
|
||||
checkCallback: (checking: boolean) => {
|
||||
let activeFile = this.app.workspace.getActiveFile()
|
||||
const activeFile = this.app.workspace.getActiveFile()
|
||||
if (activeFile) {
|
||||
if (!checking) {
|
||||
this.generateCards(activeFile)
|
||||
@ -36,7 +35,7 @@ export default class ObsidianFlashcard extends Plugin {
|
||||
});
|
||||
|
||||
this.addRibbonIcon('flashcards', 'Generate flashcards', () => {
|
||||
let activeFile = this.app.workspace.getActiveFile()
|
||||
const activeFile = this.app.workspace.getActiveFile()
|
||||
if (activeFile) {
|
||||
this.generateCards(activeFile)
|
||||
} else {
|
||||
@ -56,12 +55,12 @@ export default class ObsidianFlashcard extends Plugin {
|
||||
}
|
||||
|
||||
private getDefaultSettings(): ISettings {
|
||||
return { contextAwareMode: true, sourceSupport: false, codeHighlightSupport: false, inlineID: false, contextSeparator: " > ", deck: "Default", flashcardsTag: "card", defaultAnkiTag: "obsidian" }
|
||||
return { contextAwareMode: true, sourceSupport: false, codeHighlightSupport: false, inlineID: false, contextSeparator: " > ", deck: "Default", flashcardsTag: "card", inlineSeparator: "::", inlineSeparatorReverse: ":::", defaultAnkiTag: "obsidian" }
|
||||
}
|
||||
|
||||
private generateCards(activeFile: TFile) {
|
||||
this.cardsService.execute(activeFile).then(res => {
|
||||
for (let r of res) {
|
||||
for (const r of res) {
|
||||
new Notice(r, noticeTimeout)
|
||||
}
|
||||
console.log(res)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { Notice, PluginSettingTab, Setting } from "obsidian";
|
||||
import { Anki } from "src/services/anki";
|
||||
import { escapeRegExp } from "src/utils";
|
||||
|
||||
export class SettingsTab extends PluginSettingTab {
|
||||
display(): void {
|
||||
@ -103,6 +104,60 @@ export class SettingsTab extends PluginSettingTab {
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Inline card separator")
|
||||
.setDesc(
|
||||
"The separator to identifty the inline cards in the notes."
|
||||
)
|
||||
.addText((text) => {
|
||||
text
|
||||
.setValue(plugin.settings.inlineSeparator)
|
||||
.setPlaceholder("::")
|
||||
.onChange((value) => {
|
||||
// if the value is empty or is the same like the inlineseparatorreverse then set it to the default, otherwise save it
|
||||
if (value.trim().length === 0 || value === plugin.settings.inlineSeparatorReverse) {
|
||||
plugin.settings.inlineSeparator = "::";
|
||||
if (value.trim().length === 0) {
|
||||
new Notice("The separator must be at least 1 character long");
|
||||
} else if (value === plugin.settings.inlineSeparatorReverse) {
|
||||
new Notice("The separator must be different from the inline reverse separator");
|
||||
}
|
||||
} else {
|
||||
plugin.settings.inlineSeparator = escapeRegExp(value.trim());
|
||||
new Notice("The separator has been changed");
|
||||
}
|
||||
plugin.saveData(plugin.settings);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Inline reverse card separator")
|
||||
.setDesc(
|
||||
"The separator to identifty the inline revese cards in the notes."
|
||||
)
|
||||
.addText((text) => {
|
||||
text
|
||||
.setValue(plugin.settings.inlineSeparatorReverse)
|
||||
.setPlaceholder(":::")
|
||||
.onChange((value) => {
|
||||
// if the value is empty or is the same like the inlineseparatorreverse then set it to the default, otherwise save it
|
||||
if (value.trim().length === 0 || value === plugin.settings.inlineSeparator) {
|
||||
plugin.settings.inlineSeparatorReverse = ":::";
|
||||
if (value.trim().length === 0) {
|
||||
new Notice("The separator must be at least 1 character long");
|
||||
} else if (value === plugin.settings.inlineSeparator) {
|
||||
new Notice("The separator must be different from the inline separator");
|
||||
}
|
||||
} else {
|
||||
plugin.settings.inlineSeparatorReverse = escapeRegExp(value.trim());
|
||||
new Notice("The separator has been changed");
|
||||
}
|
||||
plugin.saveData(plugin.settings);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Default Anki tag")
|
||||
.setDesc("This tag will be added to each generated card on Anki")
|
||||
|
||||
10
src/regex.ts
10
src/regex.ts
@ -50,13 +50,17 @@ export class Regex {
|
||||
"(?:[/-]reverse)?)((?: *#[\\p{Letter}\\-\\/_]+)*) *?\\n+((?:[^\\n]\\n?)*?(?=\\^\\d{13}|$))(?:\\^(\\d{13}))?";
|
||||
this.flashscardsWithTag = new RegExp(str, flags);
|
||||
|
||||
// https://regex101.com/r/Ixtzlv/1
|
||||
// https://regex101.com/r/8wmOo8/1
|
||||
const sepLongest = settings.inlineSeparator.length >= settings.inlineSeparatorReverse.length ? settings.inlineSeparator : settings.inlineSeparatorReverse;
|
||||
const sepShortest = settings.inlineSeparator.length < settings.inlineSeparatorReverse.length ? settings.inlineSeparator : settings.inlineSeparatorReverse;
|
||||
// sepLongest is the longest between the inlineSeparator and the inlineSeparatorReverse because if the order is ::|::: then always the first will be matched
|
||||
// sepShortest is the shortest
|
||||
if (settings.inlineID) {
|
||||
str =
|
||||
"( {0,3}[#]{0,6})?(?:(?:[\\t ]*)(?:\\d.|[-+*]|#{1,6}))?(.+?) ?(:{2,3}) ?(.+?)((?: *#[\\p{Letter}\\-\\/_]+)+)?(?:\\s+\\^(\\d{13})|$)";
|
||||
"( {0,3}[#]{0,6})?(?:(?:[\\t ]*)(?:\\d.|[-+*]|#{1,6}))?(.+?) ?(" + sepLongest + "|" + sepShortest + ") ?(.+?)((?: *#[\\p{Letter}\\-\\/_]+)+)?(?:\\s+\\^(\\d{13})|$)";
|
||||
} else {
|
||||
str =
|
||||
"( {0,3}[#]{0,6})?(?:(?:[\\t ]*)(?:\\d.|[-+*]|#{1,6}))?(.+?) ?(:{2,3}) ?(.+?)((?: *#[\\p{Letter}\\-\\/_]+)+|$)(?:\\n\\^(\\d{13}))?";
|
||||
"( {0,3}[#]{0,6})?(?:(?:[\\t ]*)(?:\\d.|[-+*]|#{1,6}))?(.+?) ?(" + sepLongest + "|" + sepShortest + ") ?(.+?)((?: *#[\\p{Letter}\\-\\/_]+)+|$)(?:\\n\\^(\\d{13}))?";
|
||||
}
|
||||
this.cardsInlineStyle = new RegExp(str, flags);
|
||||
|
||||
|
||||
@ -191,7 +191,7 @@ export class Parser {
|
||||
continue;
|
||||
}
|
||||
|
||||
const reversed: boolean = match[3].trim().toLowerCase() === ":::";
|
||||
const reversed: boolean = match[3] === this.settings.inlineSeparatorReverse;
|
||||
let headingLevel = -1;
|
||||
if (match[1]) {
|
||||
headingLevel =
|
||||
|
||||
@ -6,5 +6,7 @@ export interface ISettings {
|
||||
contextSeparator: string;
|
||||
deck: string;
|
||||
flashcardsTag: string;
|
||||
inlineSeparator: string;
|
||||
inlineSeparatorReverse: string;
|
||||
defaultAnkiTag: string;
|
||||
}
|
||||
|
||||
@ -44,3 +44,8 @@ export function escapeMarkdown(string: string, skips: string[] = []) {
|
||||
: s.replace(replacement[0], replacement[1]);
|
||||
}, string);
|
||||
}
|
||||
|
||||
|
||||
export function escapeRegExp(str: string) {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user