From dcf40fc104b5dc06f621216874d14c4a64d9f5fc Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Wed, 14 Jun 2023 22:21:54 +0900 Subject: [PATCH 01/39] =?UTF-8?q?=F0=9F=93=9A=20Fix=20CI=20badge=20link=20?= =?UTF-8?q?(#291)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ff747ef..5573b622 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Big thanks to the authors of [markdown-it]: Also [John MacFarlane](https://github.com/jgm) for his work on the CommonMark spec and reference implementations. -[github-ci]: https://github.com/executablebooks/markdown-it-py/workflows/Python%20package/badge.svg?branch=master +[github-ci]: https://github.com/executablebooks/markdown-it-py/actions/workflows/tests.yml/badge.svg?branch=master [github-link]: https://github.com/executablebooks/markdown-it-py [pypi-badge]: https://img.shields.io/pypi/v/markdown-it-py.svg [pypi-link]: https://pypi.org/project/markdown-it-py From a095740cd754dccc572b77252790f23aa84c8430 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 27 Jun 2023 20:45:36 +0200 Subject: [PATCH 02/39] =?UTF-8?q?=F0=9F=93=9A=20Update=20docs=20(#292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++++-- benchmarking/bench_packages.py | 9 +++++++++ docs/_static/markdown-it-py.svg | 24 ++++++++++++++++++++++++ docs/architecture.md | 2 +- docs/conf.py | 3 +++ docs/contributing.md | 2 +- docs/index.md | 3 ++- docs/performance.md | 28 ++++++++++++++++++++++++++++ docs/{other.md => security.md} | 31 ------------------------------- pyproject.toml | 5 +++-- 10 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 docs/_static/markdown-it-py.svg create mode 100644 docs/performance.md rename docs/{other.md => security.md} (51%) diff --git a/README.md b/README.md index 5573b622..ddb6fb59 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ For details on [markdown-it] itself, see: - The __[Live demo](https://markdown-it.github.io)__ - [The markdown-it README][markdown-it-readme] +**See also:** [markdown-it-pyrs](https://github.com/chrisjsewell/markdown-it-pyrs) for an experimental Rust binding, +for even more speed! + ## Installation ```bash @@ -143,6 +146,6 @@ Also [John MacFarlane](https://github.com/jgm) for his work on the CommonMark sp [CommonMark spec]: http://spec.commonmark.org/ [markdown-it]: https://github.com/markdown-it/markdown-it [markdown-it-readme]: https://github.com/markdown-it/markdown-it/blob/master/README.md -[md-security]: https://markdown-it-py.readthedocs.io/en/latest/other.html -[md-performance]: https://markdown-it-py.readthedocs.io/en/latest/other.html +[md-security]: https://markdown-it-py.readthedocs.io/en/latest/security.html +[md-performance]: https://markdown-it-py.readthedocs.io/en/latest/performance.html [md-plugins]: https://markdown-it-py.readthedocs.io/en/latest/plugins.html diff --git a/benchmarking/bench_packages.py b/benchmarking/bench_packages.py index 1158750e..084557a9 100644 --- a/benchmarking/bench_packages.py +++ b/benchmarking/bench_packages.py @@ -18,6 +18,15 @@ def test_markdown_it_py(benchmark, spec_text): benchmark(parser.render, spec_text) +@pytest.mark.benchmark(group="packages") +def test_markdown_it_pyrs(benchmark, spec_text): + import markdown_it_pyrs + + parser = markdown_it_pyrs.MarkdownIt("commonmark") + benchmark.extra_info["version"] = markdown_it_pyrs.__version__ + benchmark(parser.render, spec_text) + + @pytest.mark.benchmark(group="packages") def test_mistune(benchmark, spec_text): import mistune diff --git a/docs/_static/markdown-it-py.svg b/docs/_static/markdown-it-py.svg new file mode 100644 index 00000000..9ac486af --- /dev/null +++ b/docs/_static/markdown-it-py.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/architecture.md b/docs/architecture.md index bebcf9dc..5190bbd2 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,6 +1,6 @@ (md/architecture)= -# markdown-it design principles +# Design principles (md/data-flow)= ## Data flow diff --git a/docs/conf.py b/docs/conf.py index 4fa12262..ed38bb50 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,8 +64,11 @@ # a list of builtin themes. # html_title = "markdown-it-py" +html_logo = html_favicon = "_static/markdown-it-py.svg" html_theme = "sphinx_book_theme" html_theme_options = { + "home_page_in_toc": True, + "use_repository_button": True, "use_edit_page_button": True, "repository_url": "https://github.com/executablebooks/markdown-it-py", "repository_branch": "master", diff --git a/docs/contributing.md b/docs/contributing.md index 6c43e0e0..d553c451 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,4 +1,4 @@ -# Contribute to markdown-it-py +# Contribute We welcome all contributions! ✨ diff --git a/docs/index.md b/docs/index.md index bff3ac31..96827f74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -33,7 +33,8 @@ Also [John MacFarlane](https://github.com/jgm) for his work on the CommonMark sp using architecture -other +security +performance plugins contributing api/markdown_it diff --git a/docs/performance.md b/docs/performance.md new file mode 100644 index 00000000..d75c2159 --- /dev/null +++ b/docs/performance.md @@ -0,0 +1,28 @@ +(md/performance)= + +# Performance + +You can view our continuous integration benchmarking analysis at: , +or you can run it for yourself within the repository: + +```bash +tox -e py311-bench-packages -- --benchmark-columns mean,stddev +``` + +| package | version | mean (ms) | stddev | +| -------------------- | ------- | --------- | ------- | +| markdown-it-pyrs[^1] | 0.2.1 | 6.410 | 0.426 | +| mistune[^2] | 3.0.1 | 80.409 | 2.335 | +| **markdown-it-py** | 3.0.0 | 97.242 | 4.427 | +| mistletoe | 1.1.0 | 99.633 | 4.628 | +| commonmark-py | 0.9.1 | 300.403 | 9.706 | +| pymarkdown | 3.4.3 | 387.775 | 10.394 | +| pymarkdown (+extras) | 3.4.3 | 646.564 | 11.316 | +| panflute | 2.3.0 | 860.105 | 208.607 | + +As you can see, `markdown-it-py` doesn't pay with speed for it's flexibility. + +[^1]: `markdown-it-pyrs` is a Rust implementation of `markdown-it-py`'s parser, in beta development, check it out at: +[^2]: `mistune` is not CommonMark compliant, which is what allows for its +faster parsing, at the expense of issues, for example, with nested inline parsing. +See [mistletoes's explanation](https://github.com/miyuchina/mistletoe/blob/master/performance.md) for further details. diff --git a/docs/other.md b/docs/security.md similarity index 51% rename from docs/other.md rename to docs/security.md index cfc5ba8c..3770d35a 100644 --- a/docs/other.md +++ b/docs/security.md @@ -33,34 +33,3 @@ If those depend on user input - always add prefixes to avoid DOM clobbering. See [discussion](https://github.com/markdown-it/markdown-it/issues/28) for details. So, if you decide to use plugins that add extended class syntax or autogenerating header anchors - be careful. - -(md/performance)= - -# Performance - -You can view our continuous integration benchmarking analysis at: , -or you can run it for yourself within the repository: - -```console -$ tox -e py38-bench-packages -- --benchmark-columns mean,stddev - -Name (time in ms) Mean StdDev ---------------------------------------------------------------- -test_mistune 70.3272 (1.0) 0.7978 (1.0) -test_mistletoe 116.0919 (1.65) 6.2870 (7.88) -test_markdown_it_py 152.9022 (2.17) 4.2988 (5.39) -test_commonmark_py 326.9506 (4.65) 15.8084 (19.81) -test_pymarkdown 368.2712 (5.24) 7.5906 (9.51) -test_pymarkdown_extra 640.4913 (9.11) 15.1769 (19.02) -test_panflute 678.3547 (9.65) 9.4622 (11.86) ---------------------------------------------------------------- -``` - -As you can see, `markdown-it-py` doesn't pay with speed for it's flexibility. - -```{note} -`mistune` is not CommonMark compliant, which is what allows for its -faster parsing, at the expense of issues, for example, with nested inline parsing. -See [mistletoes's explanation](https://github.com/miyuchina/mistletoe/blob/master/performance.md) -for further details. -``` diff --git a/pyproject.toml b/pyproject.toml index ea7cd036..46cbc762 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,13 +39,14 @@ compare = [ "commonmark~=0.9", "markdown~=3.4", "mistletoe~=1.0", - "mistune~=2.0", + "mistune~=3.0", "panflute~=2.3", + "markdown-it-pyrs", ] linkify = ["linkify-it-py>=1,<3"] plugins = ["mdit-py-plugins"] rtd = [ - "mdit-py-plugins @ git+https://github.com/executablebooks/mdit-py-plugins@master", + "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", From e5a0ff8e18dd9310d8170d495e7c662698fbd82b Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 27 Jun 2023 20:54:25 +0200 Subject: [PATCH 03/39] =?UTF-8?q?=F0=9F=93=9A=20Add=20icon=20to=20readme?= =?UTF-8?q?=20(#293)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ddb6fb59..9bebca33 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ [![Code style: black][black-badge]][black-link] [![PyPI - Downloads][install-badge]][install-link] +

+ markdown-it-py icon +

+ > Markdown parser done right. - Follows the __[CommonMark spec](http://spec.commonmark.org/)__ for baseline parsing From c2071270b86737c156244a39097867596459db9e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 20:56:53 +0200 Subject: [PATCH 04/39] [pre-commit.ci] pre-commit autoupdate (#290) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Sewell --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2aecdc6d..8b6bda1a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,12 +34,12 @@ repos: - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.270 + rev: v0.0.275 hooks: - id: ruff - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.3.0 + rev: v1.4.1 hooks: - id: mypy additional_dependencies: [mdurl] From 14cca384e608c49d205866347d66e35cb2b66ff9 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 27 Jun 2023 22:22:31 +0200 Subject: [PATCH 05/39] =?UTF-8?q?=F0=9F=93=9A=20Update=20icon=20(#294)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/_static/markdown-it-py.svg | 34 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/_static/markdown-it-py.svg b/docs/_static/markdown-it-py.svg index 9ac486af..a8e15cf3 100644 --- a/docs/_static/markdown-it-py.svg +++ b/docs/_static/markdown-it-py.svg @@ -1,24 +1,34 @@ - - - - - - + + + + + + + - + - + + + + + + + + + + + + + - + - - - From 3613e8016ecafe21709471ee0032a90a4157c2d1 Mon Sep 17 00:00:00 2001 From: DJ Ramones <50655786+djramones@users.noreply.github.com> Date: Wed, 5 Jul 2023 22:51:52 +0800 Subject: [PATCH 06/39] =?UTF-8?q?=F0=9F=93=9A=20DOCS:=20Clarify=20docs=20r?= =?UTF-8?q?egarding=20security=20configuration=20(#296)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Chris Sewell --- README.md | 2 +- docs/index.md | 2 +- docs/security.md | 39 ++++++++++++++++++++++++--------------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9bebca33..43a5da23 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - Configurable syntax: you can add new rules and even replace existing ones. - Pluggable: Adds syntax extensions to extend the parser (see the [plugin list][md-plugins]). - High speed (see our [benchmarking tests][md-performance]) -- [Safe by default][md-security] +- Easy to configure for [security][md-security] - Member of [Google's Assured Open Source Software](https://cloud.google.com/assured-open-source-software/docs/supported-packages) This is a Python port of [markdown-it], and some of its associated plugins. diff --git a/docs/index.md b/docs/index.md index 96827f74..a5484518 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ - {fa}`check,text-success mr-1` Configurable syntax: you can add new rules and even replace existing ones. - {fa}`check,text-success mr-1` Pluggable: Adds syntax extensions to extend the parser (see the [plugin list](md/plugins)) - {fa}`check,text-success mr-1` High speed (see our [benchmarking tests](md/performance)) -- {fa}`check,text-success mr-1` [Safe by default](md/security) +- {fa}`check,text-success mr-1` Easy to configure for [security](md/security) - {fa}`check,text-success mr-1` Member of [Google's Assured Open Source Software](https://cloud.google.com/assured-open-source-software/docs/supported-packages) For a good introduction to [markdown-it] see the __[Live demo](https://markdown-it.github.io)__. diff --git a/docs/security.md b/docs/security.md index 3770d35a..7cbf765f 100644 --- a/docs/security.md +++ b/docs/security.md @@ -2,27 +2,36 @@ # Security -Many people don't understand that markdown format does not care much about security. -In many cases you have to pass output to sanitizers. -`markdown-it` provides 2 possible strategies to produce safe output: +By default, the `MarkdownIt` parser is initialised to comply with the [CommonMark spec](https://spec.commonmark.org/), which allows for parsing arbitrary HTML tags. +This can be useful for many use cases, for example when writing articles for one's own blog or composing technical documentation for a software package. -1. Don't enable HTML. Extend markup features with [plugins](md/plugins). - We think it's the best choice and use it by default. - - That's ok for 99% of user needs. - - Output will be safe without sanitizer. -2. Enable HTML and use external sanitizer package(s). +However, extra precautions are needed when parsing content from untrusted sources. +Generally, the output should be run through sanitizers to ensure safety and prevent vulnerabilities like cross-site scripting (XSS). +With `markdown-it`/`markdown-it-py`, there are two strategies for doing this: -Also by default `markdown-it` prohibits some kind of links, which could be used -for XSS: +1. Enable HTML (as is needed for full CommonMark compliance), and then use external sanitizer package(s). +2. Disable HTML, and then use [plugins](md/plugins) to selectively enable markup features. + This removes the need for further sanitizing. + +```{warning} +Unlike the original `markdown-it` JavaScript project, which uses the second, safe-by-default strategy, `markdown-it-py` enables the more convenient, but less secure, CommonMark-compliant settings by default. + +This is not safe when using `markdown-it-py` in web applications that parse user-submitted content. +In such cases, [using the `js-default` preset](using.md) is strongly recommended. +For example: + +```python +from markdown_it import MarkdownIt +MarkdownIt("js-default").render("*user-submitted* text") +``` + +Note that even with the default configuration, `markdown-it-py` prohibits some kind of links which could be used for XSS: - `javascript:`, `vbscript:` - `file:` -- `data:`, except some images (gif/png/jpeg/webp). - -So, by default `markdown-it` should be safe. We care about it. +- `data:` (except some images: gif/png/jpeg/webp) -If you find a security problem - contact us via . -Such reports are fixed with top priority. +If you find a security problem, please report it to . ## Plugins From 97d32b2a869429cdd3ac01bb6334ada85589143e Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 21 Nov 2023 12:55:09 +0100 Subject: [PATCH 07/39] =?UTF-8?q?=F0=9F=93=9A=20Fix=20the=20RTD=20build=20?= =?UTF-8?q?(#311)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .readthedocs.yml | 6 +++++- pyproject.toml | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 611695db..57297d4b 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,7 +1,11 @@ version: 2 +build: + os: ubuntu-22.04 + tools: + python: "3.8" + python: - version: "3.8" install: - method: pip path: . diff --git a/pyproject.toml b/pyproject.toml index 46cbc762..89e738c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ rtd = [ "sphinx-design", "sphinx_book_theme", "jupyter_sphinx", + "ipykernel", ] testing = [ "coverage", From 4f2e5f252b9552cbc899d477e4b1d2d682ba6d2c Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 24 Nov 2023 08:18:36 +0000 Subject: [PATCH 08/39] =?UTF-8?q?=F0=9F=94=A7=20Replace=20black=20and=20is?= =?UTF-8?q?ort=20with=20ruff=20formatter=20(#313)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 20 ++++++-------------- markdown_it/cli/parse.py | 6 +++--- markdown_it/common/utils.py | 4 ++-- markdown_it/presets/__init__.py | 2 +- markdown_it/renderer.py | 2 +- markdown_it/rules_inline/autolink.py | 2 +- pyproject.toml | 12 +++++------- 7 files changed, 19 insertions(+), 29 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8b6bda1a..ed0d43c9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,30 +16,22 @@ exclude: > repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-json - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - - - repo: https://github.com/psf/black - rev: 23.3.0 - hooks: - - id: black - - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.275 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.6 hooks: - id: ruff + args: [--fix] + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.4.1 + rev: v1.7.0 hooks: - id: mypy additional_dependencies: [mdurl] diff --git a/markdown_it/cli/parse.py b/markdown_it/cli/parse.py index 890d5de3..bfd3449d 100644 --- a/markdown_it/cli/parse.py +++ b/markdown_it/cli/parse.py @@ -13,7 +13,7 @@ from markdown_it import __version__ from markdown_it.main import MarkdownIt -version_str = "markdown-it-py [version {}]".format(__version__) +version_str = f"markdown-it-py [version {__version__}]" def main(args: Sequence[str] | None = None) -> int: @@ -35,7 +35,7 @@ def convert_file(filename: str) -> None: Parse a Markdown file and dump the output to stdout. """ try: - with open(filename, "r", encoding="utf8", errors="ignore") as fin: + with open(filename, encoding="utf8", errors="ignore") as fin: rendered = MarkdownIt().render(fin.read()) print(rendered, end="") except OSError: @@ -100,7 +100,7 @@ def parse_args(args: Sequence[str] | None) -> argparse.Namespace: def print_heading() -> None: - print("{} (interactive)".format(version_str)) + print(f"{version_str} (interactive)") print("Type Ctrl-D to complete input, or Ctrl-C to exit.") diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index 0d11e3e3..dbe082a1 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -194,7 +194,7 @@ def isWhiteSpace(code: int) -> bool: # ////////////////////////////////////////////////////////////////////////////// UNICODE_PUNCT_RE = re.compile( - r"[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]" # noqa: E501 + r"[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]" ) @@ -251,7 +251,7 @@ def isMdAsciiPunct(ch: int) -> bool: Don't confuse with unicode punctuation !!! It lacks some chars in ascii range. - """ # noqa: E501 + """ return ch in MD_ASCII_PUNCT diff --git a/markdown_it/presets/__init__.py b/markdown_it/presets/__init__.py index 1e6796a2..c3fb9e9b 100644 --- a/markdown_it/presets/__init__.py +++ b/markdown_it/presets/__init__.py @@ -1,7 +1,7 @@ __all__ = ("commonmark", "default", "zero", "js_default", "gfm_like") -from . import commonmark, default, zero from ..utils import PresetType +from . import commonmark, default, zero js_default = default diff --git a/markdown_it/renderer.py b/markdown_it/renderer.py index 7fee9ffa..5a774d06 100644 --- a/markdown_it/renderer.py +++ b/markdown_it/renderer.py @@ -155,7 +155,7 @@ def renderToken( if token.nesting == 1 and (idx + 1 < len(tokens)): nextToken = tokens[idx + 1] - if nextToken.type == "inline" or nextToken.hidden: # noqa: SIM114 + if nextToken.type == "inline" or nextToken.hidden: # Block-level tag containing an inline tag. # needLf = False diff --git a/markdown_it/rules_inline/autolink.py b/markdown_it/rules_inline/autolink.py index 295d963f..6546e250 100644 --- a/markdown_it/rules_inline/autolink.py +++ b/markdown_it/rules_inline/autolink.py @@ -4,7 +4,7 @@ from .state_inline import StateInline EMAIL_RE = re.compile( - r"^([a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$" # noqa: E501 + r"^([a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$" ) AUTOLINK_RE = re.compile(r"^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$") diff --git a/pyproject.toml b/pyproject.toml index 89e738c0..e1c192c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,14 +82,12 @@ exclude = [ "benchmarking/" ] -[tool.isort] -profile = "black" -force_sort_within_sections = true - [tool.ruff] -line-length = 100 -extend-select = ["B0", "C4", "ICN", "ISC", "N", "RUF", "SIM"] -extend-ignore = ["ISC003", "N802", "N803", "N806", "N816", "RUF003"] +extend-select = ["B0", "C4", "I", "ICN", "ISC", "N", "RUF", "SIM", "UP"] +extend-ignore = ["ISC001", "ISC003", "N802", "N803", "N806", "N816", "RUF003"] + +[tool.ruff.lint.isort] +force-sort-within-sections = true [tool.mypy] show_error_codes = true From 98ef73d25592a71e540e41920df9a90b6bba25bc Mon Sep 17 00:00:00 2001 From: Bastian Venthur Date: Fri, 24 Nov 2023 09:21:07 +0100 Subject: [PATCH 09/39] Fixed Code Style paragraph still referring to flake8 (#309) Co-authored-by: Chris Sewell --- docs/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing.md b/docs/contributing.md index d553c451..8b46e678 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -16,7 +16,7 @@ Details of the port can be found in the `markdown_it/port.yaml` and in `port.yam ## Code Style -Code style is tested using [flake8](http://flake8.pycqa.org), with the configuration set in `.flake8`, and code formatted with [black](https://github.com/ambv/black). +Code style is tested using [ruff](https://github.com/astral-sh/ruff), with the configuration set in `pyproject.toml`, and code formatted with [black](https://github.com/ambv/black). Installing with `markdown-it-py[code_style]` makes the [pre-commit](https://pre-commit.com/) package available, which will ensure this style is met before commits are submitted, by reformatting the code and testing for lint errors. It can be setup by: From c4ffcd731d0956f1fad407db8c6d78286111ac33 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 24 Nov 2023 10:25:09 +0200 Subject: [PATCH 10/39] =?UTF-8?q?=F0=9F=A7=AA=20Add=20CI=20testing=20for?= =?UTF-8?q?=20Python=203.12=20(#303)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Chris Sewell --- .github/workflows/benchmark.yml | 4 ++-- .github/workflows/tests.yml | 13 +++++++------ pyproject.toml | 1 + tox.ini | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 68cc69bb..93b2781e 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.8 uses: actions/setup-python@v4 @@ -30,7 +30,7 @@ jobs: run: tox -e py38-bench-packages -- --benchmark-min-rounds 20 --benchmark-json bench-packages.json # - name: Upload package data - # uses: actions/upload-artifact@v2 + # uses: actions/upload-artifact@v3 # with: # name: bench-packages # path: bench-packages.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef1bf557..fa170cd1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.8 uses: actions/setup-python@v4 with: @@ -31,14 +31,15 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11'] + python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true - name: Install dependencies run: | python -m pip install --upgrade pip @@ -63,7 +64,7 @@ jobs: matrix: python-version: ['3.8'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: @@ -83,7 +84,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python 3.8 uses: actions/setup-python@v4 @@ -113,7 +114,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python 3.8 uses: actions/setup-python@v4 with: diff --git a/pyproject.toml b/pyproject.toml index e1c192c0..7f5af2b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", diff --git a/tox.ini b/tox.ini index 59ea5f9e..c2915b32 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ envlist = py38 [testenv] usedevelop = true -[testenv:py{38,39,310,311}] +[testenv:py{38,39,310,311,312}] extras = linkify testing @@ -27,11 +27,11 @@ commands_pre = commands = pytest {posargs} -[testenv:py{38,39,310,311}-bench-core] +[testenv:py{38,39,310,311,312}-bench-core] extras = benchmarking commands = pytest benchmarking/bench_core.py {posargs} -[testenv:py{38,39,310,311}-bench-packages] +[testenv:py{38,39,310,311,312}-bench-packages] extras = benchmarking,compare commands = pytest benchmarking/bench_packages.py {posargs} From 9b74610e9ee43b1545a4331a1a3fdb5a85b654a0 Mon Sep 17 00:00:00 2001 From: Bernhard Wagner Date: Tue, 28 Nov 2023 10:32:25 +0100 Subject: [PATCH 11/39] Update index.md (#315) --- docs/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.md b/docs/index.md index a5484518..d71458c5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,7 @@ For a good introduction to [markdown-it] see the __[Live demo](https://markdown-it.github.io)__. This is a Python port of the well used [markdown-it], and some of its associated plugins. The driving design philosophy of the port has been to change as little of the fundamental code structure (file names, function name, etc) as possible, just sprinkling in a little Python syntactical sugar ✨. -It is very simple to write complimentary extensions for both language implementations! +It is very simple to write complementary extensions for both language implementations! ## References & Thanks From df3aadfc3d3f3320bc6247523c3474dec29f938c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:55:28 +0100 Subject: [PATCH 12/39] [pre-commit.ci] pre-commit autoupdate (#314) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed0d43c9..a55107cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.6 + rev: v0.1.8 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.0 + rev: v1.7.1 hooks: - id: mypy additional_dependencies: [mdurl] From 15290f9e33b3bceb57be14ddcdeae8448e0f943e Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Fri, 12 Jan 2024 08:07:36 +0900 Subject: [PATCH 13/39] =?UTF-8?q?=F0=9F=90=9B=20Fix=20emphasis=20inside=20?= =?UTF-8?q?raw=20links=20bugs=20(#320)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed from `re.match` to `re.search` to work as intended. --- markdown_it/rules_inline/linkify.py | 2 +- tests/test_port/fixtures/linkify.md | 35 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/markdown_it/rules_inline/linkify.py b/markdown_it/rules_inline/linkify.py index a8a18153..88224e78 100644 --- a/markdown_it/rules_inline/linkify.py +++ b/markdown_it/rules_inline/linkify.py @@ -27,7 +27,7 @@ def linkify(state: StateInline, silent: bool) -> bool: ): return False - if not (match := SCHEME_RE.match(state.pending)): + if not (match := SCHEME_RE.search(state.pending)): return False proto = match.group(1) diff --git a/tests/test_port/fixtures/linkify.md b/tests/test_port/fixtures/linkify.md index f51bb6b9..02a23b17 100644 --- a/tests/test_port/fixtures/linkify.md +++ b/tests/test_port/fixtures/linkify.md @@ -211,3 +211,38 @@ google\.com .

google.com

. + +Issue [#300](https://github.com/executablebooks/markdown-it-py/issues/300) emphasis inside raw links (underscore) at beginning of line +. +http://example.org/foo._bar_-_baz This works +. +

http://example.org/foo._bar_-_baz This works

+. + +Issue [#300](https://github.com/executablebooks/markdown-it-py/issues/300) emphasis inside raw links (underscore) at end of line +. +This doesnt http://example.org/foo._bar_-_baz +. +

This doesnt http://example.org/foo._bar_-_baz

+. + +Issue [#300](https://github.com/executablebooks/markdown-it-py/issues/300) emphasis inside raw links (underscore) mix1 +. +While this `does` http://example.org/foo._bar_-_baz, this doesnt http://example.org/foo._bar_-_baz and this **does** http://example.org/foo._bar_-_baz +. +

While this does http://example.org/foo._bar_-_baz, this doesnt http://example.org/foo._bar_-_baz and this does http://example.org/foo._bar_-_baz

+. + +Issue [#300](https://github.com/executablebooks/markdown-it-py/issues/300) emphasis inside raw links (underscore) mix2 +. +This applies to _series of URLs too_ http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz, these dont http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz and these **do** http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz +. +

This applies to series of URLs too http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz, these dont http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz and these do http://example.org/foo._bar_-_baz http://example.org/foo._bar_-_baz

+. + +emphasis inside raw links (asterisk) at end of line +. +This doesnt http://example.org/foo.*bar*-*baz +. +

This doesnt http://example.org/foo.*bar*-*baz

+. \ No newline at end of file From a7544ee3931dc6062cbf685fe548706b27edfd87 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 12 Jan 2024 00:25:09 +0100 Subject: [PATCH 14/39] =?UTF-8?q?=F0=9F=93=9A=20Fix=20RTD=20build=20(#322)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7f5af2b7..8a186031 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ rtd = [ "sphinx", "sphinx-copybutton", "sphinx-design", - "sphinx_book_theme", + "sphinx-book-theme~=1.0", "jupyter_sphinx", "ipykernel", ] From 1a71f3f26f5c0106d6fc326d42a5fbde781f5b33 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:31:41 +0100 Subject: [PATCH 15/39] [pre-commit.ci] pre-commit autoupdate (#321) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Sewell --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a55107cf..822f02f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.8 + rev: v0.1.11 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.1 + rev: v1.8.0 hooks: - id: mypy additional_dependencies: [mdurl] From 1064835b30325e857252f5b67b34e622261723ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 02:12:12 +0100 Subject: [PATCH 16/39] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20aiidateam/git?= =?UTF-8?q?hub-action-benchmark=20from=202=20to=203=20(#253)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 93b2781e..4d5436a2 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -37,7 +37,7 @@ jobs: # if-no-files-found: error - name: Store benchmark result - uses: aiidateam/github-action-benchmark@v2 + uses: aiidateam/github-action-benchmark@v3 with: name: Parsing Benchmarks output-file-path: bench-packages.json From 81a5e460814cfc0b260f6852d382f01c5c0880d8 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 7 May 2024 03:16:46 +0200 Subject: [PATCH 17/39] =?UTF-8?q?=F0=9F=A7=AA=20Fix=20codecov=20(#332)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fa170cd1..12b4c746 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,7 +43,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install .[testing,linkify] + pip install -e .[testing,linkify] - name: Run pytest run: | pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing From c10312e2e475a22edb92abede15d3dcabd0cac0c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 03:31:00 +0200 Subject: [PATCH 18/39] [pre-commit.ci] pre-commit autoupdate (#323) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Sewell --- .pre-commit-config.yaml | 6 +++--- markdown_it/__init__.py | 1 + markdown_it/cli/parse.py | 1 + markdown_it/common/entities.py | 1 + markdown_it/common/html_re.py | 3 +-- markdown_it/common/utils.py | 4 ++-- markdown_it/helpers/__init__.py | 4 ++-- markdown_it/helpers/parse_link_label.py | 1 + markdown_it/helpers/parse_link_title.py | 4 ++-- markdown_it/main.py | 15 +++++---------- markdown_it/parser_block.py | 1 + markdown_it/parser_core.py | 9 +++++---- markdown_it/parser_inline.py | 4 ++-- markdown_it/presets/commonmark.py | 1 + markdown_it/presets/default.py | 1 + markdown_it/presets/zero.py | 1 + markdown_it/renderer.py | 4 ++-- markdown_it/ruler.py | 1 + markdown_it/rules_block/code.py | 1 + markdown_it/rules_block/heading.py | 3 ++- markdown_it/rules_block/hr.py | 1 + markdown_it/rules_block/paragraph.py | 1 + markdown_it/rules_core/normalize.py | 3 ++- markdown_it/rules_core/replacements.py | 1 + markdown_it/rules_core/smartquotes.py | 4 ++-- markdown_it/rules_core/text_join.py | 1 + markdown_it/rules_inline/balance_pairs.py | 1 + markdown_it/rules_inline/escape.py | 1 + markdown_it/rules_inline/link.py | 4 +--- markdown_it/rules_inline/linkify.py | 1 + markdown_it/rules_inline/newline.py | 1 + markdown_it/tree.py | 7 +++---- pyproject.toml | 2 +- scripts/build_fuzzers.py | 1 + scripts/profiler.py | 1 + tests/test_api/test_plugin_creation.py | 1 + tests/test_cmark_spec/test_spec.py | 1 + tests/test_fuzzer.py | 1 + 38 files changed, 58 insertions(+), 41 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 822f02f8..a35912c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ exclude: > repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-json - id: check-yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.11 + rev: v0.4.3 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.10.0 hooks: - id: mypy additional_dependencies: [mdurl] diff --git a/markdown_it/__init__.py b/markdown_it/__init__.py index 6606868a..399c6b70 100644 --- a/markdown_it/__init__.py +++ b/markdown_it/__init__.py @@ -1,4 +1,5 @@ """A Python port of Markdown-It""" + __all__ = ("MarkdownIt",) __version__ = "3.0.0" diff --git a/markdown_it/cli/parse.py b/markdown_it/cli/parse.py index bfd3449d..fe346b2f 100644 --- a/markdown_it/cli/parse.py +++ b/markdown_it/cli/parse.py @@ -4,6 +4,7 @@ Parse one or more markdown files, convert each to HTML, and print to stdout. """ + from __future__ import annotations import argparse diff --git a/markdown_it/common/entities.py b/markdown_it/common/entities.py index 6bb2d343..14d08ec9 100644 --- a/markdown_it/common/entities.py +++ b/markdown_it/common/entities.py @@ -1,4 +1,5 @@ """HTML5 entities map: { name -> characters }.""" + import html.entities entities = {name.rstrip(";"): chars for name, chars in html.entities.html5.items()} diff --git a/markdown_it/common/html_re.py b/markdown_it/common/html_re.py index f0c336d2..dae052e9 100644 --- a/markdown_it/common/html_re.py +++ b/markdown_it/common/html_re.py @@ -1,5 +1,4 @@ -"""Regexps to match html elements -""" +"""Regexps to match html elements""" import re diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index dbe082a1..0dafa2d6 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -1,5 +1,5 @@ -"""Utilities for parsing source text -""" +"""Utilities for parsing source text""" + from __future__ import annotations import re diff --git a/markdown_it/helpers/__init__.py b/markdown_it/helpers/__init__.py index 3dbbdd1d..bcf2dc21 100644 --- a/markdown_it/helpers/__init__.py +++ b/markdown_it/helpers/__init__.py @@ -1,5 +1,5 @@ -"""Functions for parsing Links -""" +"""Functions for parsing Links""" + __all__ = ("parseLinkLabel", "parseLinkDestination", "parseLinkTitle") from .parse_link_destination import parseLinkDestination from .parse_link_label import parseLinkLabel diff --git a/markdown_it/helpers/parse_link_label.py b/markdown_it/helpers/parse_link_label.py index 01c653c5..c80da5a7 100644 --- a/markdown_it/helpers/parse_link_label.py +++ b/markdown_it/helpers/parse_link_label.py @@ -5,6 +5,7 @@ returns the end of the label """ + from markdown_it.rules_inline import StateInline diff --git a/markdown_it/helpers/parse_link_title.py b/markdown_it/helpers/parse_link_title.py index 8f589336..fe23ea71 100644 --- a/markdown_it/helpers/parse_link_title.py +++ b/markdown_it/helpers/parse_link_title.py @@ -1,5 +1,5 @@ -"""Parse link title -""" +"""Parse link title""" + from ..common.utils import charCodeAt, unescapeAll diff --git a/markdown_it/main.py b/markdown_it/main.py index bb294a99..bf9fd18f 100644 --- a/markdown_it/main.py +++ b/markdown_it/main.py @@ -68,24 +68,19 @@ def __repr__(self) -> str: return f"{self.__class__.__module__}.{self.__class__.__name__}()" @overload - def __getitem__(self, name: Literal["inline"]) -> ParserInline: - ... + def __getitem__(self, name: Literal["inline"]) -> ParserInline: ... @overload - def __getitem__(self, name: Literal["block"]) -> ParserBlock: - ... + def __getitem__(self, name: Literal["block"]) -> ParserBlock: ... @overload - def __getitem__(self, name: Literal["core"]) -> ParserCore: - ... + def __getitem__(self, name: Literal["core"]) -> ParserCore: ... @overload - def __getitem__(self, name: Literal["renderer"]) -> RendererProtocol: - ... + def __getitem__(self, name: Literal["renderer"]) -> RendererProtocol: ... @overload - def __getitem__(self, name: str) -> Any: - ... + def __getitem__(self, name: str) -> Any: ... def __getitem__(self, name: str) -> Any: return { diff --git a/markdown_it/parser_block.py b/markdown_it/parser_block.py index 72360f9b..3c4d4019 100644 --- a/markdown_it/parser_block.py +++ b/markdown_it/parser_block.py @@ -1,4 +1,5 @@ """Block-level tokenizer.""" + from __future__ import annotations import logging diff --git a/markdown_it/parser_core.py b/markdown_it/parser_core.py index ca5ab256..77075098 100644 --- a/markdown_it/parser_core.py +++ b/markdown_it/parser_core.py @@ -1,9 +1,10 @@ """ - * class Core - * - * Top-level rules executor. Glues block/inline parsers and does intermediate - * transformations. +* class Core +* +* Top-level rules executor. Glues block/inline parsers and does intermediate +* transformations. """ + from __future__ import annotations from typing import Callable diff --git a/markdown_it/parser_inline.py b/markdown_it/parser_inline.py index 0026c383..8f3ac1e6 100644 --- a/markdown_it/parser_inline.py +++ b/markdown_it/parser_inline.py @@ -1,5 +1,5 @@ -"""Tokenizes paragraph content. -""" +"""Tokenizes paragraph content.""" + from __future__ import annotations from typing import TYPE_CHECKING, Callable diff --git a/markdown_it/presets/commonmark.py b/markdown_it/presets/commonmark.py index 3990d434..ed0de0fe 100644 --- a/markdown_it/presets/commonmark.py +++ b/markdown_it/presets/commonmark.py @@ -6,6 +6,7 @@ - block: table - inline: strikethrough """ + from ..utils import PresetType diff --git a/markdown_it/presets/default.py b/markdown_it/presets/default.py index c9ab902d..8aa858f7 100644 --- a/markdown_it/presets/default.py +++ b/markdown_it/presets/default.py @@ -1,4 +1,5 @@ """markdown-it default options.""" + from ..utils import PresetType diff --git a/markdown_it/presets/zero.py b/markdown_it/presets/zero.py index 2f69a58d..3f1fc18c 100644 --- a/markdown_it/presets/zero.py +++ b/markdown_it/presets/zero.py @@ -2,6 +2,7 @@ "Zero" preset, with nothing enabled. Useful for manual configuring of simple modes. For example, to parse bold/italic only. """ + from ..utils import PresetType diff --git a/markdown_it/renderer.py b/markdown_it/renderer.py index 5a774d06..6d60589a 100644 --- a/markdown_it/renderer.py +++ b/markdown_it/renderer.py @@ -5,6 +5,7 @@ class Renderer copy of rules. Those can be rewritten with ease. Also, you can add new rules if you create plugin and adds new token types. """ + from __future__ import annotations from collections.abc import Sequence @@ -21,8 +22,7 @@ class RendererProtocol(Protocol): def render( self, tokens: Sequence[Token], options: OptionsDict, env: EnvType - ) -> Any: - ... + ) -> Any: ... class RendererHTML(RendererProtocol): diff --git a/markdown_it/ruler.py b/markdown_it/ruler.py index bd8baba3..711edce7 100644 --- a/markdown_it/ruler.py +++ b/markdown_it/ruler.py @@ -15,6 +15,7 @@ class Ruler rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and [[MarkdownIt.use]]. """ + from __future__ import annotations from collections.abc import Iterable diff --git a/markdown_it/rules_block/code.py b/markdown_it/rules_block/code.py index 89db9cec..af8a41c8 100644 --- a/markdown_it/rules_block/code.py +++ b/markdown_it/rules_block/code.py @@ -1,4 +1,5 @@ """Code block (4 spaces padded).""" + import logging from .state_block import StateBlock diff --git a/markdown_it/rules_block/heading.py b/markdown_it/rules_block/heading.py index 850ffb50..afcf9ed4 100644 --- a/markdown_it/rules_block/heading.py +++ b/markdown_it/rules_block/heading.py @@ -1,4 +1,5 @@ -""" Atex heading (#, ##, ...) """ +"""Atex heading (#, ##, ...)""" + from __future__ import annotations import logging diff --git a/markdown_it/rules_block/hr.py b/markdown_it/rules_block/hr.py index 16df05f2..fca7d79d 100644 --- a/markdown_it/rules_block/hr.py +++ b/markdown_it/rules_block/hr.py @@ -2,6 +2,7 @@ At least 3 of these characters on a line * - _ """ + import logging from ..common.utils import isStrSpace diff --git a/markdown_it/rules_block/paragraph.py b/markdown_it/rules_block/paragraph.py index 5388a4b1..30ba8777 100644 --- a/markdown_it/rules_block/paragraph.py +++ b/markdown_it/rules_block/paragraph.py @@ -1,4 +1,5 @@ """Paragraph.""" + import logging from .state_block import StateBlock diff --git a/markdown_it/rules_core/normalize.py b/markdown_it/rules_core/normalize.py index c9f8d0d5..32439243 100644 --- a/markdown_it/rules_core/normalize.py +++ b/markdown_it/rules_core/normalize.py @@ -1,4 +1,5 @@ """Normalize input string.""" + import re from .state_core import StateCore @@ -13,6 +14,6 @@ def normalize(state: StateCore) -> None: string = NEWLINES_RE.sub("\n", state.src) # Replace NULL characters - string = NULL_RE.sub("\uFFFD", string) + string = NULL_RE.sub("\ufffd", string) state.src = string diff --git a/markdown_it/rules_core/replacements.py b/markdown_it/rules_core/replacements.py index 14912e17..bcc99800 100644 --- a/markdown_it/rules_core/replacements.py +++ b/markdown_it/rules_core/replacements.py @@ -13,6 +13,7 @@ * ``--`` → &ndash * ``---`` → &mdash """ + from __future__ import annotations import logging diff --git a/markdown_it/rules_core/smartquotes.py b/markdown_it/rules_core/smartquotes.py index c98fbd71..f9b8b457 100644 --- a/markdown_it/rules_core/smartquotes.py +++ b/markdown_it/rules_core/smartquotes.py @@ -1,5 +1,5 @@ -"""Convert straight quotation marks to typographic ones -""" +"""Convert straight quotation marks to typographic ones""" + from __future__ import annotations import re diff --git a/markdown_it/rules_core/text_join.py b/markdown_it/rules_core/text_join.py index d54ccbbc..5379f6d7 100644 --- a/markdown_it/rules_core/text_join.py +++ b/markdown_it/rules_core/text_join.py @@ -5,6 +5,7 @@ For example, `\\:)` shouldn't be replaced with an emoji. """ + from __future__ import annotations from ..token import Token diff --git a/markdown_it/rules_inline/balance_pairs.py b/markdown_it/rules_inline/balance_pairs.py index bbb2101c..9c63b27f 100644 --- a/markdown_it/rules_inline/balance_pairs.py +++ b/markdown_it/rules_inline/balance_pairs.py @@ -1,4 +1,5 @@ """Balance paired characters (*, _, etc) in inline tokens.""" + from __future__ import annotations from .state_inline import Delimiter, StateInline diff --git a/markdown_it/rules_inline/escape.py b/markdown_it/rules_inline/escape.py index 9f68b5df..0fca6c84 100644 --- a/markdown_it/rules_inline/escape.py +++ b/markdown_it/rules_inline/escape.py @@ -1,6 +1,7 @@ """ Process escaped chars and hardbreaks """ + from ..common.utils import isStrSpace from .state_inline import StateInline diff --git a/markdown_it/rules_inline/link.py b/markdown_it/rules_inline/link.py index 78cf9122..2e92c7d8 100644 --- a/markdown_it/rules_inline/link.py +++ b/markdown_it/rules_inline/link.py @@ -112,9 +112,7 @@ def link(state: StateInline, silent: bool) -> bool: label = normalizeReference(label) - ref = ( - state.env["references"][label] if label in state.env["references"] else None - ) + ref = state.env["references"].get(label, None) if not ref: state.pos = oldPos return False diff --git a/markdown_it/rules_inline/linkify.py b/markdown_it/rules_inline/linkify.py index 88224e78..3669396e 100644 --- a/markdown_it/rules_inline/linkify.py +++ b/markdown_it/rules_inline/linkify.py @@ -1,4 +1,5 @@ """Process links like https://example.org/""" + import re from .state_inline import StateInline diff --git a/markdown_it/rules_inline/newline.py b/markdown_it/rules_inline/newline.py index ca8f1db0..d05ee6da 100644 --- a/markdown_it/rules_inline/newline.py +++ b/markdown_it/rules_inline/newline.py @@ -1,4 +1,5 @@ """Proceess '\n'.""" + from ..common.utils import charStrAt, isStrSpace from .state_inline import StateInline diff --git a/markdown_it/tree.py b/markdown_it/tree.py index 6641e5a4..7e775204 100644 --- a/markdown_it/tree.py +++ b/markdown_it/tree.py @@ -2,6 +2,7 @@ This module is not part of upstream JavaScript markdown-it. """ + from __future__ import annotations from collections.abc import Generator, Sequence @@ -78,12 +79,10 @@ def __repr__(self) -> str: return f"{type(self).__name__}({self.type})" @overload - def __getitem__(self: _NodeType, item: int) -> _NodeType: - ... + def __getitem__(self: _NodeType, item: int) -> _NodeType: ... @overload - def __getitem__(self: _NodeType, item: slice) -> list[_NodeType]: - ... + def __getitem__(self: _NodeType, item: slice) -> list[_NodeType]: ... def __getitem__(self: _NodeType, item: int | slice) -> _NodeType | list[_NodeType]: return self.children[item] diff --git a/pyproject.toml b/pyproject.toml index 8a186031..09e696cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,7 +83,7 @@ exclude = [ "benchmarking/" ] -[tool.ruff] +[tool.ruff.lint] extend-select = ["B0", "C4", "I", "ICN", "ISC", "N", "RUF", "SIM", "UP"] extend-ignore = ["ISC001", "ISC003", "N802", "N803", "N806", "N816", "RUF003"] diff --git a/scripts/build_fuzzers.py b/scripts/build_fuzzers.py index 3dce8ddf..00cc1198 100644 --- a/scripts/build_fuzzers.py +++ b/scripts/build_fuzzers.py @@ -1,4 +1,5 @@ """Build fuzzers idempotently in a given folder.""" + import argparse from pathlib import Path import subprocess diff --git a/scripts/profiler.py b/scripts/profiler.py index a593baa1..bdee697c 100644 --- a/scripts/profiler.py +++ b/scripts/profiler.py @@ -4,6 +4,7 @@ - `tox -e profile` - `firefox .tox/prof/output.svg` """ + from pathlib import Path from markdown_it import MarkdownIt diff --git a/tests/test_api/test_plugin_creation.py b/tests/test_api/test_plugin_creation.py index d5bda748..d555be18 100644 --- a/tests/test_api/test_plugin_creation.py +++ b/tests/test_api/test_plugin_creation.py @@ -1,6 +1,7 @@ """Test basic plugin creation functionality: that they can be added and are called correctly """ + from markdown_it import MarkdownIt diff --git a/tests/test_cmark_spec/test_spec.py b/tests/test_cmark_spec/test_spec.py index 88d9fca7..e5199477 100644 --- a/tests/test_cmark_spec/test_spec.py +++ b/tests/test_cmark_spec/test_spec.py @@ -1,6 +1,7 @@ """In this module tests are run against the full test set, provided by https://github.com/commonmark/CommonMark.git. """ + import json from pathlib import Path diff --git a/tests/test_fuzzer.py b/tests/test_fuzzer.py index f3666cc5..7286f8ea 100644 --- a/tests/test_fuzzer.py +++ b/tests/test_fuzzer.py @@ -5,6 +5,7 @@ In the future, perhaps atheris could be directly used here, but it was not directly apparent how to integrate it into pytest. """ + import pytest from markdown_it import MarkdownIt From a4793161da298cb5555cab48cd8d2416fbdf8c48 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 30 Nov 2024 04:03:42 +0000 Subject: [PATCH 19/39] =?UTF-8?q?=F0=9F=94=A7=20Update=20pre-commit=20(#34?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 6 +++--- markdown_it/common/utils.py | 4 +--- markdown_it/helpers/__init__.py | 2 +- markdown_it/helpers/parse_link_destination.py | 2 +- markdown_it/helpers/parse_link_title.py | 2 +- markdown_it/presets/__init__.py | 2 +- markdown_it/rules_block/__init__.py | 10 +++++----- markdown_it/rules_core/__init__.py | 4 ++-- markdown_it/rules_inline/__init__.py | 18 +++++++++--------- 9 files changed, 24 insertions(+), 26 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a35912c7..d6005f6e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ exclude: > repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: check-json - id: check-yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.3 + rev: v0.8.1 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 + rev: v1.13.0 hooks: - id: mypy additional_dependencies: [mdurl] diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index 0dafa2d6..59812a80 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -70,9 +70,7 @@ def isValidEntityCode(c: int) -> bool: if c >= 0x7F and c <= 0x9F: return False # out of range - if c > 0x10FFFF: - return False - return True + return not (c > 0x10FFFF) def fromCodePoint(c: int) -> str: diff --git a/markdown_it/helpers/__init__.py b/markdown_it/helpers/__init__.py index bcf2dc21..f4e2cd21 100644 --- a/markdown_it/helpers/__init__.py +++ b/markdown_it/helpers/__init__.py @@ -1,6 +1,6 @@ """Functions for parsing Links""" -__all__ = ("parseLinkLabel", "parseLinkDestination", "parseLinkTitle") +__all__ = ("parseLinkDestination", "parseLinkLabel", "parseLinkTitle") from .parse_link_destination import parseLinkDestination from .parse_link_label import parseLinkLabel from .parse_link_title import parseLinkTitle diff --git a/markdown_it/helpers/parse_link_destination.py b/markdown_it/helpers/parse_link_destination.py index f42b2244..93989eb5 100644 --- a/markdown_it/helpers/parse_link_destination.py +++ b/markdown_it/helpers/parse_link_destination.py @@ -6,7 +6,7 @@ class _Result: - __slots__ = ("ok", "pos", "lines", "str") + __slots__ = ("lines", "ok", "pos", "str") def __init__(self) -> None: self.ok = False diff --git a/markdown_it/helpers/parse_link_title.py b/markdown_it/helpers/parse_link_title.py index fe23ea71..f002c7c4 100644 --- a/markdown_it/helpers/parse_link_title.py +++ b/markdown_it/helpers/parse_link_title.py @@ -4,7 +4,7 @@ class _Result: - __slots__ = ("ok", "pos", "lines", "str") + __slots__ = ("lines", "ok", "pos", "str") def __init__(self) -> None: self.ok = False diff --git a/markdown_it/presets/__init__.py b/markdown_it/presets/__init__.py index c3fb9e9b..e21c7806 100644 --- a/markdown_it/presets/__init__.py +++ b/markdown_it/presets/__init__.py @@ -1,4 +1,4 @@ -__all__ = ("commonmark", "default", "zero", "js_default", "gfm_like") +__all__ = ("commonmark", "default", "gfm_like", "js_default", "zero") from ..utils import PresetType from . import commonmark, default, zero diff --git a/markdown_it/rules_block/__init__.py b/markdown_it/rules_block/__init__.py index bcf138df..517da231 100644 --- a/markdown_it/rules_block/__init__.py +++ b/markdown_it/rules_block/__init__.py @@ -1,15 +1,15 @@ __all__ = ( "StateBlock", - "paragraph", - "heading", - "lheading", + "blockquote", "code", "fence", + "heading", "hr", + "html_block", + "lheading", "list_block", + "paragraph", "reference", - "blockquote", - "html_block", "table", ) diff --git a/markdown_it/rules_core/__init__.py b/markdown_it/rules_core/__init__.py index c9c5368c..e7d77536 100644 --- a/markdown_it/rules_core/__init__.py +++ b/markdown_it/rules_core/__init__.py @@ -1,11 +1,11 @@ __all__ = ( "StateCore", - "normalize", "block", "inline", + "linkify", + "normalize", "replace", "smartquotes", - "linkify", "text_join", ) diff --git a/markdown_it/rules_inline/__init__.py b/markdown_it/rules_inline/__init__.py index 3a8026ec..d82ef8fb 100644 --- a/markdown_it/rules_inline/__init__.py +++ b/markdown_it/rules_inline/__init__.py @@ -1,19 +1,19 @@ __all__ = ( "StateInline", - "text", - "fragments_join", - "link_pairs", - "linkify", - "escape", - "newline", + "autolink", "backtick", "emphasis", - "image", - "link", - "autolink", "entity", + "escape", + "fragments_join", "html_inline", + "image", + "link", + "link_pairs", + "linkify", + "newline", "strikethrough", + "text", ) from . import emphasis, strikethrough from .autolink import autolink From bbbaba06091a5ab2986fc78213c0470423200d5b Mon Sep 17 00:00:00 2001 From: Murilo Rosa <67339072+mrmurilo75@users.noreply.github.com> Date: Sat, 30 Nov 2024 04:20:45 +0000 Subject: [PATCH 20/39] Improve README (#340) --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 43a5da23..eddebb78 100644 --- a/README.md +++ b/README.md @@ -33,21 +33,28 @@ for even more speed! ## Installation +### PIP + ```bash -conda install -c conda-forge markdown-it-py +pip install markdown-it-py[plugins] ``` -or +or with extras ```bash -pip install markdown-it-py[plugins] +pip install markdown-it-py[linkify,plugins] +``` + +### Conda + +```bash +conda install -c conda-forge markdown-it-py ``` or with extras ```bash conda install -c conda-forge markdown-it-py linkify-it-py mdit-py-plugins -pip install markdown-it-py[linkify,plugins] ``` ## Usage @@ -63,7 +70,7 @@ from mdit_py_plugins.front_matter import front_matter_plugin from mdit_py_plugins.footnote import footnote_plugin md = ( - MarkdownIt('commonmark' ,{'breaks':True,'html':True}) + MarkdownIt('commonmark', {'breaks':True,'html':True}) .use(front_matter_plugin) .use(footnote_plugin) .enable('table') From 21335c8fe628f892ddc4cb7aba4e09e51d1bae2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Nov 2024 05:33:23 +0100 Subject: [PATCH 21/39] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20actions/setup?= =?UTF-8?q?-python=20from=204=20to=205=20(#327)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yml | 2 +- .github/workflows/tests.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 4d5436a2..2a6ab8d1 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.8 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 12b4c746..a4272ffe 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.8' - uses: pre-commit/action@v3.0.0 @@ -36,7 +36,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install markdown-it-py @@ -87,7 +87,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.8' @@ -116,7 +116,7 @@ jobs: - name: Checkout source uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.8' - name: install flit From 876c366ba00bf58d53f926628bd559183371a5a9 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 30 Nov 2024 04:48:33 +0000 Subject: [PATCH 22/39] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Drop=20Python=203.9,?= =?UTF-8?q?=20test=203.13=20(#342)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/benchmark.yml | 6 +++--- .github/workflows/tests.yml | 21 +++++++++++---------- .readthedocs.yml | 2 +- docs/conf.py | 4 ++-- docs/contributing.md | 2 +- markdown_it/common/utils.py | 3 ++- markdown_it/utils.py | 3 ++- pyproject.toml | 8 ++++---- tox.ini | 12 ++++++------ 9 files changed, 32 insertions(+), 29 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 2a6ab8d1..bfa7ff63 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -11,10 +11,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: 3.8 + python-version: 3.9 - name: install pandoc uses: r-lib/actions/setup-pandoc@v2 @@ -27,7 +27,7 @@ jobs: pip install tox - name: Run package benchmarks - run: tox -e py38-bench-packages -- --benchmark-min-rounds 20 --benchmark-json bench-packages.json + run: tox -e py39-bench-packages -- --benchmark-min-rounds 20 --benchmark-json bench-packages.json # - name: Upload package data # uses: actions/upload-artifact@v3 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a4272ffe..d0ccc219 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,18 +20,19 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: '3.9' - uses: pre-commit/action@v3.0.0 tests: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['pypy-3.9', '3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -48,7 +49,7 @@ jobs: run: | pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing - name: Upload to Codecov - if: matrix.python-version == '3.8' && github.repository == 'executablebooks/markdown-it-py' + if: matrix.python-version == '3.9' && github.repository == 'executablebooks/markdown-it-py' uses: codecov/codecov-action@v3 with: name: markdown-it-py-pytests @@ -62,7 +63,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -86,10 +87,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: '3.9' - name: Install tox run: | @@ -97,7 +98,7 @@ jobs: pip install tox - name: Run benchmark - run: tox -e py38-bench-core -- --benchmark-json bench-core.json + run: tox -e py39-bench-core -- --benchmark-json bench-core.json - name: Upload data uses: actions/upload-artifact@v3 @@ -115,10 +116,10 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v5 with: - python-version: '3.8' + python-version: '3.9' - name: install flit run: | pip install flit~=3.4 diff --git a/.readthedocs.yml b/.readthedocs.yml index 57297d4b..5b09f7d1 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.8" + python: "3.9" python: install: diff --git a/docs/conf.py b/docs/conf.py index ed38bb50..dc1a28fd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,7 +48,7 @@ nitpick_ignore_regex = [ ("py:.*", name) for name in ( - "_ItemTV", + ".*_ItemTV", ".*_NodeType", ".*Literal.*", ".*_Result", @@ -84,7 +84,7 @@ intersphinx_mapping = { - "python": ("https://docs.python.org/3.8", None), + "python": ("https://docs.python.org/3.9", None), "mdit-py-plugins": ("https://mdit-py-plugins.readthedocs.io/en/latest/", None), } diff --git a/docs/contributing.md b/docs/contributing.md index 8b46e678..b2302046 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -50,7 +50,7 @@ This can also be used to run benchmarking tests using [pytest-benchmark](https:/ ```shell >> cd markdown-it-py -tox -e py38-bench-packages -- --benchmark-min-rounds 50 +tox -e py39-bench-packages -- --benchmark-min-rounds 50 ``` For documentation build tests: diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index 59812a80..fedae7e1 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -3,7 +3,8 @@ from __future__ import annotations import re -from typing import Match, TypeVar +from re import Match +from typing import TypeVar from .entities import entities diff --git a/markdown_it/utils.py b/markdown_it/utils.py index a9793720..86cfee7f 100644 --- a/markdown_it/utils.py +++ b/markdown_it/utils.py @@ -1,8 +1,9 @@ from __future__ import annotations +from collections.abc import Iterable, MutableMapping from collections.abc import MutableMapping as MutableMappingABC from pathlib import Path -from typing import Any, Callable, Iterable, MutableMapping, TypedDict, cast +from typing import Any, Callable, TypedDict, cast EnvType = MutableMapping[str, Any] # note: could use TypeAlias in python 3.10 """Type for the environment sandbox used in parsing and rendering, diff --git a/pyproject.toml b/pyproject.toml index 09e696cd..aa13fadf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,18 +14,18 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup", ] keywords = ["markdown", "lexer", "parser", "commonmark", "markdown-it"] -requires-python = ">=3.8" +requires-python = ">=3.9" dependencies = [ "mdurl~=0.1", ] diff --git a/tox.ini b/tox.ini index c2915b32..b17bd9d4 100644 --- a/tox.ini +++ b/tox.ini @@ -4,18 +4,18 @@ # then run `tox` or `tox -- {pytest args}` # run in parallel using `tox -p` [tox] -envlist = py38 +envlist = py39 [testenv] usedevelop = true -[testenv:py{38,39,310,311,312}] +[testenv:py{39,310,311,312,313}] extras = linkify testing commands = pytest {posargs:tests/} -[testenv:py{38,39,310,311}-plugins] +[testenv:py{39,310,311,312,313}-plugins] extras = testing changedir = {envtmpdir} allowlist_externals = @@ -27,17 +27,17 @@ commands_pre = commands = pytest {posargs} -[testenv:py{38,39,310,311,312}-bench-core] +[testenv:py{39,310,311,312,313}-bench-core] extras = benchmarking commands = pytest benchmarking/bench_core.py {posargs} -[testenv:py{38,39,310,311,312}-bench-packages] +[testenv:py{39,310,311,312,313}-bench-packages] extras = benchmarking,compare commands = pytest benchmarking/bench_packages.py {posargs} [testenv:docs-{update,clean}] extras = linkify,plugins,rtd -whitelist_externals = +allowlist_externals = echo rm setenv = From aa4e28f8030831c3fd865daf8294decb9d34dd09 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 30 Nov 2024 05:50:00 +0000 Subject: [PATCH 23/39] =?UTF-8?q?=F0=9F=94=A7=20Add=20"store=5Flabels"=20t?= =?UTF-8?q?o=20OptionsType=20(#343)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hukkin --- .gitignore | 2 ++ .pre-commit-config.yaml | 2 +- docs/conf.py | 1 + docs/contributing.md | 2 +- markdown_it/utils.py | 11 ++++++++++- pyproject.toml | 5 ++++- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 546e6c2a..0c136bb6 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,5 @@ __pycache__/ .DS_Store docs/api/ + +uv.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d6005f6e..ebc6ab1d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,7 +34,7 @@ repos: rev: v1.13.0 hooks: - id: mypy - additional_dependencies: [mdurl] + additional_dependencies: [mdurl, typing-extensions] exclude: > (?x)^( benchmarking/.*\.py| diff --git a/docs/conf.py b/docs/conf.py index dc1a28fd..3a40249d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,6 +55,7 @@ "EnvType", "Path", "Ellipsis", + "NotRequired", ) ] diff --git a/docs/contributing.md b/docs/contributing.md index b2302046..eeb65e1c 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -32,7 +32,7 @@ All functions and class methods should be annotated with types and include a doc ## Testing -For code tests, markdown-it-py uses [pytest](https://docs.pytest.org)): +For code tests, markdown-it-py uses [pytest](https://docs.pytest.org): ```shell >> cd markdown-it-py diff --git a/markdown_it/utils.py b/markdown_it/utils.py index 86cfee7f..3d2a20e5 100644 --- a/markdown_it/utils.py +++ b/markdown_it/utils.py @@ -3,7 +3,11 @@ from collections.abc import Iterable, MutableMapping from collections.abc import MutableMapping as MutableMappingABC from pathlib import Path -from typing import Any, Callable, TypedDict, cast +from typing import TYPE_CHECKING, Any, Callable, TypedDict, cast + +if TYPE_CHECKING: + from typing_extensions import NotRequired + EnvType = MutableMapping[str, Any] # note: could use TypeAlias in python 3.10 """Type for the environment sandbox used in parsing and rendering, @@ -32,6 +36,11 @@ class OptionsType(TypedDict): """CSS language prefix for fenced blocks.""" highlight: Callable[[str, str, str], str] | None """Highlighter function: (content, lang, attrs) -> str.""" + store_labels: NotRequired[bool] + """Store link label in link/image token's metadata (under Token.meta['label']). + + This is a Python only option, and is intended for the use of round-trip parsing. + """ class PresetType(TypedDict): diff --git a/pyproject.toml b/pyproject.toml index aa13fadf..d46668a0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,9 @@ benchmarking = [ ] profiling = ["gprof2dot"] +[dependency-groups] +mypy = ["mypy", "mdurl", "typing-extensions"] + [project.scripts] markdown-it = "markdown_it.cli.parse:main" @@ -106,7 +109,7 @@ module = ["tests.test_plugins.*", "markdown.*"] ignore_errors = true [[tool.mypy.overrides]] -module = ["markdown.*"] +module = ["markdown.*", "linkify_it.*"] ignore_missing_imports = true [tool.pytest.ini_options] From d86e9a0dd3e13f522493f3aba9c260929f58cd6c Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 30 Nov 2024 06:06:21 +0000 Subject: [PATCH 24/39] =?UTF-8?q?=F0=9F=94=A7=20Move=20`code=5Fstyle`=20to?= =?UTF-8?q?=20dependency=20group=20(#344)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d46668a0..5cb7012d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,6 @@ Homepage = "https://github.com/executablebooks/markdown-it-py" Documentation = "https://markdown-it-py.readthedocs.io/" [project.optional-dependencies] -code_style = ["pre-commit~=3.0"] compare = [ "commonmark~=0.9", "markdown~=3.4", @@ -71,6 +70,7 @@ benchmarking = [ profiling = ["gprof2dot"] [dependency-groups] +pre_commit = ["pre-commit"] mypy = ["mypy", "mdurl", "typing-extensions"] [project.scripts] From 77a7ee6c9b3ef75271bccc79a87820dfe49fd9e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 Nov 2024 07:30:03 +0100 Subject: [PATCH 25/39] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20pre-commit/ac?= =?UTF-8?q?tion=20from=203.0.0=20to=203.0.1=20(#328)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d0ccc219..cd2a5576 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.9' - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 tests: From 1a43fa3e9f0698b7486b74ce3dfc16558bf9ba07 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sat, 30 Nov 2024 06:42:33 +0000 Subject: [PATCH 26/39] =?UTF-8?q?=F0=9F=94=A7=20Update=20codecov=20action?= =?UTF-8?q?=20(#345)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/tests.yml | 4 ++-- README.md | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd2a5576..93bb9cae 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -50,11 +50,11 @@ jobs: pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing - name: Upload to Codecov if: matrix.python-version == '3.9' && github.repository == 'executablebooks/markdown-it-py' - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: name: markdown-it-py-pytests flags: pytests - file: ./coverage.xml + files: ./coverage.xml fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} diff --git a/README.md b/README.md index eddebb78..b94729f8 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![Coverage Status][codecov-badge]][codecov-link] [![PyPI][pypi-badge]][pypi-link] [![Conda][conda-badge]][conda-link] -[![Code style: black][black-badge]][black-link] [![PyPI - Downloads][install-badge]][install-link]

@@ -149,8 +148,6 @@ Also [John MacFarlane](https://github.com/jgm) for his work on the CommonMark sp [conda-link]: https://anaconda.org/conda-forge/markdown-it-py [codecov-badge]: https://codecov.io/gh/executablebooks/markdown-it-py/branch/master/graph/badge.svg [codecov-link]: https://codecov.io/gh/executablebooks/markdown-it-py -[black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg -[black-link]: https://github.com/ambv/black [install-badge]: https://img.shields.io/pypi/dw/markdown-it-py?label=pypi%20installs [install-link]: https://pypistats.org/packages/markdown-it-py From c5161b550f3c6c0a98d77e8389872405e8f9f9ee Mon Sep 17 00:00:00 2001 From: Taneli Hukkinen <3275109+hukkin@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:38:01 +0200 Subject: [PATCH 27/39] =?UTF-8?q?=F0=9F=91=8C=20Improve=20performance=20of?= =?UTF-8?q?=20"text"=20inline=20rule=20(#347)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- markdown_it/rules_inline/text.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/markdown_it/rules_inline/text.py b/markdown_it/rules_inline/text.py index f306b2e4..18b2fcc7 100644 --- a/markdown_it/rules_inline/text.py +++ b/markdown_it/rules_inline/text.py @@ -1,3 +1,6 @@ +import functools +import re + # Skip text characters for text token, place those to pending buffer # and increment current pos from .state_inline import StateInline @@ -36,11 +39,17 @@ } +@functools.cache +def _terminator_char_regex() -> re.Pattern[str]: + return re.compile("[" + re.escape("".join(_TerminatorChars)) + "]") + + def text(state: StateInline, silent: bool) -> bool: pos = state.pos posMax = state.posMax - while (pos < posMax) and state.src[pos] not in _TerminatorChars: - pos += 1 + + terminator_char = _terminator_char_regex().search(state.src, pos) + pos = terminator_char.start() if terminator_char else posMax if pos == state.pos: return False From 0c933dce5e6422490a0e4807f844522bfac41ac0 Mon Sep 17 00:00:00 2001 From: Taneli Hukkinen <3275109+hukkin@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:24:19 +0200 Subject: [PATCH 28/39] =?UTF-8?q?=F0=9F=94=A7=20Use=20`str.removesuffix`?= =?UTF-8?q?=20(#348)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- markdown_it/tree.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/markdown_it/tree.py b/markdown_it/tree.py index 7e775204..5369157b 100644 --- a/markdown_it/tree.py +++ b/markdown_it/tree.py @@ -162,7 +162,7 @@ def type(self) -> str: if self.token: return self.token.type assert self.nester_tokens - return _removesuffix(self.nester_tokens.opening.type, "_open") + return self.nester_tokens.opening.type.removesuffix("_open") @property def next_sibling(self: _NodeType) -> _NodeType | None: @@ -331,14 +331,3 @@ def hidden(self) -> bool: """If it's true, ignore this element when rendering. Used for tight lists to hide paragraphs.""" return self._attribute_token().hidden - - -def _removesuffix(string: str, suffix: str) -> str: - """Remove a suffix from a string. - - Replace this with str.removesuffix() from stdlib when minimum Python - version is 3.9. - """ - if suffix and string.endswith(suffix): - return string[: -len(suffix)] - return string From 36a9d146af52265420de634cc2e25d1d40cfcdb7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 20:36:16 +0100 Subject: [PATCH 29/39] [pre-commit.ci] pre-commit autoupdate (#346) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ebc6ab1d..7d075425 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.1 + rev: v0.8.4 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.13.0 + rev: v1.14.0 hooks: - id: mypy additional_dependencies: [mdurl, typing-extensions] From 154fe43feb17947e2c933d0bb3e26618129909a8 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 8 Aug 2025 13:01:37 +0200 Subject: [PATCH 30/39] =?UTF-8?q?=F0=9F=94=A7=20Update=20pre-commit=20and?= =?UTF-8?q?=20upload-artifact=20(#359)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/fuzz.yml | 2 +- .github/workflows/tests.yml | 2 +- .pre-commit-config.yaml | 4 ++-- .readthedocs.yml | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index a74869a5..5c5ed478 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -29,7 +29,7 @@ jobs: language: python fuzz-seconds: 60 - name: Upload Crash - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 93bb9cae..4d6bf50a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -101,7 +101,7 @@ jobs: run: tox -e py39-bench-core -- --benchmark-json bench-core.json - name: Upload data - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: bench-core path: bench-core.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d075425..33f30b12 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,14 +24,14 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.4 + rev: v0.12.8 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.14.0 + rev: v1.17.1 hooks: - id: mypy additional_dependencies: [mdurl, typing-extensions] diff --git a/.readthedocs.yml b/.readthedocs.yml index 5b09f7d1..1faecd92 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,5 +14,6 @@ python: - rtd sphinx: + configuration: docs/conf.py builder: html fail_on_warning: true From 9ffe841832d33264201aaff120349f001a02953a Mon Sep 17 00:00:00 2001 From: Elijah Greenstein <197816462+elijahgreenstein@users.noreply.github.com> Date: Fri, 8 Aug 2025 04:06:45 -0700 Subject: [PATCH 31/39] =?UTF-8?q?=F0=9F=93=9A=20DOCS:=20Fix=20a=20few=20ol?= =?UTF-8?q?d=20URLs=20(#358)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/contributing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index eeb65e1c..ea774a8e 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -2,7 +2,7 @@ We welcome all contributions! ✨ -See the [EBP Contributing Guide](https://executablebooks.org/en/latest/contributing.html) for general details, and below for guidance specific to markdown-it-py. +See the [EBP Contributing Guide](https://executablebooks.org/en/latest/contribute/) for general details, and below for guidance specific to markdown-it-py. Before continuing, make sure you've read: @@ -96,13 +96,13 @@ in a more convenient way. The right sequence is to split text to several tokens and add link tokens in between. The result will be: `text` + `link_open` + `text` + `link_close` + `text`. -See implementations of [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js) and [emoji](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/replace.js) - those do text token splits. +See implementations of [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.mjs) and [emoji](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/replace.mjs) - those do text token splits. __Note:__ Don't try to replace text with HTML markup! That's not secure. ### Why is my inline rule not executed? -The inline parser skips pieces of texts to optimize speed. It stops only on [a small set of chars](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_inline/text.js), which can be tokens. We did not made this list extensible for performance reasons too. +The inline parser skips pieces of texts to optimize speed. It stops only on [a small set of chars](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_inline/text.mjs), which can be tokens. We did not made this list extensible for performance reasons too. If you are absolutely sure that something important is missing there - create a ticket and we will consider adding it as a new charcode. From fb9d3ab646e4f752dc8fd52e1dd7613c350ff190 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 8 Aug 2025 13:20:13 +0200 Subject: [PATCH 32/39] =?UTF-8?q?=20=E2=AC=86=EF=B8=8F=20Drop=20support=20?= =?UTF-8?q?for=20Python=203.9=20(#360)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is EoL next month https://devguide.python.org/versions --- .github/workflows/benchmark.yml | 6 +++--- .github/workflows/tests.yml | 20 ++++++++++---------- .readthedocs.yml | 2 +- docs/conf.py | 2 +- docs/contributing.md | 2 +- markdown_it/_compat.py | 10 ---------- markdown_it/_punycode.py | 2 +- markdown_it/parser_block.py | 3 ++- markdown_it/parser_core.py | 2 +- markdown_it/parser_inline.py | 3 ++- markdown_it/ruler.py | 4 +--- markdown_it/rules_inline/state_inline.py | 3 +-- markdown_it/token.py | 4 +--- markdown_it/utils.py | 4 ++-- pyproject.toml | 3 +-- tox.ini | 10 +++++----- 16 files changed, 33 insertions(+), 47 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index bfa7ff63..9c96c035 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -11,10 +11,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: 3.10 - name: install pandoc uses: r-lib/actions/setup-pandoc@v2 @@ -27,7 +27,7 @@ jobs: pip install tox - name: Run package benchmarks - run: tox -e py39-bench-packages -- --benchmark-min-rounds 20 --benchmark-json bench-packages.json + run: tox -e py310-bench-packages -- --benchmark-min-rounds 20 --benchmark-json bench-packages.json # - name: Upload package data # uses: actions/upload-artifact@v3 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4d6bf50a..8b0b42b9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,10 +20,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - uses: pre-commit/action@v3.0.1 tests: @@ -32,7 +32,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['pypy-3.9', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['pypy-3.10', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 @@ -49,7 +49,7 @@ jobs: run: | pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing - name: Upload to Codecov - if: matrix.python-version == '3.9' && github.repository == 'executablebooks/markdown-it-py' + if: matrix.python-version == '3.10' && github.repository == 'executablebooks/markdown-it-py' uses: codecov/codecov-action@v5 with: name: markdown-it-py-pytests @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9'] + python-version: ['3.10'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -87,10 +87,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: Install tox run: | @@ -98,7 +98,7 @@ jobs: pip install tox - name: Run benchmark - run: tox -e py39-bench-core -- --benchmark-json bench-core.json + run: tox -e py310-bench-core -- --benchmark-json bench-core.json - name: Upload data uses: actions/upload-artifact@v4 @@ -116,10 +116,10 @@ jobs: steps: - name: Checkout source uses: actions/checkout@v4 - - name: Set up Python 3.9 + - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.10' - name: install flit run: | pip install flit~=3.4 diff --git a/.readthedocs.yml b/.readthedocs.yml index 1faecd92..cb68e005 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.9" + python: "3.10" python: install: diff --git a/docs/conf.py b/docs/conf.py index 3a40249d..290eac7f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -85,7 +85,7 @@ intersphinx_mapping = { - "python": ("https://docs.python.org/3.9", None), + "python": ("https://docs.python.org/3.10", None), "mdit-py-plugins": ("https://mdit-py-plugins.readthedocs.io/en/latest/", None), } diff --git a/docs/contributing.md b/docs/contributing.md index ea774a8e..eb73ccda 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -50,7 +50,7 @@ This can also be used to run benchmarking tests using [pytest-benchmark](https:/ ```shell >> cd markdown-it-py -tox -e py39-bench-packages -- --benchmark-min-rounds 50 +tox -e py310-bench-packages -- --benchmark-min-rounds 50 ``` For documentation build tests: diff --git a/markdown_it/_compat.py b/markdown_it/_compat.py index 974d431b..9d48db4f 100644 --- a/markdown_it/_compat.py +++ b/markdown_it/_compat.py @@ -1,11 +1 @@ from __future__ import annotations - -from collections.abc import Mapping -import sys -from typing import Any - -DATACLASS_KWARGS: Mapping[str, Any] -if sys.version_info >= (3, 10): - DATACLASS_KWARGS = {"slots": True} -else: - DATACLASS_KWARGS = {} diff --git a/markdown_it/_punycode.py b/markdown_it/_punycode.py index f9baad27..312048bf 100644 --- a/markdown_it/_punycode.py +++ b/markdown_it/_punycode.py @@ -21,8 +21,8 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import codecs +from collections.abc import Callable import re -from typing import Callable REGEX_SEPARATORS = re.compile(r"[\x2E\u3002\uFF0E\uFF61]") REGEX_NON_ASCII = re.compile(r"[^\0-\x7E]") diff --git a/markdown_it/parser_block.py b/markdown_it/parser_block.py index 3c4d4019..50a7184c 100644 --- a/markdown_it/parser_block.py +++ b/markdown_it/parser_block.py @@ -2,8 +2,9 @@ from __future__ import annotations +from collections.abc import Callable import logging -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING from . import rules_block from .ruler import Ruler diff --git a/markdown_it/parser_core.py b/markdown_it/parser_core.py index 77075098..8f5b921c 100644 --- a/markdown_it/parser_core.py +++ b/markdown_it/parser_core.py @@ -7,7 +7,7 @@ from __future__ import annotations -from typing import Callable +from collections.abc import Callable from .ruler import Ruler from .rules_core import ( diff --git a/markdown_it/parser_inline.py b/markdown_it/parser_inline.py index 8f3ac1e6..26ec2e63 100644 --- a/markdown_it/parser_inline.py +++ b/markdown_it/parser_inline.py @@ -2,7 +2,8 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Callable +from collections.abc import Callable +from typing import TYPE_CHECKING from . import rules_inline from .ruler import Ruler diff --git a/markdown_it/ruler.py b/markdown_it/ruler.py index 711edce7..91ab5804 100644 --- a/markdown_it/ruler.py +++ b/markdown_it/ruler.py @@ -23,8 +23,6 @@ class Ruler from typing import TYPE_CHECKING, Generic, TypedDict, TypeVar import warnings -from markdown_it._compat import DATACLASS_KWARGS - from .utils import EnvType if TYPE_CHECKING: @@ -66,7 +64,7 @@ class RuleOptionsType(TypedDict, total=False): """A rule function, whose signature is dependent on the state type.""" -@dataclass(**DATACLASS_KWARGS) +@dataclass(slots=True) class Rule(Generic[RuleFuncTv]): name: str enabled: bool diff --git a/markdown_it/rules_inline/state_inline.py b/markdown_it/rules_inline/state_inline.py index c0c491c4..ca70294a 100644 --- a/markdown_it/rules_inline/state_inline.py +++ b/markdown_it/rules_inline/state_inline.py @@ -4,7 +4,6 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Any, Literal -from .._compat import DATACLASS_KWARGS from ..common.utils import isMdAsciiPunct, isPunctChar, isWhiteSpace from ..ruler import StateBase from ..token import Token @@ -14,7 +13,7 @@ from markdown_it import MarkdownIt -@dataclass(**DATACLASS_KWARGS) +@dataclass(slots=True) class Delimiter: # Char code of the starting marker (number). marker: int diff --git a/markdown_it/token.py b/markdown_it/token.py index 90008b72..d6d0b453 100644 --- a/markdown_it/token.py +++ b/markdown_it/token.py @@ -5,8 +5,6 @@ from typing import Any, Literal import warnings -from markdown_it._compat import DATACLASS_KWARGS - def convert_attrs(value: Any) -> Any: """Convert Token.attrs set as ``None`` or ``[[key, value], ...]`` to a dict. @@ -20,7 +18,7 @@ def convert_attrs(value: Any) -> Any: return value -@dc.dataclass(**DATACLASS_KWARGS) +@dc.dataclass(slots=True) class Token: type: str """Type of the token (string, e.g. "paragraph_open")""" diff --git a/markdown_it/utils.py b/markdown_it/utils.py index 3d2a20e5..2571a158 100644 --- a/markdown_it/utils.py +++ b/markdown_it/utils.py @@ -1,9 +1,9 @@ from __future__ import annotations -from collections.abc import Iterable, MutableMapping +from collections.abc import Callable, Iterable, MutableMapping from collections.abc import MutableMapping as MutableMappingABC from pathlib import Path -from typing import TYPE_CHECKING, Any, Callable, TypedDict, cast +from typing import TYPE_CHECKING, Any, TypedDict, cast if TYPE_CHECKING: from typing_extensions import NotRequired diff --git a/pyproject.toml b/pyproject.toml index 5cb7012d..56bd9df2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -25,7 +24,7 @@ classifiers = [ "Topic :: Text Processing :: Markup", ] keywords = ["markdown", "lexer", "parser", "commonmark", "markdown-it"] -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = [ "mdurl~=0.1", ] diff --git a/tox.ini b/tox.ini index b17bd9d4..f8a9b27e 100644 --- a/tox.ini +++ b/tox.ini @@ -4,18 +4,18 @@ # then run `tox` or `tox -- {pytest args}` # run in parallel using `tox -p` [tox] -envlist = py39 +envlist = py310 [testenv] usedevelop = true -[testenv:py{39,310,311,312,313}] +[testenv:py{310,311,312,313}] extras = linkify testing commands = pytest {posargs:tests/} -[testenv:py{39,310,311,312,313}-plugins] +[testenv:py{310,311,312,313}-plugins] extras = testing changedir = {envtmpdir} allowlist_externals = @@ -27,11 +27,11 @@ commands_pre = commands = pytest {posargs} -[testenv:py{39,310,311,312,313}-bench-core] +[testenv:py{310,311,312,313}-bench-core] extras = benchmarking commands = pytest benchmarking/bench_core.py {posargs} -[testenv:py{39,310,311,312,313}-bench-packages] +[testenv:py{310,311,312,313}-bench-packages] extras = benchmarking,compare commands = pytest benchmarking/bench_packages.py {posargs} From 8eb20ac1cb63e09dcd78e84a0c71dab8446bb73c Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 8 Aug 2025 14:29:08 +0200 Subject: [PATCH 33/39] =?UTF-8?q?=F0=9F=94=A7=20Improve=20spec=20update=20?= =?UTF-8?q?script=20(#361)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/benchmark.yml | 2 +- .github/workflows/tests.yml | 3 + docs/contributing.md | 16 +++++ pyproject.toml | 1 + tests/test_cmark_spec/get_cmark_spec.py | 77 +++++++++++++++++++++++++ tests/test_cmark_spec/spec.sh | 26 --------- 6 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 tests/test_cmark_spec/get_cmark_spec.py delete mode 100755 tests/test_cmark_spec/spec.sh diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 9c96c035..37cb7e24 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.10 + python-version: "3.10" - name: install pandoc uses: r-lib/actions/setup-pandoc@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8b0b42b9..aebd2a7c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,6 +45,9 @@ jobs: run: | python -m pip install --upgrade pip pip install -e .[testing,linkify] + - name: Check spec file is up to date + run: | + python tests/test_cmark_spec/get_cmark_spec.py - name: Run pytest run: | pytest tests/ --cov=markdown_it --cov-report=xml --cov-report=term-missing diff --git a/docs/contributing.md b/docs/contributing.md index eb73ccda..3a6d6aeb 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -61,6 +61,22 @@ For documentation build tests: >> make html-strict ``` +### Updating the commonmark specification + +If you need to update the commonmark specification, you can do so by running: + +```shell +>> cd markdown-it-py +>> python tests/test_cmark_spec/get_cmark_spec.py +``` + +or + +```shell +>> cd markdown-it-py +>> uv run tests/test_cmark_spec/get_cmark_spec.py +``` + ## Contributing a plugin 1. Does it already exist as JavaScript implementation ([see npm](https://www.npmjs.com/search?q=keywords:markdown-it-plugin))? diff --git a/pyproject.toml b/pyproject.toml index 56bd9df2..86353250 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,6 +60,7 @@ testing = [ "pytest", "pytest-cov", "pytest-regressions", + "requests", ] benchmarking = [ "psutil", diff --git a/tests/test_cmark_spec/get_cmark_spec.py b/tests/test_cmark_spec/get_cmark_spec.py new file mode 100644 index 00000000..851cad75 --- /dev/null +++ b/tests/test_cmark_spec/get_cmark_spec.py @@ -0,0 +1,77 @@ +# /// script +# dependencies = [ +# "requests", +# ] +# /// +from pathlib import Path + +default_version = "0.30" +default_output_path = Path(__file__).parent / "commonmark.json" +default_fixture_test_path = ( + Path(__file__).parent.parent / "test_port" / "fixtures" / "commonmark_spec.md" +) + + +def create_argparser(): + import argparse + + parser = argparse.ArgumentParser(description="Download CommonMark spec JSON") + parser.add_argument( + "version", + nargs="?", + default=default_version, + help=f"CommonMark spec version to download (default: {default_version})", + ) + parser.add_argument( + "--output", + "-o", + type=Path, + default=default_output_path, + help=f"Output file path (default: {default_output_path})", + ) + parser.add_argument( + "--test-fixture", + type=Path, + default=default_fixture_test_path, + help=f"Write to test fixture (default: {default_fixture_test_path})", + ) + return parser + + +if __name__ == "__main__": + import requests # type: ignore[import-untyped] + + args = create_argparser().parse_args() + version: str = args.version + output_path: Path = args.output + write_to_test_fixture = True + test_fixture: Path = args.test_fixture + changed = False + url = f"https://spec.commonmark.org/%7Bversion%7D/spec.json" + print(f"Downloading CommonMark spec from {url}") + response = requests.get(url) + response.raise_for_status() + if not output_path.exists() or output_path.read_text() != response.text: + changed = True + with output_path.open("w") as f: + f.write(response.text) + print(f"Updated to {output_path}") + else: + print(f"Spec file {output_path} is up to date, not overwriting") + + if write_to_test_fixture: + data = response.json() + text = "" + for item in data: + text += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + text += f"src line: {item['start_line'] - 1}\n\n" + text += f".\n{item['markdown']}.\n{item['html']}.\n\n" + if not test_fixture.exists() or test_fixture.read_text() != text: + changed = True + with test_fixture.open("w") as f: + f.write(text) + print(f"Also updated to {test_fixture}") + else: + print(f"Fixture file {test_fixture} is up to date, not overwriting") + + raise SystemExit(0 if not changed else 1) diff --git a/tests/test_cmark_spec/spec.sh b/tests/test_cmark_spec/spec.sh deleted file mode 100755 index c8513903..00000000 --- a/tests/test_cmark_spec/spec.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e - -REPO="https://github.com/commonmark/CommonMark.git" -VERSION="0.30" - -function main { - echo "Cloning from repo: $REPO..." - git clone --quiet $REPO - - echo "Using version $VERSION..." - cd "CommonMark" - git checkout --quiet $VERSION - - echo "Dumping tests file..." - python3 "test/spec_tests.py" --dump-tests > "../commonmark.json" - - echo "Cleaning up..." - cd .. - rm -rf CommonMark - - echo "Done." -} - -main From 4535d77edcb5f51450a266135687eeae8bcc5033 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Fri, 8 Aug 2025 18:49:43 +0200 Subject: [PATCH 34/39] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Comply=20with=20Comm?= =?UTF-8?q?onmark=200.31.2=20(#362)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR ports https://github.com/markdown-it/markdown-it/commit/cd2477863fdcc182cc8739e9bedc7363acb344d8, which in turn complies with https://spec.commonmark.org/0.31.2/changes.html: - Unicode: ```diff A [Unicode punctuation character](@) is - an [ASCII punctuation character] or anything in - he general Unicode categories `Pc`, `Pd`, `Pe`, `Pf`, `Pi`, `Po`, or `Ps`. + a character in the Unicode `P` (puncuation) or `S` (symbol) general categories. ``` - HTML comments: ```diff - An HTML comment consists of ``, - where *text* does not start with `>` or `->`, does not end with `-`, and does not contain `--`. - (See the [HTML5 spec](http://www.w3.org/TR/html5/syntax.html#comments).) + An [HTML comment](@) consists of ``, ``, or ``, and `-->` + (see the [HTML spec](https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state)). ``` - HTML blocks: ```diff Start condition: line begins the string < or --- markdown_it/common/html_blocks.py | 3 +- markdown_it/common/html_re.py | 4 +- markdown_it/common/utils.py | 8 +- tests/test_cmark_spec/commonmark.json | 3114 ++++++++--------- tests/test_cmark_spec/get_cmark_spec.py | 91 +- tests/test_cmark_spec/spec.md | 168 +- .../test_cmark_spec/test_spec/test_file.html | 159 +- tests/test_port/fixtures/commonmark_spec.md | 1346 +++---- tests/test_port/fixtures/fatal.md | 2 +- 9 files changed, 2459 insertions(+), 2436 deletions(-) diff --git a/markdown_it/common/html_blocks.py b/markdown_it/common/html_blocks.py index 8b199af3..8a3b0b7d 100644 --- a/markdown_it/common/html_blocks.py +++ b/markdown_it/common/html_blocks.py @@ -2,6 +2,7 @@ http://jgm.github.io/CommonMark/spec.html#html-blocks """ +# see https://spec.commonmark.org/0.31.2/#html-blocks block_names = [ "address", "article", @@ -52,8 +53,8 @@ "option", "p", "param", + "search", "section", - "source", "summary", "table", "tbody", diff --git a/markdown_it/common/html_re.py b/markdown_it/common/html_re.py index dae052e9..ab822c5f 100644 --- a/markdown_it/common/html_re.py +++ b/markdown_it/common/html_re.py @@ -15,9 +15,9 @@ open_tag = "<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/?>" close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>" -comment = "|" +comment = "" processing = "<[?][\\s\\S]*?[?]>" -declaration = "]*>" +declaration = "]*>" cdata = "" HTML_TAG_RE = re.compile( diff --git a/markdown_it/common/utils.py b/markdown_it/common/utils.py index fedae7e1..11bda644 100644 --- a/markdown_it/common/utils.py +++ b/markdown_it/common/utils.py @@ -5,6 +5,7 @@ import re from re import Match from typing import TypeVar +import unicodedata from .entities import entities @@ -192,15 +193,10 @@ def isWhiteSpace(code: int) -> bool: # ////////////////////////////////////////////////////////////////////////////// -UNICODE_PUNCT_RE = re.compile( - r"[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]" -) - -# Currently without astral characters support. def isPunctChar(ch: str) -> bool: """Check if character is a punctuation character.""" - return UNICODE_PUNCT_RE.search(ch) is not None + return unicodedata.category(ch).startswith(("P", "S")) MD_ASCII_PUNCT = { diff --git a/tests/test_cmark_spec/commonmark.json b/tests/test_cmark_spec/commonmark.json index d742f941..1f89e66f 100644 --- a/tests/test_cmark_spec/commonmark.json +++ b/tests/test_cmark_spec/commonmark.json @@ -3,5005 +3,5005 @@ "markdown": "\tfoo\tbaz\t\tbim\n", "html": "

foo\tbaz\t\tbim\n
\n", "example": 1, - "start_line": 356, - "end_line": 361, + "start_line": 355, + "end_line": 360, "section": "Tabs" }, { "markdown": " \tfoo\tbaz\t\tbim\n", "html": "
foo\tbaz\t\tbim\n
\n", "example": 2, - "start_line": 363, - "end_line": 368, + "start_line": 362, + "end_line": 367, "section": "Tabs" }, { "markdown": " a\ta\n ὐ\ta\n", "html": "
a\ta\nὐ\ta\n
\n", "example": 3, - "start_line": 370, - "end_line": 377, + "start_line": 369, + "end_line": 376, "section": "Tabs" }, { "markdown": " - foo\n\n\tbar\n", "html": "
    \n
  • \n

    foo

    \n

    bar

    \n
  • \n
\n", "example": 4, - "start_line": 383, - "end_line": 394, + "start_line": 382, + "end_line": 393, "section": "Tabs" }, { "markdown": "- foo\n\n\t\tbar\n", "html": "
    \n
  • \n

    foo

    \n
      bar\n
    \n
  • \n
\n", "example": 5, - "start_line": 396, - "end_line": 408, + "start_line": 395, + "end_line": 407, "section": "Tabs" }, { "markdown": ">\t\tfoo\n", "html": "
\n
  foo\n
\n
\n", "example": 6, - "start_line": 419, - "end_line": 426, + "start_line": 418, + "end_line": 425, "section": "Tabs" }, { "markdown": "-\t\tfoo\n", "html": "
    \n
  • \n
      foo\n
    \n
  • \n
\n", "example": 7, - "start_line": 428, - "end_line": 437, + "start_line": 427, + "end_line": 436, "section": "Tabs" }, { "markdown": " foo\n\tbar\n", "html": "
foo\nbar\n
\n", "example": 8, - "start_line": 440, - "end_line": 447, + "start_line": 439, + "end_line": 446, "section": "Tabs" }, { "markdown": " - foo\n - bar\n\t - baz\n", "html": "
    \n
  • foo\n
      \n
    • bar\n
        \n
      • baz
      • \n
      \n
    • \n
    \n
  • \n
\n", "example": 9, - "start_line": 449, - "end_line": 465, + "start_line": 448, + "end_line": 464, "section": "Tabs" }, { "markdown": "#\tFoo\n", "html": "

Foo

\n", "example": 10, - "start_line": 467, - "end_line": 471, + "start_line": 466, + "end_line": 470, "section": "Tabs" }, { "markdown": "*\t*\t*\t\n", "html": "
\n", "example": 11, - "start_line": 473, - "end_line": 477, + "start_line": 472, + "end_line": 476, "section": "Tabs" }, { "markdown": "\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~\n", "html": "

!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~

\n", "example": 12, - "start_line": 490, - "end_line": 494, + "start_line": 489, + "end_line": 493, "section": "Backslash escapes" }, { "markdown": "\\\t\\A\\a\\ \\3\\φ\\«\n", "html": "

\\\t\\A\\a\\ \\3\\φ\\«

\n", "example": 13, - "start_line": 500, - "end_line": 504, + "start_line": 499, + "end_line": 503, "section": "Backslash escapes" }, { "markdown": "\\*not emphasized*\n\\
not a tag\n\\[not a link](/foo)\n\\`not code`\n1\\. not a list\n\\* not a list\n\\# not a heading\n\\[foo]: /url \"not a reference\"\n\\ö not a character entity\n", "html": "

*not emphasized*\n<br/> not a tag\n[not a link](/foo)\n`not code`\n1. not a list\n* not a list\n# not a heading\n[foo]: /url "not a reference"\n&ouml; not a character entity

\n", "example": 14, - "start_line": 510, - "end_line": 530, + "start_line": 509, + "end_line": 529, "section": "Backslash escapes" }, { "markdown": "\\\\*emphasis*\n", "html": "

\\emphasis

\n", "example": 15, - "start_line": 535, - "end_line": 539, + "start_line": 534, + "end_line": 538, "section": "Backslash escapes" }, { "markdown": "foo\\\nbar\n", "html": "

foo
\nbar

\n", "example": 16, - "start_line": 544, - "end_line": 550, + "start_line": 543, + "end_line": 549, "section": "Backslash escapes" }, { "markdown": "`` \\[\\` ``\n", "html": "

\\[\\`

\n", "example": 17, - "start_line": 556, - "end_line": 560, + "start_line": 555, + "end_line": 559, "section": "Backslash escapes" }, { "markdown": " \\[\\]\n", "html": "
\\[\\]\n
\n", "example": 18, - "start_line": 563, - "end_line": 568, + "start_line": 562, + "end_line": 567, "section": "Backslash escapes" }, { "markdown": "~~~\n\\[\\]\n~~~\n", "html": "
\\[\\]\n
\n", "example": 19, - "start_line": 571, - "end_line": 578, + "start_line": 570, + "end_line": 577, "section": "Backslash escapes" }, { - "markdown": "\n", - "html": "

http://example.com?find=\\*

\n", + "markdown": "\n", + "html": "

https://example.com?find=\\*

\n", "example": 20, - "start_line": 581, - "end_line": 585, + "start_line": 580, + "end_line": 584, "section": "Backslash escapes" }, { "markdown": "\n", "html": "\n", "example": 21, - "start_line": 588, - "end_line": 592, + "start_line": 587, + "end_line": 591, "section": "Backslash escapes" }, { "markdown": "[foo](/bar\\* \"ti\\*tle\")\n", "html": "

foo

\n", "example": 22, - "start_line": 598, - "end_line": 602, + "start_line": 597, + "end_line": 601, "section": "Backslash escapes" }, { "markdown": "[foo]\n\n[foo]: /bar\\* \"ti\\*tle\"\n", "html": "

foo

\n", "example": 23, - "start_line": 605, - "end_line": 611, + "start_line": 604, + "end_line": 610, "section": "Backslash escapes" }, { "markdown": "``` foo\\+bar\nfoo\n```\n", "html": "
foo\n
\n", "example": 24, - "start_line": 614, - "end_line": 621, + "start_line": 613, + "end_line": 620, "section": "Backslash escapes" }, { "markdown": "  & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸\n", "html": "

  & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸

\n", "example": 25, - "start_line": 650, - "end_line": 658, + "start_line": 649, + "end_line": 657, "section": "Entity and numeric character references" }, { "markdown": "# Ӓ Ϡ �\n", "html": "

# Ӓ Ϡ �

\n", "example": 26, - "start_line": 669, - "end_line": 673, + "start_line": 668, + "end_line": 672, "section": "Entity and numeric character references" }, { "markdown": "" ആ ಫ\n", "html": "

" ആ ಫ

\n", "example": 27, - "start_line": 682, - "end_line": 686, + "start_line": 681, + "end_line": 685, "section": "Entity and numeric character references" }, { "markdown": "  &x; &#; &#x;\n�\n&#abcdef0;\n&ThisIsNotDefined; &hi?;\n", "html": "

&nbsp &x; &#; &#x;\n&#87654321;\n&#abcdef0;\n&ThisIsNotDefined; &hi?;

\n", "example": 28, - "start_line": 691, - "end_line": 701, + "start_line": 690, + "end_line": 700, "section": "Entity and numeric character references" }, { "markdown": "©\n", "html": "

&copy

\n", "example": 29, - "start_line": 708, - "end_line": 712, + "start_line": 707, + "end_line": 711, "section": "Entity and numeric character references" }, { "markdown": "&MadeUpEntity;\n", "html": "

&MadeUpEntity;

\n", "example": 30, - "start_line": 718, - "end_line": 722, + "start_line": 717, + "end_line": 721, "section": "Entity and numeric character references" }, { "markdown": "\n", "html": "\n", "example": 31, - "start_line": 729, - "end_line": 733, + "start_line": 728, + "end_line": 732, "section": "Entity and numeric character references" }, { "markdown": "[foo](/föö \"föö\")\n", "html": "

foo

\n", "example": 32, - "start_line": 736, - "end_line": 740, + "start_line": 735, + "end_line": 739, "section": "Entity and numeric character references" }, { "markdown": "[foo]\n\n[foo]: /föö \"föö\"\n", "html": "

foo

\n", "example": 33, - "start_line": 743, - "end_line": 749, + "start_line": 742, + "end_line": 748, "section": "Entity and numeric character references" }, { "markdown": "``` föö\nfoo\n```\n", "html": "
foo\n
\n", "example": 34, - "start_line": 752, - "end_line": 759, + "start_line": 751, + "end_line": 758, "section": "Entity and numeric character references" }, { "markdown": "`föö`\n", "html": "

f&ouml;&ouml;

\n", "example": 35, - "start_line": 765, - "end_line": 769, + "start_line": 764, + "end_line": 768, "section": "Entity and numeric character references" }, { "markdown": " föfö\n", "html": "
f&ouml;f&ouml;\n
\n", "example": 36, - "start_line": 772, - "end_line": 777, + "start_line": 771, + "end_line": 776, "section": "Entity and numeric character references" }, { "markdown": "*foo*\n*foo*\n", "html": "

*foo*\nfoo

\n", "example": 37, - "start_line": 784, - "end_line": 790, + "start_line": 783, + "end_line": 789, "section": "Entity and numeric character references" }, { "markdown": "* foo\n\n* foo\n", "html": "

* foo

\n
    \n
  • foo
  • \n
\n", "example": 38, - "start_line": 792, - "end_line": 801, + "start_line": 791, + "end_line": 800, "section": "Entity and numeric character references" }, { "markdown": "foo bar\n", "html": "

foo\n\nbar

\n", "example": 39, - "start_line": 803, - "end_line": 809, + "start_line": 802, + "end_line": 808, "section": "Entity and numeric character references" }, { "markdown": " foo\n", "html": "

\tfoo

\n", "example": 40, - "start_line": 811, - "end_line": 815, + "start_line": 810, + "end_line": 814, "section": "Entity and numeric character references" }, { "markdown": "[a](url "tit")\n", "html": "

[a](url "tit")

\n", "example": 41, - "start_line": 818, - "end_line": 822, + "start_line": 817, + "end_line": 821, "section": "Entity and numeric character references" }, { "markdown": "- `one\n- two`\n", "html": "
    \n
  • `one
  • \n
  • two`
  • \n
\n", "example": 42, - "start_line": 841, - "end_line": 849, + "start_line": 840, + "end_line": 848, "section": "Precedence" }, { "markdown": "***\n---\n___\n", "html": "
\n
\n
\n", "example": 43, - "start_line": 880, - "end_line": 888, + "start_line": 879, + "end_line": 887, "section": "Thematic breaks" }, { "markdown": "+++\n", "html": "

+++

\n", "example": 44, - "start_line": 893, - "end_line": 897, + "start_line": 892, + "end_line": 896, "section": "Thematic breaks" }, { "markdown": "===\n", "html": "

===

\n", "example": 45, - "start_line": 900, - "end_line": 904, + "start_line": 899, + "end_line": 903, "section": "Thematic breaks" }, { "markdown": "--\n**\n__\n", "html": "

--\n**\n__

\n", "example": 46, - "start_line": 909, - "end_line": 917, + "start_line": 908, + "end_line": 916, "section": "Thematic breaks" }, { "markdown": " ***\n ***\n ***\n", "html": "
\n
\n
\n", "example": 47, - "start_line": 922, - "end_line": 930, + "start_line": 921, + "end_line": 929, "section": "Thematic breaks" }, { "markdown": " ***\n", "html": "
***\n
\n", "example": 48, - "start_line": 935, - "end_line": 940, + "start_line": 934, + "end_line": 939, "section": "Thematic breaks" }, { "markdown": "Foo\n ***\n", "html": "

Foo\n***

\n", "example": 49, - "start_line": 943, - "end_line": 949, + "start_line": 942, + "end_line": 948, "section": "Thematic breaks" }, { "markdown": "_____________________________________\n", "html": "
\n", "example": 50, - "start_line": 954, - "end_line": 958, + "start_line": 953, + "end_line": 957, "section": "Thematic breaks" }, { "markdown": " - - -\n", "html": "
\n", "example": 51, - "start_line": 963, - "end_line": 967, + "start_line": 962, + "end_line": 966, "section": "Thematic breaks" }, { "markdown": " ** * ** * ** * **\n", "html": "
\n", "example": 52, - "start_line": 970, - "end_line": 974, + "start_line": 969, + "end_line": 973, "section": "Thematic breaks" }, { "markdown": "- - - -\n", "html": "
\n", "example": 53, - "start_line": 977, - "end_line": 981, + "start_line": 976, + "end_line": 980, "section": "Thematic breaks" }, { "markdown": "- - - - \n", "html": "
\n", "example": 54, - "start_line": 986, - "end_line": 990, + "start_line": 985, + "end_line": 989, "section": "Thematic breaks" }, { "markdown": "_ _ _ _ a\n\na------\n\n---a---\n", "html": "

_ _ _ _ a

\n

a------

\n

---a---

\n", "example": 55, - "start_line": 995, - "end_line": 1005, + "start_line": 994, + "end_line": 1004, "section": "Thematic breaks" }, { "markdown": " *-*\n", "html": "

-

\n", "example": 56, - "start_line": 1011, - "end_line": 1015, + "start_line": 1010, + "end_line": 1014, "section": "Thematic breaks" }, { "markdown": "- foo\n***\n- bar\n", "html": "
    \n
  • foo
  • \n
\n
\n
    \n
  • bar
  • \n
\n", "example": 57, - "start_line": 1020, - "end_line": 1032, + "start_line": 1019, + "end_line": 1031, "section": "Thematic breaks" }, { "markdown": "Foo\n***\nbar\n", "html": "

Foo

\n
\n

bar

\n", "example": 58, - "start_line": 1037, - "end_line": 1045, + "start_line": 1036, + "end_line": 1044, "section": "Thematic breaks" }, { "markdown": "Foo\n---\nbar\n", "html": "

Foo

\n

bar

\n", "example": 59, - "start_line": 1054, - "end_line": 1061, + "start_line": 1053, + "end_line": 1060, "section": "Thematic breaks" }, { "markdown": "* Foo\n* * *\n* Bar\n", "html": "
    \n
  • Foo
  • \n
\n
\n
    \n
  • Bar
  • \n
\n", "example": 60, - "start_line": 1067, - "end_line": 1079, + "start_line": 1066, + "end_line": 1078, "section": "Thematic breaks" }, { "markdown": "- Foo\n- * * *\n", "html": "
    \n
  • Foo
  • \n
  • \n
    \n
  • \n
\n", "example": 61, - "start_line": 1084, - "end_line": 1094, + "start_line": 1083, + "end_line": 1093, "section": "Thematic breaks" }, { "markdown": "# foo\n## foo\n### foo\n#### foo\n##### foo\n###### foo\n", "html": "

foo

\n

foo

\n

foo

\n

foo

\n
foo
\n
foo
\n", "example": 62, - "start_line": 1113, - "end_line": 1127, + "start_line": 1112, + "end_line": 1126, "section": "ATX headings" }, { "markdown": "####### foo\n", "html": "

####### foo

\n", "example": 63, - "start_line": 1132, - "end_line": 1136, + "start_line": 1131, + "end_line": 1135, "section": "ATX headings" }, { "markdown": "#5 bolt\n\n#hashtag\n", "html": "

#5 bolt

\n

#hashtag

\n", "example": 64, - "start_line": 1147, - "end_line": 1154, + "start_line": 1146, + "end_line": 1153, "section": "ATX headings" }, { "markdown": "\\## foo\n", "html": "

## foo

\n", "example": 65, - "start_line": 1159, - "end_line": 1163, + "start_line": 1158, + "end_line": 1162, "section": "ATX headings" }, { "markdown": "# foo *bar* \\*baz\\*\n", "html": "

foo bar *baz*

\n", "example": 66, - "start_line": 1168, - "end_line": 1172, + "start_line": 1167, + "end_line": 1171, "section": "ATX headings" }, { "markdown": "# foo \n", "html": "

foo

\n", "example": 67, - "start_line": 1177, - "end_line": 1181, + "start_line": 1176, + "end_line": 1180, "section": "ATX headings" }, { "markdown": " ### foo\n ## foo\n # foo\n", "html": "

foo

\n

foo

\n

foo

\n", "example": 68, - "start_line": 1186, - "end_line": 1194, + "start_line": 1185, + "end_line": 1193, "section": "ATX headings" }, { "markdown": " # foo\n", "html": "
# foo\n
\n", "example": 69, - "start_line": 1199, - "end_line": 1204, + "start_line": 1198, + "end_line": 1203, "section": "ATX headings" }, { "markdown": "foo\n # bar\n", "html": "

foo\n# bar

\n", "example": 70, - "start_line": 1207, - "end_line": 1213, + "start_line": 1206, + "end_line": 1212, "section": "ATX headings" }, { "markdown": "## foo ##\n ### bar ###\n", "html": "

foo

\n

bar

\n", "example": 71, - "start_line": 1218, - "end_line": 1224, + "start_line": 1217, + "end_line": 1223, "section": "ATX headings" }, { "markdown": "# foo ##################################\n##### foo ##\n", "html": "

foo

\n
foo
\n", "example": 72, - "start_line": 1229, - "end_line": 1235, + "start_line": 1228, + "end_line": 1234, "section": "ATX headings" }, { "markdown": "### foo ### \n", "html": "

foo

\n", "example": 73, - "start_line": 1240, - "end_line": 1244, + "start_line": 1239, + "end_line": 1243, "section": "ATX headings" }, { "markdown": "### foo ### b\n", "html": "

foo ### b

\n", "example": 74, - "start_line": 1251, - "end_line": 1255, + "start_line": 1250, + "end_line": 1254, "section": "ATX headings" }, { "markdown": "# foo#\n", "html": "

foo#

\n", "example": 75, - "start_line": 1260, - "end_line": 1264, + "start_line": 1259, + "end_line": 1263, "section": "ATX headings" }, { "markdown": "### foo \\###\n## foo #\\##\n# foo \\#\n", "html": "

foo ###

\n

foo ###

\n

foo #

\n", "example": 76, - "start_line": 1270, - "end_line": 1278, + "start_line": 1269, + "end_line": 1277, "section": "ATX headings" }, { "markdown": "****\n## foo\n****\n", "html": "
\n

foo

\n
\n", "example": 77, - "start_line": 1284, - "end_line": 1292, + "start_line": 1283, + "end_line": 1291, "section": "ATX headings" }, { "markdown": "Foo bar\n# baz\nBar foo\n", "html": "

Foo bar

\n

baz

\n

Bar foo

\n", "example": 78, - "start_line": 1295, - "end_line": 1303, + "start_line": 1294, + "end_line": 1302, "section": "ATX headings" }, { "markdown": "## \n#\n### ###\n", "html": "

\n

\n

\n", "example": 79, - "start_line": 1308, - "end_line": 1316, + "start_line": 1307, + "end_line": 1315, "section": "ATX headings" }, { "markdown": "Foo *bar*\n=========\n\nFoo *bar*\n---------\n", "html": "

Foo bar

\n

Foo bar

\n", "example": 80, - "start_line": 1351, - "end_line": 1360, + "start_line": 1347, + "end_line": 1356, "section": "Setext headings" }, { "markdown": "Foo *bar\nbaz*\n====\n", "html": "

Foo bar\nbaz

\n", "example": 81, - "start_line": 1365, - "end_line": 1372, + "start_line": 1361, + "end_line": 1368, "section": "Setext headings" }, { "markdown": " Foo *bar\nbaz*\t\n====\n", "html": "

Foo bar\nbaz

\n", "example": 82, - "start_line": 1379, - "end_line": 1386, + "start_line": 1375, + "end_line": 1382, "section": "Setext headings" }, { "markdown": "Foo\n-------------------------\n\nFoo\n=\n", "html": "

Foo

\n

Foo

\n", "example": 83, - "start_line": 1391, - "end_line": 1400, + "start_line": 1387, + "end_line": 1396, "section": "Setext headings" }, { "markdown": " Foo\n---\n\n Foo\n-----\n\n Foo\n ===\n", "html": "

Foo

\n

Foo

\n

Foo

\n", "example": 84, - "start_line": 1406, - "end_line": 1419, + "start_line": 1402, + "end_line": 1415, "section": "Setext headings" }, { "markdown": " Foo\n ---\n\n Foo\n---\n", "html": "
Foo\n---\n\nFoo\n
\n
\n", "example": 85, - "start_line": 1424, - "end_line": 1437, + "start_line": 1420, + "end_line": 1433, "section": "Setext headings" }, { "markdown": "Foo\n ---- \n", "html": "

Foo

\n", "example": 86, - "start_line": 1443, - "end_line": 1448, + "start_line": 1439, + "end_line": 1444, "section": "Setext headings" }, { "markdown": "Foo\n ---\n", "html": "

Foo\n---

\n", "example": 87, - "start_line": 1453, - "end_line": 1459, + "start_line": 1449, + "end_line": 1455, "section": "Setext headings" }, { "markdown": "Foo\n= =\n\nFoo\n--- -\n", "html": "

Foo\n= =

\n

Foo

\n
\n", "example": 88, - "start_line": 1464, - "end_line": 1475, + "start_line": 1460, + "end_line": 1471, "section": "Setext headings" }, { "markdown": "Foo \n-----\n", "html": "

Foo

\n", "example": 89, - "start_line": 1480, - "end_line": 1485, + "start_line": 1476, + "end_line": 1481, "section": "Setext headings" }, { "markdown": "Foo\\\n----\n", "html": "

Foo\\

\n", "example": 90, - "start_line": 1490, - "end_line": 1495, + "start_line": 1486, + "end_line": 1491, "section": "Setext headings" }, { "markdown": "`Foo\n----\n`\n\n\n", "html": "

`Foo

\n

`

\n

<a title="a lot

\n

of dashes"/>

\n", "example": 91, - "start_line": 1501, - "end_line": 1514, + "start_line": 1497, + "end_line": 1510, "section": "Setext headings" }, { "markdown": "> Foo\n---\n", "html": "
\n

Foo

\n
\n
\n", "example": 92, - "start_line": 1520, - "end_line": 1528, + "start_line": 1516, + "end_line": 1524, "section": "Setext headings" }, { "markdown": "> foo\nbar\n===\n", "html": "
\n

foo\nbar\n===

\n
\n", "example": 93, - "start_line": 1531, - "end_line": 1541, + "start_line": 1527, + "end_line": 1537, "section": "Setext headings" }, { "markdown": "- Foo\n---\n", "html": "
    \n
  • Foo
  • \n
\n
\n", "example": 94, - "start_line": 1544, - "end_line": 1552, + "start_line": 1540, + "end_line": 1548, "section": "Setext headings" }, { "markdown": "Foo\nBar\n---\n", "html": "

Foo\nBar

\n", "example": 95, - "start_line": 1559, - "end_line": 1566, + "start_line": 1555, + "end_line": 1562, "section": "Setext headings" }, { "markdown": "---\nFoo\n---\nBar\n---\nBaz\n", "html": "
\n

Foo

\n

Bar

\n

Baz

\n", "example": 96, - "start_line": 1572, - "end_line": 1584, + "start_line": 1568, + "end_line": 1580, "section": "Setext headings" }, { "markdown": "\n====\n", "html": "

====

\n", "example": 97, - "start_line": 1589, - "end_line": 1594, + "start_line": 1585, + "end_line": 1590, "section": "Setext headings" }, { "markdown": "---\n---\n", "html": "
\n
\n", "example": 98, - "start_line": 1601, - "end_line": 1607, + "start_line": 1597, + "end_line": 1603, "section": "Setext headings" }, { "markdown": "- foo\n-----\n", "html": "
    \n
  • foo
  • \n
\n
\n", "example": 99, - "start_line": 1610, - "end_line": 1618, + "start_line": 1606, + "end_line": 1614, "section": "Setext headings" }, { "markdown": " foo\n---\n", "html": "
foo\n
\n
\n", "example": 100, - "start_line": 1621, - "end_line": 1628, + "start_line": 1617, + "end_line": 1624, "section": "Setext headings" }, { "markdown": "> foo\n-----\n", "html": "
\n

foo

\n
\n
\n", "example": 101, - "start_line": 1631, - "end_line": 1639, + "start_line": 1627, + "end_line": 1635, "section": "Setext headings" }, { "markdown": "\\> foo\n------\n", "html": "

> foo

\n", "example": 102, - "start_line": 1645, - "end_line": 1650, + "start_line": 1641, + "end_line": 1646, "section": "Setext headings" }, { "markdown": "Foo\n\nbar\n---\nbaz\n", "html": "

Foo

\n

bar

\n

baz

\n", "example": 103, - "start_line": 1676, - "end_line": 1686, + "start_line": 1672, + "end_line": 1682, "section": "Setext headings" }, { "markdown": "Foo\nbar\n\n---\n\nbaz\n", "html": "

Foo\nbar

\n
\n

baz

\n", "example": 104, - "start_line": 1692, - "end_line": 1704, + "start_line": 1688, + "end_line": 1700, "section": "Setext headings" }, { "markdown": "Foo\nbar\n* * *\nbaz\n", "html": "

Foo\nbar

\n
\n

baz

\n", "example": 105, - "start_line": 1710, - "end_line": 1720, + "start_line": 1706, + "end_line": 1716, "section": "Setext headings" }, { "markdown": "Foo\nbar\n\\---\nbaz\n", "html": "

Foo\nbar\n---\nbaz

\n", "example": 106, - "start_line": 1725, - "end_line": 1735, + "start_line": 1721, + "end_line": 1731, "section": "Setext headings" }, { "markdown": " a simple\n indented code block\n", "html": "
a simple\n  indented code block\n
\n", "example": 107, - "start_line": 1753, - "end_line": 1760, + "start_line": 1749, + "end_line": 1756, "section": "Indented code blocks" }, { "markdown": " - foo\n\n bar\n", "html": "
    \n
  • \n

    foo

    \n

    bar

    \n
  • \n
\n", "example": 108, - "start_line": 1767, - "end_line": 1778, + "start_line": 1763, + "end_line": 1774, "section": "Indented code blocks" }, { "markdown": "1. foo\n\n - bar\n", "html": "
    \n
  1. \n

    foo

    \n
      \n
    • bar
    • \n
    \n
  2. \n
\n", "example": 109, - "start_line": 1781, - "end_line": 1794, + "start_line": 1777, + "end_line": 1790, "section": "Indented code blocks" }, { "markdown": "
\n *hi*\n\n - one\n", "html": "
<a/>\n*hi*\n\n- one\n
\n", "example": 110, - "start_line": 1801, - "end_line": 1812, + "start_line": 1797, + "end_line": 1808, "section": "Indented code blocks" }, { "markdown": " chunk1\n\n chunk2\n \n \n \n chunk3\n", "html": "
chunk1\n\nchunk2\n\n\n\nchunk3\n
\n", "example": 111, - "start_line": 1817, - "end_line": 1834, + "start_line": 1813, + "end_line": 1830, "section": "Indented code blocks" }, { "markdown": " chunk1\n \n chunk2\n", "html": "
chunk1\n  \n  chunk2\n
\n", "example": 112, - "start_line": 1840, - "end_line": 1849, + "start_line": 1836, + "end_line": 1845, "section": "Indented code blocks" }, { "markdown": "Foo\n bar\n\n", "html": "

Foo\nbar

\n", "example": 113, - "start_line": 1855, - "end_line": 1862, + "start_line": 1851, + "end_line": 1858, "section": "Indented code blocks" }, { "markdown": " foo\nbar\n", "html": "
foo\n
\n

bar

\n", "example": 114, - "start_line": 1869, - "end_line": 1876, + "start_line": 1865, + "end_line": 1872, "section": "Indented code blocks" }, { "markdown": "# Heading\n foo\nHeading\n------\n foo\n----\n", "html": "

Heading

\n
foo\n
\n

Heading

\n
foo\n
\n
\n", "example": 115, - "start_line": 1882, - "end_line": 1897, + "start_line": 1878, + "end_line": 1893, "section": "Indented code blocks" }, { "markdown": " foo\n bar\n", "html": "
    foo\nbar\n
\n", "example": 116, - "start_line": 1902, - "end_line": 1909, + "start_line": 1898, + "end_line": 1905, "section": "Indented code blocks" }, { "markdown": "\n \n foo\n \n\n", "html": "
foo\n
\n", "example": 117, - "start_line": 1915, - "end_line": 1924, + "start_line": 1911, + "end_line": 1920, "section": "Indented code blocks" }, { "markdown": " foo \n", "html": "
foo  \n
\n", "example": 118, - "start_line": 1929, - "end_line": 1934, + "start_line": 1925, + "end_line": 1930, "section": "Indented code blocks" }, { "markdown": "```\n<\n >\n```\n", "html": "
<\n >\n
\n", "example": 119, - "start_line": 1984, - "end_line": 1993, + "start_line": 1980, + "end_line": 1989, "section": "Fenced code blocks" }, { "markdown": "~~~\n<\n >\n~~~\n", "html": "
<\n >\n
\n", "example": 120, - "start_line": 1998, - "end_line": 2007, + "start_line": 1994, + "end_line": 2003, "section": "Fenced code blocks" }, { "markdown": "``\nfoo\n``\n", "html": "

foo

\n", "example": 121, - "start_line": 2011, - "end_line": 2017, + "start_line": 2007, + "end_line": 2013, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n~~~\n```\n", "html": "
aaa\n~~~\n
\n", "example": 122, - "start_line": 2022, - "end_line": 2031, + "start_line": 2018, + "end_line": 2027, "section": "Fenced code blocks" }, { "markdown": "~~~\naaa\n```\n~~~\n", "html": "
aaa\n```\n
\n", "example": 123, - "start_line": 2034, - "end_line": 2043, + "start_line": 2030, + "end_line": 2039, "section": "Fenced code blocks" }, { "markdown": "````\naaa\n```\n``````\n", "html": "
aaa\n```\n
\n", "example": 124, - "start_line": 2048, - "end_line": 2057, + "start_line": 2044, + "end_line": 2053, "section": "Fenced code blocks" }, { "markdown": "~~~~\naaa\n~~~\n~~~~\n", "html": "
aaa\n~~~\n
\n", "example": 125, - "start_line": 2060, - "end_line": 2069, + "start_line": 2056, + "end_line": 2065, "section": "Fenced code blocks" }, { "markdown": "```\n", "html": "
\n", "example": 126, - "start_line": 2075, - "end_line": 2079, + "start_line": 2071, + "end_line": 2075, "section": "Fenced code blocks" }, { "markdown": "`````\n\n```\naaa\n", "html": "
\n```\naaa\n
\n", "example": 127, - "start_line": 2082, - "end_line": 2092, + "start_line": 2078, + "end_line": 2088, "section": "Fenced code blocks" }, { "markdown": "> ```\n> aaa\n\nbbb\n", "html": "
\n
aaa\n
\n
\n

bbb

\n", "example": 128, - "start_line": 2095, - "end_line": 2106, + "start_line": 2091, + "end_line": 2102, "section": "Fenced code blocks" }, { "markdown": "```\n\n \n```\n", "html": "
\n  \n
\n", "example": 129, - "start_line": 2111, - "end_line": 2120, + "start_line": 2107, + "end_line": 2116, "section": "Fenced code blocks" }, { "markdown": "```\n```\n", "html": "
\n", "example": 130, - "start_line": 2125, - "end_line": 2130, + "start_line": 2121, + "end_line": 2126, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\naaa\n```\n", "html": "
aaa\naaa\n
\n", "example": 131, - "start_line": 2137, - "end_line": 2146, + "start_line": 2133, + "end_line": 2142, "section": "Fenced code blocks" }, { "markdown": " ```\naaa\n aaa\naaa\n ```\n", "html": "
aaa\naaa\naaa\n
\n", "example": 132, - "start_line": 2149, - "end_line": 2160, + "start_line": 2145, + "end_line": 2156, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\n aaa\n aaa\n ```\n", "html": "
aaa\n aaa\naaa\n
\n", "example": 133, - "start_line": 2163, - "end_line": 2174, + "start_line": 2159, + "end_line": 2170, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\n ```\n", "html": "
```\naaa\n```\n
\n", "example": 134, - "start_line": 2179, - "end_line": 2188, + "start_line": 2175, + "end_line": 2184, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n ```\n", "html": "
aaa\n
\n", "example": 135, - "start_line": 2194, - "end_line": 2201, + "start_line": 2190, + "end_line": 2197, "section": "Fenced code blocks" }, { "markdown": " ```\naaa\n ```\n", "html": "
aaa\n
\n", "example": 136, - "start_line": 2204, - "end_line": 2211, + "start_line": 2200, + "end_line": 2207, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n ```\n", "html": "
aaa\n    ```\n
\n", "example": 137, - "start_line": 2216, - "end_line": 2224, + "start_line": 2212, + "end_line": 2220, "section": "Fenced code blocks" }, { "markdown": "``` ```\naaa\n", "html": "

\naaa

\n", "example": 138, - "start_line": 2230, - "end_line": 2236, + "start_line": 2226, + "end_line": 2232, "section": "Fenced code blocks" }, { "markdown": "~~~~~~\naaa\n~~~ ~~\n", "html": "
aaa\n~~~ ~~\n
\n", "example": 139, - "start_line": 2239, - "end_line": 2247, + "start_line": 2235, + "end_line": 2243, "section": "Fenced code blocks" }, { "markdown": "foo\n```\nbar\n```\nbaz\n", "html": "

foo

\n
bar\n
\n

baz

\n", "example": 140, - "start_line": 2253, - "end_line": 2264, + "start_line": 2249, + "end_line": 2260, "section": "Fenced code blocks" }, { "markdown": "foo\n---\n~~~\nbar\n~~~\n# baz\n", "html": "

foo

\n
bar\n
\n

baz

\n", "example": 141, - "start_line": 2270, - "end_line": 2282, + "start_line": 2266, + "end_line": 2278, "section": "Fenced code blocks" }, { "markdown": "```ruby\ndef foo(x)\n return 3\nend\n```\n", "html": "
def foo(x)\n  return 3\nend\n
\n", "example": 142, - "start_line": 2292, - "end_line": 2303, + "start_line": 2288, + "end_line": 2299, "section": "Fenced code blocks" }, { "markdown": "~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~\n", "html": "
def foo(x)\n  return 3\nend\n
\n", "example": 143, - "start_line": 2306, - "end_line": 2317, + "start_line": 2302, + "end_line": 2313, "section": "Fenced code blocks" }, { "markdown": "````;\n````\n", "html": "
\n", "example": 144, - "start_line": 2320, - "end_line": 2325, + "start_line": 2316, + "end_line": 2321, "section": "Fenced code blocks" }, { "markdown": "``` aa ```\nfoo\n", "html": "

aa\nfoo

\n", "example": 145, - "start_line": 2330, - "end_line": 2336, + "start_line": 2326, + "end_line": 2332, "section": "Fenced code blocks" }, { "markdown": "~~~ aa ``` ~~~\nfoo\n~~~\n", "html": "
foo\n
\n", "example": 146, - "start_line": 2341, - "end_line": 2348, + "start_line": 2337, + "end_line": 2344, "section": "Fenced code blocks" }, { "markdown": "```\n``` aaa\n```\n", "html": "
``` aaa\n
\n", "example": 147, - "start_line": 2353, - "end_line": 2360, + "start_line": 2349, + "end_line": 2356, "section": "Fenced code blocks" }, { "markdown": "
\n
\n**Hello**,\n\n_world_.\n
\n
\n", "html": "
\n
\n**Hello**,\n

world.\n

\n
\n", "example": 148, - "start_line": 2432, - "end_line": 2447, + "start_line": 2428, + "end_line": 2443, "section": "HTML blocks" }, { "markdown": "\n \n \n \n
\n hi\n
\n\nokay.\n", "html": "\n \n \n \n
\n hi\n
\n

okay.

\n", "example": 149, - "start_line": 2461, - "end_line": 2480, + "start_line": 2457, + "end_line": 2476, "section": "HTML blocks" }, { "markdown": "
\n*foo*\n", "example": 151, - "start_line": 2496, - "end_line": 2502, + "start_line": 2492, + "end_line": 2498, "section": "HTML blocks" }, { "markdown": "
\n\n*Markdown*\n\n
\n", "html": "
\n

Markdown

\n
\n", "example": 152, - "start_line": 2507, - "end_line": 2517, + "start_line": 2503, + "end_line": 2513, "section": "HTML blocks" }, { "markdown": "
\n
\n", "html": "
\n
\n", "example": 153, - "start_line": 2523, - "end_line": 2531, + "start_line": 2519, + "end_line": 2527, "section": "HTML blocks" }, { "markdown": "
\n
\n", "html": "
\n
\n", "example": 154, - "start_line": 2534, - "end_line": 2542, + "start_line": 2530, + "end_line": 2538, "section": "HTML blocks" }, { "markdown": "
\n*foo*\n\n*bar*\n", "html": "
\n*foo*\n

bar

\n", "example": 155, - "start_line": 2546, - "end_line": 2555, + "start_line": 2542, + "end_line": 2551, "section": "HTML blocks" }, { "markdown": "
\n", "html": "\n", "example": 159, - "start_line": 2595, - "end_line": 2599, + "start_line": 2591, + "end_line": 2595, "section": "HTML blocks" }, { "markdown": "
\nfoo\n
\n", "html": "
\nfoo\n
\n", "example": 160, - "start_line": 2602, - "end_line": 2610, + "start_line": 2598, + "end_line": 2606, "section": "HTML blocks" }, { "markdown": "
\n``` c\nint x = 33;\n```\n", "html": "
\n``` c\nint x = 33;\n```\n", "example": 161, - "start_line": 2619, - "end_line": 2629, + "start_line": 2615, + "end_line": 2625, "section": "HTML blocks" }, { "markdown": "\n*bar*\n\n", "html": "\n*bar*\n\n", "example": 162, - "start_line": 2636, - "end_line": 2644, + "start_line": 2632, + "end_line": 2640, "section": "HTML blocks" }, { "markdown": "\n*bar*\n\n", "html": "\n*bar*\n\n", "example": 163, - "start_line": 2649, - "end_line": 2657, + "start_line": 2645, + "end_line": 2653, "section": "HTML blocks" }, { "markdown": "\n*bar*\n\n", "html": "\n*bar*\n\n", "example": 164, - "start_line": 2660, - "end_line": 2668, + "start_line": 2656, + "end_line": 2664, "section": "HTML blocks" }, { "markdown": "\n*bar*\n", "html": "\n*bar*\n", "example": 165, - "start_line": 2671, - "end_line": 2677, + "start_line": 2667, + "end_line": 2673, "section": "HTML blocks" }, { "markdown": "\n*foo*\n\n", "html": "\n*foo*\n\n", "example": 166, - "start_line": 2686, - "end_line": 2694, + "start_line": 2682, + "end_line": 2690, "section": "HTML blocks" }, { "markdown": "\n\n*foo*\n\n\n", "html": "\n

foo

\n
\n", "example": 167, - "start_line": 2701, - "end_line": 2711, + "start_line": 2697, + "end_line": 2707, "section": "HTML blocks" }, { "markdown": "*foo*\n", "html": "

foo

\n", "example": 168, - "start_line": 2719, - "end_line": 2723, + "start_line": 2715, + "end_line": 2719, "section": "HTML blocks" }, { "markdown": "
\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n
\nokay\n", "html": "
\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n
\n

okay

\n", "example": 169, - "start_line": 2735, - "end_line": 2751, + "start_line": 2731, + "end_line": 2747, "section": "HTML blocks" }, { "markdown": "\nokay\n", "html": "\n

okay

\n", "example": 170, - "start_line": 2756, - "end_line": 2770, + "start_line": 2752, + "end_line": 2766, "section": "HTML blocks" }, { "markdown": "\n", "html": "\n", "example": 171, - "start_line": 2775, - "end_line": 2791, + "start_line": 2771, + "end_line": 2787, "section": "HTML blocks" }, { "markdown": "\nh1 {color:red;}\n\np {color:blue;}\n\nokay\n", "html": "\nh1 {color:red;}\n\np {color:blue;}\n\n

okay

\n", "example": 172, - "start_line": 2795, - "end_line": 2811, + "start_line": 2791, + "end_line": 2807, "section": "HTML blocks" }, { "markdown": "\n\nfoo\n", "html": "\n\nfoo\n", "example": 173, - "start_line": 2818, - "end_line": 2828, + "start_line": 2814, + "end_line": 2824, "section": "HTML blocks" }, { "markdown": ">
\n> foo\n\nbar\n", "html": "
\n
\nfoo\n
\n

bar

\n", "example": 174, - "start_line": 2831, - "end_line": 2842, + "start_line": 2827, + "end_line": 2838, "section": "HTML blocks" }, { "markdown": "-
\n- foo\n", "html": "
    \n
  • \n
    \n
  • \n
  • foo
  • \n
\n", "example": 175, - "start_line": 2845, - "end_line": 2855, + "start_line": 2841, + "end_line": 2851, "section": "HTML blocks" }, { "markdown": "\n*foo*\n", "html": "\n

foo

\n", "example": 176, - "start_line": 2860, - "end_line": 2866, + "start_line": 2856, + "end_line": 2862, "section": "HTML blocks" }, { "markdown": "*bar*\n*baz*\n", "html": "*bar*\n

baz

\n", "example": 177, - "start_line": 2869, - "end_line": 2875, + "start_line": 2865, + "end_line": 2871, "section": "HTML blocks" }, { "markdown": "1. *bar*\n", "html": "1. *bar*\n", "example": 178, - "start_line": 2881, - "end_line": 2889, + "start_line": 2877, + "end_line": 2885, "section": "HTML blocks" }, { "markdown": "\nokay\n", "html": "\n

okay

\n", "example": 179, - "start_line": 2894, - "end_line": 2906, + "start_line": 2890, + "end_line": 2902, "section": "HTML blocks" }, { "markdown": "';\n\n?>\nokay\n", "html": "';\n\n?>\n

okay

\n", "example": 180, - "start_line": 2912, - "end_line": 2926, + "start_line": 2908, + "end_line": 2922, "section": "HTML blocks" }, { "markdown": "\n", "html": "\n", "example": 181, - "start_line": 2931, - "end_line": 2935, + "start_line": 2927, + "end_line": 2931, "section": "HTML blocks" }, { "markdown": "\nokay\n", "html": "\n

okay

\n", "example": 182, - "start_line": 2940, - "end_line": 2968, + "start_line": 2936, + "end_line": 2964, "section": "HTML blocks" }, { "markdown": " \n\n \n", "html": " \n
<!-- foo -->\n
\n", "example": 183, - "start_line": 2974, - "end_line": 2982, + "start_line": 2970, + "end_line": 2978, "section": "HTML blocks" }, { "markdown": "
\n\n
\n", "html": "
\n
<div>\n
\n", "example": 184, - "start_line": 2985, - "end_line": 2993, + "start_line": 2981, + "end_line": 2989, "section": "HTML blocks" }, { "markdown": "Foo\n
\nbar\n
\n", "html": "

Foo

\n
\nbar\n
\n", "example": 185, - "start_line": 2999, - "end_line": 3009, + "start_line": 2995, + "end_line": 3005, "section": "HTML blocks" }, { "markdown": "
\nbar\n
\n*foo*\n", "html": "
\nbar\n
\n*foo*\n", "example": 186, - "start_line": 3016, - "end_line": 3026, + "start_line": 3012, + "end_line": 3022, "section": "HTML blocks" }, { "markdown": "Foo\n\nbaz\n", "html": "

Foo\n\nbaz

\n", "example": 187, - "start_line": 3031, - "end_line": 3039, + "start_line": 3027, + "end_line": 3035, "section": "HTML blocks" }, { "markdown": "
\n\n*Emphasized* text.\n\n
\n", "html": "
\n

Emphasized text.

\n
\n", "example": 188, - "start_line": 3072, - "end_line": 3082, + "start_line": 3068, + "end_line": 3078, "section": "HTML blocks" }, { "markdown": "
\n*Emphasized* text.\n
\n", "html": "
\n*Emphasized* text.\n
\n", "example": 189, - "start_line": 3085, - "end_line": 3093, + "start_line": 3081, + "end_line": 3089, "section": "HTML blocks" }, { "markdown": "\n\n\n\n\n\n\n\n
\nHi\n
\n", "html": "\n\n\n\n
\nHi\n
\n", "example": 190, - "start_line": 3107, - "end_line": 3127, + "start_line": 3103, + "end_line": 3123, "section": "HTML blocks" }, { "markdown": "\n\n \n\n \n\n \n\n
\n Hi\n
\n", "html": "\n \n
<td>\n  Hi\n</td>\n
\n \n
\n", "example": 191, - "start_line": 3134, - "end_line": 3155, + "start_line": 3130, + "end_line": 3151, "section": "HTML blocks" }, { "markdown": "[foo]: /url \"title\"\n\n[foo]\n", "html": "

foo

\n", "example": 192, - "start_line": 3183, - "end_line": 3189, + "start_line": 3179, + "end_line": 3185, "section": "Link reference definitions" }, { "markdown": " [foo]: \n /url \n 'the title' \n\n[foo]\n", "html": "

foo

\n", "example": 193, - "start_line": 3192, - "end_line": 3200, + "start_line": 3188, + "end_line": 3196, "section": "Link reference definitions" }, { "markdown": "[Foo*bar\\]]:my_(url) 'title (with parens)'\n\n[Foo*bar\\]]\n", "html": "

Foo*bar]

\n", "example": 194, - "start_line": 3203, - "end_line": 3209, + "start_line": 3199, + "end_line": 3205, "section": "Link reference definitions" }, { "markdown": "[Foo bar]:\n\n'title'\n\n[Foo bar]\n", "html": "

Foo bar

\n", "example": 195, - "start_line": 3212, - "end_line": 3220, + "start_line": 3208, + "end_line": 3216, "section": "Link reference definitions" }, { "markdown": "[foo]: /url '\ntitle\nline1\nline2\n'\n\n[foo]\n", "html": "

foo

\n", "example": 196, - "start_line": 3225, - "end_line": 3239, + "start_line": 3221, + "end_line": 3235, "section": "Link reference definitions" }, { "markdown": "[foo]: /url 'title\n\nwith blank line'\n\n[foo]\n", "html": "

[foo]: /url 'title

\n

with blank line'

\n

[foo]

\n", "example": 197, - "start_line": 3244, - "end_line": 3254, + "start_line": 3240, + "end_line": 3250, "section": "Link reference definitions" }, { "markdown": "[foo]:\n/url\n\n[foo]\n", "html": "

foo

\n", "example": 198, - "start_line": 3259, - "end_line": 3266, + "start_line": 3255, + "end_line": 3262, "section": "Link reference definitions" }, { "markdown": "[foo]:\n\n[foo]\n", "html": "

[foo]:

\n

[foo]

\n", "example": 199, - "start_line": 3271, - "end_line": 3278, + "start_line": 3267, + "end_line": 3274, "section": "Link reference definitions" }, { "markdown": "[foo]: <>\n\n[foo]\n", "html": "

foo

\n", "example": 200, - "start_line": 3283, - "end_line": 3289, + "start_line": 3279, + "end_line": 3285, "section": "Link reference definitions" }, { "markdown": "[foo]: (baz)\n\n[foo]\n", "html": "

[foo]: (baz)

\n

[foo]

\n", "example": 201, - "start_line": 3294, - "end_line": 3301, + "start_line": 3290, + "end_line": 3297, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\\bar\\*baz \"foo\\\"bar\\baz\"\n\n[foo]\n", "html": "

foo

\n", "example": 202, - "start_line": 3307, - "end_line": 3313, + "start_line": 3303, + "end_line": 3309, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n[foo]: url\n", "html": "

foo

\n", "example": 203, - "start_line": 3318, - "end_line": 3324, + "start_line": 3314, + "end_line": 3320, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n[foo]: first\n[foo]: second\n", "html": "

foo

\n", "example": 204, - "start_line": 3330, - "end_line": 3337, + "start_line": 3326, + "end_line": 3333, "section": "Link reference definitions" }, { "markdown": "[FOO]: /url\n\n[Foo]\n", "html": "

Foo

\n", "example": 205, - "start_line": 3343, - "end_line": 3349, + "start_line": 3339, + "end_line": 3345, "section": "Link reference definitions" }, { "markdown": "[ΑΓΩ]: /φου\n\n[αγω]\n", "html": "

αγω

\n", "example": 206, - "start_line": 3352, - "end_line": 3358, + "start_line": 3348, + "end_line": 3354, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n", "html": "", "example": 207, - "start_line": 3367, - "end_line": 3370, + "start_line": 3363, + "end_line": 3366, "section": "Link reference definitions" }, { "markdown": "[\nfoo\n]: /url\nbar\n", "html": "

bar

\n", "example": 208, - "start_line": 3375, - "end_line": 3382, + "start_line": 3371, + "end_line": 3378, "section": "Link reference definitions" }, { "markdown": "[foo]: /url \"title\" ok\n", "html": "

[foo]: /url "title" ok

\n", "example": 209, - "start_line": 3388, - "end_line": 3392, + "start_line": 3384, + "end_line": 3388, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n\"title\" ok\n", "html": "

"title" ok

\n", "example": 210, - "start_line": 3397, - "end_line": 3402, + "start_line": 3393, + "end_line": 3398, "section": "Link reference definitions" }, { "markdown": " [foo]: /url \"title\"\n\n[foo]\n", "html": "
[foo]: /url "title"\n
\n

[foo]

\n", "example": 211, - "start_line": 3408, - "end_line": 3416, + "start_line": 3404, + "end_line": 3412, "section": "Link reference definitions" }, { "markdown": "```\n[foo]: /url\n```\n\n[foo]\n", "html": "
[foo]: /url\n
\n

[foo]

\n", "example": 212, - "start_line": 3422, - "end_line": 3432, + "start_line": 3418, + "end_line": 3428, "section": "Link reference definitions" }, { "markdown": "Foo\n[bar]: /baz\n\n[bar]\n", "html": "

Foo\n[bar]: /baz

\n

[bar]

\n", "example": 213, - "start_line": 3437, - "end_line": 3446, + "start_line": 3433, + "end_line": 3442, "section": "Link reference definitions" }, { "markdown": "# [Foo]\n[foo]: /url\n> bar\n", "html": "

Foo

\n
\n

bar

\n
\n", "example": 214, - "start_line": 3452, - "end_line": 3461, + "start_line": 3448, + "end_line": 3457, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\nbar\n===\n[foo]\n", "html": "

bar

\n

foo

\n", "example": 215, - "start_line": 3463, - "end_line": 3471, + "start_line": 3459, + "end_line": 3467, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n===\n[foo]\n", "html": "

===\nfoo

\n", "example": 216, - "start_line": 3473, - "end_line": 3480, + "start_line": 3469, + "end_line": 3476, "section": "Link reference definitions" }, { "markdown": "[foo]: /foo-url \"foo\"\n[bar]: /bar-url\n \"bar\"\n[baz]: /baz-url\n\n[foo],\n[bar],\n[baz]\n", "html": "

foo,\nbar,\nbaz

\n", "example": 217, - "start_line": 3486, - "end_line": 3499, + "start_line": 3482, + "end_line": 3495, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n> [foo]: /url\n", "html": "

foo

\n
\n
\n", "example": 218, - "start_line": 3507, - "end_line": 3515, + "start_line": 3503, + "end_line": 3511, "section": "Link reference definitions" }, { "markdown": "aaa\n\nbbb\n", "html": "

aaa

\n

bbb

\n", "example": 219, - "start_line": 3529, - "end_line": 3536, + "start_line": 3525, + "end_line": 3532, "section": "Paragraphs" }, { "markdown": "aaa\nbbb\n\nccc\nddd\n", "html": "

aaa\nbbb

\n

ccc\nddd

\n", "example": 220, - "start_line": 3541, - "end_line": 3552, + "start_line": 3537, + "end_line": 3548, "section": "Paragraphs" }, { "markdown": "aaa\n\n\nbbb\n", "html": "

aaa

\n

bbb

\n", "example": 221, - "start_line": 3557, - "end_line": 3565, + "start_line": 3553, + "end_line": 3561, "section": "Paragraphs" }, { "markdown": " aaa\n bbb\n", "html": "

aaa\nbbb

\n", "example": 222, - "start_line": 3570, - "end_line": 3576, + "start_line": 3566, + "end_line": 3572, "section": "Paragraphs" }, { "markdown": "aaa\n bbb\n ccc\n", "html": "

aaa\nbbb\nccc

\n", "example": 223, - "start_line": 3582, - "end_line": 3590, + "start_line": 3578, + "end_line": 3586, "section": "Paragraphs" }, { "markdown": " aaa\nbbb\n", "html": "

aaa\nbbb

\n", "example": 224, - "start_line": 3596, - "end_line": 3602, + "start_line": 3592, + "end_line": 3598, "section": "Paragraphs" }, { "markdown": " aaa\nbbb\n", "html": "
aaa\n
\n

bbb

\n", "example": 225, - "start_line": 3605, - "end_line": 3612, + "start_line": 3601, + "end_line": 3608, "section": "Paragraphs" }, { "markdown": "aaa \nbbb \n", "html": "

aaa
\nbbb

\n", "example": 226, - "start_line": 3619, - "end_line": 3625, + "start_line": 3615, + "end_line": 3621, "section": "Paragraphs" }, { "markdown": " \n\naaa\n \n\n# aaa\n\n \n", "html": "

aaa

\n

aaa

\n", "example": 227, - "start_line": 3636, - "end_line": 3648, + "start_line": 3632, + "end_line": 3644, "section": "Blank lines" }, { "markdown": "> # Foo\n> bar\n> baz\n", "html": "
\n

Foo

\n

bar\nbaz

\n
\n", "example": 228, - "start_line": 3704, - "end_line": 3714, + "start_line": 3700, + "end_line": 3710, "section": "Block quotes" }, { "markdown": "># Foo\n>bar\n> baz\n", "html": "
\n

Foo

\n

bar\nbaz

\n
\n", "example": 229, - "start_line": 3719, - "end_line": 3729, + "start_line": 3715, + "end_line": 3725, "section": "Block quotes" }, { "markdown": " > # Foo\n > bar\n > baz\n", "html": "
\n

Foo

\n

bar\nbaz

\n
\n", "example": 230, - "start_line": 3734, - "end_line": 3744, + "start_line": 3730, + "end_line": 3740, "section": "Block quotes" }, { "markdown": " > # Foo\n > bar\n > baz\n", "html": "
> # Foo\n> bar\n> baz\n
\n", "example": 231, - "start_line": 3749, - "end_line": 3758, + "start_line": 3745, + "end_line": 3754, "section": "Block quotes" }, { "markdown": "> # Foo\n> bar\nbaz\n", "html": "
\n

Foo

\n

bar\nbaz

\n
\n", "example": 232, - "start_line": 3764, - "end_line": 3774, + "start_line": 3760, + "end_line": 3770, "section": "Block quotes" }, { "markdown": "> bar\nbaz\n> foo\n", "html": "
\n

bar\nbaz\nfoo

\n
\n", "example": 233, - "start_line": 3780, - "end_line": 3790, + "start_line": 3776, + "end_line": 3786, "section": "Block quotes" }, { "markdown": "> foo\n---\n", "html": "
\n

foo

\n
\n
\n", "example": 234, - "start_line": 3804, - "end_line": 3812, + "start_line": 3800, + "end_line": 3808, "section": "Block quotes" }, { "markdown": "> - foo\n- bar\n", "html": "
\n
    \n
  • foo
  • \n
\n
\n
    \n
  • bar
  • \n
\n", "example": 235, - "start_line": 3824, - "end_line": 3836, + "start_line": 3820, + "end_line": 3832, "section": "Block quotes" }, { "markdown": "> foo\n bar\n", "html": "
\n
foo\n
\n
\n
bar\n
\n", "example": 236, - "start_line": 3842, - "end_line": 3852, + "start_line": 3838, + "end_line": 3848, "section": "Block quotes" }, { "markdown": "> ```\nfoo\n```\n", "html": "
\n
\n
\n

foo

\n
\n", "example": 237, - "start_line": 3855, - "end_line": 3865, + "start_line": 3851, + "end_line": 3861, "section": "Block quotes" }, { "markdown": "> foo\n - bar\n", "html": "
\n

foo\n- bar

\n
\n", "example": 238, - "start_line": 3871, - "end_line": 3879, + "start_line": 3867, + "end_line": 3875, "section": "Block quotes" }, { "markdown": ">\n", "html": "
\n
\n", "example": 239, - "start_line": 3895, - "end_line": 3900, + "start_line": 3891, + "end_line": 3896, "section": "Block quotes" }, { "markdown": ">\n> \n> \n", "html": "
\n
\n", "example": 240, - "start_line": 3903, - "end_line": 3910, + "start_line": 3899, + "end_line": 3906, "section": "Block quotes" }, { "markdown": ">\n> foo\n> \n", "html": "
\n

foo

\n
\n", "example": 241, - "start_line": 3915, - "end_line": 3923, + "start_line": 3911, + "end_line": 3919, "section": "Block quotes" }, { "markdown": "> foo\n\n> bar\n", "html": "
\n

foo

\n
\n
\n

bar

\n
\n", "example": 242, - "start_line": 3928, - "end_line": 3939, + "start_line": 3924, + "end_line": 3935, "section": "Block quotes" }, { "markdown": "> foo\n> bar\n", "html": "
\n

foo\nbar

\n
\n", "example": 243, - "start_line": 3950, - "end_line": 3958, + "start_line": 3946, + "end_line": 3954, "section": "Block quotes" }, { "markdown": "> foo\n>\n> bar\n", "html": "
\n

foo

\n

bar

\n
\n", "example": 244, - "start_line": 3963, - "end_line": 3972, + "start_line": 3959, + "end_line": 3968, "section": "Block quotes" }, { "markdown": "foo\n> bar\n", "html": "

foo

\n
\n

bar

\n
\n", "example": 245, - "start_line": 3977, - "end_line": 3985, + "start_line": 3973, + "end_line": 3981, "section": "Block quotes" }, { "markdown": "> aaa\n***\n> bbb\n", "html": "
\n

aaa

\n
\n
\n
\n

bbb

\n
\n", "example": 246, - "start_line": 3991, - "end_line": 4003, + "start_line": 3987, + "end_line": 3999, "section": "Block quotes" }, { "markdown": "> bar\nbaz\n", "html": "
\n

bar\nbaz

\n
\n", "example": 247, - "start_line": 4009, - "end_line": 4017, + "start_line": 4005, + "end_line": 4013, "section": "Block quotes" }, { "markdown": "> bar\n\nbaz\n", "html": "
\n

bar

\n
\n

baz

\n", "example": 248, - "start_line": 4020, - "end_line": 4029, + "start_line": 4016, + "end_line": 4025, "section": "Block quotes" }, { "markdown": "> bar\n>\nbaz\n", "html": "
\n

bar

\n
\n

baz

\n", "example": 249, - "start_line": 4032, - "end_line": 4041, + "start_line": 4028, + "end_line": 4037, "section": "Block quotes" }, { "markdown": "> > > foo\nbar\n", "html": "
\n
\n
\n

foo\nbar

\n
\n
\n
\n", "example": 250, - "start_line": 4048, - "end_line": 4060, + "start_line": 4044, + "end_line": 4056, "section": "Block quotes" }, { "markdown": ">>> foo\n> bar\n>>baz\n", "html": "
\n
\n
\n

foo\nbar\nbaz

\n
\n
\n
\n", "example": 251, - "start_line": 4063, - "end_line": 4077, + "start_line": 4059, + "end_line": 4073, "section": "Block quotes" }, { "markdown": "> code\n\n> not code\n", "html": "
\n
code\n
\n
\n
\n

not code

\n
\n", "example": 252, - "start_line": 4085, - "end_line": 4097, + "start_line": 4081, + "end_line": 4093, "section": "Block quotes" }, { "markdown": "A paragraph\nwith two lines.\n\n indented code\n\n> A block quote.\n", "html": "

A paragraph\nwith two lines.

\n
indented code\n
\n
\n

A block quote.

\n
\n", "example": 253, - "start_line": 4139, - "end_line": 4154, + "start_line": 4135, + "end_line": 4150, "section": "List items" }, { "markdown": "1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "
    \n
  1. \n

    A paragraph\nwith two lines.

    \n
    indented code\n
    \n
    \n

    A block quote.

    \n
    \n
  2. \n
\n", "example": 254, - "start_line": 4161, - "end_line": 4180, + "start_line": 4157, + "end_line": 4176, "section": "List items" }, { "markdown": "- one\n\n two\n", "html": "
    \n
  • one
  • \n
\n

two

\n", "example": 255, - "start_line": 4194, - "end_line": 4203, + "start_line": 4190, + "end_line": 4199, "section": "List items" }, { "markdown": "- one\n\n two\n", "html": "
    \n
  • \n

    one

    \n

    two

    \n
  • \n
\n", "example": 256, - "start_line": 4206, - "end_line": 4217, + "start_line": 4202, + "end_line": 4213, "section": "List items" }, { "markdown": " - one\n\n two\n", "html": "
    \n
  • one
  • \n
\n
 two\n
\n", "example": 257, - "start_line": 4220, - "end_line": 4230, + "start_line": 4216, + "end_line": 4226, "section": "List items" }, { "markdown": " - one\n\n two\n", "html": "
    \n
  • \n

    one

    \n

    two

    \n
  • \n
\n", "example": 258, - "start_line": 4233, - "end_line": 4244, + "start_line": 4229, + "end_line": 4240, "section": "List items" }, { "markdown": " > > 1. one\n>>\n>> two\n", "html": "
\n
\n
    \n
  1. \n

    one

    \n

    two

    \n
  2. \n
\n
\n
\n", "example": 259, - "start_line": 4255, - "end_line": 4270, + "start_line": 4251, + "end_line": 4266, "section": "List items" }, { "markdown": ">>- one\n>>\n > > two\n", "html": "
\n
\n
    \n
  • one
  • \n
\n

two

\n
\n
\n", "example": 260, - "start_line": 4282, - "end_line": 4295, + "start_line": 4278, + "end_line": 4291, "section": "List items" }, { "markdown": "-one\n\n2.two\n", "html": "

-one

\n

2.two

\n", "example": 261, - "start_line": 4301, - "end_line": 4308, + "start_line": 4297, + "end_line": 4304, "section": "List items" }, { "markdown": "- foo\n\n\n bar\n", "html": "
    \n
  • \n

    foo

    \n

    bar

    \n
  • \n
\n", "example": 262, - "start_line": 4314, - "end_line": 4326, + "start_line": 4310, + "end_line": 4322, "section": "List items" }, { "markdown": "1. foo\n\n ```\n bar\n ```\n\n baz\n\n > bam\n", "html": "
    \n
  1. \n

    foo

    \n
    bar\n
    \n

    baz

    \n
    \n

    bam

    \n
    \n
  2. \n
\n", "example": 263, - "start_line": 4331, - "end_line": 4353, + "start_line": 4327, + "end_line": 4349, "section": "List items" }, { "markdown": "- Foo\n\n bar\n\n\n baz\n", "html": "
    \n
  • \n

    Foo

    \n
    bar\n\n\nbaz\n
    \n
  • \n
\n", "example": 264, - "start_line": 4359, - "end_line": 4377, + "start_line": 4355, + "end_line": 4373, "section": "List items" }, { "markdown": "123456789. ok\n", "html": "
    \n
  1. ok
  2. \n
\n", "example": 265, - "start_line": 4381, - "end_line": 4387, + "start_line": 4377, + "end_line": 4383, "section": "List items" }, { "markdown": "1234567890. not ok\n", "html": "

1234567890. not ok

\n", "example": 266, - "start_line": 4390, - "end_line": 4394, + "start_line": 4386, + "end_line": 4390, "section": "List items" }, { "markdown": "0. ok\n", "html": "
    \n
  1. ok
  2. \n
\n", "example": 267, - "start_line": 4399, - "end_line": 4405, + "start_line": 4395, + "end_line": 4401, "section": "List items" }, { "markdown": "003. ok\n", "html": "
    \n
  1. ok
  2. \n
\n", "example": 268, - "start_line": 4408, - "end_line": 4414, + "start_line": 4404, + "end_line": 4410, "section": "List items" }, { "markdown": "-1. not ok\n", "html": "

-1. not ok

\n", "example": 269, - "start_line": 4419, - "end_line": 4423, + "start_line": 4415, + "end_line": 4419, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "
    \n
  • \n

    foo

    \n
    bar\n
    \n
  • \n
\n", "example": 270, - "start_line": 4442, - "end_line": 4454, + "start_line": 4438, + "end_line": 4450, "section": "List items" }, { "markdown": " 10. foo\n\n bar\n", "html": "
    \n
  1. \n

    foo

    \n
    bar\n
    \n
  2. \n
\n", "example": 271, - "start_line": 4459, - "end_line": 4471, + "start_line": 4455, + "end_line": 4467, "section": "List items" }, { "markdown": " indented code\n\nparagraph\n\n more code\n", "html": "
indented code\n
\n

paragraph

\n
more code\n
\n", "example": 272, - "start_line": 4478, - "end_line": 4490, + "start_line": 4474, + "end_line": 4486, "section": "List items" }, { "markdown": "1. indented code\n\n paragraph\n\n more code\n", "html": "
    \n
  1. \n
    indented code\n
    \n

    paragraph

    \n
    more code\n
    \n
  2. \n
\n", "example": 273, - "start_line": 4493, - "end_line": 4509, + "start_line": 4489, + "end_line": 4505, "section": "List items" }, { "markdown": "1. indented code\n\n paragraph\n\n more code\n", "html": "
    \n
  1. \n
     indented code\n
    \n

    paragraph

    \n
    more code\n
    \n
  2. \n
\n", "example": 274, - "start_line": 4515, - "end_line": 4531, + "start_line": 4511, + "end_line": 4527, "section": "List items" }, { "markdown": " foo\n\nbar\n", "html": "

foo

\n

bar

\n", "example": 275, - "start_line": 4542, - "end_line": 4549, + "start_line": 4538, + "end_line": 4545, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "
    \n
  • foo
  • \n
\n

bar

\n", "example": 276, - "start_line": 4552, - "end_line": 4561, + "start_line": 4548, + "end_line": 4557, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "
    \n
  • \n

    foo

    \n

    bar

    \n
  • \n
\n", "example": 277, - "start_line": 4569, - "end_line": 4580, + "start_line": 4565, + "end_line": 4576, "section": "List items" }, { "markdown": "-\n foo\n-\n ```\n bar\n ```\n-\n baz\n", "html": "
    \n
  • foo
  • \n
  • \n
    bar\n
    \n
  • \n
  • \n
    baz\n
    \n
  • \n
\n", "example": 278, - "start_line": 4596, - "end_line": 4617, + "start_line": 4592, + "end_line": 4613, "section": "List items" }, { "markdown": "- \n foo\n", "html": "
    \n
  • foo
  • \n
\n", "example": 279, - "start_line": 4622, - "end_line": 4629, + "start_line": 4618, + "end_line": 4625, "section": "List items" }, { "markdown": "-\n\n foo\n", "html": "
    \n
  • \n
\n

foo

\n", "example": 280, - "start_line": 4636, - "end_line": 4645, + "start_line": 4632, + "end_line": 4641, "section": "List items" }, { "markdown": "- foo\n-\n- bar\n", "html": "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
\n", "example": 281, - "start_line": 4650, - "end_line": 4660, + "start_line": 4646, + "end_line": 4656, "section": "List items" }, { "markdown": "- foo\n- \n- bar\n", "html": "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
\n", "example": 282, - "start_line": 4665, - "end_line": 4675, + "start_line": 4661, + "end_line": 4671, "section": "List items" }, { "markdown": "1. foo\n2.\n3. bar\n", "html": "
    \n
  1. foo
  2. \n
  3. \n
  4. bar
  5. \n
\n", "example": 283, - "start_line": 4680, - "end_line": 4690, + "start_line": 4676, + "end_line": 4686, "section": "List items" }, { "markdown": "*\n", "html": "
    \n
  • \n
\n", "example": 284, - "start_line": 4695, - "end_line": 4701, + "start_line": 4691, + "end_line": 4697, "section": "List items" }, { "markdown": "foo\n*\n\nfoo\n1.\n", "html": "

foo\n*

\n

foo\n1.

\n", "example": 285, - "start_line": 4705, - "end_line": 4716, + "start_line": 4701, + "end_line": 4712, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "
    \n
  1. \n

    A paragraph\nwith two lines.

    \n
    indented code\n
    \n
    \n

    A block quote.

    \n
    \n
  2. \n
\n", "example": 286, - "start_line": 4727, - "end_line": 4746, + "start_line": 4723, + "end_line": 4742, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "
    \n
  1. \n

    A paragraph\nwith two lines.

    \n
    indented code\n
    \n
    \n

    A block quote.

    \n
    \n
  2. \n
\n", "example": 287, - "start_line": 4751, - "end_line": 4770, + "start_line": 4747, + "end_line": 4766, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "
    \n
  1. \n

    A paragraph\nwith two lines.

    \n
    indented code\n
    \n
    \n

    A block quote.

    \n
    \n
  2. \n
\n", "example": 288, - "start_line": 4775, - "end_line": 4794, + "start_line": 4771, + "end_line": 4790, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "
1.  A paragraph\n    with two lines.\n\n        indented code\n\n    > A block quote.\n
\n", "example": 289, - "start_line": 4799, - "end_line": 4814, + "start_line": 4795, + "end_line": 4810, "section": "List items" }, { "markdown": " 1. A paragraph\nwith two lines.\n\n indented code\n\n > A block quote.\n", "html": "
    \n
  1. \n

    A paragraph\nwith two lines.

    \n
    indented code\n
    \n
    \n

    A block quote.

    \n
    \n
  2. \n
\n", "example": 290, - "start_line": 4829, - "end_line": 4848, + "start_line": 4825, + "end_line": 4844, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n", "html": "
    \n
  1. A paragraph\nwith two lines.
  2. \n
\n", "example": 291, - "start_line": 4853, - "end_line": 4861, + "start_line": 4849, + "end_line": 4857, "section": "List items" }, { "markdown": "> 1. > Blockquote\ncontinued here.\n", "html": "
\n
    \n
  1. \n
    \n

    Blockquote\ncontinued here.

    \n
    \n
  2. \n
\n
\n", "example": 292, - "start_line": 4866, - "end_line": 4880, + "start_line": 4862, + "end_line": 4876, "section": "List items" }, { "markdown": "> 1. > Blockquote\n> continued here.\n", "html": "
\n
    \n
  1. \n
    \n

    Blockquote\ncontinued here.

    \n
    \n
  2. \n
\n
\n", "example": 293, - "start_line": 4883, - "end_line": 4897, + "start_line": 4879, + "end_line": 4893, "section": "List items" }, { "markdown": "- foo\n - bar\n - baz\n - boo\n", "html": "
    \n
  • foo\n
      \n
    • bar\n
        \n
      • baz\n
          \n
        • boo
        • \n
        \n
      • \n
      \n
    • \n
    \n
  • \n
\n", "example": 294, - "start_line": 4911, - "end_line": 4932, + "start_line": 4907, + "end_line": 4928, "section": "List items" }, { "markdown": "- foo\n - bar\n - baz\n - boo\n", "html": "
    \n
  • foo
  • \n
  • bar
  • \n
  • baz
  • \n
  • boo
  • \n
\n", "example": 295, - "start_line": 4937, - "end_line": 4949, + "start_line": 4933, + "end_line": 4945, "section": "List items" }, { "markdown": "10) foo\n - bar\n", "html": "
    \n
  1. foo\n
      \n
    • bar
    • \n
    \n
  2. \n
\n", "example": 296, - "start_line": 4954, - "end_line": 4965, + "start_line": 4950, + "end_line": 4961, "section": "List items" }, { "markdown": "10) foo\n - bar\n", "html": "
    \n
  1. foo
  2. \n
\n
    \n
  • bar
  • \n
\n", "example": 297, - "start_line": 4970, - "end_line": 4980, + "start_line": 4966, + "end_line": 4976, "section": "List items" }, { "markdown": "- - foo\n", "html": "
    \n
  • \n
      \n
    • foo
    • \n
    \n
  • \n
\n", "example": 298, - "start_line": 4985, - "end_line": 4995, + "start_line": 4981, + "end_line": 4991, "section": "List items" }, { "markdown": "1. - 2. foo\n", "html": "
    \n
  1. \n
      \n
    • \n
        \n
      1. foo
      2. \n
      \n
    • \n
    \n
  2. \n
\n", "example": 299, - "start_line": 4998, - "end_line": 5012, + "start_line": 4994, + "end_line": 5008, "section": "List items" }, { "markdown": "- # Foo\n- Bar\n ---\n baz\n", "html": "
    \n
  • \n

    Foo

    \n
  • \n
  • \n

    Bar

    \nbaz
  • \n
\n", "example": 300, - "start_line": 5017, - "end_line": 5031, + "start_line": 5013, + "end_line": 5027, "section": "List items" }, { "markdown": "- foo\n- bar\n+ baz\n", "html": "
    \n
  • foo
  • \n
  • bar
  • \n
\n
    \n
  • baz
  • \n
\n", "example": 301, - "start_line": 5253, - "end_line": 5265, + "start_line": 5249, + "end_line": 5261, "section": "Lists" }, { "markdown": "1. foo\n2. bar\n3) baz\n", "html": "
    \n
  1. foo
  2. \n
  3. bar
  4. \n
\n
    \n
  1. baz
  2. \n
\n", "example": 302, - "start_line": 5268, - "end_line": 5280, + "start_line": 5264, + "end_line": 5276, "section": "Lists" }, { "markdown": "Foo\n- bar\n- baz\n", "html": "

Foo

\n
    \n
  • bar
  • \n
  • baz
  • \n
\n", "example": 303, - "start_line": 5287, - "end_line": 5297, + "start_line": 5283, + "end_line": 5293, "section": "Lists" }, { "markdown": "The number of windows in my house is\n14. The number of doors is 6.\n", "html": "

The number of windows in my house is\n14. The number of doors is 6.

\n", "example": 304, - "start_line": 5364, - "end_line": 5370, + "start_line": 5360, + "end_line": 5366, "section": "Lists" }, { "markdown": "The number of windows in my house is\n1. The number of doors is 6.\n", "html": "

The number of windows in my house is

\n
    \n
  1. The number of doors is 6.
  2. \n
\n", "example": 305, - "start_line": 5374, - "end_line": 5382, + "start_line": 5370, + "end_line": 5378, "section": "Lists" }, { "markdown": "- foo\n\n- bar\n\n\n- baz\n", "html": "
    \n
  • \n

    foo

    \n
  • \n
  • \n

    bar

    \n
  • \n
  • \n

    baz

    \n
  • \n
\n", "example": 306, - "start_line": 5388, - "end_line": 5407, + "start_line": 5384, + "end_line": 5403, "section": "Lists" }, { "markdown": "- foo\n - bar\n - baz\n\n\n bim\n", "html": "
    \n
  • foo\n
      \n
    • bar\n
        \n
      • \n

        baz

        \n

        bim

        \n
      • \n
      \n
    • \n
    \n
  • \n
\n", "example": 307, - "start_line": 5409, - "end_line": 5431, + "start_line": 5405, + "end_line": 5427, "section": "Lists" }, { "markdown": "- foo\n- bar\n\n\n\n- baz\n- bim\n", "html": "
    \n
  • foo
  • \n
  • bar
  • \n
\n\n
    \n
  • baz
  • \n
  • bim
  • \n
\n", "example": 308, - "start_line": 5439, - "end_line": 5457, + "start_line": 5435, + "end_line": 5453, "section": "Lists" }, { "markdown": "- foo\n\n notcode\n\n- foo\n\n\n\n code\n", "html": "
    \n
  • \n

    foo

    \n

    notcode

    \n
  • \n
  • \n

    foo

    \n
  • \n
\n\n
code\n
\n", "example": 309, - "start_line": 5460, - "end_line": 5483, + "start_line": 5456, + "end_line": 5479, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n - d\n - e\n - f\n- g\n", "html": "
    \n
  • a
  • \n
  • b
  • \n
  • c
  • \n
  • d
  • \n
  • e
  • \n
  • f
  • \n
  • g
  • \n
\n", "example": 310, - "start_line": 5491, - "end_line": 5509, + "start_line": 5487, + "end_line": 5505, "section": "Lists" }, { "markdown": "1. a\n\n 2. b\n\n 3. c\n", "html": "
    \n
  1. \n

    a

    \n
  2. \n
  3. \n

    b

    \n
  4. \n
  5. \n

    c

    \n
  6. \n
\n", "example": 311, - "start_line": 5512, - "end_line": 5530, + "start_line": 5508, + "end_line": 5526, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n - d\n - e\n", "html": "
    \n
  • a
  • \n
  • b
  • \n
  • c
  • \n
  • d\n- e
  • \n
\n", "example": 312, - "start_line": 5536, - "end_line": 5550, + "start_line": 5532, + "end_line": 5546, "section": "Lists" }, { "markdown": "1. a\n\n 2. b\n\n 3. c\n", "html": "
    \n
  1. \n

    a

    \n
  2. \n
  3. \n

    b

    \n
  4. \n
\n
3. c\n
\n", "example": 313, - "start_line": 5556, - "end_line": 5573, + "start_line": 5552, + "end_line": 5569, "section": "Lists" }, { "markdown": "- a\n- b\n\n- c\n", "html": "
    \n
  • \n

    a

    \n
  • \n
  • \n

    b

    \n
  • \n
  • \n

    c

    \n
  • \n
\n", "example": 314, - "start_line": 5579, - "end_line": 5596, + "start_line": 5575, + "end_line": 5592, "section": "Lists" }, { "markdown": "* a\n*\n\n* c\n", "html": "
    \n
  • \n

    a

    \n
  • \n
  • \n
  • \n

    c

    \n
  • \n
\n", "example": 315, - "start_line": 5601, - "end_line": 5616, + "start_line": 5597, + "end_line": 5612, "section": "Lists" }, { "markdown": "- a\n- b\n\n c\n- d\n", "html": "
    \n
  • \n

    a

    \n
  • \n
  • \n

    b

    \n

    c

    \n
  • \n
  • \n

    d

    \n
  • \n
\n", "example": 316, - "start_line": 5623, - "end_line": 5642, + "start_line": 5619, + "end_line": 5638, "section": "Lists" }, { "markdown": "- a\n- b\n\n [ref]: /url\n- d\n", "html": "
    \n
  • \n

    a

    \n
  • \n
  • \n

    b

    \n
  • \n
  • \n

    d

    \n
  • \n
\n", "example": 317, - "start_line": 5645, - "end_line": 5663, + "start_line": 5641, + "end_line": 5659, "section": "Lists" }, { "markdown": "- a\n- ```\n b\n\n\n ```\n- c\n", "html": "
    \n
  • a
  • \n
  • \n
    b\n\n\n
    \n
  • \n
  • c
  • \n
\n", "example": 318, - "start_line": 5668, - "end_line": 5687, + "start_line": 5664, + "end_line": 5683, "section": "Lists" }, { "markdown": "- a\n - b\n\n c\n- d\n", "html": "
    \n
  • a\n
      \n
    • \n

      b

      \n

      c

      \n
    • \n
    \n
  • \n
  • d
  • \n
\n", "example": 319, - "start_line": 5694, - "end_line": 5712, + "start_line": 5690, + "end_line": 5708, "section": "Lists" }, { "markdown": "* a\n > b\n >\n* c\n", "html": "
    \n
  • a\n
    \n

    b

    \n
    \n
  • \n
  • c
  • \n
\n", "example": 320, - "start_line": 5718, - "end_line": 5732, + "start_line": 5714, + "end_line": 5728, "section": "Lists" }, { "markdown": "- a\n > b\n ```\n c\n ```\n- d\n", "html": "
    \n
  • a\n
    \n

    b

    \n
    \n
    c\n
    \n
  • \n
  • d
  • \n
\n", "example": 321, - "start_line": 5738, - "end_line": 5756, + "start_line": 5734, + "end_line": 5752, "section": "Lists" }, { "markdown": "- a\n", "html": "
    \n
  • a
  • \n
\n", "example": 322, - "start_line": 5761, - "end_line": 5767, + "start_line": 5757, + "end_line": 5763, "section": "Lists" }, { "markdown": "- a\n - b\n", "html": "
    \n
  • a\n
      \n
    • b
    • \n
    \n
  • \n
\n", "example": 323, - "start_line": 5770, - "end_line": 5781, + "start_line": 5766, + "end_line": 5777, "section": "Lists" }, { "markdown": "1. ```\n foo\n ```\n\n bar\n", "html": "
    \n
  1. \n
    foo\n
    \n

    bar

    \n
  2. \n
\n", "example": 324, - "start_line": 5787, - "end_line": 5801, + "start_line": 5783, + "end_line": 5797, "section": "Lists" }, { "markdown": "* foo\n * bar\n\n baz\n", "html": "
    \n
  • \n

    foo

    \n
      \n
    • bar
    • \n
    \n

    baz

    \n
  • \n
\n", "example": 325, - "start_line": 5806, - "end_line": 5821, + "start_line": 5802, + "end_line": 5817, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n\n- d\n - e\n - f\n", "html": "
    \n
  • \n

    a

    \n
      \n
    • b
    • \n
    • c
    • \n
    \n
  • \n
  • \n

    d

    \n
      \n
    • e
    • \n
    • f
    • \n
    \n
  • \n
\n", "example": 326, - "start_line": 5824, - "end_line": 5849, + "start_line": 5820, + "end_line": 5845, "section": "Lists" }, { "markdown": "`hi`lo`\n", "html": "

hilo`

\n", "example": 327, - "start_line": 5858, - "end_line": 5862, + "start_line": 5854, + "end_line": 5858, "section": "Inlines" }, { "markdown": "`foo`\n", "html": "

foo

\n", "example": 328, - "start_line": 5890, - "end_line": 5894, + "start_line": 5886, + "end_line": 5890, "section": "Code spans" }, { "markdown": "`` foo ` bar ``\n", "html": "

foo ` bar

\n", "example": 329, - "start_line": 5901, - "end_line": 5905, + "start_line": 5897, + "end_line": 5901, "section": "Code spans" }, { "markdown": "` `` `\n", "html": "

``

\n", "example": 330, - "start_line": 5911, - "end_line": 5915, + "start_line": 5907, + "end_line": 5911, "section": "Code spans" }, { "markdown": "` `` `\n", "html": "

``

\n", "example": 331, - "start_line": 5919, - "end_line": 5923, + "start_line": 5915, + "end_line": 5919, "section": "Code spans" }, { "markdown": "` a`\n", "html": "

a

\n", "example": 332, - "start_line": 5928, - "end_line": 5932, + "start_line": 5924, + "end_line": 5928, "section": "Code spans" }, { "markdown": "` b `\n", "html": "

 b 

\n", "example": 333, - "start_line": 5937, - "end_line": 5941, + "start_line": 5933, + "end_line": 5937, "section": "Code spans" }, { "markdown": "` `\n` `\n", "html": "

 \n

\n", "example": 334, - "start_line": 5945, - "end_line": 5951, + "start_line": 5941, + "end_line": 5947, "section": "Code spans" }, { "markdown": "``\nfoo\nbar \nbaz\n``\n", "html": "

foo bar baz

\n", "example": 335, - "start_line": 5956, - "end_line": 5964, + "start_line": 5952, + "end_line": 5960, "section": "Code spans" }, { "markdown": "``\nfoo \n``\n", "html": "

foo

\n", "example": 336, - "start_line": 5966, - "end_line": 5972, + "start_line": 5962, + "end_line": 5968, "section": "Code spans" }, { "markdown": "`foo bar \nbaz`\n", "html": "

foo bar baz

\n", "example": 337, - "start_line": 5977, - "end_line": 5982, + "start_line": 5973, + "end_line": 5978, "section": "Code spans" }, { "markdown": "`foo\\`bar`\n", "html": "

foo\\bar`

\n", "example": 338, - "start_line": 5994, - "end_line": 5998, + "start_line": 5990, + "end_line": 5994, "section": "Code spans" }, { "markdown": "``foo`bar``\n", "html": "

foo`bar

\n", "example": 339, - "start_line": 6005, - "end_line": 6009, + "start_line": 6001, + "end_line": 6005, "section": "Code spans" }, { "markdown": "` foo `` bar `\n", "html": "

foo `` bar

\n", "example": 340, - "start_line": 6011, - "end_line": 6015, + "start_line": 6007, + "end_line": 6011, "section": "Code spans" }, { "markdown": "*foo`*`\n", "html": "

*foo*

\n", "example": 341, - "start_line": 6023, - "end_line": 6027, + "start_line": 6019, + "end_line": 6023, "section": "Code spans" }, { "markdown": "[not a `link](/foo`)\n", "html": "

[not a link](/foo)

\n", "example": 342, - "start_line": 6032, - "end_line": 6036, + "start_line": 6028, + "end_line": 6032, "section": "Code spans" }, { "markdown": "``\n", "html": "

<a href="">`

\n", "example": 343, - "start_line": 6042, - "end_line": 6046, + "start_line": 6038, + "end_line": 6042, "section": "Code spans" }, { "markdown": "
`\n", "html": "

`

\n", "example": 344, - "start_line": 6051, - "end_line": 6055, + "start_line": 6047, + "end_line": 6051, "section": "Code spans" }, { - "markdown": "``\n", - "html": "

<http://foo.bar.baz>`

\n", + "markdown": "``\n", + "html": "

<https://foo.bar.baz>`

\n", "example": 345, - "start_line": 6060, - "end_line": 6064, + "start_line": 6056, + "end_line": 6060, "section": "Code spans" }, { - "markdown": "`\n", - "html": "

http://foo.bar.`baz`

\n", + "markdown": "`\n", + "html": "

https://foo.bar.`baz`

\n", "example": 346, - "start_line": 6069, - "end_line": 6073, + "start_line": 6065, + "end_line": 6069, "section": "Code spans" }, { "markdown": "```foo``\n", "html": "

```foo``

\n", "example": 347, - "start_line": 6079, - "end_line": 6083, + "start_line": 6075, + "end_line": 6079, "section": "Code spans" }, { "markdown": "`foo\n", "html": "

`foo

\n", "example": 348, - "start_line": 6086, - "end_line": 6090, + "start_line": 6082, + "end_line": 6086, "section": "Code spans" }, { "markdown": "`foo``bar``\n", "html": "

`foobar

\n", "example": 349, - "start_line": 6095, - "end_line": 6099, + "start_line": 6091, + "end_line": 6095, "section": "Code spans" }, { "markdown": "*foo bar*\n", "html": "

foo bar

\n", "example": 350, - "start_line": 6312, - "end_line": 6316, + "start_line": 6308, + "end_line": 6312, "section": "Emphasis and strong emphasis" }, { "markdown": "a * foo bar*\n", "html": "

a * foo bar*

\n", "example": 351, - "start_line": 6322, - "end_line": 6326, + "start_line": 6318, + "end_line": 6322, "section": "Emphasis and strong emphasis" }, { "markdown": "a*\"foo\"*\n", "html": "

a*"foo"*

\n", "example": 352, - "start_line": 6333, - "end_line": 6337, + "start_line": 6329, + "end_line": 6333, "section": "Emphasis and strong emphasis" }, { "markdown": "* a *\n", "html": "

* a *

\n", "example": 353, - "start_line": 6342, - "end_line": 6346, + "start_line": 6338, + "end_line": 6342, + "section": "Emphasis and strong emphasis" + }, + { + "markdown": "*$*alpha.\n\n*£*bravo.\n\n*€*charlie.\n", + "html": "

*$*alpha.

\n

*£*bravo.

\n

*€*charlie.

\n", + "example": 354, + "start_line": 6347, + "end_line": 6357, "section": "Emphasis and strong emphasis" }, { "markdown": "foo*bar*\n", "html": "

foobar

\n", - "example": 354, - "start_line": 6351, - "end_line": 6355, + "example": 355, + "start_line": 6362, + "end_line": 6366, "section": "Emphasis and strong emphasis" }, { "markdown": "5*6*78\n", "html": "

5678

\n", - "example": 355, - "start_line": 6358, - "end_line": 6362, + "example": 356, + "start_line": 6369, + "end_line": 6373, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo bar_\n", "html": "

foo bar

\n", - "example": 356, - "start_line": 6367, - "end_line": 6371, + "example": 357, + "start_line": 6378, + "end_line": 6382, "section": "Emphasis and strong emphasis" }, { "markdown": "_ foo bar_\n", "html": "

_ foo bar_

\n", - "example": 357, - "start_line": 6377, - "end_line": 6381, + "example": 358, + "start_line": 6388, + "end_line": 6392, "section": "Emphasis and strong emphasis" }, { "markdown": "a_\"foo\"_\n", "html": "

a_"foo"_

\n", - "example": 358, - "start_line": 6387, - "end_line": 6391, + "example": 359, + "start_line": 6398, + "end_line": 6402, "section": "Emphasis and strong emphasis" }, { "markdown": "foo_bar_\n", "html": "

foo_bar_

\n", - "example": 359, - "start_line": 6396, - "end_line": 6400, + "example": 360, + "start_line": 6407, + "end_line": 6411, "section": "Emphasis and strong emphasis" }, { "markdown": "5_6_78\n", "html": "

5_6_78

\n", - "example": 360, - "start_line": 6403, - "end_line": 6407, + "example": 361, + "start_line": 6414, + "end_line": 6418, "section": "Emphasis and strong emphasis" }, { "markdown": "пристаням_стремятся_\n", "html": "

пристаням_стремятся_

\n", - "example": 361, - "start_line": 6410, - "end_line": 6414, + "example": 362, + "start_line": 6421, + "end_line": 6425, "section": "Emphasis and strong emphasis" }, { "markdown": "aa_\"bb\"_cc\n", "html": "

aa_"bb"_cc

\n", - "example": 362, - "start_line": 6420, - "end_line": 6424, + "example": 363, + "start_line": 6431, + "end_line": 6435, "section": "Emphasis and strong emphasis" }, { "markdown": "foo-_(bar)_\n", "html": "

foo-(bar)

\n", - "example": 363, - "start_line": 6431, - "end_line": 6435, + "example": 364, + "start_line": 6442, + "end_line": 6446, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo*\n", "html": "

_foo*

\n", - "example": 364, - "start_line": 6443, - "end_line": 6447, + "example": 365, + "start_line": 6454, + "end_line": 6458, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo bar *\n", "html": "

*foo bar *

\n", - "example": 365, - "start_line": 6453, - "end_line": 6457, + "example": 366, + "start_line": 6464, + "end_line": 6468, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo bar\n*\n", "html": "

*foo bar\n*

\n", - "example": 366, - "start_line": 6462, - "end_line": 6468, + "example": 367, + "start_line": 6473, + "end_line": 6479, "section": "Emphasis and strong emphasis" }, { "markdown": "*(*foo)\n", "html": "

*(*foo)

\n", - "example": 367, - "start_line": 6475, - "end_line": 6479, + "example": 368, + "start_line": 6486, + "end_line": 6490, "section": "Emphasis and strong emphasis" }, { "markdown": "*(*foo*)*\n", "html": "

(foo)

\n", - "example": 368, - "start_line": 6485, - "end_line": 6489, + "example": 369, + "start_line": 6496, + "end_line": 6500, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo*bar\n", "html": "

foobar

\n", - "example": 369, - "start_line": 6494, - "end_line": 6498, + "example": 370, + "start_line": 6505, + "end_line": 6509, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo bar _\n", "html": "

_foo bar _

\n", - "example": 370, - "start_line": 6507, - "end_line": 6511, + "example": 371, + "start_line": 6518, + "end_line": 6522, "section": "Emphasis and strong emphasis" }, { "markdown": "_(_foo)\n", "html": "

_(_foo)

\n", - "example": 371, - "start_line": 6517, - "end_line": 6521, + "example": 372, + "start_line": 6528, + "end_line": 6532, "section": "Emphasis and strong emphasis" }, { "markdown": "_(_foo_)_\n", "html": "

(foo)

\n", - "example": 372, - "start_line": 6526, - "end_line": 6530, + "example": 373, + "start_line": 6537, + "end_line": 6541, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo_bar\n", "html": "

_foo_bar

\n", - "example": 373, - "start_line": 6535, - "end_line": 6539, + "example": 374, + "start_line": 6546, + "end_line": 6550, "section": "Emphasis and strong emphasis" }, { "markdown": "_пристаням_стремятся\n", "html": "

_пристаням_стремятся

\n", - "example": 374, - "start_line": 6542, - "end_line": 6546, + "example": 375, + "start_line": 6553, + "end_line": 6557, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo_bar_baz_\n", "html": "

foo_bar_baz

\n", - "example": 375, - "start_line": 6549, - "end_line": 6553, + "example": 376, + "start_line": 6560, + "end_line": 6564, "section": "Emphasis and strong emphasis" }, { "markdown": "_(bar)_.\n", "html": "

(bar).

\n", - "example": 376, - "start_line": 6560, - "end_line": 6564, + "example": 377, + "start_line": 6571, + "end_line": 6575, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo bar**\n", "html": "

foo bar

\n", - "example": 377, - "start_line": 6569, - "end_line": 6573, + "example": 378, + "start_line": 6580, + "end_line": 6584, "section": "Emphasis and strong emphasis" }, { "markdown": "** foo bar**\n", "html": "

** foo bar**

\n", - "example": 378, - "start_line": 6579, - "end_line": 6583, + "example": 379, + "start_line": 6590, + "end_line": 6594, "section": "Emphasis and strong emphasis" }, { "markdown": "a**\"foo\"**\n", "html": "

a**"foo"**

\n", - "example": 379, - "start_line": 6590, - "end_line": 6594, + "example": 380, + "start_line": 6601, + "end_line": 6605, "section": "Emphasis and strong emphasis" }, { "markdown": "foo**bar**\n", "html": "

foobar

\n", - "example": 380, - "start_line": 6599, - "end_line": 6603, + "example": 381, + "start_line": 6610, + "end_line": 6614, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo bar__\n", "html": "

foo bar

\n", - "example": 381, - "start_line": 6608, - "end_line": 6612, + "example": 382, + "start_line": 6619, + "end_line": 6623, "section": "Emphasis and strong emphasis" }, { "markdown": "__ foo bar__\n", "html": "

__ foo bar__

\n", - "example": 382, - "start_line": 6618, - "end_line": 6622, + "example": 383, + "start_line": 6629, + "end_line": 6633, "section": "Emphasis and strong emphasis" }, { "markdown": "__\nfoo bar__\n", "html": "

__\nfoo bar__

\n", - "example": 383, - "start_line": 6626, - "end_line": 6632, + "example": 384, + "start_line": 6637, + "end_line": 6643, "section": "Emphasis and strong emphasis" }, { "markdown": "a__\"foo\"__\n", "html": "

a__"foo"__

\n", - "example": 384, - "start_line": 6638, - "end_line": 6642, + "example": 385, + "start_line": 6649, + "end_line": 6653, "section": "Emphasis and strong emphasis" }, { "markdown": "foo__bar__\n", "html": "

foo__bar__

\n", - "example": 385, - "start_line": 6647, - "end_line": 6651, + "example": 386, + "start_line": 6658, + "end_line": 6662, "section": "Emphasis and strong emphasis" }, { "markdown": "5__6__78\n", "html": "

5__6__78

\n", - "example": 386, - "start_line": 6654, - "end_line": 6658, + "example": 387, + "start_line": 6665, + "end_line": 6669, "section": "Emphasis and strong emphasis" }, { "markdown": "пристаням__стремятся__\n", "html": "

пристаням__стремятся__

\n", - "example": 387, - "start_line": 6661, - "end_line": 6665, + "example": 388, + "start_line": 6672, + "end_line": 6676, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo, __bar__, baz__\n", "html": "

foo, bar, baz

\n", - "example": 388, - "start_line": 6668, - "end_line": 6672, + "example": 389, + "start_line": 6679, + "end_line": 6683, "section": "Emphasis and strong emphasis" }, { "markdown": "foo-__(bar)__\n", "html": "

foo-(bar)

\n", - "example": 389, - "start_line": 6679, - "end_line": 6683, + "example": 390, + "start_line": 6690, + "end_line": 6694, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo bar **\n", "html": "

**foo bar **

\n", - "example": 390, - "start_line": 6692, - "end_line": 6696, + "example": 391, + "start_line": 6703, + "end_line": 6707, "section": "Emphasis and strong emphasis" }, { "markdown": "**(**foo)\n", "html": "

**(**foo)

\n", - "example": 391, - "start_line": 6705, - "end_line": 6709, + "example": 392, + "start_line": 6716, + "end_line": 6720, "section": "Emphasis and strong emphasis" }, { "markdown": "*(**foo**)*\n", "html": "

(foo)

\n", - "example": 392, - "start_line": 6715, - "end_line": 6719, + "example": 393, + "start_line": 6726, + "end_line": 6730, "section": "Emphasis and strong emphasis" }, { "markdown": "**Gomphocarpus (*Gomphocarpus physocarpus*, syn.\n*Asclepias physocarpa*)**\n", "html": "

Gomphocarpus (Gomphocarpus physocarpus, syn.\nAsclepias physocarpa)

\n", - "example": 393, - "start_line": 6722, - "end_line": 6728, + "example": 394, + "start_line": 6733, + "end_line": 6739, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo \"*bar*\" foo**\n", "html": "

foo "bar" foo

\n", - "example": 394, - "start_line": 6731, - "end_line": 6735, + "example": 395, + "start_line": 6742, + "end_line": 6746, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo**bar\n", "html": "

foobar

\n", - "example": 395, - "start_line": 6740, - "end_line": 6744, + "example": 396, + "start_line": 6751, + "end_line": 6755, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo bar __\n", "html": "

__foo bar __

\n", - "example": 396, - "start_line": 6752, - "end_line": 6756, + "example": 397, + "start_line": 6763, + "end_line": 6767, "section": "Emphasis and strong emphasis" }, { "markdown": "__(__foo)\n", "html": "

__(__foo)

\n", - "example": 397, - "start_line": 6762, - "end_line": 6766, + "example": 398, + "start_line": 6773, + "end_line": 6777, "section": "Emphasis and strong emphasis" }, { "markdown": "_(__foo__)_\n", "html": "

(foo)

\n", - "example": 398, - "start_line": 6772, - "end_line": 6776, + "example": 399, + "start_line": 6783, + "end_line": 6787, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__bar\n", "html": "

__foo__bar

\n", - "example": 399, - "start_line": 6781, - "end_line": 6785, + "example": 400, + "start_line": 6792, + "end_line": 6796, "section": "Emphasis and strong emphasis" }, { "markdown": "__пристаням__стремятся\n", "html": "

__пристаням__стремятся

\n", - "example": 400, - "start_line": 6788, - "end_line": 6792, + "example": 401, + "start_line": 6799, + "end_line": 6803, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__bar__baz__\n", "html": "

foo__bar__baz

\n", - "example": 401, - "start_line": 6795, - "end_line": 6799, + "example": 402, + "start_line": 6806, + "end_line": 6810, "section": "Emphasis and strong emphasis" }, { "markdown": "__(bar)__.\n", "html": "

(bar).

\n", - "example": 402, - "start_line": 6806, - "end_line": 6810, + "example": 403, + "start_line": 6817, + "end_line": 6821, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo [bar](/url)*\n", "html": "

foo bar

\n", - "example": 403, - "start_line": 6818, - "end_line": 6822, + "example": 404, + "start_line": 6829, + "end_line": 6833, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo\nbar*\n", "html": "

foo\nbar

\n", - "example": 404, - "start_line": 6825, - "end_line": 6831, + "example": 405, + "start_line": 6836, + "end_line": 6842, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo __bar__ baz_\n", "html": "

foo bar baz

\n", - "example": 405, - "start_line": 6837, - "end_line": 6841, + "example": 406, + "start_line": 6848, + "end_line": 6852, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo _bar_ baz_\n", "html": "

foo bar baz

\n", - "example": 406, - "start_line": 6844, - "end_line": 6848, + "example": 407, + "start_line": 6855, + "end_line": 6859, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo_ bar_\n", "html": "

foo bar

\n", - "example": 407, - "start_line": 6851, - "end_line": 6855, + "example": 408, + "start_line": 6862, + "end_line": 6866, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo *bar**\n", "html": "

foo bar

\n", - "example": 408, - "start_line": 6858, - "end_line": 6862, + "example": 409, + "start_line": 6869, + "end_line": 6873, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar** baz*\n", "html": "

foo bar baz

\n", - "example": 409, - "start_line": 6865, - "end_line": 6869, + "example": 410, + "start_line": 6876, + "end_line": 6880, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar**baz*\n", "html": "

foobarbaz

\n", - "example": 410, - "start_line": 6871, - "end_line": 6875, + "example": 411, + "start_line": 6882, + "end_line": 6886, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar*\n", "html": "

foo**bar

\n", - "example": 411, - "start_line": 6895, - "end_line": 6899, + "example": 412, + "start_line": 6906, + "end_line": 6910, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo** bar*\n", "html": "

foo bar

\n", - "example": 412, - "start_line": 6908, - "end_line": 6912, + "example": 413, + "start_line": 6919, + "end_line": 6923, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar***\n", "html": "

foo bar

\n", - "example": 413, - "start_line": 6915, - "end_line": 6919, + "example": 414, + "start_line": 6926, + "end_line": 6930, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar***\n", "html": "

foobar

\n", - "example": 414, - "start_line": 6922, - "end_line": 6926, + "example": 415, + "start_line": 6933, + "end_line": 6937, "section": "Emphasis and strong emphasis" }, { "markdown": "foo***bar***baz\n", "html": "

foobarbaz

\n", - "example": 415, - "start_line": 6933, - "end_line": 6937, + "example": 416, + "start_line": 6944, + "end_line": 6948, "section": "Emphasis and strong emphasis" }, { "markdown": "foo******bar*********baz\n", "html": "

foobar***baz

\n", - "example": 416, - "start_line": 6939, - "end_line": 6943, + "example": 417, + "start_line": 6950, + "end_line": 6954, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar *baz* bim** bop*\n", "html": "

foo bar baz bim bop

\n", - "example": 417, - "start_line": 6948, - "end_line": 6952, + "example": 418, + "start_line": 6959, + "end_line": 6963, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo [*bar*](/url)*\n", "html": "

foo bar

\n", - "example": 418, - "start_line": 6955, - "end_line": 6959, + "example": 419, + "start_line": 6966, + "end_line": 6970, "section": "Emphasis and strong emphasis" }, { "markdown": "** is not an empty emphasis\n", "html": "

** is not an empty emphasis

\n", - "example": 419, - "start_line": 6964, - "end_line": 6968, + "example": 420, + "start_line": 6975, + "end_line": 6979, "section": "Emphasis and strong emphasis" }, { "markdown": "**** is not an empty strong emphasis\n", "html": "

**** is not an empty strong emphasis

\n", - "example": 420, - "start_line": 6971, - "end_line": 6975, + "example": 421, + "start_line": 6982, + "end_line": 6986, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo [bar](/url)**\n", "html": "

foo bar

\n", - "example": 421, - "start_line": 6984, - "end_line": 6988, + "example": 422, + "start_line": 6995, + "end_line": 6999, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo\nbar**\n", "html": "

foo\nbar

\n", - "example": 422, - "start_line": 6991, - "end_line": 6997, + "example": 423, + "start_line": 7002, + "end_line": 7008, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo _bar_ baz__\n", "html": "

foo bar baz

\n", - "example": 423, - "start_line": 7003, - "end_line": 7007, + "example": 424, + "start_line": 7014, + "end_line": 7018, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo __bar__ baz__\n", "html": "

foo bar baz

\n", - "example": 424, - "start_line": 7010, - "end_line": 7014, + "example": 425, + "start_line": 7021, + "end_line": 7025, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo__ bar__\n", "html": "

foo bar

\n", - "example": 425, - "start_line": 7017, - "end_line": 7021, + "example": 426, + "start_line": 7028, + "end_line": 7032, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo **bar****\n", "html": "

foo bar

\n", - "example": 426, - "start_line": 7024, - "end_line": 7028, + "example": 427, + "start_line": 7035, + "end_line": 7039, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar* baz**\n", "html": "

foo bar baz

\n", - "example": 427, - "start_line": 7031, - "end_line": 7035, + "example": 428, + "start_line": 7042, + "end_line": 7046, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo*bar*baz**\n", "html": "

foobarbaz

\n", - "example": 428, - "start_line": 7038, - "end_line": 7042, + "example": 429, + "start_line": 7049, + "end_line": 7053, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo* bar**\n", "html": "

foo bar

\n", - "example": 429, - "start_line": 7045, - "end_line": 7049, + "example": 430, + "start_line": 7056, + "end_line": 7060, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar***\n", "html": "

foo bar

\n", - "example": 430, - "start_line": 7052, - "end_line": 7056, + "example": 431, + "start_line": 7063, + "end_line": 7067, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar **baz**\nbim* bop**\n", "html": "

foo bar baz\nbim bop

\n", - "example": 431, - "start_line": 7061, - "end_line": 7067, + "example": 432, + "start_line": 7072, + "end_line": 7078, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo [*bar*](/url)**\n", "html": "

foo bar

\n", - "example": 432, - "start_line": 7070, - "end_line": 7074, + "example": 433, + "start_line": 7081, + "end_line": 7085, "section": "Emphasis and strong emphasis" }, { "markdown": "__ is not an empty emphasis\n", "html": "

__ is not an empty emphasis

\n", - "example": 433, - "start_line": 7079, - "end_line": 7083, + "example": 434, + "start_line": 7090, + "end_line": 7094, "section": "Emphasis and strong emphasis" }, { "markdown": "____ is not an empty strong emphasis\n", "html": "

____ is not an empty strong emphasis

\n", - "example": 434, - "start_line": 7086, - "end_line": 7090, + "example": 435, + "start_line": 7097, + "end_line": 7101, "section": "Emphasis and strong emphasis" }, { "markdown": "foo ***\n", "html": "

foo ***

\n", - "example": 435, - "start_line": 7096, - "end_line": 7100, + "example": 436, + "start_line": 7107, + "end_line": 7111, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *\\**\n", "html": "

foo *

\n", - "example": 436, - "start_line": 7103, - "end_line": 7107, + "example": 437, + "start_line": 7114, + "end_line": 7118, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *_*\n", "html": "

foo _

\n", - "example": 437, - "start_line": 7110, - "end_line": 7114, + "example": 438, + "start_line": 7121, + "end_line": 7125, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *****\n", "html": "

foo *****

\n", - "example": 438, - "start_line": 7117, - "end_line": 7121, + "example": 439, + "start_line": 7128, + "end_line": 7132, "section": "Emphasis and strong emphasis" }, { "markdown": "foo **\\***\n", "html": "

foo *

\n", - "example": 439, - "start_line": 7124, - "end_line": 7128, + "example": 440, + "start_line": 7135, + "end_line": 7139, "section": "Emphasis and strong emphasis" }, { "markdown": "foo **_**\n", "html": "

foo _

\n", - "example": 440, - "start_line": 7131, - "end_line": 7135, + "example": 441, + "start_line": 7142, + "end_line": 7146, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo*\n", "html": "

*foo

\n", - "example": 441, - "start_line": 7142, - "end_line": 7146, + "example": 442, + "start_line": 7153, + "end_line": 7157, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**\n", "html": "

foo*

\n", - "example": 442, - "start_line": 7149, - "end_line": 7153, + "example": 443, + "start_line": 7160, + "end_line": 7164, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo**\n", "html": "

*foo

\n", - "example": 443, - "start_line": 7156, - "end_line": 7160, + "example": 444, + "start_line": 7167, + "end_line": 7171, "section": "Emphasis and strong emphasis" }, { "markdown": "****foo*\n", "html": "

***foo

\n", - "example": 444, - "start_line": 7163, - "end_line": 7167, + "example": 445, + "start_line": 7174, + "end_line": 7178, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo***\n", "html": "

foo*

\n", - "example": 445, - "start_line": 7170, - "end_line": 7174, + "example": 446, + "start_line": 7181, + "end_line": 7185, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo****\n", "html": "

foo***

\n", - "example": 446, - "start_line": 7177, - "end_line": 7181, + "example": 447, + "start_line": 7188, + "end_line": 7192, "section": "Emphasis and strong emphasis" }, { "markdown": "foo ___\n", "html": "

foo ___

\n", - "example": 447, - "start_line": 7187, - "end_line": 7191, + "example": 448, + "start_line": 7198, + "end_line": 7202, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _\\__\n", "html": "

foo _

\n", - "example": 448, - "start_line": 7194, - "end_line": 7198, + "example": 449, + "start_line": 7205, + "end_line": 7209, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _*_\n", "html": "

foo *

\n", - "example": 449, - "start_line": 7201, - "end_line": 7205, + "example": 450, + "start_line": 7212, + "end_line": 7216, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _____\n", "html": "

foo _____

\n", - "example": 450, - "start_line": 7208, - "end_line": 7212, + "example": 451, + "start_line": 7219, + "end_line": 7223, "section": "Emphasis and strong emphasis" }, { "markdown": "foo __\\___\n", "html": "

foo _

\n", - "example": 451, - "start_line": 7215, - "end_line": 7219, + "example": 452, + "start_line": 7226, + "end_line": 7230, "section": "Emphasis and strong emphasis" }, { "markdown": "foo __*__\n", "html": "

foo *

\n", - "example": 452, - "start_line": 7222, - "end_line": 7226, + "example": 453, + "start_line": 7233, + "end_line": 7237, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo_\n", "html": "

_foo

\n", - "example": 453, - "start_line": 7229, - "end_line": 7233, + "example": 454, + "start_line": 7240, + "end_line": 7244, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo__\n", "html": "

foo_

\n", - "example": 454, - "start_line": 7240, - "end_line": 7244, + "example": 455, + "start_line": 7251, + "end_line": 7255, "section": "Emphasis and strong emphasis" }, { "markdown": "___foo__\n", "html": "

_foo

\n", - "example": 455, - "start_line": 7247, - "end_line": 7251, + "example": 456, + "start_line": 7258, + "end_line": 7262, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo_\n", "html": "

___foo

\n", - "example": 456, - "start_line": 7254, - "end_line": 7258, + "example": 457, + "start_line": 7265, + "end_line": 7269, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo___\n", "html": "

foo_

\n", - "example": 457, - "start_line": 7261, - "end_line": 7265, + "example": 458, + "start_line": 7272, + "end_line": 7276, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo____\n", "html": "

foo___

\n", - "example": 458, - "start_line": 7268, - "end_line": 7272, + "example": 459, + "start_line": 7279, + "end_line": 7283, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo**\n", "html": "

foo

\n", - "example": 459, - "start_line": 7278, - "end_line": 7282, + "example": 460, + "start_line": 7289, + "end_line": 7293, "section": "Emphasis and strong emphasis" }, { "markdown": "*_foo_*\n", "html": "

foo

\n", - "example": 460, - "start_line": 7285, - "end_line": 7289, + "example": 461, + "start_line": 7296, + "end_line": 7300, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__\n", "html": "

foo

\n", - "example": 461, - "start_line": 7292, - "end_line": 7296, + "example": 462, + "start_line": 7303, + "end_line": 7307, "section": "Emphasis and strong emphasis" }, { "markdown": "_*foo*_\n", "html": "

foo

\n", - "example": 462, - "start_line": 7299, - "end_line": 7303, + "example": 463, + "start_line": 7310, + "end_line": 7314, "section": "Emphasis and strong emphasis" }, { "markdown": "****foo****\n", "html": "

foo

\n", - "example": 463, - "start_line": 7309, - "end_line": 7313, + "example": 464, + "start_line": 7320, + "end_line": 7324, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo____\n", "html": "

foo

\n", - "example": 464, - "start_line": 7316, - "end_line": 7320, + "example": 465, + "start_line": 7327, + "end_line": 7331, "section": "Emphasis and strong emphasis" }, { "markdown": "******foo******\n", "html": "

foo

\n", - "example": 465, - "start_line": 7327, - "end_line": 7331, + "example": 466, + "start_line": 7338, + "end_line": 7342, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo***\n", "html": "

foo

\n", - "example": 466, - "start_line": 7336, - "end_line": 7340, + "example": 467, + "start_line": 7347, + "end_line": 7351, "section": "Emphasis and strong emphasis" }, { "markdown": "_____foo_____\n", "html": "

foo

\n", - "example": 467, - "start_line": 7343, - "end_line": 7347, + "example": 468, + "start_line": 7354, + "end_line": 7358, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo _bar* baz_\n", "html": "

foo _bar baz_

\n", - "example": 468, - "start_line": 7352, - "end_line": 7356, + "example": 469, + "start_line": 7363, + "end_line": 7367, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo __bar *baz bim__ bam*\n", "html": "

foo bar *baz bim bam

\n", - "example": 469, - "start_line": 7359, - "end_line": 7363, + "example": 470, + "start_line": 7370, + "end_line": 7374, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo **bar baz**\n", "html": "

**foo bar baz

\n", - "example": 470, - "start_line": 7368, - "end_line": 7372, + "example": 471, + "start_line": 7379, + "end_line": 7383, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo *bar baz*\n", "html": "

*foo bar baz

\n", - "example": 471, - "start_line": 7375, - "end_line": 7379, + "example": 472, + "start_line": 7386, + "end_line": 7390, "section": "Emphasis and strong emphasis" }, { "markdown": "*[bar*](/url)\n", "html": "

*bar*

\n", - "example": 472, - "start_line": 7384, - "end_line": 7388, + "example": 473, + "start_line": 7395, + "end_line": 7399, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo [bar_](/url)\n", "html": "

_foo bar_

\n", - "example": 473, - "start_line": 7391, - "end_line": 7395, + "example": 474, + "start_line": 7402, + "end_line": 7406, "section": "Emphasis and strong emphasis" }, { "markdown": "*\n", "html": "

*

\n", - "example": 474, - "start_line": 7398, - "end_line": 7402, + "example": 475, + "start_line": 7409, + "end_line": 7413, "section": "Emphasis and strong emphasis" }, { "markdown": "**\n", "html": "

**

\n", - "example": 475, - "start_line": 7405, - "end_line": 7409, + "example": 476, + "start_line": 7416, + "end_line": 7420, "section": "Emphasis and strong emphasis" }, { "markdown": "__\n", "html": "

__

\n", - "example": 476, - "start_line": 7412, - "end_line": 7416, + "example": 477, + "start_line": 7423, + "end_line": 7427, "section": "Emphasis and strong emphasis" }, { "markdown": "*a `*`*\n", "html": "

a *

\n", - "example": 477, - "start_line": 7419, - "end_line": 7423, + "example": 478, + "start_line": 7430, + "end_line": 7434, "section": "Emphasis and strong emphasis" }, { "markdown": "_a `_`_\n", "html": "

a _

\n", - "example": 478, - "start_line": 7426, - "end_line": 7430, + "example": 479, + "start_line": 7437, + "end_line": 7441, "section": "Emphasis and strong emphasis" }, { - "markdown": "**a\n", - "html": "

**ahttp://foo.bar/?q=**

\n", - "example": 479, - "start_line": 7433, - "end_line": 7437, + "markdown": "**a\n", + "html": "

**ahttps://foo.bar/?q=**

\n", + "example": 480, + "start_line": 7444, + "end_line": 7448, "section": "Emphasis and strong emphasis" }, { - "markdown": "__a\n", - "html": "

__ahttp://foo.bar/?q=__

\n", - "example": 480, - "start_line": 7440, - "end_line": 7444, + "markdown": "__a\n", + "html": "

__ahttps://foo.bar/?q=__

\n", + "example": 481, + "start_line": 7451, + "end_line": 7455, "section": "Emphasis and strong emphasis" }, { "markdown": "[link](/uri \"title\")\n", "html": "

link

\n", - "example": 481, - "start_line": 7528, - "end_line": 7532, + "example": 482, + "start_line": 7539, + "end_line": 7543, "section": "Links" }, { "markdown": "[link](/uri)\n", "html": "

link

\n", - "example": 482, - "start_line": 7538, - "end_line": 7542, + "example": 483, + "start_line": 7549, + "end_line": 7553, "section": "Links" }, { "markdown": "[](./target.md)\n", "html": "

\n", - "example": 483, - "start_line": 7544, - "end_line": 7548, + "example": 484, + "start_line": 7555, + "end_line": 7559, "section": "Links" }, { "markdown": "[link]()\n", "html": "

link

\n", - "example": 484, - "start_line": 7551, - "end_line": 7555, + "example": 485, + "start_line": 7562, + "end_line": 7566, "section": "Links" }, { "markdown": "[link](<>)\n", "html": "

link

\n", - "example": 485, - "start_line": 7558, - "end_line": 7562, + "example": 486, + "start_line": 7569, + "end_line": 7573, "section": "Links" }, { "markdown": "[]()\n", "html": "

\n", - "example": 486, - "start_line": 7565, - "end_line": 7569, + "example": 487, + "start_line": 7576, + "end_line": 7580, "section": "Links" }, { "markdown": "[link](/my uri)\n", "html": "

[link](/my uri)

\n", - "example": 487, - "start_line": 7574, - "end_line": 7578, + "example": 488, + "start_line": 7585, + "end_line": 7589, "section": "Links" }, { "markdown": "[link](
)\n", "html": "

link

\n", - "example": 488, - "start_line": 7580, - "end_line": 7584, + "example": 489, + "start_line": 7591, + "end_line": 7595, "section": "Links" }, { "markdown": "[link](foo\nbar)\n", "html": "

[link](foo\nbar)

\n", - "example": 489, - "start_line": 7589, - "end_line": 7595, + "example": 490, + "start_line": 7600, + "end_line": 7606, "section": "Links" }, { "markdown": "[link]()\n", "html": "

[link]()

\n", - "example": 490, - "start_line": 7597, - "end_line": 7603, + "example": 491, + "start_line": 7608, + "end_line": 7614, "section": "Links" }, { "markdown": "[a]()\n", "html": "

a

\n", - "example": 491, - "start_line": 7608, - "end_line": 7612, + "example": 492, + "start_line": 7619, + "end_line": 7623, "section": "Links" }, { "markdown": "[link]()\n", "html": "

[link](<foo>)

\n", - "example": 492, - "start_line": 7616, - "end_line": 7620, + "example": 493, + "start_line": 7627, + "end_line": 7631, "section": "Links" }, { "markdown": "[a](\n[a](c)\n", "html": "

[a](<b)c\n[a](<b)c>\n[a](c)

\n", - "example": 493, - "start_line": 7625, - "end_line": 7633, + "example": 494, + "start_line": 7636, + "end_line": 7644, "section": "Links" }, { "markdown": "[link](\\(foo\\))\n", "html": "

link

\n", - "example": 494, - "start_line": 7637, - "end_line": 7641, + "example": 495, + "start_line": 7648, + "end_line": 7652, "section": "Links" }, { "markdown": "[link](foo(and(bar)))\n", "html": "

link

\n", - "example": 495, - "start_line": 7646, - "end_line": 7650, + "example": 496, + "start_line": 7657, + "end_line": 7661, "section": "Links" }, { "markdown": "[link](foo(and(bar))\n", "html": "

[link](foo(and(bar))

\n", - "example": 496, - "start_line": 7655, - "end_line": 7659, + "example": 497, + "start_line": 7666, + "end_line": 7670, "section": "Links" }, { "markdown": "[link](foo\\(and\\(bar\\))\n", "html": "

link

\n", - "example": 497, - "start_line": 7662, - "end_line": 7666, + "example": 498, + "start_line": 7673, + "end_line": 7677, "section": "Links" }, { "markdown": "[link]()\n", "html": "

link

\n", - "example": 498, - "start_line": 7669, - "end_line": 7673, + "example": 499, + "start_line": 7680, + "end_line": 7684, "section": "Links" }, { "markdown": "[link](foo\\)\\:)\n", "html": "

link

\n", - "example": 499, - "start_line": 7679, - "end_line": 7683, + "example": 500, + "start_line": 7690, + "end_line": 7694, "section": "Links" }, { - "markdown": "[link](#fragment)\n\n[link](http://example.com#fragment)\n\n[link](http://example.com?foo=3#frag)\n", - "html": "

link

\n

link

\n

link

\n", - "example": 500, - "start_line": 7688, - "end_line": 7698, + "markdown": "[link](#fragment)\n\n[link](https://example.com#fragment)\n\n[link](https://example.com?foo=3#frag)\n", + "html": "

link

\n

link

\n

link

\n", + "example": 501, + "start_line": 7699, + "end_line": 7709, "section": "Links" }, { "markdown": "[link](foo\\bar)\n", "html": "

link

\n", - "example": 501, - "start_line": 7704, - "end_line": 7708, + "example": 502, + "start_line": 7715, + "end_line": 7719, "section": "Links" }, { "markdown": "[link](foo%20bä)\n", "html": "

link

\n", - "example": 502, - "start_line": 7720, - "end_line": 7724, + "example": 503, + "start_line": 7731, + "end_line": 7735, "section": "Links" }, { "markdown": "[link](\"title\")\n", "html": "

link

\n", - "example": 503, - "start_line": 7731, - "end_line": 7735, + "example": 504, + "start_line": 7742, + "end_line": 7746, "section": "Links" }, { "markdown": "[link](/url \"title\")\n[link](/url 'title')\n[link](/url (title))\n", "html": "

link\nlink\nlink

\n", - "example": 504, - "start_line": 7740, - "end_line": 7748, + "example": 505, + "start_line": 7751, + "end_line": 7759, "section": "Links" }, { "markdown": "[link](/url \"title \\\""\")\n", "html": "

link

\n", - "example": 505, - "start_line": 7754, - "end_line": 7758, + "example": 506, + "start_line": 7765, + "end_line": 7769, "section": "Links" }, { "markdown": "[link](/url \"title\")\n", "html": "

link

\n", - "example": 506, - "start_line": 7765, - "end_line": 7769, + "example": 507, + "start_line": 7776, + "end_line": 7780, "section": "Links" }, { "markdown": "[link](/url \"title \"and\" title\")\n", "html": "

[link](/url "title "and" title")

\n", - "example": 507, - "start_line": 7774, - "end_line": 7778, + "example": 508, + "start_line": 7785, + "end_line": 7789, "section": "Links" }, { "markdown": "[link](/url 'title \"and\" title')\n", "html": "

link

\n", - "example": 508, - "start_line": 7783, - "end_line": 7787, + "example": 509, + "start_line": 7794, + "end_line": 7798, "section": "Links" }, { "markdown": "[link]( /uri\n \"title\" )\n", "html": "

link

\n", - "example": 509, - "start_line": 7808, - "end_line": 7813, + "example": 510, + "start_line": 7819, + "end_line": 7824, "section": "Links" }, { "markdown": "[link] (/uri)\n", "html": "

[link] (/uri)

\n", - "example": 510, - "start_line": 7819, - "end_line": 7823, + "example": 511, + "start_line": 7830, + "end_line": 7834, "section": "Links" }, { "markdown": "[link [foo [bar]]](/uri)\n", "html": "

link [foo [bar]]

\n", - "example": 511, - "start_line": 7829, - "end_line": 7833, + "example": 512, + "start_line": 7840, + "end_line": 7844, "section": "Links" }, { "markdown": "[link] bar](/uri)\n", "html": "

[link] bar](/uri)

\n", - "example": 512, - "start_line": 7836, - "end_line": 7840, + "example": 513, + "start_line": 7847, + "end_line": 7851, "section": "Links" }, { "markdown": "[link [bar](/uri)\n", "html": "

[link bar

\n", - "example": 513, - "start_line": 7843, - "end_line": 7847, + "example": 514, + "start_line": 7854, + "end_line": 7858, "section": "Links" }, { "markdown": "[link \\[bar](/uri)\n", "html": "

link [bar

\n", - "example": 514, - "start_line": 7850, - "end_line": 7854, + "example": 515, + "start_line": 7861, + "end_line": 7865, "section": "Links" }, { "markdown": "[link *foo **bar** `#`*](/uri)\n", "html": "

link foo bar #

\n", - "example": 515, - "start_line": 7859, - "end_line": 7863, + "example": 516, + "start_line": 7870, + "end_line": 7874, "section": "Links" }, { "markdown": "[![moon](moon.jpg)](/uri)\n", "html": "

\"moon\"

\n", - "example": 516, - "start_line": 7866, - "end_line": 7870, + "example": 517, + "start_line": 7877, + "end_line": 7881, "section": "Links" }, { "markdown": "[foo [bar](/uri)](/uri)\n", "html": "

[foo bar](/uri)

\n", - "example": 517, - "start_line": 7875, - "end_line": 7879, + "example": 518, + "start_line": 7886, + "end_line": 7890, "section": "Links" }, { "markdown": "[foo *[bar [baz](/uri)](/uri)*](/uri)\n", "html": "

[foo [bar baz](/uri)](/uri)

\n", - "example": 518, - "start_line": 7882, - "end_line": 7886, + "example": 519, + "start_line": 7893, + "end_line": 7897, "section": "Links" }, { "markdown": "![[[foo](uri1)](uri2)](uri3)\n", "html": "

\"[foo](uri2)\"

\n", - "example": 519, - "start_line": 7889, - "end_line": 7893, + "example": 520, + "start_line": 7900, + "end_line": 7904, "section": "Links" }, { "markdown": "*[foo*](/uri)\n", "html": "

*foo*

\n", - "example": 520, - "start_line": 7899, - "end_line": 7903, + "example": 521, + "start_line": 7910, + "end_line": 7914, "section": "Links" }, { "markdown": "[foo *bar](baz*)\n", "html": "

foo *bar

\n", - "example": 521, - "start_line": 7906, - "end_line": 7910, + "example": 522, + "start_line": 7917, + "end_line": 7921, "section": "Links" }, { "markdown": "*foo [bar* baz]\n", "html": "

foo [bar baz]

\n", - "example": 522, - "start_line": 7916, - "end_line": 7920, + "example": 523, + "start_line": 7927, + "end_line": 7931, "section": "Links" }, { "markdown": "[foo \n", "html": "

[foo

\n", - "example": 523, - "start_line": 7926, - "end_line": 7930, + "example": 524, + "start_line": 7937, + "end_line": 7941, "section": "Links" }, { "markdown": "[foo`](/uri)`\n", "html": "

[foo](/uri)

\n", - "example": 524, - "start_line": 7933, - "end_line": 7937, + "example": 525, + "start_line": 7944, + "end_line": 7948, "section": "Links" }, { - "markdown": "[foo\n", - "html": "

[foohttp://example.com/?search=](uri)

\n", - "example": 525, - "start_line": 7940, - "end_line": 7944, + "markdown": "[foo\n", + "html": "

[foohttps://example.com/?search=](uri)

\n", + "example": 526, + "start_line": 7951, + "end_line": 7955, "section": "Links" }, { "markdown": "[foo][bar]\n\n[bar]: /url \"title\"\n", "html": "

foo

\n", - "example": 526, - "start_line": 7978, - "end_line": 7984, + "example": 527, + "start_line": 7989, + "end_line": 7995, "section": "Links" }, { "markdown": "[link [foo [bar]]][ref]\n\n[ref]: /uri\n", "html": "

link [foo [bar]]

\n", - "example": 527, - "start_line": 7993, - "end_line": 7999, + "example": 528, + "start_line": 8004, + "end_line": 8010, "section": "Links" }, { "markdown": "[link \\[bar][ref]\n\n[ref]: /uri\n", "html": "

link [bar

\n", - "example": 528, - "start_line": 8002, - "end_line": 8008, + "example": 529, + "start_line": 8013, + "end_line": 8019, "section": "Links" }, { "markdown": "[link *foo **bar** `#`*][ref]\n\n[ref]: /uri\n", "html": "

link foo bar #

\n", - "example": 529, - "start_line": 8013, - "end_line": 8019, + "example": 530, + "start_line": 8024, + "end_line": 8030, "section": "Links" }, { "markdown": "[![moon](moon.jpg)][ref]\n\n[ref]: /uri\n", "html": "

\"moon\"

\n", - "example": 530, - "start_line": 8022, - "end_line": 8028, + "example": 531, + "start_line": 8033, + "end_line": 8039, "section": "Links" }, { "markdown": "[foo [bar](/uri)][ref]\n\n[ref]: /uri\n", "html": "

[foo bar]ref

\n", - "example": 531, - "start_line": 8033, - "end_line": 8039, + "example": 532, + "start_line": 8044, + "end_line": 8050, "section": "Links" }, { "markdown": "[foo *bar [baz][ref]*][ref]\n\n[ref]: /uri\n", "html": "

[foo bar baz]ref

\n", - "example": 532, - "start_line": 8042, - "end_line": 8048, + "example": 533, + "start_line": 8053, + "end_line": 8059, "section": "Links" }, { "markdown": "*[foo*][ref]\n\n[ref]: /uri\n", "html": "

*foo*

\n", - "example": 533, - "start_line": 8057, - "end_line": 8063, + "example": 534, + "start_line": 8068, + "end_line": 8074, "section": "Links" }, { "markdown": "[foo *bar][ref]*\n\n[ref]: /uri\n", "html": "

foo *bar*

\n", - "example": 534, - "start_line": 8066, - "end_line": 8072, + "example": 535, + "start_line": 8077, + "end_line": 8083, "section": "Links" }, { "markdown": "[foo \n\n[ref]: /uri\n", "html": "

[foo

\n", - "example": 535, - "start_line": 8078, - "end_line": 8084, + "example": 536, + "start_line": 8089, + "end_line": 8095, "section": "Links" }, { "markdown": "[foo`][ref]`\n\n[ref]: /uri\n", "html": "

[foo][ref]

\n", - "example": 536, - "start_line": 8087, - "end_line": 8093, - "section": "Links" - }, - { - "markdown": "[foo\n\n[ref]: /uri\n", - "html": "

[foohttp://example.com/?search=][ref]

\n", "example": 537, - "start_line": 8096, - "end_line": 8102, + "start_line": 8098, + "end_line": 8104, "section": "Links" }, { - "markdown": "[foo][BaR]\n\n[bar]: /url \"title\"\n", - "html": "

foo

\n", + "markdown": "[foo\n\n[ref]: /uri\n", + "html": "

[foohttps://example.com/?search=][ref]

\n", "example": 538, "start_line": 8107, "end_line": 8113, "section": "Links" }, { - "markdown": "[ẞ]\n\n[SS]: /url\n", - "html": "

\n", + "markdown": "[foo][BaR]\n\n[bar]: /url \"title\"\n", + "html": "

foo

\n", "example": 539, "start_line": 8118, "end_line": 8124, "section": "Links" }, + { + "markdown": "[ẞ]\n\n[SS]: /url\n", + "html": "

\n", + "example": 540, + "start_line": 8129, + "end_line": 8135, + "section": "Links" + }, { "markdown": "[Foo\n bar]: /url\n\n[Baz][Foo bar]\n", "html": "

Baz

\n", - "example": 540, - "start_line": 8130, - "end_line": 8137, + "example": 541, + "start_line": 8141, + "end_line": 8148, "section": "Links" }, { "markdown": "[foo] [bar]\n\n[bar]: /url \"title\"\n", "html": "

[foo] bar

\n", - "example": 541, - "start_line": 8143, - "end_line": 8149, + "example": 542, + "start_line": 8154, + "end_line": 8160, "section": "Links" }, { "markdown": "[foo]\n[bar]\n\n[bar]: /url \"title\"\n", "html": "

[foo]\nbar

\n", - "example": 542, - "start_line": 8152, - "end_line": 8160, + "example": 543, + "start_line": 8163, + "end_line": 8171, "section": "Links" }, { "markdown": "[foo]: /url1\n\n[foo]: /url2\n\n[bar][foo]\n", "html": "

bar

\n", - "example": 543, - "start_line": 8193, - "end_line": 8201, + "example": 544, + "start_line": 8204, + "end_line": 8212, "section": "Links" }, { "markdown": "[bar][foo\\!]\n\n[foo!]: /url\n", "html": "

[bar][foo!]

\n", - "example": 544, - "start_line": 8208, - "end_line": 8214, + "example": 545, + "start_line": 8219, + "end_line": 8225, "section": "Links" }, { "markdown": "[foo][ref[]\n\n[ref[]: /uri\n", "html": "

[foo][ref[]

\n

[ref[]: /uri

\n", - "example": 545, - "start_line": 8220, - "end_line": 8227, + "example": 546, + "start_line": 8231, + "end_line": 8238, "section": "Links" }, { "markdown": "[foo][ref[bar]]\n\n[ref[bar]]: /uri\n", "html": "

[foo][ref[bar]]

\n

[ref[bar]]: /uri

\n", - "example": 546, - "start_line": 8230, - "end_line": 8237, + "example": 547, + "start_line": 8241, + "end_line": 8248, "section": "Links" }, { "markdown": "[[[foo]]]\n\n[[[foo]]]: /url\n", "html": "

[[[foo]]]

\n

[[[foo]]]: /url

\n", - "example": 547, - "start_line": 8240, - "end_line": 8247, + "example": 548, + "start_line": 8251, + "end_line": 8258, "section": "Links" }, { "markdown": "[foo][ref\\[]\n\n[ref\\[]: /uri\n", "html": "

foo

\n", - "example": 548, - "start_line": 8250, - "end_line": 8256, + "example": 549, + "start_line": 8261, + "end_line": 8267, "section": "Links" }, { "markdown": "[bar\\\\]: /uri\n\n[bar\\\\]\n", "html": "

bar\\

\n", - "example": 549, - "start_line": 8261, - "end_line": 8267, + "example": 550, + "start_line": 8272, + "end_line": 8278, "section": "Links" }, { "markdown": "[]\n\n[]: /uri\n", "html": "

[]

\n

[]: /uri

\n", - "example": 550, - "start_line": 8273, - "end_line": 8280, + "example": 551, + "start_line": 8284, + "end_line": 8291, "section": "Links" }, { "markdown": "[\n ]\n\n[\n ]: /uri\n", "html": "

[\n]

\n

[\n]: /uri

\n", - "example": 551, - "start_line": 8283, - "end_line": 8294, + "example": 552, + "start_line": 8294, + "end_line": 8305, "section": "Links" }, { "markdown": "[foo][]\n\n[foo]: /url \"title\"\n", "html": "

foo

\n", - "example": 552, - "start_line": 8306, - "end_line": 8312, + "example": 553, + "start_line": 8317, + "end_line": 8323, "section": "Links" }, { "markdown": "[*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", "html": "

foo bar

\n", - "example": 553, - "start_line": 8315, - "end_line": 8321, + "example": 554, + "start_line": 8326, + "end_line": 8332, "section": "Links" }, { "markdown": "[Foo][]\n\n[foo]: /url \"title\"\n", "html": "

Foo

\n", - "example": 554, - "start_line": 8326, - "end_line": 8332, + "example": 555, + "start_line": 8337, + "end_line": 8343, "section": "Links" }, { "markdown": "[foo] \n[]\n\n[foo]: /url \"title\"\n", "html": "

foo\n[]

\n", - "example": 555, - "start_line": 8339, - "end_line": 8347, + "example": 556, + "start_line": 8350, + "end_line": 8358, "section": "Links" }, { "markdown": "[foo]\n\n[foo]: /url \"title\"\n", "html": "

foo

\n", - "example": 556, - "start_line": 8359, - "end_line": 8365, + "example": 557, + "start_line": 8370, + "end_line": 8376, "section": "Links" }, { "markdown": "[*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", "html": "

foo bar

\n", - "example": 557, - "start_line": 8368, - "end_line": 8374, + "example": 558, + "start_line": 8379, + "end_line": 8385, "section": "Links" }, { "markdown": "[[*foo* bar]]\n\n[*foo* bar]: /url \"title\"\n", "html": "

[foo bar]

\n", - "example": 558, - "start_line": 8377, - "end_line": 8383, + "example": 559, + "start_line": 8388, + "end_line": 8394, "section": "Links" }, { "markdown": "[[bar [foo]\n\n[foo]: /url\n", "html": "

[[bar foo

\n", - "example": 559, - "start_line": 8386, - "end_line": 8392, + "example": 560, + "start_line": 8397, + "end_line": 8403, "section": "Links" }, { "markdown": "[Foo]\n\n[foo]: /url \"title\"\n", "html": "

Foo

\n", - "example": 560, - "start_line": 8397, - "end_line": 8403, + "example": 561, + "start_line": 8408, + "end_line": 8414, "section": "Links" }, { "markdown": "[foo] bar\n\n[foo]: /url\n", "html": "

foo bar

\n", - "example": 561, - "start_line": 8408, - "end_line": 8414, + "example": 562, + "start_line": 8419, + "end_line": 8425, "section": "Links" }, { "markdown": "\\[foo]\n\n[foo]: /url \"title\"\n", "html": "

[foo]

\n", - "example": 562, - "start_line": 8420, - "end_line": 8426, + "example": 563, + "start_line": 8431, + "end_line": 8437, "section": "Links" }, { "markdown": "[foo*]: /url\n\n*[foo*]\n", "html": "

*foo*

\n", - "example": 563, - "start_line": 8432, - "end_line": 8438, + "example": 564, + "start_line": 8443, + "end_line": 8449, "section": "Links" }, { "markdown": "[foo][bar]\n\n[foo]: /url1\n[bar]: /url2\n", "html": "

foo

\n", - "example": 564, - "start_line": 8444, - "end_line": 8451, + "example": 565, + "start_line": 8455, + "end_line": 8462, "section": "Links" }, { "markdown": "[foo][]\n\n[foo]: /url1\n", "html": "

foo

\n", - "example": 565, - "start_line": 8453, - "end_line": 8459, + "example": 566, + "start_line": 8464, + "end_line": 8470, "section": "Links" }, { "markdown": "[foo]()\n\n[foo]: /url1\n", "html": "

foo

\n", - "example": 566, - "start_line": 8463, - "end_line": 8469, + "example": 567, + "start_line": 8474, + "end_line": 8480, "section": "Links" }, { "markdown": "[foo](not a link)\n\n[foo]: /url1\n", "html": "

foo(not a link)

\n", - "example": 567, - "start_line": 8471, - "end_line": 8477, + "example": 568, + "start_line": 8482, + "end_line": 8488, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url\n", "html": "

[foo]bar

\n", - "example": 568, - "start_line": 8482, - "end_line": 8488, + "example": 569, + "start_line": 8493, + "end_line": 8499, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[bar]: /url2\n", "html": "

foobaz

\n", - "example": 569, - "start_line": 8494, - "end_line": 8501, + "example": 570, + "start_line": 8505, + "end_line": 8512, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[foo]: /url2\n", "html": "

[foo]bar

\n", - "example": 570, - "start_line": 8507, - "end_line": 8514, + "example": 571, + "start_line": 8518, + "end_line": 8525, "section": "Links" }, { "markdown": "![foo](/url \"title\")\n", "html": "

\"foo\"

\n", - "example": 571, - "start_line": 8530, - "end_line": 8534, + "example": 572, + "start_line": 8541, + "end_line": 8545, "section": "Images" }, { "markdown": "![foo *bar*]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", "html": "

\"foo

\n", - "example": 572, - "start_line": 8537, - "end_line": 8543, + "example": 573, + "start_line": 8548, + "end_line": 8554, "section": "Images" }, { "markdown": "![foo ![bar](/url)](/url2)\n", "html": "

\"foo

\n", - "example": 573, - "start_line": 8546, - "end_line": 8550, + "example": 574, + "start_line": 8557, + "end_line": 8561, "section": "Images" }, { "markdown": "![foo [bar](/url)](/url2)\n", "html": "

\"foo

\n", - "example": 574, - "start_line": 8553, - "end_line": 8557, + "example": 575, + "start_line": 8564, + "end_line": 8568, "section": "Images" }, { "markdown": "![foo *bar*][]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", "html": "

\"foo

\n", - "example": 575, - "start_line": 8567, - "end_line": 8573, + "example": 576, + "start_line": 8578, + "end_line": 8584, "section": "Images" }, { "markdown": "![foo *bar*][foobar]\n\n[FOOBAR]: train.jpg \"train & tracks\"\n", "html": "

\"foo

\n", - "example": 576, - "start_line": 8576, - "end_line": 8582, + "example": 577, + "start_line": 8587, + "end_line": 8593, "section": "Images" }, { "markdown": "![foo](train.jpg)\n", "html": "

\"foo\"

\n", - "example": 577, - "start_line": 8585, - "end_line": 8589, + "example": 578, + "start_line": 8596, + "end_line": 8600, "section": "Images" }, { "markdown": "My ![foo bar](/path/to/train.jpg \"title\" )\n", "html": "

My \"foo

\n", - "example": 578, - "start_line": 8592, - "end_line": 8596, + "example": 579, + "start_line": 8603, + "end_line": 8607, "section": "Images" }, { "markdown": "![foo]()\n", "html": "

\"foo\"

\n", - "example": 579, - "start_line": 8599, - "end_line": 8603, + "example": 580, + "start_line": 8610, + "end_line": 8614, "section": "Images" }, { "markdown": "![](/url)\n", "html": "

\"\"

\n", - "example": 580, - "start_line": 8606, - "end_line": 8610, + "example": 581, + "start_line": 8617, + "end_line": 8621, "section": "Images" }, { "markdown": "![foo][bar]\n\n[bar]: /url\n", "html": "

\"foo\"

\n", - "example": 581, - "start_line": 8615, - "end_line": 8621, + "example": 582, + "start_line": 8626, + "end_line": 8632, "section": "Images" }, { "markdown": "![foo][bar]\n\n[BAR]: /url\n", "html": "

\"foo\"

\n", - "example": 582, - "start_line": 8624, - "end_line": 8630, + "example": 583, + "start_line": 8635, + "end_line": 8641, "section": "Images" }, { "markdown": "![foo][]\n\n[foo]: /url \"title\"\n", "html": "

\"foo\"

\n", - "example": 583, - "start_line": 8635, - "end_line": 8641, + "example": 584, + "start_line": 8646, + "end_line": 8652, "section": "Images" }, { "markdown": "![*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", "html": "

\"foo

\n", - "example": 584, - "start_line": 8644, - "end_line": 8650, + "example": 585, + "start_line": 8655, + "end_line": 8661, "section": "Images" }, { "markdown": "![Foo][]\n\n[foo]: /url \"title\"\n", "html": "

\"Foo\"

\n", - "example": 585, - "start_line": 8655, - "end_line": 8661, + "example": 586, + "start_line": 8666, + "end_line": 8672, "section": "Images" }, { "markdown": "![foo] \n[]\n\n[foo]: /url \"title\"\n", "html": "

\"foo\"\n[]

\n", - "example": 586, - "start_line": 8667, - "end_line": 8675, + "example": 587, + "start_line": 8678, + "end_line": 8686, "section": "Images" }, { "markdown": "![foo]\n\n[foo]: /url \"title\"\n", "html": "

\"foo\"

\n", - "example": 587, - "start_line": 8680, - "end_line": 8686, + "example": 588, + "start_line": 8691, + "end_line": 8697, "section": "Images" }, { "markdown": "![*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", "html": "

\"foo

\n", - "example": 588, - "start_line": 8689, - "end_line": 8695, + "example": 589, + "start_line": 8700, + "end_line": 8706, "section": "Images" }, { "markdown": "![[foo]]\n\n[[foo]]: /url \"title\"\n", "html": "

![[foo]]

\n

[[foo]]: /url "title"

\n", - "example": 589, - "start_line": 8700, - "end_line": 8707, + "example": 590, + "start_line": 8711, + "end_line": 8718, "section": "Images" }, { "markdown": "![Foo]\n\n[foo]: /url \"title\"\n", "html": "

\"Foo\"

\n", - "example": 590, - "start_line": 8712, - "end_line": 8718, + "example": 591, + "start_line": 8723, + "end_line": 8729, "section": "Images" }, { "markdown": "!\\[foo]\n\n[foo]: /url \"title\"\n", "html": "

![foo]

\n", - "example": 591, - "start_line": 8724, - "end_line": 8730, + "example": 592, + "start_line": 8735, + "end_line": 8741, "section": "Images" }, { "markdown": "\\![foo]\n\n[foo]: /url \"title\"\n", "html": "

!foo

\n", - "example": 592, - "start_line": 8736, - "end_line": 8742, + "example": 593, + "start_line": 8747, + "end_line": 8753, "section": "Images" }, { "markdown": "\n", "html": "

http://foo.bar.baz

\n", - "example": 593, - "start_line": 8769, - "end_line": 8773, + "example": 594, + "start_line": 8780, + "end_line": 8784, "section": "Autolinks" }, { - "markdown": "\n", - "html": "

http://foo.bar.baz/test?q=hello&id=22&boolean

\n", - "example": 594, - "start_line": 8776, - "end_line": 8780, + "markdown": "\n", + "html": "

https://foo.bar.baz/test?q=hello&id=22&boolean

\n", + "example": 595, + "start_line": 8787, + "end_line": 8791, "section": "Autolinks" }, { "markdown": "\n", "html": "

irc://foo.bar:2233/baz

\n", - "example": 595, - "start_line": 8783, - "end_line": 8787, + "example": 596, + "start_line": 8794, + "end_line": 8798, "section": "Autolinks" }, { "markdown": "\n", "html": "

MAILTO:FOO@BAR.BAZ

\n", - "example": 596, - "start_line": 8792, - "end_line": 8796, + "example": 597, + "start_line": 8803, + "end_line": 8807, "section": "Autolinks" }, { "markdown": "\n", "html": "

a+b+c:d

\n", - "example": 597, - "start_line": 8804, - "end_line": 8808, + "example": 598, + "start_line": 8815, + "end_line": 8819, "section": "Autolinks" }, { "markdown": "\n", "html": "

made-up-scheme://foo,bar

\n", - "example": 598, - "start_line": 8811, - "end_line": 8815, + "example": 599, + "start_line": 8822, + "end_line": 8826, "section": "Autolinks" }, { - "markdown": "\n", - "html": "

http://../

\n", - "example": 599, - "start_line": 8818, - "end_line": 8822, + "markdown": "\n", + "html": "

https://../

\n", + "example": 600, + "start_line": 8829, + "end_line": 8833, "section": "Autolinks" }, { "markdown": "\n", "html": "

localhost:5001/foo

\n", - "example": 600, - "start_line": 8825, - "end_line": 8829, + "example": 601, + "start_line": 8836, + "end_line": 8840, "section": "Autolinks" }, { - "markdown": "\n", - "html": "

<http://foo.bar/baz bim>

\n", - "example": 601, - "start_line": 8834, - "end_line": 8838, + "markdown": "\n", + "html": "

<https://foo.bar/baz bim>

\n", + "example": 602, + "start_line": 8845, + "end_line": 8849, "section": "Autolinks" }, { - "markdown": "\n", - "html": "

http://example.com/\\[\\

\n", - "example": 602, - "start_line": 8843, - "end_line": 8847, + "markdown": "\n", + "html": "

https://example.com/\\[\\

\n", + "example": 603, + "start_line": 8854, + "end_line": 8858, "section": "Autolinks" }, { "markdown": "\n", "html": "

foo@bar.example.com

\n", - "example": 603, - "start_line": 8865, - "end_line": 8869, + "example": 604, + "start_line": 8876, + "end_line": 8880, "section": "Autolinks" }, { "markdown": "\n", "html": "

foo+special@Bar.baz-bar0.com

\n", - "example": 604, - "start_line": 8872, - "end_line": 8876, + "example": 605, + "start_line": 8883, + "end_line": 8887, "section": "Autolinks" }, { "markdown": "\n", "html": "

<foo+@bar.example.com>

\n", - "example": 605, - "start_line": 8881, - "end_line": 8885, + "example": 606, + "start_line": 8892, + "end_line": 8896, "section": "Autolinks" }, { "markdown": "<>\n", "html": "

<>

\n", - "example": 606, - "start_line": 8890, - "end_line": 8894, + "example": 607, + "start_line": 8901, + "end_line": 8905, "section": "Autolinks" }, { - "markdown": "< http://foo.bar >\n", - "html": "

< http://foo.bar >

\n", - "example": 607, - "start_line": 8897, - "end_line": 8901, + "markdown": "< https://foo.bar >\n", + "html": "

< https://foo.bar >

\n", + "example": 608, + "start_line": 8908, + "end_line": 8912, "section": "Autolinks" }, { "markdown": "\n", "html": "

<m:abc>

\n", - "example": 608, - "start_line": 8904, - "end_line": 8908, + "example": 609, + "start_line": 8915, + "end_line": 8919, "section": "Autolinks" }, { "markdown": "\n", "html": "

<foo.bar.baz>

\n", - "example": 609, - "start_line": 8911, - "end_line": 8915, + "example": 610, + "start_line": 8922, + "end_line": 8926, "section": "Autolinks" }, { - "markdown": "http://example.com/n", - "html": "

http://example.com

\n", - "example": 610, - "start_line": 8918, - "end_line": 8922, + "markdown": "https://example.com/n", + "html": "

https://example.com

\n", + "example": 611, + "start_line": 8929, + "end_line": 8933, "section": "Autolinks" }, { "markdown": "foo@bar.example.com\n", "html": "

foo@bar.example.com

\n", - "example": 611, - "start_line": 8925, - "end_line": 8929, + "example": 612, + "start_line": 8936, + "end_line": 8940, "section": "Autolinks" }, { "markdown": "\n", "html": "

\n", - "example": 612, - "start_line": 9006, - "end_line": 9010, + "example": 613, + "start_line": 9016, + "end_line": 9020, "section": "Raw HTML" }, { "markdown": "\n", "html": "

\n", - "example": 613, - "start_line": 9015, - "end_line": 9019, + "example": 614, + "start_line": 9025, + "end_line": 9029, "section": "Raw HTML" }, { "markdown": "\n", "html": "

\n", - "example": 614, - "start_line": 9024, - "end_line": 9030, + "example": 615, + "start_line": 9034, + "end_line": 9040, "section": "Raw HTML" }, { "markdown": "\n", "html": "

\n", - "example": 615, - "start_line": 9035, - "end_line": 9041, + "example": 616, + "start_line": 9045, + "end_line": 9051, "section": "Raw HTML" }, { "markdown": "Foo \n", "html": "

Foo

\n", - "example": 616, - "start_line": 9046, - "end_line": 9050, + "example": 617, + "start_line": 9056, + "end_line": 9060, "section": "Raw HTML" }, { "markdown": "<33> <__>\n", "html": "

<33> <__>

\n", - "example": 617, - "start_line": 9055, - "end_line": 9059, + "example": 618, + "start_line": 9065, + "end_line": 9069, "section": "Raw HTML" }, { "markdown": "
\n", "html": "

<a h*#ref="hi">

\n", - "example": 618, - "start_line": 9064, - "end_line": 9068, + "example": 619, + "start_line": 9074, + "end_line": 9078, "section": "Raw HTML" }, { "markdown": "
\n", "html": "

<a href="hi'> <a href=hi'>

\n", - "example": 619, - "start_line": 9073, - "end_line": 9077, + "example": 620, + "start_line": 9083, + "end_line": 9087, "section": "Raw HTML" }, { "markdown": "< a><\nfoo>\n\n", "html": "

< a><\nfoo><bar/ >\n<foo bar=baz\nbim!bop />

\n", - "example": 620, - "start_line": 9082, - "end_line": 9092, + "example": 621, + "start_line": 9092, + "end_line": 9102, "section": "Raw HTML" }, { "markdown": "
\n", "html": "

<a href='https://github.com/bar'title=title>

\n", - "example": 621, - "start_line": 9097, - "end_line": 9101, + "example": 622, + "start_line": 9107, + "end_line": 9111, "section": "Raw HTML" }, { "markdown": "
\n", "html": "

\n", - "example": 622, - "start_line": 9106, - "end_line": 9110, + "example": 623, + "start_line": 9116, + "end_line": 9120, "section": "Raw HTML" }, { "markdown": "\n", "html": "

</a href="foo">

\n", - "example": 623, - "start_line": 9115, - "end_line": 9119, - "section": "Raw HTML" - }, - { - "markdown": "foo \n", - "html": "

foo

\n", "example": 624, - "start_line": 9124, - "end_line": 9130, + "start_line": 9125, + "end_line": 9129, "section": "Raw HTML" }, { - "markdown": "foo \n", - "html": "

foo <!-- not a comment -- two hyphens -->

\n", + "markdown": "foo \n", + "html": "

foo

\n", "example": 625, - "start_line": 9133, - "end_line": 9137, + "start_line": 9134, + "end_line": 9140, "section": "Raw HTML" }, { - "markdown": "foo foo -->\n\nfoo \n", - "html": "

foo <!--> foo -->

\n

foo <!-- foo--->

\n", + "markdown": "foo foo -->\n\nfoo foo -->\n", + "html": "

foo foo -->

\n

foo foo -->

\n", "example": 626, "start_line": 9142, "end_line": 9149, diff --git a/tests/test_cmark_spec/get_cmark_spec.py b/tests/test_cmark_spec/get_cmark_spec.py index 851cad75..d59364f0 100644 --- a/tests/test_cmark_spec/get_cmark_spec.py +++ b/tests/test_cmark_spec/get_cmark_spec.py @@ -4,10 +4,12 @@ # ] # /// from pathlib import Path +from typing import Any -default_version = "0.30" -default_output_path = Path(__file__).parent / "commonmark.json" -default_fixture_test_path = ( +default_version = "0.31.2" +default_json_path = Path(__file__).parent / "commonmark.json" +default_text_path = Path(__file__).parent / "spec.md" +default_fixture_path = ( Path(__file__).parent.parent / "test_port" / "fixtures" / "commonmark_spec.md" ) @@ -23,55 +25,72 @@ def create_argparser(): help=f"CommonMark spec version to download (default: {default_version})", ) parser.add_argument( - "--output", - "-o", + "--output-json", type=Path, - default=default_output_path, - help=f"Output file path (default: {default_output_path})", + default=default_json_path, + help=f"Output file path (default: {default_json_path})", ) parser.add_argument( - "--test-fixture", + "--output-text", type=Path, - default=default_fixture_test_path, - help=f"Write to test fixture (default: {default_fixture_test_path})", + default=default_text_path, + help=f"Output file path (default: {default_text_path})", + ) + parser.add_argument( + "--output-fixture", + type=Path, + default=default_fixture_path, + help=f"Write to test fixture (default: {default_fixture_path})", ) return parser +def _json_to_fixture(data: list[dict[str, Any]]) -> str: + text = "" + for item in data: + text += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + text += f"src line: {item['start_line'] - 1}\n\n" + text += f".\n{item['markdown']}.\n{item['html']}.\n\n" + return text + + if __name__ == "__main__": import requests # type: ignore[import-untyped] args = create_argparser().parse_args() version: str = args.version - output_path: Path = args.output - write_to_test_fixture = True - test_fixture: Path = args.test_fixture + json_path: Path = args.output_json + txt_path: Path = args.output_text + test_fixture: Path = args.output_fixture + changed = False - url = f"https://spec.commonmark.org/%7Bversion%7D/spec.json" - print(f"Downloading CommonMark spec from {url}") - response = requests.get(url) - response.raise_for_status() - if not output_path.exists() or output_path.read_text() != response.text: - changed = True - with output_path.open("w") as f: - f.write(response.text) - print(f"Updated to {output_path}") - else: - print(f"Spec file {output_path} is up to date, not overwriting") - if write_to_test_fixture: - data = response.json() - text = "" - for item in data: - text += "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" - text += f"src line: {item['start_line'] - 1}\n\n" - text += f".\n{item['markdown']}.\n{item['html']}.\n\n" - if not test_fixture.exists() or test_fixture.read_text() != text: + json_url = f"https://spec.commonmark.org/%7Bversion%7D/spec.json" + txt_url = f"https://raw.githubusercontent.com/commonmark/commonmark-spec/refs/tags/%7Bversion%7D/spec.txt" + + for url, output_path in ((json_url, json_path), (txt_url, txt_path)): + print(f"Downloading CommonMark spec from {url}") + response = requests.get(url) + response.raise_for_status() + if not output_path.exists() or output_path.read_text() != response.text: changed = True - with test_fixture.open("w") as f: - f.write(text) - print(f"Also updated to {test_fixture}") + with output_path.open("w") as f: + f.write(response.text) + print(f"Updated to {output_path}") else: - print(f"Fixture file {test_fixture} is up to date, not overwriting") + print(f"File {output_path} is up to date, not overwriting") + + # write_to_test_fixture: + response = requests.get(json_url) + response.raise_for_status() + data = response.json() + text = _json_to_fixture(data) + if not test_fixture.exists() or test_fixture.read_text() != text: + changed = True + with test_fixture.open("w") as f: + f.write(text) + print(f"Also updated to {test_fixture}") + else: + print(f"Fixture file {test_fixture} is up to date, not overwriting") raise SystemExit(0 if not changed else 1) diff --git a/tests/test_cmark_spec/spec.md b/tests/test_cmark_spec/spec.md index 2d79f7b7..f1fab281 100644 --- a/tests/test_cmark_spec/spec.md +++ b/tests/test_cmark_spec/spec.md @@ -1,9 +1,9 @@ --- title: CommonMark Spec author: John MacFarlane -version: 0.30 -date: '2021-06-19' -license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)' +version: '0.31.2' +date: '2024-01-28' +license: '[CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)' ... # Introduction @@ -14,7 +14,7 @@ Markdown is a plain text format for writing structured documents, based on conventions for indicating formatting in email and usenet posts. It was developed by John Gruber (with help from Aaron Swartz) and released in 2004 in the form of a -[syntax description](http://daringfireball.net/projects/markdown/syntax) +[syntax description](https://daringfireball.net/projects/markdown/syntax) and a Perl script (`Markdown.pl`) for converting Markdown to HTML. In the next decade, dozens of implementations were developed in many languages. Some extended the original @@ -34,10 +34,10 @@ As Gruber writes: > Markdown-formatted document should be publishable as-is, as > plain text, without looking like it's been marked up with tags > or formatting instructions. -> () +> () The point can be illustrated by comparing a sample of -[AsciiDoc](http://www.methods.co.nz/asciidoc/) with +[AsciiDoc](https://asciidoc.org/) with an equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc manual: @@ -103,7 +103,7 @@ source, not just in the processed document. ## Why is a spec needed? John Gruber's [canonical description of Markdown's -syntax](http://daringfireball.net/projects/markdown/syntax) +syntax](https://daringfireball.net/projects/markdown/syntax) does not specify the syntax unambiguously. Here are some examples of questions it does not answer: @@ -114,7 +114,7 @@ questions it does not answer: not require that. This is hardly a "corner case," and divergences between implementations on this issue often lead to surprises for users in real documents. (See [this comment by John - Gruber](http://article.gmane.org/gmane.text.markdown.general/1997).) + Gruber](https://web.archive.org/web/20170611172104/http://article.gmane.org/gmane.text.markdown.general/1997).) 2. Is a blank line needed before a block quote or heading? Most implementations do not require the blank line. However, @@ -122,7 +122,7 @@ questions it does not answer: also to ambiguities in parsing (note that some implementations put the heading inside the blockquote, while others do not). (John Gruber has also spoken [in favor of requiring the blank - lines](http://article.gmane.org/gmane.text.markdown.general/2146).) + lines](https://web.archive.org/web/20170611172104/http://article.gmane.org/gmane.text.markdown.general/2146).) 3. Is a blank line needed before an indented code block? (`Markdown.pl` requires it, but this is not mentioned in the @@ -155,7 +155,7 @@ questions it does not answer: ``` (There are some relevant comments by John Gruber - [here](http://article.gmane.org/gmane.text.markdown.general/2554).) + [here](https://web.archive.org/web/20170611172104/http://article.gmane.org/gmane.text.markdown.general/2554).) 5. Can list markers be indented? Can ordered list markers be right-aligned? @@ -316,9 +316,9 @@ A line containing no characters, or a line containing only spaces The following definitions of character classes will be used in this spec: -A [Unicode whitespace character](@) is -any code point in the Unicode `Zs` general category, or a tab (`U+0009`), -line feed (`U+000A`), form feed (`U+000C`), or carriage return (`U+000D`). +A [Unicode whitespace character](@) is a character in the Unicode `Zs` general +category, or a tab (`U+0009`), line feed (`U+000A`), form feed (`U+000C`), or +carriage return (`U+000D`). [Unicode whitespace](@) is a sequence of one or more [Unicode whitespace characters]. @@ -337,9 +337,8 @@ is `!`, `"`, `#`, `$`, `%`, `&`, `'`, `(`, `)`, `[`, `\`, `]`, `^`, `_`, `` ` `` (U+005B–0060), `{`, `|`, `}`, or `~` (U+007B–007E). -A [Unicode punctuation character](@) is an [ASCII -punctuation character] or anything in -the general Unicode categories `Pc`, `Pd`, `Pe`, `Pf`, `Pi`, `Po`, or `Ps`. +A [Unicode punctuation character](@) is a character in the Unicode `P` +(puncuation) or `S` (symbol) general categories. ## Tabs @@ -579,9 +578,9 @@ raw HTML: ```````````````````````````````` example - + . -

http://example.com?find=\*

+

https://example.com?find=\*

```````````````````````````````` @@ -1330,10 +1329,7 @@ interpretable as a [code fence], [ATX heading][ATX headings], A [setext heading underline](@) is a sequence of `=` characters or a sequence of `-` characters, with no more than 3 -spaces of indentation and any number of trailing spaces or tabs. If a line -containing a single `-` can be interpreted as an -empty [list items], it should be interpreted this way -and not as a [setext heading underline]. +spaces of indentation and any number of trailing spaces or tabs. The heading is a level 1 heading if `=` characters are used in the [setext heading underline], and a level 2 heading if `-` @@ -1967,7 +1963,7 @@ has been found, the code block contains all of the lines after the opening code fence until the end of the containing block (or document). (An alternative spec would require backtracking in the event that a closing code fence is not found. But this makes parsing -much less efficient, and there seems to be no real down side to the +much less efficient, and there seems to be no real downside to the behavior described here.) A fenced code block may interrupt a paragraph, and does not require @@ -2397,7 +2393,7 @@ followed by an ASCII letter.\ ``. -6. **Start condition:** line begins the string `<` or ``, or the string `/>`.\ @@ -4118,7 +4114,7 @@ The following rules define [list items]: blocks *Bs* starting with a character other than a space or tab, and *M* is a list marker of width *W* followed by 1 ≤ *N* ≤ 4 spaces of indentation, then the result of prepending *M* and the following spaces to the first line - of Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a + of *Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a list item with *Bs* as its contents. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start @@ -5353,11 +5349,11 @@ by itself should be a paragraph followed by a nested sublist. Since it is well established Markdown practice to allow lists to interrupt paragraphs inside list items, the [principle of uniformity] requires us to allow this outside list items as -well. ([reStructuredText](http://docutils.sourceforge.net/rst.html) +well. ([reStructuredText](https://docutils.sourceforge.net/rst.html) takes a different approach, requiring blank lines before lists even inside other list items.) -In order to solve of unwanted lists in paragraphs with +In order to solve the problem of unwanted lists in paragraphs with hard-wrapped numerals, we allow only lists starting with `1` to interrupt paragraphs. Thus, @@ -6058,18 +6054,18 @@ But this is an HTML tag: And this is code: ```````````````````````````````` example -`` +`` . -

<http://foo.bar.baz>`

+

<https://foo.bar.baz>`

```````````````````````````````` But this is an autolink: ```````````````````````````````` example -` +` . -

http://foo.bar.`baz`

+

https://foo.bar.`baz`

```````````````````````````````` @@ -6102,7 +6098,7 @@ closing backtick strings to be equal in length: ## Emphasis and strong emphasis John Gruber's original [Markdown syntax -description](http://daringfireball.net/projects/markdown/syntax#em) says: +description](https://daringfireball.net/projects/markdown/syntax#em) says: > Markdown treats asterisks (`*`) and underscores (`_`) as indicators of > emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML @@ -6204,7 +6200,7 @@ Here are some examples of delimiter runs. (The idea of distinguishing left-flanking and right-flanking delimiter runs based on the character before and the character after comes from Roopesh Chander's -[vfmd](http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags). +[vfmd](https://web.archive.org/web/20220608143320/http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags). vfmd uses the terminology "emphasis indicator string" instead of "delimiter run," and its rules for distinguishing left- and right-flanking runs are a bit more complex than the ones given here.) @@ -6346,6 +6342,21 @@ Unicode nonbreaking spaces count as whitespace, too: ```````````````````````````````` +Unicode symbols count as punctuation, too: + +```````````````````````````````` example +*$*alpha. + +*£*bravo. + +*€*charlie. +. +

*$*alpha.

+

*£*bravo.

+

*€*charlie.

+```````````````````````````````` + + Intraword emphasis with `*` is permitted: ```````````````````````````````` example @@ -7431,16 +7442,16 @@ _a `_`_ ```````````````````````````````` example -**a +**a . -

**ahttp://foo.bar/?q=**

+

**ahttps://foo.bar/?q=**

```````````````````````````````` ```````````````````````````````` example -__a +__a . -

__ahttp://foo.bar/?q=__

+

__ahttps://foo.bar/?q=__

```````````````````````````````` @@ -7688,13 +7699,13 @@ A link can contain fragment identifiers and queries: ```````````````````````````````` example [link](#fragment) -[link](http://example.com#fragment) +[link](https://example.com#fragment) -[link](http://example.com?foo=3#frag) +[link](https://example.com?foo=3#frag) .

link

-

link

-

link

+

link

+

link

```````````````````````````````` @@ -7938,9 +7949,9 @@ and autolinks over link grouping: ```````````````````````````````` example -[foo +[foo . -

[foohttp://example.com/?search=](uri)

+

[foohttps://example.com/?search=](uri)

```````````````````````````````` @@ -8094,11 +8105,11 @@ and autolinks over link grouping: ```````````````````````````````` example -[foo +[foo [ref]: /uri . -

[foohttp://example.com/?search=][ref]

+

[foohttps://example.com/?search=][ref]

```````````````````````````````` @@ -8298,7 +8309,7 @@ A [collapsed reference link](@) consists of a [link label] that [matches] a [link reference definition] elsewhere in the document, followed by the string `[]`. -The contents of the first link label are parsed as inlines, +The contents of the link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching reference link definition. Thus, `[foo][]` is equivalent to `[foo][foo]`. @@ -8351,7 +8362,7 @@ A [shortcut reference link](@) consists of a [link label] that [matches] a [link reference definition] elsewhere in the document and is not followed by `[]` or a link label. -The contents of the first link label are parsed as inlines, +The contents of the link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching link reference definition. Thus, `[foo]` is equivalent to `[foo][]`. @@ -8438,7 +8449,7 @@ following closing bracket: ```````````````````````````````` -Full and compact references take precedence over shortcut +Full and collapsed references take precedence over shortcut references: ```````````````````````````````` example @@ -8754,7 +8765,7 @@ a link to the URI, with the URI as the link's label. An [absolute URI](@), for these purposes, consists of a [scheme] followed by a colon (`:`) -followed by zero or more characters other [ASCII control +followed by zero or more characters other than [ASCII control characters][ASCII control character], [space], `<`, and `>`. If the URI includes these characters, they must be percent-encoded (e.g. `%20` for a space). @@ -8774,9 +8785,9 @@ Here are some valid autolinks: ```````````````````````````````` example - + . -

http://foo.bar.baz/test?q=hello&id=22&boolean

+

https://foo.bar.baz/test?q=hello&id=22&boolean

```````````````````````````````` @@ -8816,9 +8827,9 @@ with their syntax: ```````````````````````````````` example - + . -

http://../

+

https://../

```````````````````````````````` @@ -8832,18 +8843,18 @@ with their syntax: Spaces are not allowed in autolinks: ```````````````````````````````` example - + . -

<http://foo.bar/baz bim>

+

<https://foo.bar/baz bim>

```````````````````````````````` Backslash-escapes do not work inside autolinks: ```````````````````````````````` example - + . -

http://example.com/\[\

+

https://example.com/\[\

```````````````````````````````` @@ -8895,9 +8906,9 @@ These are not autolinks: ```````````````````````````````` example -< http://foo.bar > +< https://foo.bar > . -

< http://foo.bar >

+

< https://foo.bar >

```````````````````````````````` @@ -8916,9 +8927,9 @@ These are not autolinks: ```````````````````````````````` example -http://example.com +https://example.com . -

http://example.com

+

https://example.com

```````````````````````````````` @@ -8980,10 +8991,9 @@ A [closing tag](@) consists of the string ``. -An [HTML comment](@) consists of ``, -where *text* does not start with `>` or `->`, does not end with `-`, -and does not contain `--`. (See the -[HTML5 spec](http://www.w3.org/TR/html5/syntax.html#comments).) +An [HTML comment](@) consists of ``, ``, or ``, and `-->` (see the +[HTML spec](https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state)). A [processing instruction](@) consists of the string ` +foo . -

foo

+

foo

```````````````````````````````` - -```````````````````````````````` example -foo -. -

foo <!-- not a comment -- two hyphens -->

-```````````````````````````````` - - -Not comments: - ```````````````````````````````` example foo foo --> -foo +foo foo --> . -

foo <!--> foo -->

-

foo <!-- foo--->

+

foo foo -->

+

foo foo -->

```````````````````````````````` @@ -9674,7 +9674,7 @@ through the stack for an opening `[` or `![` delimiter. delimiter from the stack, and return a literal text node `]`. - If we find one and it's active, then we parse ahead to see if - we have an inline link/image, reference link/image, compact reference + we have an inline link/image, reference link/image, collapsed reference link/image, or shortcut reference link/image. + If we don't, then we remove the opening delimiter from the diff --git a/tests/test_cmark_spec/test_spec/test_file.html b/tests/test_cmark_spec/test_spec/test_file.html index 1c2dc3cb..60873533 100644 --- a/tests/test_cmark_spec/test_spec/test_file.html +++ b/tests/test_cmark_spec/test_spec/test_file.html @@ -1,9 +1,9 @@

title: CommonMark Spec author: John MacFarlane -version: 0.30 -date: '2021-06-19' -license: 'CC-BY-SA 4.0' +version: '0.31.2' +date: '2024-01-28' +license: 'CC-BY-SA 4.0' ...

Introduction

What is Markdown?

@@ -11,7 +11,7 @@

What is Markdown?

based on conventions for indicating formatting in email and usenet posts. It was developed by John Gruber (with help from Aaron Swartz) and released in 2004 in the form of a -syntax description +syntax description and a Perl script (Markdown.pl) for converting Markdown to HTML. In the next decade, dozens of implementations were developed in many languages. Some extended the original @@ -30,10 +30,10 @@

What is Markdown?

Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions. -(http://daringfireball.net/projects/markdown/)

+(https://daringfireball.net/projects/markdown/)

The point can be illustrated by comparing a sample of -AsciiDoc with +AsciiDoc with an equivalent sample of Markdown. Here is a sample of AsciiDoc from the AsciiDoc manual:

1. List item one.
@@ -91,7 +91,7 @@ 

What is Markdown?

to read. The nesting of list items is apparent to the eye in the source, not just in the processed document.

Why is a spec needed?

-

John Gruber's canonical description of Markdown's +

John Gruber's canonical description of Markdown's syntax does not specify the syntax unambiguously. Here are some examples of questions it does not answer:

@@ -103,7 +103,7 @@

Why is a spec needed?

they, too, must be indented four spaces, but Markdown.pl does not require that. This is hardly a "corner case," and divergences between implementations on this issue often lead to surprises for -users in real documents. (See this comment by John +users in real documents. (See this comment by John Gruber.)

  • @@ -112,7 +112,7 @@

    Why is a spec needed?

    this can lead to unexpected results in hard-wrapped text, and also to ambiguities in parsing (note that some implementations put the heading inside the blockquote, while others do not). -(John Gruber has also spoken in favor of requiring the blank +(John Gruber has also spoken in favor of requiring the blank lines.)

  • @@ -140,7 +140,7 @@

    Why is a spec needed?

    2. two
  • (There are some relevant comments by John Gruber -here.)

    +here.)

  • Can list markers be indented? Can ordered list markers be right-aligned?

    @@ -275,9 +275,9 @@

    Characters and lines

    A line containing no characters, or a line containing only spaces (U+0020) or tabs (U+0009), is called a blank line.

    The following definitions of character classes will be used in this spec:

    -

    A Unicode whitespace character is -any code point in the Unicode Zs general category, or a tab (U+0009), -line feed (U+000A), form feed (U+000C), or carriage return (U+000D).

    +

    A Unicode whitespace character is a character in the Unicode Zs general +category, or a tab (U+0009), line feed (U+000A), form feed (U+000C), or +carriage return (U+000D).

    Unicode whitespace is a sequence of one or more [Unicode whitespace characters].

    A tab is U+0009.

    @@ -290,9 +290,8 @@

    Characters and lines

    :, ;, <, =, >, ?, @ (U+003A–0040), [, \, ], ^, _, ` (U+005B–0060), {, |, }, or ~ (U+007B–007E).

    -

    A Unicode punctuation character is an [ASCII -punctuation character] or anything in -the general Unicode categories Pc, Pd, Pe, Pf, Pi, Po, or Ps.

    +

    A Unicode punctuation character is a character in the Unicode P +(puncuation) or S (symbol) general categories.

    Tabs

    Tabs in lines are not expanded to [spaces]. However, in contexts where spaces help to define block structure, @@ -467,9 +466,9 @@

    Backslash escapes

    <pre><code>\[\] </code></pre> -
    <http://example.com?find=\*>
    +
    <https://example.com?find=\*>
     .
    -<p><a href="http://example.com?find=%5C*">http://example.com?find=\*</a></p>
    +<p><a href="https://example.com?find=%5C*">https://example.com?find=\*</a></p>
     
    <a href="/bar\/)">
     .
    @@ -987,10 +986,7 @@ 

    Setext headings

    [list item][list items], or [HTML block][HTML blocks].

    A setext heading underline is a sequence of = characters or a sequence of - characters, with no more than 3 -spaces of indentation and any number of trailing spaces or tabs. If a line -containing a single - can be interpreted as an -empty [list items], it should be interpreted this way -and not as a [setext heading underline].

    +spaces of indentation and any number of trailing spaces or tabs.

    The heading is a level 1 heading if = characters are used in the [setext heading underline], and a level 2 heading if - characters are used. The contents of the heading are the result @@ -1461,7 +1457,7 @@

    Fenced code blocks

    opening code fence until the end of the containing block (or document). (An alternative spec would require backtracking in the event that a closing code fence is not found. But this makes parsing -much less efficient, and there seems to be no real down side to the +much less efficient, and there seems to be no real downside to the behavior described here.)

    A fenced code block may interrupt a paragraph, and does not require a blank line either before or after.

    @@ -1786,7 +1782,7 @@

    HTML blocks

    End condition: line contains the string ]]>.

  • -

    Start condition: line begins the string < or </ +

    Start condition: line begins with the string < or </ followed by one of the strings (case-insensitive) address, article, aside, base, basefont, blockquote, body, caption, center, col, colgroup, dd, details, dialog, @@ -1795,7 +1791,7 @@

    HTML blocks

    h1, h2, h3, h4, h5, h6, head, header, hr, html, iframe, legend, li, link, main, menu, menuitem, nav, noframes, ol, optgroup, option, p, param, -section, source, summary, table, tbody, td, +search, section, summary, table, tbody, td, tfoot, th, thead, title, tr, track, ul, followed by a space, a tab, the end of the line, the string >, or the string />.
    @@ -3085,7 +3081,7 @@

    List items

    blocks Bs starting with a character other than a space or tab, and M is a list marker of width W followed by 1 ≤ N ≤ 4 spaces of indentation, then the result of prepending M and the following spaces to the first line -of Ls*, and indenting subsequent lines of Ls by W + N spaces, is a +of Ls, and indenting subsequent lines of Ls by W + N spaces, is a list item with Bs as its contents. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start @@ -4081,10 +4077,10 @@

    Lists

    Since it is well established Markdown practice to allow lists to interrupt paragraphs inside list items, the [principle of uniformity] requires us to allow this outside list items as -well. (reStructuredText +well. (reStructuredText takes a different approach, requiring blank lines before lists even inside other list items.)

    -

    In order to solve of unwanted lists in paragraphs with +

    In order to solve the problem of unwanted lists in paragraphs with hard-wrapped numerals, we allow only lists starting with 1 to interrupt paragraphs. Thus,

    The number of windows in my house is
    @@ -4631,14 +4627,14 @@ 

    Code spans

    <p><a href="`">`</p>

    And this is code:

    -
    `<http://foo.bar.`baz>`
    +
    `<https://foo.bar.`baz>`
     .
    -<p><code>&lt;http://foo.bar.</code>baz&gt;`</p>
    +<p><code>&lt;https://foo.bar.</code>baz&gt;`</p>
     

    But this is an autolink:

    -
    <http://foo.bar.`baz>`
    +
    <https://foo.bar.`baz>`
     .
    -<p><a href="http://foo.bar.%60baz">http://foo.bar.`baz</a>`</p>
    +<p><a href="https://foo.bar.%60baz">https://foo.bar.`baz</a>`</p>
     

    When a backtick string is not closed by a matching backtick string, we just have literal backticks:

    @@ -4657,7 +4653,7 @@

    Code spans

    <p>`foo<code>bar</code></p>

    Emphasis and strong emphasis

    -

    John Gruber's original Markdown syntax +

    John Gruber's original Markdown syntax description says:

    Markdown treats asterisks (*) and underscores (_) as indicators of @@ -4744,7 +4740,7 @@

    Emphasis and strong emphasis

    (The idea of distinguishing left-flanking and right-flanking delimiter runs based on the character before and the character after comes from Roopesh Chander's -vfmd. +vfmd. vfmd uses the terminology "emphasis indicator string" instead of "delimiter run," and its rules for distinguishing left- and right-flanking runs are a bit more complex than the ones given here.)

    @@ -4887,6 +4883,17 @@

    Emphasis and strong emphasis

    . <p>* a *</p>
    +

    Unicode symbols count as punctuation, too:

    +
    *$*alpha.
    +
    +*£*bravo.
    +
    +*€*charlie.
    +.
    +<p>*$*alpha.</p>
    +<p>*£*bravo.</p>
    +<p>*€*charlie.</p>
    +

    Intraword emphasis with * is permitted:

    foo*bar*
     .
    @@ -5521,13 +5528,13 @@ 

    Emphasis and strong emphasis

    . <p><em>a <code>_</code></em></p>
    -
    **a<http://foo.bar/?q=**>
    +
    **a<https://foo.bar/?q=**>
     .
    -<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p>
    +<p>**a<a href="https://foo.bar/?q=**">https://foo.bar/?q=**</a></p>
     
    -
    __a<http://foo.bar/?q=__>
    +
    __a<https://foo.bar/?q=__>
     .
    -<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p>
    +<p>__a<a href="https://foo.bar/?q=__">https://foo.bar/?q=__</a></p>
     

    Links

    A link contains [link text] (the visible text), a [link destination] @@ -5720,13 +5727,13 @@

    Links

    A link can contain fragment identifiers and queries:

    [link](#fragment)
     
    -[link](http://example.com#fragment)
    +[link](https://example.com#fragment)
     
    -[link](http://example.com?foo=3#frag)
    +[link](https://example.com?foo=3#frag)
     .
     <p><a href="#fragment">link</a></p>
    -<p><a href="http://example.com#fragment">link</a></p>
    -<p><a href="http://example.com?foo=3#frag">link</a></p>
    +<p><a href="https://example.com#fragment">link</a></p>
    +<p><a href="https://example.com?foo=3#frag">link</a></p>
     

    Note that a backslash before a non-escapable character is just a backslash:

    @@ -5878,9 +5885,9 @@

    Links

    . <p>[foo<code>](/uri)</code></p>
    -
    [foo<http://example.com/?search=](uri)>
    +
    [foo<https://example.com/?search=](uri)>
     .
    -<p>[foo<a href="http://example.com/?search=%5D(uri)">http://example.com/?search=](uri)</a></p>
    +<p>[foo<a href="https://example.com/?search=%5D(uri)">https://example.com/?search=](uri)</a></p>
     

    There are three kinds of reference links: full, collapsed, @@ -5985,11 +5992,11 @@

    Links

    . <p>[foo<code>][ref]</code></p>
    -
    [foo<http://example.com/?search=][ref]>
    +
    [foo<https://example.com/?search=][ref]>
     
     [ref]: /uri
     .
    -<p>[foo<a href="http://example.com/?search=%5D%5Bref%5D">http://example.com/?search=][ref]</a></p>
    +<p>[foo<a href="https://example.com/?search=%5D%5Bref%5D">https://example.com/?search=][ref]</a></p>
     

    Matching is case-insensitive:

    [foo][BaR]
    @@ -6132,7 +6139,7 @@ 

    Links

    consists of a [link label] that [matches] a [link reference definition] elsewhere in the document, followed by the string []. -The contents of the first link label are parsed as inlines, +The contents of the link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching reference link definition. Thus, [foo][] is equivalent to [foo][foo].

    @@ -6169,7 +6176,7 @@

    Links

    consists of a [link label] that [matches] a [link reference definition] elsewhere in the document and is not followed by [] or a link label. -The contents of the first link label are parsed as inlines, +The contents of the link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching link reference definition. Thus, [foo] is equivalent to [foo][].

    @@ -6227,7 +6234,7 @@

    Links

    . <p>*<a href="/url">foo*</a></p>
    -

    Full and compact references take precedence over shortcut +

    Full and collapsed references take precedence over shortcut references:

    [foo][bar]
     
    @@ -6438,7 +6445,7 @@ 

    Autolinks

    a link to the URI, with the URI as the link's label.

    An absolute URI, for these purposes, consists of a [scheme] followed by a colon (:) -followed by zero or more characters other [ASCII control +followed by zero or more characters other than [ASCII control characters][ASCII control character], [space], <, and >. If the URI includes these characters, they must be percent-encoded (e.g. %20 for a space).

    @@ -6451,9 +6458,9 @@

    Autolinks

    . <p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p>
    -
    <http://foo.bar.baz/test?q=hello&id=22&boolean>
    +
    <https://foo.bar.baz/test?q=hello&id=22&boolean>
     .
    -<p><a href="http://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean">http://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean</a></p>
    +<p><a href="https://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean">https://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean</a></p>
     
    <irc://foo.bar:2233/baz>
     .
    @@ -6476,23 +6483,23 @@ 

    Autolinks

    . <p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p>
    -
    <http://../>
    +
    <https://../>
     .
    -<p><a href="http://../">http://../</a></p>
    +<p><a href="https://../">https://../</a></p>
     
    <localhost:5001/foo>
     .
     <p><a href="localhost:5001/foo">localhost:5001/foo</a></p>
     

    Spaces are not allowed in autolinks:

    -
    <http://foo.bar/baz bim>
    +
    <https://foo.bar/baz bim>
     .
    -<p>&lt;http://foo.bar/baz bim&gt;</p>
    +<p>&lt;https://foo.bar/baz bim&gt;</p>
     

    Backslash-escapes do not work inside autolinks:

    -
    <http://example.com/\[\>
    +
    <https://example.com/\[\>
     .
    -<p><a href="http://example.com/%5C%5B%5C">http://example.com/\[\</a></p>
    +<p><a href="https://example.com/%5C%5B%5C">https://example.com/\[\</a></p>
     

    An email autolink consists of <, followed by an [email address], @@ -6524,9 +6531,9 @@

    Autolinks

    . <p>&lt;&gt;</p>
    -
    < http://foo.bar >
    +
    < https://foo.bar >
     .
    -<p>&lt; http://foo.bar &gt;</p>
    +<p>&lt; https://foo.bar &gt;</p>
     
    <m:abc>
     .
    @@ -6536,9 +6543,9 @@ 

    Autolinks

    . <p>&lt;foo.bar.baz&gt;</p>
    -
    http://example.com
    +
    https://example.com
     .
    -<p>http://example.com</p>
    +<p>https://example.com</p>
     
    foo@bar.example.com
     .
    @@ -6582,10 +6589,9 @@ 

    Raw HTML

    A closing tag consists of the string </, a [tag name], optional spaces, tabs, and up to one line ending, and the character >.

    -

    An HTML comment consists of <!-- + text + -->, -where text does not start with > or ->, does not end with -, -and does not contain --. (See the -HTML5 spec.)

    +

    An HTML comment consists of <!-->, <!--->, or <!--, a string of +characters not including the string -->, and --> (see the +HTML spec).

    A processing instruction consists of the string <?, a string of characters not including the string ?>, and the string @@ -6669,23 +6675,18 @@

    Raw HTML

    <p>&lt;/a href=&quot;foo&quot;&gt;</p>

    Comments:

    -
    foo <!-- this is a
    -comment - with hyphen -->
    -.
    -<p>foo <!-- this is a
    -comment - with hyphen --></p>
    -
    -
    foo <!-- not a comment -- two hyphens -->
    +
    foo <!-- this is a --
    +comment - with hyphens -->
     .
    -<p>foo &lt;!-- not a comment -- two hyphens --&gt;</p>
    +<p>foo <!-- this is a --
    +comment - with hyphens --></p>
     
    -

    Not comments:

    foo <!--> foo -->
     
    -foo <!-- foo--->
    +foo <!---> foo -->
     .
    -<p>foo &lt;!--&gt; foo --&gt;</p>
    -<p>foo &lt;!-- foo---&gt;</p>
    +<p>foo <!--> foo --&gt;</p>
    +<p>foo <!---> foo --&gt;</p>
     

    Processing instructions:

    foo <?php echo $a; ?>
    @@ -7069,7 +7070,7 @@ 

    look for link or image

  • If we find one and it's active, then we parse ahead to see if -we have an inline link/image, reference link/image, compact reference +we have an inline link/image, reference link/image, collapsed reference link/image, or shortcut reference link/image.