pax_global_header00006660000000000000000000000064145056621260014521gustar00rootroot0000000000000052 comment=f997c86335d8a5d8435aac08b66ed3cba9381b51 mistune-3.0.2/000077500000000000000000000000001450566212600132075ustar00rootroot00000000000000mistune-3.0.2/.github/000077500000000000000000000000001450566212600145475ustar00rootroot00000000000000mistune-3.0.2/.github/FUNDING.yml000066400000000000000000000003741450566212600163700ustar00rootroot00000000000000# These are supported funding model platforms github: [lepture] patreon: lepture open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: pypi/mistune custom: https://lepture.com/donate mistune-3.0.2/.github/workflows/000077500000000000000000000000001450566212600166045ustar00rootroot00000000000000mistune-3.0.2/.github/workflows/pypi.yml000066400000000000000000000024711450566212600203140ustar00rootroot00000000000000name: Release to PyPI permissions: contents: write on: push: tags: - "v*" jobs: build: name: build dist files runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: 3.9 - name: install build run: python -m pip install --upgrade build - name: build dist run: python -m build - uses: actions/upload-artifact@v3 with: name: artifacts path: dist/* if-no-files-found: error publish: environment: name: pypi-release name: release to pypi needs: build runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v3 with: name: artifacts path: dist - name: Push build artifacts to PyPI uses: pypa/gh-action-pypi-publish@v1.6.4 with: skip_existing: true user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} release: name: write release note runs-on: ubuntu-latest needs: publish steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 with: node-version: 18 - run: npx changelogithub --no-group continue-on-error: true env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} mistune-3.0.2/.github/workflows/tests.yml000066400000000000000000000021461450566212600204740ustar00rootroot00000000000000name: Run tests on: push: branches-ignore: - 'wip-*' paths-ignore: - 'docs/**' pull_request: branches-ignore: - 'wip-*' paths-ignore: - 'docs/**' jobs: build: runs-on: ubuntu-latest strategy: fail-fast: false max-parallel: 6 matrix: os: [ubuntu-latest, macos-latest, windows-latest] python: ["3.8", "3.9", "3.10", "3.11", "pypy3.9"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python }} on ${{ matrix.os }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest pytest-cov - name: Test with Python ${{ matrix.python }} on ${{ matrix.os }} run: pytest - name: Report coverage run: pytest --cov=mistune --cov-report=xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml flags: unittests name: GitHub mistune-3.0.2/.gitignore000066400000000000000000000003241450566212600151760ustar00rootroot00000000000000*.pyc *.pyo *.egg-info .idea __pycache__ bin build develop-eggs dist eggs parts .DS_Store .installed.cfg docs/_build cover/ .tox *.bak *.c *.so .venv/ .python-version .coverage htmlcov .eggs coverage.xml demo.py mistune-3.0.2/.readthedocs.yaml000066400000000000000000000003111450566212600164310ustar00rootroot00000000000000version: 2 build: os: "ubuntu-20.04" tools: python: "3.10" sphinx: configuration: docs/conf.py python: install: - requirements: docs/requirements.txt - method: pip path: . mistune-3.0.2/BACKERS.md000066400000000000000000000013361450566212600146060ustar00rootroot00000000000000# Sponsors and Backers Many thanks to these awesome sponsors and backers. [Support Me via GitHub Sponsors](https://github.com/sponsors/lepture) ## Sponsors
Mistune is sponsored by Typlog, a blogging and podcast hosting platform, simple yet powerful. Write in Markdown.
## Awesome Backers
Hyunwoo Park
Hyunwoo Park
mistune-3.0.2/LICENSE000066400000000000000000000027031450566212600142160ustar00rootroot00000000000000Copyright (c) 2014, Hsiaoming Yang All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the creator nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mistune-3.0.2/MANIFEST.in000066400000000000000000000003371450566212600147500ustar00rootroot00000000000000# include all test files but avoid including .pyc recursive-include benchmark *.py *.txt recursive-include tests *.json *.html *.md *.py *.txt # include documentation sources but not built docs graft docs prune docs/_build mistune-3.0.2/Makefile000066400000000000000000000005751450566212600146560ustar00rootroot00000000000000.PHONY: clean-pyc clean-build build-docs clean: clean-build clean-pyc clean-build: @rm -fr build/ @rm -fr dist/ @rm -fr *.egg-info @rm -fr .coverage clean-pyc: @find . -name '*.pyc' -exec rm -f {} + @find . -name '*.pyo' -exec rm -f {} + @find . -name '*~' -exec rm -f {} + @find . -name '__pycache__' -exec rm -fr {} + build-docs: @sphinx-build docs build/_html -a mistune-3.0.2/README.md000066400000000000000000000171141450566212600144720ustar00rootroot00000000000000# Mistune v3 A fast yet powerful Python Markdown parser with renderers and plugins. Coverage **NOTE: This is the re-designed v3 of mistune.** Looking for old Mistune? Switch branch to: - v1 - v2 ## Paid plugins You can ask me to create a custom mistune plugin or directive for your needs with GitHub sponsor [one time tier (Mistune enhance)](https://github.com/sponsors/lepture/sponsorships?tier_id=220664) ## Sponsors
Mistune is sponsored by Typlog, a blogging and podcast hosting platform, simple yet powerful. Write in Markdown.
[**Support Me via GitHub Sponsors**](https://github.com/sponsors/lepture). ## Install To install mistune: ``` $ pip install mistune ``` ## Overview Convert Markdown to HTML with ease: ```python import mistune mistune.html(your_markdown_text) ``` ## Security Reporting If you found security bugs, please do not send a public issue or patch. You can send me email at . Attachment with patch is welcome. My PGP Key fingerprint is: ``` 72F8 E895 A70C EBDF 4F2A DFE0 7E55 E3E0 118B 2B4C ``` Or, you can use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. ## Benchmarks Here is the benchmark score on my computer. Check the `benchmark/bench.py` script. ``` mistune (3.0.0) - axt: 13.901472091674805ms mistune (slow) - axt: 13.122797012329102ms mistune (fast) - axt: 13.248443603515625ms mistune (full) - axt: 15.445232391357422ms markdown (3.3.7) - axt: 48.41303825378418ms markdown2 (2.4.3) - axt: 379.30870056152344ms mistletoe (0.8.2) - axt: 25.46215057373047ms markdown_it (2.1.0) - axt: 42.37723350524902ms mistune (3.0.0) - setext: 8.43048095703125ms mistune (slow) - setext: 8.97979736328125ms mistune (fast) - setext: 8.122920989990234ms mistune (full) - setext: 9.525299072265625ms markdown (3.3.7) - setext: 30.74812889099121ms markdown2 (2.4.3) - setext: 218.90878677368164ms mistletoe (0.8.2) - setext: 20.46680450439453ms markdown_it (2.1.0) - setext: 27.010202407836914ms mistune (3.0.0) - normal_ul: 60.910940170288086ms mistune (slow) - normal_ul: 59.69667434692383ms mistune (fast) - normal_ul: 60.41216850280762ms mistune (full) - normal_ul: 62.89219856262207ms markdown (3.3.7) - normal_ul: 83.7857723236084ms markdown2 (2.4.3) - normal_ul: 175.36139488220215ms mistletoe (0.8.2) - normal_ul: 74.82385635375977ms markdown_it (2.1.0) - normal_ul: 103.0113697052002ms mistune (3.0.0) - insane_ul: 104.1865348815918ms mistune (slow) - insane_ul: 105.83090782165527ms mistune (fast) - insane_ul: 103.03664207458496ms mistune (full) - insane_ul: 105.80086708068848ms markdown (3.3.7) - insane_ul: 133.82673263549805ms markdown2 (2.4.3) - insane_ul: 337.23902702331543ms mistletoe (0.8.2) - insane_ul: 122.10249900817871ms markdown_it (2.1.0) - insane_ul: 85.92629432678223ms mistune (3.0.0) - normal_ol: 25.092601776123047ms mistune (slow) - normal_ol: 25.321483612060547ms mistune (fast) - normal_ol: 25.11453628540039ms mistune (full) - normal_ol: 25.945663452148438ms markdown (3.3.7) - normal_ol: 43.30158233642578ms markdown2 (2.4.3) - normal_ol: 75.87885856628418ms mistletoe (0.8.2) - normal_ol: 33.63537788391113ms markdown_it (2.1.0) - normal_ol: 40.307044982910156ms mistune (3.0.0) - insane_ol: 46.201229095458984ms mistune (slow) - insane_ol: 49.14569854736328ms mistune (fast) - insane_ol: 45.96853256225586ms mistune (full) - insane_ol: 47.544002532958984ms markdown (3.3.7) - insane_ol: 50.154924392700195ms markdown2 (2.4.3) - insane_ol: 210.48712730407715ms mistletoe (0.8.2) - insane_ol: 84.07974243164062ms markdown_it (2.1.0) - insane_ol: 83.61554145812988ms mistune (3.0.0) - blockquote: 15.484809875488281ms mistune (slow) - blockquote: 16.12544059753418ms mistune (fast) - blockquote: 15.350818634033203ms mistune (full) - blockquote: 16.104936599731445ms markdown (3.3.7) - blockquote: 63.04144859313965ms markdown2 (2.4.3) - blockquote: 702.4445533752441ms mistletoe (0.8.2) - blockquote: 28.56159210205078ms markdown_it (2.1.0) - blockquote: 37.35041618347168ms mistune (3.0.0) - blockhtml: 7.898569107055664ms mistune (slow) - blockhtml: 7.080316543579102ms mistune (fast) - blockhtml: 7.414340972900391ms mistune (full) - blockhtml: 8.559703826904297ms markdown (3.3.7) - blockhtml: 46.65660858154297ms markdown2 (2.4.3) - blockhtml: 122.09773063659668ms mistletoe (0.8.2) - blockhtml: 12.23611831665039ms markdown_it (2.1.0) - blockhtml: 26.836156845092773ms mistune (3.0.0) - fenced: 4.281282424926758ms mistune (slow) - fenced: 4.092931747436523ms mistune (fast) - fenced: 4.024267196655273ms mistune (full) - fenced: 4.453897476196289ms markdown (3.3.7) - fenced: 33.83779525756836ms markdown2 (2.4.3) - fenced: 92.49091148376465ms mistletoe (0.8.2) - fenced: 9.19342041015625ms markdown_it (2.1.0) - fenced: 12.503623962402344ms mistune (3.0.0) - paragraph: 95.94106674194336ms mistune (slow) - paragraph: 561.2788200378418ms mistune (fast) - paragraph: 93.597412109375ms mistune (full) - paragraph: 110.09836196899414ms markdown (3.3.7) - paragraph: 304.1346073150635ms markdown2 (2.4.3) - paragraph: 267.84825325012207ms mistletoe (0.8.2) - paragraph: 779.3235778808594ms markdown_it (2.1.0) - paragraph: 825.5178928375244ms mistune (3.0.0) - emphasis: 23.591041564941406ms mistune (slow) - emphasis: 16.934871673583984ms mistune (fast) - emphasis: 23.232460021972656ms mistune (full) - emphasis: 25.2840518951416ms markdown (3.3.7) - emphasis: 76.50399208068848ms markdown2 (2.4.3) - emphasis: 9.393930435180664ms mistletoe (0.8.2) - emphasis: 33.68663787841797ms markdown_it (2.1.0) - emphasis: 60.90521812438965ms mistune (3.0.0) - auto_links: 3.7980079650878906ms mistune (slow) - auto_links: 3.3910274505615234ms mistune (fast) - auto_links: 3.6630630493164062ms mistune (full) - auto_links: 3.9186477661132812ms markdown (3.3.7) - auto_links: 23.04673194885254ms markdown2 (2.4.3) - auto_links: 6.537914276123047ms mistletoe (0.8.2) - auto_links: 8.360624313354492ms markdown_it (2.1.0) - auto_links: 19.732236862182617ms mistune (3.0.0) - std_links: 21.920442581176758ms mistune (slow) - std_links: 17.487764358520508ms mistune (fast) - std_links: 19.87743377685547ms mistune (full) - std_links: 24.514198303222656ms markdown (3.3.7) - std_links: 39.1237735748291ms markdown2 (2.4.3) - std_links: 14.519691467285156ms mistletoe (0.8.2) - std_links: 22.84979820251465ms markdown_it (2.1.0) - std_links: 32.60660171508789ms mistune (3.0.0) - ref_links: 47.673940658569336ms mistune (slow) - ref_links: 39.449214935302734ms mistune (fast) - ref_links: 44.81911659240723ms mistune (full) - ref_links: 52.37579345703125ms markdown (3.3.7) - ref_links: 87.65625953674316ms markdown2 (2.4.3) - ref_links: 23.118972778320312ms mistletoe (0.8.2) - ref_links: 59.136390686035156ms markdown_it (2.1.0) - ref_links: 80.44648170471191ms mistune (3.0.0) - readme: 56.607723236083984ms mistune (slow) - readme: 68.8173770904541ms mistune (fast) - readme: 53.86018753051758ms mistune (full) - readme: 61.25998497009277ms markdown (3.3.7) - readme: 211.02523803710938ms markdown2 (2.4.3) - readme: 533.4112644195557ms mistletoe (0.8.2) - readme: 110.12959480285645ms markdown_it (2.1.0) - readme: 247.9879856109619ms ``` ## License Mistune is licensed under BSD. Please see LICENSE for licensing details. mistune-3.0.2/README.rst000066400000000000000000000006621450566212600147020ustar00rootroot00000000000000Mistune v3 ========== A fast yet powerful Python Markdown parser with renderers and plugins. Overview -------- Convert Markdown to HTML with ease: .. code-block:: python import mistune mistune.html(your_markdown_text) Useful Links ------------ 1. GitHub: https://github.com/lepture/mistune 2. Docs: https://mistune.lepture.com/ License ------- Mistune is licensed under BSD. Please see LICENSE for licensing details. mistune-3.0.2/benchmark/000077500000000000000000000000001450566212600151415ustar00rootroot00000000000000mistune-3.0.2/benchmark/bench.py000066400000000000000000000062221450566212600165740ustar00rootroot00000000000000import os import sys import time ROOT_DIR = os.path.dirname(__file__) sys.path.insert(0, os.path.join(ROOT_DIR, '..')) CASES = {} def load_case(filename): if filename == 'readme.txt': filepath = os.path.join(ROOT_DIR, '../README.md') else: filepath = os.path.join(ROOT_DIR, 'cases', filename) with open(filepath, 'r') as f: content = f.read() name = filename.replace('.txt', '') CASES[name] = content return content def run_case(method, content, count=100): # ignore first trigger method(content) start = time.time() while count > 0: method(content) count -= 1 duration = time.time() - start return duration * 1000 def get_markdown_parsers(): parsers = {} import mistune from mistune.directives import ( RSTDirective, Admonition, TableOfContents, Include, ) parsers[f'mistune ({mistune.__version__})'] = mistune.html parsers[f'mistune (slow)'] = mistune.create_markdown(escape=False) parsers[f'mistune (fast)'] = mistune.create_markdown( escape=False, plugins=['speedup']) parsers['mistune (full)'] = mistune.create_markdown( escape=False, plugins=[ 'url', 'abbr', 'ruby', 'strikethrough', 'mark', 'insert', 'subscript', 'superscript', 'footnotes', 'def_list', 'math', 'table', 'task_lists', RSTDirective([ Admonition(), TableOfContents(), Include(), ]), 'speedup', ], ) try: import mistune_v1 parsers[f'mistune ({mistune_v1.__version__})'] = mistune_v1.markdown except ImportError: pass try: import markdown parsers[f'markdown ({markdown.__version__})'] = markdown.markdown except ImportError: pass try: from markdown2 import Markdown, __version__ as m2v markdowner = Markdown() parsers[f'markdown2 ({m2v})'] = markdowner.convert except ImportError: pass try: import mistletoe parsers[f'mistletoe ({mistletoe.__version__})'] = mistletoe.markdown except ImportError: pass try: from markdown_it import MarkdownIt, __version__ as mitv md = MarkdownIt() parsers[f'markdown_it ({mitv})'] = md.render except ImportError: pass return parsers def benchmarks(cases, count=100): methods = get_markdown_parsers() for name in cases: content = load_case(name + '.txt') for md_name in methods: func = methods[md_name] duration = run_case(func, content, count) print(f'{md_name} - {name}: {duration}ms') if __name__ == '__main__': cases = [ # block 'axt', 'setext', 'normal_ul', 'insane_ul', 'normal_ol', 'insane_ol', 'blockquote', 'blockhtml', 'fenced', 'paragraph', # inline 'emphasis', 'auto_links', 'std_links', 'ref_links', 'readme', ] if len(sys.argv) > 1: benchmarks(sys.argv[1:]) else: benchmarks(cases) mistune-3.0.2/benchmark/cases/000077500000000000000000000000001450566212600162375ustar00rootroot00000000000000mistune-3.0.2/benchmark/cases/auto_links.txt000066400000000000000000000000761450566212600211530ustar00rootroot00000000000000 mistune-3.0.2/benchmark/cases/axt.txt000066400000000000000000000003721450566212600175760ustar00rootroot00000000000000# h1 heading ## h2 heading ### h3 heading #### h4 heading ##### h5 heading ###### h6 heading ####### not heading ###### h6 heading ###### ##### h5 heading ##### #### h4 heading #### ### h3 heading ### ## h2 heading ## # h1 heading # # #not heading mistune-3.0.2/benchmark/cases/blockcode.txt000066400000000000000000000000001450566212600207130ustar00rootroot00000000000000mistune-3.0.2/benchmark/cases/blockhtml.txt000066400000000000000000000004161450566212600207600ustar00rootroot00000000000000
foo **not bold** baz
foo **is bold** baz
pre tag contains blank lines

this is still in pre
mistune-3.0.2/benchmark/cases/blockquote.txt000066400000000000000000000002231450566212600211450ustar00rootroot00000000000000> Block quote content > > Block quote paragraph > Second block quote > > Nested block quote > > > > > > > > > > > > > > > > > > > > > Block quote mistune-3.0.2/benchmark/cases/emphasis.txt000066400000000000000000000002761450566212600206160ustar00rootroot00000000000000case for emphasis: **bold** __bold__ *italic* _italic_, **bold and *italic***, **bold *italic* and __bold__**. ______________foo______________ and *********bar********* **__**__bold__**__** mistune-3.0.2/benchmark/cases/fenced.txt000066400000000000000000000003631450566212600202260ustar00rootroot00000000000000``` function foo() { return 'foo' } ``` ```js function foo() { return 'foo' } ``` ~~~python def foo(): return 'foo' ~~~ ~~~python filename=foo.py def foo(): return 'foo' ~~~ ```` ``` function foo() { return 'foo' } ``` ```` mistune-3.0.2/benchmark/cases/insane_ol.txt000066400000000000000000000007621450566212600207540ustar00rootroot000000000000001. List Item 2. List Item 3) List Item 3. List Item 5) List Item - List Item List Item 2. List Item 3. List Item 4. List Item 5. List Item 6. List Item 7. List Item 8. List Item 9. List Item 10. List Item 11. List Item 6) List Item 1. New list 2. Loose item 10) List Item List Item List Item List Item mistune-3.0.2/benchmark/cases/insane_ul.txt000066400000000000000000000012401450566212600207520ustar00rootroot00000000000000- List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item - Loose List Item Loose paragraph - List Item - List Item - List Item + List Item - List Item - List Item - List Item * List Item List Item List Item List Item mistune-3.0.2/benchmark/cases/normal_ol.txt000066400000000000000000000002171450566212600207620ustar00rootroot000000000000001. List Item 2. List Item 3) List Item 3. List Item 1) New list 2) Loose item 10. List Item List Item List Item List Item mistune-3.0.2/benchmark/cases/normal_ul.txt000066400000000000000000000004711450566212600207720ustar00rootroot00000000000000- List Item - List Item - List Item - List Item - List Item - List Item - List Item - List Item + List Item - List Item - List Item - List Item * List Item List Item List Item List Item * List Item List Item List Item List Item * List Item List Item List Item List Item mistune-3.0.2/benchmark/cases/paragraph.txt000066400000000000000000000356571450566212600207650ustar00rootroot00000000000000Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eget quam egestas, gravida quam sed, faucibus turpis. Curabitur commodo sit amet arcu vitae hendrerit. Curabitur posuere quis nisi a lobortis. Maecenas consectetur neque ut sem pulvinar tincidunt. Etiam mattis ligula at quam varius, vel laoreet diam interdum. Proin vel tempus arcu, venenatis facilisis diam. Praesent justo sapien, mattis in tempus et, luctus fermentum mi. Proin mattis felis eget augue mollis aliquet. Donec bibendum sem orci, a maximus nisi molestie in. Vestibulum et varius nisl, a sodales ligula. Curabitur gravida massa vel enim facilisis, id dapibus mauris tincidunt. Morbi pretium velit velit, vel accumsan lacus malesuada et. Vivamus massa elit, feugiat at aliquet ac, eleifend eget dui. Donec hendrerit metus elementum augue gravida posuere. Quisque convallis egestas augue. Fusce vel pulvinar dui. Sed tincidunt felis nec placerat feugiat. Fusce laoreet ligula a ipsum suscipit, id vehicula tortor scelerisque. Sed placerat est massa, sit amet egestas magna interdum in. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Ut eget pretium felis. Fusce rhoncus fringilla ipsum, sed varius ante placerat nec. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin a maximus massa. Vestibulum placerat urna quis venenatis ullamcorper. Morbi finibus imperdiet ligula ac feugiat. Fusce consectetur gravida leo id efficitur. Suspendisse potenti. Vivamus pellentesque turpis a erat sodales venenatis vel quis justo. Ut vitae viverra dui. Quisque non sagittis lectus. Nunc libero nisi, fermentum vitae imperdiet vel, pulvinar ut augue. Maecenas at magna vel dolor tempor luctus. Etiam consectetur est eu tortor luctus tristique. Aliquam rhoncus enim non felis feugiat gravida. Suspendisse eget lorem hendrerit, pellentesque dolor et, scelerisque nisl. Donec sit amet lacus a tellus mattis pretium. Sed urna lectus, gravida sed est vel, molestie luctus neque. Phasellus finibus tempor odio. Nunc ullamcorper dui at nunc sodales sagittis. In mattis dolor vitae sem efficitur, vel auctor ipsum suscipit. Mauris nec orci non justo facilisis posuere. Sed id tortor vel est elementum pellentesque non luctus lectus. Proin at quam non turpis dapibus dapibus ac nec felis. Phasellus sapien nisi, pulvinar sit amet aliquam ac, imperdiet vel leo. Nunc a nisi massa. Aenean ultricies sed dui id dapibus. Sed sit amet risus et nisl mattis consequat. Praesent semper orci eget sem imperdiet cursus. Donec fringilla convallis turpis, in sodales metus elementum dignissim. Nunc eu cursus elit. Sed malesuada, velit hendrerit volutpat varius, leo metus tristique quam, a imperdiet nunc urna a purus. Donec id tristique quam, dictum egestas ligula. Morbi varius suscipit bibendum. Etiam id diam tempor magna finibus viverra. Duis auctor interdum lorem, eget porttitor turpis. Pellentesque at malesuada eros. Vestibulum efficitur eget neque sit amet posuere. Ut est leo, ullamcorper efficitur lobortis sit amet, facilisis ut purus. Cras hendrerit eu erat vitae dignissim. Aenean et pharetra lectus. Etiam sed elementum lectus, ut interdum ligula. Nunc egestas nulla posuere, feugiat leo non, condimentum eros. Fusce scelerisque turpis lacus, a dapibus diam mattis ut. Quisque vestibulum laoreet libero, in lobortis felis ultrices id. Vivamus id tellus efficitur, porta purus at, consequat magna. Donec dapibus justo dolor. Aliquam erat volutpat. Aenean at tortor libero. Suspendisse pharetra mi urna, a accumsan mi placerat et. Proin accumsan, nunc id tristique auctor, magna leo rhoncus nisl, at commodo sem lorem et lectus. Integer massa dolor, fringilla at enim et, blandit imperdiet purus. Phasellus sit amet leo at dolor ornare ultricies. Etiam a convallis velit. Proin auctor, sem non lacinia luctus, purus metus luctus ipsum, aliquet placerat arcu felis a erat. Cras et consequat leo, sagittis ultrices sem. Nullam egestas ipsum eget porttitor tempus. Ut laoreet non lectus quis imperdiet. Duis tempus in magna eget ornare. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur a sagittis justo, et suscipit nibh. Proin sed lorem lacinia, efficitur quam sed, imperdiet felis. Morbi in condimentum arcu. Sed sodales vehicula nunc, vitae mollis ipsum faucibus ut. Suspendisse ornare efficitur turpis, non placerat nisl aliquet et. Aliquam aliquam, justo eu tincidunt ornare, nisi elit tempor velit, placerat pulvinar erat tortor vehicula erat. Nam euismod turpis eu congue pulvinar. Pellentesque fringilla sapien ac mauris efficitur viverra. Suspendisse hendrerit leo et erat condimentum sagittis. Ut lacinia mattis pharetra. Ut semper lacinia tristique. Nullam fermentum nunc in erat interdum interdum. Pellentesque fringilla, purus nec commodo elementum, nulla arcu elementum diam, vel aliquam est ante in dolor. Integer vel elit posuere, commodo felis non, aliquet diam. Duis cursus enim at metus sodales ultricies. Mauris ultricies id elit eget elementum. Aenean elementum nisi quis vehicula placerat. Morbi lobortis, neque quis lobortis vehicula, arcu nisi blandit elit, eget rhoncus orci mauris a massa. Donec a purus bibendum, vulputate tortor id, bibendum metus. Donec eget sagittis sem. Maecenas metus ex, cursus a mollis a, imperdiet sed felis. Integer gravida, lacus eget posuere laoreet, velit dui tincidunt turpis, vel hendrerit sem massa iaculis odio. Proin a metus fringilla, ullamcorper nisl nec, imperdiet massa. Maecenas sollicitudin egestas varius. Nulla dictum, nunc ut venenatis ornare, mi nibh viverra leo, a aliquam tellus velit ac erat. Nulla eget faucibus urna. Phasellus sit amet neque quis est finibus elementum. In hac habitasse platea dictumst. Quisque ultricies, orci vel bibendum venenatis, nibh nisl iaculis ipsum, sit amet interdum tortor neque non urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque convallis in nibh sit amet pulvinar. Vivamus sed orci magna. Quisque fermentum leo nunc, sit amet fringilla lacus ultrices consectetur. Nulla ullamcorper interdum aliquam. Nunc sagittis lectus eget mauris molestie consectetur. Vivamus et imperdiet tortor. Fusce faucibus velit quis rutrum tincidunt. Quisque consectetur blandit massa a facilisis. Phasellus faucibus dui eu pretium laoreet. Nullam scelerisque pulvinar ante quis elementum. Curabitur placerat sem eu neque fringilla interdum. Aliquam metus purus, vulputate ut augue vel, aliquam interdum risus. Cras a lacus et nulla feugiat vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sagittis dui enim, et dictum erat ornare in. Donec fringilla placerat ipsum, et viverra metus tincidunt et. Duis vestibulum elit pharetra mauris mattis tempor. Maecenas a finibus tortor. Nullam sed massa ac velit lacinia rutrum quis non purus. Vestibulum neque odio, accumsan vitae posuere a, tempus sit amet est. Phasellus justo dui, rhoncus non orci convallis, pulvinar consectetur ante. Suspendisse pellentesque enim magna, non accumsan tortor egestas sit amet. Proin et placerat urna, in pretium metus. Sed nulla enim, lacinia vitae nisl id, rhoncus aliquam dui. Aliquam tincidunt diam arcu, eget facilisis tellus commodo quis. Morbi luctus bibendum viverra. Donec eget elementum ex. Integer posuere turpis ac neque elementum volutpat. Nulla lacinia sem vitae nisi mattis, at iaculis tellus congue. Donec sed luctus magna. Sed sit amet gravida metus. Ut non dolor hendrerit, ultricies odio eget, pretium tortor. Suspendisse potenti. In maximus ornare felis, at rutrum enim viverra quis. Curabitur at diam ultricies, pretium lacus sed, sollicitudin dolor. Vestibulum consectetur nunc a ipsum rhoncus dapibus. In eget augue non leo blandit consectetur. Nullam ut ullamcorper nulla. Sed vulputate justo et leo scelerisque sollicitudin. Ut tincidunt volutpat placerat. Curabitur ultrices dolor eu quam venenatis, a scelerisque mi commodo. Phasellus vel venenatis ante. Integer vulputate, mi eu lacinia fermentum, sapien purus sodales massa, at malesuada urna lorem laoreet ligula. Fusce sit amet faucibus purus, id facilisis turpis. Cras sit amet vestibulum elit, ac facilisis sem. Proin eleifend semper enim non fringilla. Donec vitae justo sed sapien gravida porta sit amet in velit. Nullam a diam quis orci auctor sagittis vitae ac libero. Cras porta, nunc et auctor lobortis, ligula elit lacinia nisi, quis ultrices elit mi ac lorem. Morbi eu ligula eget turpis rhoncus aliquet et at nunc. Vivamus fermentum vitae metus vel suscipit. Donec ante metus, auctor et sapien ac, tempor eleifend sapien. Nunc viverra augue sit amet felis egestas, id pellentesque libero vulputate. Cras faucibus, risus ac suscipit semper, ipsum ante porta diam, eleifend luctus ante lectus ac ligula. Curabitur in magna ac nisl fermentum volutpat sit amet at nunc. Curabitur condimentum tempor risus in maximus. Integer ut congue nunc, eu lobortis metus. Nam vulputate nisl ut ligula blandit ornare. Suspendisse blandit pulvinar urna ac pulvinar. Maecenas rutrum pretium turpis sit amet faucibus. Fusce commodo tempor nunc, quis tincidunt felis. Pellentesque eu fermentum libero, at rutrum lacus. Quisque volutpat dui ante, sed ullamcorper odio vestibulum ut. Donec nec est tempus, bibendum est ac, placerat orci. Praesent ligula orci, commodo id iaculis vel, tristique id neque. Donec sed rhoncus arcu, vel pharetra enim. Cras convallis eu tortor sit amet venenatis. Duis posuere scelerisque justo sed posuere. Suspendisse facilisis, metus vel pharetra rutrum, augue enim gravida arcu, non fringilla sem tellus vel tortor. Cras vitae purus et erat lobortis auctor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent magna tellus, semper vitae mauris vulputate, finibus porta sem. Mauris et ipsum accumsan, dapibus dui ut, hendrerit magna. Nam malesuada odio non orci tempor, ut gravida velit faucibus. Vestibulum molestie eu nunc at tempus. Maecenas lacinia consequat lorem non dapibus. In at ultricies nisl. Fusce pretium ac nisi non euismod. Nunc ut metus turpis. Donec efficitur tincidunt mattis. Sed lacus lorem, bibendum non magna at, iaculis viverra est. Proin sed interdum ligula. Maecenas gravida finibus augue, a laoreet nisl. Fusce quis tempus sapien. Pellentesque vitae nulla risus. Fusce nec arcu ipsum. Pellentesque dapibus congue arcu ac ornare. Donec sagittis enim id dui hendrerit molestie eu pellentesque est. Donec et dui lacus. Mauris vulputate dui a turpis malesuada lacinia. Nullam non dolor pellentesque, ultrices justo id, blandit enim. Vestibulum dapibus vestibulum quam, vel lobortis sapien eleifend vitae. Sed volutpat libero sed odio vehicula ullamcorper in non nunc. Nullam placerat diam sed ex interdum, ut egestas nibh posuere. Pellentesque ac ante mauris. Etiam turpis nulla, aliquam ut nibh a, lacinia tincidunt augue. Cras ultricies nibh turpis, in consequat quam pulvinar non. Aenean vel nunc quam. Sed pulvinar mauris nec metus pulvinar vulputate. Praesent vitae varius quam, consequat sagittis sapien. In vitae tristique lacus. Aenean egestas, elit at semper porta, enim nisi eleifend lorem, at consequat sapien est suscipit velit. Duis a odio risus. In in dolor condimentum, fringilla arcu egestas, sollicitudin dui. Pellentesque laoreet lacinia dignissim. Praesent ac consectetur magna. Aliquam rutrum augue et tellus tristique consectetur. Integer sollicitudin sollicitudin imperdiet. Duis in felis fringilla, dictum risus quis, egestas odio. Nulla eu aliquet sem, sed sollicitudin felis. Nullam mauris odio, fermentum at vulputate eu, tincidunt a orci. Ut vehicula bibendum metus sed efficitur. Suspendisse dui risus, accumsan in consectetur id, dignissim a dolor. Quisque vel volutpat libero, non hendrerit lorem. Sed purus sem, accumsan id eros sed, dapibus porta est. Cras ac consequat lectus. Nam bibendum malesuada metus, id varius lorem scelerisque a. In volutpat sapien eget varius lacinia. Fusce lobortis interdum dolor, non cursus lectus. Ut blandit arcu sed dui pulvinar, ornare mattis urna porta. Nunc nibh diam, posuere vitae eleifend aliquet, egestas a magna. Morbi in orci libero. Integer tincidunt nunc rhoncus blandit gravida. Nullam cursus consequat ante vel sodales. Quisque viverra turpis vel ultrices mattis. Cras efficitur ipsum leo, sed elementum massa lacinia eget. Etiam ac massa lorem. Vivamus vitae eros ipsum. Maecenas facilisis, purus in laoreet maximus, ipsum libero luctus sem, ullamcorper dignissim erat lorem at justo. Mauris laoreet, arcu at ultricies posuere, mauris libero lacinia nibh, non faucibus velit mauris at purus. Vivamus mollis hendrerit neque vitae suscipit. Pellentesque ultricies porttitor ex id euismod. Praesent fermentum facilisis enim et aliquam. Nulla feugiat lacinia purus, vel egestas elit maximus vel. Vestibulum nunc libero, ultricies sed orci in, placerat varius eros. Cras id nibh sed erat tincidunt scelerisque vel in ante. Nulla facilisi. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras iaculis convallis nisl, eu ultrices odio efficitur in. Donec eleifend nulla nec justo commodo, ac consectetur quam consequat. Vivamus mattis condimentum massa, in accumsan purus ornare ut. Nulla ac auctor arcu, nec tincidunt nibh. Maecenas vitae nulla vel risus pretium faucibus. Morbi vel facilisis massa. Etiam tempus ornare turpis, a finibus ex aliquam eu. Praesent aliquam libero non accumsan sollicitudin. Proin imperdiet libero diam, vel malesuada leo maximus a. Ut vestibulum tortor et faucibus pellentesque. Curabitur sed malesuada augue. Ut eu dignissim eros. Integer pharetra efficitur est ut semper. Sed at lacinia justo, ut imperdiet nulla. Phasellus bibendum libero sit amet tellus imperdiet, eu consequat lorem tincidunt. Cras porttitor semper sem nec commodo. Maecenas eget nisi id velit posuere iaculis. Nulla ut scelerisque dui. Quisque sollicitudin luctus lacus, id condimentum lectus vestibulum at. Quisque euismod ex dui, at ullamcorper quam interdum egestas. Vestibulum dapibus efficitur tellus sed efficitur. Cras in felis ac lacus laoreet rutrum. Praesent eget nunc placerat, feugiat sem eu, elementum eros. Mauris vitae porta lorem, a viverra magna. Aliquam quam diam, bibendum eu ante a, iaculis tincidunt tellus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis molestie libero a fermentum. Integer pharetra, leo ut placerat tempor, nisi velit laoreet purus, vel lobortis libero leo quis tortor. Nunc viverra erat vel enim tempor, nec egestas ligula laoreet. Nam finibus, orci vitae euismod dapibus, felis erat pretium lorem, sed laoreet purus erat ut ligula. Curabitur eu rutrum purus. Nunc non efficitur ex. Vivamus non pretium erat, eget viverra diam. Donec ac orci ac mi lacinia posuere. Integer venenatis est hendrerit velit pretium rutrum. Donec vehicula mattis mi vitae vehicula. Donec eget tortor efficitur nulla semper sollicitudin. Aliquam nisl nisi, consectetur id leo quis, imperdiet fringilla diam. Nulla ultricies ipsum sapien, a posuere eros porttitor nec. Nam pretium auctor nunc at auctor. Quisque mattis velit nec tortor aliquet porttitor. Proin nulla ligula, hendrerit in fermentum sed, imperdiet ac ligula. mistune-3.0.2/benchmark/cases/ref_links.txt000066400000000000000000000004011450566212600207470ustar00rootroot00000000000000[f1]: /bar [f2]: /bar "baz" [f3]: [f4]: "baz" [foo][f1] [foo][f2] [foo][f3] [foo][f4] [f1][] [f2][] [f3][] [f4][] [f1] [f2] [f3] [f4] ![foo][f1] ![foo][f2] ![foo][f3] ![foo][f4] ![f1][] ![f2][] ![f3][] ![f4][] ![f1] ![f2] ![f3] ![f4] mistune-3.0.2/benchmark/cases/setext.txt000066400000000000000000000001141450566212600203100ustar00rootroot00000000000000h1 == h2 -- ---- heading ------- h1 == h1 == h1 == h1 h1 h1 h1 h1 h1 == mistune-3.0.2/benchmark/cases/std_links.txt000066400000000000000000000002041450566212600207660ustar00rootroot00000000000000[foo](/bar) [foo](/bar "baz") [foo]() [foo]( "baz") ![foo](/bar) ![foo](/bar "baz") ![foo]() ![foo]( "baz") mistune-3.0.2/docs/000077500000000000000000000000001450566212600141375ustar00rootroot00000000000000mistune-3.0.2/docs/Makefile000066400000000000000000000011721450566212600156000ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) mistune-3.0.2/docs/_static/000077500000000000000000000000001450566212600155655ustar00rootroot00000000000000mistune-3.0.2/docs/_static/dark-icon.svg000066400000000000000000000047401450566212600201620ustar00rootroot00000000000000mistune-3.0.2/docs/_static/light-icon.svg000066400000000000000000000047401450566212600203500ustar00rootroot00000000000000mistune-3.0.2/docs/_static/logo-black.svg000066400000000000000000000233301450566212600203210ustar00rootroot00000000000000mistune-3.0.2/docs/_static/logo-white.svg000066400000000000000000000233321450566212600203670ustar00rootroot00000000000000mistune-3.0.2/docs/_templates/000077500000000000000000000000001450566212600162745ustar00rootroot00000000000000mistune-3.0.2/docs/_templates/partials/000077500000000000000000000000001450566212600201135ustar00rootroot00000000000000mistune-3.0.2/docs/_templates/partials/globaltoc-above.html000066400000000000000000000010061450566212600240360ustar00rootroot00000000000000 mistune-3.0.2/docs/advanced.rst000066400000000000000000000115051450566212600164400ustar00rootroot00000000000000Advanced Guide ============== Create plugins -------------- Mistune has many built-in plugins, you can take a look at the source code in ``mistune/plugins`` to find out how to write a plugin. In this documentation, I'll guide you with an example, let's take a look at the math plugin (located at ``mistune/plugins/math.py``): .. code-block:: python def math(md): md.block.register('block_math', BLOCK_MATH_PATTERN, parse_block_math, before='list') md.inline.register('inline_math', INLINE_MATH_PATTERN, parse_inline_math, before='link') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('block_math', render_block_math) md.renderer.register('inline_math', render_inline_math) The parameter ``md`` is the instance of :class:`Markdown`. In our example, we have registered a block level math plugin and an inline level math plugin. Block level plugin ~~~~~~~~~~~~~~~~~~ Function ``md.block.register`` will register a block level plugin. In the math example: .. code-block:: text $$ \operatorname{ker} f=\{g\in G:f(g)=e_{H}\}{\mbox{.}} $$ This is how a block level math syntax looks like. Our ``BLOCK_MATH_PATTERN`` is: .. code-block:: python # block level pattern MUST startswith ^ BLOCK_MATH_PATTERN = r'^ {0,3}\$\$[ \t]*\n(?P.+?)\n\$\$[ \t]*$' # regex represents: BLOCK_MATH_PATTERN = ( r'^ {0,3}' # line can startswith 0~3 spaces just like other block elements defined in commonmark r'\$\$' # followed by $$ r'[ \t]*\n' # this line can contain extra spaces and tabs r'(?P.+?)' # this is the math content, MUST use named group r'\n\$\$[ \t]*$' # endswith $$ + extra spaces and tabs ) # if you want to make the math pattern more strictly, it could be like: BLOCK_MATH_PATTERN = r'^\$\$\n(?P.+?)\n\$\$$' Then the block parsing function: .. code-block:: python def parse_block_math(block, m, state): text = m.group('math_text') # use ``state.append_token`` to save parsed block math token state.append_token({'type': 'block_math', 'raw': text}) # return the end position of parsed text # since python doesn't count ``$``, we have to +1 # if the pattern is not ended with `$`, we can't +1 return m.end() + 1 The ``token`` MUST contain ``type``, others are optional. Here are some examples: .. code-block:: python {'type': 'thematic_break'} #
{'type': 'paragraph', 'text': text} {'type': 'block_code', 'raw': code} {'type': 'heading', 'text': text, 'attrs': {'level': level}} - **text**: inline parser will parse text - **raw**: inline parser WILL NOT parse the content - **attrs**: extra information saved here, renderer will use attrs Inline level plugin ~~~~~~~~~~~~~~~~~~~ Function ``md.inline.register`` will register an inline level plugin. In the math example: .. code-block:: text function $f$ This is how an inline level math syntax looks like. Our ``INLINE_MATH_PATTERN`` is: .. code-block:: python INLINE_MATH_PATTERN = r'\$(?!\s)(?P.+?)(?!\s)\$' # regex represents: INLINE_MATH_PATTERN = ( r'\$' # startswith $ r'(?!\s)' # not whitespace r'(?P.+?)' # content between `$`, MUST use named group r'(?!\s)' # not whitespace r'\$' # endswith $ ) Then the inline parsing function: .. code-block:: python def parse_inline_math(inline, m, state): text = m.group('math_text') # use ``state.append_token`` to save parsed inline math token state.append_token({'type': 'inline_math', 'raw': text}) # return the end position of parsed text return m.end() The inline token value looks the same with block token. Available keys: ``type``, ``raw``, ``text``, ``attrs``. Plugin renderers ~~~~~~~~~~~~~~~~ It is suggested to add default HTML renderers for your plugin. A renderer function looks like: .. code-block:: python def render_hr(renderer): # token with only type, like: # {'type': 'hr'} return '
' def render_math(renderer, text): # token with type and (text or raw), e.g.: # {'type': 'block_math', 'raw': 'a^b'} return '
$$' + text + '$$
' def render_link(renderer, text, **attrs): # token with type, text or raw, and attrs href = attrs['href'] return f'{text}' If current markdown instance is using HTML renderer, developers can register the plugin renderer for converting markdown to HTML. Write directives ---------------- Mistune has some built-in directives that have been presented in the directives part of the documentation. These are defined in the ``mistune/directives``, you can learn how to write a new directive by reading the source code in ``mistune/directives/``. mistune-3.0.2/docs/api.rst000066400000000000000000000041371450566212600154470ustar00rootroot00000000000000API Reference ============= Here are the list of API reference; it might be helpful for developers. .. module:: mistune Basic ----- .. function:: html(text: str) :param text: markdown formatted text Turn markdown text into HTML without escaping. For instance:: text = '**hello** world' mistune.html(text) # => '

hello world

' .. autofunction:: create_markdown Utilities --------- .. autofunction:: escape .. autofunction:: escape_url .. autofunction:: safe_entity .. autofunction:: unikey Advanced -------- .. autoclass:: Markdown .. autoclass:: BlockState :inherited-members: .. autoclass:: InlineState :inherited-members: .. autoclass:: BlockParser :inherited-members: register .. autoclass:: InlineParser :inherited-members: register Plugins ------- .. module:: mistune.plugins.footnotes .. autofunction:: footnotes .. module:: mistune.plugins.task_lists .. autofunction:: task_lists .. module:: mistune.plugins.abbr .. autofunction:: abbr .. module:: mistune.plugins.def_list .. autofunction:: def_list .. module:: mistune.plugins.table .. autofunction:: table .. autofunction:: table_in_quote .. autofunction:: table_in_list .. module:: mistune.plugins.math .. autofunction:: math .. autofunction:: math_in_quote .. autofunction:: math_in_list .. module:: mistune.plugins.ruby .. autofunction:: ruby .. module:: mistune.plugins.formatting .. autofunction:: strikethrough .. autofunction:: mark .. autofunction:: insert .. autofunction:: superscript .. autofunction:: subscript .. module:: mistune.plugins.spoiler .. autofunction:: spoiler Renderers --------- .. module:: mistune.renderers.html .. autoclass:: HTMLRenderer .. module:: mistune.renderers.markdown .. autoclass:: MarkdownRenderer .. module:: mistune.renderers.rst .. autoclass:: RSTRenderer TOC hook -------- .. module:: mistune.toc .. autofunction:: add_toc_hook .. autofunction:: render_toc_ul Directives ---------- .. module:: mistune.directives .. autoclass:: RSTDirective .. autoclass:: FencedDirective mistune-3.0.2/docs/changes.rst000066400000000000000000000035341450566212600163060ustar00rootroot00000000000000Changelog ========= Here is the full history of mistune v3. Version 3.0.2 ------------- **Released on Sep 30, 2023** * Fix list parser to avoid RecursionError Version 3.0.1 ------------- **Released on Jun 10, 2023** * Add ``py.typed`` for mypy * Add ``tests``, ``docs`` for sdist * Support ``renderer="ast"`` for rendering AST Version 3.0.0 ------------- **Released on Jun 08, 2023** * Do not strip leading unicode spaces like emsp * Ensure new line at end of the text Version 3.0.0rc5 ---------------- **Released on Mar 22, 2023** * Fix fenced directives * Fix inline link parser * Fix block math plugin for multiple lines * Fix empty list item for markdown renderer Version 3.0.0rc4 ---------------- **Released on Nov 30, 2022** * Fix plugin footnotes when there is no newline at the end * Move safe HTML entities to HTMLRenderer * Redesign directives parsing * Add Image and Figure directive Version 3.0.0rc3 ---------------- **Released on Nov 25, 2022** * Render inline math with ``\(`` and ``\)`` * Added ``RSTRenderer``, and ``MarkdownRenderer`` * Fix ``toc_hook`` method * **Breaking change**, rename ``RstDirective`` to ``RSTDirective`` Version 3.0.0rc2 ---------------- **Released on Nov 6, 2022** * Add **spoiler** plugin * Add ``collapse`` option for ``TableOfContents`` directive * **Breaking change** on directive design, added fenced directive Version 3.0.0rc1 ---------------- **Released on Sep 26, 2022** * Add **superscript** plugin Version 3.0.0a3 --------------- **Released on Jul 14, 2022** * Fix ruby plugin * Change toc parameter ``depth`` to ``level`` Version 3.0.0a2 --------------- **Released on Jul 13, 2022** * Escape block code in HTMLRenderer * Fix parsing links Version 3.0.0a1 --------------- **Released on Jul 12, 2022** This is the first release of v3. Features included: * redesigned mistune * plugins * directives mistune-3.0.2/docs/cli.rst000066400000000000000000000040101450566212600154330ustar00rootroot00000000000000Command line tools ================== .. meta:: :description: How to use the command line tools of Mistune to convert Markdown to HTML, RST, and etc. A command line tool to convert markdown content into HTML, learn about the options of the command line tool:: $ python -m mistune -h Mistune, a sane and fast python markdown parser. Here are some use cases of the command line tool: $ python -m mistune -m "Hi **Markdown**"

Hi Markdown

$ python -m mistune -f README.md

... $ cat README.md | python -m mistune

... optional arguments: -h, --help show this help message and exit -m MESSAGE, --message MESSAGE the markdown message to convert -f FILE, --file FILE the markdown file to convert -p NAME [NAME ...], --plugin NAME [NAME ...] specifiy a plugin to use --escape turn on escape option --hardwrap turn on hardwrap option -o OUTPUT, --output OUTPUT write the rendered result into file -r RENDERER, --renderer RENDERER specify the output renderer --version show program's version number and exit Convert Markdown to HTML ------------------------ By default, the command line tool of mistune will convert markdown text to HTML text:: $ python -m mistune -f README.md Convert Markdown to RestructuredText ------------------------------------ Mistune has a built-in RestructuredText formatter, specify the renderer with ``-r rst``:: $ python -m mistune -f README.md -r rst Reformat Markdown ----------------- You can reformat the markdown file with a markdown renderer:: $ python -m mistune -f README.md -r markdown -o README.md This command will reformat the text in ``README.md``. Unix PIPE --------- The command line tool supports unix PIPE. For instance:: $ echo "foo **bar**" | python -m mistune mistune-3.0.2/docs/community.rst000066400000000000000000000001601450566212600167120ustar00rootroot00000000000000Community Extensions ==================== Here is the list of plugins and directives created by the community. mistune-3.0.2/docs/conf.py000066400000000000000000000047501450566212600154440ustar00rootroot00000000000000import mistune project = 'Mistune' copyright = '2019, Hsiaoming Yang' author = 'Hsiaoming Yang' master_doc = 'index' # The full version, including alpha/beta/rc tags version = mistune.__version__ release = version # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), } # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'shibuya' html_theme_options = { "light_logo": "_static/logo-black.svg", "dark_logo": "_static/logo-white.svg", "light_css_variables": { "--sy-rc-theme": "143, 118, 214", }, "dark_css_variables": { "--sy-rc-theme": "130, 80, 223", }, 'twitter_site': 'lepture', 'twitter_creator': 'lepture', 'twitter_url': 'https://twitter.com/lepture', 'github_url': 'https://github.com/lepture/mistune', 'nav_links': [ { 'title': 'Projects', 'children': [ { 'title': 'Authlib', 'url': 'https://authlib.org/', 'summary': 'OAuth, JOSE, OpenID, etc' }, { 'title': 'Shibuya', 'url': 'https://shibuya.lepture.com/', 'summary': 'A pretty Sphinx theme', } ] }, {'title': 'Sponsor me', 'url': 'https://github.com/sponsors/lepture'} ] } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] html_copy_source = False html_show_sourcelink = False html_favicon = "_static/light-icon.svg" mistune-3.0.2/docs/directives.rst000066400000000000000000000074531450566212600170430ustar00rootroot00000000000000.. _directives: Directives ========== A directive is a generic block of explicit markup that is powerful and extensible. In mistune v3, there are 2 styles of directives for now: 1. reStructuredText style 2. fenced style .. versionchanged:: 3.0 Fenced style directive is added in 3.0. Because v3 has multiple styles of directives, developers can not add each directive into ``plugins`` parameter of ``mistune.create_markdown`` directly. Instead, each directive should be wrapped by:: import mistune from mistune.directives import FencedDirective, RSTDirective from mistune.directives import Admonition, TableOfContents markdown = mistune.create_markdown(plugins=[ 'math', 'footnotes', # ... FencedDirective([ Admonition(), TableOfContents(), ]), ]) markdown = mistune.create_markdown(plugins=[ 'math', 'footnotes', # ... RSTDirective([ Admonition(), TableOfContents(), ]), ]) A **reStructuredText** style of directive is inspired by reStructuredText_, and the syntax looks like: .. code-block:: text .. directive-type:: title :option-key: option value :option-key: option value content text here A **fenced** style of directive looks like a fenced code block, it is inspired by `markdown-it-docutils`_. The syntax looks like: .. code-block:: text ```{directive-type} title :option-key: option value :option-key: option value content text here ``` .. _reStructuredText: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#directives .. _`markdown-it-docutils`: https://executablebooks.github.io/markdown-it-docutils/ Developers can choose the directive style in their own favor. Admonitions ----------- The reStructuredText style syntax: .. code-block:: text .. warning:: You are looking at the **dev** documentation. Check out our [stable](/stable/) documentation instead. The fenced style syntax: .. code-block:: text ```{warning} You are looking at the **dev** documentation. Check out our [stable](/stable/) documentation instead. ``` Admonitions contains a group of ``directive-name``: .. code-block:: text attention caution danger error hint important note tip warning To enable admonitions:: import mistune from mistune.directives import Admonition markdown = mistune.create_markdown( plugins=[ ... RSTDirective([Admonition()]), # FencedDirective([Admonition()]), ] ) Table of Contents ----------------- .. code-block:: text .. toc:: Table of Contents :max-level: 3 TOC plugin is based on directive. It can add a table of contents section in the documentation. Let's take an example: .. code-block:: text Here is the first paragraph, and we put TOC below. .. toc:: # H1 title ## H2 title # H1 title The rendered HTML will show a TOC at the ``.. toc::`` position. To enable TOC plugin:: import mistune from mistune.directives import RSTDirective, TableOfContents markdown = mistune.create_markdown( plugins=[ # ... RSTDirective([TableOfContents()]), ] ) Include ------- .. code-block:: text .. include:: hello.md ``include`` is a powerful plugin for documentation generator. With this plugin, we can embed contents from other files. Image ----- .. code-block:: text ```{image} https://domain/path.png :alt: alt text :width: 800 :height: 500 ``` Figure ------ .. code-block:: text ```{figure} https://domain/path.png :alt: alt text :width: 800 :height: 500 ``` mistune-3.0.2/docs/guide.rst000066400000000000000000000052711450566212600157730ustar00rootroot00000000000000How to Use Mistune ================== Mistune is super easy to use. Here is how you can convert Markdown formatted text into HTML:: import mistune mistune.html(YOUR_MARKDOWN_TEXT) The ``.html()`` methods has enabled all the features you might want by default: * No escape of HTML tags * With **strikethrough** plugin * With **table** plugin * With **footnote** plugin Customize Mistune ----------------- Mistune provides a function to create Markdown instance easily:: import mistune markdown = mistune.create_markdown() This method will create a "escaped" Markdown instance without any plugins, which means:: markdown('

hello
') # ==> '

<div>hello</div>

' Non escaped version:: markdown = mistune.create_markdown(escape=False) markdown('
hello
') # ==> '
hello
' Adding plugins:: markdown = mistune.create_markdown() markdown('~~s~~') # ==> '

~~s~~

' markdown = mistune.create_markdown(plugins=['strikethrough']) markdown('~~s~~') # ==> '

s

' Find out what plugins mistune has built-in in :ref:`plugins` sections. Customize Renderer ------------------ Mistune supports renderer feature which enables developers to customize the output. For instance, to add code syntax highlight:: import mistune from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import html class HighlightRenderer(mistune.HTMLRenderer): def block_code(self, code, info=None): if info: lexer = get_lexer_by_name(info, stripall=True) formatter = html.HtmlFormatter() return highlight(code, lexer, formatter) return '
' + mistune.escape(code) + '
' markdown = mistune.create_markdown(renderer=HighlightRenderer()) print(markdown('```python\nassert 1 == 1\n```')) In this way, we can use Pygments to highlight the fenced code. Learn more at :ref:`renderers`. Abstract syntax tree -------------------- Mistune can produce AST by default without any renderer:: markdown = mistune.create_markdown(renderer=None) This ``markdown`` function will generate a list of tokens instead of HTML:: text = 'hello **world**' markdown(text) # ==> [ { 'type': 'paragraph', 'children': [ {'type': 'text', 'raw': 'hello '}, {'type': 'strong', 'children': [{'type': 'text', 'raw': 'world'}]} ] } ] It is also possible to pass ``renderer='ast'`` to create the markdown instance:: markdown = mistune.create_markdown(renderer='ast') mistune-3.0.2/docs/index.rst000066400000000000000000000016031450566212600160000ustar00rootroot00000000000000.. mistune documentation master file, created by sphinx-quickstart on Wed Sep 18 13:29:37 2019. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Mistune: Python Markdown Parser =============================== Release v\ |version|. A fast yet powerful Python Markdown parser with renderers and plugins, compatible with sane CommonMark rules. Using old Mistune? Checkout docs: - https://mistune.lepture.com/en/v0.8.4/ - https://mistune.lepture.com/en/v2/ Installation ------------ Installing Mistune is quite easy with `pip `_. .. parsed-literal:: $ pip install mistune==\ |version| Mistune has no external dependencies. User Guide ---------- .. toctree:: :maxdepth: 2 guide cli renderers plugins directives advanced api upgrade community changes mistune-3.0.2/docs/plugins.rst000066400000000000000000000260661450566212600163640ustar00rootroot00000000000000.. _plugins: Built-in Plugins ================ .. meta:: :description: List of Mistune built-in plugins, their syntax and how to enable them. Mistune offers many built-in plugins, including all the popular markups. .. _strikethrough: strikethrough ------------- .. code-block:: text ~~here is the content~~ ``mistune.html()`` has enabled strikethrough plugin by default. To create a markdown instance your own:: markdown = mistune.create_markdown(plugins=['strikethrough']) Another way to create your own Markdown instance:: from mistune.plugins.formatting import strikethrough renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[strikethrough]) footnotes --------- .. code-block:: text content in paragraph with footnote[^1] markup. [^1]: footnote explain ``mistune.html()`` has enabled footnote plugin by default. To create a markdown instance your own:: markdown = mistune.create_markdown(plugins=['footnotes']) Another way to create your own Markdown instance:: from mistune.plugins.footnotes import footnotes renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[footnotes]) table ----- Simple formatted table: .. code-block:: text First Header | Second Header ------------- | ------------- Content Cell | Content Cell Content Cell | Content Cell Complex formatted table: .. code-block:: text | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | Align formatted table: .. code-block:: text Left Header | Center Header | Right Header :----------- | :-------------: | ------------: Conent Cell | Content Cell | Content Cell | Left Header | Center Header | Right Header | | :---------- | :-------------: | ------------: | | Conent Cell | Content Cell | Content Cell | ``mistune.html()`` has enabled table plugin by default. To create a markdown instance your own:: markdown = mistune.create_markdown(plugins=['table']) Another way to create your own Markdown instance:: from mistune.plugins.table import table renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[table]) url --- URL plugin enables creating link with raw URL by default: .. code-block:: text For instance, https://typlog.com/ Will be converted into: .. code-block:: html

For instance, item 1

  • item 2
  • This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **task_lists** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['task_lists']) Another way to create your own Markdown instance:: from mistune.plugins.task_lists import task_lists renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[task_lists]) def_list -------- def_list plugin enables creating html definition lists: .. code-block:: text First term : First definition : Second definition Second term : Third definition Will be converted into: .. code-block:: html
    First term
    First definition
    Second definition
    Second term
    Third definition
    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **def_list** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['def_list']) Another way to create your own Markdown instance:: from mistune.plugins.def_list import def_list renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[def_list]) abbr ---- abbr plugin enables creating abbreviations: .. code-block:: text The HTML specification is maintained by the W3C. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium Will be converted into: .. code-block:: html The HTML specification is maintained by the W3C. This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **abbr** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['abbr']) Another way to create your own Markdown instance:: from mistune.plugins.abbr import abbr renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[abbr]) mark ---- mark plugin adds the ability to insert ```` tags. To mark some text, simply surround the text with ``==``: .. code-block:: text ==mark me== ==mark with\=\=equal== Will be converted into: .. code-block:: html mark me mark with==equal This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **mark** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['mark']) Another way to create your own Markdown instance:: from mistune.plugins.formatting import mark renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[mark]) insert ------ insert plugin adds the ability to insert ```` tags. To insert some text, simply surround the text with ``^^``: .. code-block:: text ^^insert me^^ ^^insert\^\^me^^ Will be converted into: .. code-block:: html insert me insert^^me This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **insert** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['insert']) Another way to create your own Markdown instance:: from mistune.plugins.formatting import insert renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[insert]) superscript ----------- superscript plugin adds the ability to insert ```` tags. The syntax looks like: .. code-block:: text Hello^superscript^ Will be converted into: .. code-block:: html

    Hellosuperscript

    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **superscript** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['superscript']) Another way to create your own Markdown instance:: from mistune.plugins.formatting import superscript renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[superscript]) subscript --------- subscript plugin adds the ability to insert ```` tags. The syntax looks like: .. code-block:: text Hello~subscript~ CH~3~CH~2~OH Will be converted into: .. code-block:: html

    Hellosubscript

    CH3CH2OH

    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **subscript** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['subscript']) Another way to create your own Markdown instance:: from mistune.plugins.formatting import subscript renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[subscript]) math ---- Math plugin wraps ``
    `` for block level math syntax, and ```` for inline level math syntax. A block math is surrounded with ``$$``: .. code-block:: text $$ \operatorname{ker} f=\{g\in G:f(g)=e_{H}\}{\mbox{.}} $$ Will be converted into: .. code-block:: html
    $$ \operatorname{ker} f=\{g\in G:f(g)=e_{H}\}{\mbox{.}} $$
    An inline math is surrounded with ``$`` inline: .. code-block:: text function $f$ Will be converted into: .. code-block:: html

    function $f$

    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **math** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['math']) Another way to create your own Markdown instance:: from mistune.plugins.math import math renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[math]) ruby ---- insert plugin adds the ability to insert ```` tags. Here are some examples for ruby syntax: .. code-block:: text [漢字(ㄏㄢˋㄗˋ)] [link]: /url [漢字(ㄏㄢˋㄗˋ)][link] [漢字(ㄏㄢˋㄗˋ)](/url) [漢(ㄏㄢˋ)字(ㄗˋ)] Will be converted into: .. code-block:: html

    漢字ㄏㄢˋㄗˋ

    漢字ㄏㄢˋㄗˋ

    漢字ㄏㄢˋㄗˋ

    ㄏㄢˋㄗˋ

    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **ruby** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['ruby']) Another way to create your own Markdown instance:: from mistune.plugins.ruby import ruby renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[ruby]) Blog post: https://lepture.com/en/2022/markdown-ruby-markup spoiler ------- Spoiler plugin wraps ``
    `` for block level syntax, and ```` for inline level syntax. A block level spoiler looks like block quote, but the marker is ``>!``: .. code-block:: text >! here is the spoiler content >! >! it will be hidden Will be converted into: .. code-block:: html

    here is the spoiler content

    it will be hidden

    An inline spoiler is surrounded with ``>!`` and ``!<``: .. code-block:: text this is the >! hidden text !< Will be converted into: .. code-block:: html

    this is the hidden text

    This plugin is **NOT ENABLED** by default in ``mistune.html()``. To enable **spoiler** plugin with your own markdown instance:: markdown = mistune.create_markdown(plugins=['spoiler']) Another way to create your own Markdown instance:: from mistune.plugins.spoiler import spoiler renderer = mistune.HTMLRenderer() markdown = mistune.Markdown(renderer, plugins=[spoiler]) mistune-3.0.2/docs/renderers.rst000066400000000000000000000113371450566212600166670ustar00rootroot00000000000000.. _renderers: Renderers ========= Mistune has several built-in renderers, including: - :class:`mistune.renderers.html.HTMLRenderer` - :class:`mistune.renderers.markdown.MarkdownRenderer` - :class:`mistune.renderers.rst.RSTRenderer` You're welcome to contribute more renderers. Customize HTMLRenderer ---------------------- You can customize HTML output with your own renderers. Take an example, we're going to add an inline math syntax like below: .. code:: `$a^2=4$` To render this syntax, we can create a subclass of ``mistune.HTMLRenderer``: .. code-block:: python from mistune import HTMLRenderer class MyRenderer(HTMLRenderer): def codespan(self, text): if text.startswith('$') and text.endswith('$'): return '' + escape(text) + '' return '' + escape(text) + '' # use customized renderer markdown = mistune.create_markdown(renderer=MyRenderer()) print(markdown('hi `$a^2=4$`')) Available methods ~~~~~~~~~~~~~~~~~ Here is a a list of available renderer functions for ``HTMLRenderer``, including methods on plugins: .. code-block:: # inline level text(self, text) link(self, text, url, title=None) image(self, alt, url, title=None) emphasis(self, text) strong(self, text) codespan(self, text) linebreak(self) softbreak(self) inline_html(self, html) # block level paragraph(self, text) heading(self, text, level, **attrs) blank_line(self) thematic_break(self) block_text(self, text) block_code(self, code, info=None) block_quote(self, text) block_html(self, html) block_error(self, html) list(self, text, ordered, **attrs) list_item(self, text, **attrs) # provided by strikethrough plugin strikethrough(self, text) # provided by mark plugin mark(self, text) # provided by insert plugin insert(self, text) # provided by subscript plugin subscript(self, text) # provided by abbr plugin abbr(self, text, title) # provided by ruby plugin ruby(self, text, rt) # provided by task_lists plugin task_list_item(self, text, checked=False, **attrs) # provide by table plugin table(self, text) table_head(self, text) table_body(self, text) table_row(self, text) table_cell(self, text, align=None, head=False) # provided by footnotes plugin footnote_ref(self, key, index) footnotes(self, text) footnote_item(self, text, key, index) # provide by def_list plugin def_list(self, text) def_list_head(self, text) def_list_item(self, text) # provide by math plugin block_math(self, text) inline_math(self, text) RestructuredText Renderer ------------------------- The ``RSTRenderer`` can be used to convert markdown text to RestructuredText. .. code-block:: python from mistune.renderers.rst import RSTRenderer convert_rst = mistune.create_markdown(renderer=RSTRenderer()) convert_rst(your_markdown_text) Markdown Renderer ----------------- The ``MarkdownRenderer`` can be used to reformat your Markdown text. .. code-block:: python from mistune.renderers.markdown import MarkdownRenderer format_markdown = mistune.create_markdown(renderer=MarkdownRenderer()) format_markdown(your_markdown_text) With plugins ~~~~~~~~~~~~ The original ``MarkdownRenderer`` can **ONLY** render the basic Markdown syntax. If you're using plugins, you would need to customize ``MarkdownRenderer`` with extra render methods. Take an example, you are going to add the :ref:`strikethrough` plugin: .. code-block:: python from mistune.renderers.markdown import MarkdownRenderer class MyRenderer(MarkdownRenderer): def strikethrough(self, token, state): return '~~' + self.render_children(token, state) + '~~' format_markdown = mistune.create_markdown(renderer=MarkdownRenderer(), plugins=['strikethrough']) format_markdown(your_markdown_text) Default methods ~~~~~~~~~~~~~~~ Here is a a list of default renderer functions of ``MarkdownRenderer``: .. code-block:: # inline level text(self, token, state) link(self, token, state) image(self, token, state) emphasis(self, token, state) strong(self, token, state) codespan(self, token, state) linebreak(self, token, state) softbreak(self, token, state) inline_html(self, token, state) # block level paragraph(self, token, state) heading(self, token, state) blank_line(self, token, state) thematic_break(self, token, state) block_text(self, token, state) block_code(self, token, state) block_quote(self, token, state) block_html(self, token, state) block_error(self, token, state) list(self, token, state) mistune-3.0.2/docs/requirements.txt000066400000000000000000000001041450566212600174160ustar00rootroot00000000000000sphinx==6.2.1 sphinx-copybutton==0.5.2 sphinx-design==0.4.1 shibuya mistune-3.0.2/docs/upgrade.rst000066400000000000000000000027021450566212600163210ustar00rootroot00000000000000Upgrade Guide ============= Upgrade from v2 to v3 --------------------- HTMLRenderer ~~~~~~~~~~~~ When customizing renderers, these methods' parameters are changed: .. code-block:: diff - link(self, link, text=None, title=None) + link(self, text, url, title=None) - image(self, src, alt="", title=None) + image(self, alt, url, title=None) - heading(self, text, level) + heading(self, text, level, **attrs) - list(self, text, ordered, level, start=None) + list(self, text, ordered, **attrs) - list_item(self, text, level) + list_item(self, text) - table_cell(self, text, align=None, is_head=False) + table_cell(self, text, align=None, head=False) For plugins: .. code-block:: diff - abbr(self, key, definition) + abbr(self, text: str, title: str) - task_list_item(self, text: str, level: int, checked: bool) + task_list_item(self, text: str, checked: bool) AstRenderer ~~~~~~~~~~~ There is no ``AstRenderer`` in v3, just pass ``None`` or ``'ast'`` to ``create_markdown``:: import mistune md = mistune.create_markdown(renderer='ast') # or render=None md('...markdown text...') Plugins ~~~~~~~ Please check the advanced guide and built-in plugins source code to find out how to write a mistune plugin. Directives ~~~~~~~~~~ Find out all the details in :ref:`directives`. In v3, there is one more style of directive -- fenced style directive. mistune-3.0.2/pyproject.toml000066400000000000000000000033221450566212600161230ustar00rootroot00000000000000[project] name = "mistune" description = "A sane and fast Markdown parser with useful plugins and renderers" authors = [{name = "Hsiaoming Yang", email="me@lepture.com"}] dependencies = [] license = {text = "BSD-3-Clause"} dynamic = ["version"] requires-python = ">=3.7" readme = "README.rst" classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Text Processing :: Markup", ] [project.urls] Documentation = "https://mistune.lepture.com/" Source = "https://github.com/lepture/mistune" Donate = "https://github.com/sponsors/lepture" [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] version = {attr = "mistune.__version__"} [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] mistune = ["py.typed"] [tool.pytest.ini_options] pythonpath = ["src", "."] testpaths = ["tests"] filterwarnings = ["error"] [tool.coverage.run] branch = true source = ["mistune"] [tool.coverage.paths] source = ["src"] [tool.coverage.report] exclude_lines = [ "pragma: no cover", "def __repr__", "raise NotImplementedError", "@(abc\\.)?abstractmethod", ] mistune-3.0.2/serve-doc.py000066400000000000000000000002111450566212600154420ustar00rootroot00000000000000from livereload import Server, shell app = Server() app.watch("docs", shell("make build-docs"), delay=2) app.serve(root="build/_html/") mistune-3.0.2/setup.py000066400000000000000000000000641450566212600147210ustar00rootroot00000000000000from setuptools import setup setup(name="mistune") mistune-3.0.2/src/000077500000000000000000000000001450566212600137765ustar00rootroot00000000000000mistune-3.0.2/src/mistune/000077500000000000000000000000001450566212600154625ustar00rootroot00000000000000mistune-3.0.2/src/mistune/__init__.py000066400000000000000000000046131450566212600175770ustar00rootroot00000000000000""" mistune ~~~~~~~ A fast yet powerful Python Markdown parser with renderers and plugins, compatible with sane CommonMark rules. Documentation: https://mistune.lepture.com/ """ from .markdown import Markdown from .core import BlockState, InlineState, BaseRenderer from .block_parser import BlockParser from .inline_parser import InlineParser from .renderers.html import HTMLRenderer from .util import escape, escape_url, safe_entity, unikey from .plugins import import_plugin def create_markdown(escape: bool=True, hard_wrap: bool=False, renderer='html', plugins=None) -> Markdown: """Create a Markdown instance based on the given condition. :param escape: Boolean. If using html renderer, escape html. :param hard_wrap: Boolean. Break every new line into ``
    ``. :param renderer: renderer instance, default is HTMLRenderer. :param plugins: List of plugins. This method is used when you want to re-use a Markdown instance:: markdown = create_markdown( escape=False, hard_wrap=True, ) # re-use markdown function markdown('.... your text ...') """ if renderer == 'ast': # explicit and more similar to 2.x's API renderer = None elif renderer == 'html': renderer = HTMLRenderer(escape=escape) inline = InlineParser(hard_wrap=hard_wrap) if plugins is not None: plugins = [import_plugin(n) for n in plugins] return Markdown(renderer=renderer, inline=inline, plugins=plugins) html: Markdown = create_markdown( escape=False, plugins=['strikethrough', 'footnotes', 'table', 'speedup'] ) __cached_parsers = {} def markdown(text, escape=True, renderer='html', plugins=None) -> str: if renderer == 'ast': # explicit and more similar to 2.x's API renderer = None key = (escape, renderer, plugins) if key in __cached_parsers: return __cached_parsers[key](text) md = create_markdown(escape=escape, renderer=renderer, plugins=plugins) # improve the speed for markdown parser creation __cached_parsers[key] = md return md(text) __all__ = [ 'Markdown', 'HTMLRenderer', 'BlockParser', 'BlockState', 'BaseRenderer', 'InlineParser', 'InlineState', 'escape', 'escape_url', 'safe_entity', 'unikey', 'html', 'create_markdown', 'markdown', ] __version__ = '3.0.2' __homepage__ = 'https://mistune.lepture.com/' mistune-3.0.2/src/mistune/__main__.py000066400000000000000000000054521450566212600175620ustar00rootroot00000000000000import sys import argparse from .renderers.rst import RSTRenderer from .renderers.markdown import MarkdownRenderer from . import ( create_markdown, __version__ as version ) def _md(args): if args.plugin: plugins = args.plugin else: # default plugins plugins = ['strikethrough', 'footnotes', 'table', 'speedup'] if args.renderer == 'rst': renderer = RSTRenderer() elif args.renderer == 'markdown': renderer = MarkdownRenderer() else: renderer = args.renderer return create_markdown( escape=args.escape, hard_wrap=args.hardwrap, renderer=renderer, plugins=plugins, ) def _output(text, args): if args.output: with open(args.output, 'w') as f: f.write(text) else: print(text) CMD_HELP = '''Mistune, a sane and fast python markdown parser. Here are some use cases of the command line tool: $ python -m mistune -m "Hi **Markdown**"

    Hi Markdown

    $ python -m mistune -f README.md

    ... $ cat README.md | python -m mistune

    ... ''' def cli(): parser = argparse.ArgumentParser( prog='python -m mistune', description=CMD_HELP, formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument( '-m', '--message', help='the markdown message to convert', ) parser.add_argument( '-f', '--file', help='the markdown file to convert', ) parser.add_argument( '-p', '--plugin', metavar='NAME', action='extend', nargs='+', help='specifiy a plugin to use', ) parser.add_argument( '--escape', action='store_true', help='turn on escape option', ) parser.add_argument( '--hardwrap', action='store_true', help='turn on hardwrap option', ) parser.add_argument( '-o', '--output', help='write the rendered result into file', ) parser.add_argument( '-r', '--renderer', default='html', help='specify the output renderer', ) parser.add_argument('--version', action='version', version='mistune ' + version) args = parser.parse_args() message = args.message if not message and not args.file: message = read_stdin() if message: md = _md(args) text = md(message) _output(text, args) elif args.file: md = _md(args) text = md.read(args.file)[0] _output(text, args) else: print('You MUST specify a message or file') return sys.exit(1) def read_stdin(): is_stdin_pipe = not sys.stdin.isatty() if is_stdin_pipe: return sys.stdin.read() else: return None if __name__ == '__main__': cli() mistune-3.0.2/src/mistune/block_parser.py000066400000000000000000000371641450566212600205150ustar00rootroot00000000000000import re from typing import Optional, List, Tuple, Match from .util import ( unikey, escape_url, expand_tab, expand_leading_tab, ) from .core import Parser, BlockState from .helpers import ( LINK_LABEL, HTML_TAGNAME, HTML_ATTRIBUTES, BLOCK_TAGS, PRE_TAGS, unescape_char, parse_link_href, parse_link_title, ) from .list_parser import parse_list, LIST_PATTERN _INDENT_CODE_TRIM = re.compile(r'^ {1,4}', flags=re.M) _AXT_HEADING_TRIM = re.compile(r'(\s+|^)#+\s*$') _BLOCK_QUOTE_TRIM = re.compile(r'^ ?', flags=re.M) _BLOCK_QUOTE_LEADING = re.compile(r'^ *>', flags=re.M) _LINE_BLANK_END = re.compile(r'\n[ \t]*\n$') _BLANK_TO_LINE = re.compile(r'[ \t]*\n') _BLOCK_TAGS_PATTERN = '|'.join(BLOCK_TAGS) + '|' + '|'.join(PRE_TAGS) _OPEN_TAG_END = re.compile(HTML_ATTRIBUTES + r'[ \t]*>[ \t]*(?:\n|$)') _CLOSE_TAG_END = re.compile(r'[ \t]*>[ \t]*(?:\n|$)') _STRICT_BLOCK_QUOTE = re.compile(r'( {0,3}>[^\n]*(?:\n|$))+') class BlockParser(Parser): BLANK_LINE = re.compile(r'(^[ \t\v\f]*\n)+', re.M) RAW_HTML = ( r'^ {0,3}(' r'#{1,6})(?!#+)(?P[ \t]*|[ \t]+.*?)$', 'setex_heading': r'^ {0,3}(?P=|-){1,}[ \t]*$', 'fenced_code': ( r'^(?P {0,3})(?P`{3,}|~{3,})' r'[ \t]*(?P.*?)$' ), 'indent_code': ( r'^(?: {4}| *\t)[^\n]+(?:\n+|$)' r'((?:(?: {4}| *\t)[^\n]+(?:\n+|$))|\s)*' ), 'thematic_break': r'^ {0,3}((?:-[ \t]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})$', 'ref_link': r'^ {0,3}\[(?P' + LINK_LABEL + r')\]:', 'block_quote': r'^ {0,3}>(?P.*?)$', 'list': LIST_PATTERN, 'block_html': BLOCK_HTML, 'raw_html': RAW_HTML, } DEFAULT_RULES = ( 'fenced_code', 'indent_code', 'axt_heading', 'setex_heading', 'thematic_break', 'block_quote', 'list', 'ref_link', 'raw_html', 'blank_line', ) def __init__( self, block_quote_rules: Optional[List[str]]=None, list_rules: Optional[List[str]]=None, max_nested_level: int=6 ): super(BlockParser, self).__init__() if block_quote_rules is None: block_quote_rules = list(self.DEFAULT_RULES) if list_rules is None: list_rules = list(self.DEFAULT_RULES) self.block_quote_rules = block_quote_rules self.list_rules = list_rules self.max_nested_level = max_nested_level # register default parse methods self._methods = { name: getattr(self, 'parse_' + name) for name in self.SPECIFICATION } def parse_blank_line(self, m: Match, state: BlockState) -> int: """Parse token for blank lines.""" state.append_token({'type': 'blank_line'}) return m.end() def parse_thematic_break(self, m: Match, state: BlockState) -> int: """Parse token for thematic break, e.g. ``


    `` tag in HTML.""" state.append_token({'type': 'thematic_break'}) # $ does not count '\n' return m.end() + 1 def parse_indent_code(self, m: Match, state: BlockState) -> int: """Parse token for code block which is indented by 4 spaces.""" # it is a part of the paragraph end_pos = state.append_paragraph() if end_pos: return end_pos code = m.group(0) code = expand_leading_tab(code) code = _INDENT_CODE_TRIM.sub('', code) code = code.strip('\n') state.append_token({'type': 'block_code', 'raw': code, 'style': 'indent'}) return m.end() def parse_fenced_code(self, m: Match, state: BlockState) -> Optional[int]: """Parse token for fenced code block. A fenced code block is started with 3 or more backtick(`) or tilde(~). An example of a fenced code block: .. code-block:: markdown ```python def markdown(text): return mistune.html(text) ``` """ spaces = m.group('fenced_1') marker = m.group('fenced_2') info = m.group('fenced_3') c = marker[0] if info and c == '`': # CommonMark Example 145 # Info strings for backtick code blocks cannot contain backticks if info.find(c) != -1: return _end = re.compile( r'^ {0,3}' + c + '{' + str(len(marker)) + r',}[ \t]*(?:\n|$)', re.M) cursor_start = m.end() + 1 m2 = _end.search(state.src, cursor_start) if m2: code = state.src[cursor_start:m2.start()] end_pos = m2.end() else: code = state.src[cursor_start:] end_pos = state.cursor_max if spaces and code: _trim_pattern = re.compile('^ {0,' + str(len(spaces)) + '}', re.M) code = _trim_pattern.sub('', code) token = {'type': 'block_code', 'raw': code, 'style': 'fenced', 'marker': marker} if info: info = unescape_char(info) token['attrs'] = {'info': info.strip()} state.append_token(token) return end_pos def parse_axt_heading(self, m: Match, state: BlockState) -> int: """Parse token for AXT heading. An AXT heading is started with 1 to 6 symbol of ``#``.""" level = len(m.group('axt_1')) text = m.group('axt_2').strip() # remove last # if text: text = _AXT_HEADING_TRIM.sub('', text) token = {'type': 'heading', 'text': text, 'attrs': {'level': level}, 'style': 'axt'} state.append_token(token) return m.end() + 1 def parse_setex_heading(self, m: Match, state: BlockState) -> Optional[int]: """Parse token for setex style heading. A setex heading syntax looks like: .. code-block:: markdown H1 title ======== """ last_token = state.last_token() if last_token and last_token['type'] == 'paragraph': level = 1 if m.group('setext_1') == '=' else 2 last_token['type'] = 'heading' last_token['style'] = 'setext' last_token['attrs'] = {'level': level} return m.end() + 1 sc = self.compile_sc(['thematic_break', 'list']) m = sc.match(state.src, state.cursor) if m: return self.parse_method(m, state) def parse_ref_link(self, m: Match, state: BlockState) -> Optional[int]: """Parse link references and save the link information into ``state.env``. Here is an example of a link reference: .. code-block:: markdown a [link][example] [example]: https://example.com "Optional title" This method will save the link reference into ``state.env`` as:: state.env['ref_links']['example'] = { 'url': 'https://example.com', 'title': "Optional title", } """ end_pos = state.append_paragraph() if end_pos: return end_pos label = m.group('reflink_1') key = unikey(label) if not key: return href, href_pos = parse_link_href(state.src, m.end(), block=True) if href is None: return _blank = self.BLANK_LINE.search(state.src, href_pos) if _blank: max_pos = _blank.start() else: max_pos = state.cursor_max title, title_pos = parse_link_title(state.src, href_pos, max_pos) if title_pos: m = _BLANK_TO_LINE.match(state.src, title_pos) if m: title_pos = m.end() else: title_pos = None title = None if title_pos is None: m = _BLANK_TO_LINE.match(state.src, href_pos) if m: href_pos = m.end() else: href_pos = None href = None end_pos = title_pos or href_pos if not end_pos: return if key not in state.env['ref_links']: href = unescape_char(href) data = {'url': escape_url(href), 'label': label} if title: data['title'] = title state.env['ref_links'][key] = data return end_pos def extract_block_quote(self, m: Match, state: BlockState) -> Tuple[str, int]: """Extract text and cursor end position of a block quote.""" # cleanup at first to detect if it is code block text = m.group('quote_1') + '\n' text = expand_leading_tab(text, 3) text = _BLOCK_QUOTE_TRIM.sub('', text) sc = self.compile_sc(['blank_line', 'indent_code', 'fenced_code']) require_marker = bool(sc.match(text)) state.cursor = m.end() + 1 end_pos = None if require_marker: m = _STRICT_BLOCK_QUOTE.match(state.src, state.cursor) if m: quote = m.group(0) quote = _BLOCK_QUOTE_LEADING.sub('', quote) quote = expand_leading_tab(quote, 3) quote = _BLOCK_QUOTE_TRIM.sub('', quote) text += quote state.cursor = m.end() else: prev_blank_line = False break_sc = self.compile_sc([ 'blank_line', 'thematic_break', 'fenced_code', 'list', 'block_html', ]) while state.cursor < state.cursor_max: m = _STRICT_BLOCK_QUOTE.match(state.src, state.cursor) if m: quote = m.group(0) quote = _BLOCK_QUOTE_LEADING.sub('', quote) quote = expand_leading_tab(quote, 3) quote = _BLOCK_QUOTE_TRIM.sub('', quote) text += quote state.cursor = m.end() if not quote.strip(): prev_blank_line = True else: prev_blank_line = bool(_LINE_BLANK_END.search(quote)) continue if prev_blank_line: # CommonMark Example 249 # because of laziness, a blank line is needed between # a block quote and a following paragraph break m = break_sc.match(state.src, state.cursor) if m: end_pos = self.parse_method(m, state) if end_pos: break # lazy continuation line pos = state.find_line_end() line = state.get_text(pos) line = expand_leading_tab(line, 3) text += line state.cursor = pos # according to CommonMark Example 6, the second tab should be # treated as 4 spaces return expand_tab(text), end_pos def parse_block_quote(self, m: Match, state: BlockState) -> int: """Parse token for block quote. Here is an example of the syntax: .. code-block:: markdown > a block quote starts > with right arrows """ text, end_pos = self.extract_block_quote(m, state) # scan children state child = state.child_state(text) if state.depth() >= self.max_nested_level - 1: rules = list(self.block_quote_rules) rules.remove('block_quote') else: rules = self.block_quote_rules self.parse(child, rules) token = {'type': 'block_quote', 'children': child.tokens} if end_pos: state.prepend_token(token) return end_pos state.append_token(token) return state.cursor def parse_list(self, m: Match, state: BlockState) -> int: """Parse tokens for ordered and unordered list.""" return parse_list(self, m, state) def parse_block_html(self, m: Match, state: BlockState) -> Optional[int]: return self.parse_raw_html(m, state) def parse_raw_html(self, m: Match, state: BlockState) -> Optional[int]: marker = m.group(0).strip() # rule 2 if marker == '', m.end()) # rule 3 if marker == '', m.end()) # rule 5 if marker == '', m.end()) # rule 4 if marker.startswith('', m.end()) close_tag = None open_tag = None if marker.startswith('' return _parse_html_to_end(state, end_tag, m.end()) # rule 6 if open_tag in BLOCK_TAGS: return _parse_html_to_newline(state, self.BLANK_LINE) # Blocks of type 7 may not interrupt a paragraph. end_pos = state.append_paragraph() if end_pos: return end_pos # rule 7 start_pos = m.end() end_pos = state.find_line_end() if (open_tag and _OPEN_TAG_END.match(state.src, start_pos, end_pos)) or \ (close_tag and _CLOSE_TAG_END.match(state.src, start_pos, end_pos)): return _parse_html_to_newline(state, self.BLANK_LINE) def parse(self, state: BlockState, rules: Optional[List[str]]=None) -> None: sc = self.compile_sc(rules) while state.cursor < state.cursor_max: m = sc.search(state.src, state.cursor) if not m: break end_pos = m.start() if end_pos > state.cursor: text = state.get_text(end_pos) state.add_paragraph(text) state.cursor = end_pos end_pos = self.parse_method(m, state) if end_pos: state.cursor = end_pos else: end_pos = state.find_line_end() text = state.get_text(end_pos) state.add_paragraph(text) state.cursor = end_pos if state.cursor < state.cursor_max: text = state.src[state.cursor:] state.add_paragraph(text) state.cursor = state.cursor_max def _parse_html_to_end(state, end_marker, start_pos): marker_pos = state.src.find(end_marker, start_pos) if marker_pos == -1: text = state.src[state.cursor:] end_pos = state.cursor_max else: text = state.get_text(marker_pos) state.cursor = marker_pos end_pos = state.find_line_end() text += state.get_text(end_pos) state.append_token({'type': 'block_html', 'raw': text}) return end_pos def _parse_html_to_newline(state, newline): m = newline.search(state.src, state.cursor) if m: end_pos = m.start() text = state.get_text(end_pos) else: text = state.src[state.cursor:] end_pos = state.cursor_max state.append_token({'type': 'block_html', 'raw': text}) return end_pos mistune-3.0.2/src/mistune/core.py000066400000000000000000000136221450566212600167700ustar00rootroot00000000000000import re from typing import Dict, Any _LINE_END = re.compile(r'\n|$') class BlockState: """The state to save block parser's cursor and tokens.""" def __init__(self, parent=None): self.src = '' self.tokens = [] # current cursor position self.cursor = 0 self.cursor_max = 0 # for list and block quote chain self.list_tight = True self.parent = parent # for saving def references if parent: self.env = parent.env else: self.env = {'ref_links': {}} def child_state(self, src: str): child = self.__class__(self) child.process(src) return child def process(self, src: str): self.src = src self.cursor_max = len(src) def find_line_end(self): m = _LINE_END.search(self.src, self.cursor) return m.end() def get_text(self, end_pos: int): return self.src[self.cursor:end_pos] def last_token(self): if self.tokens: return self.tokens[-1] def prepend_token(self, token: Dict[str, Any]): """Insert token before the last token.""" self.tokens.insert(len(self.tokens) - 1, token) def append_token(self, token: Dict[str, Any]): """Add token to the end of token list.""" self.tokens.append(token) def add_paragraph(self, text: str): last_token = self.last_token() if last_token and last_token['type'] == 'paragraph': last_token['text'] += text else: self.tokens.append({'type': 'paragraph', 'text': text}) def append_paragraph(self): last_token = self.last_token() if last_token and last_token['type'] == 'paragraph': pos = self.find_line_end() last_token['text'] += self.get_text(pos) return pos def depth(self): d = 0 parent = self.parent while parent: d += 1 parent = parent.parent return d class InlineState: """The state to save inline parser's tokens.""" def __init__(self, env: Dict[str, Any]): self.env = env self.src = '' self.tokens = [] self.in_image = False self.in_link = False self.in_emphasis = False self.in_strong = False def prepend_token(self, token: Dict[str, Any]): """Insert token before the last token.""" self.tokens.insert(len(self.tokens) - 1, token) def append_token(self, token: Dict[str, Any]): """Add token to the end of token list.""" self.tokens.append(token) def copy(self): """Create a copy of current state.""" state = self.__class__(self.env) state.in_image = self.in_image state.in_link = self.in_link state.in_emphasis = self.in_emphasis state.in_strong = self.in_strong return state class Parser: sc_flag = re.M state_cls = BlockState SPECIFICATION = {} DEFAULT_RULES = [] def __init__(self): self.specification = self.SPECIFICATION.copy() self.rules = list(self.DEFAULT_RULES) self._methods = {} self.__sc = {} def compile_sc(self, rules=None): if rules is None: key = '$' rules = self.rules else: key = '|'.join(rules) sc = self.__sc.get(key) if sc: return sc regex = '|'.join(r'(?P<%s>%s)' % (k, self.specification[k]) for k in rules) sc = re.compile(regex, self.sc_flag) self.__sc[key] = sc return sc def register(self, name: str, pattern, func, before=None): """Register a new rule to parse the token. This method is usually used to create a new plugin. :param name: name of the new grammar :param pattern: regex pattern in string :param func: the parsing function :param before: insert this rule before a built-in rule """ self._methods[name] = lambda m, state: func(self, m, state) if pattern: self.specification[name] = pattern if name not in self.rules: self.insert_rule(self.rules, name, before=before) def register_rule(self, name, pattern, func): raise DeprecationWarning('This plugin is not compatible with mistune v3.') @staticmethod def insert_rule(rules, name, before=None): if before: try: index = rules.index(before) rules.insert(index, name) except ValueError: rules.append(name) else: rules.append(name) def parse_method(self, m, state): func = self._methods[m.lastgroup] return func(m, state) class BaseRenderer(object): NAME = 'base' def __init__(self): self.__methods = {} def register(self, name: str, method): """Register a render method for the named token. For example:: def render_wiki(renderer, key, title): return f'{title}' renderer.register('wiki', render_wiki) """ # bind self into renderer method self.__methods[name] = lambda *arg, **kwargs: method(self, *arg, **kwargs) def _get_method(self, name): try: return object.__getattribute__(self, name) except AttributeError: method = self.__methods.get(name) if not method: raise AttributeError('No renderer "{!r}"'.format(name)) return method def render_token(self, token, state): func = self._get_method(token['type']) return func(token, state) def iter_tokens(self, tokens, state): for tok in tokens: yield self.render_token(tok, state) def render_tokens(self, tokens, state): return ''.join(self.iter_tokens(tokens, state)) def __call__(self, tokens, state): return self.render_tokens(tokens, state) mistune-3.0.2/src/mistune/directives/000077500000000000000000000000001450566212600176235ustar00rootroot00000000000000mistune-3.0.2/src/mistune/directives/__init__.py000066400000000000000000000014521450566212600217360ustar00rootroot00000000000000from ._base import DirectiveParser, BaseDirective, DirectivePlugin from ._rst import RSTDirective from ._fenced import FencedDirective from .admonition import Admonition from .toc import TableOfContents from .include import Include from .image import Image, Figure class RstDirective(RSTDirective): # pragma: no cover def __init__(self, plugins): super(RstDirective, self).__init__(plugins) import warnings warnings.warn( "'RstDirective' is deprecated, please use 'RSTDirective' instead.", DeprecationWarning, stacklevel=2, ) __all__ = [ 'DirectiveParser', 'BaseDirective', 'DirectivePlugin', 'RSTDirective', 'FencedDirective', 'Admonition', 'TableOfContents', 'Include', 'Image', 'Figure', ] mistune-3.0.2/src/mistune/directives/_base.py000066400000000000000000000060661450566212600212560ustar00rootroot00000000000000import re class DirectiveParser: name = 'directive' @staticmethod def parse_type(m: re.Match): raise NotImplementedError() @staticmethod def parse_title(m: re.Match): raise NotImplementedError() @staticmethod def parse_content(m: re.Match): raise NotImplementedError() @classmethod def parse_tokens(cls, block, text, state): if state.depth() >= block.max_nested_level - 1 and cls.name in block.rules: rules = list(block.rules) rules.remove(cls.name) else: rules = block.rules child = state.child_state(text) block.parse(child, rules) return child.tokens @staticmethod def parse_options(m: re.Match): text = m.group('options') if not text.strip(): return [] options = [] for line in re.split(r'\n+', text): line = line.strip()[1:] if not line: continue i = line.find(':') k = line[:i] v = line[i + 1:].strip() options.append((k, v)) return options class BaseDirective: parser = DirectiveParser directive_pattern = None def __init__(self, plugins): self._methods = {} self.__plugins = plugins def register(self, name, fn): self._methods[name] = fn def parse_method(self, block, m, state): _type = self.parser.parse_type(m) method = self._methods.get(_type) if method: try: token = method(block, m, state) except ValueError as e: token = {'type': 'block_error', 'raw': str(e)} else: text = m.group(0) token = { 'type': 'block_error', 'raw': text, } if isinstance(token, list): for tok in token: state.append_token(tok) else: state.append_token(token) return token def parse_directive(self, block, m, state): raise NotImplementedError() def register_block_parser(self, md, before=None): md.block.register( self.parser.name, self.directive_pattern, self.parse_directive, before=before, ) def __call__(self, md): for plugin in self.__plugins: plugin.parser = self.parser plugin(self, md) class DirectivePlugin: def __init__(self): self.parser = None def parse_options(self, m: re.Match): return self.parser.parse_options(m) def parse_type(self, m: re.Match): return self.parser.parse_type(m) def parse_title(self, m: re.Match): return self.parser.parse_title(m) def parse_content(self, m: re.Match): return self.parser.parse_content(m) def parse_tokens(self, block, text, state): return self.parser.parse_tokens(block, text, state) def parse(self, block, m, state): raise NotImplementedError() def __call__(self, md): raise NotImplementedError() mistune-3.0.2/src/mistune/directives/_fenced.py000066400000000000000000000104021450566212600215550ustar00rootroot00000000000000import re from ._base import DirectiveParser, BaseDirective __all__ = ['FencedDirective'] _type_re = re.compile(r'^ *\{[a-zA-Z0-9_-]+\}') _directive_re = re.compile( r'\{(?P[a-zA-Z0-9_-]+)\} *(?P[^\n]*)(?:\n|$)' r'(?P<options>(?:\:[a-zA-Z0-9_-]+\: *[^\n]*\n+)*)' r'\n*(?P<text>(?:[^\n]*\n+)*)' ) class FencedParser(DirectiveParser): name = 'fenced_directive' @staticmethod def parse_type(m: re.Match): return m.group('type') @staticmethod def parse_title(m: re.Match): return m.group('title') @staticmethod def parse_content(m: re.Match): return m.group('text') class FencedDirective(BaseDirective): """A **fenced** style of directive looks like a fenced code block, it is inspired by markdown-it-docutils. The syntax looks like: .. code-block:: text ```{directive-type} title :option-key: option value :option-key: option value content text here ``` To use ``FencedDirective``, developers can add it into plugin list in the :class:`Markdown` instance: .. code-block:: python import mistune from mistune.directives import FencedDirective, Admonition md = mistune.create_markdown(plugins=[ # ... FencedDirective([Admonition()]), ]) FencedDirective is using >= 3 backticks or curly-brackets for the fenced syntax. Developers can change it to other characters, e.g. colon: .. code-block:: python directive = FencedDirective([Admonition()], ':') And then the directive syntax would look like: .. code-block:: text ::::{note} Nesting directives You can nest directives by ensuring the start and end fence matching the length. For instance, in this example, the admonition is started with 4 colons, then it should end with 4 colons. You can nest another admonition with other length of colons except 4. :::{tip} Longer outermost fence It would be better that you put longer markers for the outer fence, and shorter markers for the inner fence. In this example, we put 4 colons outsie, and 3 colons inside. ::: :::: :param plugins: list of directive plugins :param markers: characters to determine the fence, default is backtick and curly-bracket """ parser = FencedParser def __init__(self, plugins, markers='`~'): super(FencedDirective, self).__init__(plugins) self.markers = markers _marker_pattern = '|'.join(re.escape(c) for c in markers) self.directive_pattern = ( r'^(?P<fenced_directive_mark>(?:' + _marker_pattern + r'){3,})' r'\{[a-zA-Z0-9_-]+\}' ) def _process_directive(self, block, marker, start, state): mlen = len(marker) cursor_start = start + len(marker) _end_pattern = ( r'^ {0,3}' + marker[0] + '{' + str(mlen) + r',}' r'[ \t]*(?:\n|$)' ) _end_re = re.compile(_end_pattern, re.M) _end_m = _end_re.search(state.src, cursor_start) if _end_m: text = state.src[cursor_start:_end_m.start()] end_pos = _end_m.end() else: text = state.src[cursor_start:] end_pos = state.cursor_max m = _directive_re.match(text) if not m: return self.parse_method(block, m, state) return end_pos def parse_directive(self, block, m, state): marker = m.group('fenced_directive_mark') return self._process_directive(block, marker, m.start(), state) def parse_fenced_code(self, block, m, state): info = m.group('fenced_3') if not info or not _type_re.match(info): return block.parse_fenced_code(m, state) if state.depth() >= block.max_nested_level: return block.parse_fenced_code(m, state) marker = m.group('fenced_2') return self._process_directive(block, marker, m.start(), state) def __call__(self, md): super(FencedDirective, self).__call__(md) if self.markers == '`~': md.block.register('fenced_code', None, self.parse_fenced_code) else: self.register_block_parser(md, 'fenced_code') ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/directives/_rst.py��������������������������������������������������������0000664�0000000�0000000�00000003655�14505662126�0021155�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ._base import DirectiveParser, BaseDirective __all__ = ['RSTDirective'] _directive_re = re.compile( r'\.\.( +)(?P<type>[a-zA-Z0-9_-]+)\:\: *(?P<title>[^\n]*)(?:\n|$)' r'(?P<options>(?: \1 {0,3}\:[a-zA-Z0-9_-]+\: *[^\n]*\n+)*)' r'\n*(?P<text>(?: \1 {0,3}[^\n]*\n+)*)' ) class RSTParser(DirectiveParser): name = 'rst_directive' @staticmethod def parse_type(m: re.Match): return m.group('type') @staticmethod def parse_title(m: re.Match): return m.group('title') @staticmethod def parse_content(m: re.Match): full_content = m.group(0) text = m.group('text') pretext = full_content[:-len(text)] leading = len(m.group(1)) + 2 return '\n'.join(line[leading:] for line in text.splitlines()) + '\n' class RSTDirective(BaseDirective): """A RST style of directive syntax is inspired by reStructuredText. The syntax is very powerful that you can define a lot of custom features on your own. The syntax looks like: .. code-block:: text .. directive-type:: directive value :option-key: option value :option-key: option value content text here To use ``RSTDirective``, developers can add it into plugin list in the :class:`Markdown` instance: .. code-block:: python import mistune from mistune.directives import RSTDirective, Admonition md = mistune.create_markdown(plugins=[ # ... RSTDirective([Admonition()]), ]) """ parser = RSTParser directive_pattern = r'^\.\. +[a-zA-Z0-9_-]+\:\:' def parse_directive(self, block, m, state): m = _directive_re.match(state.src, state.cursor) if not m: return self.parse_method(block, m, state) return m.end() def __call__(self, md): super(RSTDirective, self).__call__(md) self.register_block_parser(md) �����������������������������������������������������������������������������������mistune-3.0.2/src/mistune/directives/admonition.py��������������������������������������������������0000664�0000000�0000000�00000003333�14505662126�0022340�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from ._base import DirectivePlugin class Admonition(DirectivePlugin): SUPPORTED_NAMES = { "attention", "caution", "danger", "error", "hint", "important", "note", "tip", "warning", } def parse(self, block, m, state): name = self.parse_type(m) attrs = {'name': name} options = dict(self.parse_options(m)) if 'class' in options: attrs['class'] = options['class'] title = self.parse_title(m) if not title: title = name.capitalize() content = self.parse_content(m) children = [ { 'type': 'admonition_title', 'text': title, }, { 'type': 'admonition_content', 'children': self.parse_tokens(block, content, state), } ] return { 'type': 'admonition', 'children': children, 'attrs': attrs, } def __call__(self, directive, md): for name in self.SUPPORTED_NAMES: directive.register(name, self.parse) if md.renderer.NAME == 'html': md.renderer.register('admonition', render_admonition) md.renderer.register('admonition_title', render_admonition_title) md.renderer.register('admonition_content', render_admonition_content) def render_admonition(self, text, name, **attrs): html = '<section class="admonition ' + name _cls = attrs.get('class') if _cls: html += ' ' + _cls return html + '">\n' + text + '</section>\n' def render_admonition_title(self, text): return '<p class="admonition-title">' + text + '</p>\n' def render_admonition_content(self, text): return text �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/directives/image.py�������������������������������������������������������0000664�0000000�0000000�00000010540�14505662126�0021257�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ._base import DirectivePlugin from ..util import escape as escape_text, escape_url __all__ = ['Image', 'Figure'] _num_re = re.compile(r'^\d+(?:\.\d*)?') _allowed_aligns = ["top", "middle", "bottom", "left", "center", "right"] def _parse_attrs(options): attrs = {} if 'alt' in options: attrs['alt'] = options['alt'] # validate align align = options.get('align') if align and align in _allowed_aligns: attrs['align'] = align height = options.get('height') width = options.get('width') if height and _num_re.match(height): attrs['height'] = height if width and _num_re.match(width): attrs['width'] = width if 'target' in options: attrs['target'] = escape_url(options['target']) return attrs class Image(DirectivePlugin): NAME = 'image' def parse(self, block, m, state): options = dict(self.parse_options(m)) attrs = _parse_attrs(options) attrs['src'] = self.parse_title(m) return {'type': 'block_image', 'attrs': attrs} def __call__(self, directive, md): directive.register(self.NAME, self.parse) if md.renderer.NAME == 'html': md.renderer.register('block_image', render_block_image) def render_block_image(self, src: str, alt=None, width=None, height=None, **attrs): img = '<img src="' + src + '"' style = '' if alt: img += ' alt="' + escape_text(alt) + '"' if width: if width.isdigit(): img += ' width="' + width + '"' else: style += 'width:' + width + ';' if height: if height.isdigit(): img += ' height="' + height + '"' else: style += 'height:' + height + ';' if style: img += ' style="' + escape_text(style) + '"' img += ' />' _cls = 'block-image' align = attrs.get('align') if align: _cls += ' align-' + align target = attrs.get('target') if target: href = escape_text(self.safe_url(target)) outer = '<a class="' + _cls + '" href="' + href + '">' return outer + img + '</a>\n' else: return '<div class="' + _cls + '">' + img + '</div>\n' class Figure(DirectivePlugin): NAME = 'figure' def parse_directive_content(self, block, m, state): content = self.parse_content(m) if not content: return tokens = self.parse_tokens(block, content, state) caption = tokens[0] if caption['type'] == 'paragraph': caption['type'] = 'figcaption' children = [caption] if len(tokens) > 1: children.append({ 'type': 'legend', 'children': tokens[1:] }) return children def parse(self, block, m, state): options = dict(self.parse_options(m)) image_attrs = _parse_attrs(options) image_attrs['src'] = self.parse_title(m) align = image_attrs.pop('align', None) fig_attrs = {} if align: fig_attrs['align'] = align for k in ['figwidth', 'figclass']: if k in options: fig_attrs[k] = options[k] children = [{'type': 'block_image', 'attrs': image_attrs}] content = self.parse_directive_content(block, m, state) if content: children.extend(content) return { 'type': 'figure', 'attrs': fig_attrs, 'children': children, } def __call__(self, directive, md): directive.register(self.NAME, self.parse) if md.renderer.NAME == 'html': md.renderer.register('figure', render_figure) md.renderer.register('block_image', render_block_image) md.renderer.register('figcaption', render_figcaption) md.renderer.register('legend', render_legend) def render_figure(self, text, align=None, figwidth=None, figclass=None): _cls = 'figure' if align: _cls += ' align-' + align if figclass: _cls += ' ' + figclass html = '<figure class="' + _cls + '"' if figwidth: html += ' style="width:' + figwidth + '"' return html + '>\n' + text + '</figure>\n' def render_figcaption(self, text): return '<figcaption>' + text + '</figcaption>\n' def render_legend(self, text): return '<div class="legend">\n' + text + '</div>\n' ����������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/directives/include.py�����������������������������������������������������0000664�0000000�0000000�00000003671�14505662126�0021627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os from ._base import DirectivePlugin class Include(DirectivePlugin): def parse(self, block, m, state): source_file = state.env.get('__file__') if not source_file: return {'type': 'block_error', 'raw': 'Missing source file'} encoding = 'utf-8' options = self.parse_options(m) if options: attrs = dict(options) if 'encoding' in attrs: encoding = attrs['encoding'] else: attrs = {} relpath = self.parse_title(m) dest = os.path.join(os.path.dirname(source_file), relpath) dest = os.path.normpath(dest) if dest == source_file: return { 'type': 'block_error', 'raw': 'Could not include self: ' + relpath, } if not os.path.isfile(dest): return { 'type': 'block_error', 'raw': 'Could not find file: ' + relpath, } with open(dest, 'rb') as f: content = f.read() content = content.decode(encoding) ext = os.path.splitext(relpath)[1] if ext in {'.md', '.markdown', '.mkd'}: new_state = block.state_cls() new_state.env['__file__'] = dest new_state.process(content) block.parse(new_state) return new_state.tokens elif ext in {'.html', '.xhtml', '.htm'}: return {'type': 'block_html', 'raw': content} attrs['filepath'] = dest return { 'type': 'include', 'raw': content, 'attrs': attrs, } def __call__(self, directive, md): directive.register('include', self.parse) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('include', render_html_include) def render_html_include(renderer, text, **attrs): return '<pre class="directive-include">\n' + text + '</pre>\n' �����������������������������������������������������������������������mistune-3.0.2/src/mistune/directives/toc.py���������������������������������������������������������0000664�0000000�0000000�00000006666�14505662126�0021000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" TOC directive ~~~~~~~~~~~~~ The TOC directive syntax looks like:: .. toc:: Title :min-level: 1 :max-level: 3 "Title", "min-level", and "max-level" option can be empty. "min-level" and "max-level" are integers >= 1 and <= 6, which define the allowed heading levels writers want to include in the table of contents. """ from ._base import DirectivePlugin from ..toc import normalize_toc_item, render_toc_ul class TableOfContents(DirectivePlugin): def __init__(self, min_level=1, max_level=3): self.min_level = min_level self.max_level = max_level def generate_heading_id(self, token, index): return 'toc_' + str(index + 1) def parse(self, block, m, state): title = self.parse_title(m) options = self.parse_options(m) if options: d_options = dict(options) collapse = 'collapse' in d_options min_level = _normalize_level(d_options, 'min-level', self.min_level) max_level = _normalize_level(d_options, 'max-level', self.max_level) if min_level < self.min_level: raise ValueError(f'"min-level" option MUST be >= {self.min_level}') if max_level > self.max_level: raise ValueError(f'"max-level" option MUST be <= {self.max_level}') if min_level > max_level: raise ValueError('"min-level" option MUST be less than "max-level" option') else: collapse = False min_level = self.min_level max_level = self.max_level attrs = { 'min_level': min_level, 'max_level': max_level, 'collapse': collapse, } return {'type': 'toc', 'text': title or '', 'attrs': attrs} def toc_hook(self, md, state): sections = [] headings = [] for tok in state.tokens: if tok['type'] == 'toc': sections.append(tok) elif tok['type'] == 'heading': headings.append(tok) if sections: toc_items = [] # adding ID for each heading for i, tok in enumerate(headings): tok['attrs']['id'] = self.generate_heading_id(tok, i) toc_items.append(normalize_toc_item(md, tok)) for sec in sections: _min = sec['attrs']['min_level'] _max = sec['attrs']['max_level'] toc = [item for item in toc_items if _min <= item[0] <= _max] sec['attrs']['toc'] = toc def __call__(self, directive, md): if md.renderer and md.renderer.NAME == 'html': # only works with HTML renderer directive.register('toc', self.parse) md.before_render_hooks.append(self.toc_hook) md.renderer.register('toc', render_html_toc) def render_html_toc(renderer, title, collapse=False, **attrs): if not title: title = 'Table of Contents' toc = attrs['toc'] content = render_toc_ul(attrs['toc']) html = '<details class="toc"' if not collapse: html += ' open' html += '>\n<summary>' + title + '</summary>\n' return html + content + '</details>\n' def _normalize_level(options, name, default): level = options.get(name) if not level: return default try: return int(level) except (ValueError, TypeError): raise ValueError(f'"{name}" option MUST be integer') ��������������������������������������������������������������������������mistune-3.0.2/src/mistune/helpers.py����������������������������������������������������������������0000664�0000000�0000000�00000007247�14505662126�0017510�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re import string from .util import escape_url PREVENT_BACKSLASH = r'(?<!\\)(?:\\\\)*' PUNCTUATION = r'[' + re.escape(string.punctuation) + r']' LINK_LABEL = r'(?:[^\\\[\]]|\\.){0,500}' LINK_BRACKET_START = re.compile(r'[ \t]*\n?[ \t]*<') LINK_BRACKET_RE = re.compile(r'<([^<>\n\\\x00]*)>') LINK_HREF_BLOCK_RE = re.compile(r'[ \t]*\n?[ \t]*([^\s]+)(?:\s|$)') LINK_HREF_INLINE_RE = re.compile( r'[ \t]*\n?[ \t]*([^ \t\n]*?)(?:[ \t\n]|' r'(?:' + PREVENT_BACKSLASH + r'\)))' ) LINK_TITLE_RE = re.compile( r'[ \t\n]+(' r'"(?:\\' + PUNCTUATION + r'|[^"\x00])*"|' # "title" r"'(?:\\" + PUNCTUATION + r"|[^'\x00])*'" # 'title' r')' ) PAREN_END_RE = re.compile(r'\s*\)') HTML_TAGNAME = r'[A-Za-z][A-Za-z0-9-]*' HTML_ATTRIBUTES = ( r'(?:\s+[A-Za-z_:][A-Za-z0-9_.:-]*' r'(?:\s*=\s*(?:[^ !"\'=<>`]+|\'[^\']*?\'|"[^\"]*?"))?)*' ) BLOCK_TAGS = ( 'address', 'article', 'aside', 'base', 'basefont', 'blockquote', 'body', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dialog', 'dir', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hr', 'html', 'iframe', 'legend', 'li', 'link', 'main', 'menu', 'menuitem', 'meta', 'nav', 'noframes', 'ol', 'optgroup', 'option', 'p', 'param', 'section', 'source', 'summary', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul' ) PRE_TAGS = ('pre', 'script', 'style', 'textarea') _INLINE_LINK_LABEL_RE = re.compile(LINK_LABEL + r'\]') _INLINE_SQUARE_BRACKET_RE = re.compile(PREVENT_BACKSLASH + r'[\[\]]') _ESCAPE_CHAR_RE = re.compile(r'\\(' + PUNCTUATION + r')') def unescape_char(text): return _ESCAPE_CHAR_RE.sub(r'\1', text) def parse_link_text(src, pos): level = 1 found = False start_pos = pos while pos < len(src): m = _INLINE_SQUARE_BRACKET_RE.search(src, pos) if not m: break pos = m.end() marker = m.group(0) if marker == ']': level -= 1 if level == 0: found = True break else: level += 1 if found: text = src[start_pos:pos-1] return text, pos return None, None def parse_link_label(src, start_pos): m = _INLINE_LINK_LABEL_RE.match(src, start_pos) if m: label = m.group(0)[:-1] return label, m.end() return None, None def parse_link_href(src, start_pos, block=False): m = LINK_BRACKET_START.match(src, start_pos) if m: start_pos = m.end() - 1 m = LINK_BRACKET_RE.match(src, start_pos) if m: return m.group(1), m.end() return None, None if block: m = LINK_HREF_BLOCK_RE.match(src, start_pos) else: m = LINK_HREF_INLINE_RE.match(src, start_pos) if not m: return None, None end_pos = m.end() href = m.group(1) if block and src[end_pos - 1] == href[-1]: return href, end_pos return href, end_pos - 1 def parse_link_title(src, start_pos, max_pos): m = LINK_TITLE_RE.match(src, start_pos, max_pos) if m: title = m.group(1)[1:-1] title = unescape_char(title) return title, m.end() return None, None def parse_link(src, pos): href, href_pos = parse_link_href(src, pos) if href is None: return None, None title, title_pos = parse_link_title(src, href_pos, len(src)) next_pos = title_pos or href_pos m = PAREN_END_RE.match(src, next_pos) if not m: return None, None href = unescape_char(href) attrs = {'url': escape_url(href)} if title: attrs['title'] = title return attrs, m.end() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/inline_parser.py����������������������������������������������������������0000664�0000000�0000000�00000027357�14505662126�0020704�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from typing import Optional, List, Dict, Any, Match from .core import Parser, InlineState from .util import ( escape, escape_url, unikey, ) from .helpers import ( PREVENT_BACKSLASH, PUNCTUATION, HTML_TAGNAME, HTML_ATTRIBUTES, unescape_char, parse_link, parse_link_label, parse_link_text, ) PAREN_END_RE = re.compile(r'\s*\)') AUTO_EMAIL = ( r'''<[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]''' r'(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?' r'(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*>' ) INLINE_HTML = ( r'<' + HTML_TAGNAME + HTML_ATTRIBUTES + r'\s*/?>|' # open tag r'</' + HTML_TAGNAME + r'\s*>|' # close tag r'<!--(?!>|->)(?:(?!--)[\s\S])+?(?<!-)-->|' # comment r'<\?[\s\S]+?\?>|' # script like <?php?> r'<![A-Z][\s\S]+?>|' # doctype r'<!\[CDATA[\s\S]+?\]\]>' # cdata ) EMPHASIS_END_RE = { '*': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\\*|[^\s*])\*(?!\*)'), '_': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\_|[^\s_])_(?!_)\b'), '**': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\\*|[^\s*])\*\*(?!\*)'), '__': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\_|[^\s_])__(?!_)\b'), '***': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\\*|[^\s*])\*\*\*(?!\*)'), '___': re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\_|[^\s_])___(?!_)\b'), } class InlineParser(Parser): sc_flag = 0 state_cls = InlineState #: linebreak leaves two spaces at the end of line STD_LINEBREAK = r'(?:\\| {2,})\n\s*' #: every new line becomes <br> HARD_LINEBREAK = r' *\n\s*' # we only need to find the start pattern of an inline token SPECIFICATION = { # e.g. \`, \$ 'escape': r'(?:\\' + PUNCTUATION + ')+', # `code, ```code 'codespan': r'`{1,}', # *w, **w, _w, __w 'emphasis': r'\*{1,3}(?=[^\s*])|\b_{1,3}(?=[^\s_])', # [link], ![img] 'link': r'!?\[', # <https://example.com>. regex copied from commonmark.js 'auto_link': r'<[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*>', 'auto_email': AUTO_EMAIL, 'inline_html': INLINE_HTML, 'linebreak': STD_LINEBREAK, 'softbreak': HARD_LINEBREAK, 'prec_auto_link': r'<[A-Za-z][A-Za-z\d.+-]{1,31}:', 'prec_inline_html': r'</?' + HTML_TAGNAME + r'|<!|<\?', } DEFAULT_RULES = ( 'escape', 'codespan', 'emphasis', 'link', 'auto_link', 'auto_email', 'inline_html', 'linebreak', ) def __init__(self, hard_wrap: bool=False): super(InlineParser, self).__init__() self.hard_wrap = hard_wrap # lazy add linebreak if hard_wrap: self.specification['linebreak'] = self.HARD_LINEBREAK else: self.rules.append('softbreak') self._methods = { name: getattr(self, 'parse_' + name) for name in self.rules } def parse_escape(self, m: Match, state: InlineState) -> int: text = m.group(0) text = unescape_char(text) state.append_token({ 'type': 'text', 'raw': text, }) return m.end() def parse_link(self, m: Match, state: InlineState) -> Optional[int]: pos = m.end() marker = m.group(0) is_image = marker[0] == '!' if is_image and state.in_image: state.append_token({'type': 'text', 'raw': marker}) return pos elif not is_image and state.in_link: state.append_token({'type': 'text', 'raw': marker}) return pos text = None label, end_pos = parse_link_label(state.src, pos) if label is None: text, end_pos = parse_link_text(state.src, pos) if text is None: return if text is None: text = label if end_pos >= len(state.src) and label is None: return rules = ['codespan', 'prec_auto_link', 'prec_inline_html'] prec_pos = self.precedence_scan(m, state, end_pos, rules) if prec_pos: return prec_pos if end_pos < len(state.src): c = state.src[end_pos] if c == '(': # standard link [text](<url> "title") attrs, pos2 = parse_link(state.src, end_pos + 1) if pos2: token = self.__parse_link_token(is_image, text, attrs, state) state.append_token(token) return pos2 elif c == '[': # standard ref link [text][label] label2, pos2 = parse_link_label(state.src, end_pos + 1) if pos2: end_pos = pos2 if label2: label = label2 if label is None: return ref_links = state.env.get('ref_links') if not ref_links: return key = unikey(label) env = ref_links.get(key) if env: attrs = {'url': env['url'], 'title': env.get('title')} token = self.__parse_link_token(is_image, text, attrs, state) token['ref'] = key token['label'] = label state.append_token(token) return end_pos def __parse_link_token(self, is_image, text, attrs, state): new_state = state.copy() new_state.src = text if is_image: new_state.in_image = True token = { 'type': 'image', 'children': self.render(new_state), 'attrs': attrs, } else: new_state.in_link = True token = { 'type': 'link', 'children': self.render(new_state), 'attrs': attrs, } return token def parse_auto_link(self, m: Match, state: InlineState) -> int: text = m.group(0) pos = m.end() if state.in_link: self.process_text(text, state) return pos text = text[1:-1] self._add_auto_link(text, text, state) return pos def parse_auto_email(self, m: Match, state: InlineState) -> int: text = m.group(0) pos = m.end() if state.in_link: self.process_text(text, state) return pos text = text[1:-1] url = 'mailto:' + text self._add_auto_link(url, text, state) return pos def _add_auto_link(self, url, text, state): state.append_token({ 'type': 'link', 'children': [{'type': 'text', 'raw': text}], 'attrs': {'url': escape_url(url)}, }) def parse_emphasis(self, m: Match, state: InlineState) -> int: pos = m.end() marker = m.group(0) mlen = len(marker) if mlen == 1 and state.in_emphasis: state.append_token({'type': 'text', 'raw': marker}) return pos elif mlen == 2 and state.in_strong: state.append_token({'type': 'text', 'raw': marker}) return pos _end_re = EMPHASIS_END_RE[marker] m1 = _end_re.search(state.src, pos) if not m1: state.append_token({'type': 'text', 'raw': marker}) return pos end_pos = m1.end() text = state.src[pos:end_pos-mlen] prec_pos = self.precedence_scan(m, state, end_pos) if prec_pos: return prec_pos new_state = state.copy() new_state.src = text if mlen == 1: new_state.in_emphasis = True children = self.render(new_state) state.append_token({'type': 'emphasis', 'children': children}) elif mlen == 2: new_state.in_strong = True children = self.render(new_state) state.append_token({'type': 'strong', 'children': children}) else: new_state.in_emphasis = True new_state.in_strong = True children = [{ 'type': 'strong', 'children': self.render(new_state) }] state.append_token({ 'type': 'emphasis', 'children': children, }) return end_pos def parse_codespan(self, m: Match, state: InlineState) -> int: marker = m.group(0) # require same marker with same length at end pattern = re.compile(r'(.*?[^`])' + marker + r'(?!`)', re.S) pos = m.end() m = pattern.match(state.src, pos) if m: end_pos = m.end() code = m.group(1) # Line endings are treated like spaces code = code.replace('\n', ' ') if len(code.strip()): if code.startswith(' ') and code.endswith(' '): code = code[1:-1] state.append_token({'type': 'codespan', 'raw': escape(code)}) return end_pos else: state.append_token({'type': 'text', 'raw': marker}) return pos def parse_linebreak(self, m: Match, state: InlineState) -> int: state.append_token({'type': 'linebreak'}) return m.end() def parse_softbreak(self, m: Match, state: InlineState) -> int: state.append_token({'type': 'softbreak'}) return m.end() def parse_inline_html(self, m: Match, state: InlineState) -> int: end_pos = m.end() html = m.group(0) state.append_token({'type': 'inline_html', 'raw': html}) if html.startswith(('<a ', '<a>', '<A ', '<A>')): state.in_link = True elif html.startswith(('</a ', '</a>', '</A ', '</A>')): state.in_link = False return end_pos def process_text(self, text: str, state: InlineState): state.append_token({'type': 'text', 'raw': text}) def parse(self, state: InlineState) -> List[Dict[str, Any]]: pos = 0 sc = self.compile_sc() while pos < len(state.src): m = sc.search(state.src, pos) if not m: break end_pos = m.start() if end_pos > pos: hole = state.src[pos:end_pos] self.process_text(hole, state) new_pos = self.parse_method(m, state) if not new_pos: # move cursor 1 character forward pos = end_pos + 1 hole = state.src[end_pos:pos] self.process_text(hole, state) else: pos = new_pos if pos == 0: # special case, just pure text self.process_text(state.src, state) elif pos < len(state.src): self.process_text(state.src[pos:], state) return state.tokens def precedence_scan(self, m: Match, state: InlineState, end_pos: int, rules=None): if rules is None: rules = ['codespan', 'link', 'prec_auto_link', 'prec_inline_html'] mark_pos = m.end() sc = self.compile_sc(rules) m1 = sc.search(state.src, mark_pos, end_pos) if not m1: return rule_name = m1.lastgroup.replace('prec_', '') sc = self.compile_sc([rule_name]) m2 = sc.match(state.src, m1.start()) if not m2: return func = self._methods[rule_name] new_state = state.copy() new_state.src = state.src m2_pos = func(m2, new_state) if not m2_pos or m2_pos < end_pos: return raw_text = state.src[m.start():m2.start()] state.append_token({'type': 'text', 'raw': raw_text}) for token in new_state.tokens: state.append_token(token) return m2_pos def render(self, state: InlineState): self.parse(state) return state.tokens def __call__(self, s, env): state = self.state_cls(env) state.src = s return self.render(state) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/list_parser.py������������������������������������������������������������0000664�0000000�0000000�00000016003�14505662126�0020363�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from .core import BlockState from .util import ( strip_end, expand_tab, expand_leading_tab, ) # because list is complex, split list parser in a new file LIST_PATTERN = ( r'^(?P<list_1> {0,3})' r'(?P<list_2>[\*\+-]|\d{1,9}[.)])' r'(?P<list_3>[ \t]*|[ \t].+)$' ) _LINE_HAS_TEXT = re.compile(r'( *)\S') def parse_list(block, m: re.Match, state: BlockState) -> int: """Parse tokens for ordered and unordered list.""" text = m.group('list_3') if not text.strip(): # Example 285 # an empty list item cannot interrupt a paragraph end_pos = state.append_paragraph() if end_pos: return end_pos marker = m.group('list_2') ordered = len(marker) > 1 depth = state.depth() token = { 'type': 'list', 'children': [], 'tight': True, 'bullet': marker[-1], 'attrs': { 'depth': depth, 'ordered': ordered, }, } if ordered: start = int(marker[:-1]) if start != 1: # Example 304 # we allow only lists starting with 1 to interrupt paragraphs end_pos = state.append_paragraph() if end_pos: return end_pos token['attrs']['start'] = start state.cursor = m.end() + 1 groups = (m.group('list_1'), marker, text) if depth >= block.max_nested_level - 1: rules = list(block.list_rules) rules.remove('list') else: rules = block.list_rules bullet = _get_list_bullet(marker[-1]) while groups: groups = _parse_list_item(block, bullet, groups, token, state, rules) end_pos = token.pop('_end_pos', None) _transform_tight_list(token) if end_pos: index = token.pop('_tok_index') state.tokens.insert(index, token) return end_pos state.append_token(token) return state.cursor def _transform_tight_list(token): if token['tight']: # reset tight list item for list_item in token['children']: for tok in list_item['children']: if tok['type'] == 'paragraph': tok['type'] = 'block_text' elif tok['type'] == 'list': _transform_tight_list(tok) def _parse_list_item(block, bullet, groups, token, state, rules): spaces, marker, text = groups leading_width = len(spaces) + len(marker) text, continue_width = _compile_continue_width(text, leading_width) item_pattern = _compile_list_item_pattern(bullet, leading_width) pairs = [ ('thematic_break', block.specification['thematic_break']), ('fenced_code', block.specification['fenced_code']), ('axt_heading', block.specification['axt_heading']), ('block_quote', block.specification['block_quote']), ('block_html', block.specification['block_html']), ('list', block.specification['list']), ] if leading_width < 3: _repl_w = str(leading_width) pairs = [(n, p.replace('3', _repl_w, 1)) for n, p in pairs] pairs.insert(1, ('list_item', item_pattern)) regex = '|'.join(r'(?P<%s>(?<=\n)%s)' % pair for pair in pairs) sc = re.compile(regex, re.M) src = '' next_group = None prev_blank_line = False pos = state.cursor continue_space = ' ' * continue_width while pos < state.cursor_max: pos = state.find_line_end() line = state.get_text(pos) if block.BLANK_LINE.match(line): src += '\n' prev_blank_line = True state.cursor = pos continue line = expand_leading_tab(line) if line.startswith(continue_space): if prev_blank_line and not text and not src.strip(): # Example 280 # A list item can begin with at most one blank line break src += line prev_blank_line = False state.cursor = pos continue m = sc.match(state.src, state.cursor) if m: tok_type = m.lastgroup if tok_type == 'list_item': if prev_blank_line: token['tight'] = False next_group = ( m.group('listitem_1'), m.group('listitem_2'), m.group('listitem_3') ) state.cursor = m.end() + 1 break if tok_type == 'list': break tok_index = len(state.tokens) end_pos = block.parse_method(m, state) if end_pos: token['_tok_index'] = tok_index token['_end_pos'] = end_pos break if prev_blank_line and not line.startswith(continue_space): # not a continue line, and previous line is blank break src += line state.cursor = pos text += _clean_list_item_text(src, continue_width) child = state.child_state(strip_end(text)) block.parse(child, rules) if token['tight'] and _is_loose_list(child.tokens): token['tight'] = False token['children'].append({ 'type': 'list_item', 'children': child.tokens, }) if next_group: return next_group def _get_list_bullet(c): if c == '.': bullet = r'\d{0,9}\.' elif c == ')': bullet = r'\d{0,9}\)' elif c == '*': bullet = r'\*' elif c == '+': bullet = r'\+' else: bullet = '-' return bullet def _compile_list_item_pattern(bullet, leading_width): if leading_width > 3: leading_width = 3 return ( r'^(?P<listitem_1> {0,' + str(leading_width) + '})' r'(?P<listitem_2>' + bullet + ')' r'(?P<listitem_3>[ \t]*|[ \t][^\n]+)$' ) def _compile_continue_width(text, leading_width): text = expand_leading_tab(text, 3) text = expand_tab(text) m2 = _LINE_HAS_TEXT.match(text) if m2: # indent code, startswith 5 spaces if text.startswith(' '): space_width = 1 else: space_width = len(m2.group(1)) text = text[space_width:] + '\n' else: space_width = 1 text = '' continue_width = leading_width + space_width return text, continue_width def _clean_list_item_text(src, continue_width): # according to Example 7, tab should be treated as 3 spaces rv = [] trim_space = ' ' * continue_width lines = src.split('\n') for line in lines: if line.startswith(trim_space): line = line.replace(trim_space, '', 1) # according to CommonMark Example 5 # tab should be treated as 4 spaces line = expand_tab(line) rv.append(line) else: rv.append(line) return '\n'.join(rv) def _is_loose_list(tokens): paragraph_count = 0 for tok in tokens: if tok['type'] == 'blank_line': return True if tok['type'] == 'paragraph': paragraph_count += 1 if paragraph_count > 1: return True �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/markdown.py���������������������������������������������������������������0000664�0000000�0000000�00000006367�14505662126�0017672�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from typing import Optional from .core import BlockState from .block_parser import BlockParser from .inline_parser import InlineParser class Markdown: """Markdown instance to convert markdown text into HTML or other formats. Here is an example with the HTMLRenderer:: from mistune import HTMLRenderer md = Markdown(renderer=HTMLRenderer(escape=False)) md('hello **world**') :param renderer: a renderer to convert parsed tokens :param block: block level syntax parser :param inline: inline level syntax parser :param plugins: mistune plugins to use """ def __init__(self, renderer=None, block: Optional[BlockParser]=None, inline: Optional[InlineParser]=None, plugins=None): if block is None: block = BlockParser() if inline is None: inline = InlineParser() self.renderer = renderer self.block: BlockParser = block self.inline: InlineParser = inline self.before_parse_hooks = [] self.before_render_hooks = [] self.after_render_hooks = [] if plugins: for plugin in plugins: plugin(self) def use(self, plugin): plugin(self) def render_state(self, state: BlockState): data = self._iter_render(state.tokens, state) if self.renderer: return self.renderer(data, state) return list(data) def _iter_render(self, tokens, state): for tok in tokens: if 'children' in tok: children = self._iter_render(tok['children'], state) tok['children'] = list(children) elif 'text' in tok: text = tok.pop('text') # process inline text # avoid striping emsp or other unicode spaces tok['children'] = self.inline(text.strip(' \r\n\t\f'), state.env) yield tok def parse(self, s: str, state: Optional[BlockState]=None): """Parse and convert the given markdown string. If renderer is None, the returned **result** will be parsed markdown tokens. :param s: markdown string :param state: instance of BlockState :returns: result, state """ if state is None: state = self.block.state_cls() # normalize line separator s = s.replace('\r\n', '\n') s = s.replace('\r', '\n') if not s.endswith('\n'): s += '\n' state.process(s) for hook in self.before_parse_hooks: hook(self, state) self.block.parse(state) for hook in self.before_render_hooks: hook(self, state) result = self.render_state(state) for hook in self.after_render_hooks: result = hook(self, result, state) return result, state def read(self, filepath, encoding='utf-8', state=None): if state is None: state = self.block.state_cls() state.env['__file__'] = filepath with open(filepath, 'rb') as f: s = f.read() s = s.decode(encoding) return self.parse(s, state) def __call__(self, s: str): if s is None: s = '\n' return self.parse(s)[0] �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/������������������������������������������������������������������0000775�0000000�0000000�00000000000�14505662126�0017143�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/__init__.py�������������������������������������������������������0000664�0000000�0000000�00000002345�14505662126�0021260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from importlib import import_module _plugins = { 'speedup': 'mistune.plugins.speedup.speedup', 'strikethrough': 'mistune.plugins.formatting.strikethrough', 'mark': 'mistune.plugins.formatting.mark', 'insert': 'mistune.plugins.formatting.insert', 'superscript': 'mistune.plugins.formatting.superscript', 'subscript': 'mistune.plugins.formatting.subscript', 'footnotes': 'mistune.plugins.footnotes.footnotes', 'table': 'mistune.plugins.table.table', 'url': 'mistune.plugins.url.url', 'abbr': 'mistune.plugins.abbr.abbr', 'def_list': 'mistune.plugins.def_list.def_list', 'math': 'mistune.plugins.math.math', 'ruby': 'mistune.plugins.ruby.ruby', 'task_lists': 'mistune.plugins.task_lists.task_lists', 'spoiler': 'mistune.plugins.spoiler.spoiler', } _cached_modules = {} def import_plugin(name): if name in _cached_modules: return _cached_modules[name] if callable(name): return name if name in _plugins: module_path, func_name = _plugins[name].rsplit(".", 1) else: module_path, func_name = name.rsplit(".", 1) module = import_module(module_path) plugin = getattr(module, func_name) _cached_modules[name] = plugin return plugin �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/abbr.py�����������������������������������������������������������0000664�0000000�0000000�00000005526�14505662126�0020433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re import types from ..util import escape from ..helpers import PREVENT_BACKSLASH __all__ = ['abbr'] # https://michelf.ca/projects/php-markdown/extra/#abbr REF_ABBR = ( r'^ {0,3}\*\[(?P<abbr_key>[^\]]+)'+ PREVENT_BACKSLASH + r'\]:' r'(?P<abbr_text>(?:[ \t]*\n(?: {3,}|\t)[^\n]+)|(?:[^\n]*))$' ) def parse_ref_abbr(block, m, state): ref = state.env.get('ref_abbrs') if not ref: ref = {} key = m.group('abbr_key') text = m.group('abbr_text') ref[key] = text.strip() state.env['ref_abbrs'] = ref # abbr definition can split paragraph state.append_token({'type': 'blank_line'}) return m.end() + 1 def process_text(inline, text, state): ref = state.env.get('ref_abbrs') if not ref: return state.append_token({'type': 'text', 'raw': text}) if state.tokens: last = state.tokens[-1] if last['type'] == 'text': state.tokens.pop() text = last['raw'] + text abbrs_re = state.env.get('abbrs_re') if not abbrs_re: abbrs_re = re.compile(r'|'.join(re.escape(k) for k in ref.keys())) state.env['abbrs_re'] = abbrs_re pos = 0 while pos < len(text): m = abbrs_re.search(text, pos) if not m: break end_pos = m.start() if end_pos > pos: hole = text[pos:end_pos] state.append_token({'type': 'text', 'raw': hole}) label = m.group(0) state.append_token({ 'type': 'abbr', 'children': [{'type': 'text', 'raw': label}], 'attrs': {'title': ref[label]} }) pos = m.end() if pos == 0: # special case, just pure text state.append_token({'type': 'text', 'raw': text}) elif pos < len(text): state.append_token({'type': 'text', 'raw': text[pos:]}) def render_abbr(renderer, text, title): if not title: return '<abbr>' + text + '</abbr>' return '<abbr title="' + escape(title) + '">' + text + '</abbr>' def abbr(md): """A mistune plugin to support abbreviations, spec defined at https://michelf.ca/projects/php-markdown/extra/#abbr Here is an example: .. code-block:: text The HTML specification is maintained by the W3C. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium It will be converted into HTML: .. code-block:: html The <abbr title="Hyper Text Markup Language">HTML</abbr> specification is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>. :param md: Markdown instance """ md.block.register('ref_abbr', REF_ABBR, parse_ref_abbr, before='paragraph') # replace process_text md.inline.process_text = types.MethodType(process_text, md.inline) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('abbr', render_abbr) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/def_list.py�������������������������������������������������������0000664�0000000�0000000�00000006603�14505662126�0021313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ..util import strip_end __all__ = ['def_list'] # https://michelf.ca/projects/php-markdown/extra/#def-list DEF_PATTERN = ( r'^(?P<def_list_head>(?:[^\n]+\n)+?)' r'\n?(?:' r'\:[ \t]+.*\n' r'(?:[^\n]+\n)*' # lazy continue line r'(?:(?:[ \t]*\n)*[ \t]+[^\n]+\n)*' r'(?:[ \t]*\n)*' r')+' ) DEF_RE = re.compile(DEF_PATTERN, re.M) DD_START_RE = re.compile(r'^:[ \t]+', re.M) TRIM_RE = re.compile(r'^ {0,4}', re.M) HAS_BLANK_LINE_RE = re.compile(r'\n[ \t]*\n$') def parse_def_list(block, m, state): pos = m.end() children = list(_parse_def_item(block, m)) m = DEF_RE.match(state.src, pos) while m: children.extend(list(_parse_def_item(block, m))) pos = m.end() m = DEF_RE.match(state.src, pos) state.append_token({ 'type': 'def_list', 'children': children, }) return pos def _parse_def_item(block, m): head = m.group('def_list_head') for line in head.splitlines(): yield { 'type': 'def_list_head', 'text': line, } src = m.group(0) end = len(head) m = DD_START_RE.search(src, end) start = m.start() prev_blank_line = src[end:start] == '\n' while m: m = DD_START_RE.search(src, start + 1) if not m: break end = m.start() text = src[start:end].replace(':', ' ', 1) children = _process_text(block, text, prev_blank_line) prev_blank_line = bool(HAS_BLANK_LINE_RE.search(text)) yield { 'type': 'def_list_item', 'children': children, } start = end text = src[start:].replace(':', ' ', 1) children = _process_text(block, text, prev_blank_line) yield { 'type': 'def_list_item', 'children': children, } def _process_text(block, text, loose): text = TRIM_RE.sub('', text) state = block.state_cls() state.process(strip_end(text)) # use default list rules block.parse(state, block.list_rules) tokens = state.tokens if not loose and len(tokens) == 1 and tokens[0]['type'] == 'paragraph': tokens[0]['type'] = 'block_text' return tokens def render_def_list(renderer, text): return '<dl>\n' + text + '</dl>\n' def render_def_list_head(renderer, text): return '<dt>' + text + '</dt>\n' def render_def_list_item(renderer, text): return '<dd>' + text + '</dd>\n' def def_list(md): """A mistune plugin to support def list, spec defined at https://michelf.ca/projects/php-markdown/extra/#def-list Here is an example: .. code-block:: text Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus. It will be converted into HTML: .. code-block:: html <dl> <dt>Apple</dt> <dd>Pomaceous fruit of plants of the genus Malus in the family Rosaceae.</dd> <dt>Orange</dt> <dd>The fruit of an evergreen tree of the genus Citrus.</dd> </dl> :param md: Markdown instance """ md.block.register('def_list', DEF_PATTERN, parse_def_list, before='paragraph') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('def_list', render_def_list) md.renderer.register('def_list_head', render_def_list_head) md.renderer.register('def_list_item', render_def_list_item) �����������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/footnotes.py������������������������������������������������������0000664�0000000�0000000�00000010520�14505662126�0021533�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ..core import BlockState from ..util import unikey from ..helpers import LINK_LABEL __all__ = ['footnotes'] _PARAGRAPH_SPLIT = re.compile(r'\n{2,}') # https://michelf.ca/projects/php-markdown/extra/#footnotes REF_FOOTNOTE = ( r'^(?P<footnote_lead> {0,3})' r'\[\^(?P<footnote_key>' + LINK_LABEL + r')]:[ \t]' r'(?P<footnote_text>[^\n]*(?:\n+|$)' r'(?:(?P=footnote_lead) {1,3}(?! )[^\n]*\n+)*' r')' ) INLINE_FOOTNOTE = r'\[\^(?P<footnote_key>' + LINK_LABEL + r')\]' def parse_inline_footnote(inline, m: re.Match, state): key = unikey(m.group('footnote_key')) ref = state.env.get('ref_footnotes') if ref and key in ref: notes = state.env.get('footnotes') if not notes: notes = [] if key not in notes: notes.append(key) state.env['footnotes'] = notes state.append_token({ 'type': 'footnote_ref', 'raw': key, 'attrs': {'index': notes.index(key) + 1} }) else: state.append_token({'type': 'text', 'raw': m.group(0)}) return m.end() def parse_ref_footnote(block, m: re.Match, state: BlockState): ref = state.env.get('ref_footnotes') if not ref: ref = {} key = unikey(m.group('footnote_key')) if key not in ref: ref[key] = m.group('footnote_text') state.env['ref_footnotes'] = ref return m.end() def parse_footnote_item(block, key: str, index: int, state: BlockState): ref = state.env.get('ref_footnotes') text = ref[key] lines = text.splitlines() second_line = None for second_line in lines[1:]: if second_line: break if second_line: spaces = len(second_line) - len(second_line.lstrip()) pattern = re.compile(r'^ {' + str(spaces) + r',}', flags=re.M) text = pattern.sub('', text).strip() items = _PARAGRAPH_SPLIT.split(text) children = [{'type': 'paragraph', 'text': s} for s in items] else: text = text.strip() children = [{'type': 'paragraph', 'text': text}] return { 'type': 'footnote_item', 'children': children, 'attrs': {'key': key, 'index': index} } def md_footnotes_hook(md, result: str, state: BlockState): notes = state.env.get('footnotes') if not notes: return result children = [ parse_footnote_item(md.block, k, i + 1, state) for i, k in enumerate(notes) ] state = BlockState() state.tokens = [{'type': 'footnotes', 'children': children}] output = md.render_state(state) return result + output def render_footnote_ref(renderer, key: str, index: int): i = str(index) html = '<sup class="footnote-ref" id="fnref-' + i + '">' return html + '<a href="#fn-' + i + '">' + i + '</a></sup>' def render_footnotes(renderer, text: str): return '<section class="footnotes">\n<ol>\n' + text + '</ol>\n</section>\n' def render_footnote_item(renderer, text: str, key: str, index: int): i = str(index) back = '<a href="#fnref-' + i + '" class="footnote">↩</a>' text = text.rstrip()[:-4] + back + '</p>' return '<li id="fn-' + i + '">' + text + '</li>\n' def footnotes(md): """A mistune plugin to support footnotes, spec defined at https://michelf.ca/projects/php-markdown/extra/#footnotes Here is an example: .. code-block:: text That's some text with a footnote.[^1] [^1]: And that's the footnote. It will be converted into HTML: .. code-block:: html <p>That's some text with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <section class="footnotes"> <ol> <li id="fn-1"><p>And that's the footnote.<a href="#fnref-1" class="footnote">↩</a></p></li> </ol> </section> :param md: Markdown instance """ md.inline.register( 'footnote', INLINE_FOOTNOTE, parse_inline_footnote, before='link', ) md.block.register( 'ref_footnote', REF_FOOTNOTE, parse_ref_footnote, before='ref_link', ) md.after_render_hooks.append(md_footnotes_hook) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('footnote_ref', render_footnote_ref) md.renderer.register('footnote_item', render_footnote_item) md.renderer.register('footnotes', render_footnotes) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/formatting.py�����������������������������������������������������0000664�0000000�0000000�00000010722�14505662126�0021671�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ..helpers import PREVENT_BACKSLASH __all__ = ["strikethrough", "mark", "insert", "superscript", "subscript"] _STRIKE_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\~|[^\s~])~~(?!~)') _MARK_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\=|[^\s=])==(?!=)') _INSERT_END = re.compile(r'(?:' + PREVENT_BACKSLASH + r'\\\^|[^\s^])\^\^(?!\^)') SUPERSCRIPT_PATTERN = r'\^(?:' + PREVENT_BACKSLASH + r'\\\^|\S|\\ )+?\^' SUBSCRIPT_PATTERN = r'~(?:' + PREVENT_BACKSLASH + r'\\~|\S|\\ )+?~' def parse_strikethrough(inline, m, state): return _parse_to_end(inline, m, state, 'strikethrough', _STRIKE_END) def render_strikethrough(renderer, text): return '<del>' + text + '</del>' def parse_mark(inline, m, state): return _parse_to_end(inline, m, state, 'mark', _MARK_END) def render_mark(renderer, text): return '<mark>' + text + '</mark>' def parse_insert(inline, m, state): return _parse_to_end(inline, m, state, 'insert', _INSERT_END) def render_insert(renderer, text): return '<ins>' + text + '</ins>' def parse_superscript(inline, m, state): return _parse_script(inline, m, state, 'superscript') def render_superscript(renderer, text): return '<sup>' + text + '</sup>' def parse_subscript(inline, m, state): return _parse_script(inline, m, state, 'subscript') def render_subscript(renderer, text): return '<sub>' + text + '</sub>' def _parse_to_end(inline, m, state, tok_type, end_pattern): pos = m.end() m1 = end_pattern.search(state.src, pos) if not m1: return end_pos = m1.end() text = state.src[pos:end_pos-2] new_state = state.copy() new_state.src = text children = inline.render(new_state) state.append_token({'type': tok_type, 'children': children}) return end_pos def _parse_script(inline, m, state, tok_type): text = m.group(0) new_state = state.copy() new_state.src = text[1:-1].replace('\\ ', ' ') children = inline.render(new_state) state.append_token({ 'type': tok_type, 'children': children }) return m.end() def strikethrough(md): """A mistune plugin to support strikethrough. Spec defined by GitHub flavored Markdown and commonly used by many parsers: .. code-block:: text ~~This was mistaken text~~ It will be converted into HTML: .. code-block:: html <del>This was mistaken text</del> :param md: Markdown instance """ md.inline.register( 'strikethrough', r'~~(?=[^\s~])', parse_strikethrough, before='link', ) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('strikethrough', render_strikethrough) def mark(md): """A mistune plugin to add ``<mark>`` tag. Spec defined at https://facelessuser.github.io/pymdown-extensions/extensions/mark/: .. code-block:: text ==mark me== ==mark \\=\\= equal== :param md: Markdown instance """ md.inline.register( 'mark', r'==(?=[^\s=])', parse_mark, before='link', ) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('mark', render_mark) def insert(md): """A mistune plugin to add ``<ins>`` tag. Spec defined at https://facelessuser.github.io/pymdown-extensions/extensions/caret/#insert: .. code-block:: text ^^insert me^^ :param md: Markdown instance """ md.inline.register( 'insert', r'\^\^(?=[^\s\^])', parse_insert, before='link', ) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('insert', render_insert) def superscript(md): """A mistune plugin to add ``<sup>`` tag. Spec defined at https://pandoc.org/MANUAL.html#superscripts-and-subscripts: .. code-block:: text 2^10^ is 1024. :param md: Markdown instance """ md.inline.register('superscript', SUPERSCRIPT_PATTERN, parse_superscript, before='linebreak') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('superscript', render_superscript) def subscript(md): """A mistune plugin to add ``<sub>`` tag. Spec defined at https://pandoc.org/MANUAL.html#superscripts-and-subscripts: .. code-block:: text H~2~O is a liquid. :param md: Markdown instance """ md.inline.register('subscript', SUBSCRIPT_PATTERN, parse_subscript, before='linebreak') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('subscript', render_subscript) ����������������������������������������������mistune-3.0.2/src/mistune/plugins/math.py�����������������������������������������������������������0000664�0000000�0000000�00000003227�14505662126�0020452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������__all__ = ['math', 'math_in_quote', 'math_in_list'] BLOCK_MATH_PATTERN = r'^ {0,3}\$\$[ \t]*\n(?P<math_text>[\s\S]+?)\n\$\$[ \t]*$' INLINE_MATH_PATTERN = r'\$(?!\s)(?P<math_text>.+?)(?!\s)\$' def parse_block_math(block, m, state): text = m.group('math_text') state.append_token({'type': 'block_math', 'raw': text}) return m.end() + 1 def parse_inline_math(inline, m, state): text = m.group('math_text') state.append_token({'type': 'inline_math', 'raw': text}) return m.end() def render_block_math(renderer, text): return '<div class="math">$$\n' + text + '\n$$</div>\n' def render_inline_math(renderer, text): return r'<span class="math">\(' + text + r'\)</span>' def math(md): """A mistune plugin to support math. The syntax is used by many markdown extensions: .. code-block:: text Block math is surrounded by $$: $$ f(a)=f(b) $$ Inline math is surrounded by `$`, such as $f(a)=f(b)$ :param md: Markdown instance """ md.block.register('block_math', BLOCK_MATH_PATTERN, parse_block_math, before='list') md.inline.register('inline_math', INLINE_MATH_PATTERN, parse_inline_math, before='link') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('block_math', render_block_math) md.renderer.register('inline_math', render_inline_math) def math_in_quote(md): """Enable block math plugin in block quote.""" md.block.insert_rule(md.block.block_quote_rules, 'block_math', before='list') def math_in_list(md): """Enable block math plugin in list.""" md.block.insert_rule(md.block.list_rules, 'block_math', before='list') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/ruby.py�����������������������������������������������������������0000664�0000000�0000000�00000005317�14505662126�0020504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ..util import unikey from ..helpers import parse_link, parse_link_label RUBY_PATTERN = r'\[(?:\w+\(\w+\))+\]' _ruby_re = re.compile(RUBY_PATTERN) def parse_ruby(inline, m, state): text = m.group(0)[1:-2] items = text.split(')') tokens = [] for item in items: rb, rt = item.split('(') tokens.append({ 'type': 'ruby', 'raw': rb, 'attrs': {'rt': rt} }) end_pos = m.end() next_match = _ruby_re.match(state.src, end_pos) if next_match: for tok in tokens: state.append_token(tok) return parse_ruby(inline, next_match, state) # repeat link logic if end_pos < len(state.src): link_pos = _parse_ruby_link(inline, state, end_pos, tokens) if link_pos: return link_pos for tok in tokens: state.append_token(tok) return end_pos def _parse_ruby_link(inline, state, pos, tokens): c = state.src[pos] if c == '(': # standard link [text](<url> "title") attrs, link_pos = parse_link(state.src, pos + 1) if link_pos: state.append_token({ 'type': 'link', 'children': tokens, 'attrs': attrs, }) return link_pos elif c == '[': # standard ref link [text][label] label, link_pos = parse_link_label(state.src, pos + 1) if label and link_pos: ref_links = state.env['ref_links'] key = unikey(label) env = ref_links.get(key) if env: attrs = {'url': env['url'], 'title': env.get('title')} state.append_token({ 'type': 'link', 'children': tokens, 'attrs': attrs, }) else: for tok in tokens: state.append_token(tok) state.append_token({ 'type': 'text', 'raw': '[' + label + ']', }) return link_pos def render_ruby(renderer, text, rt): return '<ruby><rb>' + text + '</rb><rt>' + rt + '</rt></ruby>' def ruby(md): """A mistune plugin to support ``<ruby>`` tag. The syntax is defined at https://lepture.com/en/2022/markdown-ruby-markup: .. code-block:: text [漢字(ㄏㄢˋㄗˋ)] [漢(ㄏㄢˋ)字(ㄗˋ)] [漢字(ㄏㄢˋㄗˋ)][link] [漢字(ㄏㄢˋㄗˋ)](/url "title") [link]: /url "title" :param md: Markdown instance """ md.inline.register('ruby', RUBY_PATTERN, parse_ruby, before='link') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('ruby', render_ruby) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/speedup.py��������������������������������������������������������0000664�0000000�0000000�00000002057�14505662126�0021166�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re import string # because mismatch is too slow, add parsers for paragraph and text HARD_LINEBREAK_RE = re.compile(r' *\n\s*') PARAGRAPH = ( # start with none punctuation, not number, not whitespace r'(?:^[^\s\d' + re.escape(string.punctuation) + r'][^\n]*\n)+' ) __all__ = ['speedup'] def parse_text(inline, m, state): text = m.group(0) text = HARD_LINEBREAK_RE.sub('\n', text) inline.process_text(text, state) return m.end() def parse_paragraph(block, m, state): text = m.group(0) state.add_paragraph(text) return m.end() def speedup(md): """Increase the speed of parsing paragraph and inline text.""" md.block.register('paragraph', PARAGRAPH, parse_paragraph) punc = r'\\><!\[_*`~\^\$=' text_pattern = r'[\s\S]+?(?=[' + punc + r']|' if 'url_link' in md.inline.rules: text_pattern += 'https?:|' if md.inline.hard_wrap: text_pattern += r' *\n|' else: text_pattern += r' {2,}\n|' text_pattern += r'$)' md.inline.register('text', text_pattern, parse_text) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/spoiler.py��������������������������������������������������������0000664�0000000�0000000�00000004545�14505662126�0021202�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re __all__ = ['spoiler'] _BLOCK_SPOILER_START = re.compile(r'^ {0,3}! ?', re.M) _BLOCK_SPOILER_MATCH = re.compile(r'^( {0,3}![^\n]*\n)+$') INLINE_SPOILER_PATTERN = r'>!\s*(?P<spoiler_text>.+?)\s*!<' def parse_block_spoiler(block, m, state): text, end_pos = block.extract_block_quote(m, state) if not text.endswith('\n'): # ensure it endswith \n to make sure # _BLOCK_SPOILER_MATCH.match works text += '\n' depth = state.depth() if not depth and _BLOCK_SPOILER_MATCH.match(text): text = _BLOCK_SPOILER_START.sub('', text) tok_type = 'block_spoiler' else: tok_type = 'block_quote' # scan children state child = state.child_state(text) if state.depth() >= block.max_nested_level - 1: rules = list(block.block_quote_rules) rules.remove('block_quote') else: rules = block.block_quote_rules block.parse(child, rules) token = {'type': tok_type, 'children': child.tokens} if end_pos: state.prepend_token(token) return end_pos state.append_token(token) return state.cursor def parse_inline_spoiler(inline, m, state): text = m.group('spoiler_text') new_state = state.copy() new_state.src = text children = inline.render(new_state) state.append_token({'type': 'inline_spoiler', 'children': children}) return m.end() def render_block_spoiler(renderer, text): return '<div class="spoiler">\n' + text + '</div>\n' def render_inline_spoiler(renderer, text): return '<span class="spoiler">' + text + '</span>' def spoiler(md): """A mistune plugin to support block and inline spoiler. The syntax is inspired by stackexchange: .. code-block:: text Block level spoiler looks like block quote, but with `>!`: >! this is spoiler >! >! the content will be hidden Inline spoiler is surrounded by `>!` and `!<`, such as >! hide me !<. :param md: Markdown instance """ # reset block quote parser with block spoiler parser md.block.register('block_quote', None, parse_block_spoiler) md.inline.register('inline_spoiler', INLINE_SPOILER_PATTERN, parse_inline_spoiler) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('block_spoiler', render_block_spoiler) md.renderer.register('inline_spoiler', render_inline_spoiler) �����������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/table.py����������������������������������������������������������0000664�0000000�0000000�00000011576�14505662126�0020616�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from ..helpers import PREVENT_BACKSLASH # https://michelf.ca/projects/php-markdown/extra/#table __all__ = ['table', 'table_in_quote', 'table_in_list'] TABLE_PATTERN = ( r'^ {0,3}\|(?P<table_head>.+)\|[ \t]*\n' r' {0,3}\|(?P<table_align> *[-:]+[-| :]*)\|[ \t]*\n' r'(?P<table_body>(?: {0,3}\|.*\|[ \t]*(?:\n|$))*)\n*' ) NP_TABLE_PATTERN = ( r'^ {0,3}(?P<nptable_head>\S.*\|.*)\n' r' {0,3}(?P<nptable_align>[-:]+ *\|[-| :]*)\n' r'(?P<nptable_body>(?:.*\|.*(?:\n|$))*)\n*' ) TABLE_CELL = re.compile(r'^ {0,3}\|(.+)\|[ \t]*$') CELL_SPLIT = re.compile(r' *' + PREVENT_BACKSLASH + r'\| *') ALIGN_CENTER = re.compile(r'^ *:-+: *$') ALIGN_LEFT = re.compile(r'^ *:-+ *$') ALIGN_RIGHT = re.compile(r'^ *-+: *$') def parse_table(block, m, state): pos = m.end() header = m.group('table_head') align = m.group('table_align') thead, aligns = _process_thead(header, align) if not thead: return rows = [] body = m.group('table_body') for text in body.splitlines(): m = TABLE_CELL.match(text) if not m: # pragma: no cover return row = _process_row(m.group(1), aligns) if not row: return rows.append(row) children = [thead, {'type': 'table_body', 'children': rows}] state.append_token({'type': 'table', 'children': children}) return pos def parse_nptable(block, m, state): header = m.group('nptable_head') align = m.group('nptable_align') thead, aligns = _process_thead(header, align) if not thead: return rows = [] body = m.group('nptable_body') for text in body.splitlines(): row = _process_row(text, aligns) if not row: return rows.append(row) children = [thead, {'type': 'table_body', 'children': rows}] state.append_token({'type': 'table', 'children': children}) return m.end() def _process_thead(header, align): headers = CELL_SPLIT.split(header) aligns = CELL_SPLIT.split(align) if len(headers) != len(aligns): return None, None for i, v in enumerate(aligns): if ALIGN_CENTER.match(v): aligns[i] = 'center' elif ALIGN_LEFT.match(v): aligns[i] = 'left' elif ALIGN_RIGHT.match(v): aligns[i] = 'right' else: aligns[i] = None children = [ { 'type': 'table_cell', 'text': text.strip(), 'attrs': {'align': aligns[i], 'head': True} } for i, text in enumerate(headers) ] thead = {'type': 'table_head', 'children': children} return thead, aligns def _process_row(text, aligns): cells = CELL_SPLIT.split(text) if len(cells) != len(aligns): return None children = [ { 'type': 'table_cell', 'text': text.strip(), 'attrs': {'align': aligns[i], 'head': False} } for i, text in enumerate(cells) ] return {'type': 'table_row', 'children': children} def render_table(renderer, text): return '<table>\n' + text + '</table>\n' def render_table_head(renderer, text): return '<thead>\n<tr>\n' + text + '</tr>\n</thead>\n' def render_table_body(renderer, text): return '<tbody>\n' + text + '</tbody>\n' def render_table_row(renderer, text): return '<tr>\n' + text + '</tr>\n' def render_table_cell(renderer, text, align=None, head=False): if head: tag = 'th' else: tag = 'td' html = ' <' + tag if align: html += ' style="text-align:' + align + '"' return html + '>' + text + '</' + tag + '>\n' def table(md): """A mistune plugin to support table, spec defined at https://michelf.ca/projects/php-markdown/extra/#table Here is an example: .. code-block:: text First Header | Second Header ------------- | ------------- Content Cell | Content Cell Content Cell | Content Cell :param md: Markdown instance """ md.block.register('table', TABLE_PATTERN, parse_table, before='paragraph') md.block.register('nptable', NP_TABLE_PATTERN, parse_nptable, before='paragraph') if md.renderer and md.renderer.NAME == 'html': md.renderer.register('table', render_table) md.renderer.register('table_head', render_table_head) md.renderer.register('table_body', render_table_body) md.renderer.register('table_row', render_table_row) md.renderer.register('table_cell', render_table_cell) def table_in_quote(md): """Enable table plugin in block quotes.""" md.block.insert_rule(md.block.block_quote_rules, 'table', before='paragraph') md.block.insert_rule(md.block.block_quote_rules, 'nptable', before='paragraph') def table_in_list(md): """Enable table plugin in list.""" md.block.insert_rule(md.block.list_rules, 'table', before='paragraph') md.block.insert_rule(md.block.list_rules, 'nptable', before='paragraph') ����������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/task_lists.py�����������������������������������������������������0000664�0000000�0000000�00000003221�14505662126�0021673�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re __all__ = ['task_lists'] TASK_LIST_ITEM = re.compile(r'^(\[[ xX]\])\s+') def task_lists_hook(md, state): return _rewrite_all_list_items(state.tokens) def render_task_list_item(renderer, text, checked=False): checkbox = ( '<input class="task-list-item-checkbox" ' 'type="checkbox" disabled' ) if checked: checkbox += ' checked/>' else: checkbox += '/>' if text.startswith('<p>'): text = text.replace('<p>', '<p>' + checkbox, 1) else: text = checkbox + text return '<li class="task-list-item">' + text + '</li>\n' def task_lists(md): """A mistune plugin to support task lists. Spec defined by GitHub flavored Markdown and commonly used by many parsers: .. code-block:: text - [ ] unchecked task - [x] checked task :param md: Markdown instance """ md.before_render_hooks.append(task_lists_hook) if md.renderer and md.renderer.NAME == 'html': md.renderer.register('task_list_item', render_task_list_item) def _rewrite_all_list_items(tokens): for tok in tokens: if tok['type'] == 'list_item': _rewrite_list_item(tok) if 'children' in tok: _rewrite_all_list_items(tok['children']) return tokens def _rewrite_list_item(tok): children = tok['children'] if children: first_child = children[0] text = first_child.get('text', '') m = TASK_LIST_ITEM.match(text) if m: mark = m.group(1) first_child['text'] = text[m.end():] tok['type'] = 'task_list_item' tok['attrs'] = {'checked': mark != '[ ]'} �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/plugins/url.py������������������������������������������������������������0000664�0000000�0000000�00000001014�14505662126�0020313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from ..util import escape_url __all__ = ['url'] URL_LINK_PATTERN = r'''https?:\/\/[^\s<]+[^<.,:;"')\]\s]''' def parse_url_link(inline, m, state): text = m.group(0) pos = m.end() if state.in_link: inline.process_text(text, state) return pos state.append_token({ 'type': 'link', 'children': [{'type': 'text', 'raw': text}], 'attrs': {'url': escape_url(text)}, }) return pos def url(md): md.inline.register('url_link', URL_LINK_PATTERN, parse_url_link) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/py.typed������������������������������������������������������������������0000664�0000000�0000000�00000000265�14505662126�0017164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# when type checking dependents, tell type checkers, e.g. mypy, to use this package's types # without this file, mypy will write a warning and ignore type annotations from mistune. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/renderers/����������������������������������������������������������������0000775�0000000�0000000�00000000000�14505662126�0017453�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/renderers/__init__.py�����������������������������������������������������0000664�0000000�0000000�00000000000�14505662126�0021552�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/renderers/_list.py��������������������������������������������������������0000664�0000000�0000000�00000003203�14505662126�0021135�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from ..util import strip_end def render_list(renderer, token, state) -> str: attrs = token['attrs'] if attrs['ordered']: children = _render_ordered_list(renderer, token, state) else: children = _render_unordered_list(renderer, token, state) text = ''.join(children) parent = token.get('parent') if parent: if parent['tight']: return text return text + '\n' return strip_end(text) + '\n' def _render_list_item(renderer, parent, item, state): leading = parent['leading'] text = '' for tok in item['children']: if tok['type'] == 'list': tok['parent'] = parent elif tok['type'] == 'blank_line': continue text += renderer.render_token(tok, state) lines = text.splitlines() text = (lines[0] if lines else '') + '\n' prefix = ' ' * len(leading) for line in lines[1:]: if line: text += prefix + line + '\n' else: text += '\n' return leading + text def _render_ordered_list(renderer, token, state): attrs = token['attrs'] start = attrs.get('start', 1) for item in token['children']: leading = str(start) + token['bullet'] + ' ' parent = { 'leading': leading, 'tight': token['tight'], } yield _render_list_item(renderer, parent, item, state) start += 1 def _render_unordered_list(renderer, token, state): parent = { 'leading': token['bullet'] + ' ', 'tight': token['tight'], } for item in token['children']: yield _render_list_item(renderer, parent, item, state) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/renderers/html.py���������������������������������������������������������0000664�0000000�0000000�00000010741�14505662126�0020774�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from ..core import BaseRenderer from ..util import escape as escape_text, striptags, safe_entity class HTMLRenderer(BaseRenderer): """A renderer for converting Markdown to HTML.""" NAME = 'html' HARMFUL_PROTOCOLS = ( 'javascript:', 'vbscript:', 'file:', 'data:', ) GOOD_DATA_PROTOCOLS = ( 'data:image/gif;', 'data:image/png;', 'data:image/jpeg;', 'data:image/webp;', ) def __init__(self, escape=True, allow_harmful_protocols=None): super(HTMLRenderer, self).__init__() self._allow_harmful_protocols = allow_harmful_protocols self._escape = escape def render_token(self, token, state): # backward compitable with v2 func = self._get_method(token['type']) attrs = token.get('attrs') if 'raw' in token: text = token['raw'] elif 'children' in token: text = self.render_tokens(token['children'], state) else: if attrs: return func(**attrs) else: return func() if attrs: return func(text, **attrs) else: return func(text) def safe_url(self, url: str) -> str: """Ensure the given URL is safe. This method is used for rendering links, images, and etc. """ if self._allow_harmful_protocols is True: return url _url = url.lower() if self._allow_harmful_protocols and \ _url.startswith(tuple(self._allow_harmful_protocols)): return url if _url.startswith(self.HARMFUL_PROTOCOLS) and \ not _url.startswith(self.GOOD_DATA_PROTOCOLS): return '#harmful-link' return url def text(self, text: str) -> str: if self._escape: return escape_text(text) return safe_entity(text) def emphasis(self, text: str) -> str: return '<em>' + text + '</em>' def strong(self, text: str) -> str: return '<strong>' + text + '</strong>' def link(self, text: str, url: str, title=None) -> str: s = '<a href="' + self.safe_url(url) + '"' if title: s += ' title="' + safe_entity(title) + '"' return s + '>' + text + '</a>' def image(self, text: str, url: str, title=None) -> str: src = self.safe_url(url) alt = escape_text(striptags(text)) s = '<img src="' + src + '" alt="' + alt + '"' if title: s += ' title="' + safe_entity(title) + '"' return s + ' />' def codespan(self, text: str) -> str: return '<code>' + text + '</code>' def linebreak(self) -> str: return '<br />\n' def softbreak(self) -> str: return '\n' def inline_html(self, html: str) -> str: if self._escape: return escape_text(html) return html def paragraph(self, text: str) -> str: return '<p>' + text + '</p>\n' def heading(self, text: str, level: int, **attrs) -> str: tag = 'h' + str(level) html = '<' + tag _id = attrs.get('id') if _id: html += ' id="' + _id + '"' return html + '>' + text + '</' + tag + '>\n' def blank_line(self) -> str: return '' def thematic_break(self) -> str: return '<hr />\n' def block_text(self, text: str) -> str: return text def block_code(self, code: str, info=None) -> str: html = '<pre><code' if info is not None: info = safe_entity(info.strip()) if info: lang = info.split(None, 1)[0] html += ' class="language-' + lang + '"' return html + '>' + escape_text(code) + '</code></pre>\n' def block_quote(self, text: str) -> str: return '<blockquote>\n' + text + '</blockquote>\n' def block_html(self, html: str) -> str: if self._escape: return '<p>' + escape_text(html.strip()) + '</p>\n' return html + '\n' def block_error(self, text: str) -> str: return '<div class="error"><pre>' + text + '</pre></div>\n' def list(self, text: str, ordered: bool, **attrs) -> str: if ordered: html = '<ol' start = attrs.get('start') if start is not None: html += ' start="' + str(start) + '"' return html + '>\n' + text + '</ol>\n' return '<ul>\n' + text + '</ul>\n' def list_item(self, text: str) -> str: return '<li>' + text + '</li>\n' �������������������������������mistune-3.0.2/src/mistune/renderers/markdown.py�����������������������������������������������������0000664�0000000�0000000�00000011112�14505662126�0021643�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from typing import Dict, Any from textwrap import indent from ._list import render_list from ..core import BaseRenderer, BlockState from ..util import strip_end fenced_re = re.compile(r'^[`~]+', re.M) class MarkdownRenderer(BaseRenderer): """A renderer to re-format Markdown text.""" NAME = 'markdown' def __call__(self, tokens, state: BlockState): out = self.render_tokens(tokens, state) # special handle for line breaks out += '\n\n'.join(self.render_referrences(state)) + '\n' return strip_end(out) def render_referrences(self, state: BlockState): ref_links = state.env['ref_links'] for key in ref_links: attrs = ref_links[key] text = '[' + attrs['label'] + ']: ' + attrs['url'] title = attrs.get('title') if title: text += ' "' + title + '"' yield text def render_children(self, token, state: BlockState): children = token['children'] return self.render_tokens(children, state) def text(self, token: Dict[str, Any], state: BlockState) -> str: return token['raw'] def emphasis(self, token: Dict[str, Any], state: BlockState) -> str: return '*' + self.render_children(token, state) + '*' def strong(self, token: Dict[str, Any], state: BlockState) -> str: return '**' + self.render_children(token, state) + '**' def link(self, token: Dict[str, Any], state: BlockState) -> str: label = token.get('label') text = self.render_children(token, state) out = '[' + text + ']' if label: return out + '[' + label + ']' attrs = token['attrs'] url = attrs['url'] title = attrs.get('title') if text == url and not title: return '<' + text + '>' elif 'mailto:' + text == url and not title: return '<' + text + '>' out += '(' if '(' in url or ')' in url: out += '<' + url + '>' else: out += url if title: out += ' "' + title + '"' return out + ')' def image(self, token: Dict[str, Any], state: BlockState) -> str: return '!' + self.link(token, state) def codespan(self, token: Dict[str, Any], state: BlockState) -> str: return '`' + token['raw'] + '`' def linebreak(self, token: Dict[str, Any], state: BlockState) -> str: return ' \n' def softbreak(self, token: Dict[str, Any], state: BlockState) -> str: return '\n' def blank_line(self, token: Dict[str, Any], state: BlockState) -> str: return '' def inline_html(self, token: Dict[str, Any], state: BlockState) -> str: return token['raw'] def paragraph(self, token: Dict[str, Any], state: BlockState) -> str: text = self.render_children(token, state) return text + '\n\n' def heading(self, token: Dict[str, Any], state: BlockState) -> str: level = token['attrs']['level'] marker = '#' * level text = self.render_children(token, state) return marker + ' ' + text + '\n\n' def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str: return '***\n\n' def block_text(self, token: Dict[str, Any], state: BlockState) -> str: return self.render_children(token, state) + '\n' def block_code(self, token: Dict[str, Any], state: BlockState) -> str: attrs = token.get('attrs', {}) info = attrs.get('info', '') code = token['raw'] if code and code[-1] != '\n': code += '\n' marker = token.get('marker') if not marker: marker = _get_fenced_marker(code) return marker + info + '\n' + code + marker + '\n\n' def block_quote(self, token: Dict[str, Any], state: BlockState) -> str: text = indent(self.render_children(token, state), '> ') return text + '\n\n' def block_html(self, token: Dict[str, Any], state: BlockState) -> str: return token['raw'] + '\n\n' def block_error(self, token: Dict[str, Any], state: BlockState) -> str: return '' def list(self, token: Dict[str, Any], state: BlockState) -> str: return render_list(self, token, state) def _get_fenced_marker(code): found = fenced_re.findall(code) if not found: return '```' ticks = [] # ` waves = [] # ~ for s in found: if s[0] == '`': ticks.append(len(s)) else: waves.append(len(s)) if not ticks: return '```' if not waves: return '~~~' return '`' * (max(ticks) + 1) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/renderers/rst.py����������������������������������������������������������0000664�0000000�0000000�00000012222�14505662126�0020634�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from typing import Dict, Any from textwrap import indent from ._list import render_list from ..core import BaseRenderer, BlockState from ..util import strip_end class RSTRenderer(BaseRenderer): """A renderer for converting Markdown to ReST.""" NAME = 'rst' #: marker symbols for heading HEADING_MARKERS = { 1: '=', 2: '-', 3: '~', 4: '^', 5: '"', 6: "'", } INLINE_IMAGE_PREFIX = 'img-' def iter_tokens(self, tokens, state): prev = None for tok in tokens: # ignore blank line if tok['type'] == 'blank_line': continue tok['prev'] = prev prev = tok yield self.render_token(tok, state) def __call__(self, tokens, state: BlockState): state.env['inline_images'] = [] out = self.render_tokens(tokens, state) # special handle for line breaks out += '\n\n'.join(self.render_referrences(state)) + '\n' return strip_end(out) def render_referrences(self, state: BlockState): images = state.env['inline_images'] for index, token in enumerate(images): attrs = token['attrs'] alt = self.render_children(token, state) ident = self.INLINE_IMAGE_PREFIX + str(index) yield '.. |' + ident + '| image:: ' + attrs['url'] + '\n :alt: ' + alt def render_children(self, token, state: BlockState): children = token['children'] return self.render_tokens(children, state) def text(self, token: Dict[str, Any], state: BlockState) -> str: text = token['raw'] return text.replace('|', r'\|') def emphasis(self, token: Dict[str, Any], state: BlockState) -> str: return '*' + self.render_children(token, state) + '*' def strong(self, token: Dict[str, Any], state: BlockState) -> str: return '**' + self.render_children(token, state) + '**' def link(self, token: Dict[str, Any], state: BlockState) -> str: attrs = token['attrs'] text = self.render_children(token, state) return '`' + text + ' <' + attrs['url'] + '>`__' def image(self, token: Dict[str, Any], state: BlockState) -> str: refs: list = state.env['inline_images'] index = len(refs) refs.append(token) return '|' + self.INLINE_IMAGE_PREFIX + str(index) + '|' def codespan(self, token: Dict[str, Any], state: BlockState) -> str: return '``' + token['raw'] + '``' def linebreak(self, token: Dict[str, Any], state: BlockState) -> str: return '<linebreak>' def softbreak(self, token: Dict[str, Any], state: BlockState) -> str: return ' ' def inline_html(self, token: Dict[str, Any], state: BlockState) -> str: # rst does not support inline html return '' def paragraph(self, token: Dict[str, Any], state: BlockState) -> str: children = token['children'] if len(children) == 1 and children[0]['type'] == 'image': image = children[0] attrs = image['attrs'] title = attrs.get('title') alt = self.render_children(image, state) text = '.. figure:: ' + attrs['url'] if title: text += '\n :alt: ' + title text += '\n\n' + indent(alt, ' ') else: text = self.render_tokens(children, state) lines = text.split('<linebreak>') if len(lines) > 1: text = '\n'.join('| ' + line for line in lines) return text + '\n\n' def heading(self, token: Dict[str, Any], state: BlockState) -> str: attrs = token['attrs'] text = self.render_children(token, state) marker = self.HEADING_MARKERS[attrs['level']] return text + '\n' + marker * len(text) + '\n\n' def thematic_break(self, token: Dict[str, Any], state: BlockState) -> str: return '--------------\n\n' def block_text(self, token: Dict[str, Any], state: BlockState) -> str: return self.render_children(token, state) + '\n' def block_code(self, token: Dict[str, Any], state: BlockState) -> str: attrs = token.get('attrs', {}) info = attrs.get('info') code = indent(token['raw'], ' ') if info: lang = info.split()[0] return '.. code:: ' + lang + '\n\n' + code + '\n' else: return '::\n\n' + code + '\n\n' def block_quote(self, token: Dict[str, Any], state: BlockState) -> str: text = indent(self.render_children(token, state), ' ') prev = token['prev'] ignore_blocks = ( 'paragraph', 'thematic_break', 'linebreak', 'heading', ) if prev and prev['type'] not in ignore_blocks: text = '..\n\n' + text return text def block_html(self, token: Dict[str, Any], state: BlockState) -> str: raw = token['raw'] return '.. raw:: html\n\n' + indent(raw, ' ') + '\n\n' def block_error(self, token: Dict[str, Any], state: BlockState) -> str: return '' def list(self, token: Dict[str, Any], state: BlockState) -> str: return render_list(self, token, state) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/toc.py��������������������������������������������������������������������0000664�0000000�0000000�00000006055�14505662126�0016627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .util import striptags def add_toc_hook(md, min_level=1, max_level=3, heading_id=None): """Add a hook to save toc items into ``state.env``. This is usually helpful for doc generator:: import mistune from mistune.toc import add_toc_hook, render_toc_ul md = mistune.create_markdown(...) add_toc_hook(md) html, state = md.parse(text) toc_items = state.env['toc_items'] toc_html = render_toc_ul(toc_items) :param md: Markdown instance :param min_level: min heading level :param max_level: max heading level :param heading_id: a function to generate heading_id """ if heading_id is None: def heading_id(token, index): return 'toc_' + str(index + 1) def toc_hook(md, state): headings = [] for tok in state.tokens: if tok['type'] == 'heading': level = tok['attrs']['level'] if min_level <= level <= max_level: headings.append(tok) toc_items = [] for i, tok in enumerate(headings): tok['attrs']['id'] = heading_id(tok, i) toc_items.append(normalize_toc_item(md, tok)) # save items into state state.env['toc_items'] = toc_items md.before_render_hooks.append(toc_hook) def normalize_toc_item(md, token): text = token['text'] tokens = md.inline(text, {}) html = md.renderer(tokens, {}) text = striptags(html) attrs = token['attrs'] return attrs['level'], attrs['id'], text def render_toc_ul(toc): """Render a <ul> table of content HTML. The param "toc" should be formatted into this structure:: [ (level, id, text), ] For example:: [ (1, 'toc-intro', 'Introduction'), (2, 'toc-install', 'Install'), (2, 'toc-upgrade', 'Upgrade'), (1, 'toc-license', 'License'), ] """ if not toc: return '' s = '<ul>\n' levels = [] for level, k, text in toc: item = '<a href="#{}">{}</a>'.format(k, text) if not levels: s += '<li>' + item levels.append(level) elif level == levels[-1]: s += '</li>\n<li>' + item elif level > levels[-1]: s += '\n<ul>\n<li>' + item levels.append(level) else: levels.pop() while levels: last_level = levels.pop() if level == last_level: s += '</li>\n</ul>\n</li>\n<li>' + item levels.append(level) break elif level > last_level: s += '</li>\n<li>' + item levels.append(last_level) levels.append(level) break else: s += '</li>\n</ul>\n' else: levels.append(level) s += '</li>\n<li>' + item while len(levels) > 1: s += '</li>\n</ul>\n' levels.pop() return s + '</li>\n</ul>\n' �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/src/mistune/util.py�������������������������������������������������������������������0000664�0000000�0000000�00000003510�14505662126�0017010�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from urllib.parse import quote from html import _replace_charref _expand_tab_re = re.compile(r'^( {0,3})\t', flags=re.M) def expand_leading_tab(text: str, width=4): def repl(m): s = m.group(1) return s + ' ' * (width - len(s)) return _expand_tab_re.sub(repl, text) def expand_tab(text: str, space: str=' '): repl = r'\1' + space return _expand_tab_re.sub(repl, text) def escape(s: str, quote: bool=True): """Escape characters of ``&<>``. If quote=True, ``"`` will be converted to ``"e;``.""" s = s.replace("&", "&") s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) return s def escape_url(link: str): """Escape URL for safety.""" safe = ( ':/?#@' # gen-delims - '[]' (rfc3986) '!$&()*+,;=' # sub-delims - "'" (rfc3986) '%' # leave already-encoded octets alone ) return escape(quote(unescape(link), safe=safe)) def safe_entity(s: str): """Escape characters for safety.""" return escape(unescape(s)) def unikey(s: str): """Generate a unique key for links and footnotes.""" key = ' '.join(s.split()).strip() return key.lower().upper() _charref_re = re.compile( r'&(#[0-9]{1,7};' r'|#[xX][0-9a-fA-F]+;' r'|[^\t\n\f <&#;]{1,32};)' ) def unescape(s: str): """ Copy from `html.unescape`, but `_charref` is different. CommonMark does not accept entity references without a trailing semicolon """ if '&' not in s: return s return _charref_re.sub(_replace_charref, s) _striptags_re = re.compile(r'(<!--.*?-->|<[^>]*>)') def striptags(s: str): return _striptags_re.sub('', s) _strip_end_re = re.compile(r'\n\s+$') def strip_end(src: str): return _strip_end_re.sub('\n', src) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/��������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14505662126�0014351�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/__init__.py���������������������������������������������������������������������0000664�0000000�0000000�00000001655�14505662126�0016471�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from tests import fixtures from unittest import TestCase class BaseTestCase(TestCase): @classmethod def load_fixtures(cls, case_file): def attach_case(n, text, html): def method(self): self.assert_case(n, text, html) name = 'test_{}'.format(n) method.__name__ = name method.__doc__ = 'Run fixture {} - {}'.format(case_file, n) setattr(cls, name, method) for n, text, html in fixtures.load_examples(case_file): if cls.ignore_case(n): continue attach_case(n, text, html) @classmethod def ignore_case(cls, name): return False def assert_case(self, name, text, html): result = self.parse(text) self.assertEqual(result, html) def normalize_html(html): html = re.sub(r'>\n+', '>', html) html = re.sub(r'\n+<', '<', html) return html.strip() �����������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�14505662126�0016222�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/__init__.py������������������������������������������������������������0000664�0000000�0000000�00000002520�14505662126�0020332�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os import re import json ROOT = os.path.join(os.path.dirname(__file__)) EXAMPLE_PATTERN = re.compile( r'^`{32} example\n([\s\S]*?)' r'^\.\n([\s\S]*?)' r'^`{32}$|^#{1,6} *(.*)$', flags=re.M ) def load_ast(filename): with open(os.path.join(ROOT, 'ast', filename)) as f: return json.load(f) def load_json(filename): with open(os.path.join(ROOT, filename)) as f: return json.load(f) def load_examples(filename): if filename.endswith('.json'): data = load_json(filename) for item in data: section = item['section'].lower().replace(' ', '_') n = '%s_%03d' % (section, item['example']) yield n, item['markdown'], item['html'] else: with open(os.path.join(ROOT, filename), 'rb') as f: content = f.read() s = content.decode('utf-8') yield from parse_examples(s) def parse_examples(text): data = EXAMPLE_PATTERN.findall(text) section = None count = 0 for md, html, title in data: if title: count = 0 section = title.lower().replace(' ', '_') if md and html: count += 1 n = '%s_%03d' % (section, count) md = md.replace(u'\u2192', '\t') html = html.replace(u'\u2192', '\t') yield n, md, html ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/abbr.txt���������������������������������������������������������������0000664�0000000�0000000�00000005217�14505662126�0017676�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Abbreviation ## abbreviation ```````````````````````````````` example HTML . <p>HTML</p> ```````````````````````````````` ```````````````````````````````` example HTML *[HTML]: Hyper Text Markup Language . <p><abbr title="Hyper Text Markup Language">HTML</abbr></p> ```````````````````````````````` ```````````````````````````````` example The HTML specification is maintained by the W3C. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium . <p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p> ```````````````````````````````` ```````````````````````````````` example The HTML specification is maintained by the W3C. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium . <p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p> ```````````````````````````````` ```````````````````````````````` example The HTML specification is maintained by the W3C. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium There is more text below this one. . <p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p> <p>There is more text below this one.</p> ```````````````````````````````` ```````````````````````````````` example The latest spec of HTML is HTML5. *[HTML]: Hyper Text Markup Language . <p>The latest spec of <abbr title="Hyper Text Markup Language">HTML</abbr> is <abbr title="Hyper Text Markup Language">HTML</abbr>5.</p> ```````````````````````````````` ```````````````````````````````` example HTML should always be spelt with capital letters and not spelt html. *[HTML]: Hyper Text Markup Language . <p><abbr title="Hyper Text Markup Language">HTML</abbr> should always be spelt with capital letters and not spelt html.</p> ```````````````````````````````` ```````````````````````````````` example HTML is an abbreviation but nobody knows what it stands for. *[HTML]: . <p><abbr>HTML</abbr> is an abbreviation but nobody knows what it stands for.</p> ```````````````````````````````` ```````````````````````````````` example Foo.* looks like a regular expression. *[Foo.*]: Just foo . <p><abbr title="Just foo">Foo.*</abbr> looks like a regular expression.</p> ```````````````````````````````` ```````````````````````````````` example Untrusted HTML should be escaped. *[HTML]: <p>This is some HTML</p> . <p>Untrusted <abbr title="<p>This is some HTML</p>">HTML</abbr> should be escaped.</p> ```````````````````````````````` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/commonmark.json��������������������������������������������������������0000664�0000000�0000000�00000422207�14505662126�0021267�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[ { "markdown": "\tfoo\tbaz\t\tbim\n", "html": "<pre><code>foo\tbaz\t\tbim\n</code></pre>\n", "example": 1, "start_line": 356, "end_line": 361, "section": "Tabs" }, { "markdown": " \tfoo\tbaz\t\tbim\n", "html": "<pre><code>foo\tbaz\t\tbim\n</code></pre>\n", "example": 2, "start_line": 363, "end_line": 368, "section": "Tabs" }, { "markdown": " a\ta\n ὐ\ta\n", "html": "<pre><code>a\ta\nὐ\ta\n</code></pre>\n", "example": 3, "start_line": 370, "end_line": 377, "section": "Tabs" }, { "markdown": " - foo\n\n\tbar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", "example": 4, "start_line": 383, "end_line": 394, "section": "Tabs" }, { "markdown": "- foo\n\n\t\tbar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<pre><code> bar\n</code></pre>\n</li>\n</ul>\n", "example": 5, "start_line": 396, "end_line": 408, "section": "Tabs" }, { "markdown": ">\t\tfoo\n", "html": "<blockquote>\n<pre><code> foo\n</code></pre>\n</blockquote>\n", "example": 6, "start_line": 419, "end_line": 426, "section": "Tabs" }, { "markdown": "-\t\tfoo\n", "html": "<ul>\n<li>\n<pre><code> foo\n</code></pre>\n</li>\n</ul>\n", "example": 7, "start_line": 428, "end_line": 437, "section": "Tabs" }, { "markdown": " foo\n\tbar\n", "html": "<pre><code>foo\nbar\n</code></pre>\n", "example": 8, "start_line": 440, "end_line": 447, "section": "Tabs" }, { "markdown": " - foo\n - bar\n\t - baz\n", "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", "example": 9, "start_line": 449, "end_line": 465, "section": "Tabs" }, { "markdown": "#\tFoo\n", "html": "<h1>Foo</h1>\n", "example": 10, "start_line": 467, "end_line": 471, "section": "Tabs" }, { "markdown": "*\t*\t*\t\n", "html": "<hr />\n", "example": 11, "start_line": 473, "end_line": 477, "section": "Tabs" }, { "markdown": "\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~\n", "html": "<p>!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~</p>\n", "example": 12, "start_line": 490, "end_line": 494, "section": "Backslash escapes" }, { "markdown": "\\\t\\A\\a\\ \\3\\φ\\«\n", "html": "<p>\\\t\\A\\a\\ \\3\\φ\\«</p>\n", "example": 13, "start_line": 500, "end_line": 504, "section": "Backslash escapes" }, { "markdown": "\\*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\\ö not a character entity\n", "html": "<p>*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</p>\n", "example": 14, "start_line": 510, "end_line": 530, "section": "Backslash escapes" }, { "markdown": "\\\\*emphasis*\n", "html": "<p>\\<em>emphasis</em></p>\n", "example": 15, "start_line": 535, "end_line": 539, "section": "Backslash escapes" }, { "markdown": "foo\\\nbar\n", "html": "<p>foo<br />\nbar</p>\n", "example": 16, "start_line": 544, "end_line": 550, "section": "Backslash escapes" }, { "markdown": "`` \\[\\` ``\n", "html": "<p><code>\\[\\`</code></p>\n", "example": 17, "start_line": 556, "end_line": 560, "section": "Backslash escapes" }, { "markdown": " \\[\\]\n", "html": "<pre><code>\\[\\]\n</code></pre>\n", "example": 18, "start_line": 563, "end_line": 568, "section": "Backslash escapes" }, { "markdown": "~~~\n\\[\\]\n~~~\n", "html": "<pre><code>\\[\\]\n</code></pre>\n", "example": 19, "start_line": 571, "end_line": 578, "section": "Backslash escapes" }, { "markdown": "<http://example.com?find=\\*>\n", "html": "<p><a href=\"http://example.com?find=%5C*\">http://example.com?find=\\*</a></p>\n", "example": 20, "start_line": 581, "end_line": 585, "section": "Backslash escapes" }, { "markdown": "<a href=\"/bar\\/)\">\n", "html": "<a href=\"/bar\\/)\">\n", "example": 21, "start_line": 588, "end_line": 592, "section": "Backslash escapes" }, { "markdown": "[foo](/bar\\* \"ti\\*tle\")\n", "html": "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>\n", "example": 22, "start_line": 598, "end_line": 602, "section": "Backslash escapes" }, { "markdown": "[foo]\n\n[foo]: /bar\\* \"ti\\*tle\"\n", "html": "<p><a href=\"/bar*\" title=\"ti*tle\">foo</a></p>\n", "example": 23, "start_line": 605, "end_line": 611, "section": "Backslash escapes" }, { "markdown": "``` foo\\+bar\nfoo\n```\n", "html": "<pre><code class=\"language-foo+bar\">foo\n</code></pre>\n", "example": 24, "start_line": 614, "end_line": 621, "section": "Backslash escapes" }, { "markdown": "  & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸\n", "html": "<p>  & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸</p>\n", "example": 25, "start_line": 650, "end_line": 658, "section": "Entity and numeric character references" }, { "markdown": "# Ӓ Ϡ �\n", "html": "<p># Ӓ Ϡ �</p>\n", "example": 26, "start_line": 669, "end_line": 673, "section": "Entity and numeric character references" }, { "markdown": "" ആ ಫ\n", "html": "<p>" ആ ಫ</p>\n", "example": 27, "start_line": 682, "end_line": 686, "section": "Entity and numeric character references" }, { "markdown": "  &x; &#; &#x;\n�\n&#abcdef0;\n&ThisIsNotDefined; &hi?;\n", "html": "<p>&nbsp &x; &#; &#x;\n&#87654321;\n&#abcdef0;\n&ThisIsNotDefined; &hi?;</p>\n", "example": 28, "start_line": 691, "end_line": 701, "section": "Entity and numeric character references" }, { "markdown": "©\n", "html": "<p>&copy</p>\n", "example": 29, "start_line": 708, "end_line": 712, "section": "Entity and numeric character references" }, { "markdown": "&MadeUpEntity;\n", "html": "<p>&MadeUpEntity;</p>\n", "example": 30, "start_line": 718, "end_line": 722, "section": "Entity and numeric character references" }, { "markdown": "<a href=\"öö.html\">\n", "html": "<a href=\"öö.html\">\n", "example": 31, "start_line": 729, "end_line": 733, "section": "Entity and numeric character references" }, { "markdown": "[foo](/föö \"föö\")\n", "html": "<p><a href=\"/f%C3%B6%C3%B6\" title=\"föö\">foo</a></p>\n", "example": 32, "start_line": 736, "end_line": 740, "section": "Entity and numeric character references" }, { "markdown": "[foo]\n\n[foo]: /föö \"föö\"\n", "html": "<p><a href=\"/f%C3%B6%C3%B6\" title=\"föö\">foo</a></p>\n", "example": 33, "start_line": 743, "end_line": 749, "section": "Entity and numeric character references" }, { "markdown": "``` föö\nfoo\n```\n", "html": "<pre><code class=\"language-föö\">foo\n</code></pre>\n", "example": 34, "start_line": 752, "end_line": 759, "section": "Entity and numeric character references" }, { "markdown": "`föö`\n", "html": "<p><code>f&ouml;&ouml;</code></p>\n", "example": 35, "start_line": 765, "end_line": 769, "section": "Entity and numeric character references" }, { "markdown": " föfö\n", "html": "<pre><code>f&ouml;f&ouml;\n</code></pre>\n", "example": 36, "start_line": 772, "end_line": 777, "section": "Entity and numeric character references" }, { "markdown": "*foo*\n*foo*\n", "html": "<p>*foo*\n<em>foo</em></p>\n", "example": 37, "start_line": 784, "end_line": 790, "section": "Entity and numeric character references" }, { "markdown": "* foo\n\n* foo\n", "html": "<p>* foo</p>\n<ul>\n<li>foo</li>\n</ul>\n", "example": 38, "start_line": 792, "end_line": 801, "section": "Entity and numeric character references" }, { "markdown": "foo bar\n", "html": "<p>foo\n\nbar</p>\n", "example": 39, "start_line": 803, "end_line": 809, "section": "Entity and numeric character references" }, { "markdown": " foo\n", "html": "<p>\tfoo</p>\n", "example": 40, "start_line": 811, "end_line": 815, "section": "Entity and numeric character references" }, { "markdown": "[a](url "tit")\n", "html": "<p>[a](url "tit")</p>\n", "example": 41, "start_line": 818, "end_line": 822, "section": "Entity and numeric character references" }, { "markdown": "- `one\n- two`\n", "html": "<ul>\n<li>`one</li>\n<li>two`</li>\n</ul>\n", "example": 42, "start_line": 841, "end_line": 849, "section": "Precedence" }, { "markdown": "***\n---\n___\n", "html": "<hr />\n<hr />\n<hr />\n", "example": 43, "start_line": 880, "end_line": 888, "section": "Thematic breaks" }, { "markdown": "+++\n", "html": "<p>+++</p>\n", "example": 44, "start_line": 893, "end_line": 897, "section": "Thematic breaks" }, { "markdown": "===\n", "html": "<p>===</p>\n", "example": 45, "start_line": 900, "end_line": 904, "section": "Thematic breaks" }, { "markdown": "--\n**\n__\n", "html": "<p>--\n**\n__</p>\n", "example": 46, "start_line": 909, "end_line": 917, "section": "Thematic breaks" }, { "markdown": " ***\n ***\n ***\n", "html": "<hr />\n<hr />\n<hr />\n", "example": 47, "start_line": 922, "end_line": 930, "section": "Thematic breaks" }, { "markdown": " ***\n", "html": "<pre><code>***\n</code></pre>\n", "example": 48, "start_line": 935, "end_line": 940, "section": "Thematic breaks" }, { "markdown": "Foo\n ***\n", "html": "<p>Foo\n***</p>\n", "example": 49, "start_line": 943, "end_line": 949, "section": "Thematic breaks" }, { "markdown": "_____________________________________\n", "html": "<hr />\n", "example": 50, "start_line": 954, "end_line": 958, "section": "Thematic breaks" }, { "markdown": " - - -\n", "html": "<hr />\n", "example": 51, "start_line": 963, "end_line": 967, "section": "Thematic breaks" }, { "markdown": " ** * ** * ** * **\n", "html": "<hr />\n", "example": 52, "start_line": 970, "end_line": 974, "section": "Thematic breaks" }, { "markdown": "- - - -\n", "html": "<hr />\n", "example": 53, "start_line": 977, "end_line": 981, "section": "Thematic breaks" }, { "markdown": "- - - - \n", "html": "<hr />\n", "example": 54, "start_line": 986, "end_line": 990, "section": "Thematic breaks" }, { "markdown": "_ _ _ _ a\n\na------\n\n---a---\n", "html": "<p>_ _ _ _ a</p>\n<p>a------</p>\n<p>---a---</p>\n", "example": 55, "start_line": 995, "end_line": 1005, "section": "Thematic breaks" }, { "markdown": " *-*\n", "html": "<p><em>-</em></p>\n", "example": 56, "start_line": 1011, "end_line": 1015, "section": "Thematic breaks" }, { "markdown": "- foo\n***\n- bar\n", "html": "<ul>\n<li>foo</li>\n</ul>\n<hr />\n<ul>\n<li>bar</li>\n</ul>\n", "example": 57, "start_line": 1020, "end_line": 1032, "section": "Thematic breaks" }, { "markdown": "Foo\n***\nbar\n", "html": "<p>Foo</p>\n<hr />\n<p>bar</p>\n", "example": 58, "start_line": 1037, "end_line": 1045, "section": "Thematic breaks" }, { "markdown": "Foo\n---\nbar\n", "html": "<h2>Foo</h2>\n<p>bar</p>\n", "example": 59, "start_line": 1054, "end_line": 1061, "section": "Thematic breaks" }, { "markdown": "* Foo\n* * *\n* Bar\n", "html": "<ul>\n<li>Foo</li>\n</ul>\n<hr />\n<ul>\n<li>Bar</li>\n</ul>\n", "example": 60, "start_line": 1067, "end_line": 1079, "section": "Thematic breaks" }, { "markdown": "- Foo\n- * * *\n", "html": "<ul>\n<li>Foo</li>\n<li>\n<hr />\n</li>\n</ul>\n", "example": 61, "start_line": 1084, "end_line": 1094, "section": "Thematic breaks" }, { "markdown": "# foo\n## foo\n### foo\n#### foo\n##### foo\n###### foo\n", "html": "<h1>foo</h1>\n<h2>foo</h2>\n<h3>foo</h3>\n<h4>foo</h4>\n<h5>foo</h5>\n<h6>foo</h6>\n", "example": 62, "start_line": 1113, "end_line": 1127, "section": "ATX headings" }, { "markdown": "####### foo\n", "html": "<p>####### foo</p>\n", "example": 63, "start_line": 1132, "end_line": 1136, "section": "ATX headings" }, { "markdown": "#5 bolt\n\n#hashtag\n", "html": "<p>#5 bolt</p>\n<p>#hashtag</p>\n", "example": 64, "start_line": 1147, "end_line": 1154, "section": "ATX headings" }, { "markdown": "\\## foo\n", "html": "<p>## foo</p>\n", "example": 65, "start_line": 1159, "end_line": 1163, "section": "ATX headings" }, { "markdown": "# foo *bar* \\*baz\\*\n", "html": "<h1>foo <em>bar</em> *baz*</h1>\n", "example": 66, "start_line": 1168, "end_line": 1172, "section": "ATX headings" }, { "markdown": "# foo \n", "html": "<h1>foo</h1>\n", "example": 67, "start_line": 1177, "end_line": 1181, "section": "ATX headings" }, { "markdown": " ### foo\n ## foo\n # foo\n", "html": "<h3>foo</h3>\n<h2>foo</h2>\n<h1>foo</h1>\n", "example": 68, "start_line": 1186, "end_line": 1194, "section": "ATX headings" }, { "markdown": " # foo\n", "html": "<pre><code># foo\n</code></pre>\n", "example": 69, "start_line": 1199, "end_line": 1204, "section": "ATX headings" }, { "markdown": "foo\n # bar\n", "html": "<p>foo\n# bar</p>\n", "example": 70, "start_line": 1207, "end_line": 1213, "section": "ATX headings" }, { "markdown": "## foo ##\n ### bar ###\n", "html": "<h2>foo</h2>\n<h3>bar</h3>\n", "example": 71, "start_line": 1218, "end_line": 1224, "section": "ATX headings" }, { "markdown": "# foo ##################################\n##### foo ##\n", "html": "<h1>foo</h1>\n<h5>foo</h5>\n", "example": 72, "start_line": 1229, "end_line": 1235, "section": "ATX headings" }, { "markdown": "### foo ### \n", "html": "<h3>foo</h3>\n", "example": 73, "start_line": 1240, "end_line": 1244, "section": "ATX headings" }, { "markdown": "### foo ### b\n", "html": "<h3>foo ### b</h3>\n", "example": 74, "start_line": 1251, "end_line": 1255, "section": "ATX headings" }, { "markdown": "# foo#\n", "html": "<h1>foo#</h1>\n", "example": 75, "start_line": 1260, "end_line": 1264, "section": "ATX headings" }, { "markdown": "### foo \\###\n## foo #\\##\n# foo \\#\n", "html": "<h3>foo ###</h3>\n<h2>foo ###</h2>\n<h1>foo #</h1>\n", "example": 76, "start_line": 1270, "end_line": 1278, "section": "ATX headings" }, { "markdown": "****\n## foo\n****\n", "html": "<hr />\n<h2>foo</h2>\n<hr />\n", "example": 77, "start_line": 1284, "end_line": 1292, "section": "ATX headings" }, { "markdown": "Foo bar\n# baz\nBar foo\n", "html": "<p>Foo bar</p>\n<h1>baz</h1>\n<p>Bar foo</p>\n", "example": 78, "start_line": 1295, "end_line": 1303, "section": "ATX headings" }, { "markdown": "## \n#\n### ###\n", "html": "<h2></h2>\n<h1></h1>\n<h3></h3>\n", "example": 79, "start_line": 1308, "end_line": 1316, "section": "ATX headings" }, { "markdown": "Foo *bar*\n=========\n\nFoo *bar*\n---------\n", "html": "<h1>Foo <em>bar</em></h1>\n<h2>Foo <em>bar</em></h2>\n", "example": 80, "start_line": 1351, "end_line": 1360, "section": "Setext headings" }, { "markdown": "Foo *bar\nbaz*\n====\n", "html": "<h1>Foo <em>bar\nbaz</em></h1>\n", "example": 81, "start_line": 1365, "end_line": 1372, "section": "Setext headings" }, { "markdown": " Foo *bar\nbaz*\t\n====\n", "html": "<h1>Foo <em>bar\nbaz</em></h1>\n", "example": 82, "start_line": 1379, "end_line": 1386, "section": "Setext headings" }, { "markdown": "Foo\n-------------------------\n\nFoo\n=\n", "html": "<h2>Foo</h2>\n<h1>Foo</h1>\n", "example": 83, "start_line": 1391, "end_line": 1400, "section": "Setext headings" }, { "markdown": " Foo\n---\n\n Foo\n-----\n\n Foo\n ===\n", "html": "<h2>Foo</h2>\n<h2>Foo</h2>\n<h1>Foo</h1>\n", "example": 84, "start_line": 1406, "end_line": 1419, "section": "Setext headings" }, { "markdown": " Foo\n ---\n\n Foo\n---\n", "html": "<pre><code>Foo\n---\n\nFoo\n</code></pre>\n<hr />\n", "example": 85, "start_line": 1424, "end_line": 1437, "section": "Setext headings" }, { "markdown": "Foo\n ---- \n", "html": "<h2>Foo</h2>\n", "example": 86, "start_line": 1443, "end_line": 1448, "section": "Setext headings" }, { "markdown": "Foo\n ---\n", "html": "<p>Foo\n---</p>\n", "example": 87, "start_line": 1453, "end_line": 1459, "section": "Setext headings" }, { "markdown": "Foo\n= =\n\nFoo\n--- -\n", "html": "<p>Foo\n= =</p>\n<p>Foo</p>\n<hr />\n", "example": 88, "start_line": 1464, "end_line": 1475, "section": "Setext headings" }, { "markdown": "Foo \n-----\n", "html": "<h2>Foo</h2>\n", "example": 89, "start_line": 1480, "end_line": 1485, "section": "Setext headings" }, { "markdown": "Foo\\\n----\n", "html": "<h2>Foo\\</h2>\n", "example": 90, "start_line": 1490, "end_line": 1495, "section": "Setext headings" }, { "markdown": "`Foo\n----\n`\n\n<a title=\"a lot\n---\nof dashes\"/>\n", "html": "<h2>`Foo</h2>\n<p>`</p>\n<h2><a title="a lot</h2>\n<p>of dashes"/></p>\n", "example": 91, "start_line": 1501, "end_line": 1514, "section": "Setext headings" }, { "markdown": "> Foo\n---\n", "html": "<blockquote>\n<p>Foo</p>\n</blockquote>\n<hr />\n", "example": 92, "start_line": 1520, "end_line": 1528, "section": "Setext headings" }, { "markdown": "> foo\nbar\n===\n", "html": "<blockquote>\n<p>foo\nbar\n===</p>\n</blockquote>\n", "example": 93, "start_line": 1531, "end_line": 1541, "section": "Setext headings" }, { "markdown": "- Foo\n---\n", "html": "<ul>\n<li>Foo</li>\n</ul>\n<hr />\n", "example": 94, "start_line": 1544, "end_line": 1552, "section": "Setext headings" }, { "markdown": "Foo\nBar\n---\n", "html": "<h2>Foo\nBar</h2>\n", "example": 95, "start_line": 1559, "end_line": 1566, "section": "Setext headings" }, { "markdown": "---\nFoo\n---\nBar\n---\nBaz\n", "html": "<hr />\n<h2>Foo</h2>\n<h2>Bar</h2>\n<p>Baz</p>\n", "example": 96, "start_line": 1572, "end_line": 1584, "section": "Setext headings" }, { "markdown": "\n====\n", "html": "<p>====</p>\n", "example": 97, "start_line": 1589, "end_line": 1594, "section": "Setext headings" }, { "markdown": "---\n---\n", "html": "<hr />\n<hr />\n", "example": 98, "start_line": 1601, "end_line": 1607, "section": "Setext headings" }, { "markdown": "- foo\n-----\n", "html": "<ul>\n<li>foo</li>\n</ul>\n<hr />\n", "example": 99, "start_line": 1610, "end_line": 1618, "section": "Setext headings" }, { "markdown": " foo\n---\n", "html": "<pre><code>foo\n</code></pre>\n<hr />\n", "example": 100, "start_line": 1621, "end_line": 1628, "section": "Setext headings" }, { "markdown": "> foo\n-----\n", "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<hr />\n", "example": 101, "start_line": 1631, "end_line": 1639, "section": "Setext headings" }, { "markdown": "\\> foo\n------\n", "html": "<h2>> foo</h2>\n", "example": 102, "start_line": 1645, "end_line": 1650, "section": "Setext headings" }, { "markdown": "Foo\n\nbar\n---\nbaz\n", "html": "<p>Foo</p>\n<h2>bar</h2>\n<p>baz</p>\n", "example": 103, "start_line": 1676, "end_line": 1686, "section": "Setext headings" }, { "markdown": "Foo\nbar\n\n---\n\nbaz\n", "html": "<p>Foo\nbar</p>\n<hr />\n<p>baz</p>\n", "example": 104, "start_line": 1692, "end_line": 1704, "section": "Setext headings" }, { "markdown": "Foo\nbar\n* * *\nbaz\n", "html": "<p>Foo\nbar</p>\n<hr />\n<p>baz</p>\n", "example": 105, "start_line": 1710, "end_line": 1720, "section": "Setext headings" }, { "markdown": "Foo\nbar\n\\---\nbaz\n", "html": "<p>Foo\nbar\n---\nbaz</p>\n", "example": 106, "start_line": 1725, "end_line": 1735, "section": "Setext headings" }, { "markdown": " a simple\n indented code block\n", "html": "<pre><code>a simple\n indented code block\n</code></pre>\n", "example": 107, "start_line": 1753, "end_line": 1760, "section": "Indented code blocks" }, { "markdown": " - foo\n\n bar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", "example": 108, "start_line": 1767, "end_line": 1778, "section": "Indented code blocks" }, { "markdown": "1. foo\n\n - bar\n", "html": "<ol>\n<li>\n<p>foo</p>\n<ul>\n<li>bar</li>\n</ul>\n</li>\n</ol>\n", "example": 109, "start_line": 1781, "end_line": 1794, "section": "Indented code blocks" }, { "markdown": " <a/>\n *hi*\n\n - one\n", "html": "<pre><code><a/>\n*hi*\n\n- one\n</code></pre>\n", "example": 110, "start_line": 1801, "end_line": 1812, "section": "Indented code blocks" }, { "markdown": " chunk1\n\n chunk2\n \n \n \n chunk3\n", "html": "<pre><code>chunk1\n\nchunk2\n\n\n\nchunk3\n</code></pre>\n", "example": 111, "start_line": 1817, "end_line": 1834, "section": "Indented code blocks" }, { "markdown": " chunk1\n \n chunk2\n", "html": "<pre><code>chunk1\n \n chunk2\n</code></pre>\n", "example": 112, "start_line": 1840, "end_line": 1849, "section": "Indented code blocks" }, { "markdown": "Foo\n bar\n\n", "html": "<p>Foo\nbar</p>\n", "example": 113, "start_line": 1855, "end_line": 1862, "section": "Indented code blocks" }, { "markdown": " foo\nbar\n", "html": "<pre><code>foo\n</code></pre>\n<p>bar</p>\n", "example": 114, "start_line": 1869, "end_line": 1876, "section": "Indented code blocks" }, { "markdown": "# Heading\n foo\nHeading\n------\n foo\n----\n", "html": "<h1>Heading</h1>\n<pre><code>foo\n</code></pre>\n<h2>Heading</h2>\n<pre><code>foo\n</code></pre>\n<hr />\n", "example": 115, "start_line": 1882, "end_line": 1897, "section": "Indented code blocks" }, { "markdown": " foo\n bar\n", "html": "<pre><code> foo\nbar\n</code></pre>\n", "example": 116, "start_line": 1902, "end_line": 1909, "section": "Indented code blocks" }, { "markdown": "\n \n foo\n \n\n", "html": "<pre><code>foo\n</code></pre>\n", "example": 117, "start_line": 1915, "end_line": 1924, "section": "Indented code blocks" }, { "markdown": " foo \n", "html": "<pre><code>foo \n</code></pre>\n", "example": 118, "start_line": 1929, "end_line": 1934, "section": "Indented code blocks" }, { "markdown": "```\n<\n >\n```\n", "html": "<pre><code><\n >\n</code></pre>\n", "example": 119, "start_line": 1984, "end_line": 1993, "section": "Fenced code blocks" }, { "markdown": "~~~\n<\n >\n~~~\n", "html": "<pre><code><\n >\n</code></pre>\n", "example": 120, "start_line": 1998, "end_line": 2007, "section": "Fenced code blocks" }, { "markdown": "``\nfoo\n``\n", "html": "<p><code>foo</code></p>\n", "example": 121, "start_line": 2011, "end_line": 2017, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n~~~\n```\n", "html": "<pre><code>aaa\n~~~\n</code></pre>\n", "example": 122, "start_line": 2022, "end_line": 2031, "section": "Fenced code blocks" }, { "markdown": "~~~\naaa\n```\n~~~\n", "html": "<pre><code>aaa\n```\n</code></pre>\n", "example": 123, "start_line": 2034, "end_line": 2043, "section": "Fenced code blocks" }, { "markdown": "````\naaa\n```\n``````\n", "html": "<pre><code>aaa\n```\n</code></pre>\n", "example": 124, "start_line": 2048, "end_line": 2057, "section": "Fenced code blocks" }, { "markdown": "~~~~\naaa\n~~~\n~~~~\n", "html": "<pre><code>aaa\n~~~\n</code></pre>\n", "example": 125, "start_line": 2060, "end_line": 2069, "section": "Fenced code blocks" }, { "markdown": "```\n", "html": "<pre><code></code></pre>\n", "example": 126, "start_line": 2075, "end_line": 2079, "section": "Fenced code blocks" }, { "markdown": "`````\n\n```\naaa\n", "html": "<pre><code>\n```\naaa\n</code></pre>\n", "example": 127, "start_line": 2082, "end_line": 2092, "section": "Fenced code blocks" }, { "markdown": "> ```\n> aaa\n\nbbb\n", "html": "<blockquote>\n<pre><code>aaa\n</code></pre>\n</blockquote>\n<p>bbb</p>\n", "example": 128, "start_line": 2095, "end_line": 2106, "section": "Fenced code blocks" }, { "markdown": "```\n\n \n```\n", "html": "<pre><code>\n \n</code></pre>\n", "example": 129, "start_line": 2111, "end_line": 2120, "section": "Fenced code blocks" }, { "markdown": "```\n```\n", "html": "<pre><code></code></pre>\n", "example": 130, "start_line": 2125, "end_line": 2130, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\naaa\n```\n", "html": "<pre><code>aaa\naaa\n</code></pre>\n", "example": 131, "start_line": 2137, "end_line": 2146, "section": "Fenced code blocks" }, { "markdown": " ```\naaa\n aaa\naaa\n ```\n", "html": "<pre><code>aaa\naaa\naaa\n</code></pre>\n", "example": 132, "start_line": 2149, "end_line": 2160, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\n aaa\n aaa\n ```\n", "html": "<pre><code>aaa\n aaa\naaa\n</code></pre>\n", "example": 133, "start_line": 2163, "end_line": 2174, "section": "Fenced code blocks" }, { "markdown": " ```\n aaa\n ```\n", "html": "<pre><code>```\naaa\n```\n</code></pre>\n", "example": 134, "start_line": 2179, "end_line": 2188, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n ```\n", "html": "<pre><code>aaa\n</code></pre>\n", "example": 135, "start_line": 2194, "end_line": 2201, "section": "Fenced code blocks" }, { "markdown": " ```\naaa\n ```\n", "html": "<pre><code>aaa\n</code></pre>\n", "example": 136, "start_line": 2204, "end_line": 2211, "section": "Fenced code blocks" }, { "markdown": "```\naaa\n ```\n", "html": "<pre><code>aaa\n ```\n</code></pre>\n", "example": 137, "start_line": 2216, "end_line": 2224, "section": "Fenced code blocks" }, { "markdown": "``` ```\naaa\n", "html": "<p><code> </code>\naaa</p>\n", "example": 138, "start_line": 2230, "end_line": 2236, "section": "Fenced code blocks" }, { "markdown": "~~~~~~\naaa\n~~~ ~~\n", "html": "<pre><code>aaa\n~~~ ~~\n</code></pre>\n", "example": 139, "start_line": 2239, "end_line": 2247, "section": "Fenced code blocks" }, { "markdown": "foo\n```\nbar\n```\nbaz\n", "html": "<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>\n", "example": 140, "start_line": 2253, "end_line": 2264, "section": "Fenced code blocks" }, { "markdown": "foo\n---\n~~~\nbar\n~~~\n# baz\n", "html": "<h2>foo</h2>\n<pre><code>bar\n</code></pre>\n<h1>baz</h1>\n", "example": 141, "start_line": 2270, "end_line": 2282, "section": "Fenced code blocks" }, { "markdown": "```ruby\ndef foo(x)\n return 3\nend\n```\n", "html": "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>\n", "example": 142, "start_line": 2292, "end_line": 2303, "section": "Fenced code blocks" }, { "markdown": "~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~\n", "html": "<pre><code class=\"language-ruby\">def foo(x)\n return 3\nend\n</code></pre>\n", "example": 143, "start_line": 2306, "end_line": 2317, "section": "Fenced code blocks" }, { "markdown": "````;\n````\n", "html": "<pre><code class=\"language-;\"></code></pre>\n", "example": 144, "start_line": 2320, "end_line": 2325, "section": "Fenced code blocks" }, { "markdown": "``` aa ```\nfoo\n", "html": "<p><code>aa</code>\nfoo</p>\n", "example": 145, "start_line": 2330, "end_line": 2336, "section": "Fenced code blocks" }, { "markdown": "~~~ aa ``` ~~~\nfoo\n~~~\n", "html": "<pre><code class=\"language-aa\">foo\n</code></pre>\n", "example": 146, "start_line": 2341, "end_line": 2348, "section": "Fenced code blocks" }, { "markdown": "```\n``` aaa\n```\n", "html": "<pre><code>``` aaa\n</code></pre>\n", "example": 147, "start_line": 2353, "end_line": 2360, "section": "Fenced code blocks" }, { "markdown": "<table><tr><td>\n<pre>\n**Hello**,\n\n_world_.\n</pre>\n</td></tr></table>\n", "html": "<table><tr><td>\n<pre>\n**Hello**,\n<p><em>world</em>.\n</pre></p>\n</td></tr></table>\n", "example": 148, "start_line": 2432, "end_line": 2447, "section": "HTML blocks" }, { "markdown": "<table>\n <tr>\n <td>\n hi\n </td>\n </tr>\n</table>\n\nokay.\n", "html": "<table>\n <tr>\n <td>\n hi\n </td>\n </tr>\n</table>\n<p>okay.</p>\n", "example": 149, "start_line": 2461, "end_line": 2480, "section": "HTML blocks" }, { "markdown": " <div>\n *hello*\n <foo><a>\n", "html": " <div>\n *hello*\n <foo><a>\n", "example": 150, "start_line": 2483, "end_line": 2491, "section": "HTML blocks" }, { "markdown": "</div>\n*foo*\n", "html": "</div>\n*foo*\n", "example": 151, "start_line": 2496, "end_line": 2502, "section": "HTML blocks" }, { "markdown": "<DIV CLASS=\"foo\">\n\n*Markdown*\n\n</DIV>\n", "html": "<DIV CLASS=\"foo\">\n<p><em>Markdown</em></p>\n</DIV>\n", "example": 152, "start_line": 2507, "end_line": 2517, "section": "HTML blocks" }, { "markdown": "<div id=\"foo\"\n class=\"bar\">\n</div>\n", "html": "<div id=\"foo\"\n class=\"bar\">\n</div>\n", "example": 153, "start_line": 2523, "end_line": 2531, "section": "HTML blocks" }, { "markdown": "<div id=\"foo\" class=\"bar\n baz\">\n</div>\n", "html": "<div id=\"foo\" class=\"bar\n baz\">\n</div>\n", "example": 154, "start_line": 2534, "end_line": 2542, "section": "HTML blocks" }, { "markdown": "<div>\n*foo*\n\n*bar*\n", "html": "<div>\n*foo*\n<p><em>bar</em></p>\n", "example": 155, "start_line": 2546, "end_line": 2555, "section": "HTML blocks" }, { "markdown": "<div id=\"foo\"\n*hi*\n", "html": "<div id=\"foo\"\n*hi*\n", "example": 156, "start_line": 2562, "end_line": 2568, "section": "HTML blocks" }, { "markdown": "<div class\nfoo\n", "html": "<div class\nfoo\n", "example": 157, "start_line": 2571, "end_line": 2577, "section": "HTML blocks" }, { "markdown": "<div *???-&&&-<---\n*foo*\n", "html": "<div *???-&&&-<---\n*foo*\n", "example": 158, "start_line": 2583, "end_line": 2589, "section": "HTML blocks" }, { "markdown": "<div><a href=\"bar\">*foo*</a></div>\n", "html": "<div><a href=\"bar\">*foo*</a></div>\n", "example": 159, "start_line": 2595, "end_line": 2599, "section": "HTML blocks" }, { "markdown": "<table><tr><td>\nfoo\n</td></tr></table>\n", "html": "<table><tr><td>\nfoo\n</td></tr></table>\n", "example": 160, "start_line": 2602, "end_line": 2610, "section": "HTML blocks" }, { "markdown": "<div></div>\n``` c\nint x = 33;\n```\n", "html": "<div></div>\n``` c\nint x = 33;\n```\n", "example": 161, "start_line": 2619, "end_line": 2629, "section": "HTML blocks" }, { "markdown": "<a href=\"foo\">\n*bar*\n</a>\n", "html": "<a href=\"foo\">\n*bar*\n</a>\n", "example": 162, "start_line": 2636, "end_line": 2644, "section": "HTML blocks" }, { "markdown": "<Warning>\n*bar*\n</Warning>\n", "html": "<Warning>\n*bar*\n</Warning>\n", "example": 163, "start_line": 2649, "end_line": 2657, "section": "HTML blocks" }, { "markdown": "<i class=\"foo\">\n*bar*\n</i>\n", "html": "<i class=\"foo\">\n*bar*\n</i>\n", "example": 164, "start_line": 2660, "end_line": 2668, "section": "HTML blocks" }, { "markdown": "</ins>\n*bar*\n", "html": "</ins>\n*bar*\n", "example": 165, "start_line": 2671, "end_line": 2677, "section": "HTML blocks" }, { "markdown": "<del>\n*foo*\n</del>\n", "html": "<del>\n*foo*\n</del>\n", "example": 166, "start_line": 2686, "end_line": 2694, "section": "HTML blocks" }, { "markdown": "<del>\n\n*foo*\n\n</del>\n", "html": "<del>\n<p><em>foo</em></p>\n</del>\n", "example": 167, "start_line": 2701, "end_line": 2711, "section": "HTML blocks" }, { "markdown": "<del>*foo*</del>\n", "html": "<p><del><em>foo</em></del></p>\n", "example": 168, "start_line": 2719, "end_line": 2723, "section": "HTML blocks" }, { "markdown": "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\nokay\n", "html": "<pre language=\"haskell\"><code>\nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n</code></pre>\n<p>okay</p>\n", "example": 169, "start_line": 2735, "end_line": 2751, "section": "HTML blocks" }, { "markdown": "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\nokay\n", "html": "<script type=\"text/javascript\">\n// JavaScript example\n\ndocument.getElementById(\"demo\").innerHTML = \"Hello JavaScript!\";\n</script>\n<p>okay</p>\n", "example": 170, "start_line": 2756, "end_line": 2770, "section": "HTML blocks" }, { "markdown": "<textarea>\n\n*foo*\n\n_bar_\n\n</textarea>\n", "html": "<textarea>\n\n*foo*\n\n_bar_\n\n</textarea>\n", "example": 171, "start_line": 2775, "end_line": 2791, "section": "HTML blocks" }, { "markdown": "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\nokay\n", "html": "<style\n type=\"text/css\">\nh1 {color:red;}\n\np {color:blue;}\n</style>\n<p>okay</p>\n", "example": 172, "start_line": 2795, "end_line": 2811, "section": "HTML blocks" }, { "markdown": "<style\n type=\"text/css\">\n\nfoo\n", "html": "<style\n type=\"text/css\">\n\nfoo\n", "example": 173, "start_line": 2818, "end_line": 2828, "section": "HTML blocks" }, { "markdown": "> <div>\n> foo\n\nbar\n", "html": "<blockquote>\n<div>\nfoo\n</blockquote>\n<p>bar</p>\n", "example": 174, "start_line": 2831, "end_line": 2842, "section": "HTML blocks" }, { "markdown": "- <div>\n- foo\n", "html": "<ul>\n<li>\n<div>\n</li>\n<li>foo</li>\n</ul>\n", "example": 175, "start_line": 2845, "end_line": 2855, "section": "HTML blocks" }, { "markdown": "<style>p{color:red;}</style>\n*foo*\n", "html": "<style>p{color:red;}</style>\n<p><em>foo</em></p>\n", "example": 176, "start_line": 2860, "end_line": 2866, "section": "HTML blocks" }, { "markdown": "<!-- foo -->*bar*\n*baz*\n", "html": "<!-- foo -->*bar*\n<p><em>baz</em></p>\n", "example": 177, "start_line": 2869, "end_line": 2875, "section": "HTML blocks" }, { "markdown": "<script>\nfoo\n</script>1. *bar*\n", "html": "<script>\nfoo\n</script>1. *bar*\n", "example": 178, "start_line": 2881, "end_line": 2889, "section": "HTML blocks" }, { "markdown": "<!-- Foo\n\nbar\n baz -->\nokay\n", "html": "<!-- Foo\n\nbar\n baz -->\n<p>okay</p>\n", "example": 179, "start_line": 2894, "end_line": 2906, "section": "HTML blocks" }, { "markdown": "<?php\n\n echo '>';\n\n?>\nokay\n", "html": "<?php\n\n echo '>';\n\n?>\n<p>okay</p>\n", "example": 180, "start_line": 2912, "end_line": 2926, "section": "HTML blocks" }, { "markdown": "<!DOCTYPE html>\n", "html": "<!DOCTYPE html>\n", "example": 181, "start_line": 2931, "end_line": 2935, "section": "HTML blocks" }, { "markdown": "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\nokay\n", "html": "<![CDATA[\nfunction matchwo(a,b)\n{\n if (a < b && a < 0) then {\n return 1;\n\n } else {\n\n return 0;\n }\n}\n]]>\n<p>okay</p>\n", "example": 182, "start_line": 2940, "end_line": 2968, "section": "HTML blocks" }, { "markdown": " <!-- foo -->\n\n <!-- foo -->\n", "html": " <!-- foo -->\n<pre><code><!-- foo -->\n</code></pre>\n", "example": 183, "start_line": 2974, "end_line": 2982, "section": "HTML blocks" }, { "markdown": " <div>\n\n <div>\n", "html": " <div>\n<pre><code><div>\n</code></pre>\n", "example": 184, "start_line": 2985, "end_line": 2993, "section": "HTML blocks" }, { "markdown": "Foo\n<div>\nbar\n</div>\n", "html": "<p>Foo</p>\n<div>\nbar\n</div>\n", "example": 185, "start_line": 2999, "end_line": 3009, "section": "HTML blocks" }, { "markdown": "<div>\nbar\n</div>\n*foo*\n", "html": "<div>\nbar\n</div>\n*foo*\n", "example": 186, "start_line": 3016, "end_line": 3026, "section": "HTML blocks" }, { "markdown": "Foo\n<a href=\"bar\">\nbaz\n", "html": "<p>Foo\n<a href=\"bar\">\nbaz</p>\n", "example": 187, "start_line": 3031, "end_line": 3039, "section": "HTML blocks" }, { "markdown": "<div>\n\n*Emphasized* text.\n\n</div>\n", "html": "<div>\n<p><em>Emphasized</em> text.</p>\n</div>\n", "example": 188, "start_line": 3072, "end_line": 3082, "section": "HTML blocks" }, { "markdown": "<div>\n*Emphasized* text.\n</div>\n", "html": "<div>\n*Emphasized* text.\n</div>\n", "example": 189, "start_line": 3085, "end_line": 3093, "section": "HTML blocks" }, { "markdown": "<table>\n\n<tr>\n\n<td>\nHi\n</td>\n\n</tr>\n\n</table>\n", "html": "<table>\n<tr>\n<td>\nHi\n</td>\n</tr>\n</table>\n", "example": 190, "start_line": 3107, "end_line": 3127, "section": "HTML blocks" }, { "markdown": "<table>\n\n <tr>\n\n <td>\n Hi\n </td>\n\n </tr>\n\n</table>\n", "html": "<table>\n <tr>\n<pre><code><td>\n Hi\n</td>\n</code></pre>\n </tr>\n</table>\n", "example": 191, "start_line": 3134, "end_line": 3155, "section": "HTML blocks" }, { "markdown": "[foo]: /url \"title\"\n\n[foo]\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 192, "start_line": 3183, "end_line": 3189, "section": "Link reference definitions" }, { "markdown": " [foo]: \n /url \n 'the title' \n\n[foo]\n", "html": "<p><a href=\"/url\" title=\"the title\">foo</a></p>\n", "example": 193, "start_line": 3192, "end_line": 3200, "section": "Link reference definitions" }, { "markdown": "[Foo*bar\\]]:my_(url) 'title (with parens)'\n\n[Foo*bar\\]]\n", "html": "<p><a href=\"my_(url)\" title=\"title (with parens)\">Foo*bar]</a></p>\n", "example": 194, "start_line": 3203, "end_line": 3209, "section": "Link reference definitions" }, { "markdown": "[Foo bar]:\n<my url>\n'title'\n\n[Foo bar]\n", "html": "<p><a href=\"my%20url\" title=\"title\">Foo bar</a></p>\n", "example": 195, "start_line": 3212, "end_line": 3220, "section": "Link reference definitions" }, { "markdown": "[foo]: /url '\ntitle\nline1\nline2\n'\n\n[foo]\n", "html": "<p><a href=\"/url\" title=\"\ntitle\nline1\nline2\n\">foo</a></p>\n", "example": 196, "start_line": 3225, "end_line": 3239, "section": "Link reference definitions" }, { "markdown": "[foo]: /url 'title\n\nwith blank line'\n\n[foo]\n", "html": "<p>[foo]: /url 'title</p>\n<p>with blank line'</p>\n<p>[foo]</p>\n", "example": 197, "start_line": 3244, "end_line": 3254, "section": "Link reference definitions" }, { "markdown": "[foo]:\n/url\n\n[foo]\n", "html": "<p><a href=\"/url\">foo</a></p>\n", "example": 198, "start_line": 3259, "end_line": 3266, "section": "Link reference definitions" }, { "markdown": "[foo]:\n\n[foo]\n", "html": "<p>[foo]:</p>\n<p>[foo]</p>\n", "example": 199, "start_line": 3271, "end_line": 3278, "section": "Link reference definitions" }, { "markdown": "[foo]: <>\n\n[foo]\n", "html": "<p><a href=\"\">foo</a></p>\n", "example": 200, "start_line": 3283, "end_line": 3289, "section": "Link reference definitions" }, { "markdown": "[foo]: <bar>(baz)\n\n[foo]\n", "html": "<p>[foo]: <bar>(baz)</p>\n<p>[foo]</p>\n", "example": 201, "start_line": 3294, "end_line": 3301, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\\bar\\*baz \"foo\\\"bar\\baz\"\n\n[foo]\n", "html": "<p><a href=\"/url%5Cbar*baz\" title=\"foo"bar\\baz\">foo</a></p>\n", "example": 202, "start_line": 3307, "end_line": 3313, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n[foo]: url\n", "html": "<p><a href=\"url\">foo</a></p>\n", "example": 203, "start_line": 3318, "end_line": 3324, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n[foo]: first\n[foo]: second\n", "html": "<p><a href=\"first\">foo</a></p>\n", "example": 204, "start_line": 3330, "end_line": 3337, "section": "Link reference definitions" }, { "markdown": "[FOO]: /url\n\n[Foo]\n", "html": "<p><a href=\"/url\">Foo</a></p>\n", "example": 205, "start_line": 3343, "end_line": 3349, "section": "Link reference definitions" }, { "markdown": "[ΑΓΩ]: /φου\n\n[αγω]\n", "html": "<p><a href=\"/%CF%86%CE%BF%CF%85\">αγω</a></p>\n", "example": 206, "start_line": 3352, "end_line": 3358, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n", "html": "", "example": 207, "start_line": 3367, "end_line": 3370, "section": "Link reference definitions" }, { "markdown": "[\nfoo\n]: /url\nbar\n", "html": "<p>bar</p>\n", "example": 208, "start_line": 3375, "end_line": 3382, "section": "Link reference definitions" }, { "markdown": "[foo]: /url \"title\" ok\n", "html": "<p>[foo]: /url "title" ok</p>\n", "example": 209, "start_line": 3388, "end_line": 3392, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n\"title\" ok\n", "html": "<p>"title" ok</p>\n", "example": 210, "start_line": 3397, "end_line": 3402, "section": "Link reference definitions" }, { "markdown": " [foo]: /url \"title\"\n\n[foo]\n", "html": "<pre><code>[foo]: /url "title"\n</code></pre>\n<p>[foo]</p>\n", "example": 211, "start_line": 3408, "end_line": 3416, "section": "Link reference definitions" }, { "markdown": "```\n[foo]: /url\n```\n\n[foo]\n", "html": "<pre><code>[foo]: /url\n</code></pre>\n<p>[foo]</p>\n", "example": 212, "start_line": 3422, "end_line": 3432, "section": "Link reference definitions" }, { "markdown": "Foo\n[bar]: /baz\n\n[bar]\n", "html": "<p>Foo\n[bar]: /baz</p>\n<p>[bar]</p>\n", "example": 213, "start_line": 3437, "end_line": 3446, "section": "Link reference definitions" }, { "markdown": "# [Foo]\n[foo]: /url\n> bar\n", "html": "<h1><a href=\"/url\">Foo</a></h1>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", "example": 214, "start_line": 3452, "end_line": 3461, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\nbar\n===\n[foo]\n", "html": "<h1>bar</h1>\n<p><a href=\"/url\">foo</a></p>\n", "example": 215, "start_line": 3463, "end_line": 3471, "section": "Link reference definitions" }, { "markdown": "[foo]: /url\n===\n[foo]\n", "html": "<p>===\n<a href=\"/url\">foo</a></p>\n", "example": 216, "start_line": 3473, "end_line": 3480, "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": "<p><a href=\"/foo-url\" title=\"foo\">foo</a>,\n<a href=\"/bar-url\" title=\"bar\">bar</a>,\n<a href=\"/baz-url\">baz</a></p>\n", "example": 217, "start_line": 3486, "end_line": 3499, "section": "Link reference definitions" }, { "markdown": "[foo]\n\n> [foo]: /url\n", "html": "<p><a href=\"/url\">foo</a></p>\n<blockquote>\n</blockquote>\n", "example": 218, "start_line": 3507, "end_line": 3515, "section": "Link reference definitions" }, { "markdown": "aaa\n\nbbb\n", "html": "<p>aaa</p>\n<p>bbb</p>\n", "example": 219, "start_line": 3529, "end_line": 3536, "section": "Paragraphs" }, { "markdown": "aaa\nbbb\n\nccc\nddd\n", "html": "<p>aaa\nbbb</p>\n<p>ccc\nddd</p>\n", "example": 220, "start_line": 3541, "end_line": 3552, "section": "Paragraphs" }, { "markdown": "aaa\n\n\nbbb\n", "html": "<p>aaa</p>\n<p>bbb</p>\n", "example": 221, "start_line": 3557, "end_line": 3565, "section": "Paragraphs" }, { "markdown": " aaa\n bbb\n", "html": "<p>aaa\nbbb</p>\n", "example": 222, "start_line": 3570, "end_line": 3576, "section": "Paragraphs" }, { "markdown": "aaa\n bbb\n ccc\n", "html": "<p>aaa\nbbb\nccc</p>\n", "example": 223, "start_line": 3582, "end_line": 3590, "section": "Paragraphs" }, { "markdown": " aaa\nbbb\n", "html": "<p>aaa\nbbb</p>\n", "example": 224, "start_line": 3596, "end_line": 3602, "section": "Paragraphs" }, { "markdown": " aaa\nbbb\n", "html": "<pre><code>aaa\n</code></pre>\n<p>bbb</p>\n", "example": 225, "start_line": 3605, "end_line": 3612, "section": "Paragraphs" }, { "markdown": "aaa \nbbb \n", "html": "<p>aaa<br />\nbbb</p>\n", "example": 226, "start_line": 3619, "end_line": 3625, "section": "Paragraphs" }, { "markdown": " \n\naaa\n \n\n# aaa\n\n \n", "html": "<p>aaa</p>\n<h1>aaa</h1>\n", "example": 227, "start_line": 3636, "end_line": 3648, "section": "Blank lines" }, { "markdown": "> # Foo\n> bar\n> baz\n", "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", "example": 228, "start_line": 3704, "end_line": 3714, "section": "Block quotes" }, { "markdown": "># Foo\n>bar\n> baz\n", "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", "example": 229, "start_line": 3719, "end_line": 3729, "section": "Block quotes" }, { "markdown": " > # Foo\n > bar\n > baz\n", "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", "example": 230, "start_line": 3734, "end_line": 3744, "section": "Block quotes" }, { "markdown": " > # Foo\n > bar\n > baz\n", "html": "<pre><code>> # Foo\n> bar\n> baz\n</code></pre>\n", "example": 231, "start_line": 3749, "end_line": 3758, "section": "Block quotes" }, { "markdown": "> # Foo\n> bar\nbaz\n", "html": "<blockquote>\n<h1>Foo</h1>\n<p>bar\nbaz</p>\n</blockquote>\n", "example": 232, "start_line": 3764, "end_line": 3774, "section": "Block quotes" }, { "markdown": "> bar\nbaz\n> foo\n", "html": "<blockquote>\n<p>bar\nbaz\nfoo</p>\n</blockquote>\n", "example": 233, "start_line": 3780, "end_line": 3790, "section": "Block quotes" }, { "markdown": "> foo\n---\n", "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<hr />\n", "example": 234, "start_line": 3804, "end_line": 3812, "section": "Block quotes" }, { "markdown": "> - foo\n- bar\n", "html": "<blockquote>\n<ul>\n<li>foo</li>\n</ul>\n</blockquote>\n<ul>\n<li>bar</li>\n</ul>\n", "example": 235, "start_line": 3824, "end_line": 3836, "section": "Block quotes" }, { "markdown": "> foo\n bar\n", "html": "<blockquote>\n<pre><code>foo\n</code></pre>\n</blockquote>\n<pre><code>bar\n</code></pre>\n", "example": 236, "start_line": 3842, "end_line": 3852, "section": "Block quotes" }, { "markdown": "> ```\nfoo\n```\n", "html": "<blockquote>\n<pre><code></code></pre>\n</blockquote>\n<p>foo</p>\n<pre><code></code></pre>\n", "example": 237, "start_line": 3855, "end_line": 3865, "section": "Block quotes" }, { "markdown": "> foo\n - bar\n", "html": "<blockquote>\n<p>foo\n- bar</p>\n</blockquote>\n", "example": 238, "start_line": 3871, "end_line": 3879, "section": "Block quotes" }, { "markdown": ">\n", "html": "<blockquote>\n</blockquote>\n", "example": 239, "start_line": 3895, "end_line": 3900, "section": "Block quotes" }, { "markdown": ">\n> \n> \n", "html": "<blockquote>\n</blockquote>\n", "example": 240, "start_line": 3903, "end_line": 3910, "section": "Block quotes" }, { "markdown": ">\n> foo\n> \n", "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n", "example": 241, "start_line": 3915, "end_line": 3923, "section": "Block quotes" }, { "markdown": "> foo\n\n> bar\n", "html": "<blockquote>\n<p>foo</p>\n</blockquote>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", "example": 242, "start_line": 3928, "end_line": 3939, "section": "Block quotes" }, { "markdown": "> foo\n> bar\n", "html": "<blockquote>\n<p>foo\nbar</p>\n</blockquote>\n", "example": 243, "start_line": 3950, "end_line": 3958, "section": "Block quotes" }, { "markdown": "> foo\n>\n> bar\n", "html": "<blockquote>\n<p>foo</p>\n<p>bar</p>\n</blockquote>\n", "example": 244, "start_line": 3963, "end_line": 3972, "section": "Block quotes" }, { "markdown": "foo\n> bar\n", "html": "<p>foo</p>\n<blockquote>\n<p>bar</p>\n</blockquote>\n", "example": 245, "start_line": 3977, "end_line": 3985, "section": "Block quotes" }, { "markdown": "> aaa\n***\n> bbb\n", "html": "<blockquote>\n<p>aaa</p>\n</blockquote>\n<hr />\n<blockquote>\n<p>bbb</p>\n</blockquote>\n", "example": 246, "start_line": 3991, "end_line": 4003, "section": "Block quotes" }, { "markdown": "> bar\nbaz\n", "html": "<blockquote>\n<p>bar\nbaz</p>\n</blockquote>\n", "example": 247, "start_line": 4009, "end_line": 4017, "section": "Block quotes" }, { "markdown": "> bar\n\nbaz\n", "html": "<blockquote>\n<p>bar</p>\n</blockquote>\n<p>baz</p>\n", "example": 248, "start_line": 4020, "end_line": 4029, "section": "Block quotes" }, { "markdown": "> bar\n>\nbaz\n", "html": "<blockquote>\n<p>bar</p>\n</blockquote>\n<p>baz</p>\n", "example": 249, "start_line": 4032, "end_line": 4041, "section": "Block quotes" }, { "markdown": "> > > foo\nbar\n", "html": "<blockquote>\n<blockquote>\n<blockquote>\n<p>foo\nbar</p>\n</blockquote>\n</blockquote>\n</blockquote>\n", "example": 250, "start_line": 4048, "end_line": 4060, "section": "Block quotes" }, { "markdown": ">>> foo\n> bar\n>>baz\n", "html": "<blockquote>\n<blockquote>\n<blockquote>\n<p>foo\nbar\nbaz</p>\n</blockquote>\n</blockquote>\n</blockquote>\n", "example": 251, "start_line": 4063, "end_line": 4077, "section": "Block quotes" }, { "markdown": "> code\n\n> not code\n", "html": "<blockquote>\n<pre><code>code\n</code></pre>\n</blockquote>\n<blockquote>\n<p>not code</p>\n</blockquote>\n", "example": 252, "start_line": 4085, "end_line": 4097, "section": "Block quotes" }, { "markdown": "A paragraph\nwith two lines.\n\n indented code\n\n> A block quote.\n", "html": "<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n", "example": 253, "start_line": 4139, "end_line": 4154, "section": "List items" }, { "markdown": "1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", "example": 254, "start_line": 4161, "end_line": 4180, "section": "List items" }, { "markdown": "- one\n\n two\n", "html": "<ul>\n<li>one</li>\n</ul>\n<p>two</p>\n", "example": 255, "start_line": 4194, "end_line": 4203, "section": "List items" }, { "markdown": "- one\n\n two\n", "html": "<ul>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ul>\n", "example": 256, "start_line": 4206, "end_line": 4217, "section": "List items" }, { "markdown": " - one\n\n two\n", "html": "<ul>\n<li>one</li>\n</ul>\n<pre><code> two\n</code></pre>\n", "example": 257, "start_line": 4220, "end_line": 4230, "section": "List items" }, { "markdown": " - one\n\n two\n", "html": "<ul>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ul>\n", "example": 258, "start_line": 4233, "end_line": 4244, "section": "List items" }, { "markdown": " > > 1. one\n>>\n>> two\n", "html": "<blockquote>\n<blockquote>\n<ol>\n<li>\n<p>one</p>\n<p>two</p>\n</li>\n</ol>\n</blockquote>\n</blockquote>\n", "example": 259, "start_line": 4255, "end_line": 4270, "section": "List items" }, { "markdown": ">>- one\n>>\n > > two\n", "html": "<blockquote>\n<blockquote>\n<ul>\n<li>one</li>\n</ul>\n<p>two</p>\n</blockquote>\n</blockquote>\n", "example": 260, "start_line": 4282, "end_line": 4295, "section": "List items" }, { "markdown": "-one\n\n2.two\n", "html": "<p>-one</p>\n<p>2.two</p>\n", "example": 261, "start_line": 4301, "end_line": 4308, "section": "List items" }, { "markdown": "- foo\n\n\n bar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", "example": 262, "start_line": 4314, "end_line": 4326, "section": "List items" }, { "markdown": "1. foo\n\n ```\n bar\n ```\n\n baz\n\n > bam\n", "html": "<ol>\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n<p>baz</p>\n<blockquote>\n<p>bam</p>\n</blockquote>\n</li>\n</ol>\n", "example": 263, "start_line": 4331, "end_line": 4353, "section": "List items" }, { "markdown": "- Foo\n\n bar\n\n\n baz\n", "html": "<ul>\n<li>\n<p>Foo</p>\n<pre><code>bar\n\n\nbaz\n</code></pre>\n</li>\n</ul>\n", "example": 264, "start_line": 4359, "end_line": 4377, "section": "List items" }, { "markdown": "123456789. ok\n", "html": "<ol start=\"123456789\">\n<li>ok</li>\n</ol>\n", "example": 265, "start_line": 4381, "end_line": 4387, "section": "List items" }, { "markdown": "1234567890. not ok\n", "html": "<p>1234567890. not ok</p>\n", "example": 266, "start_line": 4390, "end_line": 4394, "section": "List items" }, { "markdown": "0. ok\n", "html": "<ol start=\"0\">\n<li>ok</li>\n</ol>\n", "example": 267, "start_line": 4399, "end_line": 4405, "section": "List items" }, { "markdown": "003. ok\n", "html": "<ol start=\"3\">\n<li>ok</li>\n</ol>\n", "example": 268, "start_line": 4408, "end_line": 4414, "section": "List items" }, { "markdown": "-1. not ok\n", "html": "<p>-1. not ok</p>\n", "example": 269, "start_line": 4419, "end_line": 4423, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n</li>\n</ul>\n", "example": 270, "start_line": 4442, "end_line": 4454, "section": "List items" }, { "markdown": " 10. foo\n\n bar\n", "html": "<ol start=\"10\">\n<li>\n<p>foo</p>\n<pre><code>bar\n</code></pre>\n</li>\n</ol>\n", "example": 271, "start_line": 4459, "end_line": 4471, "section": "List items" }, { "markdown": " indented code\n\nparagraph\n\n more code\n", "html": "<pre><code>indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n", "example": 272, "start_line": 4478, "end_line": 4490, "section": "List items" }, { "markdown": "1. indented code\n\n paragraph\n\n more code\n", "html": "<ol>\n<li>\n<pre><code>indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n</li>\n</ol>\n", "example": 273, "start_line": 4493, "end_line": 4509, "section": "List items" }, { "markdown": "1. indented code\n\n paragraph\n\n more code\n", "html": "<ol>\n<li>\n<pre><code> indented code\n</code></pre>\n<p>paragraph</p>\n<pre><code>more code\n</code></pre>\n</li>\n</ol>\n", "example": 274, "start_line": 4515, "end_line": 4531, "section": "List items" }, { "markdown": " foo\n\nbar\n", "html": "<p>foo</p>\n<p>bar</p>\n", "example": 275, "start_line": 4542, "end_line": 4549, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "<ul>\n<li>foo</li>\n</ul>\n<p>bar</p>\n", "example": 276, "start_line": 4552, "end_line": 4561, "section": "List items" }, { "markdown": "- foo\n\n bar\n", "html": "<ul>\n<li>\n<p>foo</p>\n<p>bar</p>\n</li>\n</ul>\n", "example": 277, "start_line": 4569, "end_line": 4580, "section": "List items" }, { "markdown": "-\n foo\n-\n ```\n bar\n ```\n-\n baz\n", "html": "<ul>\n<li>foo</li>\n<li>\n<pre><code>bar\n</code></pre>\n</li>\n<li>\n<pre><code>baz\n</code></pre>\n</li>\n</ul>\n", "example": 278, "start_line": 4596, "end_line": 4617, "section": "List items" }, { "markdown": "- \n foo\n", "html": "<ul>\n<li>foo</li>\n</ul>\n", "example": 279, "start_line": 4622, "end_line": 4629, "section": "List items" }, { "markdown": "-\n\n foo\n", "html": "<ul>\n<li></li>\n</ul>\n<p>foo</p>\n", "example": 280, "start_line": 4636, "end_line": 4645, "section": "List items" }, { "markdown": "- foo\n-\n- bar\n", "html": "<ul>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ul>\n", "example": 281, "start_line": 4650, "end_line": 4660, "section": "List items" }, { "markdown": "- foo\n- \n- bar\n", "html": "<ul>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ul>\n", "example": 282, "start_line": 4665, "end_line": 4675, "section": "List items" }, { "markdown": "1. foo\n2.\n3. bar\n", "html": "<ol>\n<li>foo</li>\n<li></li>\n<li>bar</li>\n</ol>\n", "example": 283, "start_line": 4680, "end_line": 4690, "section": "List items" }, { "markdown": "*\n", "html": "<ul>\n<li></li>\n</ul>\n", "example": 284, "start_line": 4695, "end_line": 4701, "section": "List items" }, { "markdown": "foo\n*\n\nfoo\n1.\n", "html": "<p>foo\n*</p>\n<p>foo\n1.</p>\n", "example": 285, "start_line": 4705, "end_line": 4716, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", "example": 286, "start_line": 4727, "end_line": 4746, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", "example": 287, "start_line": 4751, "end_line": 4770, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", "example": 288, "start_line": 4775, "end_line": 4794, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n", "html": "<pre><code>1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n</code></pre>\n", "example": 289, "start_line": 4799, "end_line": 4814, "section": "List items" }, { "markdown": " 1. A paragraph\nwith two lines.\n\n indented code\n\n > A block quote.\n", "html": "<ol>\n<li>\n<p>A paragraph\nwith two lines.</p>\n<pre><code>indented code\n</code></pre>\n<blockquote>\n<p>A block quote.</p>\n</blockquote>\n</li>\n</ol>\n", "example": 290, "start_line": 4829, "end_line": 4848, "section": "List items" }, { "markdown": " 1. A paragraph\n with two lines.\n", "html": "<ol>\n<li>A paragraph\nwith two lines.</li>\n</ol>\n", "example": 291, "start_line": 4853, "end_line": 4861, "section": "List items" }, { "markdown": "> 1. > Blockquote\ncontinued here.\n", "html": "<blockquote>\n<ol>\n<li>\n<blockquote>\n<p>Blockquote\ncontinued here.</p>\n</blockquote>\n</li>\n</ol>\n</blockquote>\n", "example": 292, "start_line": 4866, "end_line": 4880, "section": "List items" }, { "markdown": "> 1. > Blockquote\n> continued here.\n", "html": "<blockquote>\n<ol>\n<li>\n<blockquote>\n<p>Blockquote\ncontinued here.</p>\n</blockquote>\n</li>\n</ol>\n</blockquote>\n", "example": 293, "start_line": 4883, "end_line": 4897, "section": "List items" }, { "markdown": "- foo\n - bar\n - baz\n - boo\n", "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>baz\n<ul>\n<li>boo</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", "example": 294, "start_line": 4911, "end_line": 4932, "section": "List items" }, { "markdown": "- foo\n - bar\n - baz\n - boo\n", "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n<li>baz</li>\n<li>boo</li>\n</ul>\n", "example": 295, "start_line": 4937, "end_line": 4949, "section": "List items" }, { "markdown": "10) foo\n - bar\n", "html": "<ol start=\"10\">\n<li>foo\n<ul>\n<li>bar</li>\n</ul>\n</li>\n</ol>\n", "example": 296, "start_line": 4954, "end_line": 4965, "section": "List items" }, { "markdown": "10) foo\n - bar\n", "html": "<ol start=\"10\">\n<li>foo</li>\n</ol>\n<ul>\n<li>bar</li>\n</ul>\n", "example": 297, "start_line": 4970, "end_line": 4980, "section": "List items" }, { "markdown": "- - foo\n", "html": "<ul>\n<li>\n<ul>\n<li>foo</li>\n</ul>\n</li>\n</ul>\n", "example": 298, "start_line": 4985, "end_line": 4995, "section": "List items" }, { "markdown": "1. - 2. foo\n", "html": "<ol>\n<li>\n<ul>\n<li>\n<ol start=\"2\">\n<li>foo</li>\n</ol>\n</li>\n</ul>\n</li>\n</ol>\n", "example": 299, "start_line": 4998, "end_line": 5012, "section": "List items" }, { "markdown": "- # Foo\n- Bar\n ---\n baz\n", "html": "<ul>\n<li>\n<h1>Foo</h1>\n</li>\n<li>\n<h2>Bar</h2>\nbaz</li>\n</ul>\n", "example": 300, "start_line": 5017, "end_line": 5031, "section": "List items" }, { "markdown": "- foo\n- bar\n+ baz\n", "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<ul>\n<li>baz</li>\n</ul>\n", "example": 301, "start_line": 5253, "end_line": 5265, "section": "Lists" }, { "markdown": "1. foo\n2. bar\n3) baz\n", "html": "<ol>\n<li>foo</li>\n<li>bar</li>\n</ol>\n<ol start=\"3\">\n<li>baz</li>\n</ol>\n", "example": 302, "start_line": 5268, "end_line": 5280, "section": "Lists" }, { "markdown": "Foo\n- bar\n- baz\n", "html": "<p>Foo</p>\n<ul>\n<li>bar</li>\n<li>baz</li>\n</ul>\n", "example": 303, "start_line": 5287, "end_line": 5297, "section": "Lists" }, { "markdown": "The number of windows in my house is\n14. The number of doors is 6.\n", "html": "<p>The number of windows in my house is\n14. The number of doors is 6.</p>\n", "example": 304, "start_line": 5364, "end_line": 5370, "section": "Lists" }, { "markdown": "The number of windows in my house is\n1. The number of doors is 6.\n", "html": "<p>The number of windows in my house is</p>\n<ol>\n<li>The number of doors is 6.</li>\n</ol>\n", "example": 305, "start_line": 5374, "end_line": 5382, "section": "Lists" }, { "markdown": "- foo\n\n- bar\n\n\n- baz\n", "html": "<ul>\n<li>\n<p>foo</p>\n</li>\n<li>\n<p>bar</p>\n</li>\n<li>\n<p>baz</p>\n</li>\n</ul>\n", "example": 306, "start_line": 5388, "end_line": 5407, "section": "Lists" }, { "markdown": "- foo\n - bar\n - baz\n\n\n bim\n", "html": "<ul>\n<li>foo\n<ul>\n<li>bar\n<ul>\n<li>\n<p>baz</p>\n<p>bim</p>\n</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n", "example": 307, "start_line": 5409, "end_line": 5431, "section": "Lists" }, { "markdown": "- foo\n- bar\n\n<!-- -->\n\n- baz\n- bim\n", "html": "<ul>\n<li>foo</li>\n<li>bar</li>\n</ul>\n<!-- -->\n<ul>\n<li>baz</li>\n<li>bim</li>\n</ul>\n", "example": 308, "start_line": 5439, "end_line": 5457, "section": "Lists" }, { "markdown": "- foo\n\n notcode\n\n- foo\n\n<!-- -->\n\n code\n", "html": "<ul>\n<li>\n<p>foo</p>\n<p>notcode</p>\n</li>\n<li>\n<p>foo</p>\n</li>\n</ul>\n<!-- -->\n<pre><code>code\n</code></pre>\n", "example": 309, "start_line": 5460, "end_line": 5483, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n - d\n - e\n - f\n- g\n", "html": "<ul>\n<li>a</li>\n<li>b</li>\n<li>c</li>\n<li>d</li>\n<li>e</li>\n<li>f</li>\n<li>g</li>\n</ul>\n", "example": 310, "start_line": 5491, "end_line": 5509, "section": "Lists" }, { "markdown": "1. a\n\n 2. b\n\n 3. c\n", "html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ol>\n", "example": 311, "start_line": 5512, "end_line": 5530, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n - d\n - e\n", "html": "<ul>\n<li>a</li>\n<li>b</li>\n<li>c</li>\n<li>d\n- e</li>\n</ul>\n", "example": 312, "start_line": 5536, "end_line": 5550, "section": "Lists" }, { "markdown": "1. a\n\n 2. b\n\n 3. c\n", "html": "<ol>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n</ol>\n<pre><code>3. c\n</code></pre>\n", "example": 313, "start_line": 5556, "end_line": 5573, "section": "Lists" }, { "markdown": "- a\n- b\n\n- c\n", "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>c</p>\n</li>\n</ul>\n", "example": 314, "start_line": 5579, "end_line": 5596, "section": "Lists" }, { "markdown": "* a\n*\n\n* c\n", "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li></li>\n<li>\n<p>c</p>\n</li>\n</ul>\n", "example": 315, "start_line": 5601, "end_line": 5616, "section": "Lists" }, { "markdown": "- a\n- b\n\n c\n- d\n", "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n<p>c</p>\n</li>\n<li>\n<p>d</p>\n</li>\n</ul>\n", "example": 316, "start_line": 5623, "end_line": 5642, "section": "Lists" }, { "markdown": "- a\n- b\n\n [ref]: /url\n- d\n", "html": "<ul>\n<li>\n<p>a</p>\n</li>\n<li>\n<p>b</p>\n</li>\n<li>\n<p>d</p>\n</li>\n</ul>\n", "example": 317, "start_line": 5645, "end_line": 5663, "section": "Lists" }, { "markdown": "- a\n- ```\n b\n\n\n ```\n- c\n", "html": "<ul>\n<li>a</li>\n<li>\n<pre><code>b\n\n\n</code></pre>\n</li>\n<li>c</li>\n</ul>\n", "example": 318, "start_line": 5668, "end_line": 5687, "section": "Lists" }, { "markdown": "- a\n - b\n\n c\n- d\n", "html": "<ul>\n<li>a\n<ul>\n<li>\n<p>b</p>\n<p>c</p>\n</li>\n</ul>\n</li>\n<li>d</li>\n</ul>\n", "example": 319, "start_line": 5694, "end_line": 5712, "section": "Lists" }, { "markdown": "* a\n > b\n >\n* c\n", "html": "<ul>\n<li>a\n<blockquote>\n<p>b</p>\n</blockquote>\n</li>\n<li>c</li>\n</ul>\n", "example": 320, "start_line": 5718, "end_line": 5732, "section": "Lists" }, { "markdown": "- a\n > b\n ```\n c\n ```\n- d\n", "html": "<ul>\n<li>a\n<blockquote>\n<p>b</p>\n</blockquote>\n<pre><code>c\n</code></pre>\n</li>\n<li>d</li>\n</ul>\n", "example": 321, "start_line": 5738, "end_line": 5756, "section": "Lists" }, { "markdown": "- a\n", "html": "<ul>\n<li>a</li>\n</ul>\n", "example": 322, "start_line": 5761, "end_line": 5767, "section": "Lists" }, { "markdown": "- a\n - b\n", "html": "<ul>\n<li>a\n<ul>\n<li>b</li>\n</ul>\n</li>\n</ul>\n", "example": 323, "start_line": 5770, "end_line": 5781, "section": "Lists" }, { "markdown": "1. ```\n foo\n ```\n\n bar\n", "html": "<ol>\n<li>\n<pre><code>foo\n</code></pre>\n<p>bar</p>\n</li>\n</ol>\n", "example": 324, "start_line": 5787, "end_line": 5801, "section": "Lists" }, { "markdown": "* foo\n * bar\n\n baz\n", "html": "<ul>\n<li>\n<p>foo</p>\n<ul>\n<li>bar</li>\n</ul>\n<p>baz</p>\n</li>\n</ul>\n", "example": 325, "start_line": 5806, "end_line": 5821, "section": "Lists" }, { "markdown": "- a\n - b\n - c\n\n- d\n - e\n - f\n", "html": "<ul>\n<li>\n<p>a</p>\n<ul>\n<li>b</li>\n<li>c</li>\n</ul>\n</li>\n<li>\n<p>d</p>\n<ul>\n<li>e</li>\n<li>f</li>\n</ul>\n</li>\n</ul>\n", "example": 326, "start_line": 5824, "end_line": 5849, "section": "Lists" }, { "markdown": "`hi`lo`\n", "html": "<p><code>hi</code>lo`</p>\n", "example": 327, "start_line": 5858, "end_line": 5862, "section": "Inlines" }, { "markdown": "`foo`\n", "html": "<p><code>foo</code></p>\n", "example": 328, "start_line": 5890, "end_line": 5894, "section": "Code spans" }, { "markdown": "`` foo ` bar ``\n", "html": "<p><code>foo ` bar</code></p>\n", "example": 329, "start_line": 5901, "end_line": 5905, "section": "Code spans" }, { "markdown": "` `` `\n", "html": "<p><code>``</code></p>\n", "example": 330, "start_line": 5911, "end_line": 5915, "section": "Code spans" }, { "markdown": "` `` `\n", "html": "<p><code> `` </code></p>\n", "example": 331, "start_line": 5919, "end_line": 5923, "section": "Code spans" }, { "markdown": "` a`\n", "html": "<p><code> a</code></p>\n", "example": 332, "start_line": 5928, "end_line": 5932, "section": "Code spans" }, { "markdown": "` b `\n", "html": "<p><code> b </code></p>\n", "example": 333, "start_line": 5937, "end_line": 5941, "section": "Code spans" }, { "markdown": "` `\n` `\n", "html": "<p><code> </code>\n<code> </code></p>\n", "example": 334, "start_line": 5945, "end_line": 5951, "section": "Code spans" }, { "markdown": "``\nfoo\nbar \nbaz\n``\n", "html": "<p><code>foo bar baz</code></p>\n", "example": 335, "start_line": 5956, "end_line": 5964, "section": "Code spans" }, { "markdown": "``\nfoo \n``\n", "html": "<p><code>foo </code></p>\n", "example": 336, "start_line": 5966, "end_line": 5972, "section": "Code spans" }, { "markdown": "`foo bar \nbaz`\n", "html": "<p><code>foo bar baz</code></p>\n", "example": 337, "start_line": 5977, "end_line": 5982, "section": "Code spans" }, { "markdown": "`foo\\`bar`\n", "html": "<p><code>foo\\</code>bar`</p>\n", "example": 338, "start_line": 5994, "end_line": 5998, "section": "Code spans" }, { "markdown": "``foo`bar``\n", "html": "<p><code>foo`bar</code></p>\n", "example": 339, "start_line": 6005, "end_line": 6009, "section": "Code spans" }, { "markdown": "` foo `` bar `\n", "html": "<p><code>foo `` bar</code></p>\n", "example": 340, "start_line": 6011, "end_line": 6015, "section": "Code spans" }, { "markdown": "*foo`*`\n", "html": "<p>*foo<code>*</code></p>\n", "example": 341, "start_line": 6023, "end_line": 6027, "section": "Code spans" }, { "markdown": "[not a `link](/foo`)\n", "html": "<p>[not a <code>link](/foo</code>)</p>\n", "example": 342, "start_line": 6032, "end_line": 6036, "section": "Code spans" }, { "markdown": "`<a href=\"`\">`\n", "html": "<p><code><a href="</code>">`</p>\n", "example": 343, "start_line": 6042, "end_line": 6046, "section": "Code spans" }, { "markdown": "<a href=\"`\">`\n", "html": "<p><a href=\"`\">`</p>\n", "example": 344, "start_line": 6051, "end_line": 6055, "section": "Code spans" }, { "markdown": "`<http://foo.bar.`baz>`\n", "html": "<p><code><http://foo.bar.</code>baz>`</p>\n", "example": 345, "start_line": 6060, "end_line": 6064, "section": "Code spans" }, { "markdown": "<http://foo.bar.`baz>`\n", "html": "<p><a href=\"http://foo.bar.%60baz\">http://foo.bar.`baz</a>`</p>\n", "example": 346, "start_line": 6069, "end_line": 6073, "section": "Code spans" }, { "markdown": "```foo``\n", "html": "<p>```foo``</p>\n", "example": 347, "start_line": 6079, "end_line": 6083, "section": "Code spans" }, { "markdown": "`foo\n", "html": "<p>`foo</p>\n", "example": 348, "start_line": 6086, "end_line": 6090, "section": "Code spans" }, { "markdown": "`foo``bar``\n", "html": "<p>`foo<code>bar</code></p>\n", "example": 349, "start_line": 6095, "end_line": 6099, "section": "Code spans" }, { "markdown": "*foo bar*\n", "html": "<p><em>foo bar</em></p>\n", "example": 350, "start_line": 6312, "end_line": 6316, "section": "Emphasis and strong emphasis" }, { "markdown": "a * foo bar*\n", "html": "<p>a * foo bar*</p>\n", "example": 351, "start_line": 6322, "end_line": 6326, "section": "Emphasis and strong emphasis" }, { "markdown": "a*\"foo\"*\n", "html": "<p>a*"foo"*</p>\n", "example": 352, "start_line": 6333, "end_line": 6337, "section": "Emphasis and strong emphasis" }, { "markdown": "* a *\n", "html": "<p>* a *</p>\n", "example": 353, "start_line": 6342, "end_line": 6346, "section": "Emphasis and strong emphasis" }, { "markdown": "foo*bar*\n", "html": "<p>foo<em>bar</em></p>\n", "example": 354, "start_line": 6351, "end_line": 6355, "section": "Emphasis and strong emphasis" }, { "markdown": "5*6*78\n", "html": "<p>5<em>6</em>78</p>\n", "example": 355, "start_line": 6358, "end_line": 6362, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo bar_\n", "html": "<p><em>foo bar</em></p>\n", "example": 356, "start_line": 6367, "end_line": 6371, "section": "Emphasis and strong emphasis" }, { "markdown": "_ foo bar_\n", "html": "<p>_ foo bar_</p>\n", "example": 357, "start_line": 6377, "end_line": 6381, "section": "Emphasis and strong emphasis" }, { "markdown": "a_\"foo\"_\n", "html": "<p>a_"foo"_</p>\n", "example": 358, "start_line": 6387, "end_line": 6391, "section": "Emphasis and strong emphasis" }, { "markdown": "foo_bar_\n", "html": "<p>foo_bar_</p>\n", "example": 359, "start_line": 6396, "end_line": 6400, "section": "Emphasis and strong emphasis" }, { "markdown": "5_6_78\n", "html": "<p>5_6_78</p>\n", "example": 360, "start_line": 6403, "end_line": 6407, "section": "Emphasis and strong emphasis" }, { "markdown": "пристаням_стремятся_\n", "html": "<p>пристаням_стремятся_</p>\n", "example": 361, "start_line": 6410, "end_line": 6414, "section": "Emphasis and strong emphasis" }, { "markdown": "aa_\"bb\"_cc\n", "html": "<p>aa_"bb"_cc</p>\n", "example": 362, "start_line": 6420, "end_line": 6424, "section": "Emphasis and strong emphasis" }, { "markdown": "foo-_(bar)_\n", "html": "<p>foo-<em>(bar)</em></p>\n", "example": 363, "start_line": 6431, "end_line": 6435, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo*\n", "html": "<p>_foo*</p>\n", "example": 364, "start_line": 6443, "end_line": 6447, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo bar *\n", "html": "<p>*foo bar *</p>\n", "example": 365, "start_line": 6453, "end_line": 6457, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo bar\n*\n", "html": "<p>*foo bar\n*</p>\n", "example": 366, "start_line": 6462, "end_line": 6468, "section": "Emphasis and strong emphasis" }, { "markdown": "*(*foo)\n", "html": "<p>*(*foo)</p>\n", "example": 367, "start_line": 6475, "end_line": 6479, "section": "Emphasis and strong emphasis" }, { "markdown": "*(*foo*)*\n", "html": "<p><em>(<em>foo</em>)</em></p>\n", "example": 368, "start_line": 6485, "end_line": 6489, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo*bar\n", "html": "<p><em>foo</em>bar</p>\n", "example": 369, "start_line": 6494, "end_line": 6498, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo bar _\n", "html": "<p>_foo bar _</p>\n", "example": 370, "start_line": 6507, "end_line": 6511, "section": "Emphasis and strong emphasis" }, { "markdown": "_(_foo)\n", "html": "<p>_(_foo)</p>\n", "example": 371, "start_line": 6517, "end_line": 6521, "section": "Emphasis and strong emphasis" }, { "markdown": "_(_foo_)_\n", "html": "<p><em>(<em>foo</em>)</em></p>\n", "example": 372, "start_line": 6526, "end_line": 6530, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo_bar\n", "html": "<p>_foo_bar</p>\n", "example": 373, "start_line": 6535, "end_line": 6539, "section": "Emphasis and strong emphasis" }, { "markdown": "_пристаням_стремятся\n", "html": "<p>_пристаням_стремятся</p>\n", "example": 374, "start_line": 6542, "end_line": 6546, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo_bar_baz_\n", "html": "<p><em>foo_bar_baz</em></p>\n", "example": 375, "start_line": 6549, "end_line": 6553, "section": "Emphasis and strong emphasis" }, { "markdown": "_(bar)_.\n", "html": "<p><em>(bar)</em>.</p>\n", "example": 376, "start_line": 6560, "end_line": 6564, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo bar**\n", "html": "<p><strong>foo bar</strong></p>\n", "example": 377, "start_line": 6569, "end_line": 6573, "section": "Emphasis and strong emphasis" }, { "markdown": "** foo bar**\n", "html": "<p>** foo bar**</p>\n", "example": 378, "start_line": 6579, "end_line": 6583, "section": "Emphasis and strong emphasis" }, { "markdown": "a**\"foo\"**\n", "html": "<p>a**"foo"**</p>\n", "example": 379, "start_line": 6590, "end_line": 6594, "section": "Emphasis and strong emphasis" }, { "markdown": "foo**bar**\n", "html": "<p>foo<strong>bar</strong></p>\n", "example": 380, "start_line": 6599, "end_line": 6603, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo bar__\n", "html": "<p><strong>foo bar</strong></p>\n", "example": 381, "start_line": 6608, "end_line": 6612, "section": "Emphasis and strong emphasis" }, { "markdown": "__ foo bar__\n", "html": "<p>__ foo bar__</p>\n", "example": 382, "start_line": 6618, "end_line": 6622, "section": "Emphasis and strong emphasis" }, { "markdown": "__\nfoo bar__\n", "html": "<p>__\nfoo bar__</p>\n", "example": 383, "start_line": 6626, "end_line": 6632, "section": "Emphasis and strong emphasis" }, { "markdown": "a__\"foo\"__\n", "html": "<p>a__"foo"__</p>\n", "example": 384, "start_line": 6638, "end_line": 6642, "section": "Emphasis and strong emphasis" }, { "markdown": "foo__bar__\n", "html": "<p>foo__bar__</p>\n", "example": 385, "start_line": 6647, "end_line": 6651, "section": "Emphasis and strong emphasis" }, { "markdown": "5__6__78\n", "html": "<p>5__6__78</p>\n", "example": 386, "start_line": 6654, "end_line": 6658, "section": "Emphasis and strong emphasis" }, { "markdown": "пристаням__стремятся__\n", "html": "<p>пристаням__стремятся__</p>\n", "example": 387, "start_line": 6661, "end_line": 6665, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo, __bar__, baz__\n", "html": "<p><strong>foo, <strong>bar</strong>, baz</strong></p>\n", "example": 388, "start_line": 6668, "end_line": 6672, "section": "Emphasis and strong emphasis" }, { "markdown": "foo-__(bar)__\n", "html": "<p>foo-<strong>(bar)</strong></p>\n", "example": 389, "start_line": 6679, "end_line": 6683, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo bar **\n", "html": "<p>**foo bar **</p>\n", "example": 390, "start_line": 6692, "end_line": 6696, "section": "Emphasis and strong emphasis" }, { "markdown": "**(**foo)\n", "html": "<p>**(**foo)</p>\n", "example": 391, "start_line": 6705, "end_line": 6709, "section": "Emphasis and strong emphasis" }, { "markdown": "*(**foo**)*\n", "html": "<p><em>(<strong>foo</strong>)</em></p>\n", "example": 392, "start_line": 6715, "end_line": 6719, "section": "Emphasis and strong emphasis" }, { "markdown": "**Gomphocarpus (*Gomphocarpus physocarpus*, syn.\n*Asclepias physocarpa*)**\n", "html": "<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.\n<em>Asclepias physocarpa</em>)</strong></p>\n", "example": 393, "start_line": 6722, "end_line": 6728, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo \"*bar*\" foo**\n", "html": "<p><strong>foo "<em>bar</em>" foo</strong></p>\n", "example": 394, "start_line": 6731, "end_line": 6735, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo**bar\n", "html": "<p><strong>foo</strong>bar</p>\n", "example": 395, "start_line": 6740, "end_line": 6744, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo bar __\n", "html": "<p>__foo bar __</p>\n", "example": 396, "start_line": 6752, "end_line": 6756, "section": "Emphasis and strong emphasis" }, { "markdown": "__(__foo)\n", "html": "<p>__(__foo)</p>\n", "example": 397, "start_line": 6762, "end_line": 6766, "section": "Emphasis and strong emphasis" }, { "markdown": "_(__foo__)_\n", "html": "<p><em>(<strong>foo</strong>)</em></p>\n", "example": 398, "start_line": 6772, "end_line": 6776, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__bar\n", "html": "<p>__foo__bar</p>\n", "example": 399, "start_line": 6781, "end_line": 6785, "section": "Emphasis and strong emphasis" }, { "markdown": "__пристаням__стремятся\n", "html": "<p>__пристаням__стремятся</p>\n", "example": 400, "start_line": 6788, "end_line": 6792, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__bar__baz__\n", "html": "<p><strong>foo__bar__baz</strong></p>\n", "example": 401, "start_line": 6795, "end_line": 6799, "section": "Emphasis and strong emphasis" }, { "markdown": "__(bar)__.\n", "html": "<p><strong>(bar)</strong>.</p>\n", "example": 402, "start_line": 6806, "end_line": 6810, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo [bar](/url)*\n", "html": "<p><em>foo <a href=\"/url\">bar</a></em></p>\n", "example": 403, "start_line": 6818, "end_line": 6822, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo\nbar*\n", "html": "<p><em>foo\nbar</em></p>\n", "example": 404, "start_line": 6825, "end_line": 6831, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo __bar__ baz_\n", "html": "<p><em>foo <strong>bar</strong> baz</em></p>\n", "example": 405, "start_line": 6837, "end_line": 6841, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo _bar_ baz_\n", "html": "<p><em>foo <em>bar</em> baz</em></p>\n", "example": 406, "start_line": 6844, "end_line": 6848, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo_ bar_\n", "html": "<p><em><em>foo</em> bar</em></p>\n", "example": 407, "start_line": 6851, "end_line": 6855, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo *bar**\n", "html": "<p><em>foo <em>bar</em></em></p>\n", "example": 408, "start_line": 6858, "end_line": 6862, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar** baz*\n", "html": "<p><em>foo <strong>bar</strong> baz</em></p>\n", "example": 409, "start_line": 6865, "end_line": 6869, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar**baz*\n", "html": "<p><em>foo<strong>bar</strong>baz</em></p>\n", "example": 410, "start_line": 6871, "end_line": 6875, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar*\n", "html": "<p><em>foo**bar</em></p>\n", "example": 411, "start_line": 6895, "end_line": 6899, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo** bar*\n", "html": "<p><em><strong>foo</strong> bar</em></p>\n", "example": 412, "start_line": 6908, "end_line": 6912, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar***\n", "html": "<p><em>foo <strong>bar</strong></em></p>\n", "example": 413, "start_line": 6915, "end_line": 6919, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**bar***\n", "html": "<p><em>foo<strong>bar</strong></em></p>\n", "example": 414, "start_line": 6922, "end_line": 6926, "section": "Emphasis and strong emphasis" }, { "markdown": "foo***bar***baz\n", "html": "<p>foo<em><strong>bar</strong></em>baz</p>\n", "example": 415, "start_line": 6933, "end_line": 6937, "section": "Emphasis and strong emphasis" }, { "markdown": "foo******bar*********baz\n", "html": "<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>\n", "example": 416, "start_line": 6939, "end_line": 6943, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo **bar *baz* bim** bop*\n", "html": "<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>\n", "example": 417, "start_line": 6948, "end_line": 6952, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo [*bar*](/url)*\n", "html": "<p><em>foo <a href=\"/url\"><em>bar</em></a></em></p>\n", "example": 418, "start_line": 6955, "end_line": 6959, "section": "Emphasis and strong emphasis" }, { "markdown": "** is not an empty emphasis\n", "html": "<p>** is not an empty emphasis</p>\n", "example": 419, "start_line": 6964, "end_line": 6968, "section": "Emphasis and strong emphasis" }, { "markdown": "**** is not an empty strong emphasis\n", "html": "<p>**** is not an empty strong emphasis</p>\n", "example": 420, "start_line": 6971, "end_line": 6975, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo [bar](/url)**\n", "html": "<p><strong>foo <a href=\"/url\">bar</a></strong></p>\n", "example": 421, "start_line": 6984, "end_line": 6988, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo\nbar**\n", "html": "<p><strong>foo\nbar</strong></p>\n", "example": 422, "start_line": 6991, "end_line": 6997, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo _bar_ baz__\n", "html": "<p><strong>foo <em>bar</em> baz</strong></p>\n", "example": 423, "start_line": 7003, "end_line": 7007, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo __bar__ baz__\n", "html": "<p><strong>foo <strong>bar</strong> baz</strong></p>\n", "example": 424, "start_line": 7010, "end_line": 7014, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo__ bar__\n", "html": "<p><strong><strong>foo</strong> bar</strong></p>\n", "example": 425, "start_line": 7017, "end_line": 7021, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo **bar****\n", "html": "<p><strong>foo <strong>bar</strong></strong></p>\n", "example": 426, "start_line": 7024, "end_line": 7028, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar* baz**\n", "html": "<p><strong>foo <em>bar</em> baz</strong></p>\n", "example": 427, "start_line": 7031, "end_line": 7035, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo*bar*baz**\n", "html": "<p><strong>foo<em>bar</em>baz</strong></p>\n", "example": 428, "start_line": 7038, "end_line": 7042, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo* bar**\n", "html": "<p><strong><em>foo</em> bar</strong></p>\n", "example": 429, "start_line": 7045, "end_line": 7049, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar***\n", "html": "<p><strong>foo <em>bar</em></strong></p>\n", "example": 430, "start_line": 7052, "end_line": 7056, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo *bar **baz**\nbim* bop**\n", "html": "<p><strong>foo <em>bar <strong>baz</strong>\nbim</em> bop</strong></p>\n", "example": 431, "start_line": 7061, "end_line": 7067, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo [*bar*](/url)**\n", "html": "<p><strong>foo <a href=\"/url\"><em>bar</em></a></strong></p>\n", "example": 432, "start_line": 7070, "end_line": 7074, "section": "Emphasis and strong emphasis" }, { "markdown": "__ is not an empty emphasis\n", "html": "<p>__ is not an empty emphasis</p>\n", "example": 433, "start_line": 7079, "end_line": 7083, "section": "Emphasis and strong emphasis" }, { "markdown": "____ is not an empty strong emphasis\n", "html": "<p>____ is not an empty strong emphasis</p>\n", "example": 434, "start_line": 7086, "end_line": 7090, "section": "Emphasis and strong emphasis" }, { "markdown": "foo ***\n", "html": "<p>foo ***</p>\n", "example": 435, "start_line": 7096, "end_line": 7100, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *\\**\n", "html": "<p>foo <em>*</em></p>\n", "example": 436, "start_line": 7103, "end_line": 7107, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *_*\n", "html": "<p>foo <em>_</em></p>\n", "example": 437, "start_line": 7110, "end_line": 7114, "section": "Emphasis and strong emphasis" }, { "markdown": "foo *****\n", "html": "<p>foo *****</p>\n", "example": 438, "start_line": 7117, "end_line": 7121, "section": "Emphasis and strong emphasis" }, { "markdown": "foo **\\***\n", "html": "<p>foo <strong>*</strong></p>\n", "example": 439, "start_line": 7124, "end_line": 7128, "section": "Emphasis and strong emphasis" }, { "markdown": "foo **_**\n", "html": "<p>foo <strong>_</strong></p>\n", "example": 440, "start_line": 7131, "end_line": 7135, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo*\n", "html": "<p>*<em>foo</em></p>\n", "example": 441, "start_line": 7142, "end_line": 7146, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo**\n", "html": "<p><em>foo</em>*</p>\n", "example": 442, "start_line": 7149, "end_line": 7153, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo**\n", "html": "<p>*<strong>foo</strong></p>\n", "example": 443, "start_line": 7156, "end_line": 7160, "section": "Emphasis and strong emphasis" }, { "markdown": "****foo*\n", "html": "<p>***<em>foo</em></p>\n", "example": 444, "start_line": 7163, "end_line": 7167, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo***\n", "html": "<p><strong>foo</strong>*</p>\n", "example": 445, "start_line": 7170, "end_line": 7174, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo****\n", "html": "<p><em>foo</em>***</p>\n", "example": 446, "start_line": 7177, "end_line": 7181, "section": "Emphasis and strong emphasis" }, { "markdown": "foo ___\n", "html": "<p>foo ___</p>\n", "example": 447, "start_line": 7187, "end_line": 7191, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _\\__\n", "html": "<p>foo <em>_</em></p>\n", "example": 448, "start_line": 7194, "end_line": 7198, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _*_\n", "html": "<p>foo <em>*</em></p>\n", "example": 449, "start_line": 7201, "end_line": 7205, "section": "Emphasis and strong emphasis" }, { "markdown": "foo _____\n", "html": "<p>foo _____</p>\n", "example": 450, "start_line": 7208, "end_line": 7212, "section": "Emphasis and strong emphasis" }, { "markdown": "foo __\\___\n", "html": "<p>foo <strong>_</strong></p>\n", "example": 451, "start_line": 7215, "end_line": 7219, "section": "Emphasis and strong emphasis" }, { "markdown": "foo __*__\n", "html": "<p>foo <strong>*</strong></p>\n", "example": 452, "start_line": 7222, "end_line": 7226, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo_\n", "html": "<p>_<em>foo</em></p>\n", "example": 453, "start_line": 7229, "end_line": 7233, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo__\n", "html": "<p><em>foo</em>_</p>\n", "example": 454, "start_line": 7240, "end_line": 7244, "section": "Emphasis and strong emphasis" }, { "markdown": "___foo__\n", "html": "<p>_<strong>foo</strong></p>\n", "example": 455, "start_line": 7247, "end_line": 7251, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo_\n", "html": "<p>___<em>foo</em></p>\n", "example": 456, "start_line": 7254, "end_line": 7258, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo___\n", "html": "<p><strong>foo</strong>_</p>\n", "example": 457, "start_line": 7261, "end_line": 7265, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo____\n", "html": "<p><em>foo</em>___</p>\n", "example": 458, "start_line": 7268, "end_line": 7272, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo**\n", "html": "<p><strong>foo</strong></p>\n", "example": 459, "start_line": 7278, "end_line": 7282, "section": "Emphasis and strong emphasis" }, { "markdown": "*_foo_*\n", "html": "<p><em><em>foo</em></em></p>\n", "example": 460, "start_line": 7285, "end_line": 7289, "section": "Emphasis and strong emphasis" }, { "markdown": "__foo__\n", "html": "<p><strong>foo</strong></p>\n", "example": 461, "start_line": 7292, "end_line": 7296, "section": "Emphasis and strong emphasis" }, { "markdown": "_*foo*_\n", "html": "<p><em><em>foo</em></em></p>\n", "example": 462, "start_line": 7299, "end_line": 7303, "section": "Emphasis and strong emphasis" }, { "markdown": "****foo****\n", "html": "<p><strong><strong>foo</strong></strong></p>\n", "example": 463, "start_line": 7309, "end_line": 7313, "section": "Emphasis and strong emphasis" }, { "markdown": "____foo____\n", "html": "<p><strong><strong>foo</strong></strong></p>\n", "example": 464, "start_line": 7316, "end_line": 7320, "section": "Emphasis and strong emphasis" }, { "markdown": "******foo******\n", "html": "<p><strong><strong><strong>foo</strong></strong></strong></p>\n", "example": 465, "start_line": 7327, "end_line": 7331, "section": "Emphasis and strong emphasis" }, { "markdown": "***foo***\n", "html": "<p><em><strong>foo</strong></em></p>\n", "example": 466, "start_line": 7336, "end_line": 7340, "section": "Emphasis and strong emphasis" }, { "markdown": "_____foo_____\n", "html": "<p><em><strong><strong>foo</strong></strong></em></p>\n", "example": 467, "start_line": 7343, "end_line": 7347, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo _bar* baz_\n", "html": "<p><em>foo _bar</em> baz_</p>\n", "example": 468, "start_line": 7352, "end_line": 7356, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo __bar *baz bim__ bam*\n", "html": "<p><em>foo <strong>bar *baz bim</strong> bam</em></p>\n", "example": 469, "start_line": 7359, "end_line": 7363, "section": "Emphasis and strong emphasis" }, { "markdown": "**foo **bar baz**\n", "html": "<p>**foo <strong>bar baz</strong></p>\n", "example": 470, "start_line": 7368, "end_line": 7372, "section": "Emphasis and strong emphasis" }, { "markdown": "*foo *bar baz*\n", "html": "<p>*foo <em>bar baz</em></p>\n", "example": 471, "start_line": 7375, "end_line": 7379, "section": "Emphasis and strong emphasis" }, { "markdown": "*[bar*](/url)\n", "html": "<p>*<a href=\"/url\">bar*</a></p>\n", "example": 472, "start_line": 7384, "end_line": 7388, "section": "Emphasis and strong emphasis" }, { "markdown": "_foo [bar_](/url)\n", "html": "<p>_foo <a href=\"/url\">bar_</a></p>\n", "example": 473, "start_line": 7391, "end_line": 7395, "section": "Emphasis and strong emphasis" }, { "markdown": "*<img src=\"foo\" title=\"*\"/>\n", "html": "<p>*<img src=\"foo\" title=\"*\"/></p>\n", "example": 474, "start_line": 7398, "end_line": 7402, "section": "Emphasis and strong emphasis" }, { "markdown": "**<a href=\"**\">\n", "html": "<p>**<a href=\"**\"></p>\n", "example": 475, "start_line": 7405, "end_line": 7409, "section": "Emphasis and strong emphasis" }, { "markdown": "__<a href=\"__\">\n", "html": "<p>__<a href=\"__\"></p>\n", "example": 476, "start_line": 7412, "end_line": 7416, "section": "Emphasis and strong emphasis" }, { "markdown": "*a `*`*\n", "html": "<p><em>a <code>*</code></em></p>\n", "example": 477, "start_line": 7419, "end_line": 7423, "section": "Emphasis and strong emphasis" }, { "markdown": "_a `_`_\n", "html": "<p><em>a <code>_</code></em></p>\n", "example": 478, "start_line": 7426, "end_line": 7430, "section": "Emphasis and strong emphasis" }, { "markdown": "**a<http://foo.bar/?q=**>\n", "html": "<p>**a<a href=\"http://foo.bar/?q=**\">http://foo.bar/?q=**</a></p>\n", "example": 479, "start_line": 7433, "end_line": 7437, "section": "Emphasis and strong emphasis" }, { "markdown": "__a<http://foo.bar/?q=__>\n", "html": "<p>__a<a href=\"http://foo.bar/?q=__\">http://foo.bar/?q=__</a></p>\n", "example": 480, "start_line": 7440, "end_line": 7444, "section": "Emphasis and strong emphasis" }, { "markdown": "[link](/uri \"title\")\n", "html": "<p><a href=\"/uri\" title=\"title\">link</a></p>\n", "example": 481, "start_line": 7528, "end_line": 7532, "section": "Links" }, { "markdown": "[link](/uri)\n", "html": "<p><a href=\"/uri\">link</a></p>\n", "example": 482, "start_line": 7538, "end_line": 7542, "section": "Links" }, { "markdown": "[](./target.md)\n", "html": "<p><a href=\"./target.md\"></a></p>\n", "example": 483, "start_line": 7544, "end_line": 7548, "section": "Links" }, { "markdown": "[link]()\n", "html": "<p><a href=\"\">link</a></p>\n", "example": 484, "start_line": 7551, "end_line": 7555, "section": "Links" }, { "markdown": "[link](<>)\n", "html": "<p><a href=\"\">link</a></p>\n", "example": 485, "start_line": 7558, "end_line": 7562, "section": "Links" }, { "markdown": "[]()\n", "html": "<p><a href=\"\"></a></p>\n", "example": 486, "start_line": 7565, "end_line": 7569, "section": "Links" }, { "markdown": "[link](/my uri)\n", "html": "<p>[link](/my uri)</p>\n", "example": 487, "start_line": 7574, "end_line": 7578, "section": "Links" }, { "markdown": "[link](</my uri>)\n", "html": "<p><a href=\"/my%20uri\">link</a></p>\n", "example": 488, "start_line": 7580, "end_line": 7584, "section": "Links" }, { "markdown": "[link](foo\nbar)\n", "html": "<p>[link](foo\nbar)</p>\n", "example": 489, "start_line": 7589, "end_line": 7595, "section": "Links" }, { "markdown": "[link](<foo\nbar>)\n", "html": "<p>[link](<foo\nbar>)</p>\n", "example": 490, "start_line": 7597, "end_line": 7603, "section": "Links" }, { "markdown": "[a](<b)c>)\n", "html": "<p><a href=\"b)c\">a</a></p>\n", "example": 491, "start_line": 7608, "end_line": 7612, "section": "Links" }, { "markdown": "[link](<foo\\>)\n", "html": "<p>[link](<foo>)</p>\n", "example": 492, "start_line": 7616, "end_line": 7620, "section": "Links" }, { "markdown": "[a](<b)c\n[a](<b)c>\n[a](<b>c)\n", "html": "<p>[a](<b)c\n[a](<b)c>\n[a](<b>c)</p>\n", "example": 493, "start_line": 7625, "end_line": 7633, "section": "Links" }, { "markdown": "[link](\\(foo\\))\n", "html": "<p><a href=\"(foo)\">link</a></p>\n", "example": 494, "start_line": 7637, "end_line": 7641, "section": "Links" }, { "markdown": "[link](foo(and(bar)))\n", "html": "<p><a href=\"foo(and(bar))\">link</a></p>\n", "example": 495, "start_line": 7646, "end_line": 7650, "section": "Links" }, { "markdown": "[link](foo(and(bar))\n", "html": "<p>[link](foo(and(bar))</p>\n", "example": 496, "start_line": 7655, "end_line": 7659, "section": "Links" }, { "markdown": "[link](foo\\(and\\(bar\\))\n", "html": "<p><a href=\"foo(and(bar)\">link</a></p>\n", "example": 497, "start_line": 7662, "end_line": 7666, "section": "Links" }, { "markdown": "[link](<foo(and(bar)>)\n", "html": "<p><a href=\"foo(and(bar)\">link</a></p>\n", "example": 498, "start_line": 7669, "end_line": 7673, "section": "Links" }, { "markdown": "[link](foo\\)\\:)\n", "html": "<p><a href=\"foo):\">link</a></p>\n", "example": 499, "start_line": 7679, "end_line": 7683, "section": "Links" }, { "markdown": "[link](#fragment)\n\n[link](http://example.com#fragment)\n\n[link](http://example.com?foo=3#frag)\n", "html": "<p><a href=\"#fragment\">link</a></p>\n<p><a href=\"http://example.com#fragment\">link</a></p>\n<p><a href=\"http://example.com?foo=3#frag\">link</a></p>\n", "example": 500, "start_line": 7688, "end_line": 7698, "section": "Links" }, { "markdown": "[link](foo\\bar)\n", "html": "<p><a href=\"foo%5Cbar\">link</a></p>\n", "example": 501, "start_line": 7704, "end_line": 7708, "section": "Links" }, { "markdown": "[link](foo%20bä)\n", "html": "<p><a href=\"foo%20b%C3%A4\">link</a></p>\n", "example": 502, "start_line": 7720, "end_line": 7724, "section": "Links" }, { "markdown": "[link](\"title\")\n", "html": "<p><a href=\"%22title%22\">link</a></p>\n", "example": 503, "start_line": 7731, "end_line": 7735, "section": "Links" }, { "markdown": "[link](/url \"title\")\n[link](/url 'title')\n[link](/url (title))\n", "html": "<p><a href=\"/url\" title=\"title\">link</a>\n<a href=\"/url\" title=\"title\">link</a>\n<a href=\"/url\" title=\"title\">link</a></p>\n", "example": 504, "start_line": 7740, "end_line": 7748, "section": "Links" }, { "markdown": "[link](/url \"title \\\""\")\n", "html": "<p><a href=\"/url\" title=\"title ""\">link</a></p>\n", "example": 505, "start_line": 7754, "end_line": 7758, "section": "Links" }, { "markdown": "[link](/url \"title\")\n", "html": "<p><a href=\"/url%C2%A0%22title%22\">link</a></p>\n", "example": 506, "start_line": 7765, "end_line": 7769, "section": "Links" }, { "markdown": "[link](/url \"title \"and\" title\")\n", "html": "<p>[link](/url "title "and" title")</p>\n", "example": 507, "start_line": 7774, "end_line": 7778, "section": "Links" }, { "markdown": "[link](/url 'title \"and\" title')\n", "html": "<p><a href=\"/url\" title=\"title "and" title\">link</a></p>\n", "example": 508, "start_line": 7783, "end_line": 7787, "section": "Links" }, { "markdown": "[link]( /uri\n \"title\" )\n", "html": "<p><a href=\"/uri\" title=\"title\">link</a></p>\n", "example": 509, "start_line": 7808, "end_line": 7813, "section": "Links" }, { "markdown": "[link] (/uri)\n", "html": "<p>[link] (/uri)</p>\n", "example": 510, "start_line": 7819, "end_line": 7823, "section": "Links" }, { "markdown": "[link [foo [bar]]](/uri)\n", "html": "<p><a href=\"/uri\">link [foo [bar]]</a></p>\n", "example": 511, "start_line": 7829, "end_line": 7833, "section": "Links" }, { "markdown": "[link] bar](/uri)\n", "html": "<p>[link] bar](/uri)</p>\n", "example": 512, "start_line": 7836, "end_line": 7840, "section": "Links" }, { "markdown": "[link [bar](/uri)\n", "html": "<p>[link <a href=\"/uri\">bar</a></p>\n", "example": 513, "start_line": 7843, "end_line": 7847, "section": "Links" }, { "markdown": "[link \\[bar](/uri)\n", "html": "<p><a href=\"/uri\">link [bar</a></p>\n", "example": 514, "start_line": 7850, "end_line": 7854, "section": "Links" }, { "markdown": "[link *foo **bar** `#`*](/uri)\n", "html": "<p><a href=\"/uri\">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>\n", "example": 515, "start_line": 7859, "end_line": 7863, "section": "Links" }, { "markdown": "[![moon](moon.jpg)](/uri)\n", "html": "<p><a href=\"/uri\"><img src=\"moon.jpg\" alt=\"moon\" /></a></p>\n", "example": 516, "start_line": 7866, "end_line": 7870, "section": "Links" }, { "markdown": "[foo [bar](/uri)](/uri)\n", "html": "<p>[foo <a href=\"/uri\">bar</a>](/uri)</p>\n", "example": 517, "start_line": 7875, "end_line": 7879, "section": "Links" }, { "markdown": "[foo *[bar [baz](/uri)](/uri)*](/uri)\n", "html": "<p>[foo <em>[bar <a href=\"/uri\">baz</a>](/uri)</em>](/uri)</p>\n", "example": 518, "start_line": 7882, "end_line": 7886, "section": "Links" }, { "markdown": "![[[foo](uri1)](uri2)](uri3)\n", "html": "<p><img src=\"uri3\" alt=\"[foo](uri2)\" /></p>\n", "example": 519, "start_line": 7889, "end_line": 7893, "section": "Links" }, { "markdown": "*[foo*](/uri)\n", "html": "<p>*<a href=\"/uri\">foo*</a></p>\n", "example": 520, "start_line": 7899, "end_line": 7903, "section": "Links" }, { "markdown": "[foo *bar](baz*)\n", "html": "<p><a href=\"baz*\">foo *bar</a></p>\n", "example": 521, "start_line": 7906, "end_line": 7910, "section": "Links" }, { "markdown": "*foo [bar* baz]\n", "html": "<p><em>foo [bar</em> baz]</p>\n", "example": 522, "start_line": 7916, "end_line": 7920, "section": "Links" }, { "markdown": "[foo <bar attr=\"](baz)\">\n", "html": "<p>[foo <bar attr=\"](baz)\"></p>\n", "example": 523, "start_line": 7926, "end_line": 7930, "section": "Links" }, { "markdown": "[foo`](/uri)`\n", "html": "<p>[foo<code>](/uri)</code></p>\n", "example": 524, "start_line": 7933, "end_line": 7937, "section": "Links" }, { "markdown": "[foo<http://example.com/?search=](uri)>\n", "html": "<p>[foo<a href=\"http://example.com/?search=%5D(uri)\">http://example.com/?search=](uri)</a></p>\n", "example": 525, "start_line": 7940, "end_line": 7944, "section": "Links" }, { "markdown": "[foo][bar]\n\n[bar]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 526, "start_line": 7978, "end_line": 7984, "section": "Links" }, { "markdown": "[link [foo [bar]]][ref]\n\n[ref]: /uri\n", "html": "<p><a href=\"/uri\">link [foo [bar]]</a></p>\n", "example": 527, "start_line": 7993, "end_line": 7999, "section": "Links" }, { "markdown": "[link \\[bar][ref]\n\n[ref]: /uri\n", "html": "<p><a href=\"/uri\">link [bar</a></p>\n", "example": 528, "start_line": 8002, "end_line": 8008, "section": "Links" }, { "markdown": "[link *foo **bar** `#`*][ref]\n\n[ref]: /uri\n", "html": "<p><a href=\"/uri\">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>\n", "example": 529, "start_line": 8013, "end_line": 8019, "section": "Links" }, { "markdown": "[![moon](moon.jpg)][ref]\n\n[ref]: /uri\n", "html": "<p><a href=\"/uri\"><img src=\"moon.jpg\" alt=\"moon\" /></a></p>\n", "example": 530, "start_line": 8022, "end_line": 8028, "section": "Links" }, { "markdown": "[foo [bar](/uri)][ref]\n\n[ref]: /uri\n", "html": "<p>[foo <a href=\"/uri\">bar</a>]<a href=\"/uri\">ref</a></p>\n", "example": 531, "start_line": 8033, "end_line": 8039, "section": "Links" }, { "markdown": "[foo *bar [baz][ref]*][ref]\n\n[ref]: /uri\n", "html": "<p>[foo <em>bar <a href=\"/uri\">baz</a></em>]<a href=\"/uri\">ref</a></p>\n", "example": 532, "start_line": 8042, "end_line": 8048, "section": "Links" }, { "markdown": "*[foo*][ref]\n\n[ref]: /uri\n", "html": "<p>*<a href=\"/uri\">foo*</a></p>\n", "example": 533, "start_line": 8057, "end_line": 8063, "section": "Links" }, { "markdown": "[foo *bar][ref]*\n\n[ref]: /uri\n", "html": "<p><a href=\"/uri\">foo *bar</a>*</p>\n", "example": 534, "start_line": 8066, "end_line": 8072, "section": "Links" }, { "markdown": "[foo <bar attr=\"][ref]\">\n\n[ref]: /uri\n", "html": "<p>[foo <bar attr=\"][ref]\"></p>\n", "example": 535, "start_line": 8078, "end_line": 8084, "section": "Links" }, { "markdown": "[foo`][ref]`\n\n[ref]: /uri\n", "html": "<p>[foo<code>][ref]</code></p>\n", "example": 536, "start_line": 8087, "end_line": 8093, "section": "Links" }, { "markdown": "[foo<http://example.com/?search=][ref]>\n\n[ref]: /uri\n", "html": "<p>[foo<a href=\"http://example.com/?search=%5D%5Bref%5D\">http://example.com/?search=][ref]</a></p>\n", "example": 537, "start_line": 8096, "end_line": 8102, "section": "Links" }, { "markdown": "[foo][BaR]\n\n[bar]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 538, "start_line": 8107, "end_line": 8113, "section": "Links" }, { "markdown": "[ẞ]\n\n[SS]: /url\n", "html": "<p><a href=\"/url\">ẞ</a></p>\n", "example": 539, "start_line": 8118, "end_line": 8124, "section": "Links" }, { "markdown": "[Foo\n bar]: /url\n\n[Baz][Foo bar]\n", "html": "<p><a href=\"/url\">Baz</a></p>\n", "example": 540, "start_line": 8130, "end_line": 8137, "section": "Links" }, { "markdown": "[foo] [bar]\n\n[bar]: /url \"title\"\n", "html": "<p>[foo] <a href=\"/url\" title=\"title\">bar</a></p>\n", "example": 541, "start_line": 8143, "end_line": 8149, "section": "Links" }, { "markdown": "[foo]\n[bar]\n\n[bar]: /url \"title\"\n", "html": "<p>[foo]\n<a href=\"/url\" title=\"title\">bar</a></p>\n", "example": 542, "start_line": 8152, "end_line": 8160, "section": "Links" }, { "markdown": "[foo]: /url1\n\n[foo]: /url2\n\n[bar][foo]\n", "html": "<p><a href=\"/url1\">bar</a></p>\n", "example": 543, "start_line": 8193, "end_line": 8201, "section": "Links" }, { "markdown": "[bar][foo\\!]\n\n[foo!]: /url\n", "html": "<p>[bar][foo!]</p>\n", "example": 544, "start_line": 8208, "end_line": 8214, "section": "Links" }, { "markdown": "[foo][ref[]\n\n[ref[]: /uri\n", "html": "<p>[foo][ref[]</p>\n<p>[ref[]: /uri</p>\n", "example": 545, "start_line": 8220, "end_line": 8227, "section": "Links" }, { "markdown": "[foo][ref[bar]]\n\n[ref[bar]]: /uri\n", "html": "<p>[foo][ref[bar]]</p>\n<p>[ref[bar]]: /uri</p>\n", "example": 546, "start_line": 8230, "end_line": 8237, "section": "Links" }, { "markdown": "[[[foo]]]\n\n[[[foo]]]: /url\n", "html": "<p>[[[foo]]]</p>\n<p>[[[foo]]]: /url</p>\n", "example": 547, "start_line": 8240, "end_line": 8247, "section": "Links" }, { "markdown": "[foo][ref\\[]\n\n[ref\\[]: /uri\n", "html": "<p><a href=\"/uri\">foo</a></p>\n", "example": 548, "start_line": 8250, "end_line": 8256, "section": "Links" }, { "markdown": "[bar\\\\]: /uri\n\n[bar\\\\]\n", "html": "<p><a href=\"/uri\">bar\\</a></p>\n", "example": 549, "start_line": 8261, "end_line": 8267, "section": "Links" }, { "markdown": "[]\n\n[]: /uri\n", "html": "<p>[]</p>\n<p>[]: /uri</p>\n", "example": 550, "start_line": 8273, "end_line": 8280, "section": "Links" }, { "markdown": "[\n ]\n\n[\n ]: /uri\n", "html": "<p>[\n]</p>\n<p>[\n]: /uri</p>\n", "example": 551, "start_line": 8283, "end_line": 8294, "section": "Links" }, { "markdown": "[foo][]\n\n[foo]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 552, "start_line": 8306, "end_line": 8312, "section": "Links" }, { "markdown": "[*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\"><em>foo</em> bar</a></p>\n", "example": 553, "start_line": 8315, "end_line": 8321, "section": "Links" }, { "markdown": "[Foo][]\n\n[foo]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">Foo</a></p>\n", "example": 554, "start_line": 8326, "end_line": 8332, "section": "Links" }, { "markdown": "[foo] \n[]\n\n[foo]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a>\n[]</p>\n", "example": 555, "start_line": 8339, "end_line": 8347, "section": "Links" }, { "markdown": "[foo]\n\n[foo]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 556, "start_line": 8359, "end_line": 8365, "section": "Links" }, { "markdown": "[*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\"><em>foo</em> bar</a></p>\n", "example": 557, "start_line": 8368, "end_line": 8374, "section": "Links" }, { "markdown": "[[*foo* bar]]\n\n[*foo* bar]: /url \"title\"\n", "html": "<p>[<a href=\"/url\" title=\"title\"><em>foo</em> bar</a>]</p>\n", "example": 558, "start_line": 8377, "end_line": 8383, "section": "Links" }, { "markdown": "[[bar [foo]\n\n[foo]: /url\n", "html": "<p>[[bar <a href=\"/url\">foo</a></p>\n", "example": 559, "start_line": 8386, "end_line": 8392, "section": "Links" }, { "markdown": "[Foo]\n\n[foo]: /url \"title\"\n", "html": "<p><a href=\"/url\" title=\"title\">Foo</a></p>\n", "example": 560, "start_line": 8397, "end_line": 8403, "section": "Links" }, { "markdown": "[foo] bar\n\n[foo]: /url\n", "html": "<p><a href=\"/url\">foo</a> bar</p>\n", "example": 561, "start_line": 8408, "end_line": 8414, "section": "Links" }, { "markdown": "\\[foo]\n\n[foo]: /url \"title\"\n", "html": "<p>[foo]</p>\n", "example": 562, "start_line": 8420, "end_line": 8426, "section": "Links" }, { "markdown": "[foo*]: /url\n\n*[foo*]\n", "html": "<p>*<a href=\"/url\">foo*</a></p>\n", "example": 563, "start_line": 8432, "end_line": 8438, "section": "Links" }, { "markdown": "[foo][bar]\n\n[foo]: /url1\n[bar]: /url2\n", "html": "<p><a href=\"/url2\">foo</a></p>\n", "example": 564, "start_line": 8444, "end_line": 8451, "section": "Links" }, { "markdown": "[foo][]\n\n[foo]: /url1\n", "html": "<p><a href=\"/url1\">foo</a></p>\n", "example": 565, "start_line": 8453, "end_line": 8459, "section": "Links" }, { "markdown": "[foo]()\n\n[foo]: /url1\n", "html": "<p><a href=\"\">foo</a></p>\n", "example": 566, "start_line": 8463, "end_line": 8469, "section": "Links" }, { "markdown": "[foo](not a link)\n\n[foo]: /url1\n", "html": "<p><a href=\"/url1\">foo</a>(not a link)</p>\n", "example": 567, "start_line": 8471, "end_line": 8477, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url\n", "html": "<p>[foo]<a href=\"/url\">bar</a></p>\n", "example": 568, "start_line": 8482, "end_line": 8488, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[bar]: /url2\n", "html": "<p><a href=\"/url2\">foo</a><a href=\"/url1\">baz</a></p>\n", "example": 569, "start_line": 8494, "end_line": 8501, "section": "Links" }, { "markdown": "[foo][bar][baz]\n\n[baz]: /url1\n[foo]: /url2\n", "html": "<p>[foo]<a href=\"/url1\">bar</a></p>\n", "example": 570, "start_line": 8507, "end_line": 8514, "section": "Links" }, { "markdown": "![foo](/url \"title\")\n", "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", "example": 571, "start_line": 8530, "end_line": 8534, "section": "Images" }, { "markdown": "![foo *bar*]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", "example": 572, "start_line": 8537, "end_line": 8543, "section": "Images" }, { "markdown": "![foo ![bar](/url)](/url2)\n", "html": "<p><img src=\"/url2\" alt=\"foo bar\" /></p>\n", "example": 573, "start_line": 8546, "end_line": 8550, "section": "Images" }, { "markdown": "![foo [bar](/url)](/url2)\n", "html": "<p><img src=\"/url2\" alt=\"foo bar\" /></p>\n", "example": 574, "start_line": 8553, "end_line": 8557, "section": "Images" }, { "markdown": "![foo *bar*][]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n", "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", "example": 575, "start_line": 8567, "end_line": 8573, "section": "Images" }, { "markdown": "![foo *bar*][foobar]\n\n[FOOBAR]: train.jpg \"train & tracks\"\n", "html": "<p><img src=\"train.jpg\" alt=\"foo bar\" title=\"train & tracks\" /></p>\n", "example": 576, "start_line": 8576, "end_line": 8582, "section": "Images" }, { "markdown": "![foo](train.jpg)\n", "html": "<p><img src=\"train.jpg\" alt=\"foo\" /></p>\n", "example": 577, "start_line": 8585, "end_line": 8589, "section": "Images" }, { "markdown": "My ![foo bar](/path/to/train.jpg \"title\" )\n", "html": "<p>My <img src=\"/path/to/train.jpg\" alt=\"foo bar\" title=\"title\" /></p>\n", "example": 578, "start_line": 8592, "end_line": 8596, "section": "Images" }, { "markdown": "![foo](<url>)\n", "html": "<p><img src=\"url\" alt=\"foo\" /></p>\n", "example": 579, "start_line": 8599, "end_line": 8603, "section": "Images" }, { "markdown": "![](/url)\n", "html": "<p><img src=\"/url\" alt=\"\" /></p>\n", "example": 580, "start_line": 8606, "end_line": 8610, "section": "Images" }, { "markdown": "![foo][bar]\n\n[bar]: /url\n", "html": "<p><img src=\"/url\" alt=\"foo\" /></p>\n", "example": 581, "start_line": 8615, "end_line": 8621, "section": "Images" }, { "markdown": "![foo][bar]\n\n[BAR]: /url\n", "html": "<p><img src=\"/url\" alt=\"foo\" /></p>\n", "example": 582, "start_line": 8624, "end_line": 8630, "section": "Images" }, { "markdown": "![foo][]\n\n[foo]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", "example": 583, "start_line": 8635, "end_line": 8641, "section": "Images" }, { "markdown": "![*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>\n", "example": 584, "start_line": 8644, "end_line": 8650, "section": "Images" }, { "markdown": "![Foo][]\n\n[foo]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"Foo\" title=\"title\" /></p>\n", "example": 585, "start_line": 8655, "end_line": 8661, "section": "Images" }, { "markdown": "![foo] \n[]\n\n[foo]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" />\n[]</p>\n", "example": 586, "start_line": 8667, "end_line": 8675, "section": "Images" }, { "markdown": "![foo]\n\n[foo]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"foo\" title=\"title\" /></p>\n", "example": 587, "start_line": 8680, "end_line": 8686, "section": "Images" }, { "markdown": "![*foo* bar]\n\n[*foo* bar]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"foo bar\" title=\"title\" /></p>\n", "example": 588, "start_line": 8689, "end_line": 8695, "section": "Images" }, { "markdown": "![[foo]]\n\n[[foo]]: /url \"title\"\n", "html": "<p>![[foo]]</p>\n<p>[[foo]]: /url "title"</p>\n", "example": 589, "start_line": 8700, "end_line": 8707, "section": "Images" }, { "markdown": "![Foo]\n\n[foo]: /url \"title\"\n", "html": "<p><img src=\"/url\" alt=\"Foo\" title=\"title\" /></p>\n", "example": 590, "start_line": 8712, "end_line": 8718, "section": "Images" }, { "markdown": "!\\[foo]\n\n[foo]: /url \"title\"\n", "html": "<p>![foo]</p>\n", "example": 591, "start_line": 8724, "end_line": 8730, "section": "Images" }, { "markdown": "\\![foo]\n\n[foo]: /url \"title\"\n", "html": "<p>!<a href=\"/url\" title=\"title\">foo</a></p>\n", "example": 592, "start_line": 8736, "end_line": 8742, "section": "Images" }, { "markdown": "<http://foo.bar.baz>\n", "html": "<p><a href=\"http://foo.bar.baz\">http://foo.bar.baz</a></p>\n", "example": 593, "start_line": 8769, "end_line": 8773, "section": "Autolinks" }, { "markdown": "<http://foo.bar.baz/test?q=hello&id=22&boolean>\n", "html": "<p><a href=\"http://foo.bar.baz/test?q=hello&id=22&boolean\">http://foo.bar.baz/test?q=hello&id=22&boolean</a></p>\n", "example": 594, "start_line": 8776, "end_line": 8780, "section": "Autolinks" }, { "markdown": "<irc://foo.bar:2233/baz>\n", "html": "<p><a href=\"irc://foo.bar:2233/baz\">irc://foo.bar:2233/baz</a></p>\n", "example": 595, "start_line": 8783, "end_line": 8787, "section": "Autolinks" }, { "markdown": "<MAILTO:FOO@BAR.BAZ>\n", "html": "<p><a href=\"MAILTO:FOO@BAR.BAZ\">MAILTO:FOO@BAR.BAZ</a></p>\n", "example": 596, "start_line": 8792, "end_line": 8796, "section": "Autolinks" }, { "markdown": "<a+b+c:d>\n", "html": "<p><a href=\"a+b+c:d\">a+b+c:d</a></p>\n", "example": 597, "start_line": 8804, "end_line": 8808, "section": "Autolinks" }, { "markdown": "<made-up-scheme://foo,bar>\n", "html": "<p><a href=\"made-up-scheme://foo,bar\">made-up-scheme://foo,bar</a></p>\n", "example": 598, "start_line": 8811, "end_line": 8815, "section": "Autolinks" }, { "markdown": "<http://../>\n", "html": "<p><a href=\"http://../\">http://../</a></p>\n", "example": 599, "start_line": 8818, "end_line": 8822, "section": "Autolinks" }, { "markdown": "<localhost:5001/foo>\n", "html": "<p><a href=\"localhost:5001/foo\">localhost:5001/foo</a></p>\n", "example": 600, "start_line": 8825, "end_line": 8829, "section": "Autolinks" }, { "markdown": "<http://foo.bar/baz bim>\n", "html": "<p><http://foo.bar/baz bim></p>\n", "example": 601, "start_line": 8834, "end_line": 8838, "section": "Autolinks" }, { "markdown": "<http://example.com/\\[\\>\n", "html": "<p><a href=\"http://example.com/%5C%5B%5C\">http://example.com/\\[\\</a></p>\n", "example": 602, "start_line": 8843, "end_line": 8847, "section": "Autolinks" }, { "markdown": "<foo@bar.example.com>\n", "html": "<p><a href=\"mailto:foo@bar.example.com\">foo@bar.example.com</a></p>\n", "example": 603, "start_line": 8865, "end_line": 8869, "section": "Autolinks" }, { "markdown": "<foo+special@Bar.baz-bar0.com>\n", "html": "<p><a href=\"mailto:foo+special@Bar.baz-bar0.com\">foo+special@Bar.baz-bar0.com</a></p>\n", "example": 604, "start_line": 8872, "end_line": 8876, "section": "Autolinks" }, { "markdown": "<foo\\+@bar.example.com>\n", "html": "<p><foo+@bar.example.com></p>\n", "example": 605, "start_line": 8881, "end_line": 8885, "section": "Autolinks" }, { "markdown": "<>\n", "html": "<p><></p>\n", "example": 606, "start_line": 8890, "end_line": 8894, "section": "Autolinks" }, { "markdown": "< http://foo.bar >\n", "html": "<p>< http://foo.bar ></p>\n", "example": 607, "start_line": 8897, "end_line": 8901, "section": "Autolinks" }, { "markdown": "<m:abc>\n", "html": "<p><m:abc></p>\n", "example": 608, "start_line": 8904, "end_line": 8908, "section": "Autolinks" }, { "markdown": "<foo.bar.baz>\n", "html": "<p><foo.bar.baz></p>\n", "example": 609, "start_line": 8911, "end_line": 8915, "section": "Autolinks" }, { "markdown": "http://example.com\n", "html": "<p>http://example.com</p>\n", "example": 610, "start_line": 8918, "end_line": 8922, "section": "Autolinks" }, { "markdown": "foo@bar.example.com\n", "html": "<p>foo@bar.example.com</p>\n", "example": 611, "start_line": 8925, "end_line": 8929, "section": "Autolinks" }, { "markdown": "<a><bab><c2c>\n", "html": "<p><a><bab><c2c></p>\n", "example": 612, "start_line": 9006, "end_line": 9010, "section": "Raw HTML" }, { "markdown": "<a/><b2/>\n", "html": "<p><a/><b2/></p>\n", "example": 613, "start_line": 9015, "end_line": 9019, "section": "Raw HTML" }, { "markdown": "<a /><b2\ndata=\"foo\" >\n", "html": "<p><a /><b2\ndata=\"foo\" ></p>\n", "example": 614, "start_line": 9024, "end_line": 9030, "section": "Raw HTML" }, { "markdown": "<a foo=\"bar\" bam = 'baz <em>\"</em>'\n_boolean zoop:33=zoop:33 />\n", "html": "<p><a foo=\"bar\" bam = 'baz <em>\"</em>'\n_boolean zoop:33=zoop:33 /></p>\n", "example": 615, "start_line": 9035, "end_line": 9041, "section": "Raw HTML" }, { "markdown": "Foo <responsive-image src=\"foo.jpg\" />\n", "html": "<p>Foo <responsive-image src=\"foo.jpg\" /></p>\n", "example": 616, "start_line": 9046, "end_line": 9050, "section": "Raw HTML" }, { "markdown": "<33> <__>\n", "html": "<p><33> <__></p>\n", "example": 617, "start_line": 9055, "end_line": 9059, "section": "Raw HTML" }, { "markdown": "<a h*#ref=\"hi\">\n", "html": "<p><a h*#ref="hi"></p>\n", "example": 618, "start_line": 9064, "end_line": 9068, "section": "Raw HTML" }, { "markdown": "<a href=\"hi'> <a href=hi'>\n", "html": "<p><a href="hi'> <a href=hi'></p>\n", "example": 619, "start_line": 9073, "end_line": 9077, "section": "Raw HTML" }, { "markdown": "< a><\nfoo><bar/ >\n<foo bar=baz\nbim!bop />\n", "html": "<p>< a><\nfoo><bar/ >\n<foo bar=baz\nbim!bop /></p>\n", "example": 620, "start_line": 9082, "end_line": 9092, "section": "Raw HTML" }, { "markdown": "<a href='bar'title=title>\n", "html": "<p><a href='bar'title=title></p>\n", "example": 621, "start_line": 9097, "end_line": 9101, "section": "Raw HTML" }, { "markdown": "</a></foo >\n", "html": "<p></a></foo ></p>\n", "example": 622, "start_line": 9106, "end_line": 9110, "section": "Raw HTML" }, { "markdown": "</a href=\"foo\">\n", "html": "<p></a href="foo"></p>\n", "example": 623, "start_line": 9115, "end_line": 9119, "section": "Raw HTML" }, { "markdown": "foo <!-- this is a\ncomment - with hyphen -->\n", "html": "<p>foo <!-- this is a\ncomment - with hyphen --></p>\n", "example": 624, "start_line": 9124, "end_line": 9130, "section": "Raw HTML" }, { "markdown": "foo <!-- not a comment -- two hyphens -->\n", "html": "<p>foo <!-- not a comment -- two hyphens --></p>\n", "example": 625, "start_line": 9133, "end_line": 9137, "section": "Raw HTML" }, { "markdown": "foo <!--> foo -->\n\nfoo <!-- foo--->\n", "html": "<p>foo <!--> foo --></p>\n<p>foo <!-- foo---></p>\n", "example": 626, "start_line": 9142, "end_line": 9149, "section": "Raw HTML" }, { "markdown": "foo <?php echo $a; ?>\n", "html": "<p>foo <?php echo $a; ?></p>\n", "example": 627, "start_line": 9154, "end_line": 9158, "section": "Raw HTML" }, { "markdown": "foo <!ELEMENT br EMPTY>\n", "html": "<p>foo <!ELEMENT br EMPTY></p>\n", "example": 628, "start_line": 9163, "end_line": 9167, "section": "Raw HTML" }, { "markdown": "foo <![CDATA[>&<]]>\n", "html": "<p>foo <![CDATA[>&<]]></p>\n", "example": 629, "start_line": 9172, "end_line": 9176, "section": "Raw HTML" }, { "markdown": "foo <a href=\"ö\">\n", "html": "<p>foo <a href=\"ö\"></p>\n", "example": 630, "start_line": 9182, "end_line": 9186, "section": "Raw HTML" }, { "markdown": "foo <a href=\"\\*\">\n", "html": "<p>foo <a href=\"\\*\"></p>\n", "example": 631, "start_line": 9191, "end_line": 9195, "section": "Raw HTML" }, { "markdown": "<a href=\"\\\"\">\n", "html": "<p><a href="""></p>\n", "example": 632, "start_line": 9198, "end_line": 9202, "section": "Raw HTML" }, { "markdown": "foo \nbaz\n", "html": "<p>foo<br />\nbaz</p>\n", "example": 633, "start_line": 9212, "end_line": 9218, "section": "Hard line breaks" }, { "markdown": "foo\\\nbaz\n", "html": "<p>foo<br />\nbaz</p>\n", "example": 634, "start_line": 9224, "end_line": 9230, "section": "Hard line breaks" }, { "markdown": "foo \nbaz\n", "html": "<p>foo<br />\nbaz</p>\n", "example": 635, "start_line": 9235, "end_line": 9241, "section": "Hard line breaks" }, { "markdown": "foo \n bar\n", "html": "<p>foo<br />\nbar</p>\n", "example": 636, "start_line": 9246, "end_line": 9252, "section": "Hard line breaks" }, { "markdown": "foo\\\n bar\n", "html": "<p>foo<br />\nbar</p>\n", "example": 637, "start_line": 9255, "end_line": 9261, "section": "Hard line breaks" }, { "markdown": "*foo \nbar*\n", "html": "<p><em>foo<br />\nbar</em></p>\n", "example": 638, "start_line": 9267, "end_line": 9273, "section": "Hard line breaks" }, { "markdown": "*foo\\\nbar*\n", "html": "<p><em>foo<br />\nbar</em></p>\n", "example": 639, "start_line": 9276, "end_line": 9282, "section": "Hard line breaks" }, { "markdown": "`code \nspan`\n", "html": "<p><code>code span</code></p>\n", "example": 640, "start_line": 9287, "end_line": 9292, "section": "Hard line breaks" }, { "markdown": "`code\\\nspan`\n", "html": "<p><code>code\\ span</code></p>\n", "example": 641, "start_line": 9295, "end_line": 9300, "section": "Hard line breaks" }, { "markdown": "<a href=\"foo \nbar\">\n", "html": "<p><a href=\"foo \nbar\"></p>\n", "example": 642, "start_line": 9305, "end_line": 9311, "section": "Hard line breaks" }, { "markdown": "<a href=\"foo\\\nbar\">\n", "html": "<p><a href=\"foo\\\nbar\"></p>\n", "example": 643, "start_line": 9314, "end_line": 9320, "section": "Hard line breaks" }, { "markdown": "foo\\\n", "html": "<p>foo\\</p>\n", "example": 644, "start_line": 9327, "end_line": 9331, "section": "Hard line breaks" }, { "markdown": "foo \n", "html": "<p>foo</p>\n", "example": 645, "start_line": 9334, "end_line": 9338, "section": "Hard line breaks" }, { "markdown": "### foo\\\n", "html": "<h3>foo\\</h3>\n", "example": 646, "start_line": 9341, "end_line": 9345, "section": "Hard line breaks" }, { "markdown": "### foo \n", "html": "<h3>foo</h3>\n", "example": 647, "start_line": 9348, "end_line": 9352, "section": "Hard line breaks" }, { "markdown": "foo\nbaz\n", "html": "<p>foo\nbaz</p>\n", "example": 648, "start_line": 9363, "end_line": 9369, "section": "Soft line breaks" }, { "markdown": "foo \n baz\n", "html": "<p>foo\nbaz</p>\n", "example": 649, "start_line": 9375, "end_line": 9381, "section": "Soft line breaks" }, { "markdown": "hello $.;'there\n", "html": "<p>hello $.;'there</p>\n", "example": 650, "start_line": 9395, "end_line": 9399, "section": "Textual content" }, { "markdown": "Foo χρῆν\n", "html": "<p>Foo χρῆν</p>\n", "example": 651, "start_line": 9402, "end_line": 9406, "section": "Textual content" }, { "markdown": "Multiple spaces\n", "html": "<p>Multiple spaces</p>\n", "example": 652, "start_line": 9411, "end_line": 9415, "section": "Textual content" } ]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/def_list.txt�����������������������������������������������������������0000664�0000000�0000000�00000005422�14505662126�0020557�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Definition Lists ```````````````````````````````` example Term : definition . <dl> <dt>Term</dt> <dd>definition</dd> </dl> ```````````````````````````````` ```````````````````````````````` example Term : definition1 : definition2 . <dl> <dt>Term</dt> <dd>definition1</dd> <dd>definition2</dd> </dl> ```````````````````````````````` ```````````````````````````````` example Term : definition1 : definition2 paragraph . <dl> <dt>Term</dt> <dd>definition1</dd> <dd>definition2</dd> </dl> <p>paragraph</p> ```````````````````````````````` ```````````````````````````````` example First Term : This is the definition of the first term. Second Term : This is one definition of the second term. : This is another definition of the second term. . <dl> <dt>First Term</dt> <dd>This is the definition of the first term.</dd> <dt>Second Term</dt> <dd>This is one definition of the second term.</dd> <dd>This is another definition of the second term.</dd> </dl> ```````````````````````````````` ```````````````````````````````` example First Term : This is the definition of the first term. Second Term : This is one definition of the second term. : This is another definition of the second term. paragraph . <dl> <dt>First Term</dt> <dd>This is the definition of the first term.</dd> <dt>Second Term</dt> <dd>This is one definition of the second term.</dd> <dd>This is another definition of the second term.</dd> </dl> <p>paragraph</p> ```````````````````````````````` ```````````````````````````````` example First Term : This is the definition of the first term. Not Second Term : This is one definition of the second term. : This is another definition of the second term. paragraph . <dl> <dt>First Term</dt> <dd>This is the definition of the first term. Not Second Term</dd> <dd>This is one definition of the second term.</dd> <dd>This is another definition of the second term.</dd> </dl> <p>paragraph</p> ```````````````````````````````` ## Definition with Multiple Lines ```````````````````````````````` example Term : definition . <dl> <dt>Term</dt> <dd><p>definition</p> </dd> </dl> ```````````````````````````````` ```````````````````````````````` example Term : foo bar . <dl> <dt>Term</dt> <dd><p>foo</p> <p>bar</p> </dd> </dl> ```````````````````````````````` Leading 4 white spaces ```````````````````````````````` example Term : foo bar . <dl> <dt>Term</dt> <dd><p>foo</p> <p>bar</p> </dd> </dl> ```````````````````````````````` ```````````````````````````````` example Term : foo bar . <dl> <dt>Term</dt> <dd><p>foo</p> <pre><code>bar</code></pre> </dd> </dl> ```````````````````````````````` ```````````````````````````````` example Term : foo - bar - baz . <dl> <dt>Term</dt> <dd><p>foo</p> <ul> <li>bar</li> <li>baz</li> </ul> </dd> </dl> ```````````````````````````````` ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/diff-commonmark.txt����������������������������������������������������0000664�0000000�0000000�00000002230�14505662126�0022031�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Differences Results different than commonmark. ## Setext headings Example: 93 ```````````````````````````````` example > foo bar === . <blockquote> <h1>foo bar</h1> </blockquote> ```````````````````````````````` If the dash is less than 3, it is not a `<hr>`, in this case, it can be rendered into `<h2>`. ```````````````````````````````` example - # Foo - Bar -- baz . <ul> <li> <h1>Foo</h1> </li> <li> <h2>Bar</h2> baz</li> </ul> ```````````````````````````````` ## Image Example 573 ```````````````````````````````` example ![foo ![bar](/url)](/url2) . <p><img src="/url2" alt="foo ![bar](/url)" /></p> ```````````````````````````````` ## Link Example 517 ```````````````````````````````` example [foo [bar](/uri)](/uri) . <p><a href="/uri">foo [bar](/uri)</a></p> ```````````````````````````````` Example 518 ```````````````````````````````` example [foo *[bar [baz](/uri)](/uri)*](/uri) . <p><a href="/uri">foo <em>[bar [baz](/uri)](/uri)</em></a></p> ```````````````````````````````` Example 519 ```````````````````````````````` example ![[[foo](uri1)](uri2)](uri3) . <p><img src="uri3" alt="[foo](uri1)" /></p> ```````````````````````````````` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/fenced_admonition.txt��������������������������������������������������0000664�0000000�0000000�00000004450�14505662126�0022433�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Admonition ```````````````````````````````` example ```{unknown} Hi this is **strong** world ``` . <div class="error"><pre>{unknown} Hi this is **strong** world </pre></div> ```````````````````````````````` ```````````````````````````````` example ``` this is code ``` . <pre><code>this is code </code></pre> ```````````````````````````````` ```````````````````````````````` example ~~~{note} Warning message ~~~ . <section class="admonition note"> <p class="admonition-title">Warning</p> <p>message</p> </section> ```````````````````````````````` ```````````````````````````````` example ~~~{note} A **strong** title _message_ ~~~ . <section class="admonition note"> <p class="admonition-title">A <strong>strong</strong> title</p> <p><em>message</em></p> </section> ```````````````````````````````` Test with code block. ```````````````````````````````` example ```{note} print() ``` . <section class="admonition note"> <p class="admonition-title">Note</p> <pre><code>print()</code></pre> </section> ```````````````````````````````` Test with no message. ```````````````````````````````` example ~~~{note} Warning ~~~ . <section class="admonition note"> <p class="admonition-title">Warning</p> </section> ```````````````````````````````` Test with no ending fence ```````````````````````````````` example ~~~{note} Warning . <section class="admonition note"> <p class="admonition-title">Warning</p> </section> ```````````````````````````````` Test with nested admonition ```````````````````````````````` example ~~~~~~~{note} ~~~~~~{warning} ~~~~~{tip} ~~~~{caution} ~~~{hint} ``````{danger} `````{attention} ````{important} ```{error} ``` ```` ````` `````` ~~~ ~~~~ ~~~~~ ~~~~~~ ~~~~~~~ . <section class="admonition note"> <p class="admonition-title">Note</p> <section class="admonition warning"> <p class="admonition-title">Warning</p> <section class="admonition tip"> <p class="admonition-title">Tip</p> <section class="admonition caution"> <p class="admonition-title">Caution</p> <section class="admonition hint"> <p class="admonition-title">Hint</p> <section class="admonition danger"> <p class="admonition-title">Danger</p> <pre><code class="language-{attention}">````{important} ```{error} ``` ```` </code></pre> </section> </section> </section> </section> </section> </section> ```````````````````````````````` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/fenced_figure.txt������������������������������������������������������0000664�0000000�0000000�00000006631�14505662126�0021556�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Figure ## No options ```````````````````````````````` example ~~~{figure} picture.png ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" /></div> </figure> ```````````````````````````````` ## Align options ```````````````````````````````` example ~~~{figure} picture.png :align: left ~~~ . <figure class="figure align-left"> <div class="block-image"><img src="picture.png" /></div> </figure> ```````````````````````````````` ```````````````````````````````` example ~~~{figure} picture.png :align: invalid ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" /></div> </figure> ```````````````````````````````` ## width and height ```````````````````````````````` example ~~~{figure} picture.png :width: 100 :height: 50 ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" width="100" height="50" /></div> </figure> ```````````````````````````````` ```````````````````````````````` example ~~~{figure} picture.png :width: 100px :height: 50px ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" style="width:100px;height:50px;" /></div> </figure> ```````````````````````````````` ```````````````````````````````` example ~~~{figure} picture.png :figwidth: 400px ~~~ . <figure class="figure" style="width:400px"> <div class="block-image"><img src="picture.png" /></div> </figure> ```````````````````````````````` ## alt option ```````````````````````````````` example ~~~{figure} picture.png :alt: description text ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" alt="description text" /></div> </figure> ```````````````````````````````` ## target option ```````````````````````````````` example ~~~{figure} picture.png :target: https://lepture.com ~~~ . <figure class="figure"> <a class="block-image" href="https://lepture.com"><img src="picture.png" /></a> </figure> ```````````````````````````````` ## caption ```````````````````````````````` example ~~~{figure} picture.png a caption with **emphasis** text ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" /></div> <figcaption>a caption with <strong>emphasis</strong> text</figcaption> </figure> ```````````````````````````````` ## legend ```````````````````````````````` example ~~~{figure} picture.png a caption with **emphasis** text > quote ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" /></div> <figcaption>a caption with <strong>emphasis</strong> text</figcaption> <div class="legend"> <blockquote> <p>quote</p> </blockquote> </div> </figure> ```````````````````````````````` ```````````````````````````````` example ~~~{figure} picture.png > quote ~~~ . <figure class="figure"> <div class="block-image"><img src="picture.png" /></div> </figure> ```````````````````````````````` ## all options ```````````````````````````````` example ~~~{figure} picture.png :figwidth: 400px :figclass: all-options :target: https://lepture.com :alt: description :align: left :width: 100 :height: 50 a caption with **emphasis** text > quote ~~~ . <figure class="figure align-left all-options" style="width:400px"> <a class="block-image" href="https://lepture.com"><img src="picture.png" alt="description" width="100" height="50" /></a> <figcaption>a caption with <strong>emphasis</strong> text</figcaption> <div class="legend"> <blockquote> <p>quote</p> </blockquote> </div> </figure> ```````````````````````````````` �������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/fenced_image.txt�������������������������������������������������������0000664�0000000�0000000�00000003417�14505662126�0021356�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Image ## No options ```````````````````````````````` example ~~~{image} picture.png ~~~ . <div class="block-image"><img src="picture.png" /></div> ```````````````````````````````` ## Align options ```````````````````````````````` example ~~~{image} picture.png :align: left ~~~ . <div class="block-image align-left"><img src="picture.png" /></div> ```````````````````````````````` ```````````````````````````````` example ~~~{image} picture.png :align: invalid ~~~ . <div class="block-image"><img src="picture.png" /></div> ```````````````````````````````` ## width and height ```````````````````````````````` example ~~~{image} picture.png :width: 100 :height: 50 ~~~ . <div class="block-image"><img src="picture.png" width="100" height="50" /></div> ```````````````````````````````` ```````````````````````````````` example ~~~{image} picture.png :width: 100px :height: 50px ~~~ . <div class="block-image"><img src="picture.png" style="width:100px;height:50px;" /></div> ```````````````````````````````` ## alt option ```````````````````````````````` example ~~~{image} picture.png :alt: description text ~~~ . <div class="block-image"><img src="picture.png" alt="description text" /></div> ```````````````````````````````` ## target option ```````````````````````````````` example ~~~{image} picture.png :target: https://lepture.com ~~~ . <a class="block-image" href="https://lepture.com"><img src="picture.png" /></a> ```````````````````````````````` ## all options ```````````````````````````````` example ~~~{image} picture.png :target: https://lepture.com :alt: description :align: left :width: 100 :height: 50 ~~~ . <a class="block-image align-left" href="https://lepture.com"><img src="picture.png" alt="description" width="100" height="50" /></a> ```````````````````````````````` �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/fenced_toc.txt���������������������������������������������������������0000664�0000000�0000000�00000007110�14505662126�0021053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Table of Contents ## No TOC ```````````````````````````````` example none . <p>none</p> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 . <h1>H1</h1> <h2>H2</h2> ```````````````````````````````` ## Simple TOC ```````````````````````````````` example ~~~{toc} ~~~ # H1 ## H2 . <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a></li> </ul> </li> </ul> </details> <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> ```````````````````````````````` ## Invalid Option ```````````````````````````````` example # H1 ## H2 ~~~{toc} :max-level: s ~~~ . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"max-level" option MUST be integer</pre></div> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 ~~~{toc} :max-level: 9 ~~~ . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"max-level" option MUST be <= 3</pre></div> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 ~~~{toc} :min-level: 2 :max-level: 1 ~~~ . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"min-level" option MUST be less than "max-level" option</pre></div> ```````````````````````````````` ## Complex ```````````````````````````````` example # H1 ## H2 ### H3 #### H4 # H1 B # H1 `C` ```{toc} Contents ``` . <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> <h3 id="toc_3">H3</h3> <h4 id="toc_4">H4</h4> <h1 id="toc_5">H1 B</h1> <h1 id="toc_6">H1 <code>C</code></h1> <details class="toc" open> <summary>Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a> <ul> <li><a href="#toc_3">H3</a></li> </ul> </li> </ul> </li> <li><a href="#toc_5">H1 B</a></li> <li><a href="#toc_6">H1 C</a></li> </ul> </details> ```````````````````````````````` ## Insane ```````````````````````````````` example # H1 ### H3 ## H2 #### H4 ### H3 B # H1 B ```{toc} ``` . <h1 id="toc_1">H1</h1> <h3 id="toc_2">H3</h3> <h2 id="toc_3">H2</h2> <h4 id="toc_4">H4</h4> <h3 id="toc_5">H3 B</h3> <h1 id="toc_6">H1 B</h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H3</a></li> <li><a href="#toc_3">H2</a> <ul> <li><a href="#toc_5">H3 B</a></li> </ul> </li> </ul> </li> <li><a href="#toc_6">H1 B</a></li> </ul> </details> ```````````````````````````````` ```````````````````````````````` example ### H3 ## H2 # H1 ```{toc} ``` . <h3 id="toc_1">H3</h3> <h2 id="toc_2">H2</h2> <h1 id="toc_3">H1</h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H3</a></li> <li><a href="#toc_2">H2</a></li> <li><a href="#toc_3">H1</a></li> </ul> </details> ```````````````````````````````` ## Link in Heading ```````````````````````````````` example # [foo](/bar) ```{toc} ``` . <h1 id="toc_1"><a href="/bar">foo</a></h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">foo</a></li> </ul> </details> ```````````````````````````````` ## HTML in Heading ```````````````````````````````` example # <em>H1</em> ```{toc} ``` . <h1 id="toc_1"><em>H1</em></h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a></li> </ul> </details> ```````````````````````````````` ## Collapse TOC ```````````````````````````````` example ```{toc} :collapse: ``` # H1 ## H2 . <details class="toc"> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a></li> </ul> </li> </ul> </details> <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/fix-commonmark.txt�����������������������������������������������������0000664�0000000�0000000�00000003561�14505662126�0021717�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Fix problems that commonmark has. ## Links Links can't contain links. ```````````````````````````````` example [<https://example.com>](/foo) . <p><a href="/foo"><https://example.com></a></p> ```````````````````````````````` ```````````````````````````````` example [<name@example.com>](/foo) . <p><a href="/foo"><name@example.com></a></p> ```````````````````````````````` ## Emphasis `<em>` doesn't contain `<em>`, `<strong>` doesn't contain `<strong>`. ```````````````````````````````` example *_em_* __**strong**__ ______m______ . <p><em>_em_</em> <strong>**strong**</strong> ______m______</p> ```````````````````````````````` ### Non aggressive emphasis ```````````````````````````````` example *a **b c* d** . <p><em>a **b c</em> d**</p> ```````````````````````````````` While CommonMark would render it into: ``` <p><em>a <em><em>b c</em> d</em></em></p> ``` ```````````````````````````````` example *a **b c* d** . <p><em>a **b c</em> d**</p> ```````````````````````````````` While CommonMark would render it into: ``` <p><em>a <em><em>b c</em> d</em></em></p> ``` What if the string is: ```````````````````````````````` example *a **b c* d . <p><em>a **b c</em> d</p> ```````````````````````````````` CommonMark would still be a mess: ``` <p>*a *<em>b c</em> d</p> ``` ## Max depth ```````````````````````````````` example > > > > > > > > b . <blockquote> <blockquote> <blockquote> <blockquote> <blockquote> <blockquote> <p>> > b</p> </blockquote> </blockquote> </blockquote> </blockquote> </blockquote> </blockquote> ```````````````````````````````` ```````````````````````````````` example - a - b - c - d - e - f - g - h . <ul> <li>a<ul> <li>b<ul> <li>c<ul> <li>d<ul> <li>e<ul> <li>f - g - h</li> </ul> </li> </ul> </li> </ul> </li> </ul> </li> </ul> </li> </ul> ```````````````````````````````` �����������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/footnotes.txt����������������������������������������������������������0000664�0000000�0000000�00000001517�14505662126�0021007�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Footnotes ```````````````````````````````` example none [^1] . <p>none [^1]</p> ```````````````````````````````` ```````````````````````````````` example oneline [^1] [^1]: foo . <p>oneline <sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <section class="footnotes"> <ol> <li id="fn-1"><p>foo<a href="#fnref-1" class="footnote">↩</a></p></li> </ol> </section> ```````````````````````````````` ```````````````````````````````` example multiple lines [^1] [^1]: foo one two three four . <p>multiple lines <sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p> <pre><code>four</code></pre> <section class="footnotes"> <ol> <li id="fn-1"><p>foo</p> <p>one</p> <p>two</p> <p>three<a href="#fnref-1" class="footnote">↩</a></p></li> </ol> </section> ```````````````````````````````` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/hook_toc.txt�����������������������������������������������������������0000664�0000000�0000000�00000003550�14505662126�0020573�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Table of Contents ## Simple TOC ```````````````````````````````` example # H1 content ## H2 . <h1 id="toc_1">H1</h1> <p>content</p> <h2 id="toc_2">H2</h2> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a></li> </ul> </li> </ul> ```````````````````````````````` ## Complex TOC ```````````````````````````````` example # H1 ## H2 ### H3 #### H4 # H1 B # H1 `C` . <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> <h3 id="toc_3">H3</h3> <h4>H4</h4> <h1 id="toc_4">H1 B</h1> <h1 id="toc_5">H1 <code>C</code></h1> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a> <ul> <li><a href="#toc_3">H3</a></li> </ul> </li> </ul> </li> <li><a href="#toc_4">H1 B</a></li> <li><a href="#toc_5">H1 C</a></li> </ul> ```````````````````````````````` ## Insane TOC ```````````````````````````````` example # H1 ### H3 ## H2 #### H4 ### H3 B # H1 B . <h1 id="toc_1">H1</h1> <h3 id="toc_2">H3</h3> <h2 id="toc_3">H2</h2> <h4>H4</h4> <h3 id="toc_4">H3 B</h3> <h1 id="toc_5">H1 B</h1> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H3</a></li> <li><a href="#toc_3">H2</a> <ul> <li><a href="#toc_4">H3 B</a></li> </ul> </li> </ul> </li> <li><a href="#toc_5">H1 B</a></li> </ul> ```````````````````````````````` ```````````````````````````````` example ### H3 ## H2 # H1 . <h3 id="toc_1">H3</h3> <h2 id="toc_2">H2</h2> <h1 id="toc_3">H1</h1> <ul> <li><a href="#toc_1">H3</a></li> <li><a href="#toc_2">H2</a></li> <li><a href="#toc_3">H1</a></li> </ul> ```````````````````````````````` ## Link in Heading ```````````````````````````````` example # [foo](/bar) . <h1 id="toc_1"><a href="/bar">foo</a></h1> <ul> <li><a href="#toc_1">foo</a></li> </ul> ```````````````````````````````` ## HTML in Heading ```````````````````````````````` example # <em>H1</em> . <h1 id="toc_1"><em>H1</em></h1> <ul> <li><a href="#toc_1">H1</a></li> </ul> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/include/���������������������������������������������������������������0000775�0000000�0000000�00000000000�14505662126�0017645�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/include/hello.md�������������������������������������������������������0000664�0000000�0000000�00000000010�14505662126�0021261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������> hello ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/include/hello.txt������������������������������������������������������0000664�0000000�0000000�00000000006�14505662126�0021505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������hello ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/include/text.html������������������������������������������������������0000664�0000000�0000000�00000000030�14505662126�0021510�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<div>include html</div> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/include/text.md��������������������������������������������������������0000664�0000000�0000000�00000000243�14505662126�0021152�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Include .. include:: ./text.md .. include:: ./not-exist.md .. include:: ./text.html :encoding: utf-8 .. include:: ./hello.md .. include:: ../rst_toc.txt �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/insert.txt�������������������������������������������������������������0000664�0000000�0000000�00000002215�14505662126�0020267�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Insert ```````````````````````````````` example ^^insert me . <p>^^insert me</p> ```````````````````````````````` ## normal insert ```````````````````````````````` example ^^insert me^^ . <p><ins>insert me</ins></p> ```````````````````````````````` ```````````````````````````````` example foo ^^insert me^^ . <p>foo <ins>insert me</ins></p> ```````````````````````````````` ```````````````````````````````` example ^^insert me^^foo . <p><ins>insert me</ins>foo</p> ```````````````````````````````` ```````````````````````````````` example ^^insert me^^^ . <p>^^insert me^^^</p> ```````````````````````````````` ## escape insert ```````````````````````````````` example ^^insert me\^^^ . <p><ins>insert me^</ins></p> ```````````````````````````````` ```````````````````````````````` example ^^insert \^\^ me^^ . <p><ins>insert ^^ me</ins></p> ```````````````````````````````` ## insert link ```````````````````````````````` example ^^insert [me^^](/) . <p><ins>insert [me</ins>](/)</p> ```````````````````````````````` ```````````````````````````````` example ^^[hello](/)^^ . <p><ins><a href="/">hello</a></ins></p> ```````````````````````````````` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/mark.txt���������������������������������������������������������������0000664�0000000�0000000�00000002162�14505662126�0017716�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Mark ```````````````````````````````` example ==mark me . <p>==mark me</p> ```````````````````````````````` ## normal mark ```````````````````````````````` example ==mark me== . <p><mark>mark me</mark></p> ```````````````````````````````` ```````````````````````````````` example foo ==mark me== . <p>foo <mark>mark me</mark></p> ```````````````````````````````` ```````````````````````````````` example ==mark me==foo . <p><mark>mark me</mark>foo</p> ```````````````````````````````` ```````````````````````````````` example ==mark me=== . <p>==mark me===</p> ```````````````````````````````` ## escape mark ```````````````````````````````` example ==mark me\=== . <p><mark>mark me=</mark></p> ```````````````````````````````` ```````````````````````````````` example ==mark \=\= me== . <p><mark>mark == me</mark></p> ```````````````````````````````` ## mark link ```````````````````````````````` example ==mark [me==](/) . <p><mark>mark [me</mark>](/)</p> ```````````````````````````````` ```````````````````````````````` example ==[hello](/)== . <p><mark><a href="/">hello</a></mark></p> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/math.txt���������������������������������������������������������������0000664�0000000�0000000�00000002226�14505662126�0017716�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Math ## Block Math ```````````````````````````````` example $$ . <p>$$</p> ```````````````````````````````` ```````````````````````````````` example $$ \operatorname{ker} f=\{g\in G:f(g)=e_{H}\}{\mbox{.}} $$ . <div class="math">$$ \operatorname{ker} f=\{g\in G:f(g)=e_{H}\}{\mbox{.}} $$</div> ```````````````````````````````` ```````````````````````````````` example $$ foo $$ bar . <div class="math">$$ foo $$</div> <p>bar</p> ```````````````````````````````` ```````````````````````````````` example $$ foo bar $$ . <div class="math">$$ foo bar $$</div> ```````````````````````````````` ## Inline Math ```````````````````````````````` example The homomorphism $f$ is injective if and only if its kernel is only the singleton set $e_G$, because otherwise $\exists a,b\in G$ with $a\neq b$ such that $f(a)=f(b)$. . <p>The homomorphism <span class="math">\(f\)</span> is injective if and only if its kernel is only the singleton set <span class="math">\(e_G\)</span>, because otherwise <span class="math">\(\exists a,b\in G\)</span> with <span class="math">\(a\neq b\)</span> such that <span class="math">\(f(a)=f(b)\)</span>.</p> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/renderer_markdown.txt��������������������������������������������������0000664�0000000�0000000�00000006650�14505662126�0022502�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# MarkdownRenderer ## inline ```````````````````````````````` example this is _em_, **strong**, and `code` . this is *em*, **strong**, and `code` ```````````````````````````````` ## links ```````````````````````````````` example [link], [link][], [text][link], [link](/foo), [link](/foo "title") [link]: /url . [link][link], [link][link], [text][link], [link](/foo), [link](/foo "title") [link]: /url ```````````````````````````````` ```````````````````````````````` example [link], [link](https://foo(bar "title") [link]: /url "title" . [link][link], [link](<https://foo(bar> "title") [link]: /url "title" ```````````````````````````````` ```````````````````````````````` example [https://lepture.com](https://lepture.com) <https://lepture.com> <demo@example.com> [demo@example.com](mailto:demo@example.com) . <https://lepture.com> <https://lepture.com> <demo@example.com> <demo@example.com> ```````````````````````````````` ## images ```````````````````````````````` example [link]: /url ![link], ![link][], ![alt][link] . ![link][link], ![link][link], ![alt][link] [link]: /url ```````````````````````````````` ## linebreak ```````````````````````````````` example foo\ bar . foo bar ```````````````````````````````` ## html ```````````````````````````````` example inline html <a>text</a> and block html <div>hi</div> . inline html <a>text</a> and block html <div>hi</div> ```````````````````````````````` ## heading ```````````````````````````````` example # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 h1 == . # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 # h1 ```````````````````````````````` ## thematic break ```````````````````````````````` example hi *** . hi *** ```````````````````````````````` ## code ```````````````````````````````` example start def foo(): pass end . start ``` def foo(): pass ``` end ```````````````````````````````` ```````````````````````````````` example start ```py def foo(): pass ``` end . start ```py def foo(): pass ``` end ```````````````````````````````` ```````````````````````````````` example indent code markdown ``` fenced . indent code ~~~ markdown ``` fenced ~~~ ```````````````````````````````` ```````````````````````````````` example indent code markdown ~~~ fenced . indent code ``` markdown ~~~ fenced ``` ```````````````````````````````` ```````````````````````````````` example indent code markdown ``` fenced ~~~ . indent code ```` markdown ``` fenced ~~~ ```` ```````````````````````````````` ## quote ```````````````````````````````` example > quote . > quote ```````````````````````````````` ```````````````````````````````` example hello > quote . hello > quote ```````````````````````````````` ## list ```````````````````````````````` example - list + list . - list + list ```````````````````````````````` ```````````````````````````````` example - item 1 item 2 . - item 1 item 2 ```````````````````````````````` ```````````````````````````````` example - item 1 item 2 - item 3 . - item 1 item 2 - item 3 ```````````````````````````````` ```````````````````````````````` example - item 1 1. item 2 . - item 1 1. item 2 ```````````````````````````````` ```````````````````````````````` example - item 1 2. item 2 . - item 1 2. item 2 ```````````````````````````````` ```````````````````````````````` example - list - . - list - ```````````````````````````````` ����������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/renderer_rst.txt�������������������������������������������������������0000664�0000000�0000000�00000005543�14505662126�0021470�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# RSTRenderer ## inline ```````````````````````````````` example this is _em_, **strong**, and `code` . this is *em*, **strong**, and ``code`` ```````````````````````````````` ```````````````````````````````` example | escape | . \| escape \| ```````````````````````````````` ## links ```````````````````````````````` example this is [link][] and [link](/foo) [link]: /url . this is `link </url>`__ and `link </foo>`__ ```````````````````````````````` ## images ```````````````````````````````` example this is inline ![alt _text_](/foo) . this is inline |img-0| .. |img-0| image:: /foo :alt: alt *text* ```````````````````````````````` ```````````````````````````````` example this is figure ![alt _text_](/foo) . this is figure .. figure:: /foo alt *text* ```````````````````````````````` ```````````````````````````````` example this is figure ![alt _text_](/foo "title") . this is figure .. figure:: /foo :alt: title alt *text* ```````````````````````````````` ## html ```````````````````````````````` example ignore inline html <a>text</a> but show block html <div>hi</div> . ignore inline html text but show block html .. raw:: html <div>hi</div> ```````````````````````````````` ## line break ```````````````````````````````` example hello world . | hello | world ```````````````````````````````` ## heading ```````````````````````````````` example # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 . h1 == h2 -- h3 ~~ h4 ^^ h5 "" h6 '' ```````````````````````````````` ## thematic break ```````````````````````````````` example hi *** . hi -------------- ```````````````````````````````` ## code ```````````````````````````````` example start def foo(): pass end . start :: def foo(): pass end ```````````````````````````````` ```````````````````````````````` example start ```py def foo(): pass ``` end . start .. code:: py def foo(): pass end ```````````````````````````````` ## quote ```````````````````````````````` example > quote . quote ```````````````````````````````` ```````````````````````````````` example hello > quote . hello quote ```````````````````````````````` ```````````````````````````````` example > hello > quote . hello .. quote ```````````````````````````````` ## list ```````````````````````````````` example - list + list . - list + list ```````````````````````````````` ```````````````````````````````` example - item 1 item 2 . - item 1 item 2 ```````````````````````````````` ```````````````````````````````` example - item 1 item 2 - item 3 . - item 1 item 2 - item 3 ```````````````````````````````` ```````````````````````````````` example - item 1 1. item 2 . - item 1 1. item 2 ```````````````````````````````` ```````````````````````````````` example - item 1 1. item 2 . - item 1 1. item 2 ```````````````````````````````` �������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/rst_admonition.txt�����������������������������������������������������0000664�0000000�0000000�00000001520�14505662126�0022012�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Admonition ```````````````````````````````` example .. hello:: Warning message . <div class="error"><pre>.. hello:: Warning message </pre></div> ```````````````````````````````` ```````````````````````````````` example .. note:: Warning message . <section class="admonition note"> <p class="admonition-title">Warning</p> <p>message</p> </section> ```````````````````````````````` Test with code block. ```````````````````````````````` example .. note:: print() . <section class="admonition note"> <p class="admonition-title">Note</p> <pre><code>print()</code></pre> </section> ```````````````````````````````` Test with no message. ```````````````````````````````` example .. note:: Warning . <section class="admonition note"> <p class="admonition-title">Warning</p> </section> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/rst_toc.txt������������������������������������������������������������0000664�0000000�0000000�00000007073�14505662126�0020447�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Table of Contents ## No TOC ```````````````````````````````` example none . <p>none</p> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 . <h1>H1</h1> <h2>H2</h2> ```````````````````````````````` ## Simple TOC ```````````````````````````````` example .. toc:: # H1 ## H2 . <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a></li> </ul> </li> </ul> </details> <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> ```````````````````````````````` ## Invalid Option ```````````````````````````````` example # H1 ## H2 .. toc:: :max-level: s . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"max-level" option MUST be integer</pre></div> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 .. toc:: :max-level: 9 . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"max-level" option MUST be <= 3</pre></div> ```````````````````````````````` ```````````````````````````````` example # H1 ## H2 .. toc:: :min-level: 2 :max-level: 1 . <h1>H1</h1> <h2>H2</h2> <div class="error"><pre>"min-level" option MUST be less than "max-level" option</pre></div> ```````````````````````````````` ## Complex ```````````````````````````````` example # H1 ## H2 ### H3 #### H4 # H1 B # H1 `C` .. toc:: Contents :max-level: 3 . <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> <h3 id="toc_3">H3</h3> <h4 id="toc_4">H4</h4> <h1 id="toc_5">H1 B</h1> <h1 id="toc_6">H1 <code>C</code></h1> <details class="toc" open> <summary>Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a> <ul> <li><a href="#toc_3">H3</a></li> </ul> </li> </ul> </li> <li><a href="#toc_5">H1 B</a></li> <li><a href="#toc_6">H1 C</a></li> </ul> </details> ```````````````````````````````` ## Insane ```````````````````````````````` example # H1 ### H3 ## H2 #### H4 ### H3 B # H1 B .. toc:: . <h1 id="toc_1">H1</h1> <h3 id="toc_2">H3</h3> <h2 id="toc_3">H2</h2> <h4 id="toc_4">H4</h4> <h3 id="toc_5">H3 B</h3> <h1 id="toc_6">H1 B</h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H3</a></li> <li><a href="#toc_3">H2</a> <ul> <li><a href="#toc_5">H3 B</a></li> </ul> </li> </ul> </li> <li><a href="#toc_6">H1 B</a></li> </ul> </details> ```````````````````````````````` ```````````````````````````````` example ### H3 ## H2 # H1 .. toc:: . <h3 id="toc_1">H3</h3> <h2 id="toc_2">H2</h2> <h1 id="toc_3">H1</h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H3</a></li> <li><a href="#toc_2">H2</a></li> <li><a href="#toc_3">H1</a></li> </ul> </details> ```````````````````````````````` ## Link in Heading ```````````````````````````````` example # [foo](/bar) .. toc:: . <h1 id="toc_1"><a href="/bar">foo</a></h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">foo</a></li> </ul> </details> ```````````````````````````````` ## HTML in Heading ```````````````````````````````` example # <em>H1</em> .. toc:: . <h1 id="toc_1"><em>H1</em></h1> <details class="toc" open> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a></li> </ul> </details> ```````````````````````````````` ## Collapse TOC ```````````````````````````````` example .. toc:: :collapse: # H1 ## H2 . <details class="toc"> <summary>Table of Contents</summary> <ul> <li><a href="#toc_1">H1</a> <ul> <li><a href="#toc_2">H2</a></li> </ul> </li> </ul> </details> <h1 id="toc_1">H1</h1> <h2 id="toc_2">H2</h2> ```````````````````````````````` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/ruby.txt���������������������������������������������������������������0000664�0000000�0000000�00000003355�14505662126�0017752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Ruby ## ruby without link ```````````````````````````````` example [漢字(ㄏㄢˋㄗˋ)] . <p><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby></p> ```````````````````````````````` ```````````````````````````````` example [漢(ㄏㄢˋ)字(ㄗˋ)] . <p><ruby><rb>漢</rb><rt>ㄏㄢˋ</rt></ruby><ruby><rb>字</rb><rt>ㄗˋ</rt></ruby></p> ```````````````````````````````` ```````````````````````````````` example [漢字(ㄏㄢˋㄗˋ)][] . <p><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby>[]</p> ```````````````````````````````` ```````````````````````````````` example [漢字(ㄏㄢˋㄗˋ)][link] . <p><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby>[link]</p> ```````````````````````````````` ## ruby with link ```````````````````````````````` example [link]: /url [漢字(ㄏㄢˋㄗˋ)][link] . <p><a href="/url"><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby></a></p> ```````````````````````````````` ```````````````````````````````` example [漢字(ㄏㄢˋㄗˋ)]() . <p><a href=""><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby></a></p> ```````````````````````````````` ```````````````````````````````` example [漢字(ㄏㄢˋㄗˋ)](/url) . <p><a href="/url"><ruby><rb>漢字</rb><rt>ㄏㄢˋㄗˋ</rt></ruby></a></p> ```````````````````````````````` ## ruby splits ```````````````````````````````` example [漢(かん)][字(じ)] . <p><ruby><rb>漢</rb><rt>かん</rt></ruby><ruby><rb>字</rb><rt>じ</rt></ruby></p> ```````````````````````````````` ```````````````````````````````` example [[漢(かん)][字(じ)]](https://jisho.org/search/漢字) . <p><a href="https://jisho.org/search/%E6%BC%A2%E5%AD%97"><ruby><rb>漢</rb><rt>かん</rt></ruby><ruby><rb>字</rb><rt>じ</rt></ruby></a></p> ```````````````````````````````` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/spoiler.txt������������������������������������������������������������0000664�0000000�0000000�00000002202�14505662126�0020434�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Spoiler ## Block spoiler ```````````````````````````````` example >! hi . <div class="spoiler"> <p>hi</p> </div> ```````````````````````````````` ```````````````````````````````` example >! not > spoiler . <blockquote> <p>! not spoiler</p> </blockquote> ```````````````````````````````` ```````````````````````````````` example >! multiple >! lines . <div class="spoiler"> <p>multiple lines</p> </div> ```````````````````````````````` ```````````````````````````````` example >! foo >! >! bar . <div class="spoiler"> <p>foo</p> <p>bar</p> </div> ```````````````````````````````` ```````````````````````````````` example >! foo > >! bar . <blockquote> <p>! foo</p> <p>! bar</p> </blockquote> ```````````````````````````````` ## Inline spoiler ```````````````````````````````` example hi >! hide !< . <p>hi <span class="spoiler">hide</span></p> ```````````````````````````````` ```````````````````````````````` example hi >!hide !< . <p>hi <span class="spoiler">hide</span></p> ```````````````````````````````` ```````````````````````````````` example hi >!hide!< . <p>hi <span class="spoiler">hide</span></p> ```````````````````````````````` ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/strikethrough.txt������������������������������������������������������0000664�0000000�0000000�00000001566�14505662126�0021675�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Strikethrough ## strikethrough ```````````````````````````````` example ~~delete me . <p>~~delete me</p> ```````````````````````````````` ```````````````````````````````` example ~~delete me~~ . <p><del>delete me</del></p> ```````````````````````````````` ```````````````````````````````` example ~~delete me~~~ . <p>~~delete me~~~</p> ```````````````````````````````` ```````````````````````````````` example ~~delete me\~~~ . <p><del>delete me~</del></p> ```````````````````````````````` ```````````````````````````````` example ~~delete \~\~ me~~ . <p><del>delete ~~ me</del></p> ```````````````````````````````` ```````````````````````````````` example ~~delete [me~~](/) . <p><del>delete [me</del>](/)</p> ```````````````````````````````` ```````````````````````````````` example ~~[hello](/)~~ . <p><del><a href="/">hello</a></del></p> ```````````````````````````````` ������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/subscript.txt����������������������������������������������������������0000664�0000000�0000000�00000001011�14505662126�0020772�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Subscript ```````````````````````````````` example CH~3~CH~2~OH . <p>CH<sub>3</sub>CH<sub>2</sub>OH</p> ```````````````````````````````` ```````````````````````````````` example text~a\ subscript~ . <p>text<sub>a subscript</sub></p> ```````````````````````````````` ```````````````````````````````` example text~a subscript~ . <p>text~a subscript~</p> ```````````````````````````````` ```````````````````````````````` example text~a\~subscript~ . <p>text<sub>a~subscript</sub></p> ```````````````````````````````` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/superscript.txt��������������������������������������������������������0000664�0000000�0000000�00000001013�14505662126�0021341�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Superscript ```````````````````````````````` example CH^3^CH^2^OH . <p>CH<sup>3</sup>CH<sup>2</sup>OH</p> ```````````````````````````````` ```````````````````````````````` example text^a\ supscript^ . <p>text<sup>a supscript</sup></p> ```````````````````````````````` ```````````````````````````````` example text^a supscript^ . <p>text^a supscript^</p> ```````````````````````````````` ```````````````````````````````` example text^a\^supscript^ . <p>text<sup>a^supscript</sup></p> ```````````````````````````````` ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/table.txt��������������������������������������������������������������0000664�0000000�0000000�00000010046�14505662126�0020053�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Table in Markdown https://michelf.ca/projects/php-markdown/extra/#table ## nptable ```````````````````````````````` example First Header | Second Header ------------- | ------------- Content Cell | Content Cell Content Cell | Content Cell . <table> <thead> <tr> <th>First Header</th> <th>Second Header</th> </tr> </thead> <tbody> <tr> <td>Content Cell</td> <td>Content Cell</td> </tr> <tr> <td>Content Cell</td> <td>Content Cell</td> </tr> </tbody> </table> ```````````````````````````````` ## table ```````````````````````````````` example | First Header | Second Header | | ------------- | ------------- | | Content Cell | | | Content Cell | Content Cell | . <table> <thead> <tr> <th>First Header</th> <th>Second Header</th> </tr> </thead> <tbody> <tr> <td>Content Cell</td> <td></td> </tr> <tr> <td>Content Cell</td> <td>Content Cell</td> </tr> </tbody> </table> ```````````````````````````````` ```````````````````````````````` example | Command | Description | | --- | --- | | git status | List all new or modified files | | git diff | Show file differences that haven't been staged | . <table> <thead> <tr> <th>Command</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td>git status</td> <td>List all new or modified files</td> </tr> <tr> <td>git diff</td> <td>Show file differences that haven't been staged</td> </tr> </tbody> </table> ```````````````````````````````` ## align table ```````````````````````````````` example Left | Center | Right :---- | :--------: | ------: a | b | c . <table> <thead> <tr> <th style="text-align:left">Left</th> <th style="text-align:center">Center</th> <th style="text-align:right">Right</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">a</td> <td style="text-align:center">b</td> <td style="text-align:right">c</td> </tr> </tbody> </table> ```````````````````````````````` ```````````````````````````````` example | Left | Center | Right | | :--- | :----: | ----: | | a | b | c | . <table> <thead> <tr> <th style="text-align:left">Left</th> <th style="text-align:center">Center</th> <th style="text-align:right">Right</th> </tr> </thead> <tbody> <tr> <td style="text-align:left">a</td> <td style="text-align:center">b</td> <td style="text-align:right">c</td> </tr> </tbody> </table> ```````````````````````````````` ## Misc Table ```````````````````````````````` example | A | | | - | | | a | b | . <table> <thead> <tr> <th>A</th> <th></th> </tr> </thead> <tbody> <tr> <td>a</td> <td>b</td> </tr> </tbody> </table> ```````````````````````````````` ```````````````````````````````` example A | - | a | b . <table> <thead> <tr> <th>A</th> <th></th> </tr> </thead> <tbody> <tr> <td>a</td> <td>b</td> </tr> </tbody> </table> ```````````````````````````````` ```````````````````````````````` example | Foo | Bar | |-----|-----| | boo | baz | | faz | | . <table> <thead> <tr> <th>Foo</th> <th>Bar</th> </tr> </thead> <tbody> <tr> <td>boo</td> <td>baz</td> </tr> <tr> <td>faz</td> <td></td> </tr> </tbody> </table> ```````````````````````````````` ## Mismatch length ```````````````````````````````` example | First Header | | ------------- | ------------- | | Content Cell | | | Content Cell | Content Cell | . <p>| First Header | | ------------- | ------------- | | Content Cell | | | Content Cell | Content Cell |</p> ```````````````````````````````` ```````````````````````````````` example | First Header | Second Header | | ------------- | ------------- | | Content Cell | | Content Cell | Content Cell | . <p>| First Header | Second Header | | ------------- | ------------- | | Content Cell | | Content Cell | Content Cell |</p> ```````````````````````````````` ```````````````````````````````` example A | - | - | a | b | c . <p>A |</p> <ul> <li>| - | a | b | c</li> </ul> ```````````````````````````````` ```````````````````````````````` example A | B | C - | - | - a | b . <p>A | B | C</p> <ul> <li>| - | - a | b</li> </ul> ```````````````````````````````` ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/task_lists.txt���������������������������������������������������������0000664�0000000�0000000�00000006040�14505662126�0021143�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Task Lists ```````````````````````````````` example - [ ] foo - [x] bar - [X] baz . <ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>foo</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>bar</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>baz</li> </ul> ```````````````````````````````` ```````````````````````````````` example - foo - [ ] bar . <ul> <li>foo</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>bar</li> </ul> ```````````````````````````````` ```````````````````````````````` example - foo - [ ] bar - [x] baz text . <ul> <li><p>foo</p> </li> <li class="task-list-item"><p><input class="task-list-item-checkbox" type="checkbox" disabled/>bar</p> </li> <li class="task-list-item"><p><input class="task-list-item-checkbox" type="checkbox" disabled checked/>baz</p> <p>text</p> </li> </ul> ```````````````````````````````` ```````````````````````````````` example 1. [ ] foo 2. [x] bar 3. [X] baz . <ol> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>foo</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>bar</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>baz</li> </ol> ```````````````````````````````` ```````````````````````````````` example - [ ] Task list item over two lines . <ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>Task list item over two lines</li> </ul> ```````````````````````````````` ```````````````````````````````` example - [ ] foo - [x] bar - [ ] baz . <ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>foo<ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>bar</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>baz</li> </ul> </li> </ul> ```````````````````````````````` ```````````````````````````````` example 1. [ ] foo 1. [ ] bar 2. [ ] baz . <ol> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>foo<ol> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>bar</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>baz</li> </ol> </li> </ol> ```````````````````````````````` ```````````````````````````````` example > - [ ] foo > - [x] bar > - [ ] baz . <blockquote> <ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>foo<ul> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled checked/>bar</li> <li class="task-list-item"><input class="task-list-item-checkbox" type="checkbox" disabled/>baz</li> </ul> </li> </ul> </blockquote> ````````````````````````````````������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/fixtures/url.txt����������������������������������������������������������������0000664�0000000�0000000�00000001022�14505662126�0017560�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# url plugin ```````````````````````````````` example visit https://lepture.com/ . <p>visit <a href="https://lepture.com/">https://lepture.com/</a></p> ```````````````````````````````` ```````````````````````````````` example visit [https://lepture.com/](/foo) . <p>visit <a href="/foo">https://lepture.com/</a></p> ```````````````````````````````` ```````````````````````````````` example visit <a href="/foo">https://lepture.com/</a> . <p>visit <a href="/foo">https://lepture.com/</a></p> ```````````````````````````````` ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_commonmark.py��������������������������������������������������������������0000664�0000000�0000000�00000004227�14505662126�0020132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import mistune from tests import BaseTestCase, normalize_html DIFF_CASES = { 'setext_headings_093', 'html_blocks_191', # mistune keeps \n 'images_573', # image can not be in image 'links_495', 'links_517', # aggressive link group 'links_518', 'links_519', 'links_531', 'links_532', } IGNORE_CASES = { # we don't support link title in (title) 'links_496', 'links_504', # we don't support flanking delimiter run 'emphasis_and_strong_emphasis_352', 'emphasis_and_strong_emphasis_367', 'emphasis_and_strong_emphasis_368', 'emphasis_and_strong_emphasis_372', 'emphasis_and_strong_emphasis_379', 'emphasis_and_strong_emphasis_388', 'emphasis_and_strong_emphasis_391', 'emphasis_and_strong_emphasis_406', 'emphasis_and_strong_emphasis_407', 'emphasis_and_strong_emphasis_408', 'emphasis_and_strong_emphasis_412', 'emphasis_and_strong_emphasis_413', 'emphasis_and_strong_emphasis_414', 'emphasis_and_strong_emphasis_416', 'emphasis_and_strong_emphasis_417', 'emphasis_and_strong_emphasis_418', 'emphasis_and_strong_emphasis_424', 'emphasis_and_strong_emphasis_425', 'emphasis_and_strong_emphasis_426', 'emphasis_and_strong_emphasis_429', 'emphasis_and_strong_emphasis_430', 'emphasis_and_strong_emphasis_431', 'emphasis_and_strong_emphasis_460', 'emphasis_and_strong_emphasis_467', 'emphasis_and_strong_emphasis_470', 'emphasis_and_strong_emphasis_471', 'emphasis_and_strong_emphasis_477', 'emphasis_and_strong_emphasis_478', } for i in range(441, 447): IGNORE_CASES.add('emphasis_and_strong_emphasis_' + str(i)) for i in range(453, 459): IGNORE_CASES.add('emphasis_and_strong_emphasis_' + str(i)) for i in range(462, 466): IGNORE_CASES.add('emphasis_and_strong_emphasis_' + str(i)) class TestCommonMark(BaseTestCase): @classmethod def ignore_case(cls, n): return n in IGNORE_CASES or n in DIFF_CASES def assert_case(self, n, text, html): result = mistune.html(text) self.assertEqual(normalize_html(result), normalize_html(html)) TestCommonMark.load_fixtures('commonmark.json') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_directives.py��������������������������������������������������������������0000664�0000000�0000000�00000005557�14505662126�0020137�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os from mistune import create_markdown from mistune.directives import ( RSTDirective, FencedDirective, Admonition, TableOfContents, Include, Image, Figure, ) from tests import BaseTestCase from tests.fixtures import ROOT def load_directive_test(filename, directive, cls): class TestDirective(BaseTestCase): @staticmethod def parse(text): md = create_markdown( escape=False, plugins=[cls([directive])], ) html = md(text) return html TestDirective.load_fixtures(filename + '.txt') globals()["TestDirective_" + filename] = TestDirective load_directive_test('rst_admonition', Admonition(), RSTDirective) load_directive_test('rst_toc', TableOfContents(), RSTDirective) load_directive_test('fenced_admonition', Admonition(), FencedDirective) load_directive_test('fenced_toc', TableOfContents(), FencedDirective) load_directive_test('fenced_image', Image(), FencedDirective) load_directive_test('fenced_figure', Figure(), FencedDirective) class CustomizeTableOfContents(TableOfContents): def generate_heading_id(self, token, i): return 't-' + str(i + 1) class TestCustomizeToc(BaseTestCase): def test_rst_toc(self): md = create_markdown( escape=False, plugins=[ RSTDirective([CustomizeTableOfContents()]), ], ) html = md('# h1\n\n.. toc::\n') self.assertIn('<h1 id="t-1">h1</h1>', html) self.assertIn('<a href="#t-1">h1</a>', html) def test_fenced_toc(self): md = create_markdown( escape=False, plugins=[ FencedDirective([CustomizeTableOfContents()]), ], ) html = md('# h1\n\n```{toc}\n```\n') self.assertIn('<h1 id="t-1">h1</h1>', html) self.assertIn('<a href="#t-1">h1</a>', html) def test_colon_fenced_toc(self): md = create_markdown( escape=False, plugins=[ FencedDirective([CustomizeTableOfContents()], ':'), ], ) html = md('# h1\n\n:::{toc}\n:::\n') self.assertIn('<h1 id="t-1">h1</h1>', html) self.assertIn('<a href="#t-1">h1</a>', html) class TestDirectiveInclude(BaseTestCase): md = create_markdown(escape=False, plugins=[RSTDirective([Include()])]) def test_html_include(self): html = self.md.read(os.path.join(ROOT, 'include/text.md'))[0] self.assertIn('Could not include self', html) self.assertIn('Could not find file', html) self.assertIn('<div>include html</div>', html) self.assertIn('<blockquote>', html) self.assertIn('# Table of Contents', html) def test_include_missing_source(self): s = '.. include:: foo.txt' html = self.md(s) self.assertIn('Missing source file', html) �������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_hooks.py�������������������������������������������������������������������0000664�0000000�0000000�00000001331�14505662126�0017103�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os from mistune import create_markdown from mistune.toc import add_toc_hook, render_toc_ul from tests import BaseTestCase class TestTocHook(BaseTestCase): @staticmethod def parse(text): md = create_markdown(escape=False) add_toc_hook(md) html, state = md.parse(text) result = html + render_toc_ul(state.env['toc_items']) return result def test_customize_heading_id_func(self): def heading_id(token, i): return 't-' + str(i + 1) md = create_markdown(escape=False) add_toc_hook(md, heading_id=heading_id) html = md('# h1') self.assertEqual(html, '<h1 id="t-1">h1</h1>\n') TestTocHook.load_fixtures('hook_toc.txt') �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_misc.py��������������������������������������������������������������������0000664�0000000�0000000�00000007163�14505662126�0016724�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import mistune from unittest import TestCase class TestMiscCases(TestCase): def test_none(self): self.assertEqual(mistune.html(None), '') def test_before_parse_hooks(self): def _add_name(md, state): state.env['name'] = 'test' md = mistune.create_markdown() md.before_parse_hooks.append(_add_name) state = md.block.state_cls() md.parse('', state) self.assertEqual(state.env['name'], 'test') def test_hard_wrap(self): md = mistune.create_markdown(escape=False, hard_wrap=True) result = md('foo\nbar') expected = '<p>foo<br />\nbar</p>' self.assertEqual(result.strip(), expected) md = mistune.create_markdown( escape=False, hard_wrap=True, plugins=['speedup']) result = md('foo\nbar') self.assertEqual(result.strip(), expected) def test_escape_html(self): md = mistune.create_markdown(escape=True) result = md('<div>1</div>') expected = '<p><div>1</div></p>' self.assertEqual(result.strip(), expected) result = md('<em>1</em>') expected = '<p><em>1</em></p>' self.assertEqual(result.strip(), expected) def test_harmful_links(self): result = mistune.html('[h](javAscript:alert)') expected = '<p><a href="#harmful-link">h</a></p>' self.assertEqual(result.strip(), expected) def test_ref_link(self): result = mistune.html('[link][h]\n\n[h]: /foo') expected = '<p><a href="/foo">link</a></p>' self.assertEqual(result.strip(), expected) def test_allow_harmful_protocols(self): renderer = mistune.HTMLRenderer(allow_harmful_protocols=True) md = mistune.Markdown(renderer) result = md('[h](javascript:alert)') expected = '<p><a href="javascript:alert">h</a></p>' self.assertEqual(result.strip(), expected) def test_allow_data_protocols(self): renderer = mistune.HTMLRenderer(allow_harmful_protocols=['data:']) md = mistune.Markdown(renderer) result = md('[h](data:alert)') expected = '<p><a href="data:alert">h</a></p>' self.assertEqual(result.strip(), expected) def test_use_plugin(self): from mistune.plugins.url import url md = mistune.Markdown(mistune.HTMLRenderer()) md.use(url) def test_markdown_func(self): result = mistune.markdown('**b**') expected = '<p><strong>b</strong></p>\n' self.assertEqual(result, expected) # trigger to use cached parser result = mistune.markdown('**b**') self.assertEqual(result, expected) def test_ast_output(self): md = mistune.create_markdown(escape=False, renderer=None) text = '# h1\n\nfoo **bar**' result = md(text) expected = [ { 'type': 'heading', 'children': [{'type': 'text', 'raw': 'h1'}], 'attrs': {'level': 1}, 'style': 'axt', }, {'type': 'blank_line'}, { 'type': 'paragraph', 'children': [ {'type': 'text', 'raw': 'foo '}, {'type': 'strong', 'children': [{'type': 'text', 'raw': 'bar'}]} ] }, ] self.assertEqual(result, expected) def test_emsp(self): md = mistune.create_markdown(escape=False, hard_wrap=True) result = md('\u2003\u2003foo\nbar\n\n\u2003\u2003foobar') expected = '<p>\u2003\u2003foo<br />\nbar</p>\n<p>\u2003\u2003foobar</p>' self.assertEqual(result.strip(), expected) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_plugins.py�����������������������������������������������������������������0000664�0000000�0000000�00000004350�14505662126�0017445�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from mistune import create_markdown from mistune.plugins.table import table_in_list, table_in_quote from mistune.plugins.math import math_in_list, math_in_quote from tests import BaseTestCase def load_plugin(plugin_name): md1 = create_markdown(escape=False, plugins=[plugin_name]) md2 = create_markdown(escape=False, plugins=[plugin_name, 'speedup']) class TestPlugin1(BaseTestCase): parse = md1 class TestPlugin2(BaseTestCase): parse = md2 TestPlugin1.load_fixtures(plugin_name + ".txt") TestPlugin2.load_fixtures(plugin_name + ".txt") globals()["TestPlugin1_" + plugin_name] = TestPlugin1 globals()["TestPlugin2_" + plugin_name] = TestPlugin2 load_plugin("url") load_plugin("strikethrough") load_plugin("mark") load_plugin("insert") load_plugin("superscript") load_plugin("subscript") load_plugin("task_lists") load_plugin("table") load_plugin("def_list") load_plugin("footnotes") load_plugin("abbr") load_plugin("math") load_plugin("ruby") load_plugin("spoiler") class TestExtraPlugins(BaseTestCase): def test_table_in_list(self): text = '''- Cell | Cell\n ---- | ----\n 1 | 2\n''' md1 = create_markdown(escape=False) md2 = create_markdown(escape=False, plugins=['table', table_in_list]) self.assertNotIn('<table>', md1(text)) self.assertIn('<table>', md2(text)) def test_table_in_quote(self): text = '''> Cell | Cell\n> ---- | ----\n> 1 | 2\n''' md1 = create_markdown(escape=False) md2 = create_markdown(escape=False, plugins=['table', table_in_quote]) self.assertNotIn('<table>', md1(text)) self.assertIn('<table>', md2(text)) def test_math_in_list(self): text = '''- $$\n foo\n $$\n''' md1 = create_markdown(escape=False) md2 = create_markdown(escape=False, plugins=['math', math_in_list]) self.assertNotIn('class="math"', md1(text)) self.assertIn('class="math"', md2(text)) def test_math_in_quote(self): text = '''> $$\n> foo\n> $$\n''' md1 = create_markdown(escape=False) md2 = create_markdown(escape=False, plugins=['math', math_in_quote]) self.assertNotIn('class="math"', md1(text)) self.assertIn('class="math"', md2(text)) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mistune-3.0.2/tests/test_renderers.py���������������������������������������������������������������0000664�0000000�0000000�00000000764�14505662126�0017762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from mistune import create_markdown from mistune.renderers.rst import RSTRenderer from mistune.renderers.markdown import MarkdownRenderer from tests import BaseTestCase def load_renderer(renderer): class TestRenderer(BaseTestCase): parse = create_markdown(renderer=renderer) name = renderer.NAME TestRenderer.load_fixtures('renderer_' + name + '.txt') globals()["TestRenderer" + name.title()] = TestRenderer load_renderer(RSTRenderer()) load_renderer(MarkdownRenderer()) ������������mistune-3.0.2/tests/test_syntax.py������������������������������������������������������������������0000664�0000000�0000000�00000000526�14505662126�0017313�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import mistune from tests import BaseTestCase, normalize_html class TestSyntax(BaseTestCase): def assert_case(self, n, text, html): result = mistune.html(text) self.assertEqual(normalize_html(result), normalize_html(html)) TestSyntax.load_fixtures('fix-commonmark.txt') TestSyntax.load_fixtures('diff-commonmark.txt') ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������