diff --git a/app/build.gradle b/app/build.gradle index 7a1a3544e..23fced5e9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -134,6 +134,7 @@ dependencies { implementation "com.vladsch.flexmark:flexmark-ext-footnotes:${version_library_flexmark}" implementation "com.vladsch.flexmark:flexmark-ext-gitlab:${version_library_flexmark}" implementation "com.vladsch.flexmark:flexmark-ext-typographic:${version_library_flexmark}" + implementation "com.vladsch.flexmark:flexmark-ext-admonition:${version_library_flexmark}" // UI libs implementation 'com.pixplicity.generate:library:1.1.8' diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java index 0e36944c5..5e8f83e11 100644 --- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java +++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java @@ -13,6 +13,7 @@ import android.support.annotation.NonNull; import android.text.TextUtils; +import com.vladsch.flexmark.ext.admonition.AdmonitionExtension; import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension; import com.vladsch.flexmark.ext.autolink.AutolinkExtension; import com.vladsch.flexmark.ext.emoji.EmojiExtension; @@ -98,6 +99,10 @@ public class MarkdownTextConverter extends TextConverter { public static final String HTML_MERMAID_INCLUDE = ""; + public static final String HTML_ADMONITION_INCLUDE = "" + + ""; + public static final String CSS_ADMONITION = CSS_S + ".adm-block { width: initial; font-size: 90%; text-indent: 0em; } .adm-heading { height: auto; padding-top: 0.4em; padding-left: 2.2em; padding-bottom: 0.4em; } .adm-body { padding-top: 0.25em; padding-bottom: 0.25em; margin-left: 0.5em; margin-right: 0.5em; } .adm-icon { position: absolute; top: 50%; left: 0.5em; transform: translateY(-50%); } .adm-block > .adm-heading { position: relative; cursor: pointer; } .adm-block.adm-open > .adm-heading:after, .adm-block.adm-collapsed > .adm-heading:after { top: 50%; transform: translateY(-50%); content: '▼'; } .adm-block.adm-collapsed > .adm-heading:after { content: '◀'; } pre + div.adm-block, div.adm-block + pre { margin-top: 1.75em; }" + CSS_E; + //######################## //## Converter library //######################## @@ -120,6 +125,7 @@ public class MarkdownTextConverter extends TextConverter { YamlFrontMatterExtension.create(), TypographicExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Typographic-Extension GitLabExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Extensions#gitlab-flavoured-markdown + AdmonitionExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Extensions#admonition FootnoteExtension.create() // https://github.com/vsch/flexmark-java/wiki/Footnotes-Extension#overview ); private static final Parser flexmarkParser = Parser.builder().extensions(flexmarkExtensions).build(); @@ -204,11 +210,16 @@ public String convertMarkup(String markup, Context context, boolean isExportInLi head += HTML_MERMAID_INCLUDE; } + // Enable flexmark Admonition support + if (markup.contains("!!!") || markup.contains("???")) { + head += HTML_ADMONITION_INCLUDE; + head += CSS_ADMONITION; + } + // Enable View (block) code syntax highlighting final String xt = getViewHlPrismIncludes(context, (appSettings.isDarkThemeEnabled() ? "-tomorrow" : "")); head += xt; - // Jekyll: Replace {{ site.baseurl }} with ..--> usually used in Jekyll blog _posts folder which is one folder below repository root, for reference to e.g. pictures in assets folder markup = markup.replace("{{ site.baseurl }}", "..").replace(TOKEN_SITE_DATE_JEKYLL, TOKEN_POST_TODAY_DATE); diff --git a/app/src/main/java/net/gsantner/markor/ui/NewFileDialog.java b/app/src/main/java/net/gsantner/markor/ui/NewFileDialog.java index dc3de224b..8e3482d9b 100644 --- a/app/src/main/java/net/gsantner/markor/ui/NewFileDialog.java +++ b/app/src/main/java/net/gsantner/markor/ui/NewFileDialog.java @@ -233,7 +233,7 @@ private byte[] getTemplateContent(final Spinner templateSpinner, final File base byte[] bytes = null; switch (templateSpinner.getSelectedItemPosition()) { case 1: { - t = "# Markdown Reference\nAutomatically generate _table of contents_ by checking the option here: `Settings > Format > Markdown`.\n\n## H2 Header\n### H3 header\n#### H4 Header\n##### H5 Header\n###### H6 Header\n\n\n\n## Format Text\n\n*Italic emphasis* , _Alternative italic emphasis_\n\n**Bold emphasis** , __Alternative bold emphasis__\n\n~~Strikethrough~~\n\nBreak line (two spaces at end of line) \n\n> Block quote\n\n`Inline code`\n\n```\nCode blocks\nare\nawesome\n```\n\n\n \n## Lists\n### Ordered & unordered\n\n* Unordered list\n* ...with asterisk/star\n* Test\n\n- Another unordered list\n- ...with hyphen/minus\n- Test\n\n1. Ordered list\n2. Test\n3. Test\n4. Test\n\n- Nested lists\n * Unordered nested list\n * Test\n * Test\n * Test\n- Ordered nested list\n 1. Test\n 2. Test\n 3. Test\n 4. Test\n- Double-nested unordered list\n - Test\n - Unordered\n - Test a\n - Test b\n - Ordered\n 1. Test 1\n 2. Test 2\n\n### Checklist\n* [ ] Salad\n* [x] Potatoes\n\n1. [x] Clean\n2. [ ] Cook\n\n\n\n## Links\n[Link](https://duckduckgo.com/)\n\n[File in same folder as the document.](markor-markdown-reference.md) Use %20 for spaces!\n\n\n\n## Tables\n\n| Left aligned | Middle aligned | Right aligned |\n| :--------------- | :------------------: | -----------------: |\n| Test | Test | Test |\n| Test | Test | Test |\n\n÷÷÷÷\n\nShorter | Table | Syntax\n:---: | ---: | :---\nTest | Test | Test\nTest | Test | Test\n\n\n\n\n\n## Math (KaTeX)\nSee [reference](https://katex.org/docs/supported.html) & [examples](https://github.com/waylonflinn/markdown-it-katex/blob/master/README.md). Enable by checking Math at `Settings > Markdown`.\n\n### Math inline\n\n$ I = \\frac V R $\n\n### Math block\n\n$$\\begin{array}{c} \\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\ \\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\ \\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \\end{array}$$\n\n\n$$\\frac{k_t}{k_e} = \\sqrt{2}$$\n\n\n\n## Format Text (continued)\n\n### Text color\n\nText with background color / highlight\n\nText foreground color\n\nText with colored outline / Text with colored outline\n\n\n### Text sub & superscript\n\nUnderline\n\nThe Subway sandwich was super\n\nSuper special characters: ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ™ ® ℠\n\n### Text positioning\n
\n\ntext on the **right**\n\n
\n\n
\n\ntext in the **center** \n(one empy line above and below \nrequired for Markdown support OR markdown='1')\n\n
\n\n### Block Text\n\n
\nlorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. \n
\n\n### Dropdown\n\n
Click to Expand/Collapse\n\nExpanded content. Shows up and keeps visible when clicking expand. Hide again by clicking the dropdown button again.\n\n
\n\n\n\n\n## Multimedia\n\n### Images\n![Image](https://gsantner.net/assets/blog/img/markor/markor-v1-7-showcase-3.jpg)\n\n### Videos\n**Youtube** [Welcome to Upper Austria](https://www.youtube.com/watch?v=RJREFH7Lmm8)\n\n\n**Peertube** [Road in the wood](https://open.tube/videos/watch/8116312a-dbbd-43a3-9260-9ea6367c72fc)\n
\n\n\n\n### Audio & Music\n**Web audio** [Guifrog - Xia Yu](https://www.freemusicarchive.org/music/Guifrog/Xia_Yu)\n\n\n**Local audio** Yellowcard - Lights up in the sky\n\n\n------------------\n\nThis Markdown reference file was created for the [Markor](https://gsantner.net/project/markor?source=markdownref) project by [Gregor Santner](https://gsantner.net) and is licensed [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (public domain). File revision 2.\n\n------------------\n\n\n"; + t = "# Markdown Reference\nAutomatically generate _table of contents_ by checking the option here: `Settings > Format > Markdown`.\n\n## H2 Header\n### H3 header\n#### H4 Header\n##### H5 Header\n###### H6 Header\n\n\n\n## Format Text\n\n*Italic emphasis* , _Alternative italic emphasis_\n\n**Bold emphasis** , __Alternative bold emphasis__\n\n~~Strikethrough~~\n\nBreak line (two spaces at end of line) \n\n> Block quote\n\n`Inline code`\n\n```\nCode blocks\nare\nawesome\n```\n\n\n \n## Lists\n### Ordered & unordered\n\n* Unordered list\n* ...with asterisk/star\n* Test\n\n- Another unordered list\n- ...with hyphen/minus\n- Test\n\n1. Ordered list\n2. Test\n3. Test\n4. Test\n\n- Nested lists\n * Unordered nested list\n * Test\n * Test\n * Test\n- Ordered nested list\n 1. Test\n 2. Test\n 3. Test\n 4. Test\n- Double-nested unordered list\n - Test\n - Unordered\n - Test a\n - Test b\n - Ordered\n 1. Test 1\n 2. Test 2\n\n### Checklist\n* [ ] Salad\n* [x] Potatoes\n\n1. [x] Clean\n2. [ ] Cook\n\n\n\n## Links\n[Link](https://duckduckgo.com/)\n\n[File in same folder as the document.](markor-markdown-reference.md) Use %20 for spaces!\n\n\n\n## Tables\n\n| Left aligned | Middle aligned | Right aligned |\n| :--------------- | :------------------: | -----------------: |\n| Test | Test | Test |\n| Test | Test | Test |\n\n÷÷÷÷\n\nShorter | Table | Syntax\n:---: | ---: | :---\nTest | Test | Test\nTest | Test | Test\n\n\n\n\n\n## Math (KaTeX)\nSee [reference](https://katex.org/docs/supported.html) & [examples](https://github.com/waylonflinn/markdown-it-katex/blob/master/README.md). Enable by checking Math at `Settings > Markdown`.\n\n### Math inline\n\n$ I = \\frac V R $\n\n### Math block\n\n$$\\begin{array}{c} \\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\ \\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\ \\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \\end{array}$$\n\n\n$$\\frac{k_t}{k_e} = \\sqrt{2}$$\n\n\n\n## Format Text (continued)\n\n### Text color\n\nText with background color / highlight\n\nText foreground color\n\nText with colored outline / Text with colored outline\n\n\n### Text sub & superscript\n\nUnderline\n\nThe Subway sandwich was super\n\nSuper special characters: ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ™ ® ℠\n\n### Text positioning\n
\n\ntext on the **right**\n\n
\n\n
\n\ntext in the **center** \n(one empy line above and below \nrequired for Markdown support OR markdown='1')\n\n
\n\n### Block Text\n\n
\nlorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. \n
\n\n### Dropdown\n\n
Click to Expand/Collapse\n\nExpanded content. Shows up and keeps visible when clicking expand. Hide again by clicking the dropdown button again.\n\n
\n\n\n\n\n## Multimedia\n\n### Images\n![Image](https://gsantner.net/assets/blog/img/markor/markor-v1-7-showcase-3.jpg)\n\n### Videos\n**Youtube** [Welcome to Upper Austria](https://www.youtube.com/watch?v=RJREFH7Lmm8)\n\n\n**Peertube** [Road in the wood](https://open.tube/videos/watch/8116312a-dbbd-43a3-9260-9ea6367c72fc)\n
\n\n\n\n### Audio & Music\n**Web audio** [Guifrog - Xia Yu](https://www.freemusicarchive.org/music/Guifrog/Xia_Yu)\n\n\n**Local audio** Yellowcard - Lights up in the sky\n\n\n## Admonition Extension\nCreate block-styled side content. \nUse one of these qualifiers to select the icon and the block color: abstract, summary, tldr, bug, danger, error, example, snippet, failure, fail, missing, question, help, faq, info, todo, note, seealso, quote, cite, success, check, done, tip, hint, important, warning, caution, attention.\n\n!!! warning 'Optional Title'\n Block-Styled Side Content with **Markdown support**\n\n!!! info ''\n No-Heading Content\n\n??? bug 'Collapsed by default'\n Collapsible Block-Styled Side Content\n\n???+ example 'Open by default'\n Collapsible Block-Styled Side Content\n\n------------------\n\nThis Markdown reference file was created for the [Markor](https://gsantner.net/project/markor?source=markdownref) project by [Gregor Santner](https://gsantner.net) and is licensed [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (public domain). File revision 3.\n\n------------------\n\n\n"; break; } case 2: { diff --git a/app/thirdparty/assets/flexmark/admonition.css b/app/thirdparty/assets/flexmark/admonition.css new file mode 100644 index 000000000..9ec268acf --- /dev/null +++ b/app/thirdparty/assets/flexmark/admonition.css @@ -0,0 +1,265 @@ +.adm-block { + display: block; + width: 99%; + border-radius: 6px; + padding-left: 10px; + margin-bottom: 1em; + border: 1px solid; + border-left-width: 4px; + box-shadow: 2px 2px 6px #cdcdcd; +} + +.adm-heading { + display: block; + font-weight: bold; + font-size: 0.9em; + height: 1.8em; + padding-top: 0.3em; + padding-bottom: 2em; + border-bottom: solid 1px; + padding-left: 10px; + margin-left: -10px; +} + +.adm-body { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 1.5em; + margin-right: 1.5em; +} + +.adm-heading > span { + color: initial; +} + +.adm-icon { + height: 1.6em; + width: 1.6em; + display: inline-block; + vertical-align: middle; + margin-right: 0.25em; + margin-left: -0.25em; +} + +.adm-hidden { + display: none !important; +} + +.adm-block.adm-collapsed > .adm-heading, .adm-block.adm-open > .adm-heading { + position: relative; + cursor: pointer; +} + +.adm-block.adm-collapsed > .adm-heading { + margin-bottom: 0; +} + +.adm-block.adm-collapsed .adm-body { + display: none !important; +} + +.adm-block.adm-open > .adm-heading:after, +.adm-block.adm-collapsed > .adm-heading:after { + display: inline-block; + position: absolute; + top:calc(50% - .65em); + right: 0.5em; + font-size: 1.3em; + content: '▼'; +} + +.adm-block.adm-collapsed > .adm-heading:after { + right: 0.50em; + top:calc(50% - .75em); + transform: rotate(90deg); +} + +/* default scheme */ + +.adm-block { + border-color: #ebebeb; + border-bottom-color: #bfbfbf; +} + +.adm-block.adm-abstract { + border-left-color: #48C4FF; +} + +.adm-block.adm-abstract .adm-heading { + background: #E8F7FF; + color: #48C4FF; + border-bottom-color: #dbf3ff; +} + +.adm-block.adm-abstract.adm-open > .adm-heading:after, +.adm-block.adm-abstract.adm-collapsed > .adm-heading:after { + color: #80d9ff; +} + + +.adm-block.adm-bug { + border-left-color: #F50057; +} + +.adm-block.adm-bug .adm-heading { + background: #FEE7EE; + color: #F50057; + border-bottom-color: #fcd9e4; +} + +.adm-block.adm-bug.adm-open > .adm-heading:after, +.adm-block.adm-bug.adm-collapsed > .adm-heading:after { + color: #f57aab; +} + +.adm-block.adm-danger { + border-left-color: #FE1744; +} + +.adm-block.adm-danger .adm-heading { + background: #FFE9ED; + color: #FE1744; + border-bottom-color: #ffd9e0; +} + +.adm-block.adm-danger.adm-open > .adm-heading:after, +.adm-block.adm-danger.adm-collapsed > .adm-heading:after { + color: #fc7e97; +} + +.adm-block.adm-example { + border-left-color: #7940ff; +} + +.adm-block.adm-example .adm-heading { + background: #EFEBFF; + color: #7940ff; + border-bottom-color: #e0d9ff; +} + +.adm-block.adm-example.adm-open > .adm-heading:after, +.adm-block.adm-example.adm-collapsed > .adm-heading:after { + color: #b199ff; +} + +.adm-block.adm-fail { + border-left-color: #FE5E5E; +} + +.adm-block.adm-fail .adm-heading { + background: #FFEEEE; + color: #Fe5e5e; + border-bottom-color: #ffe3e3; +} + +.adm-block.adm-fail.adm-open > .adm-heading:after, +.adm-block.adm-fail.adm-collapsed > .adm-heading:after { + color: #fcb1b1; +} + +.adm-block.adm-faq { + border-left-color: #5ED116; +} + +.adm-block.adm-faq .adm-heading { + background: #EEFAE8; + color: #5ED116; + border-bottom-color: #e6fadc; +} + +.adm-block.adm-faq.adm-open > .adm-heading:after, +.adm-block.adm-faq.adm-collapsed > .adm-heading:after { + color: #98cf72; +} + +.adm-block.adm-info { + border-left-color: #00B8D4; +} + +.adm-block.adm-info .adm-heading { + background: #E8F7FA; + color: #00B8D4; + border-bottom-color: #dcf5fa; +} + +.adm-block.adm-info.adm-open > .adm-heading:after, +.adm-block.adm-info.adm-collapsed > .adm-heading:after { + color: #83ced6; +} + +.adm-block.adm-note { + border-left-color: #448AFF; +} + +.adm-block.adm-note .adm-heading { + background: #EDF4FF; + color: #448AFF; + border-bottom-color: #e0edff; +} + +.adm-block.adm-note.adm-open > .adm-heading:after, +.adm-block.adm-note.adm-collapsed > .adm-heading:after { + color: #8cb8ff; +} + +.adm-block.adm-quote { + border-left-color: #9E9E9E; +} + +.adm-block.adm-quote .adm-heading { + background: #F4F4F4; + color: #9E9E9E; + border-bottom-color: #e8e8e8; +} + +.adm-block.adm-quote.adm-open > .adm-heading:after, +.adm-block.adm-quote.adm-collapsed > .adm-heading:after { + color: #b3b3b3; +} + +.adm-block.adm-success { + border-left-color: #1DCD63; +} + +.adm-block.adm-success .adm-heading { + background: #E9F8EE; + color: #1DCD63; + border-bottom-color: #dcf7e5; +} + +.adm-block.adm-success.adm-open > .adm-heading:after, +.adm-block.adm-success.adm-collapsed > .adm-heading:after { + color: #7acc98; +} + +.adm-block.adm-tip { + border-left-color: #01BFA5; +} + +.adm-block.adm-tip .adm-heading { + background: #E9F9F6; + color: #01BFA5; + border-bottom-color: #dcf7f2; +} + +.adm-block.adm-tip.adm-open > .adm-heading:after, +.adm-block.adm-tip.adm-collapsed > .adm-heading:after { + color: #7dd1c0; +} + +.adm-block.adm-warning { + border-left-color: #FF9001; +} + +.adm-block.adm-warning .adm-heading { + background: #FEF3E8; + color: #FF9001; + border-bottom-color: #Fef3e8; +} + +.adm-block.adm-warning.adm-open > .adm-heading:after, +.adm-block.adm-warning.adm-collapsed > .adm-heading:after { + color: #fcbb6a; +} + diff --git a/app/thirdparty/assets/flexmark/admonition.js b/app/thirdparty/assets/flexmark/admonition.js new file mode 100644 index 000000000..560c91f3a --- /dev/null +++ b/app/thirdparty/assets/flexmark/admonition.js @@ -0,0 +1,31 @@ +(() => { +/* begin change from upstream admonition.js */ + document.addEventListener("DOMContentLoaded", function() { +/* end change */ + let divs = document.getElementsByClassName("adm-block"); + for (let i = 0; i < divs.length; i++) { + let div = divs[i]; + if (div.classList.contains("adm-collapsed") || div.classList.contains("adm-open")) { + let headings = div.getElementsByClassName("adm-heading"); + if (headings.length > 0) { + headings[0].addEventListener("click", event => { + let el = div; + event.preventDefault(); + event.stopImmediatePropagation(); + if (el.classList.contains("adm-collapsed")) { + console.debug("Admonition Open", event.srcElement); + el.classList.remove("adm-collapsed"); + el.classList.add("adm-open"); + } else { + console.debug("Admonition Collapse", event.srcElement); + el.classList.add("adm-collapsed"); + el.classList.remove("adm-open"); + } + }); + } + } + } +/* begin change from upstream admonition.js */ +}) +/* end change */ +})(); diff --git a/samples/markor-markdown-reference.md b/samples/markor-markdown-reference.md index b0396c014..018ccd311 100644 --- a/samples/markor-markdown-reference.md +++ b/samples/markor-markdown-reference.md @@ -195,9 +195,26 @@ Relevant for creating printable pages from the document (Print / PDF). **Local audio** Yellowcard - Lights up in the sky + +## Admonition Extension +Create block-styled side content. +Use one of these qualifiers to select the icon and the block color: abstract, summary, tldr, bug, danger, error, example, snippet, failure, fail, missing, question, help, faq, info, todo, note, seealso, quote, cite, success, check, done, tip, hint, important, warning, caution, attention. + +!!! warning 'Optional Title' + Block-Styled Side Content with **Markdown support** + +!!! info '' + No-Heading Content + +??? bug 'Collapsed by default' + Collapsible Block-Styled Side Content + +???+ example 'Open by default' + Collapsible Block-Styled Side Content + ------------------ -This Markdown reference file was created for the [Markor](https://gsantner.net/project/markor?source=markdownref) project by [Gregor Santner](https://gsantner.net) and is licensed [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (public domain). File revision 2. +This Markdown reference file was created for the [Markor](https://gsantner.net/project/markor?source=markdownref) project by [Gregor Santner](https://gsantner.net) and is licensed [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (public domain). File revision 3. ------------------