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

Cloze Update: Adds Cloze hints, Anki-Like Clozes, Cloze Overlapping and Custom Cloze Patterns #943

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"dependencies": {
"chart.js": "^4.4.2",
"clozecraft": "^0.4.0",
"pagerank.js": "^1.0.2"
},
"packageManager": "^pnpm@8.15.4"
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

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

4 changes: 1 addition & 3 deletions src/NoteQuestionParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ export class NoteQuestionParser {
settings.singleLineReversedCardSeparator,
settings.multilineCardSeparator,
settings.multilineReversedCardSeparator,
settings.convertHighlightsToClozes,
settings.convertBoldTextToClozes,
settings.convertCurlyBracketsToClozes,
settings.clozePatterns,
Copy link
Owner

Choose a reason for hiding this comment

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

Just removing the existing settings would break existing instances of the plugin.. There's a upgradeSettings function in settings.ts that would help with gracefully migrating the settings to clozePatterns.

);
return result;
}
Expand Down
64 changes: 14 additions & 50 deletions src/QuestionType.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClozeCrafter, IClozeFormatter } from "clozecraft";
import { CardType } from "./Question";
import { SRSettings } from "./settings";
import { findLineIndexOfSearchStringIgnoringWs } from "./util/utils";
Expand Down Expand Up @@ -92,68 +93,31 @@ class QuestionType_MultiLineReversed implements IQuestionTypeHandler {

class QuestionType_Cloze implements IQuestionTypeHandler {
expand(questionText: string, settings: SRSettings): CardFrontBack[] {
const siblings: RegExpMatchArray[] = [];
if (settings.convertHighlightsToClozes) {
siblings.push(...questionText.matchAll(/==(.*?)==/gm));
}
if (settings.convertBoldTextToClozes) {
siblings.push(...questionText.matchAll(/\*\*(.*?)\*\*/gm));
}
if (settings.convertCurlyBracketsToClozes) {
siblings.push(...questionText.matchAll(/{{(.*?)}}/gm));
}
siblings.sort((a, b) => {
if (a.index < b.index) {
return -1;
}
if (a.index > b.index) {
return 1;
}
// What is unit test to cover following statement; otherwise jest please ignore
return 0;
});
const clozecrafter = new ClozeCrafter(settings.clozePatterns);
const clozeNote = clozecrafter.createClozeNote(questionText);
const clozeFormatter = new QuestionType_ClozeFormatter();

let front: string, back: string;
const result: CardFrontBack[] = [];
for (const m of siblings) {
const deletionStart: number = m.index,
deletionEnd: number = deletionStart + m[0].length;
front =
questionText.substring(0, deletionStart) +
QuestionType_ClozeUtil.renderClozeFront() +
questionText.substring(deletionEnd);
front = QuestionType_ClozeUtil.removeClozeTokens(front, settings);
back =
questionText.substring(0, deletionStart) +
QuestionType_ClozeUtil.renderClozeBack(
questionText.substring(deletionStart, deletionEnd),
) +
questionText.substring(deletionEnd);
back = QuestionType_ClozeUtil.removeClozeTokens(back, settings);
for (let i = 0; i < clozeNote.numCards; i++) {
front = clozeNote.getCardFront(i, clozeFormatter);
back = clozeNote.getCardBack(i, clozeFormatter);
result.push(new CardFrontBack(front, back));
}

return result;
}
}

export class QuestionType_ClozeUtil {
static renderClozeFront(): string {
return "<span style='color:#2196f3'>[...]</span>";
export class QuestionType_ClozeFormatter implements IClozeFormatter {
asking(answer?: string, hint?: string): string {
return `<span style='color:#2196f3'>${!hint ? "[...]" : `[${hint}]`}</span>`;
}

static renderClozeBack(str: string): string {
return "<span style='color:#2196f3'>" + str + "</span>";
showingAnswer(answer: string, _hint?: string): string {
return `<span style='color:#2196f3'>${answer}</span>`;
}

static removeClozeTokens(text: string, settings: SRSettings): string {
let result: string = text;
if (settings.convertHighlightsToClozes) result = result.replace(/==/gm, "");
if (settings.convertBoldTextToClozes) result = result.replace(/\*\*/gm, "");
if (settings.convertCurlyBracketsToClozes) {
result = result.replace(/{{/gm, "").replace(/}}/gm, "");
}
return result;
hiding(answer?: string, hint?: string): string {
return `<span style='color:var(--code-comment)'>${!hint ? "[...]" : `[${hint}]`}</span>`;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Convert ==hightlights== to clozes?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Convert **bolded text** to clozes?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convert {{curly brackets}} to clozes?",
CLOZE_PATTERNS: "Cloze Patterns",
CLOZE_PATTERNS_DESC: "Enter cloze patterns separated by newlines",
INLINE_CARDS_SEPARATOR: "فاصل من أجل البطاقات المضمنة",
FIX_SEPARATORS_MANUALLY_WARNING:
"ضع في حسابك أنه بعد تغيير هذا ، يجب عليك تعديل أي بطاقات لديك بالفعل يدويًا",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/cz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Převést ==zvýraznění== na clozes?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Převést **tučný text** na clozes?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Převést {{složené závorky}} na clozes?",
CLOZE_PATTERNS: "Cloze vzory",
CLOZE_PATTERNS_DESC: "Zadejte cloze vzory oddělené odřádkováním",
INLINE_CARDS_SEPARATOR: "Oddělovač pro inline kartičky",
FIX_SEPARATORS_MANUALLY_WARNING:
"Pozor. Jakmile toto změníte, budete muset ručně upravit všechny existující kartičky.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export default {
CONVERT_BOLD_TEXT_TO_CLOZES: "**Fettgedruckten** Text in Lückentextkarten umwandeln?",
CONVERT_CURLY_BRACKETS_TO_CLOZES:
"{{Geschweifte Klammern}} Text in Lückentextkarten umwandeln?",
CLOZE_PATTERNS: "Lückentextmuster",
CLOZE_PATTERNS_DESC: "Geben Sie Lückentextmuster durch Zeilenumbrüche getrennt ein",
INLINE_CARDS_SEPARATOR: "Trennzeichen für einzeilige Lernkarten",
FIX_SEPARATORS_MANUALLY_WARNING:
"Wenn diese Einstellung geändert wird, dann müssen die entsprechenden Lernkarten manuell angepasst werden.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Convert ==hightlights== to clozes?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Convert **bolded text** to clozes?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convert {{curly brackets}} to clozes?",
CLOZE_PATTERNS: "Cloze Patterns",
CLOZE_PATTERNS_DESC: "Enter cloze patterns separated by newlines",
INLINE_CARDS_SEPARATOR: "Separator for inline flashcards",
FIX_SEPARATORS_MANUALLY_WARNING:
"Note that after changing this you have to manually edit any flashcards you already have.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "¿Convertir ==resaltados== a deletreo de huecos?",
CONVERT_BOLD_TEXT_TO_CLOZES: "¿Convertir **texto en negrita** a deletreo de huecos?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "¿Convertir {{llaves rizadas}} a deletreo de huecos?",
CLOZE_PATTERNS: "Patrones de deletreo de huecos",
CLOZE_PATTERNS_DESC: "Escriba los patrones de deletreo de huecos separados por saltos de línea",
INLINE_CARDS_SEPARATOR: "Separador de tarjetas de memorización en línea",
FIX_SEPARATORS_MANUALLY_WARNING:
"Note que después de cambiar este ajuste, tendrá que cambiar manualmente todas las notas que tenga.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Convertire ==testo evidenziato== in spazi da riempire?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Convertire **testo in grassetto** in spazi da riempire",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Convertire {{parentesi graffe}} in spazi da riempire?",
CLOZE_PATTERNS: "Modelli di spazi da riempire",
CLOZE_PATTERNS_DESC: "Inserisci i modelli di spazi da riempire separati da a capo",
INLINE_CARDS_SEPARATOR: "Separatore per schede sulla stessa riga",
FIX_SEPARATORS_MANUALLY_WARNING:
"Si avvisa che dopo aver cambiato questo dovrai manualmente modificare le schede che hai già.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "==ハイライト==を穴埋めとして使用しますか?",
CONVERT_BOLD_TEXT_TO_CLOZES: "**ボールド体**を穴埋めとして使用しますか?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{中括弧}}を穴埋めとして使用しますか?",
CLOZE_PATTERNS: "穴埋めパターン",
CLOZE_PATTERNS_DESC: "改行で区切って穴埋めパターンを入力してください。",
INLINE_CARDS_SEPARATOR: "インラインフラッシュカードに使用するセパレーター",
FIX_SEPARATORS_MANUALLY_WARNING:
"このオプションを変更する場合には、作成済みのフラッシュカードを手動で編集し直す必要があることに注意してください。",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "==hightlights== 를 빈 칸 채우기로 전환하시겠습니까?",
CONVERT_BOLD_TEXT_TO_CLOZES: "**bolded text** 를 빈 칸 채우기로 전환하시겠습니까?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "{{curly brackets}} 를 빈 칸 채우기로 전환하시겠습니까?",
CLOZE_PATTERNS: "빈 칸 채우기 패턴",
CLOZE_PATTERNS_DESC: "빈 칸 채우기 패턴을 입력해주세요. 줄바꿈으로 구분합니다.",
INLINE_CARDS_SEPARATOR: "인라인 플래시카드 구분자",
FIX_SEPARATORS_MANUALLY_WARNING:
"주의: 이 옵션을 수정한 후에는 이미 작성된 플래시카드를 수동으로 수정해야 함을 주의하십시오.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Konwertować ==podświetlenia== na karty zamaskowane?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Konwertować pogrubiony tekst na karty zamaskowane?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Konwertować {{klamry}} na karty zamaskowane?",
CLOZE_PATTERNS: "Wzory kart zamaskowanych",
CLOZE_PATTERNS_DESC: "Wprowadź wzory kart zamaskowanych oddzielone nowymi liniami",
INLINE_CARDS_SEPARATOR: "Separator dla kart zamaskowanych w linii",
FIX_SEPARATORS_MANUALLY_WARNING:
"Pamiętaj, że po zmianie tego musisz ręcznie edytować wszystkie karty zamaskowane, które już masz.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/pt-br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "Converter ==marca-texto== em omissões?",
CONVERT_BOLD_TEXT_TO_CLOZES: "Converter **texto em negrito** em omissões?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "Converter {{chaves}} em omissões?",
CLOZE_PATTERNS: "Padrões de Omissão",
CLOZE_PATTERNS_DESC: "Entre os padrões de omissão separados por quebras de linha",
INLINE_CARDS_SEPARATOR: "Separador para flashcards inline",
FIX_SEPARATORS_MANUALLY_WARNING:
"Note que depois de mudar isso você vai ter que manualmente mudar quaisquer flashcards que você tenha.",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ export default {
CONVERT_BOLD_TEXT_TO_CLOZES: "Конвертировать **жирный текст** в пропуски (пример: [...])?",
CONVERT_CURLY_BRACKETS_TO_CLOZES:
"Конвертировать {{фигурные скобки}} в пропуски (пример: [...])?",
CLOZE_PATTERNS: "Шаблоны пропусков",
CLOZE_PATTERNS_DESC: "Введите шаблоны пропусков, разделенные переводами строк",
INLINE_CARDS_SEPARATOR: "Разделитель для внутристрочных карточек",
FIX_SEPARATORS_MANUALLY_WARNING:
"Внимание! После изменения этого вам придётся вручную редактировать уже существующие карточки",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "将 ==高亮== 转换为完形填空?",
CONVERT_BOLD_TEXT_TO_CLOZES: "将 **粗体** 转换为完形填空?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "将 {{大括号}} 转换为完形填空?",
CLOZE_PATTERNS: "完形填空模式",
CLOZE_PATTERNS_DESC: "输入以换行符分隔的完形填空模式",
INLINE_CARDS_SEPARATOR: "单行卡片的分隔符",
FIX_SEPARATORS_MANUALLY_WARNING: "注意:更改此选项后你将需要自行更改已存在卡片的分隔符。",
INLINE_REVERSED_CARDS_SEPARATOR: "单行翻转卡片的分隔符",
Expand Down
2 changes: 2 additions & 0 deletions src/lang/locale/zh-tw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export default {
CONVERT_HIGHLIGHTS_TO_CLOZES: "將 ==高亮== 轉換為填空克漏字?",
CONVERT_BOLD_TEXT_TO_CLOZES: "將 **粗體** 轉換為填空克漏字?",
CONVERT_CURLY_BRACKETS_TO_CLOZES: "將 {{大括號}} 轉換為填空克漏字?",
CLOZE_PATTERNS: "填空克漏字模式",
CLOZE_PATTERNS_DESC: "輸入以換行符分隔的填空克漏字模式",
INLINE_CARDS_SEPARATOR: "單行卡片的分隔字元",
FIX_SEPARATORS_MANUALLY_WARNING: "注意:更改此選項後你將需要自行更改已存在卡片的分隔字元。",
INLINE_REVERSED_CARDS_SEPARATOR: "單行反轉卡片的分隔字元",
Expand Down
13 changes: 4 additions & 9 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClozeCrafter } from "clozecraft";
import { CardType } from "./Question";

export class ParsedQuestionInfo {
Expand Down Expand Up @@ -43,15 +44,14 @@ export function parseEx(
singlelineReversedCardSeparator: string,
multilineCardSeparator: string,
multilineReversedCardSeparator: string,
convertHighlightsToClozes: boolean,
convertBoldTextToClozes: boolean,
convertCurlyBracketsToClozes: boolean,
clozePatterns: string[],
): ParsedQuestionInfo[] {
let cardText = "";
const cards: ParsedQuestionInfo[] = [];
let cardType: CardType | null = null;
let firstLineNo = 0;
let lastLineNo = 0;
const clozecrafter = new ClozeCrafter(clozePatterns);

const lines: string[] = text.replaceAll("\r\n", "\n").split("\n");
for (let i = 0; i < lines.length; i++) {
Expand Down Expand Up @@ -96,12 +96,7 @@ export function parseEx(
cards.push(new ParsedQuestionInfo(cardType, cardText, firstLineNo, lastLineNo));
cardType = null;
cardText = "";
} else if (
cardType === null &&
((convertHighlightsToClozes && /==.*?==/gm.test(currentLine)) ||
(convertBoldTextToClozes && /\*\*.*?\*\*/gm.test(currentLine)) ||
(convertCurlyBracketsToClozes && /{{.*?}}/gm.test(currentLine)))
) {
} else if (cardType === null && clozecrafter.isClozeNote(currentLine)) {
Copy link
Owner

Choose a reason for hiding this comment

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

The parser was completely reworked in #1012 & #1081 to use Peggy. There's clozes_grammar in parser.ts/generateGrammar that we should update instead.

cardType = CardType.Cloze;

// Explicitly don't change firstLineNo, as we might not see the cloze markers on the first line
Expand Down
Loading