diff --git a/src/cloze-matching.ts b/src/cloze-matching.ts
new file mode 100644
index 00000000..464e7fd1
--- /dev/null
+++ b/src/cloze-matching.ts
@@ -0,0 +1,27 @@
+import { SRSettings } from "./settings";
+
+export function matchClozesWithinCardText(
+ cardText: string,
+ settings: SRSettings
+): RegExpMatchArray[] {
+ const siblings: RegExpMatchArray[] = [];
+ if (settings.convertHighlightsToClozes) {
+ siblings.push(...cardText.matchAll(/==(.*?)==/gm));
+ }
+ if (settings.convertBoldTextToClozes) {
+ siblings.push(...cardText.matchAll(/\*\*(.*?)\*\*/gm));
+ }
+ if (settings.convertCurlyBracketsToClozes) {
+ siblings.push(...cardText.matchAll(/{{(.*?)}}/gm));
+ }
+
+ return siblings.sort((a, b) => {
+ if (a.index < b.index) {
+ return -1;
+ }
+ if (a.index > b.index) {
+ return 1;
+ }
+ return 0;
+ });
+}
diff --git a/src/flashcard-modal.tsx b/src/flashcard-modal.tsx
index 7b4cba98..fda459dc 100644
--- a/src/flashcard-modal.tsx
+++ b/src/flashcard-modal.tsx
@@ -24,6 +24,7 @@ import {
} from "src/constants";
import { escapeRegexString, cyrb53 } from "src/utils";
import { t } from "src/lang/helpers";
+import { matchClozesWithinCardText } from "./cloze-matching";
export enum FlashcardModalMode {
DecksList,
@@ -193,6 +194,7 @@ export class FlashcardModal extends Modal {
// Checks if the input textbox is in focus before processing keyboard shortcuts.
if (
document.activeElement.nodeName != "TEXTAREA" &&
+ document.activeElement.nodeName !== "INPUT" &&
this.mode !== FlashcardModalMode.DecksList
) {
const consume = () => {
@@ -413,7 +415,26 @@ export class FlashcardModal extends Modal {
this.currentDeck.nextCard(this);
}
+ private getClozeBackView(clozeInputs: string[]): string {
+ const { cardText } = this.currentCard;
+
+ const clozeMatches = matchClozesWithinCardText(cardText, this.plugin.data.settings);
+ const correctAnswers = clozeMatches.map((match) => match[1]);
+
+ return correctAnswers.reduce((acc, answer, index) => {
+ return acc.replace(
+ clozeMatches[index][0],
+ answer === clozeInputs[index]
+ ? `${clozeInputs[index]}`
+ : `[${clozeInputs[index]}${answer}]`
+ );
+ }, this.currentCard.cardText);
+ }
+
private showAnswer(): void {
+ const clozeInputFields = Array.from(document.getElementsByClassName("cloze-input"));
+ const clozeInputs = clozeInputFields.map((clozeInput) => clozeInput.value);
+
this.mode = FlashcardModalMode.Back;
this.answerBtn.style.display = "none";
@@ -428,6 +449,7 @@ export class FlashcardModal extends Modal {
hr.setAttribute("id", "sr-hr-card-divide");
this.flashcardView.appendChild(hr);
} else {
+ this.currentCard.back = this.getClozeBackView(clozeInputs);
this.flashcardView.empty();
}
diff --git a/src/main.ts b/src/main.ts
index 5704b1d7..35353491 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -25,6 +25,7 @@ import { ReviewDeck, ReviewDeckSelectionModal } from "src/review-deck";
import { t } from "src/lang/helpers";
import { parse } from "src/parser";
import { appIcon } from "src/icons/appicon";
+import { matchClozesWithinCardText } from "./cloze-matching";
interface PluginData {
settings: SRSettings;
@@ -690,52 +691,19 @@ export default class SRPlugin extends Plugin {
const siblingMatches: [string, string][] = [];
if (cardType === CardType.Cloze) {
- const siblings: RegExpMatchArray[] = [];
- if (settings.convertHighlightsToClozes) {
- siblings.push(...cardText.matchAll(/==(.*?)==/gm));
- }
- if (settings.convertBoldTextToClozes) {
- siblings.push(...cardText.matchAll(/\*\*(.*?)\*\*/gm));
- }
- if (settings.convertCurlyBracketsToClozes) {
- siblings.push(...cardText.matchAll(/{{(.*?)}}/gm));
- }
- siblings.sort((a, b) => {
- if (a.index < b.index) {
- return -1;
- }
- if (a.index > b.index) {
- return 1;
- }
- return 0;
- });
-
- let front: string, back: string;
- for (const m of siblings) {
- const deletionStart: number = m.index,
- deletionEnd: number = deletionStart + m[0].length;
- front =
- cardText.substring(0, deletionStart) +
- "[...]" +
- cardText.substring(deletionEnd);
- front = front
- .replace(/==/gm, "")
- .replace(/\*\*/gm, "")
- .replace(/{{/gm, "")
- .replace(/}}/gm, "");
- back =
- cardText.substring(0, deletionStart) +
- "" +
- cardText.substring(deletionStart, deletionEnd) +
- "" +
- cardText.substring(deletionEnd);
- back = back
- .replace(/==/gm, "")
- .replace(/\*\*/gm, "")
- .replace(/{{/gm, "")
- .replace(/}}/gm, "");
- siblingMatches.push([front, back]);
- }
+ const front = matchClozesWithinCardText(cardText, this.data.settings).reduce(
+ (acc, sibling) => {
+ const inputHTML = ``;
+
+ return acc
+ ? acc.replace(sibling[0], inputHTML)
+ : acc + sibling.input.replace(sibling[0], inputHTML);
+ },
+ ""
+ );
+
+ // back is being created in flashcard-modal.tsx with getClozeBackView()
+ siblingMatches.push([front, ""]);
} else {
let idx: number;
if (cardType === CardType.SingleLineBasic) {