Anki (GitHub) addon (GitHub) that allows adding and editing notes in extended CommonMark Markdown, either directly in the editor fields ("field input mode", similar to the core rich and plain text edit interface) or by opening a separate window to edit a specific field or the entire note ("window input mode").
The editor DOM and internal functioning which Markdown input
depends on changed in Anki version 2.1.56. The current version of Markdown input
ships with both 2.1.56+ compatible code as well as the last release targeted at 2.1.55. Going forward no updates/fixes will be made to the legacy code, any development/bug fixes will be in the 2.1.56+ code.
- Markdown is not "another way to write HTML", it is a plain text format that has a determined translation to HTML (the format the Anki editor uses). The HTML generated is a subset of all HTML and, amongst other things, makes heavy use of
<p>
tags (which are not used by the Anki editor). Furthermore there is no spec on the conversion from HTML to Markdown. This makes conversion tricky and there is risk for loss of information when cycling HTML → Markdown → HTML. - Editing a field in Markdown will result in the original field HTML being converted to Markdown and then back to HTML - the end result may differ from the original (especially in case of complex HTML). For instance, the representation of tables does not allow for nested tables in Markdown. So if the original HTML has nested tables these will be lost on cycling. If you are not familiar with Markdown consider duplicating your deck and play around with a copy so that you are sure you know what you are doing.
- Note however, that if you do not make any changes in the "field input mode" or cancel the "window input mode" the orginal Anki HTML will remain untouched when you toggle back. Also note that in field input mode making a change and then undoing will still count as "making a change" (changes update the HTML continuously).
- If you are not familiar with Markdown look it up where it began or here or here for instance, to determine if it is for you.
Conversion to/from HTML is done through unified Markdown functions hast-util-from/to-html
hast-util-to-mdast
/mdast-util-to-hast
and mdast-util-to/from-markdown
which are CommonMark compliant. The following changes/extensions has been made in the addon:
-
Markdown uses
<p>
tags to mark paragraphs, these are replaced with<br>
tags instead to match the Anki editor. -
Markdown has a concept of lists being "tight" or "loose" which results in list items being wrapped in
<p>
tags or not. This has been replaced with HTML.markdown-tight
or.markdown-loose
classes to allow styling, example:ul.markdown-loose > li, ol.markdown-loose > li {padding-top: 10px; padding-bottom: 10px;} ul.markdown-tight > li, ol.markdown-tight > li {padding: 0px}
-
Spec
<em>sample</em>
(*sample*
) and<strong>sample</strong>
(**sample**
) are swapped to<i>
and<b>
to match the Anki editor. -
Markdown syntax extensions (set to
true
or"some vale"
to enable,false
to disable):-
Subscript
:true
for~sample~
subscript -
Superscript
:true
for^sample^
superscript -
Underline
:true
for_sample_
underline (spec Markdown is<em>
, disable to revert to spec). -
Strikethrough
:"double"
for~~sample~~
strikthrough ("single"
supports single tilde, incompatible with subscript above). -
Inline media
:true
for Inline Media directive, e.g.:audio(im-xyz.ogg){loop auto_front}
/:video(im-xyz.ogg){loop auto_front height=200}
. -
Definition lists
:true
for Defintion lists (not available in the core Anki editor). -
Table stle
: Table syntax,"gfm"
/"extended"
:- GFM table syntax
| A | GFM | | :---- | ----: | | table | ! |
- Extended table syntax - GFM style extended to allow headerless tables (no
<thead>
generated):
| :--: | ----: | | A | table | | with | rows |
Table newline
: Symbol to replace hard line break (<br>
) inside table cells (newline characters are normally not allowed inside Markdown table cells)fences
: Optional fencing pipes (i.e. at start and end of each row).- Align none, left, right and center as per GFM format.
-
The editor used is CodeMirror 6 with the following configurations:
- Markdown syntax highlighting and auto fill (continue lists, autoindent etc.).
- Undo history.
- Multiple drawable selections.
- Search and replace,
Ctrl+F
, note: the Anki editor eatsCtrl+F
, set to other shortcut in config or remap the Anki editor shortcuts with Customize Keyboard Shortcuts or similar. - Insert cloze deletions
- Cloze without increment:
Ctrl+Shift+Z
- For some reason I am unable to getCtrl+Alt+Shift+C
to work (the default Anki keyboard shortcut) - Cloze with increment:
Ctrl+Shift+c
(with multiple selections this will cloze each incrementally) - If you feel the cloze deletion tags end up in the wrong place please make sure you understand how Markdown is converted to HTML (notably line breaks and empty lines).
- Cloze without increment:
- Allows image pasting in the same way the "rich text input" does.
- Customize the editor styling by copying
cm.css
intouser_files
subdirectory and customize. Consider using--var(xyz)
to use the Anki colors from the current theme (i.e. follows light/dark mode). - Customize Markdown input editor shortcuts (i.e. inside the field/window, not the core Anki editor) in
config.json
, seeconfig.json
and CodeMirror documentation for further information. Available functions to map are all in @codemirror/commands, @codemirror/search and custom commandsclozeNext
,clozeCurrent
,joinLines
. - Configurable search/replace default options (
caseSensitive
,regexp
,wholeWord
).
- Configurable default state for editor fields (
rich text
,markdown
orrich text/markdown
, defaultrich text
). - Configurable behaviour of "field input mode" shortcut, cycle between rich text and Markdown (
true
) or just toggle Markdown input (false
). (defaulttrue
) - Configurable shortcut to toggle rich text input. (default
Ctrl+Alt+X
) - Configurable shortcuts to move to next/previous input (since tab is a valid Markdown character it will not work to "tab out" of a markdown input). (default
Ctrl+PgDown
andCtrl+PgUp
) - Configurable option to autohide editor toolbar when focusing Markdown input (to increase available space). (default
true
)
- Configurable window size (
parent
,last
orWidthxHeight
, defaultparent
) - Configurable note editing mode, either the entire note (i.e. all fields) or current field. In
note
editing mode the fields are separated by HTML comments (e.g.<!-- Front -->
) and content will be inserted into the correspondingly named field. (note
orfield
, defaultnote
)
- "Field input mode" can be configured under
Field input
, note that the default shortcut,Ctrl+M
conflicts with Mathjax shortcuts, remap one of them. - "Window input mode" can be configured under
Window input
. - HTML ↔ Markdown conversion configurable under
Converter
. See mdastToMarkdown forMarkdown format
options. - Editor configurable under
CodeMirror
. See CodeMirror documentation how to configure. - Default Anki behaviour is to use the entire sort field text in the Browser table,
Browser sort field
option (defaulttrue
) instead uses content of first level 1 heading (if existing). - Note that Anki shortcuts grab key sequences before they reach the CodeMirror editor, use Customize Keyboard Shortcut or other addon to change the Anki shortcuts as needed. At the time of writing Customize Keyboard Shortcut hooks into the Qt/Python for the cloze shortcuts. This means they never reach CodeMirror so unmap (
<nop
>) them in Customize Keyboard Shortcut (the new Anki editor grabs the shortcuts on the JavaScript side). - To customize the look of the finished HTML apply custom CSS styling (for instance of
<h1/2/3/etc>
,<table>
<ul/ol>
etc.) to the note template. - To customize the look and feel of the editor, make a copy of
cm.css
(styling of CodeMirror and syntax highlighting) into auser_files
subdirectory in the addon directory and modify that file (it will be given precedence and not be overwritten on addon update).
To achieve a note editing friendly interface consider using:
-
CSS Injector - Change default editor styles to modify the editor interface for smaller margins, for instance something like this will give a slicker, VS Code inspired, editor interface:
/* editor.css */ div > div.editor-field { border-radius: unset; border: none !important; box-shadow: none !important; padding-left: 10px; padding-right: 10px; padding-bottom: 5px; } div:not(:nth-child(1)) > .field-container { border-top: 1px solid var(--border); } .editor-toolbar .button-toolbar { border: none; padding: 7px 7px 0px 7px; margin: 0px; } .editor-field { --fg: #3b3b3b; --selected-bg: #ADD6FF80; } .night_mode .editor-field { --fg: #d4d4d4; --selected-bg: #ADD6FF26; } body { --fg: #3b3b3b; --canvas: #ffffff; --canvas-elevated: #ffffff; --border: #CECECE; --border-focus: 1px solid #3794ff; } body.night_mode { --fg: #858585; --canvas: #1e1e1e; --canvas-elevated: #1e1e1e; --border: #474747; --border-focus: 1px solid #3794ff; }
and
/* field.css */ anki-editable.night_mode { color: var(--fg); font-size: 18px; }
-
Sidebar table to move the note/card table to the side for increased editing space, esp. with
Markdown input``Autohide toolbar
set totrue
-
Browser Maximize/Hide Table/Editor/Sidebar to toggle hiding the sidebar with a keyboard shortcut (e.g.
Ctrl+Shift+B
)
Functionality split into different classes to facilitate reuse:
- anki-md-html: library which converts Anki style HTML ↔ Markdown.
- CustomInputClass encapsulates adding an editor to the
Note editor
fields. - Editor encapsulates the CodeMirror editor.
- 2022-08-27: Add image paste support, prevent focus from being stolen on focus in/out, bug fixes.
- 2022-10-16: Make window mode non-modal (and allow multiple windows open), add
Ctrl-Shift-j
to join lines, make inline Markdown syntax configurable, make several options configurable, bug fixes. - 2022-11-20: Make rich and plain text input editable while Markdown input is visible and adjust
config.json
appropriately, add buttons/badges, restructure configuration. - 2022-12-13: Correct update
json.config
bug. - 2022-12-16: Fix multiple badges bug.
- 2022-12-20: Fix field input mode bug for *nix (tested in VM
Ubuntu 22.04 LTS
) and macOS (tested in a really slow VMHigh Sierra
). - 2022-12-22: Badge rework and bug fix
- 2023-01-09: Move to 2.1.56 platform (last 2.1.55 shipped until further notice), fix syntax highlighting.
- 2023-03-11: Restructuring of code to allow modularity with other projects and easier maintenance.
- 2023-03-12: Change "dialog mode" to "window mode" and inherit QMainWindow rather than QDialog. Add option to edit complete note in window mode, improve CSS styling of editor, now done from separate CSS file. Modify default styling (based on VS Code styles) to suit both light and dark mode. Fix anyoing eating of trailing spaces when focusing to another window. Add option to hide editor toolbar when focusing a Markdown field.
- 2023-04-26: Improve logic to fix anoying eating of trailing spaces, change search/replace dialog placement so that it is visible without having to scroll.
- 2023-05-04: Add
rich text/markdown
field default configuration option, add list continuation thanks to David C.. - 2023-06-01: Table bug fix (tables now non-optional), rename config option from
Table style
toTables
, add code block syntax highlighting, addBrowser sort field
option, add styling of cloze tags in the Markdown editor.