diff --git a/Default (Linux).sublime-keymap b/Default (Linux).sublime-keymap index af96e827..ee05f200 100644 --- a/Default (Linux).sublime-keymap +++ b/Default (Linux).sublime-keymap @@ -1084,6 +1084,12 @@ { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, + // Reset GFM tasks + { "keys": ["alt+shift+x"], "command": "mde_reset_task_list_items", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, // Toggle GFM tasks { "keys": ["alt+x"], "command": "mde_toggle_task_list_item", "context": [ @@ -1462,6 +1468,18 @@ ] }, + // navigate between critics + { "keys": ["alt+c", "alt+down"], "command": "mde_goto_next_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + { "keys": ["alt+c", "alt+up"], "command": "mde_goto_prev_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + // // Wiki // diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap index 08df0d66..0eda54e7 100644 --- a/Default (OSX).sublime-keymap +++ b/Default (OSX).sublime-keymap @@ -1084,6 +1084,12 @@ { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, + // Reset GFM tasks + { "keys": ["alt+shift+x"], "command": "mde_reset_task_list_items", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, // Toggle GFM tasks { "keys": ["alt+x"], "command": "mde_toggle_task_list_item", "context": [ @@ -1462,6 +1468,18 @@ ] }, + // navigate between critics + { "keys": ["super+alt+c", "super+alt+down"], "command": "mde_goto_next_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + { "keys": ["super+alt+c", "super+alt+up"], "command": "mde_goto_prev_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + // // Wiki // diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap index af96e827..ee05f200 100644 --- a/Default (Windows).sublime-keymap +++ b/Default (Windows).sublime-keymap @@ -1084,6 +1084,12 @@ { "key": "overlay_visible", "operator": "equal", "operand": false } ] }, + // Reset GFM tasks + { "keys": ["alt+shift+x"], "command": "mde_reset_task_list_items", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, // Toggle GFM tasks { "keys": ["alt+x"], "command": "mde_toggle_task_list_item", "context": [ @@ -1462,6 +1468,18 @@ ] }, + // navigate between critics + { "keys": ["alt+c", "alt+down"], "command": "mde_goto_next_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + { "keys": ["alt+c", "alt+up"], "command": "mde_goto_prev_critic", "context": + [ + { "key": "selector", "operator": "equal", "operand": "text.html.markdown", "match_all": true } + ] + }, + // // Wiki // diff --git a/Default.sublime-commands b/Default.sublime-commands index 52864992..1d071cef 100644 --- a/Default.sublime-commands +++ b/Default.sublime-commands @@ -205,6 +205,23 @@ "command": "mde_switch_list_bullet_type" }, + // + // Tasks + // + + { + "caption": "MarkdownEditing: Insert Task", + "command": "mde_insert_task_list_item" + }, + { + "caption": "MarkdownEditing: Toggle Task", + "command": "mde_toggle_task_list_item" + }, + { + "caption": "MarkdownEditing: Reset Tasks", + "command": "mde_reset_task_list_items" + }, + // // References // @@ -262,6 +279,19 @@ "command": "mde_reference_organize" }, + // + // CriticMarkup + // + + { + "caption": "MarkdownEditing: Goto Next Critic", + "command": "mde_goto_next_critic" + }, + { + "caption": "MarkdownEditing: Goto Previous Critic", + "command": "mde_goto_prev_critic" + }, + // // Wiki // diff --git a/docs/usage.md b/docs/usage.md index 22577279..4d743a9b 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -250,7 +250,7 @@ Further available key bindings: | Ctrl + Shift + , | + + , | Decrease block quote level (remove a `> `) | Ctrl + Enter | + Enterkbd> | Terminate block quote by adding two newline's.
If the current line is empty, block quote signs are removed. -# Lists and Tasks +# Lists List bullets are automatically changed when indenting or unindenting list items by default. This behaviour can be disabled via `"mde.list_indent_auto_switch_bullet": false`. @@ -261,12 +261,24 @@ Following commands are provided via Command Palette: * **Switch List Bullet Type** Switches the highlighted list between numbered and bulleted style. +# Tasks + +Following commands are provided via Command Palette to manage tasks: + +* **Insert Task** + Creates new GFM task (`* [ ] task`) +* **Toggle Task** + Toggles GFM task check marks (`* [x] task`) +* **Reset Tasks** + Clear all task check boxes. If non-empty selection exists, only selected tasks are reset. + Following key bindings may be used to create or toggle tasks. | Linux/Windows | MacOS | Description |---------------|-------|------------- | Alt + t | + + t | Creates new GFM task (`* [ ] task`) -| Alt + x | + + x | Toggles GFM task check marks (`* [x] task`) +| Alt + Shift + x | + + x | Clear GFM all (selected) task check marks (`* [0] task`) +| Alt + x | + x | Toggles GFM task check marks (`* [x] task`) # References @@ -321,6 +333,11 @@ Important functions are bound to following keys by default: MarkdownEditing supports document review by highlighting critic markup and enable adding critic or accepting and rejecting proposed changes via key bindings. +| Linux/Windows | MacOS | Description +|---------------|-------|------------- +| Alt + c, Alt + down | + + c, + + down | Jump to next critic marker. +| Alt + c, Alt + up | + + c, + + up | Jump to previous critic marker. + ## Reviewer A document reviewer can insert critic or propose changes for single words or selections with following key bindings: diff --git a/make.cmd b/make.cmd index 9258dfe8..d629151c 100644 --- a/make.cmd +++ b/make.cmd @@ -53,23 +53,12 @@ goto :usage :RELEASE if "%2"== "" goto :usage - git checkout st3176 && git merge st3-develop --no-ff - if not errorlevel 0 ( - echo Unable to merge st3-develop into st3176! - exit /b 1 - ) git checkout master && git merge st4-develop --no-ff if not errorlevel 0 ( echo Unable to merge st4-develop into master! exit /b 1 ) - echo Hit any key to push branches! - pause - call git push origin st3176 - if not errorlevel 0 ( - echo Failed to push st3176! - exit /b 1 - ) + call git push origin master if not errorlevel 0 ( echo Failed to push master! @@ -80,22 +69,13 @@ goto :usage echo Createing assets for "%package%"... - :: create downloadable asset for ST4126+ - set build=3176 - set archive=%package%-%2-st%build%.sublime-package - set assets="%archive%#%archive%" - call git tag -f %build%-%2 st%build% - call git archive --format zip -o "%archive%" %build%-%2 - :: create downloadable asset for ST4134+ set build=4107 set archive=%package%-%2-st%build%.sublime-package - set assets=%assets% "%archive%#%archive%" - call git tag -f %build%-%2 master - call git archive --format zip -o "%archive%" %build%-%2 + set assets="%archive%#%archive%" + call git archive --format zip -o "%archive%" master :: create the release - call git push --tags --force gh release create --target master -t "%package% %2" "%build%-%2" %assets% del /f /q *.sublime-package git fetch diff --git a/messages.json b/messages.json index 8a823144..518b2542 100644 --- a/messages.json +++ b/messages.json @@ -48,5 +48,7 @@ "3.1.11": "messages/3.1.11.md", "3.1.12": "messages/3.1.12.md", "3.1.13": "messages/3.1.13.md", - "3.1.14": "messages/3.1.14.md" + "3.1.14": "messages/3.1.14.md", + "3.2.0": "messages/3.2.0.md", + "3.3.0": "messages/3.3.0.md" } diff --git a/messages/3.2.0.md b/messages/3.2.0.md new file mode 100644 index 00000000..5dd660a7 --- /dev/null +++ b/messages/3.2.0.md @@ -0,0 +1,17 @@ +# MarkdownEditing 3.2.0 Changelog + +Your _MarkdownEditing_ plugin is updated. Enjoy new version. For any type of +feedback you can use [GitHub issues][issues]. + +## Bug Fixes + +## New Features + +* add support for auto-folding headings when loading document +* add support for pandoc fenced divs + +## Changes + +* merge shellscript related fenced code block contexts + +[issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues diff --git a/messages/3.3.0.md b/messages/3.3.0.md new file mode 100644 index 00000000..2a56f2b5 --- /dev/null +++ b/messages/3.3.0.md @@ -0,0 +1,22 @@ +# MarkdownEditing 3.3.0 Changelog + +Your _MarkdownEditing_ plugin is updated. Enjoy new version. For any type of +feedback you can use [GitHub issues][issues]. + +## Bug Fixes + +* fix `==highlight==` not being scoped at beginning of paragraphs (#789) + +## New Features + +* add `Reset Task Items` (#786) +* add `Goto Next Critic` and `Goto Previous Critic` (#787) + +## Changes + +* drop support for ST3 (latest available version for ST3 is 3.2.0) +* align frontmatter punctuation scopes with ST's default Markdown syntax +* align code fence scopes with ST's default Markdown syntax +* optimize paragraph termination patterns to improve parsing performance + +[issues]: https://github.com/SublimeText-Markdown/MarkdownEditing/issues diff --git a/plugin.py b/plugin.py index 3ef1bfd4..ee39cdfe 100644 --- a/plugin.py +++ b/plugin.py @@ -27,6 +27,10 @@ from .plugins.color_schemes import ( MdeSelectColorSchemeCommand, ) + from .plugins.critic import ( + MdeGotoNextCriticCommand, + MdeGotoPrevCriticCommand + ) from .plugins.folding import ( MdeAutoFoldListener, MdeFoldAllSectionsCommand, @@ -63,6 +67,7 @@ MdeNumberListCommand, MdeSwitchListBulletTypeCommand, MdeInsertTaskListItemCommand, + MdeResetTaskListItemsCommand, MdeToggleTaskListItemCommand, MdeJoinLines, ) diff --git a/plugins/critic.py b/plugins/critic.py new file mode 100644 index 00000000..ca7b8b4c --- /dev/null +++ b/plugins/critic.py @@ -0,0 +1,36 @@ +from bisect import bisect_left, bisect_right +from .view import MdeTextCommand + + +class MdeGotoNextCriticCommand(MdeTextCommand): + def run(self, edit): + sel = self.view.sel() + if not sel: + return + + critics = self.view.find_by_selector("markup.critic") + if not critics: + return + + idx = bisect_right(critics, sel[0]) + sel = critics[idx] if idx < len(critics) else critics[0] + self.view.sel().clear() + self.view.sel().add(sel) + self.view.show_at_center(sel) + + +class MdeGotoPrevCriticCommand(MdeTextCommand): + def run(self, edit): + sel = self.view.sel() + if not sel: + return + + critics = self.view.find_by_selector("markup.critic") + if not critics: + return + + idx = bisect_left(critics, sel[0]) - 1 + sel = critics[idx] if idx >= 0 else critics[-1] + self.view.sel().clear() + self.view.sel().add(sel) + self.view.show_at_center(sel) diff --git a/plugins/lists.py b/plugins/lists.py index 0cad48d1..22dbd0ce 100644 --- a/plugins/lists.py +++ b/plugins/lists.py @@ -196,6 +196,49 @@ def run(self, edit): self.view.insert(edit, sel.begin(), to_insert) +class MdeResetTaskListItemsCommand(MdeTextCommand): + """ + The `mde_reset_task_list_items` command resets check mark of all task list items. + + It must be called in the line of the check mark. + + **Examples:** + + ```markdown + # Ordered Task List + + 1. [ ] task 1 + 2. [x] task 2 + + # Unordered Task List + + * [ ] task 1 + - [x] task 2 + + [ ] task 3 + + # Quoted Task List + + > * [ ] task 1 + > * [x] task 2 + ``` + """ + + def run(self, edit): + sels = self.view.sel() + if not sels: + return + + # list of non-empty selections + sels = [sel for sel in sels if not sel.empty()] + + # replace all check marks by space + for mark in self.view.find_by_selector( + "text.html.markdown markup.list markup.checkbox.mark" + ): + if not sels or any(mark in sel for sel in sels): + self.view.replace(edit, mark, " ") + + class MdeToggleTaskListItemCommand(MdeTextCommand): """ The `mde_toggle_task_list_item` command toggles the check mark of task list items. diff --git a/syntaxes/Fold.tmPreferences b/syntaxes/Fold.tmPreferences index a3a3fa14..07d3bee4 100644 --- a/syntaxes/Fold.tmPreferences +++ b/syntaxes/Fold.tmPreferences @@ -31,6 +31,14 @@ excludeTrailingNewlines + + begin + punctuation.section.frontmatter.begin.markdown + end + punctuation.section.frontmatter.end.markdown + excludeTrailingNewlines + + diff --git a/syntaxes/Markdown.sublime-syntax b/syntaxes/Markdown.sublime-syntax index e3b4b103..ed539b3f 100644 --- a/syntaxes/Markdown.sublime-syntax +++ b/syntaxes/Markdown.sublime-syntax @@ -15,31 +15,37 @@ version: 2 hidden: true variables: - atx_heading: (?:[ ]{,3}[#]{1,6}(?:[ \t]|$)) # between 0 and 3 spaces, followed 1 to 6 hashes, followed by at least one space or tab or by end of the line - atx_heading_space: (?:(?=[ \t]+#+[ \t]*$)|[ \t]+|$) # consume spaces only if heading is not empty to ensure `atx_heading_end` can fully match closing hashes - atx_heading_end: (?:[ \t]+(#+))?[ \t]*($\n?) # \n is optional so ## is matched as end punctuation in new document (at eof) - setext_heading_or_paragraph: ^(?:[ ]{,3}=+|(?=[ ]{,3}\S)) # between 0 and 3 spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) - setext_heading_escape: ^(?=[ ]{,3}(?:=+|-+)[ \t]*$) # between 0 and 3 spaces, followed by at least one hyphen or equal sign (setext underline can be of any length) - setext_heading1_escape: ^(?=[ ]{,3}=+[ \t]*$) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) - setext_heading1_end: ^[ ]{,3}(=+)[ \t]*$(\n?) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) - setext_heading2_end: ^[ ]{,3}(-+)[ \t]*$(\n?) # between 0 and 3 spaces, followed by at least one hyphen (setext underline can be of any length) + # Headings + # ======== - list_setext_heading_or_paragraph: (?:[ \t]*=+|(?=[ \t]*\S)) # any number of spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) - list_setext_heading_escape: ^(?=[ \t]{2,}(?:==+|--+)[ \t]*$) # two or more spaces, followed by at least one hyphen or equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) - list_setext_heading1_escape: ^(?=[ \t]{2,}==+[ \t]*$) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) - list_setext_heading1_end: ^[ \t]{2,}(==+)[ \t]*$(\n?) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) - list_setext_heading2_end: ^[ \t]{2,}(--+)[ \t]*$(\n?) # two or more spaces, followed by at least one hyphen (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + atx_heading: (?:\#{1,6}[ \t\n]) # 1 to 6 hashes, followed by at least one space or tab or by end of the line + atx_heading_space: (?:(?=[ \t]+#+[ \t]*$)|[ \t]+|$) # consume spaces only if heading is not empty to ensure `atx_heading_end` can fully match closing hashes + atx_heading_end: (?:[ \t]+(#+))?[ \t]*($\n?) # \n is optional so ## is matched as end punctuation in new document (at eof) - block_quote: (?:[ ]{,3}(>)[ ]?) # between 0 and 3 spaces, followed by a greater than sign, (followed by any character or the end of the line = "only care about optional space!") - indented_code_block: (?:[ ]{4}|[ ]{0,3}\t) # a visual tab of width 4 consisting of 4 spaces or 0 to 3 spaces followed by 1 tab + setext_heading_or_paragraph: ^(?:[ ]{,3}=+[ \t]*$|(?=[ ]{,3}\S)) # between 0 and 3 spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) + setext_heading_escape: ^(?=[ ]{,3}(?:=+|-+)[ \t]*$) # between 0 and 3 spaces, followed by at least one hyphen or equal sign (setext underline can be of any length) + setext_heading1_escape: ^(?=[ ]{,3}=+[ \t]*$) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) + setext_heading1_end: ^[ ]{,3}(=+)[ \t]*($\n?) # between 0 and 3 spaces, followed by at least one equal sign (setext underline can be of any length) + setext_heading2_end: ^[ ]{,3}(-+)[ \t]*($\n?) # between 0 and 3 spaces, followed by at least one hyphen (setext underline can be of any length) - first_list_item: (?:[ ]{,3}(?:1[.)]|[*+-])\s) # between 0 and 3 spaces, followed by either: at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace - list_item: (?:[ ]{,3}(?:\d{1,9}[.)]|[*+-])\s) # between 0 and 3 spaces, followed by either: at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace + list_setext_heading_or_paragraph: (?:[ \t]*=+[ \t]*$|(?=[ \t]*\S)) # any number of spaces, followed by non-whitespace (consume equal signs as paragraphs may start with them) + list_setext_heading_escape: ^(?=[ \t]{2,}(?:==+|--+)[ \t]*$) # two or more spaces, followed by at least one hyphen or equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading1_escape: ^(?=[ \t]{2,}==+[ \t]*$) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading1_end: ^[ \t]{2,}(==+)[ \t]*($\n?) # two or more spaces, followed by at least one equal sign (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + list_setext_heading2_end: ^[ \t]{2,}(--+)[ \t]*($\n?) # two or more spaces, followed by at least one hyphen (setext underline can be of any length, but ST needs at least 2 to avoid ambiguity with empty list items) + + # Common Block Indicators + # ======================= + + block_quote: '>' # a greater than sign, (followed by any character or the end of the line) + indented_code_block: (?:[ ]{4}|[ ]{0,3}\t) # a visual tab of width 4 consisting of 4 spaces or 0 to 3 spaces followed by 1 tab + + first_list_item: (?:(?:1[.)]|[*+-])[ \t\n]) # at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace + list_item: (?:(?:\d{1,9}[.)]|[*+-])[ \t\n]) # at least one integer and a full stop or a parenthesis, or (a star, plus or dash), followed by whitespace thematic_break: |- (?x: - [ ]{,3} # between 0 to 3 spaces (?: # followed by one of the following: [-](?:[ \t]*[-]){2,} # - a dash, followed by the following at least twice: any number of spaces or tabs followed by a dash | [*](?:[ \t]*[*]){2,} # - a star, followed by the following at least twice: any number of spaces or tabs followed by a star @@ -48,97 +54,23 @@ variables: [ \t]*$ # followed by any number of tabs or spaces, followed by the end of the line ) - backticks: |- - (?x: - (`{4})[^`](?:[^`]|(?!`{4})`+[^`])*(`{4})(?!`) # 4 backticks, followed by at least one non backtick character, followed by (less than 4 backticks, or at least one non backtick character) at least once, followed by exactly 4 backticks - | (`{3})[^`](?:[^`]|(?!`{3})`+[^`])*(`{3})(?!`) # 3 backticks, followed by at least one non backtick character, followed by (less than 3 backticks, or at least one non backtick character) at least once, followed by exactly 3 backticks - | (`{2})[^`](?:[^`]|(?!`{2})`+[^`])*(`{2})(?!`) # 2 backticks, followed by at least one non backtick character, followed by (less than 2 backticks, or at least one non backtick character) at least once, followed by exactly 2 backticks - | (`{1})[^`](?:[^`]|(?!`{1})`+[^`])*(`{1})(?!`) # 1 backtick, followed by at least one non backtick character, followed by ( at least one non backtick character) at least once, followed by exactly 1 backtick - ) - escapes: \\[-+*/!"#$%&'(),.:;<=>?@\[\\\]^_`{|}~] - - balance_square_brackets: |- - (?x: - (?: - \\. # maybe escaped character (be lazy) - | [^\[\]`] # anything that isn't a square bracket or backtick - | {{backticks}} # inline code - | \[ (?: # nested square brackets (one level deep) - \\. # maybe escaped character (be lazy) - | [^\[\]`] # anything that isn't a square bracket or backtick - | {{backticks}} # inline code - )* \] # closing square bracket - )+ - ) - balance_square_brackets_and_emphasis: |- - (?x: - (?: - \\. # maybe escaped character (be lazy) - | [^\[\]`_*] # anything that isn't a square bracket, backtick or emphasis - | {{backticks}} # inline code - | \[ (?: # nested square brackets (one level deep) - \\. # maybe escaped character (be lazy) - | [^\[\]`_*] # anything that isn't a square bracket, backtick or emphasis - | {{backticks}} # inline code - )* \] # closing square bracket - )+ # at least one character - ) - balance_square_brackets_pipes_and_emphasis: |- - (?x: - (?: - \\. # maybe escaped character (be lazy) - | [^\[\]`_*|] # anything that isn't a square bracket, backtick or emphasis or table cell separator - | {{backticks}} # inline code - | \[ (?: # nested square brackets (one level deep) - \\. # maybe escaped character (be lazy) - | [^\[\]`_*|] # anything that isn't a square bracket, backtick or emphasis or table cell separator - | {{backticks}} # inline code - )* \] # closing square bracket - )+ # at least one character - ) - balanced_emphasis: |- - (?x: - \* (?!\*){{balance_square_brackets_and_emphasis}}\* (?!\*) - | \*\* {{balance_square_brackets_and_emphasis}}\*\* - | _ (?!_) {{balance_square_brackets_and_emphasis}}_ (?!_) - | __ {{balance_square_brackets_and_emphasis}}__ - ) - - table_cell: |- - (?x: - # Pipes inside other inline spans (such as emphasis, code, etc.) will not break a cell, - # emphasis in table cells can't span multiple lines - (?: - {{balance_square_brackets_pipes_and_emphasis}} - | {{balanced_emphasis}} - )+ # at least one character - ) - table_first_row: |- - (?x: - # at least 2 non-escaped pipe chars on the line - (?:{{table_cell}}?\|){2} - - # something other than whitespace followed by a pipe char or hyphen, - # followed by something other than whitespace and the end of the line - | (?! \s*\-\s+ | \s+\|){{table_cell}}\|(?!\s+$) - ) + # Fenced code blocks + # ================== - table_codespan_content: |- + fenced_code_block: |- (?x: - [^`|] # first or only char must not be a backtick or pipe. - (?:[^|]*?[^`|])? # none must be a pipe, the last additionally must not be a backtick + (`){3,} # 3 or more backticks + (?![^`]*`) # not followed by any more backticks on the same line + | # or + (~){3,} # 3 or more tildas ) fenced_code_block_start: |- (?x: ([ \t]*) - ( - (`){3,} # 3 or more backticks - (?![^`]*`) # not followed by any more backticks on the same line - | # or - (~){3,} # 3 or more tildas - ) + ({{fenced_code_block}}) ) + fenced_code_block_language: |- (?x: # first word of an infostring is used as language specifier \s* # allow for whitespace between code block start and info string @@ -147,6 +79,7 @@ variables: [^\s:;`]* # optionally followed by any nonwhitespace character (except backticks) ) ) + fenced_code_block_trailing_infostring_characters: |- (?x: (?: @@ -155,6 +88,7 @@ variables: )? (\s*$\n?) # ... until EOL (fold begin marker) ) + fenced_code_block_end: |- (?x: [ \t]* @@ -164,29 +98,26 @@ variables: ) (\s*$\n?) # any amount of whitespace until EOL (fold end marker) ) + fenced_code_block_escape: ^{{fenced_code_block_end}} # https://pandoc.org/MANUAL.html#divs-and-spans - fenced_div_block: '[ \t]*(:{3,})' + fenced_div_block: ':{3,}' - # https://spec.commonmark.org/0.30/#email-autolink - email_domain_commonmark: '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?' - email_user_commonmark: '[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+' + # HTML blocks + # =========== # https://spec.commonmark.org/0.30/#html-blocks html_block: |- (?x: - [ ]{,3} - (?: - {{html_tag_block_end_at_close_tag}} # html block type 1 - | {{html_tag_block_end_at_blank_line}} # html block type 6 - | {{html_block_open_tag}} # html block type 7 - | {{html_block_close_tag}} # html block type 7 - | {{html_block_comment}} # html block type 2 - | {{html_block_decl}} # html block type 4 - | {{html_block_cdata}} # html block type 5 - | {{html_block_preprocessor}} # html block type 3 - ) + {{html_tag_block_end_at_close_tag}} # html block type 1 + | {{html_tag_block_end_at_blank_line}} # html block type 6 + | {{html_block_open_tag}} # html block type 7 + | {{html_block_close_tag}} # html block type 7 + | {{html_block_comment}} # html block type 2 + | {{html_block_decl}} # html block type 4 + | {{html_block_cdata}} # html block type 5 + | {{html_block_preprocessor}} # html block type 3 ) html_block_comment: