Skip to content
2 changes: 2 additions & 0 deletions src/note-question-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ export class NoteQuestionParser {
multilineReversedCardSeparator: settings.multilineReversedCardSeparator,
multilineCardEndMarker: settings.multilineCardEndMarker,
clozePatterns: settings.clozePatterns,
calloutCardMarker: settings.calloutCardMarker,
calloutLineMarker: settings.calloutLineMarker,
};

// We pass contentText which has the frontmatter blanked out; see extractFrontmatter for reasoning
Expand Down
22 changes: 20 additions & 2 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface ParserOptions {
multilineReversedCardSeparator: string;
multilineCardEndMarker: string;
clozePatterns: string[];
calloutCardMarker: string[];
calloutLineMarker: string;
}

export function setDebugParser(value: boolean) {
Expand Down Expand Up @@ -117,8 +119,8 @@ export function parse(text: string, options: ParserOptions): ParsedQuestionInfo[
if (
// We've probably reached the end of a card
(isEmptyLine && !options.multilineCardEndMarker) ||
// Empty line & we're not picking up any card
(isEmptyLine && cardType == null) ||
// Empty line AND (we're not picking up any card OR callout is done)
(isEmptyLine && (cardType == null || cardType == CardType.Callout)) ||
// We've reached the end of a multi line card &
// we're using custom end markers
hasMultilineCardEndMarker
Expand Down Expand Up @@ -190,6 +192,22 @@ export function parse(text: string, options: ParserOptions): ParsedQuestionInfo[
} else if (cardType === null && clozecrafter.isClozeNote(currentLine)) {
// Pick up cloze cards
cardType = CardType.Cloze;
} else if (
cardType === null &&
options.calloutCardMarker.length != 0 &&
// no marker is empty
options.calloutCardMarker.every((marker) => marker.trim().length > 0) &&
// at least one marker matches the start of the current line
options.calloutCardMarker.some((marker) =>
currentLine.trim().toLowerCase().startsWith(marker.toLowerCase()),
)
) {
// remove all lines before the question(=current line) from cardText
const split = cardText.split("\n");
cardText = split[split.length - 1];
// increase firstLineNo accordingly
firstLineNo += split.length - 1;
cardType = CardType.Callout;
}
}

Expand Down
23 changes: 22 additions & 1 deletion src/question-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,29 @@ class QuestionTypeCloze implements IQuestionTypeHandler {
back = clozeNote.getCardBack(i, clozeFormatter);
result.push(new CardFrontBack(front, back));
}

return result;
}
}

class CalloutType implements IQuestionTypeHandler {
expand(questionText: string, settings: SRSettings): CardFrontBack[] {
const questionLines = questionText.split("\n");
// assume the line is supposed to become a flashcard and thus has a valid `calloutCardMarker`
// then deleting everything in the `[]` brackets suffices to delete the marker
const regex = new RegExp("^>\\[.*?\\][+-]?", "i");
// question is always in the first line
const side1: string = questionLines[0].replace(regex, "").trim();
const side2 = questionLines
.slice(1)
// remove first level of `calloutLineMarker`
.map((line) => line.replace(settings.calloutLineMarker, ""))
.join("\n")
.trim();

const result: CardFrontBack[] = [new CardFrontBack(side1, side2)];
return result;
}
}
export class QuestionTypeClozeFormatter implements IClozeFormatter {
asking(answer?: string, hint?: string): string {
return `<span style='color:#2196f3'>${!hint ? "[...]" : `[${hint}]`}</span>`;
Expand Down Expand Up @@ -143,6 +161,9 @@ export class QuestionTypeFactory {
case CardType.Cloze:
handler = new QuestionTypeCloze();
break;
case CardType.Callout:
handler = new CalloutType();
break;
}
return handler;
}
Expand Down
1 change: 1 addition & 0 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum CardType {
MultiLineBasic,
MultiLineReversed,
Cloze,
Callout,
}

// QuestionText comprises the following components:
Expand Down
4 changes: 4 additions & 0 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface SRSettings {
multilineCardSeparator: string;
multilineReversedCardSeparator: string;
multilineCardEndMarker: string;
calloutCardMarker: string[];
calloutLineMarker: string;
editLaterTag: string;

// notes
Expand Down Expand Up @@ -82,6 +84,8 @@ export const DEFAULT_SETTINGS: SRSettings = {
multilineCardSeparator: "?",
multilineReversedCardSeparator: "??",
multilineCardEndMarker: "",
calloutCardMarker: [">[!Question]", ">[!Definition]", ">[!Card]"],
calloutLineMarker: ">",
editLaterTag: "#edit-later",

// notes
Expand Down
Loading