Obsidian_to_Anki
Obsidian_to_Anki copied to clipboard
Regex: Flashcards from native callout blocks (admonitions)
This regex creates a flashcards from callout blocks, that are now native to Obsidian as of v0.14.0.
Regex line: (?:\> \[!anki\]-) ([^\n]+)\n(.+(?:\n(?:^.{1,3}$|^.{4}(?<!<!--).*))*)
To make it more specific, the regex will only match a callout block that start with > [!anki]-
.
This allows you to keep using all defaults callout blocks without any issues.
Example
> [!anki]- First flashcard
> This is the body of the callout
> $Math$ and `inline code` both work.
> $$\dfrac{\sum _{i}m_{i}\vec{a}_{i}}{m}$$
> [!check]- Any other callout block will be left untouched
> This will NOT generate a flashcard
> [!anki]- Second flashcard
Lines of the body don't have to start with a > just like for Obsidian
These lines will be displayed by Obsidian as part of the callout block's body and will be part of the flashcard.
This is not part of the flashcard as it's separated by a blank line.
Why this regex?
I see this regex as a replacement for the Markdown table style. The goal is the same: it looks nice when rendered in the Preview view of Obsidian.
The benefits over the markdown table are:
- callout blocks can be collapsed
- more selective: only one type of callout is matched while all other are left untouched
- more customizable: it's possible to create a CSS snippet to style this custom block any way you like. (See image below)
Hey! I love your work, it looks pleasant and integrated. Is it possible to add a whitespace in-between the body?

I'm glad you like it.
"Is it possible to add a whitespace in-between the body?"
Yes, it is. According to the Obsidian syntax, you can add a blank line inside the body of the callout block as long as you start it with a >
. See the example below:
> [!anki]- Title of the flashcard
> **Classical conditioning**
> Some text...
>
> **Operant conditioning**
> Some other text...
Here's how the flashcard looks like in Anki
That was very helpful. Thank you.
Thank you, GBergatto, great work!
For anyone, who might be interested: this regex works not only for Basic card type, but also at least for Cloze and Basic (type in answer) types. You just have to change in the regex line how the callout block starts, for example > [!anki-cloze]-
for Cloze card type and > [!anki-typein]-
for type in cards.
I wonder if someone has implemented this using the obsidian-admonition plugin. In my opinion it would make cards much easier to type and the markdown would be cleaner.
Awesome regex!!! Thanks for save my time to find solution to integrate obsidian callout and anki flashcard :3
Thanks for this @GBergatto. Images can be used?
Thanks for this @GBergatto. Images can be used?
Yes, you can add images too. You simply need to embed them into the body of the callout block
> [!anki]- Flashcard with image
> 
Awesome, it does work really nice. Only thing I noticed is that the answer is been added as a blockquote. Is there anyway to correct that?
Awesome, it does work really nice. Only thing I noticed is that the answer is been added as a blockquote. Is there anyway to correct that?
@SubZeroX I'd never noticed that and I don't know how that could be fixed. As you can see from the picture below, when I open a card from the Anki editing view, it doesn't show any HTML tags like in your screenshot. All I can see is that the text inside the "Back" field has an unexpected indentation which I guess is caused by the "blockquote" tag.
Anyway, I don't think that it changes the way the content is displayed inside Anki, or does it?
Awesome, it does work really nice. Only thing I noticed is that the answer is been added as a blockquote. Is there anyway to correct that?
@SubZeroX I'd never noticed that and I don't know how that could be fixed. As you can see from the picture below, when I open a card from the Anki editing view, it doesn't show any HTML tags like in your screenshot. All I can see is that the text inside the "Back" field has an unexpected indentation which I guess is caused by the "blockquote" tag.
Anyway, I don't think that it changes the way the content is displayed inside Anki, or does it?
Yep, it don't changes the behavior at all. In order to show the html in Anki you need to type the combo "CTRL+SHIFT+X".
Much appreciated for your answers
Has anyone tried to get the callout information when it has a description or not? I tried but was not successful.
Example 1 - Many line description
Callout
[!anki-cloze]- Question with {c1:two or more} lines of description. Explanation - Line 1 Explanation - Line 2 Explanation - Line 3
Anki Fields text: Question with {c1:two or more} lines of description. extra: Explanation - Line 1 Explanation - Line 2 Explanation - Line 3
Example 2 - One line description
Callout
[!anki-cloze]- Question with {c1:only} one line of description Explanation - Line 1
Anki Fields text: Question with {c1:only} one line of description extra: Explanation - Line 1
Example 3 - No description
Callout
[!anki-cloze]- {c1:Only} the question.
Anki Fields text: {c1:Only} the question. extra:
Awesome, it does work really nice. Only thing I noticed is that the answer is been added as a blockquote. Is there anyway to correct that?
I had the same problem as you do. Unfortunately, it is not easily fixable via regex, but what you can do is to edit the processing step to handle these types of notes. To do that you need to edit your main.js file of this plugin - replace the format function with the following:
/**
* Removes a single layer of indentation from notes that are fully indented e.g. in callouts
* @param {string} note_text
* @returns string
*/
formatCallouts(note_text){
let split_string = note_text.split('\n')
if(!split_string.every(line => line.charAt(0) =='>'))
{
return note_text
}
split_string = split_string.map(line => line.substring(1))
note_text = split_string.join('\n')
return note_text
}
format(note_text, cloze, highlights_to_cloze) {
note_text = this.obsidian_to_anki_math(note_text);
//Extract the parts that are anki math
let math_matches;
let inline_code_matches;
let display_code_matches;
const add_highlight_css = note_text.match(OBS_DISPLAY_CODE_REGEXP) ? true : false;
[note_text, math_matches] = this.censor(note_text, ANKI_MATH_REGEXP, MATH_REPLACE);
[note_text, display_code_matches] = this.censor(note_text, OBS_DISPLAY_CODE_REGEXP, DISPLAY_CODE_REPLACE);
[note_text, inline_code_matches] = this.censor(note_text, OBS_CODE_REGEXP, INLINE_CODE_REPLACE);
if (cloze) {
if (highlights_to_cloze) {
note_text = note_text.replace(HIGHLIGHT_REGEXP, "{$1}");
}
note_text = this.curly_to_cloze(note_text);
}
note_text = this.getAndFormatMedias(note_text);
note_text = this.formatLinks(note_text);
// Special Processing for Full Codeblock Notes (e.g. Callouts)
note_text = this.formatCallouts(note_text)
//Special for formatting highlights now, but want to avoid any == in code
note_text = note_text.replace(HIGHLIGHT_REGEXP, String.raw `<mark>$1</mark>`);
note_text = this.decensor(note_text, DISPLAY_CODE_REPLACE, display_code_matches, false);
note_text = this.decensor(note_text, INLINE_CODE_REPLACE, inline_code_matches, false);
note_text = converter.makeHtml(note_text);
note_text = this.decensor(note_text, MATH_REPLACE, math_matches, true).trim();
// Remove unnecessary paragraph tag
if (note_text.startsWith(PARA_OPEN) && note_text.endsWith(PARA_CLOSE)) {
note_text = note_text.slice(PARA_OPEN.length, -1 * PARA_CLOSE.length);
}
if (add_highlight_css) {
note_text = '<link href="' + CODE_CSS_URL + '" rel="stylesheet">' + note_text;
}
return note_text;
}
Hi! I've started using your regex thaht mak my vaul much cleaner! Thanks for the job!!! However is there a way to add a link to where the callout block is saved in my obsidian vault ?
Hi! I've started using your regex thaht mak my vaul much cleaner! Thanks for the job!!! However is there a way to add a link to where the callout block is saved in my obsidian vault ?
@Davidb-2107 Yes, from the plugin settings
All you need to do is choose which field should contain the "file link" and the plugin will take care of the rest
Awesome, it does work really nice. Only thing I noticed is that the answer is been added as a blockquote. Is there anyway to correct that?
I had the same problem as you do. Unfortunately, it is not easily fixable via regex, but what you can do is to edit the processing step to handle these types of notes. To do that you need to edit your main.js file of this plugin - replace the format function with the following:
/** * Removes a single layer of indentation from notes that are fully indented e.g. in callouts * @param {string} note_text * @returns string */ formatCallouts(note_text){ let split_string = note_text.split('\n') if(!split_string.every(line => line.charAt(0) =='>')) { return note_text } split_string = split_string.map(line => line.substring(1)) note_text = split_string.join('\n') return note_text } format(note_text, cloze, highlights_to_cloze) { note_text = this.obsidian_to_anki_math(note_text); //Extract the parts that are anki math let math_matches; let inline_code_matches; let display_code_matches; const add_highlight_css = note_text.match(OBS_DISPLAY_CODE_REGEXP) ? true : false; [note_text, math_matches] = this.censor(note_text, ANKI_MATH_REGEXP, MATH_REPLACE); [note_text, display_code_matches] = this.censor(note_text, OBS_DISPLAY_CODE_REGEXP, DISPLAY_CODE_REPLACE); [note_text, inline_code_matches] = this.censor(note_text, OBS_CODE_REGEXP, INLINE_CODE_REPLACE); if (cloze) { if (highlights_to_cloze) { note_text = note_text.replace(HIGHLIGHT_REGEXP, "{$1}"); } note_text = this.curly_to_cloze(note_text); } note_text = this.getAndFormatMedias(note_text); note_text = this.formatLinks(note_text); // Special Processing for Full Codeblock Notes (e.g. Callouts) note_text = this.formatCallouts(note_text) //Special for formatting highlights now, but want to avoid any == in code note_text = note_text.replace(HIGHLIGHT_REGEXP, String.raw `<mark>$1</mark>`); note_text = this.decensor(note_text, DISPLAY_CODE_REPLACE, display_code_matches, false); note_text = this.decensor(note_text, INLINE_CODE_REPLACE, inline_code_matches, false); note_text = converter.makeHtml(note_text); note_text = this.decensor(note_text, MATH_REPLACE, math_matches, true).trim(); // Remove unnecessary paragraph tag if (note_text.startsWith(PARA_OPEN) && note_text.endsWith(PARA_CLOSE)) { note_text = note_text.slice(PARA_OPEN.length, -1 * PARA_CLOSE.length); } if (add_highlight_css) { note_text = '<link href="' + CODE_CSS_URL + '" rel="stylesheet">' + note_text; } return note_text; }
Hello! I'm unsure where exactly in main.js I should paste this? As the name implies I'm new to tinkering around with code! :P
Hey, no worries. In the main.js there should already be a function called format(...). You just have to replace the existing format function with the code snippet provided. Essentially, this just modifies the format function and adds the format callouts function. Does that help?
Great expression. It is possible to add one more file, like a source, notes or whatever. Thanks
I absolute love this Regex. It's even better than the common ones!
I have been wondering: Is there a way to manually tag cards with this regex? If I append a "Tags: [Tag]", it doesn't register and only shows up as a text in the answer field.
Hi GBergatto,
thanks for the great work - i am using it a lot for my studies. Do you have a idea how to modify the regex for nested callouts or multiple callouts in one admonition? For example like this:
` ```ad-note
[!anki]- First flashcard This is the body of the callout $Math$ and
inline code
both work.
$$\dfrac{\sum {i}m{i}\vec{a}_{i}}{m}$$
[!check]- Any other callout block will be left untouched This will NOT generate a flashcard
[!anki]- Second flashcard Lines of the body don't have to start with a > just like for Obsidian These lines will be displayed by Obsidian as part of the callout block's body and will be part of the flashcard.
This is not part of the flashcard as it's separated by a blank line. ``` ` I tired to manage by myself but not very succesful..
@daelen-j I'm not sure what you mean. FYI I have stopped using this plugin and this regex, so I'm not sure I will be able to test any changes to the original regex I posted.