pax_global_header00006660000000000000000000000064146676547330014537gustar00rootroot0000000000000052 comment=2236898619148b33c51bae3c1aca380618c82db7 mdit-py-plugins-0.4.2/000077500000000000000000000000001466765473300146045ustar00rootroot00000000000000mdit-py-plugins-0.4.2/.coveragerc000066400000000000000000000001041466765473300167200ustar00rootroot00000000000000[report] exclude_lines = pragma: no cover if TYPE_CHECKING: mdit-py-plugins-0.4.2/.github/000077500000000000000000000000001466765473300161445ustar00rootroot00000000000000mdit-py-plugins-0.4.2/.github/dependabot.yml000066400000000000000000000011261466765473300207740ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: github-actions directory: / commit-message: prefix: ⬆️ schedule: interval: weekly - package-ecosystem: pip directory: / commit-message: prefix: ⬆️ schedule: interval: weekly mdit-py-plugins-0.4.2/.github/workflows/000077500000000000000000000000001466765473300202015ustar00rootroot00000000000000mdit-py-plugins-0.4.2/.github/workflows/tests.yml000066400000000000000000000042211466765473300220650ustar00rootroot00000000000000# This workflow will install Python dependencies, run tests and lint with a variety of Python versions # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions name: continuous-integration on: push: branches: [master] tags: - 'v*' pull_request: jobs: pre-commit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.8 uses: actions/setup-python@v5 with: python-version: 3.8 - uses: pre-commit/action@v3.0.1 tests: runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ['pypy-3.8', '3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install -e .[testing] - name: Run pytest run: | pytest --cov=mdit_py_plugins --cov-report=xml --cov-report=term-missing - name: Upload to Codecov uses: codecov/codecov-action@v3 if: github.event.pull_request.head.repo.full_name == github.repository with: token: ${{ secrets.CODECOV_TOKEN }} name: mdit-py-plugins-pytests flags: pytests file: ./coverage.xml fail_ci_if_error: true allgood: runs-on: ubuntu-latest needs: - pre-commit - tests steps: - run: echo "Great success!" publish: name: Publish to PyPi needs: [pre-commit, tests] if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.8" - name: install flit run: | pip install flit~=3.4 - name: Build and publish run: | flit publish env: FLIT_USERNAME: __token__ FLIT_PASSWORD: ${{ secrets.PYPI_KEY }} mdit-py-plugins-0.4.2/.gitignore000066400000000000000000000036121466765473300165760ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ benchmark/extra/ node_modules/ coverage/ demo/ apidoc/ *.log __pycache__/ .ropeproject/ *.egg-info/ .vscode/ .DS_Store docs/api/ mdit-py-plugins-0.4.2/.pre-commit-config.yaml000066400000000000000000000012441466765473300210660ustar00rootroot00000000000000# Install pre-commit hooks via # pre-commit install exclude: > (?x)^( \.vscode/settings\.json| test.*\.md| test.*\.txt| test.*\.html| )$ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: - id: check-json - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.4.4 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.10.0 hooks: - id: mypy additional_dependencies: [markdown-it-py~=3.0] exclude: ^tests/ mdit-py-plugins-0.4.2/.readthedocs.yml000066400000000000000000000003001466765473300176630ustar00rootroot00000000000000version: 2 build: os: ubuntu-22.04 tools: python: "3.8" python: install: - method: pip path: . extra_requirements: [rtd] sphinx: builder: html fail_on_warning: true mdit-py-plugins-0.4.2/CHANGELOG.md000066400000000000000000000135521466765473300164230ustar00rootroot00000000000000# Change Log ## 0.4.2 - 2024-09-09 - πŸ‘Œ Improve parsing of nested amsmath The previous logic was problematic for amsmath blocks nested in other blocs (such as blockquotes) The new parsing code now principally follows the logic in `markdown_it/rules_block/fence.py` (see also ), except that: 1. it allows for a closing tag on the same line as the opening tag, and 2. it does not allow for an opening tag without closing tag (i.e. no auto-closing) - ✨ Add `allowed` option for inline/block attributes The `allowed` option accepts a list of allowed attribute names. If not ``None``, any attributes not in this list will be removed and placed in the token's meta under the key `"insecure_attrs"`. ## 0.4.1 - 2024-05-12 * πŸ‘Œ Add option for footnotes references to always be matched Usually footnote references are only matched when a footnote definition of the same label has already been found. If `always_match_refs=True`, any `[^...]` syntax will be treated as a footnote. ## 0.4.0 - 2023-06-05 * ⬆️ UPGRADE: Drop python 3.7 and support 3.11 ([#77](https://github.com/executablebooks/mdit-py-plugins/pull/77)) * ⬆️ UPGRADE: Allow markdown-it-py v3 ([#85](https://github.com/executablebooks/mdit-py-plugins/pull/85)) * πŸ‘Œ Make field_list compatible with latest upstream ([#75](https://github.com/executablebooks/mdit-py-plugins/pull/75)) * πŸ”§ Convert `state.srcCharCode` -> `state.src` ([#84](https://github.com/executablebooks/mdit-py-plugins/pull/84)) * πŸ”§ Remove unnecessary method arg by @chrisjsewell in( [#76](https://github.com/executablebooks/mdit-py-plugins/pull/76)) * πŸ‘Œ Centralise code block test ([#83](https://github.com/executablebooks/mdit-py-plugins/pull/83) and [#87](https://github.com/executablebooks/mdit-py-plugins/pull/87)) * This means that disabling the `code` block rule in markdown-it-py v3+ will now allow all syntax blocks to be indented by any amount of whitespace. * πŸ‘Œ Improve `dollarmath` plugin: Add `allow_blank_lines` option, thanks to [@eric-wieser](https://github.com/eric-wieser) ([#46](https://github.com/executablebooks/mdit-py-plugins/pull/46)) * πŸ‘Œ Improve `admon` plugin: Add `???` support, thanks to [@KyleKing](https://github.com/KyleKing) ([#58](https://github.com/executablebooks/mdit-py-plugins/pull/58)) * πŸ”§ MAINTAIN: Make type checking strict ([#86](https://github.com/executablebooks/mdit-py-plugins/pull/86)) **Full Changelog**: ## 0.3.5 - 2023-03-02 - πŸ› FIX: Regression in dollarmath by @chrisjsewell in [#69](https://github.com/executablebooks/mdit-py-plugins/pull/69) - πŸ› Fix regression in amsmath by @chrisjsewell in [#70](https://github.com/executablebooks/mdit-py-plugins/pull/70) - πŸ”§ Correct project documentation link by @andersk in [#73](https://github.com/executablebooks/mdit-py-plugins/pull/73) ## 0.3.4 - 2023-02-18 - ✨ NEW: Add attrs_block_plugin by @chrisjsewell in [#66](https://github.com/executablebooks/mdit-py-plugins/pull/66) - πŸ‘Œ Improve field lists by @chrisjsewell in [#65](https://github.com/executablebooks/mdit-py-plugins/pull/65) - πŸ”§ Update pre-commit by @chrisjsewell in [#64](https://github.com/executablebooks/mdit-py-plugins/pull/64) (moving from flake8 to ruff) **Full Changelog**: [v0.3.3...v0.3.](https://github.com/executablebooks/mdit-py-plugins/compare/v0.3.3...v0.3.4) ## 0.3.3 - 2022-12-06 πŸ› FIX: span with end of inline before attrs ## 0.3.2 - 2022-12-05 - ✨ NEW: Port `admon` plugin by @KyleKing ([#53](https://github.com/executablebooks/mdit-py-plugins/pull/53)) - ✨ NEW: Add span parsing to inline attributes plugin by @chrisjsewell ([#55](https://github.com/executablebooks/mdit-py-plugins/pull/55)) - πŸ› FIX: Task list item marker can be followed by any GFM whitespace by @hukkin in ([#42](https://github.com/executablebooks/mdit-py-plugins/pull/42)) **Full Changelog**: [v0.3.1...v0.4.0](https://github.com/executablebooks/mdit-py-plugins/compare/v0.3.1...v0.4.0) ## 0.3.1 - 2022-09-27 - ⬆️ UPGRADE: Drop Python 3.6, support Python 3.10 - πŸ› FIX: Parsing when newline is between footnote ID and first paragraph - πŸ› FIX: Anchor ids in separate renders no longer affect each other. - ✨ NEW: Add `attrs_plugin` - πŸ”§ MAINTAIN: Use flit PEP 621 package build ## 0.3.0 - 2021-12-03 - ⬆️ UPGRADE: Compatible with markdown-it-py `v2`. - ✨ NEW: Add field list plugin, Based on the [restructuredtext syntax](https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#field-lists) - ♻️ REFACTOR: dollarmath plugin, `math_block_eqno` -> `math_block_label` token - ♻️ REFACTOR: Remove AttrDict usage from texmath - πŸ‘Œ IMPROVE: Default HTML rendering for dollarmath and amsmath plugins - πŸ‘Œ IMPROVE: Add render options for dollarmath and amsmath plugins - πŸ‘Œ IMPROVE: MyST parsing of target blocks (allow whitespace) and roles (allow for new lines) ## 0.2.8 - 2021-05-03 πŸ› FIX: `wordcount` update of minutes ## 0.2.7 - 2021-05-03 - ⬆️ UPDATE: markdown-it-py~=1.0 - ✨ NEW: Add `wordcount_plugin` - πŸ‘Œ IMPROVE: `dollarmath`: Allow inline double-dollar - πŸ‘Œ IMPROVE: `myst_blocks`: Parse multiline comments - πŸ‘Œ IMPROVE: Replace use of `env` as an `AttrDict` - πŸ› FIX: `front_matter`: don't duplicate content storage in `Token.meta` ## 0.2.6 - 2021-03-17 πŸ‘Œ IMPROVE: Remove direct use of `Token.attrs` ## 0.2.5 - 2021-02-06 πŸ› FIX: front-matter: `IndexError` if first line is single dash ## 0.2.2 - 2020-12-16 ✨ NEW: Add substitution_plugin (improvements in 0.2.3 and 0.2.4) ## 0.2.0 - 2020-12-14 Add mypy type-checking, code taken from: https://github.com/executablebooks/markdown-it-py/commit/2eb1fe6b47cc0ad4ebe954cabd91fb8e52a2f03d ## 0.1.0 - 2020-12-14 First release, code taken from: https://github.com/executablebooks/markdown-it-py/commit/3a5bdcc98e67de9df26ebb8bc7cd0221a0d6b51b mdit-py-plugins-0.4.2/LICENSE000066400000000000000000000020661466765473300156150ustar00rootroot00000000000000MIT License Copyright (c) 2020 ExecutableBookProject Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. mdit-py-plugins-0.4.2/README.md000066400000000000000000000022621466765473300160650ustar00rootroot00000000000000# mdit-py-plugins [![Github-CI][github-ci]][github-link] [![Coverage Status][codecov-badge]][codecov-link] [![PyPI][pypi-badge]][pypi-link] [![Conda][conda-badge]][conda-link] [![Code style: black][black-badge]][black-link] Collection of core plugins for [markdown-it-py](https://github.com/executablebooks/markdown-it-py). [github-ci]: https://github.com/executablebooks/mdit-py-plugins/workflows/continuous-integration/badge.svg [github-link]: https://github.com/executablebooks/mdit-py-plugins [pypi-badge]: https://img.shields.io/pypi/v/mdit-py-plugins.svg [pypi-link]: https://pypi.org/project/mdit-py-plugins [conda-badge]: https://anaconda.org/conda-forge/mdit-py-plugins/badges/version.svg [conda-link]: https://anaconda.org/conda-forge/mdit-py-plugins [codecov-badge]: https://codecov.io/gh/executablebooks/mdit-py-plugins/branch/master/graph/badge.svg [codecov-link]: https://codecov.io/gh/executablebooks/mdit-py-plugins [black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg [black-link]: https://github.com/ambv/black [install-badge]: https://img.shields.io/pypi/dw/mdit-py-plugins?label=pypi%20installs [install-link]: https://pypistats.org/packages/mdit-py-plugins mdit-py-plugins-0.4.2/codecov.yml000066400000000000000000000002421466765473300167470ustar00rootroot00000000000000coverage: status: project: default: target: 92% threshold: 0.2% patch: default: target: 80% threshold: 0.2% mdit-py-plugins-0.4.2/docs/000077500000000000000000000000001466765473300155345ustar00rootroot00000000000000mdit-py-plugins-0.4.2/docs/conf.py000066400000000000000000000013271466765473300170360ustar00rootroot00000000000000project = "mdit-py-plugins" copyright = "2020, Executable Book Project" author = "Executable Book Project" master_doc = "index" extensions = [ "sphinx.ext.autodoc", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", "myst_parser", ] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] intersphinx_mapping = { "python": ("https://docs.python.org/3.8", None), "markdown_it": ("https://markdown-it-py.readthedocs.io/en/latest", None), } html_title = "mdit-py-plugins" html_theme = "sphinx_book_theme" html_theme_options = { "use_edit_page_button": True, "repository_url": "https://github.com/executablebooks/mdit-py-plugins", "repository_branch": "master", "path_to_docs": "docs", } mdit-py-plugins-0.4.2/docs/index.md000066400000000000000000000062741466765473300171760ustar00rootroot00000000000000# Markdown-It-Py Plugin Extensions ## Built-in The following plugins are embedded within the core package: - [tables](https://help.github.com/articles/organizing-information-with-tables/) (GFM) - [strikethrough](https://help.github.com/articles/basic-writing-and-formatting-syntax/#styling-text) (GFM) These can be enabled individually: ```python from markdown_it import MarkdownIt md = MarkdownIt("commonmark").enable('table') ``` or as part of a configuration: ```python from markdown_it import MarkdownIt md = MarkdownIt("gfm-like") ``` ```{seealso} See ``` ## mdit-py-plugins package The [`mdit_py_plugins`](https://github.com/executablebooks/mdit-py-plugins), contains a number of common plugins. They can be chained and loaded *via*: ```python from markdown_it import MarkdownIt from mdit_py_plugins import plugin1, plugin2 md = MarkdownIt().use(plugin1, keyword=value).use(plugin2, keyword=value) html_string = md.render("some *Markdown*") ``` ## Front-Matter ```{eval-rst} .. autofunction:: mdit_py_plugins.front_matter.front_matter_plugin ``` ## Footnotes ```{eval-rst} .. autofunction:: mdit_py_plugins.footnote.footnote_plugin ``` ## Definition Lists ```{eval-rst} .. autofunction:: mdit_py_plugins.deflist.deflist_plugin ``` ## Task lists ```{eval-rst} .. autofunction:: mdit_py_plugins.tasklists.tasklists_plugin ``` ## Field Lists ```{eval-rst} .. autofunction:: mdit_py_plugins.field_list.fieldlist_plugin ``` ## Heading Anchors ```{eval-rst} .. autofunction:: mdit_py_plugins.anchors.anchors_plugin ``` ## Word Count ```{eval-rst} .. autofunction:: mdit_py_plugins.wordcount.wordcount_plugin ``` ## Containers ```{eval-rst} .. autofunction:: mdit_py_plugins.container.container_plugin ``` ```{eval-rst} .. autofunction:: mdit_py_plugins.admon.admon_plugin ``` ## Attributes ```{eval-rst} .. autofunction:: mdit_py_plugins.attrs.attrs_plugin ``` ```{eval-rst} .. autofunction:: mdit_py_plugins.attrs.attrs_block_plugin ``` ## Math ```{eval-rst} .. autofunction:: mdit_py_plugins.texmath.texmath_plugin ``` ```{eval-rst} .. autofunction:: mdit_py_plugins.dollarmath.dollarmath_plugin ``` ```{eval-rst} .. autofunction:: mdit_py_plugins.amsmath.amsmath_plugin ``` ## MyST plugins `myst_blocks` and `myst_role` plugins are also available, for utilisation by the [MyST renderer](https://myst-parser.readthedocs.io/en/latest/using/syntax.html) ```{eval-rst} .. autofunction:: mdit_py_plugins.myst_role.myst_role_plugin .. autofunction:: mdit_py_plugins.myst_blocks.myst_block_plugin ``` ## Write your own Use the `mdit_py_plugins` as a guide to write your own, following the [markdown-it design principles](inv:markdown_it#architecture). There are many other plugins which could easily be ported from the JS versions (and hopefully will): - [subscript](https://github.com/markdown-it/markdown-it-sub) - [superscript](https://github.com/markdown-it/markdown-it-sup) - [abbreviation](https://github.com/markdown-it/markdown-it-abbr) - [emoji](https://github.com/markdown-it/markdown-it-emoji) - [insert](https://github.com/markdown-it/markdown-it-ins) - [mark](https://github.com/markdown-it/markdown-it-mark) - ... and [others](https://www.npmjs.org/browse/keyword/markdown-it-plugin) mdit-py-plugins-0.4.2/mdit_py_plugins/000077500000000000000000000000001466765473300200125ustar00rootroot00000000000000mdit-py-plugins-0.4.2/mdit_py_plugins/__init__.py000066400000000000000000000000261466765473300221210ustar00rootroot00000000000000__version__ = "0.4.2" mdit-py-plugins-0.4.2/mdit_py_plugins/admon/000077500000000000000000000000001466765473300211105ustar00rootroot00000000000000mdit-py-plugins-0.4.2/mdit_py_plugins/admon/LICENSE000066400000000000000000000021511466765473300221140ustar00rootroot00000000000000Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. Copyright (c) 2018 jebbs Copyright (c) 2021- commenthol Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. mdit-py-plugins-0.4.2/mdit_py_plugins/admon/__init__.py000066400000000000000000000000751466765473300232230ustar00rootroot00000000000000from .index import admon_plugin __all__ = ("admon_plugin",) mdit-py-plugins-0.4.2/mdit_py_plugins/admon/index.py000066400000000000000000000152661466765473300226030ustar00rootroot00000000000000# Process admonitions and pass to cb. from __future__ import annotations from contextlib import suppress import re from typing import TYPE_CHECKING, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def _get_multiple_tags(params: str) -> tuple[list[str], str]: """Check for multiple tags when the title is double quoted.""" re_tags = re.compile(r'^\s*(?P[^"]+)\s+"(?P.*)"\S*$') match = re_tags.match(params) if match: tags = match["tokens"].strip().split(" ") return [tag.lower() for tag in tags], match["title"] raise ValueError("No match found for parameters") def _get_tag(_params: str) -> tuple[list[str], str]: """Separate the tag name from the admonition title.""" params = _params.strip() if not params: return [""], "" with suppress(ValueError): return _get_multiple_tags(params) tag, *_title = params.split(" ") joined = " ".join(_title) title = "" if not joined: title = tag.title() elif joined != '""': # Specifically check for no title title = joined return [tag.lower()], title def _validate(params: str) -> bool: """Validate the presence of the tag name after the marker.""" tag = params.strip().split(" ", 1)[-1] or "" return bool(tag) MARKER_LEN = 3 # Regardless of extra characters, block indent stays the same MARKERS = ("!!!", "???", "???+") MARKER_CHARS = {_m[0] for _m in MARKERS} MAX_MARKER_LEN = max(len(_m) for _m in MARKERS) def _extra_classes(markup: str) -> list[str]: """Return the list of additional classes based on the markup.""" if markup.startswith("?"): if markup.endswith("+"): return ["is-collapsible collapsible-open"] return ["is-collapsible collapsible-closed"] return [] def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False start = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] # Check out the first character quickly, which should filter out most of non-containers if state.src[start] not in MARKER_CHARS: return False # Check out the rest of the marker string marker = "" marker_len = MAX_MARKER_LEN while marker_len > 0: marker_pos = start + marker_len markup = state.src[start:marker_pos] if markup in MARKERS: marker = markup break marker_len -= 1 else: return False params = state.src[marker_pos:maximum] if not _validate(params): return False # Since start is found, we can report success here in validation mode if silent: return True old_parent = state.parentType old_line_max = state.lineMax old_indent = state.blkIndent blk_start = marker_pos while blk_start < maximum and state.src[blk_start] == " ": blk_start += 1 state.parentType = "admonition" # Correct block indentation when extra marker characters are present marker_alignment_correction = MARKER_LEN - len(marker) state.blkIndent += blk_start - start + marker_alignment_correction was_empty = False # Search for the end of the block next_line = startLine while True: next_line += 1 if next_line >= endLine: # unclosed block should be autoclosed by end of document. # also block seems to be autoclosed by end of parent break pos = state.bMarks[next_line] + state.tShift[next_line] maximum = state.eMarks[next_line] is_empty = state.sCount[next_line] < state.blkIndent # two consecutive empty lines autoclose the block if is_empty and was_empty: break was_empty = is_empty if pos < maximum and state.sCount[next_line] < state.blkIndent: # non-empty line with negative indent should stop the block: # - !!! # test break # this will prevent lazy continuations from ever going past our end marker state.lineMax = next_line tags, title = _get_tag(params) tag = tags[0] token = state.push("admonition_open", "div", 1) token.markup = markup token.block = True token.attrs = {"class": " ".join(["admonition", *tags, *_extra_classes(markup)])} token.meta = {"tag": tag} token.content = title token.info = params token.map = [startLine, next_line] if title: title_markup = f"{markup} {tag}" token = state.push("admonition_title_open", "p", 1) token.markup = title_markup token.attrs = {"class": "admonition-title"} token.map = [startLine, startLine + 1] token = state.push("inline", "", 0) token.content = title token.map = [startLine, startLine + 1] token.children = [] token = state.push("admonition_title_close", "p", -1) state.md.block.tokenize(state, startLine + 1, next_line) token = state.push("admonition_close", "div", -1) token.markup = markup token.block = True state.parentType = old_parent state.lineMax = old_line_max state.blkIndent = old_indent state.line = next_line return True def admon_plugin(md: MarkdownIt, render: None | Callable[..., str] = None) -> None: """Plugin to use `python-markdown style admonitions <https://python-markdown.github.io/extensions/admonition>`_. .. code-block:: md !!! note *content* `And mkdocs-style collapsible blocks <https://squidfunk.github.io/mkdocs-material/reference/admonitions/#collapsible-blocks>`_. .. code-block:: md ???+ note *content* Note, this is ported from `markdown-it-admon <https://github.com/commenthol/markdown-it-admon>`_. """ def renderDefault( self: RendererProtocol, tokens: Sequence[Token], idx: int, _options: OptionsDict, env: EnvType, ) -> str: return self.renderToken(tokens, idx, _options, env) # type: ignore[attr-defined,no-any-return] render = render or renderDefault md.add_render_rule("admonition_open", render) md.add_render_rule("admonition_close", render) md.add_render_rule("admonition_title_open", render) md.add_render_rule("admonition_title_close", render) md.block.ruler.before( "fence", "admonition", admonition, {"alt": ["paragraph", "reference", "blockquote", "list"]}, ) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/admon/port.yaml�����������������������������������������������0000664�0000000�0000000�00000000165�14667654733�0022762�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-admon commit: 9820ba89415c464a3cc18a780f222a0ceb3e18bd date: Jul 3, 2021 version: 1.0.0 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/amsmath/������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021444�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/amsmath/__init__.py�������������������������������������������0000664�0000000�0000000�00000012176�14667654733�0023564�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""An extension to capture amsmath latex environments.""" from __future__ import annotations import re from typing import TYPE_CHECKING, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict # Taken from amsmath version 2.1 # http://anorien.csc.warwick.ac.uk/mirrors/CTAN/macros/latex/required/amsmath/amsldoc.pdf ENVIRONMENTS = [ # 3.2 single equation with an automatically gen-erated number "equation", # 3.3 variation equation, used for equations that dont fit on a single line "multline", # 3.5 a group of consecutive equations when there is no alignment desired among them "gather", # 3.6 Used for two or more equations when vertical alignment is desired "align", # allows the horizontal space between equationsto be explicitly specified. "alignat", # stretches the space betweenthe equation columns to the maximum possible width "flalign", # 4.1 The pmatrix, bmatrix, Bmatrix, vmatrix and Vmatrix have (respectively) # (),[],{},||,and β€–β€– delimiters built in. "matrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix", # eqnarray is another math environment, it is not part of amsmath, # and note that it is better to use align or equation+split instead "eqnarray", ] # other "non-top-level" environments: # 3.4 the split environment is for single equations that are too long to fit on one line # and hence must be split into multiple lines, # it is intended for use only inside some other displayed equation structure, # usually an equation, align, or gather environment # 3.7 variants gathered, aligned,and alignedat are provided # whose total width is the actual width of the contents; # thus they can be used as a component in a containing expression RE_OPEN = r"\\begin\{(" + "|".join(ENVIRONMENTS) + r")([\*]?)\}" def amsmath_plugin( md: MarkdownIt, *, renderer: Callable[[str], str] | None = None ) -> None: """Parses TeX math equations, without any surrounding delimiters, only for top-level `amsmath <https://ctan.org/pkg/amsmath>`__ environments: .. code-block:: latex \\begin{gather*} a_1=b_1+c_1\\\\ a_2=b_2+c_2-d_2+e_2 \\end{gather*} :param renderer: Function to render content, by default escapes HTML """ md.block.ruler.before( "blockquote", "amsmath", amsmath_block, {"alt": ["paragraph", "reference", "blockquote", "list", "footnote_def"]}, ) _renderer = (lambda content: escapeHtml(content)) if renderer is None else renderer def render_amsmath_block( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: content = _renderer(str(tokens[idx].content)) return f'<div class="math amsmath">\n{content}\n</div>\n' md.add_render_rule("amsmath", render_amsmath_block) def amsmath_block( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: # note the code principally follows the logic in markdown_it/rules_block/fence.py, # except that: # (a) it allows for closing tag on same line as opening tag # (b) it does not allow for opening tag without closing tag (i.e. no auto-closing) if is_code_block(state, startLine): return False # does the first line contain the beginning of an amsmath environment first_start = state.bMarks[startLine] + state.tShift[startLine] first_end = state.eMarks[startLine] first_text = state.src[first_start:first_end] if not (match_open := re.match(RE_OPEN, first_text)): return False # construct the closing tag environment = match_open.group(1) numbered = match_open.group(2) closing = rf"\end{{{match_open.group(1)}{match_open.group(2)}}}" # start looking for the closing tag, including the current line nextLine = startLine - 1 while True: nextLine += 1 if nextLine >= endLine: # reached the end of the block without finding the closing tag return False next_start = state.bMarks[nextLine] + state.tShift[nextLine] next_end = state.eMarks[nextLine] if next_start < first_end and state.sCount[nextLine] < state.blkIndent: # non-empty line with negative indent should stop the list: # - \begin{align} # test return False if state.src[next_start:next_end].rstrip().endswith(closing): # found the closing tag break state.line = nextLine + 1 if not silent: token = state.push("amsmath", "math", 0) token.block = True token.content = state.getLines( startLine, state.line, state.sCount[startLine], False ) token.meta = {"environment": environment, "numbered": numbered} token.map = [startLine, nextLine] return True ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/anchors/������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021447�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/anchors/__init__.py�������������������������������������������0000664�0000000�0000000�00000000101�14667654733�0023550�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import anchors_plugin __all__ = ("anchors_plugin",) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/anchors/index.py����������������������������������������������0000664�0000000�0000000�00000010022�14667654733�0023123�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from typing import Callable, List, Optional, Set from markdown_it import MarkdownIt from markdown_it.rules_core import StateCore from markdown_it.token import Token def anchors_plugin( md: MarkdownIt, min_level: int = 1, max_level: int = 2, slug_func: Optional[Callable[[str], str]] = None, permalink: bool = False, permalinkSymbol: str = "ΒΆ", permalinkBefore: bool = False, permalinkSpace: bool = True, ) -> None: """Plugin for adding header anchors, based on `markdown-it-anchor <https://github.com/valeriangalliat/markdown-it-anchor>`__ .. code-block:: md # Title String renders as: .. code-block:: html <h1 id="title-string">Title String <a class="header-anchor" href="#title-string">ΒΆ</a></h1> :param min_level: minimum header level to apply anchors :param max_level: maximum header level to apply anchors :param slug_func: function to convert title text to id slug. :param permalink: Add a permalink next to the title :param permalinkSymbol: the symbol to show :param permalinkBefore: Add the permalink before the title, otherwise after :param permalinkSpace: Add a space between the permalink and the title Note, the default slug function aims to mimic the GitHub Markdown format, see: - https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/toc_filter.rb - https://gist.github.com/asabaylus/3071099 """ selected_levels = list(range(min_level, max_level + 1)) md.core.ruler.push( "anchor", _make_anchors_func( selected_levels, slug_func or slugify, permalink, permalinkSymbol, permalinkBefore, permalinkSpace, ), ) def _make_anchors_func( selected_levels: List[int], slug_func: Callable[[str], str], permalink: bool, permalinkSymbol: str, permalinkBefore: bool, permalinkSpace: bool, ) -> Callable[[StateCore], None]: def _anchor_func(state: StateCore) -> None: slugs: Set[str] = set() for idx, token in enumerate(state.tokens): if token.type != "heading_open": continue level = int(token.tag[1]) if level not in selected_levels: continue inline_token = state.tokens[idx + 1] assert inline_token.children is not None title = "".join( child.content for child in inline_token.children if child.type in ["text", "code_inline"] ) slug = unique_slug(slug_func(title), slugs) token.attrSet("id", slug) if permalink: link_open = Token( "link_open", "a", 1, ) link_open.attrSet("class", "header-anchor") link_open.attrSet("href", f"#{slug}") link_tokens = [ link_open, Token("html_block", "", 0, content=permalinkSymbol), Token("link_close", "a", -1), ] if permalinkBefore: inline_token.children = ( link_tokens + ( [Token("text", "", 0, content=" ")] if permalinkSpace else [] ) + inline_token.children ) else: inline_token.children.extend( ([Token("text", "", 0, content=" ")] if permalinkSpace else []) + link_tokens ) return _anchor_func def slugify(title: str) -> str: return re.sub(r"[^\w\u4e00-\u9fff\- ]", "", title.strip().lower().replace(" ", "-")) def unique_slug(slug: str, slugs: Set[str]) -> str: uniq = slug i = 1 while uniq in slugs: uniq = f"{slug}-{i}" i += 1 slugs.add(uniq) return uniq ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/��������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021147�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/__init__.py���������������������������������������������0000664�0000000�0000000�00000000146�14667654733�0023261�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import attrs_block_plugin, attrs_plugin __all__ = ("attrs_block_plugin", "attrs_plugin") ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/index.py������������������������������������������������0000664�0000000�0000000�00000021341�14667654733�0022631�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import annotations from functools import partial from typing import Any, Sequence from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from markdown_it.rules_core import StateCore from markdown_it.rules_inline import StateInline from markdown_it.token import Token from mdit_py_plugins.utils import is_code_block from .parse import ParseError, parse def attrs_plugin( md: MarkdownIt, *, after: Sequence[str] = ("image", "code_inline", "link_close", "span_close"), spans: bool = False, span_after: str = "link", allowed: Sequence[str] | None = None, ) -> None: """Parse inline attributes that immediately follow certain inline elements:: ![alt](https://image.com){#id .a b=c} This syntax is inspired by `Djot spans <https://htmlpreview.github.io/?https://github.com/jgm/djot/blob/master/doc/syntax.html#inline-attributes>`_. Inside the curly braces, the following syntax is possible: - `.foo` specifies foo as a class. Multiple classes may be given in this way; they will be combined. - `#foo` specifies foo as an identifier. An element may have only one identifier; if multiple identifiers are given, the last one is used. - `key="value"` or `key=value` specifies a key-value attribute. Quotes are not needed when the value consists entirely of ASCII alphanumeric characters or `_` or `:` or `-`. Backslash escapes may be used inside quoted values. - `%` begins a comment, which ends with the next `%` or the end of the attribute (`}`). Multiple attribute blocks are merged. :param md: The MarkdownIt instance to modify. :param after: The names of inline elements after which attributes may be specified. This plugin does not support attributes after emphasis, strikethrough or text elements, which all require post-parse processing. :param spans: If True, also parse attributes after spans of text, encapsulated by `[]`. Note Markdown link references take precedence over this syntax. :param span_after: The name of an inline rule after which spans may be specified. :param allowed: A list of allowed attribute names. If not ``None``, any attributes not in this list will be removed and placed in the token's meta under the key "insecure_attrs". """ if spans: md.inline.ruler.after(span_after, "span", _span_rule) if after: md.inline.ruler.push( "attr", partial( _attr_inline_rule, after=after, allowed=None if allowed is None else set(allowed), ), ) def attrs_block_plugin(md: MarkdownIt, *, allowed: Sequence[str] | None = None) -> None: """Parse block attributes. Block attributes are attributes on a single line, with no other content. They attach the specified attributes to the block below them:: {.a #b c=1} A paragraph, that will be assigned the class ``a`` and the identifier ``b``. Attributes can be stacked, with classes accumulating and lower attributes overriding higher:: {#a .a c=1} {#b .b c=2} A paragraph, that will be assigned the class ``a b c``, and the identifier ``b``. This syntax is inspired by Djot block attributes. :param allowed: A list of allowed attribute names. If not ``None``, any attributes not in this list will be removed and placed in the token's meta under the key "insecure_attrs". """ md.block.ruler.before("fence", "attr", _attr_block_rule) md.core.ruler.after( "block", "attr", partial( _attr_resolve_block_rule, allowed=None if allowed is None else set(allowed) ), ) def _find_opening(tokens: Sequence[Token], index: int) -> int | None: """Find the opening token index, if the token is closing.""" if tokens[index].nesting != -1: return index level = 0 while index >= 0: level += tokens[index].nesting if level == 0: return index index -= 1 return None def _span_rule(state: StateInline, silent: bool) -> bool: if state.src[state.pos] != "[": return False maximum = state.posMax labelStart = state.pos + 1 labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, False) # parser failed to find ']', so it's not a valid span if labelEnd < 0: return False pos = labelEnd + 1 # check not at end of inline if pos >= maximum: return False try: new_pos, attrs = parse(state.src[pos:]) except ParseError: return False pos += new_pos + 1 if not silent: state.pos = labelStart state.posMax = labelEnd token = state.push("span_open", "span", 1) token.attrs = attrs # type: ignore[assignment] state.md.inline.tokenize(state) token = state.push("span_close", "span", -1) state.pos = pos state.posMax = maximum return True def _attr_inline_rule( state: StateInline, silent: bool, after: Sequence[str], *, allowed: set[str] | None = None, ) -> bool: if state.pending or not state.tokens: return False token = state.tokens[-1] if token.type not in after: return False try: new_pos, attrs = parse(state.src[state.pos :]) except ParseError: return False token_index = _find_opening(state.tokens, len(state.tokens) - 1) if token_index is None: return False state.pos += new_pos + 1 if not silent: attr_token = state.tokens[token_index] if "class" in attrs and "class" in token.attrs: attrs["class"] = f"{token.attrs['class']} {attrs['class']}" _add_attrs(attr_token, attrs, allowed) return True def _attr_block_rule( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: """Find a block of attributes. The block must be a single line that begins with a `{`, after three or less spaces, and end with a `}` followed by any number if spaces. """ if is_code_block(state, startLine): return False pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] # if it doesn't start with a {, it's not an attribute block if state.src[pos] != "{": return False # find first non-space character from the right while maximum > pos and state.src[maximum - 1] in (" ", "\t"): maximum -= 1 # if it doesn't end with a }, it's not an attribute block if maximum <= pos: return False if state.src[maximum - 1] != "}": return False try: new_pos, attrs = parse(state.src[pos:maximum]) except ParseError: return False # if the block was resolved earlier than expected, it's not an attribute block # TODO this was not working in some instances, so I disabled it # if (maximum - 1) != new_pos: # return False if silent: return True token = state.push("attrs_block", "", 0) token.attrs = attrs # type: ignore[assignment] token.map = [startLine, startLine + 1] state.line = startLine + 1 return True def _attr_resolve_block_rule(state: StateCore, *, allowed: set[str] | None) -> None: """Find attribute block then move its attributes to the next block.""" i = 0 len_tokens = len(state.tokens) while i < len_tokens: if state.tokens[i].type != "attrs_block": i += 1 continue if i + 1 < len_tokens: next_token = state.tokens[i + 1] # classes are appended if "class" in state.tokens[i].attrs and "class" in next_token.attrs: state.tokens[i].attrs["class"] = ( f"{state.tokens[i].attrs['class']} {next_token.attrs['class']}" ) if next_token.type == "attrs_block": # subsequent attribute blocks take precedence, when merging for key, value in state.tokens[i].attrs.items(): if key == "class" or key not in next_token.attrs: next_token.attrs[key] = value else: _add_attrs(next_token, state.tokens[i].attrs, allowed) state.tokens.pop(i) len_tokens -= 1 def _add_attrs( token: Token, attrs: dict[str, Any], allowed: set[str] | None, ) -> None: """Add attributes to a token, skipping any disallowed attributes.""" if allowed is not None and ( disallowed := {k: v for k, v in attrs.items() if k not in allowed} ): token.meta["insecure_attrs"] = disallowed attrs = {k: v for k, v in attrs.items() if k in allowed} # attributes takes precedence over existing attributes token.attrs.update(attrs) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/attrs/parse.py������������������������������������������������0000664�0000000�0000000�00000017113�14667654733�0022636�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Parser for attributes:: attributes { id = "foo", class = "bar baz", key1 = "val1", key2 = "val2" } Adapted from: https://github.com/jgm/djot/blob/fae7364b86bfce69bc6d5b5eede1f5196d845fd6/djot/attributes.lua#L1 syntax: attributes <- '{' whitespace* attribute (whitespace attribute)* whitespace* '}' attribute <- identifier | class | keyval identifier <- '#' name class <- '.' name name <- (nonspace, nonpunctuation other than ':', '_', '-')+ keyval <- key '=' val key <- (ASCII_ALPHANUM | ':' | '_' | '-')+ val <- bareval | quotedval bareval <- (ASCII_ALPHANUM | ':' | '_' | '-')+ quotedval <- '"' ([^"] | '\"') '"' """ from __future__ import annotations from enum import Enum import re from typing import Callable class State(Enum): START = 0 SCANNING = 1 SCANNING_ID = 2 SCANNING_CLASS = 3 SCANNING_KEY = 4 SCANNING_VALUE = 5 SCANNING_BARE_VALUE = 6 SCANNING_QUOTED_VALUE = 7 SCANNING_COMMENT = 8 SCANNING_ESCAPED = 9 DONE = 10 REGEX_SPACE = re.compile(r"\s") REGEX_SPACE_PUNCTUATION = re.compile(r"[\s!\"#$%&'()*+,./;<=>?@[\]^`{|}~]") REGEX_KEY_CHARACTERS = re.compile(r"[a-zA-Z\d_:-]") class TokenState: def __init__(self) -> None: self._tokens: list[tuple[int, int, str]] = [] self.start: int = 0 def set_start(self, start: int) -> None: self.start = start def append(self, start: int, end: int, ttype: str) -> None: self._tokens.append((start, end, ttype)) def compile(self, string: str) -> dict[str, str]: """compile the tokens into a dictionary""" attributes = {} classes = [] idx = 0 while idx < len(self._tokens): start, end, ttype = self._tokens[idx] if ttype == "id": attributes["id"] = string[start:end] elif ttype == "class": classes.append(string[start:end]) elif ttype == "key": key = string[start:end] if idx + 1 < len(self._tokens): start, end, ttype = self._tokens[idx + 1] if ttype == "value": if key == "class": classes.append(string[start:end]) else: attributes[key] = string[start:end] idx += 1 idx += 1 if classes: attributes["class"] = " ".join(classes) return attributes def __str__(self) -> str: return str(self._tokens) def __repr__(self) -> str: return repr(self._tokens) class ParseError(Exception): def __init__(self, msg: str, pos: int) -> None: self.pos = pos super().__init__(msg + f" at position {pos}") def parse(string: str) -> tuple[int, dict[str, str]]: """Parse attributes from start of string. :returns: (length of parsed string, dict of attributes) """ pos = 0 state: State = State.START tokens = TokenState() while pos < len(string): state = HANDLERS[state](string[pos], pos, tokens) if state == State.DONE: return pos, tokens.compile(string) pos = pos + 1 return pos, tokens.compile(string) def handle_start(char: str, pos: int, tokens: TokenState) -> State: if char == "{": return State.SCANNING raise ParseError("Attributes must start with '{'", pos) def handle_scanning(char: str, pos: int, tokens: TokenState) -> State: if char == " " or char == "\t" or char == "\n" or char == "\r": return State.SCANNING if char == "}": return State.DONE if char == "#": tokens.set_start(pos) return State.SCANNING_ID if char == "%": tokens.set_start(pos) return State.SCANNING_COMMENT if char == ".": tokens.set_start(pos) return State.SCANNING_CLASS if REGEX_KEY_CHARACTERS.fullmatch(char): tokens.set_start(pos) return State.SCANNING_KEY raise ParseError(f"Unexpected character whilst scanning: {char}", pos) def handle_scanning_comment(char: str, pos: int, tokens: TokenState) -> State: if char == "%": return State.SCANNING return State.SCANNING_COMMENT def handle_scanning_id(char: str, pos: int, tokens: TokenState) -> State: if not REGEX_SPACE_PUNCTUATION.fullmatch(char): return State.SCANNING_ID if char == "}": if (pos - 1) > tokens.start: tokens.append(tokens.start + 1, pos, "id") return State.DONE if REGEX_SPACE.fullmatch(char): if (pos - 1) > tokens.start: tokens.append(tokens.start + 1, pos, "id") return State.SCANNING raise ParseError(f"Unexpected character whilst scanning id: {char}", pos) def handle_scanning_class(char: str, pos: int, tokens: TokenState) -> State: if not REGEX_SPACE_PUNCTUATION.fullmatch(char): return State.SCANNING_CLASS if char == "}": if (pos - 1) > tokens.start: tokens.append(tokens.start + 1, pos, "class") return State.DONE if REGEX_SPACE.fullmatch(char): if (pos - 1) > tokens.start: tokens.append(tokens.start + 1, pos, "class") return State.SCANNING raise ParseError(f"Unexpected character whilst scanning class: {char}", pos) def handle_scanning_key(char: str, pos: int, tokens: TokenState) -> State: if char == "=": tokens.append(tokens.start, pos, "key") return State.SCANNING_VALUE if REGEX_KEY_CHARACTERS.fullmatch(char): return State.SCANNING_KEY raise ParseError(f"Unexpected character whilst scanning key: {char}", pos) def handle_scanning_value(char: str, pos: int, tokens: TokenState) -> State: if char == '"': tokens.set_start(pos) return State.SCANNING_QUOTED_VALUE if REGEX_KEY_CHARACTERS.fullmatch(char): tokens.set_start(pos) return State.SCANNING_BARE_VALUE raise ParseError(f"Unexpected character whilst scanning value: {char}", pos) def handle_scanning_bare_value(char: str, pos: int, tokens: TokenState) -> State: if REGEX_KEY_CHARACTERS.fullmatch(char): return State.SCANNING_BARE_VALUE if char == "}": tokens.append(tokens.start, pos, "value") return State.DONE if REGEX_SPACE.fullmatch(char): tokens.append(tokens.start, pos, "value") return State.SCANNING raise ParseError(f"Unexpected character whilst scanning bare value: {char}", pos) def handle_scanning_escaped(char: str, pos: int, tokens: TokenState) -> State: return State.SCANNING_QUOTED_VALUE def handle_scanning_quoted_value(char: str, pos: int, tokens: TokenState) -> State: if char == '"': tokens.append(tokens.start + 1, pos, "value") return State.SCANNING if char == "\\": return State.SCANNING_ESCAPED if char == "{" or char == "}": raise ParseError( f"Unexpected character whilst scanning quoted value: {char}", pos ) if char == "\n": tokens.append(tokens.start + 1, pos, "value") return State.SCANNING_QUOTED_VALUE return State.SCANNING_QUOTED_VALUE HANDLERS: dict[State, Callable[[str, int, TokenState], State]] = { State.START: handle_start, State.SCANNING: handle_scanning, State.SCANNING_COMMENT: handle_scanning_comment, State.SCANNING_ID: handle_scanning_id, State.SCANNING_CLASS: handle_scanning_class, State.SCANNING_KEY: handle_scanning_key, State.SCANNING_VALUE: handle_scanning_value, State.SCANNING_BARE_VALUE: handle_scanning_bare_value, State.SCANNING_QUOTED_VALUE: handle_scanning_quoted_value, State.SCANNING_ESCAPED: handle_scanning_escaped, } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/colon_fence.py������������������������������������������������0000664�0000000�0000000�00000007563�14667654733�0022651�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import annotations from typing import TYPE_CHECKING, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml, unescapeAll from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def colon_fence_plugin(md: MarkdownIt) -> None: """This plugin directly mimics regular fences, but with `:` colons. Example:: :::name contained text ::: """ md.block.ruler.before( "fence", "colon_fence", _rule, {"alt": ["paragraph", "reference", "blockquote", "list", "footnote_def"]}, ) md.add_render_rule("colon_fence", _render) def _rule(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False haveEndMarker = False pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] if pos + 3 > maximum: return False marker = state.src[pos] if marker != ":": return False # scan marker length mem = pos pos = _skipCharsStr(state, pos, marker) length = pos - mem if length < 3: return False markup = state.src[mem:pos] params = state.src[pos:maximum] # Since start is found, we can report success here in validation mode if silent: return True # search end of block nextLine = startLine while True: nextLine += 1 if nextLine >= endLine: # unclosed block should be autoclosed by end of document. # also block seems to be autoclosed by end of parent break pos = mem = state.bMarks[nextLine] + state.tShift[nextLine] maximum = state.eMarks[nextLine] if pos < maximum and state.sCount[nextLine] < state.blkIndent: # non-empty line with negative indent should stop the list: # - ``` # test break if state.src[pos] != marker: continue if is_code_block(state, nextLine): continue pos = _skipCharsStr(state, pos, marker) # closing code fence must be at least as long as the opening one if pos - mem < length: continue # make sure tail has spaces only pos = state.skipSpaces(pos) if pos < maximum: continue haveEndMarker = True # found! break # If a fence has heading spaces, they should be removed from its inner block length = state.sCount[startLine] state.line = nextLine + (1 if haveEndMarker else 0) token = state.push("colon_fence", "code", 0) token.info = params token.content = state.getLines(startLine + 1, nextLine, length, True) token.markup = markup token.map = [startLine, state.line] return True def _skipCharsStr(state: StateBlock, pos: int, ch: str) -> int: """Skip character string from given position.""" # TODO this can be replaced with StateBlock.skipCharsStr in markdown-it-py 3.0.0 while True: try: current = state.src[pos] except IndexError: break if current != ch: break pos += 1 return pos def _render( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: token = tokens[idx] info = unescapeAll(token.info).strip() if token.info else "" content = escapeHtml(token.content) block_name = "" if info: block_name = info.split()[0] return ( "<pre><code" + (f' class="block-{block_name}" ' if block_name else "") + ">" + content + "</code></pre>\n" ) ���������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/����������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021774�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/LICENSE���������������������������������������������0000664�0000000�0000000�00000002061�14667654733�0023000�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/README.md�������������������������������������������0000664�0000000�0000000�00000004745�14667654733�0023265�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# markdown-it-container [![Build Status](https://img.shields.io/travis/markdown-it/markdown-it-container/master.svg?style=flat)](https://travis-ci.org/markdown-it/markdown-it-container) [![NPM version](https://img.shields.io/npm/v/markdown-it-container.svg?style=flat)](https://www.npmjs.org/package/markdown-it-container) [![Coverage Status](https://img.shields.io/coveralls/markdown-it/markdown-it-container/master.svg?style=flat)](https://coveralls.io/r/markdown-it/markdown-it-container?branch=master) > Plugin for creating block-level custom containers for [markdown-it](https://github.com/markdown-it/markdown-it) markdown parser. __v2.+ requires `markdown-it` v5.+, see changelog.__ With this plugin you can create block containers like: ``` ::: warning *here be dragons* ::: ``` .... and specify how they should be rendered. If no renderer defined, `<div>` with container name class will be created: ```html <div class="warning"> <em>here be dragons</em> </div> ``` Markup is the same as for [fenced code blocks](http://spec.commonmark.org/0.18/#fenced-code-blocks). Difference is, that marker use another character and content is rendered as markdown markup. ## Installation node.js, browser: ```bash $ npm install markdown-it-container --save $ bower install markdown-it-container --save ``` ## API ```js var md = require('markdown-it')() .use(require('markdown-it-container'), name [, options]); ``` Params: - __name__ - container name (mandatory) - __options:__ - __validate__ - optional, function to validate tail after opening marker, should return `true` on success. - __render__ - optional, renderer function for opening/closing tokens. - __marker__ - optional (`:`), character to use in delimiter. ## Example ```js var md = require('markdown-it')(); md.use(require('markdown-it-container'), 'spoiler', { validate: function(params) { return params.trim().match(/^spoiler\s+(.*)$/); }, render: function (tokens, idx) { var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/); if (tokens[idx].nesting === 1) { // opening tag return '<details><summary>' + md.utils.escapeHtml(m[1]) + '</summary>\n'; } else { // closing tag return '</details>\n'; } } }); console.log(md.render('::: spoiler click me\n*content*\n:::\n')); // Output: // // <details><summary>click me</summary> // <p><em>content</em></p> // </details> ``` ## License [MIT](https://github.com/markdown-it/markdown-it-container/blob/master/LICENSE) ���������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/__init__.py�����������������������������������������0000664�0000000�0000000�00000000105�14667654733�0024101�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import container_plugin __all__ = ("container_plugin",) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/index.py��������������������������������������������0000664�0000000�0000000�00000013212�14667654733�0023454�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Process block-level custom containers.""" from __future__ import annotations from math import floor from typing import TYPE_CHECKING, Any, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def container_plugin( md: MarkdownIt, name: str, marker: str = ":", validate: None | Callable[[str, str], bool] = None, render: None | Callable[..., str] = None, ) -> None: """Plugin ported from `markdown-it-container <https://github.com/markdown-it/markdown-it-container>`__. It is a plugin for creating block-level custom containers: .. code-block:: md :::: name ::: name *markdown* ::: :::: :param name: the name of the container to parse :param marker: the marker character to use :param validate: func(marker, param) -> bool, default matches against the name :param render: render func """ def validateDefault(params: str, *args: Any) -> bool: return params.strip().split(" ", 2)[0] == name def renderDefault( self: RendererProtocol, tokens: Sequence[Token], idx: int, _options: OptionsDict, env: EnvType, ) -> str: # add a class to the opening tag if tokens[idx].nesting == 1: tokens[idx].attrJoin("class", name) return self.renderToken(tokens, idx, _options, env) # type: ignore[attr-defined,no-any-return] min_markers = 3 marker_str = marker marker_char = marker_str[0] marker_len = len(marker_str) validate = validate or validateDefault render = render or renderDefault def container_func( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: if is_code_block(state, startLine): return False auto_closed = False start = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] # Check out the first character quickly, # this should filter out most of non-containers if marker_char != state.src[start]: return False # Check out the rest of the marker string pos = start + 1 while pos <= maximum: try: character = state.src[pos] except IndexError: break if marker_str[(pos - start) % marker_len] != character: break pos += 1 marker_count = floor((pos - start) / marker_len) if marker_count < min_markers: return False pos -= (pos - start) % marker_len markup = state.src[start:pos] params = state.src[pos:maximum] assert validate is not None if not validate(params, markup): return False # Since start is found, we can report success here in validation mode if silent: return True # Search for the end of the block nextLine = startLine while True: nextLine += 1 if nextLine >= endLine: # unclosed block should be autoclosed by end of document. # also block seems to be autoclosed by end of parent break start = state.bMarks[nextLine] + state.tShift[nextLine] maximum = state.eMarks[nextLine] if start < maximum and state.sCount[nextLine] < state.blkIndent: # non-empty line with negative indent should stop the list: # - ``` # test break if marker_char != state.src[start]: continue if is_code_block(state, nextLine): continue pos = start + 1 while pos <= maximum: try: character = state.src[pos] except IndexError: break if marker_str[(pos - start) % marker_len] != character: break pos += 1 # closing code fence must be at least as long as the opening one if floor((pos - start) / marker_len) < marker_count: continue # make sure tail has spaces only pos -= (pos - start) % marker_len pos = state.skipSpaces(pos) if pos < maximum: continue # found! auto_closed = True break old_parent = state.parentType old_line_max = state.lineMax state.parentType = "container" # this will prevent lazy continuations from ever going past our end marker state.lineMax = nextLine token = state.push(f"container_{name}_open", "div", 1) token.markup = markup token.block = True token.info = params token.map = [startLine, nextLine] state.md.block.tokenize(state, startLine + 1, nextLine) token = state.push(f"container_{name}_close", "div", -1) token.markup = state.src[start:pos] token.block = True state.parentType = old_parent state.lineMax = old_line_max state.line = nextLine + (1 if auto_closed else 0) return True md.block.ruler.before( "fence", "container_" + name, container_func, {"alt": ["paragraph", "reference", "blockquote", "list"]}, ) md.add_render_rule(f"container_{name}_open", render) md.add_render_rule(f"container_{name}_close", render) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/container/port.yaml�������������������������������������������0000664�0000000�0000000�00000000204�14667654733�0023640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-container commit: adb3defde3a1c56015895b47ce4c6591b8b1e3a2 date: Jun 2, 2020 version: 3.0.0 changes: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021444�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/LICENSE�����������������������������������������������0000664�0000000�0000000�00000002066�14667654733�0022455�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2014-2015 Vitaly Puzrin, Alex Kocharin. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/README.md���������������������������������������������0000664�0000000�0000000�00000002371�14667654733�0022726�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# markdown-it-deflist [![Build Status](https://img.shields.io/travis/markdown-it/markdown-it-deflist/master.svg?style=flat)](https://travis-ci.org/markdown-it/markdown-it-deflist) [![NPM version](https://img.shields.io/npm/v/markdown-it-deflist.svg?style=flat)](https://www.npmjs.org/package/markdown-it-deflist) [![Coverage Status](https://img.shields.io/coveralls/markdown-it/markdown-it-deflist/master.svg?style=flat)](https://coveralls.io/r/markdown-it/markdown-it-deflist?branch=master) > Definition list (`<dl>`) tag plugin for [markdown-it](https://github.com/markdown-it/markdown-it) markdown parser. __v2.+ requires `markdown-it` v5.+, see changelog.__ Syntax is based on [pandoc definition lists](http://johnmacfarlane.net/pandoc/README.html#definition-lists). ## Install node.js, browser: ```bash npm install markdown-it-deflist --save bower install markdown-it-deflist --save ``` ## Use ```js var md = require('markdown-it')() .use(require('markdown-it-deflist')); md.render(/*...*/); ``` _Differences in browser._ If you load script directly into the page, without package system, module will add itself globally as `window.markdownitDeflist`. ## License [MIT](https://github.com/markdown-it/markdown-it-deflist/blob/master/LICENSE) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/__init__.py�������������������������������������������0000664�0000000�0000000�00000000101�14667654733�0023545�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import deflist_plugin __all__ = ("deflist_plugin",) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/index.py����������������������������������������������0000664�0000000�0000000�00000016417�14667654733�0023136�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Process definition lists.""" from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block def deflist_plugin(md: MarkdownIt) -> None: """Plugin ported from `markdown-it-deflist <https://github.com/markdown-it/markdown-it-deflist>`__. The syntax is based on `pandoc definition lists <http://johnmacfarlane.net/pandoc/README.html#definition-lists>`__: .. code-block:: md Term 1 : Definition 1 long form second paragraph Term 2 with *inline markup* ~ Definition 2a compact style ~ Definition 2b """ def skipMarker(state: StateBlock, line: int) -> int: """Search `[:~][\n ]`, returns next pos after marker on success or -1 on fail.""" start = state.bMarks[line] + state.tShift[line] maximum = state.eMarks[line] if start >= maximum: return -1 # Check bullet marker = state.src[start] start += 1 if marker != "~" and marker != ":": return -1 pos = state.skipSpaces(start) # require space after ":" if start == pos: return -1 # no empty definitions, e.g. " : " if pos >= maximum: return -1 return start def markTightParagraphs(state: StateBlock, idx: int) -> None: level = state.level + 2 i = idx + 2 l2 = len(state.tokens) - 2 while i < l2: if ( state.tokens[i].level == level and state.tokens[i].type == "paragraph_open" ): state.tokens[i + 2].hidden = True state.tokens[i].hidden = True i += 2 i += 1 def deflist(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False if silent: # quirk: validation mode validates a dd block only, not a whole deflist if state.ddIndent < 0: return False return skipMarker(state, startLine) >= 0 nextLine = startLine + 1 if nextLine >= endLine: return False if state.isEmpty(nextLine): nextLine += 1 if nextLine >= endLine: return False if state.sCount[nextLine] < state.blkIndent: return False contentStart = skipMarker(state, nextLine) if contentStart < 0: return False # Start list listTokIdx = len(state.tokens) tight = True token = state.push("dl_open", "dl", 1) token.map = listLines = [startLine, 0] # Iterate list items dtLine = startLine ddLine = nextLine # One definition list can contain multiple DTs, # and one DT can be followed by multiple DDs. # # Thus, there is two loops here, and label is # needed to break out of the second one # break_outer = False while True: prevEmptyEnd = False token = state.push("dt_open", "dt", 1) token.map = [dtLine, dtLine] token = state.push("inline", "", 0) token.map = [dtLine, dtLine] token.content = state.getLines( dtLine, dtLine + 1, state.blkIndent, False ).strip() token.children = [] token = state.push("dt_close", "dt", -1) while True: token = state.push("dd_open", "dd", 1) token.map = itemLines = [nextLine, 0] pos = contentStart maximum = state.eMarks[ddLine] offset = ( state.sCount[ddLine] + contentStart - (state.bMarks[ddLine] + state.tShift[ddLine]) ) while pos < maximum: if state.src[pos] == "\t": offset += 4 - offset % 4 elif state.src[pos] == " ": offset += 1 else: break pos += 1 contentStart = pos oldTight = state.tight oldDDIndent = state.ddIndent oldIndent = state.blkIndent oldTShift = state.tShift[ddLine] oldSCount = state.sCount[ddLine] oldParentType = state.parentType state.blkIndent = state.ddIndent = state.sCount[ddLine] + 2 state.tShift[ddLine] = contentStart - state.bMarks[ddLine] state.sCount[ddLine] = offset state.tight = True state.parentType = "deflist" state.md.block.tokenize(state, ddLine, endLine) # If any of list item is tight, mark list as tight if not state.tight or prevEmptyEnd: tight = False # Item become loose if finish with empty line, # but we should filter last element, because it means list finish prevEmptyEnd = (state.line - ddLine) > 1 and state.isEmpty( state.line - 1 ) state.tShift[ddLine] = oldTShift state.sCount[ddLine] = oldSCount state.tight = oldTight state.parentType = oldParentType state.blkIndent = oldIndent state.ddIndent = oldDDIndent token = state.push("dd_close", "dd", -1) itemLines[1] = nextLine = state.line if nextLine >= endLine: break_outer = True break if state.sCount[nextLine] < state.blkIndent: break_outer = True break contentStart = skipMarker(state, nextLine) if contentStart < 0: break ddLine = nextLine # go to the next loop iteration: # insert DD tag and repeat checking if break_outer: break_outer = False break if nextLine >= endLine: break dtLine = nextLine if state.isEmpty(dtLine): break if state.sCount[dtLine] < state.blkIndent: break ddLine = dtLine + 1 if ddLine >= endLine: break if state.isEmpty(ddLine): ddLine += 1 if ddLine >= endLine: break if state.sCount[ddLine] < state.blkIndent: break contentStart = skipMarker(state, ddLine) if contentStart < 0: break # go to the next loop iteration: # insert DT and DD tags and repeat checking # Finalise list token = state.push("dl_close", "dl", -1) listLines[1] = nextLine state.line = nextLine # mark paragraphs tight if needed if tight: markTightParagraphs(state, listTokIdx) return True md.block.ruler.before( "paragraph", "deflist", deflist, {"alt": ["paragraph", "reference", "blockquote"]}, ) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/deflist/port.yaml���������������������������������������������0000664�0000000�0000000�00000000204�14667654733�0023310�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-deflist commit: 20db400948520308291da029a23b0751cb30f3a0 date: July 12, 2017 version: 2.0.3 changes: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/dollarmath/���������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022141�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/dollarmath/__init__.py����������������������������������������0000664�0000000�0000000�00000000107�14667654733�0024250�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import dollarmath_plugin __all__ = ("dollarmath_plugin",) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/dollarmath/index.py�������������������������������������������0000664�0000000�0000000�00000030303�14667654733�0023621�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import annotations import re from typing import TYPE_CHECKING, Any, Callable, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml, isWhiteSpace from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def dollarmath_plugin( md: MarkdownIt, *, allow_labels: bool = True, allow_space: bool = True, allow_digits: bool = True, allow_blank_lines: bool = True, double_inline: bool = False, label_normalizer: Callable[[str], str] | None = None, renderer: Callable[[str, dict[str, Any]], str] | None = None, label_renderer: Callable[[str], str] | None = None, ) -> None: """Plugin for parsing dollar enclosed math, e.g. inline: ``$a=1$``, block: ``$$b=2$$`` This is an improved version of ``texmath``; it is more performant, and handles ``\\`` escaping properly and allows for more configuration. :param allow_labels: Capture math blocks with label suffix, e.g. ``$$a=1$$ (eq1)`` :param allow_space: Parse inline math when there is space after/before the opening/closing ``$``, e.g. ``$ a $`` :param allow_digits: Parse inline math when there is a digit before/after the opening/closing ``$``, e.g. ``1$`` or ``$2``. This is useful when also using currency. :param allow_blank_lines: Allow blank lines inside ``$$``. Note that blank lines are not allowed in LaTeX, executablebooks/markdown-it-dollarmath, or the Github or StackExchange markdown dialects. Hoever, they have special semantics if used within Sphinx `..math` admonitions, so are allowed for backwards-compatibility. :param double_inline: Search for double-dollar math within inline contexts :param label_normalizer: Function to normalize the label, by default replaces whitespace with `-` :param renderer: Function to render content: `(str, {"display_mode": bool}) -> str`, by default escapes HTML :param label_renderer: Function to render labels, by default creates anchor """ if label_normalizer is None: label_normalizer = lambda label: re.sub(r"\s+", "-", label) # noqa: E731 md.inline.ruler.before( "escape", "math_inline", math_inline_dollar(allow_space, allow_digits, double_inline), ) md.block.ruler.before( "fence", "math_block", math_block_dollar(allow_labels, label_normalizer, allow_blank_lines), ) # TODO the current render rules are really just for testing # would be good to allow "proper" math rendering, # e.g. https://github.com/roniemartinez/latex2mathml _renderer = ( (lambda content, _: escapeHtml(content)) if renderer is None else renderer ) _label_renderer: Callable[[str], str] if label_renderer is None: _label_renderer = ( # noqa: E731 lambda label: f'<a href="#{label}" class="mathlabel" title="Permalink to this equation">ΒΆ</a>' ) else: _label_renderer = label_renderer def render_math_inline( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: content = _renderer(str(tokens[idx].content).strip(), {"display_mode": False}) return f'<span class="math inline">{content}</span>' def render_math_inline_double( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: content = _renderer(str(tokens[idx].content).strip(), {"display_mode": True}) return f'<div class="math inline">{content}</div>' def render_math_block( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: content = _renderer(str(tokens[idx].content).strip(), {"display_mode": True}) return f'<div class="math block">\n{content}\n</div>\n' def render_math_block_label( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: content = _renderer(str(tokens[idx].content).strip(), {"display_mode": True}) _id = tokens[idx].info label = _label_renderer(tokens[idx].info) return f'<div id="{_id}" class="math block">\n{label}\n{content}\n</div>\n' md.add_render_rule("math_inline", render_math_inline) md.add_render_rule("math_inline_double", render_math_inline_double) md.add_render_rule("math_block", render_math_block) md.add_render_rule("math_block_label", render_math_block_label) def is_escaped(state: StateInline, back_pos: int, mod: int = 0) -> bool: """Test if dollar is escaped.""" # count how many \ are before the current position backslashes = 0 while back_pos >= 0: back_pos = back_pos - 1 if state.src[back_pos] == "\\": backslashes += 1 else: break if not backslashes: return False # if an odd number of \ then ignore if (backslashes % 2) != mod: return True return False def math_inline_dollar( allow_space: bool = True, allow_digits: bool = True, allow_double: bool = False ) -> Callable[[StateInline, bool], bool]: """Generate inline dollar rule. :param allow_space: Parse inline math when there is space after/before the opening/closing ``$``, e.g. ``$ a $`` :param allow_digits: Parse inline math when there is a digit before/after the opening/closing ``$``, e.g. ``1$`` or ``$2``. This is useful when also using currency. :param allow_double: Search for double-dollar math within inline contexts """ def _math_inline_dollar(state: StateInline, silent: bool) -> bool: """Inline dollar rule. - Initial check: - check if first character is a $ - check if the first character is escaped - check if the next character is a space (if not allow_space) - check if the next character is a digit (if not allow_digits) - Advance one, if allow_double - Find closing (advance one, if allow_double) - Check closing: - check if the previous character is a space (if not allow_space) - check if the next character is a digit (if not allow_digits) - Check empty content """ # TODO options: # even/odd backslash escaping if state.src[state.pos] != "$": return False if not allow_space: # whitespace not allowed straight after opening $ try: if isWhiteSpace(ord(state.src[state.pos + 1])): return False except IndexError: return False if not allow_digits: # digit not allowed straight before opening $ try: if state.src[state.pos - 1].isdigit(): return False except IndexError: pass if is_escaped(state, state.pos): return False try: is_double = allow_double and state.src[state.pos + 1] == "$" except IndexError: return False # find closing $ pos = state.pos + 1 + (1 if is_double else 0) found_closing = False while not found_closing: try: end = state.src.index("$", pos) except ValueError: return False if is_escaped(state, end): pos = end + 1 continue try: if is_double and state.src[end + 1] != "$": pos = end + 1 continue except IndexError: return False if is_double: end += 1 found_closing = True if not found_closing: return False if not allow_space: # whitespace not allowed straight before closing $ try: if isWhiteSpace(ord(state.src[end - 1])): return False except IndexError: return False if not allow_digits: # digit not allowed straight after closing $ try: if state.src[end + 1].isdigit(): return False except IndexError: pass text = ( state.src[state.pos + 2 : end - 1] if is_double else state.src[state.pos + 1 : end] ) # ignore empty if not text: return False if not silent: token = state.push( "math_inline_double" if is_double else "math_inline", "math", 0 ) token.content = text token.markup = "$$" if is_double else "$" state.pos = end + 1 return True return _math_inline_dollar # reversed end of block dollar equation, with equation label DOLLAR_EQNO_REV = re.compile(r"^\s*\)([^)$\r\n]+?)\(\s*\${2}") def math_block_dollar( allow_labels: bool = True, label_normalizer: Callable[[str], str] | None = None, allow_blank_lines: bool = False, ) -> Callable[[StateBlock, int, int, bool], bool]: """Generate block dollar rule.""" def _math_block_dollar( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: # TODO internal backslash escaping if is_code_block(state, startLine): return False haveEndMarker = False startPos = state.bMarks[startLine] + state.tShift[startLine] end = state.eMarks[startLine] if startPos + 2 > end: return False if state.src[startPos] != "$" or state.src[startPos + 1] != "$": return False # search for end of block nextLine = startLine label = None # search for end of block on same line lineText = state.src[startPos:end] if len(lineText.strip()) > 3: if lineText.strip().endswith("$$"): haveEndMarker = True end = end - 2 - (len(lineText) - len(lineText.strip())) elif allow_labels: # reverse the line and match eqnoMatch = DOLLAR_EQNO_REV.match(lineText[::-1]) if eqnoMatch: haveEndMarker = True label = eqnoMatch.group(1)[::-1] end = end - eqnoMatch.end() # search for end of block on subsequent line if not haveEndMarker: while True: nextLine += 1 if nextLine >= endLine: break start = state.bMarks[nextLine] + state.tShift[nextLine] end = state.eMarks[nextLine] lineText = state.src[start:end] if lineText.strip().endswith("$$"): haveEndMarker = True end = end - 2 - (len(lineText) - len(lineText.strip())) break if lineText.strip() == "" and not allow_blank_lines: break # blank lines are not allowed within $$ # reverse the line and match if allow_labels: eqnoMatch = DOLLAR_EQNO_REV.match(lineText[::-1]) if eqnoMatch: haveEndMarker = True label = eqnoMatch.group(1)[::-1] end = end - eqnoMatch.end() break if not haveEndMarker: return False state.line = nextLine + (1 if haveEndMarker else 0) token = state.push("math_block_label" if label else "math_block", "math", 0) token.block = True token.content = state.src[startPos + 2 : end] token.markup = "$$" token.map = [startLine, state.line] if label: token.info = label if label_normalizer is None else label_normalizer(label) return True return _math_block_dollar �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/field_list/���������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022130�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/field_list/__init__.py����������������������������������������0000664�0000000�0000000�00000020133�14667654733�0024240�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Field list plugin""" from contextlib import contextmanager from typing import Iterator, Optional, Tuple from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block def fieldlist_plugin(md: MarkdownIt) -> None: """Field lists are mappings from field names to field bodies, based on the `reStructureText syntax <https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#field-lists>`_. .. code-block:: md :name *markup*: :name1: body content :name2: paragraph 1 paragraph 2 :name3: paragraph 1 paragraph 2 A field name may consist of any characters except colons (":"). Inline markup is parsed in field names. The field name is followed by whitespace and the field body. The field body may be empty or contain multiple body elements. Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other. """ md.block.ruler.before( "paragraph", "fieldlist", _fieldlist_rule, {"alt": ["paragraph", "reference", "blockquote"]}, ) def parseNameMarker(state: StateBlock, startLine: int) -> Tuple[int, str]: """Parse field name: `:name:` :returns: position after name marker, name text """ start = state.bMarks[startLine] + state.tShift[startLine] pos = start maximum = state.eMarks[startLine] # marker should have at least 3 chars (colon + character + colon) if pos + 2 >= maximum: return -1, "" # first character should be ':' if state.src[pos] != ":": return -1, "" # scan name length name_length = 1 found_close = False for ch in state.src[pos + 1 :]: if ch == "\n": break if ch == ":": # TODO backslash escapes found_close = True break name_length += 1 if not found_close: return -1, "" # get name name_text = state.src[pos + 1 : pos + name_length] # name should contain at least one character if not name_text.strip(): return -1, "" return pos + name_length + 1, name_text @contextmanager def set_parent_type(state: StateBlock, name: str) -> Iterator[None]: """Temporarily set parent type to `name`""" oldParentType = state.parentType state.parentType = name yield state.parentType = oldParentType def _fieldlist_rule( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: # adapted from markdown_it/rules_block/list.py::list_block if is_code_block(state, startLine): return False posAfterName, name_text = parseNameMarker(state, startLine) if posAfterName < 0: return False # For validation mode we can terminate immediately if silent: return True # start field list token = state.push("field_list_open", "dl", 1) token.attrSet("class", "field-list") token.map = listLines = [startLine, 0] # iterate list items nextLine = startLine with set_parent_type(state, "fieldlist"): while nextLine < endLine: # create name tokens token = state.push("fieldlist_name_open", "dt", 1) token.map = [startLine, startLine] token = state.push("inline", "", 0) token.map = [startLine, startLine] token.content = name_text token.children = [] token = state.push("fieldlist_name_close", "dt", -1) # set indent positions pos = posAfterName maximum: int = state.eMarks[nextLine] first_line_body_indent = ( state.sCount[nextLine] + posAfterName - (state.bMarks[startLine] + state.tShift[startLine]) ) # find indent to start of body on first line while pos < maximum: ch = state.src[pos] if ch == "\t": first_line_body_indent += ( 4 - (first_line_body_indent + state.bsCount[nextLine]) % 4 ) elif ch == " ": first_line_body_indent += 1 else: break pos += 1 contentStart = pos # to figure out the indent of the body, # we look at all non-empty, indented lines and find the minimum indent block_indent: Optional[int] = None _line = startLine + 1 while _line < endLine: # if start_of_content < end_of_content, then non-empty line if (state.bMarks[_line] + state.tShift[_line]) < state.eMarks[_line]: if state.tShift[_line] <= 0: # the line has no indent, so it's the end of the field break block_indent = ( state.tShift[_line] if block_indent is None else min(block_indent, state.tShift[_line]) ) _line += 1 has_first_line = contentStart < maximum if block_indent is None: # no body content if not has_first_line: # noqa: SIM108 # no body or first line, so just use default block_indent = 2 else: # only a first line, so use it's indent block_indent = first_line_body_indent else: block_indent = min(block_indent, first_line_body_indent) # Run subparser on the field body token = state.push("fieldlist_body_open", "dd", 1) token.map = [startLine, startLine] with temp_state_changes(state, startLine): diff = 0 if has_first_line and block_indent < first_line_body_indent: # this is a hack to get the first line to render correctly # we temporarily "shift" it to the left by the difference # between the first line indent and the block indent # and replace the "hole" left with space, # so that src indexes still match diff = first_line_body_indent - block_indent state.src = ( state.src[: contentStart - diff] + " " * diff + state.src[contentStart:] ) state.tShift[startLine] = contentStart - diff - state.bMarks[startLine] state.sCount[startLine] = first_line_body_indent - diff state.blkIndent = block_indent state.md.block.tokenize(state, startLine, endLine) state.push("fieldlist_body_close", "dd", -1) nextLine = startLine = state.line token.map[1] = nextLine if nextLine >= endLine: break contentStart = state.bMarks[startLine] # Try to check if list is terminated or continued. if state.sCount[nextLine] < state.blkIndent: break if is_code_block(state, startLine): break # get next field item posAfterName, name_text = parseNameMarker(state, startLine) if posAfterName < 0: break # Finalize list token = state.push("field_list_close", "dl", -1) listLines[1] = nextLine state.line = nextLine return True @contextmanager def temp_state_changes(state: StateBlock, startLine: int) -> Iterator[None]: """Allow temporarily changing certain state attributes.""" oldTShift = state.tShift[startLine] oldSCount = state.sCount[startLine] oldBlkIndent = state.blkIndent oldSrc = state.src yield state.blkIndent = oldBlkIndent state.tShift[startLine] = oldTShift state.sCount[startLine] = oldSCount state.src = oldSrc �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/�����������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021647�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/LICENSE����������������������������������������������0000664�0000000�0000000�00000002066�14667654733�0022660�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2014-2015 Vitaly Puzrin, Alex Kocharin. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/__init__.py������������������������������������������0000664�0000000�0000000�00000000103�14667654733�0023752�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import footnote_plugin __all__ = ("footnote_plugin",) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/index.py���������������������������������������������0000664�0000000�0000000�00000034366�14667654733�0023344�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Process footnotes""" from __future__ import annotations from functools import partial from typing import TYPE_CHECKING, Sequence, TypedDict from markdown_it import MarkdownIt from markdown_it.helpers import parseLinkLabel from markdown_it.rules_block import StateBlock from markdown_it.rules_core import StateCore from markdown_it.rules_inline import StateInline from markdown_it.token import Token from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.utils import EnvType, OptionsDict def footnote_plugin( md: MarkdownIt, *, inline: bool = True, move_to_end: bool = True, always_match_refs: bool = False, ) -> None: """Plugin ported from `markdown-it-footnote <https://github.com/markdown-it/markdown-it-footnote>`__. It is based on the `pandoc definition <http://johnmacfarlane.net/pandoc/README.html#footnotes>`__: .. code-block:: md Normal footnote: Here is a footnote reference,[^1] and another.[^longnote] [^1]: Here is the footnote. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous footnote. :param inline: If True, also parse inline footnotes (^[...]). :param move_to_end: If True, move footnote definitions to the end of the token stream. :param always_match_refs: If True, match references, even if the footnote is not defined. """ md.block.ruler.before( "reference", "footnote_def", footnote_def, {"alt": ["paragraph", "reference"]} ) _footnote_ref = partial(footnote_ref, always_match=always_match_refs) if inline: md.inline.ruler.after("image", "footnote_inline", footnote_inline) md.inline.ruler.after("footnote_inline", "footnote_ref", _footnote_ref) else: md.inline.ruler.after("image", "footnote_ref", _footnote_ref) if move_to_end: md.core.ruler.after("inline", "footnote_tail", footnote_tail) md.add_render_rule("footnote_ref", render_footnote_ref) md.add_render_rule("footnote_block_open", render_footnote_block_open) md.add_render_rule("footnote_block_close", render_footnote_block_close) md.add_render_rule("footnote_open", render_footnote_open) md.add_render_rule("footnote_close", render_footnote_close) md.add_render_rule("footnote_anchor", render_footnote_anchor) # helpers (only used in other rules, no tokens are attached to those) md.add_render_rule("footnote_caption", render_footnote_caption) md.add_render_rule("footnote_anchor_name", render_footnote_anchor_name) class _RefData(TypedDict, total=False): # standard label: str count: int # inline content: str tokens: list[Token] class _FootnoteData(TypedDict): refs: dict[str, int] """A mapping of all footnote labels (prefixed with ``:``) to their ID (-1 if not yet set).""" list: dict[int, _RefData] """A mapping of all footnote IDs to their data.""" def _data_from_env(env: EnvType) -> _FootnoteData: footnotes = env.setdefault("footnotes", {}) footnotes.setdefault("refs", {}) footnotes.setdefault("list", {}) return footnotes # type: ignore[no-any-return] # ## RULES ## def footnote_def(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: """Process footnote block definition""" if is_code_block(state, startLine): return False start = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] # line should be at least 5 chars - "[^x]:" if start + 4 > maximum: return False if state.src[start] != "[": return False if state.src[start + 1] != "^": return False pos = start + 2 while pos < maximum: if state.src[pos] == " ": return False if state.src[pos] == "]": break pos += 1 if pos == start + 2: # no empty footnote labels return False pos += 1 if pos >= maximum or state.src[pos] != ":": return False if silent: return True pos += 1 label = state.src[start + 2 : pos - 2] footnote_data = _data_from_env(state.env) footnote_data["refs"][":" + label] = -1 open_token = Token("footnote_reference_open", "", 1) open_token.meta = {"label": label} open_token.level = state.level state.level += 1 state.tokens.append(open_token) oldBMark = state.bMarks[startLine] oldTShift = state.tShift[startLine] oldSCount = state.sCount[startLine] oldParentType = state.parentType posAfterColon = pos initial = offset = ( state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]) ) while pos < maximum: ch = state.src[pos] if ch == "\t": offset += 4 - offset % 4 elif ch == " ": offset += 1 else: break pos += 1 state.tShift[startLine] = pos - posAfterColon state.sCount[startLine] = offset - initial state.bMarks[startLine] = posAfterColon state.blkIndent += 4 state.parentType = "footnote" if state.sCount[startLine] < state.blkIndent: state.sCount[startLine] += state.blkIndent state.md.block.tokenize(state, startLine, endLine) state.parentType = oldParentType state.blkIndent -= 4 state.tShift[startLine] = oldTShift state.sCount[startLine] = oldSCount state.bMarks[startLine] = oldBMark open_token.map = [startLine, state.line] token = Token("footnote_reference_close", "", -1) state.level -= 1 token.level = state.level state.tokens.append(token) return True def footnote_inline(state: StateInline, silent: bool) -> bool: """Process inline footnotes (^[...])""" maximum = state.posMax start = state.pos if start + 2 >= maximum: return False if state.src[start] != "^": return False if state.src[start + 1] != "[": return False labelStart = start + 2 labelEnd = parseLinkLabel(state, start + 1) # parser failed to find ']', so it's not a valid note if labelEnd < 0: return False # We found the end of the link, and know for a fact it's a valid link # so all that's left to do is to call tokenizer. # if not silent: refs = _data_from_env(state.env)["list"] footnoteId = len(refs) tokens: list[Token] = [] state.md.inline.parse( state.src[labelStart:labelEnd], state.md, state.env, tokens ) token = state.push("footnote_ref", "", 0) token.meta = {"id": footnoteId} refs[footnoteId] = {"content": state.src[labelStart:labelEnd], "tokens": tokens} state.pos = labelEnd + 1 state.posMax = maximum return True def footnote_ref( state: StateInline, silent: bool, *, always_match: bool = False ) -> bool: """Process footnote references ([^...])""" maximum = state.posMax start = state.pos # should be at least 4 chars - "[^x]" if start + 3 > maximum: return False footnote_data = _data_from_env(state.env) if not (always_match or footnote_data["refs"]): return False if state.src[start] != "[": return False if state.src[start + 1] != "^": return False pos = start + 2 while pos < maximum: if state.src[pos] in (" ", "\n"): return False if state.src[pos] == "]": break pos += 1 if pos == start + 2: # no empty footnote labels return False if pos >= maximum: return False pos += 1 label = state.src[start + 2 : pos - 1] if ((":" + label) not in footnote_data["refs"]) and not always_match: return False if not silent: if footnote_data["refs"].get(":" + label, -1) < 0: footnoteId = len(footnote_data["list"]) footnote_data["list"][footnoteId] = {"label": label, "count": 0} footnote_data["refs"][":" + label] = footnoteId else: footnoteId = footnote_data["refs"][":" + label] footnoteSubId = footnote_data["list"][footnoteId]["count"] footnote_data["list"][footnoteId]["count"] += 1 token = state.push("footnote_ref", "", 0) token.meta = {"id": footnoteId, "subId": footnoteSubId, "label": label} state.pos = pos state.posMax = maximum return True def footnote_tail(state: StateCore) -> None: """Post-processing step, to move footnote tokens to end of the token stream. Also removes un-referenced tokens. """ insideRef = False refTokens = {} if "footnotes" not in state.env: return current: list[Token] = [] tok_filter = [] for tok in state.tokens: if tok.type == "footnote_reference_open": insideRef = True current = [] currentLabel = tok.meta["label"] tok_filter.append(False) continue if tok.type == "footnote_reference_close": insideRef = False # prepend ':' to avoid conflict with Object.prototype members refTokens[":" + currentLabel] = current tok_filter.append(False) continue if insideRef: current.append(tok) tok_filter.append(not insideRef) state.tokens = [t for t, f in zip(state.tokens, tok_filter) if f] footnote_data = _data_from_env(state.env) if not footnote_data["list"]: return token = Token("footnote_block_open", "", 1) state.tokens.append(token) for i, foot_note in footnote_data["list"].items(): token = Token("footnote_open", "", 1) token.meta = {"id": i, "label": foot_note.get("label", None)} # TODO propagate line positions of original foot note # (but don't store in token.map, because this is used for scroll syncing) state.tokens.append(token) if "tokens" in foot_note: tokens = [] token = Token("paragraph_open", "p", 1) token.block = True tokens.append(token) token = Token("inline", "", 0) token.children = foot_note["tokens"] token.content = foot_note["content"] tokens.append(token) token = Token("paragraph_close", "p", -1) token.block = True tokens.append(token) elif "label" in foot_note: tokens = refTokens.get(":" + foot_note["label"], []) state.tokens.extend(tokens) if state.tokens[len(state.tokens) - 1].type == "paragraph_close": lastParagraph: Token | None = state.tokens.pop() else: lastParagraph = None t = ( foot_note["count"] if (("count" in foot_note) and (foot_note["count"] > 0)) else 1 ) j = 0 while j < t: token = Token("footnote_anchor", "", 0) token.meta = {"id": i, "subId": j, "label": foot_note.get("label", None)} state.tokens.append(token) j += 1 if lastParagraph: state.tokens.append(lastParagraph) token = Token("footnote_close", "", -1) state.tokens.append(token) token = Token("footnote_block_close", "", -1) state.tokens.append(token) ######################################## # Renderer partials def render_footnote_anchor_name( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: n = str(tokens[idx].meta["id"] + 1) prefix = "" doc_id = env.get("docId", None) if isinstance(doc_id, str): prefix = f"-{doc_id}-" return prefix + n def render_footnote_caption( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: n = str(tokens[idx].meta["id"] + 1) if tokens[idx].meta.get("subId", -1) > 0: n += ":" + str(tokens[idx].meta["subId"]) return "[" + n + "]" def render_footnote_ref( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: ident: str = self.rules["footnote_anchor_name"](tokens, idx, options, env) # type: ignore[attr-defined] caption: str = self.rules["footnote_caption"](tokens, idx, options, env) # type: ignore[attr-defined] refid = ident if tokens[idx].meta.get("subId", -1) > 0: refid += ":" + str(tokens[idx].meta["subId"]) return ( '<sup class="footnote-ref"><a href="#fn' + ident + '" id="fnref' + refid + '">' + caption + "</a></sup>" ) def render_footnote_block_open( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: return ( ( '<hr class="footnotes-sep" />\n' if options.xhtmlOut else '<hr class="footnotes-sep">\n' ) + '<section class="footnotes">\n' + '<ol class="footnotes-list">\n' ) def render_footnote_block_close( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: return "</ol>\n</section>\n" def render_footnote_open( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: ident: str = self.rules["footnote_anchor_name"](tokens, idx, options, env) # type: ignore[attr-defined] if tokens[idx].meta.get("subId", -1) > 0: ident += ":" + tokens[idx].meta["subId"] return '<li id="fn' + ident + '" class="footnote-item">' def render_footnote_close( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: return "</li>\n" def render_footnote_anchor( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: ident: str = self.rules["footnote_anchor_name"](tokens, idx, options, env) # type: ignore[attr-defined] if tokens[idx].meta["subId"] > 0: ident += ":" + str(tokens[idx].meta["subId"]) # ↩ with escape code to prevent display as Apple Emoji on iOS return ' <a href="#fnref' + ident + '" class="footnote-backref">\u21a9\ufe0e</a>' ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/footnote/port.yaml��������������������������������������������0000664�0000000�0000000�00000000170�14667654733�0023515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-footnote commit: cab6665ba39c6eb517cbbae3baeb549004bf740c date: Jul 9, 2019 version: 3.0.2 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/front_matter/�������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022516�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/front_matter/LICENSE������������������������������������������0000664�0000000�0000000�00000002040�14667654733�0023517�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2016-2020 ParkSB. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/front_matter/__init__.py��������������������������������������0000664�0000000�0000000�00000000113�14667654733�0024622�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import front_matter_plugin __all__ = ("front_matter_plugin",) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/front_matter/index.py�����������������������������������������0000664�0000000�0000000�00000006440�14667654733�0024203�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Process front matter.""" from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block def front_matter_plugin(md: MarkdownIt) -> None: """Plugin ported from `markdown-it-front-matter <https://github.com/ParkSB/markdown-it-front-matter>`__. It parses initial metadata, stored between opening/closing dashes: .. code-block:: md --- valid-front-matter: true --- """ md.block.ruler.before( "table", "front_matter", _front_matter_rule, {"alt": ["paragraph", "reference", "blockquote", "list"]}, ) def _front_matter_rule( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: marker_chr = "-" min_markers = 3 auto_closed = False start = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] src_len = len(state.src) # Check out the first character of the first line quickly, # this should filter out non-front matter if startLine != 0 or state.src[0] != marker_chr: return False # Check out the rest of the marker string # while pos <= 3 pos = start + 1 while pos <= maximum and pos < src_len: if state.src[pos] != marker_chr: break pos += 1 marker_count = pos - start if marker_count < min_markers: return False # Since start is found, we can report success here in validation mode if silent: return True # Search for the end of the block nextLine = startLine while True: nextLine += 1 if nextLine >= endLine: # unclosed block should be autoclosed by end of document. return False if state.src[start:maximum] == "...": break start = state.bMarks[nextLine] + state.tShift[nextLine] maximum = state.eMarks[nextLine] if start < maximum and state.sCount[nextLine] < state.blkIndent: # non-empty line with negative indent should stop the list: # - ``` # test break if state.src[start] != marker_chr: continue if is_code_block(state, nextLine): continue pos = start + 1 while pos < maximum: if state.src[pos] != marker_chr: break pos += 1 # closing code fence must be at least as long as the opening one if (pos - start) < marker_count: continue # make sure tail has spaces only pos = state.skipSpaces(pos) if pos < maximum: continue # found! auto_closed = True break old_parent = state.parentType old_line_max = state.lineMax state.parentType = "container" # this will prevent lazy continuations from ever going past our end marker state.lineMax = nextLine token = state.push("front_matter", "", 0) token.hidden = True token.markup = marker_chr * min_markers token.content = state.src[state.bMarks[startLine + 1] : state.eMarks[nextLine - 1]] token.block = True state.parentType = old_parent state.lineMax = old_line_max state.line = nextLine + (1 if auto_closed else 0) token.map = [startLine, state.line] return True ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/front_matter/port.yaml����������������������������������������0000664�0000000�0000000�00000000174�14667654733�0024370�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-front-matter commit: b404f5d8fd536e7e9ddb276267ae0b6f76e9cf9d date: Feb 7, 2020 version: 0.2.1 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_blocks/��������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022343�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_blocks/__init__.py���������������������������������������0000664�0000000�0000000�00000000107�14667654733�0024452�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import myst_block_plugin __all__ = ("myst_block_plugin",) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_blocks/index.py������������������������������������������0000664�0000000�0000000�00000010730�14667654733�0024025�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import annotations import itertools from typing import TYPE_CHECKING, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml from markdown_it.rules_block import StateBlock from mdit_py_plugins.utils import is_code_block if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def myst_block_plugin(md: MarkdownIt) -> None: """Parse MyST targets (``(name)=``), blockquotes (``% comment``) and block breaks (``+++``).""" md.block.ruler.before( "blockquote", "myst_line_comment", line_comment, {"alt": ["paragraph", "reference", "blockquote", "list", "footnote_def"]}, ) md.block.ruler.before( "hr", "myst_block_break", block_break, {"alt": ["paragraph", "reference", "blockquote", "list", "footnote_def"]}, ) md.block.ruler.before( "hr", "myst_target", target, {"alt": ["paragraph", "reference", "blockquote", "list", "footnote_def"]}, ) md.add_render_rule("myst_target", render_myst_target) md.add_render_rule("myst_line_comment", render_myst_line_comment) def line_comment(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] if state.src[pos] != "%": return False if silent: return True token = state.push("myst_line_comment", "", 0) token.attrSet("class", "myst-line-comment") token.content = state.src[pos + 1 : maximum].rstrip() token.markup = "%" # search end of block while appending lines to `token.content` for nextLine in itertools.count(startLine + 1): if nextLine >= endLine: break pos = state.bMarks[nextLine] + state.tShift[nextLine] maximum = state.eMarks[nextLine] if state.src[pos] != "%": break token.content += "\n" + state.src[pos + 1 : maximum].rstrip() state.line = nextLine token.map = [startLine, nextLine] return True def block_break(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] marker = state.src[pos] pos += 1 # Check block marker if marker != "+": return False # markers can be mixed with spaces, but there should be at least 3 of them cnt = 1 while pos < maximum: ch = state.src[pos] if ch != marker and ch not in ("\t", " "): break if ch == marker: cnt += 1 pos += 1 if cnt < 3: return False if silent: return True state.line = startLine + 1 token = state.push("myst_block_break", "hr", 0) token.attrSet("class", "myst-block") token.content = state.src[pos:maximum].strip() token.map = [startLine, state.line] token.markup = marker * cnt return True def target(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: if is_code_block(state, startLine): return False pos = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] text = state.src[pos:maximum].strip() if not text.startswith("("): return False if not text.endswith(")="): return False if not text[1:-2]: return False if silent: return True state.line = startLine + 1 token = state.push("myst_target", "", 0) token.attrSet("class", "myst-target") token.content = text[1:-2] token.map = [startLine, state.line] return True def render_myst_target( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: label = tokens[idx].content class_name = "myst-target" target = f'<a href="#{label}">({label})=</a>' return f'<div class="{class_name}">{target}</div>' def render_myst_line_comment( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: # Strip leading whitespace from all lines content = "\n".join(line.lstrip() for line in tokens[idx].content.split("\n")) return f"<!-- {escapeHtml(content)} -->" ����������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_role/����������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022027�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_role/__init__.py�����������������������������������������0000664�0000000�0000000�00000000105�14667654733�0024134�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import myst_role_plugin __all__ = ("myst_role_plugin",) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/myst_role/index.py��������������������������������������������0000664�0000000�0000000�00000003763�14667654733�0023521�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import re from typing import TYPE_CHECKING, Sequence from markdown_it import MarkdownIt from markdown_it.common.utils import escapeHtml from markdown_it.rules_inline import StateInline if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict VALID_NAME_PATTERN = re.compile(r"^\{([a-zA-Z0-9\_\-\+\:]+)\}") def myst_role_plugin(md: MarkdownIt) -> None: """Parse ``{role-name}`content```""" md.inline.ruler.before("backticks", "myst_role", myst_role) md.add_render_rule("myst_role", render_myst_role) def myst_role(state: StateInline, silent: bool) -> bool: # check name match = VALID_NAME_PATTERN.match(state.src[state.pos :]) if not match: return False name = match.group(1) # check for starting backslash escape try: if state.src[state.pos - 1] == "\\": # escaped (this could be improved in the case of edge case '\\{') return False except IndexError: pass # scan opening tick length start = pos = state.pos + match.end() try: while state.src[pos] == "`": pos += 1 except IndexError: return False tick_length = pos - start if not tick_length: return False # search for closing ticks match = re.search("`" * tick_length, state.src[pos + 1 :]) if not match: return False content = state.src[pos : pos + match.start() + 1].replace("\n", " ") if not silent: token = state.push("myst_role", "", 0) token.meta = {"name": name} token.content = content state.pos = pos + match.end() + 1 return True def render_myst_role( self: "RendererProtocol", tokens: Sequence["Token"], idx: int, options: "OptionsDict", env: "EnvType", ) -> str: token = tokens[idx] name = token.meta.get("name", "unknown") return f'<code class="myst role">{{{name}}}[{escapeHtml(token.content)}]</code>' �������������mdit-py-plugins-0.4.2/mdit_py_plugins/py.typed������������������������������������������������������0000664�0000000�0000000�00000000032�14667654733�0021504�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Marker file for PEP 561 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/substitution.py�����������������������������������������������0000664�0000000�0000000�00000006062�14667654733�0023144�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from mdit_py_plugins.utils import is_code_block def substitution_plugin( md: MarkdownIt, start_delimiter: str = "{", end_delimiter: str = "}" ) -> None: """A plugin to create substitution tokens. These, token should be handled by the renderer. Example:: {{ block }} a {{ inline }} b """ def _substitution_inline(state: StateInline, silent: bool) -> bool: try: if ( state.src[state.pos] != start_delimiter or state.src[state.pos + 1] != start_delimiter ): return False except IndexError: return False pos = state.pos + 2 found_closing = False while True: try: end = state.src.index(end_delimiter, pos) except ValueError: return False try: if state.src[end + 1] == end_delimiter: found_closing = True break except IndexError: return False pos = end + 2 if not found_closing: return False text = state.src[state.pos + 2 : end].strip() state.pos = end + 2 if silent: return True token = state.push("substitution_inline", "span", 0) token.block = False token.content = text token.attrSet("class", "substitution") token.attrSet("text", text) token.markup = f"{start_delimiter}{end_delimiter}" return True def _substitution_block( state: StateBlock, startLine: int, endLine: int, silent: bool ) -> bool: if is_code_block(state, startLine): return False startPos = state.bMarks[startLine] + state.tShift[startLine] end = state.eMarks[startLine] lineText = state.src[startPos:end].strip() try: if ( lineText[0] != start_delimiter or lineText[1] != start_delimiter or lineText[-1] != end_delimiter or lineText[-2] != end_delimiter or len(lineText) < 5 ): return False except IndexError: return False text = lineText[2:-2].strip() # special case if multiple on same line, e.g. {{a}}{{b}} if (end_delimiter * 2) in text: return False state.line = startLine + 1 if silent: return True token = state.push("substitution_block", "div", 0) token.block = True token.content = text token.attrSet("class", "substitution") token.attrSet("text", text) token.markup = f"{start_delimiter}{end_delimiter}" token.map = [startLine, state.line] return True md.block.ruler.before("fence", "substitution_block", _substitution_block) md.inline.ruler.before("escape", "substitution_inline", _substitution_inline) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/tasklists/����������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022033�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/tasklists/__init__.py�����������������������������������������0000664�0000000�0000000�00000013206�14667654733�0024146�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Builds task/todo lists out of markdown lists with items starting with [ ] or [x]""" # Ported by Wolmar Nyberg Γ…kerstrΓΆm from https://github.com/revin/markdown-it-task-lists # ISC License # Copyright (c) 2016, Revin Guillen # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from __future__ import annotations import re from uuid import uuid4 from markdown_it import MarkdownIt from markdown_it.rules_core import StateCore from markdown_it.token import Token # Regex string to match a whitespace character, as specified in # https://github.github.com/gfm/#whitespace-character # (spec version 0.29-gfm (2019-04-06)) _GFM_WHITESPACE_RE = r"[ \t\n\v\f\r]" def tasklists_plugin( md: MarkdownIt, enabled: bool = False, label: bool = False, label_after: bool = False, ) -> None: """Plugin for building task/todo lists out of markdown lists with items starting with [ ] or [x] .. Nothing else For example:: - [ ] An item that needs doing - [x] An item that is complete The rendered HTML checkboxes are disabled; to change this, pass a truthy value into the enabled property of the plugin options. :param enabled: True enables the rendered checkboxes :param label: True wraps the rendered list items in a <label> element for UX purposes, :param label_after: True adds the <label> element after the checkbox. """ disable_checkboxes = not enabled use_label_wrapper = label use_label_after = label_after def fcn(state: StateCore) -> None: tokens = state.tokens for i in range(2, len(tokens) - 1): if is_todo_item(tokens, i): todoify(tokens[i]) tokens[i - 2].attrSet( "class", "task-list-item" + (" enabled" if not disable_checkboxes else ""), ) tokens[parent_token(tokens, i - 2)].attrSet( "class", "contains-task-list" ) md.core.ruler.after("inline", "github-tasklists", fcn) def parent_token(tokens: list[Token], index: int) -> int: target_level = tokens[index].level - 1 for i in range(1, index + 1): if tokens[index - i].level == target_level: return index - i return -1 def is_todo_item(tokens: list[Token], index: int) -> bool: return ( is_inline(tokens[index]) and is_paragraph(tokens[index - 1]) and is_list_item(tokens[index - 2]) and starts_with_todo_markdown(tokens[index]) ) def todoify(token: Token) -> None: assert token.children is not None token.children.insert(0, make_checkbox(token)) token.children[1].content = token.children[1].content[3:] token.content = token.content[3:] if use_label_wrapper: if use_label_after: token.children.pop() # Replaced number generator from original plugin with uuid. checklist_id = f"task-item-{uuid4()}" token.children[0].content = ( token.children[0].content[0:-1] + f' id="{checklist_id}">' ) token.children.append(after_label(token.content, checklist_id)) else: token.children.insert(0, begin_label()) token.children.append(end_label()) def make_checkbox(token: Token) -> Token: checkbox = Token("html_inline", "", 0) disabled_attr = 'disabled="disabled"' if disable_checkboxes else "" if token.content.startswith("[ ] "): checkbox.content = ( '<input class="task-list-item-checkbox" ' f'{disabled_attr} type="checkbox">' ) elif token.content.startswith("[x] ") or token.content.startswith("[X] "): checkbox.content = ( '<input class="task-list-item-checkbox" checked="checked" ' f'{disabled_attr} type="checkbox">' ) return checkbox def begin_label() -> Token: token = Token("html_inline", "", 0) token.content = "<label>" return token def end_label() -> Token: token = Token("html_inline", "", 0) token.content = "</label>" return token def after_label(content: str, checkbox_id: str) -> Token: token = Token("html_inline", "", 0) token.content = ( f'<label class="task-list-item-label" for="{checkbox_id}">{content}</label>' ) token.attrs = {"for": checkbox_id} return token def is_inline(token: Token) -> bool: return token.type == "inline" def is_paragraph(token: Token) -> bool: return token.type == "paragraph_open" def is_list_item(token: Token) -> bool: return token.type == "list_item_open" def starts_with_todo_markdown(token: Token) -> bool: # leading whitespace in a list item is already trimmed off by markdown-it return re.match(rf"\[[ xX]]{_GFM_WHITESPACE_RE}+", token.content) is not None ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/tasklists/port.yaml�������������������������������������������0000664�0000000�0000000�00000000303�14667654733�0023677�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-task-lists commit: 8233e000559fae5a6306009e55332a54a9d3f606 date: 6 Mar 2018 version: 2.1.1 changes: - Replaced number generator from original plugin with uuid �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021464�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/LICENSE�����������������������������������������������0000664�0000000�0000000�00000002063�14667654733�0022472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������MIT License Copyright (c) 2013-17 Stefan Goessner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/README.md���������������������������������������������0000664�0000000�0000000�00000012107�14667654733�0022744�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[![License](https://img.shields.io/github/license/goessner/markdown-it-texmath.svg)](https://github.com/goessner/markdown-it-texmath/blob/master/licence.txt) [![npm](https://img.shields.io/npm/v/markdown-it-texmath.svg)](https://www.npmjs.com/package/markdown-it-texmath) [![npm](https://img.shields.io/npm/dt/markdown-it-texmath.svg)](https://www.npmjs.com/package/markdown-it-texmath) # markdown-it-texmath Add TeX math equations to your Markdown documents rendered by [markdown-it](https://github.com/markdown-it/markdown-it) parser. [KaTeX](https://github.com/Khan/KaTeX) is used as a fast math renderer. ## Features Simplify the process of authoring markdown documents containing math formulas. This extension is a comfortable tool for scientists, engineers and students with markdown as their first choice document format. * Macro support * Simple formula numbering * Inline math with tables, lists and blockquote. * User setting delimiters: * `'dollars'` (default) * inline: `$...$` * display: `$$...$$` * display + equation number: `$$...$$ (1)` * `'brackets'` * inline: `\(...\)` * display: `\[...\]` * display + equation number: `\[...\] (1)` * `'gitlab'` * inline: ``$`...`$`` * display: `` ```math ... ``` `` * display + equation number: `` ```math ... ``` (1)`` * `'julia'` * inline: `$...$` or ``` ``...`` ``` * display: `` ```math ... ``` `` * display + equation number: `` ```math ... ``` (1)`` * `'kramdown'` * inline: ``$$...$$`` * display: `$$...$$` * display + equation number: `$$...$$ (1)` ## Show me View a [test table](https://goessner.github.io/markdown-it-texmath/index.html). [try it out ...](https://goessner.github.io/markdown-it-texmath/markdown-it-texmath-demo.html) ## Use with `node.js` Install the extension. Verify having `markdown-it` and `katex` already installed . ``` npm install markdown-it-texmath ``` Use it with JavaScript. ```js let kt = require('katex'), tm = require('markdown-it-texmath').use(kt), md = require('markdown-it')().use(tm,{delimiters:'dollars',macros:{"\\RR": "\\mathbb{R}"}}); md.render('Euler\'s identity \(e^{i\pi}+1=0\) is a beautiful formula in $\\RR 2$.') ``` ## Use in Browser ```html <html> <head> <meta charset='utf-8'> <link rel="stylesheet" href="katex.min.css"> <link rel="stylesheet" href="texmath.css"> <script src="markdown-it.min.js"></script> <script src="katex.min.js"></script> <script src="texmath.js"></script> </head> <body> <div id="out"></div> <script> let md; document.addEventListener("DOMContentLoaded", () => { const tm = texmath.use(katex); md = markdownit().use(tm,{delimiters:'dollars',macros:{"\\RR": "\\mathbb{R}"}}); out.innerHTML = md.render('Euler\'s identity $e^{i\pi}+1=0$ is a beautiful formula in //RR 2.'); }) </script> </body> </html> ``` ## CDN Use following links for `texmath.js` and `texmath.css` * `https://gitcdn.xyz/cdn/goessner/markdown-it-texmath/master/texmath.js` * `https://gitcdn.xyz/cdn/goessner/markdown-it-texmath/master/texmath.css` ## Dependencies * [`markdown-it`](https://github.com/markdown-it/markdown-it): Markdown parser done right. Fast and easy to extend. * [`katex`](https://github.com/Khan/KaTeX): This is where credits for fast rendering TeX math in HTML go to. ## ToDo nothing yet ## FAQ * __`markdown-it-texmath` with React Native does not work, why ?__ * `markdown-it-texmath` is using regular expressions with `y` [(sticky) property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky) and cannot avoid this. The use of the `y` flag in regular expressions means the plugin is not compatible with React Native (which as of now doesn't support it and throws an error `Invalid flags supplied to RegExp constructor`). ## CHANGELOG ### [0.6.0] on October 04, 2019 * Add support for [Julia Markdown](https://docs.julialang.org/en/v1/stdlib/Markdown/) on [request](https://github.com/goessner/markdown-it-texmath/issues/15). ### [0.5.5] on February 07, 2019 * Remove [rendering bug with brackets delimiters](https://github.com/goessner/markdown-it-texmath/issues/9). ### [0.5.4] on January 20, 2019 * Remove pathological [bug within blockquotes](https://github.com/goessner/mdmath/issues/50). ### [0.5.3] on November 11, 2018 * Add support for Tex macros (https://katex.org/docs/supported.html#macros) . * Bug with [brackets delimiters](https://github.com/goessner/markdown-it-texmath/issues/9) . ### [0.5.2] on September 07, 2018 * Add support for [Kramdown](https://kramdown.gettalong.org/) . ### [0.5.0] on August 15, 2018 * Fatal blockquote bug investigated. Implemented workaround to vscode bug, which has finally gone with vscode 1.26.0 . ### [0.4.6] on January 05, 2018 * Escaped underscore bug removed. ### [0.4.5] on November 06, 2017 * Backslash bug removed. ### [0.4.4] on September 27, 2017 * Modifying the `block` mode regular expression with `gitlab` delimiters, so removing the `newline` bug. ## License `markdown-it-texmath` is licensed under the [MIT License](./license.txt) Β© [Stefan GΓΆssner](https://github.com/goessner) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/__init__.py�������������������������������������������0000664�0000000�0000000�00000000101�14667654733�0023565�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .index import texmath_plugin __all__ = ("texmath_plugin",) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/index.py����������������������������������������������0000664�0000000�0000000�00000025104�14667654733�0023147�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import annotations import re from typing import TYPE_CHECKING, Any, Callable, Match, Sequence, TypedDict from markdown_it import MarkdownIt from markdown_it.common.utils import charCodeAt if TYPE_CHECKING: from markdown_it.renderer import RendererProtocol from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from markdown_it.token import Token from markdown_it.utils import EnvType, OptionsDict def texmath_plugin( md: MarkdownIt, delimiters: str = "dollars", macros: Any = None ) -> None: """Plugin ported from `markdown-it-texmath <https://github.com/goessner/markdown-it-texmath>`__. It parses TeX math equations set inside opening and closing delimiters: .. code-block:: md $\\alpha = \\frac{1}{2}$ :param delimiters: one of: brackets, dollars, gitlab, julia, kramdown """ macros = macros or {} if delimiters in rules: for rule_inline in rules[delimiters]["inline"]: md.inline.ruler.before( "escape", rule_inline["name"], make_inline_func(rule_inline) ) def render_math_inline( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: return rule_inline["tmpl"].format( # noqa: B023 render(tokens[idx].content, False, macros) ) md.add_render_rule(rule_inline["name"], render_math_inline) for rule_block in rules[delimiters]["block"]: md.block.ruler.before( "fence", rule_block["name"], make_block_func(rule_block) ) def render_math_block( self: RendererProtocol, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType, ) -> str: return rule_block["tmpl"].format( # noqa: B023 render(tokens[idx].content, True, macros), tokens[idx].info ) md.add_render_rule(rule_block["name"], render_math_block) class _RuleDictReqType(TypedDict): name: str rex: re.Pattern[str] tmpl: str tag: str class RuleDictType(_RuleDictReqType, total=False): # Note in Python 3.10+ could use Req annotation pre: Any post: Any def applyRule( rule: RuleDictType, string: str, begin: int, inBlockquote: bool ) -> None | Match[str]: if not ( string.startswith(rule["tag"], begin) and (rule["pre"](string, begin) if "pre" in rule else True) ): return None match = rule["rex"].match(string[begin:]) if not match or match.start() != 0: return None lastIndex = match.end() + begin - 1 if "post" in rule and not ( rule["post"](string, lastIndex) # valid post-condition # remove evil blockquote bug (https:#github.com/goessner/mdmath/issues/50) and (not inBlockquote or "\n" not in match.group(1)) ): return None return match def make_inline_func(rule: RuleDictType) -> Callable[[StateInline, bool], bool]: def _func(state: StateInline, silent: bool) -> bool: res = applyRule(rule, state.src, state.pos, False) if res: if not silent: token = state.push(rule["name"], "math", 0) token.content = res[1] # group 1 from regex .. token.markup = rule["tag"] state.pos += res.end() return bool(res) return _func def make_block_func(rule: RuleDictType) -> Callable[[StateBlock, int, int, bool], bool]: def _func(state: StateBlock, begLine: int, endLine: int, silent: bool) -> bool: begin = state.bMarks[begLine] + state.tShift[begLine] res = applyRule(rule, state.src, begin, state.parentType == "blockquote") if res: if not silent: token = state.push(rule["name"], "math", 0) token.block = True token.content = res[1] token.info = res[len(res.groups())] token.markup = rule["tag"] line = begLine endpos = begin + res.end() - 1 while line < endLine: if endpos >= state.bMarks[line] and endpos <= state.eMarks[line]: # line for end of block math found ... state.line = line + 1 break line += 1 return bool(res) return _func def dollar_pre(src: str, beg: int) -> bool: prv = charCodeAt(src[beg - 1], 0) if beg > 0 else False return ( (not prv) or prv != 0x5C and (prv < 0x30 or prv > 0x39) # no backslash, ) # no decimal digit .. before opening '$' def dollar_post(src: str, end: int) -> bool: try: nxt = src[end + 1] and charCodeAt(src[end + 1], 0) except IndexError: return True return ( (not nxt) or (nxt < 0x30) or (nxt > 0x39) ) # no decimal digit .. after closing '$' def render(tex: str, displayMode: bool, macros: Any) -> str: return tex # TODO better HTML renderer port for math # try: # res = katex.renderToString(tex,{throwOnError:False,displayMode,macros}) # except: # res = tex+": "+err.message.replace("<","<") # return res # def use(katex): # math renderer used ... # texmath.katex = katex; # ... katex solely at current ... # return texmath; # } # All regexes areg global (g) and sticky (y), see: # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky rules: dict[str, dict[str, list[RuleDictType]]] = { "brackets": { "inline": [ { "name": "math_inline", "rex": re.compile(r"^\\\((.+?)\\\)", re.DOTALL), "tmpl": "<eq>{0}</eq>", "tag": "\\(", } ], "block": [ { "name": "math_block_eqno", "rex": re.compile( r"^\\\[(((?!\\\]|\\\[)[\s\S])+?)\\\]\s*?\(([^)$\r\n]+?)\)", re.M ), "tmpl": '<section class="eqno"><eqn>{0}</eqn><span>({1})</span></section>', "tag": "\\[", }, { "name": "math_block", "rex": re.compile(r"^\\\[([\s\S]+?)\\\]", re.M), "tmpl": "<section>\n<eqn>{0}</eqn>\n</section>\n", "tag": "\\[", }, ], }, "gitlab": { "inline": [ { "name": "math_inline", "rex": re.compile(r"^\$`(.+?)`\$"), "tmpl": "<eq>{0}</eq>", "tag": "$`", } ], "block": [ { "name": "math_block_eqno", "rex": re.compile( r"^`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)", re.M ), "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', "tag": "```math", }, { "name": "math_block", "rex": re.compile(r"^`{3}math\s+?([^`]+?)\s+?`{3}", re.M), "tmpl": "<section>\n<eqn>{0}</eqn>\n</section>\n", "tag": "```math", }, ], }, "julia": { "inline": [ { "name": "math_inline", "rex": re.compile(r"^`{2}([^`]+?)`{2}"), "tmpl": "<eq>{0}</eq>", "tag": "``", }, { "name": "math_inline", "rex": re.compile(r"^\$(\S[^$\r\n]*?[^\s\\]{1}?)\$"), "tmpl": "<eq>{0}</eq>", "tag": "$", "pre": dollar_pre, "post": dollar_post, }, { "name": "math_single", "rex": re.compile(r"^\$([^$\s\\]{1}?)\$"), "tmpl": "<eq>{0}</eq>", "tag": "$", "pre": dollar_pre, "post": dollar_post, }, ], "block": [ { "name": "math_block_eqno", "rex": re.compile( r"^`{3}math\s+?([^`]+?)\s+?`{3}\s*?\(([^)$\r\n]+?)\)", re.M ), "tmpl": '<section class="eqno"><eqn>{0}</eqn><span>({1})</span></section>', "tag": "```math", }, { "name": "math_block", "rex": re.compile(r"^`{3}math\s+?([^`]+?)\s+?`{3}", re.M), "tmpl": "<section><eqn>{0}</eqn></section>", "tag": "```math", }, ], }, "kramdown": { "inline": [ { "name": "math_inline", "rex": re.compile(r"^\${2}([^$\r\n]*?)\${2}"), "tmpl": "<eq>{0}</eq>", "tag": "$$", } ], "block": [ { "name": "math_block_eqno", "rex": re.compile(r"^\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)", re.M), "tmpl": '<section class="eqno"><eqn>{0}</eqn><span>({1})</span></section>', "tag": "$$", }, { "name": "math_block", "rex": re.compile(r"^\${2}([^$]*?)\${2}", re.M), "tmpl": "<section><eqn>{0}</eqn></section>", "tag": "$$", }, ], }, "dollars": { "inline": [ { "name": "math_inline", "rex": re.compile(r"^\$(\S[^$]*?[^\s\\]{1}?)\$"), "tmpl": "<eq>{0}</eq>", "tag": "$", "pre": dollar_pre, "post": dollar_post, }, { "name": "math_single", "rex": re.compile(r"^\$([^$\s\\]{1}?)\$"), "tmpl": "<eq>{0}</eq>", "tag": "$", "pre": dollar_pre, "post": dollar_post, }, ], "block": [ { "name": "math_block_eqno", "rex": re.compile(r"^\${2}([^$]*?)\${2}\s*?\(([^)$\r\n]+?)\)", re.M), "tmpl": '<section class="eqno">\n<eqn>{0}</eqn><span>({1})</span>\n</section>\n', "tag": "$$", }, { "name": "math_block", "rex": re.compile(r"^\${2}([^$]*?)\${2}", re.M), "tmpl": "<section>\n<eqn>{0}</eqn>\n</section>\n", "tag": "$$", }, ], }, } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/texmath/port.yaml���������������������������������������������0000664�0000000�0000000�00000000365�14667654733�0023340�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- package: markdown-it-texmath commit: 78c548829ce2ef85c73dc71e680d01e5ae41ffbf date: Oct 4, 2019 version: 0.6 changes: | both dollars/math_inline and brackets/math_inline regexes have been changed, to allow (single) line breaks ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/utils.py������������������������������������������������������0000664�0000000�0000000�00000000554�14667654733�0021530�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from markdown_it.rules_block import StateBlock def is_code_block(state: StateBlock, line: int) -> bool: """Check if the line is part of a code block, compat for markdown-it-py v2.""" try: # markdown-it-py v3+ return state.is_code_block(line) except AttributeError: pass return (state.sCount[line] - state.blkIndent) >= 4 ����������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/wordcount/����������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0022036�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/mdit_py_plugins/wordcount/__init__.py�����������������������������������������0000664�0000000�0000000�00000003377�14667654733�0024161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import string from typing import Callable, List from markdown_it import MarkdownIt from markdown_it.rules_core import StateCore def basic_count(text: str) -> int: """Split the string and ignore punctuation only elements.""" return sum([el.strip(string.punctuation).isalpha() for el in text.split()]) def wordcount_plugin( md: MarkdownIt, *, per_minute: int = 200, count_func: Callable[[str], int] = basic_count, store_text: bool = False, ) -> None: """Plugin for computing and storing the word count. Stores in the ``env`` e.g.:: env["wordcount"] = { "words": 200 "minutes": 1, } If "wordcount" is already in the env, it will update it. :param per_minute: Words per minute reading speed :param store_text: store all text under a "text" key, as a list of strings """ def _word_count_rule(state: StateCore) -> None: text: List[str] = [] words = 0 for token in state.tokens: if token.type == "text": words += count_func(token.content) if store_text: text.append(token.content) elif token.type == "inline": for child in token.children or (): if child.type == "text": words += count_func(child.content) if store_text: text.append(child.content) data = state.env.setdefault("wordcount", {}) if store_text: data.setdefault("text", []) data["text"] += text data.setdefault("words", 0) data["words"] += words data["minutes"] = int(round(data["words"] / per_minute)) md.core.ruler.push("wordcount", _word_count_rule) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/pyproject.toml����������������������������������������������������������������0000664�0000000�0000000�00000004442�14667654733�0017524�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[build-system] requires = ["flit_core >=3.4,<4"] build-backend = "flit_core.buildapi" [project] name = "mdit-py-plugins" dynamic = ["version"] description = "Collection of plugins for markdown-it-py" readme = "README.md" authors = [{name = "Chris Sewell", email = "chrisj_sewell@hotmail.com"}] license = {file = "LICENSE"} classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup", ] keywords = ["markdown", "markdown-it", "lexer", "parser", "development"] requires-python = ">=3.8" dependencies = ["markdown-it-py>=1.0.0,<4.0.0"] [project.urls] Homepage = "https://github.com/executablebooks/mdit-py-plugins" Documentation = "https://mdit-py-plugins.readthedocs.io" [project.optional-dependencies] code_style = ["pre-commit"] testing = [ "coverage", "pytest", "pytest-cov", "pytest-regressions", ] rtd = [ "myst-parser", "sphinx-book-theme", ] [tool.flit.module] name = "mdit_py_plugins" [tool.flit.sdist] exclude = [ "docs/", "tests/", ] [tool.ruff.lint] extend-select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions "I", # isort "ICN", # flake8-import-conventions "ISC", # flake8-implicit-str-concat "N", # pep8-naming "PERF", # perflint (performance anti-patterns) "PGH", # pygrep-hooks "PIE", # flake8-pie "PTH", # flake8-use-pathlib "RUF", # Ruff-specific rules "SIM", # flake8-simplify "UP", # pyupgrade "T20", # flake8-print ] extend-ignore = ["ISC001", "N802", "N803", "N806"] [tool.ruff.lint.per-file-ignores] "tests/**.py" = ["T201"] [tool.ruff.lint.isort] force-sort-within-sections = true [tool.mypy] show_error_codes = true warn_unused_ignores = true warn_redundant_casts = true strict = true ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/������������������������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0015746�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/���������������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0017617�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/admon.md�������������������������������������������������������0000664�0000000�0000000�00000010531�14667654733�0021237�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Simple admonition . !!! note *content* . <div class="admonition note"> <p class="admonition-title">Note</p> <p><em>content</em></p> </div> . Could contain block elements too . !!! note ### heading ----------- . <div class="admonition note"> <p class="admonition-title">Note</p> <h3>heading</h3> <hr> </div> . Shows custom title . !!! note Custom title Some text . <div class="admonition note"> <p class="admonition-title">Custom title</p> <p>Some text</p> </div> . Shows no title . !!! note "" Some text . <div class="admonition note"> <p>Some text</p> </div> . Removes extra quotes from the title . !!! danger "Don't try this at home" ... . <div class="admonition danger"> <p class="admonition-title">Don't try this at home</p> <p>...</p> </div> . Parse additional classes to support Python markdown (https://github.com/executablebooks/mdit-py-plugins/issues/93#issuecomment-1601822723) . !!! a b c d inline-classes "Note: note about "foo"" ... . <div class="admonition a b c d inline-classes"> <p class="admonition-title">Note: note about "foo"</p> <p>...</p> </div> . Closes block after 2 empty lines . !!! note Some text A code block . <div class="admonition note"> <p class="admonition-title">Note</p> <p>Some text</p> </div> <pre><code>A code block </code></pre> . Nested blocks . !!! note !!! note Some text code block . <div class="admonition note"> <p class="admonition-title">Note</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Some text</p> <pre><code>code block </code></pre> </div> </div> . Consecutive admonitions . !!! note !!! warning . <div class="admonition note"> <p class="admonition-title">Note</p> </div> <div class="admonition warning"> <p class="admonition-title">Warning</p> </div> . Marker may be indented up to 3 chars . !!! note content . <div class="admonition note"> <p class="admonition-title">Note</p> <p>content</p> </div> . But that's a code block . !!! note content . <pre><code>!!! note content </code></pre> . Some more indent checks . !!! note not a code block code block . <div class="admonition note"> <p class="admonition-title">Note</p> </div> <p>not a code block</p> <pre><code>code block </code></pre> . Type could be adjacent to marker . !!!note xxx . <div class="admonition note"> <p class="admonition-title">Note</p> <p>xxx</p> </div> . Type could be adjacent to marker and content may be shifted up to 3 chars . !!!note xxx . <div class="admonition note"> <p class="admonition-title">Note</p> <p>xxx</p> </div> . Or several spaces apart . !!! note xxx . <div class="admonition note"> <p class="admonition-title">Note</p> <p>xxx</p> </div> . Admonitions self-close at the end of the document . !!! note xxx . <div class="admonition note"> <p class="admonition-title">Note</p> <p>xxx</p> </div> . They could be nested in lists . - !!! note - a - b - !!! warning - c - d . <ul> <li> <div class="admonition note"> <p class="admonition-title">Note</p> <ul> <li>a</li> <li>b</li> </ul> </div> </li> <li> <div class="admonition warning"> <p class="admonition-title">Warning</p> <ul> <li>c</li> <li>d</li> </ul> </div> </li> </ul> . Or in blockquotes . > !!! note > xxx > > yyy > zzz > . <blockquote> <div class="admonition note"> <p class="admonition-title">Note</p> <p>xxx</p> <blockquote> <p>yyy zzz</p> </blockquote> </div> </blockquote> . Renders unknown admonition type . !!! unknown title content . <div class="admonition unknown"> <p class="admonition-title">title</p> <p>content</p> </div> . Does not render . !!! content . <p>!!! content</p> . MKdocs Closed Collapsible Sections . ??? note content . <div class="admonition note is-collapsible collapsible-closed"> <p class="admonition-title">Note</p> <p>content</p> </div> . MKdocs Open Collapsible Sections . ???+ note content . <div class="admonition note is-collapsible collapsible-open"> <p class="admonition-title">Note</p> <p>content</p> </div> . Indented by 4 spaces . ??? note content . <pre><code>??? note content </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . ??? note content . <div class="admonition note is-collapsible collapsible-closed"> <p class="admonition-title">Note</p> <p>content</p> </div> . �����������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/amsmath.md�����������������������������������������������������0000664�0000000�0000000�00000010242�14667654733�0021572�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������equation environment: . \begin{equation} a = 1 \end{equation} . <div class="math amsmath"> \begin{equation} a = 1 \end{equation} </div> . equation environment on one line: . \begin{equation}a = 1\end{equation} . <div class="math amsmath"> \begin{equation}a = 1\end{equation} </div> . equation* environment: . \begin{equation*} a = 1 \end{equation*} . <div class="math amsmath"> \begin{equation*} a = 1 \end{equation*} </div> . multline environment: . \begin{multline} a = 1 \end{multline} . <div class="math amsmath"> \begin{multline} a = 1 \end{multline} </div> . multline* environment: . \begin{multline*} a = 1 \end{multline*} . <div class="math amsmath"> \begin{multline*} a = 1 \end{multline*} </div> . gather environment: . \begin{gather} a = 1 \end{gather} . <div class="math amsmath"> \begin{gather} a = 1 \end{gather} </div> . gather* environment: . \begin{gather*} a = 1 \end{gather*} . <div class="math amsmath"> \begin{gather*} a = 1 \end{gather*} </div> . align environment: . \begin{align} a = 1 \end{align} . <div class="math amsmath"> \begin{align} a = 1 \end{align} </div> . align* environment: . \begin{align*} a = 1 \end{align*} . <div class="math amsmath"> \begin{align*} a = 1 \end{align*} </div> . alignat environment: . \begin{alignat} a = 1 \end{alignat} . <div class="math amsmath"> \begin{alignat} a = 1 \end{alignat} </div> . alignat* environment: . \begin{alignat*} a = 1 \end{alignat*} . <div class="math amsmath"> \begin{alignat*} a = 1 \end{alignat*} </div> . flalign environment: . \begin{flalign} a = 1 \end{flalign} . <div class="math amsmath"> \begin{flalign} a = 1 \end{flalign} </div> . flalign* environment: . \begin{flalign*} a = 1 \end{flalign*} . <div class="math amsmath"> \begin{flalign*} a = 1 \end{flalign*} </div> . equation environment, with before/after paragraphs: . before \begin{equation} a = 1 \end{equation} after . <p>before</p> <div class="math amsmath"> \begin{equation} a = 1 \end{equation} </div> <p>after</p> . equation environment, in list: . - \begin{equation} a = 1 \end{equation} . <ul> <li> <div class="math amsmath"> \begin{equation} a = 1 \end{equation} </div> </li> </ul> . equation environment, in block quote: . > \begin{matrix} > -0.707 & 0.408 & 0.577 \\ > -0.707 & -0.408 & -0.577 \\ > -0. & -0.816 & 0.577 > \end{matrix} > \begin{equation} a = 1 \end{equation} . <blockquote> <div class="math amsmath"> \begin{matrix} -0.707 & 0.408 & 0.577 \\ -0.707 & -0.408 & -0.577 \\ -0. & -0.816 & 0.577 \end{matrix} </div> </blockquote> <blockquote> <div class="math amsmath"> \begin{equation} a = 1 \end{equation} </div> </blockquote> . `alignat` environment and HTML escaping . \begin{alignat}{3} & d = \frac{1}{1 + 0.2316419x} \quad && a_1 = 0.31938153 \quad && a_2 = -0.356563782 \\ & a_3 = 1.781477937 \quad && a_4 = -1.821255978 \quad && a_5 = 1.330274429 \end{alignat} . <div class="math amsmath"> \begin{alignat}{3} & d = \frac{1}{1 + 0.2316419x} \quad && a_1 = 0.31938153 \quad && a_2 = -0.356563782 \\ & a_3 = 1.781477937 \quad && a_4 = -1.821255978 \quad && a_5 = 1.330274429 \end{alignat} </div> . `alignat*` environment and HTML escaping . \begin{alignat*}{3} & m \quad && \text{mΓ³dulo} \quad && m>0\\ & a \quad && \text{multiplicador} \quad && 0<a<m\\ & c \quad && \text{constante aditiva} \quad && 0\leq c<m\\ & x_0 \quad && \text{valor inicial} \quad && 0\leq x_0 <m \end{alignat*} . <div class="math amsmath"> \begin{alignat*}{3} & m \quad && \text{mΓ³dulo} \quad && m>0\\ & a \quad && \text{multiplicador} \quad && 0<a<m\\ & c \quad && \text{constante aditiva} \quad && 0\leq c<m\\ & x_0 \quad && \text{valor inicial} \quad && 0\leq x_0 <m \end{alignat*} </div> . Indented by 4 spaces . \begin{equation} a = 1 \end{equation} . <pre><code>\begin{equation} a = 1 \end{equation} </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . \begin{equation} a = 1 \end{equation} . <div class="math amsmath"> \begin{equation} a = 1 \end{equation} </div> . ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/anchors.md�����������������������������������������������������0000664�0000000�0000000�00000001145�14667654733�0021577�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������basic (max level 2): . # H1 ## H2 ### H3 . <h1 id="h1">H1</h1> <h2 id="h2">H2</h2> <h3>H3</h3> . space: . # a b c . <h1 id="a-b--c">a b c</h1> . characters: . # a,b\cβÊ . <h1 id="abcΞ²Γͺ">a,b\cβÊ</h1> . emoji: . # πŸš€a . <h1 id="a">πŸš€a</h1> . html entity: . # foo&bar . <h1 id="foobar">foo&bar</h1> . uniqueness: . # a # a ## a . <h1 id="a">a</h1> <h1 id="a-1">a</h1> <h2 id="a-2">a</h2> . standard (permalink after): . # a . <h1 id="a">a <a class="header-anchor" href="#a">ΒΆ</a></h1> . standard (permalink before): . # a . <h1 id="a"><a class="header-anchor" href="#a">ΒΆ</a> a</h1> . ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/attrs.md�������������������������������������������������������0000664�0000000�0000000�00000005530�14667654733�0021301�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������block with preceding text is not a block . {#a .a b=c} a . <p>{#a .a b=c} a</p> . block no preceding . {#a .a c=1} . . block basic . {#a .a c=1} a . <p id="a" c="1" class="a">a</p> . multiple blocks . {#a .a c=1} {#b .b c=2} a . <p id="b" c="2" class="a b">a</p> . block list . {#a .a c=1} - a . <ul id="a" c="1" class="a"> <li>a</li> </ul> . block quote . {#a .a c=1} > a . <blockquote id="a" c="1" class="a"> <p>a</p> </blockquote> . block fence . {#a .b c=1} ```python a = 1 ``` . <pre><code id="a" c="1" class="b language-python">a = 1 </code></pre> . block after paragraph . a {#a .a c=1} . <p>a {#a .a c=1}</p> . simple reference link . [text *emphasis*](a){#id .a} . <p><a href="a" id="id" class="a">text <em>emphasis</em></a></p> . simple definition link . [a][]{#id .b} [a]: /url . <p><a href="/url" id="id" class="b">a</a></p> . simple image . ![a](b){#id .a b=c} . <p><img src="b" alt="a" id="id" b="c" class="a"></p> . simple inline code . `a`{#id .a b=c} . <p><code id="id" b="c" class="a">a</code></p> . ignore if space . ![a](b) {#id key="*"} . <p><img src="b" alt="a"> {#id key="*"}</p> . ignore if text . ![a](b)b{#id key="*"} . <p><img src="b" alt="a">b{#id key="*"}</p> . multi-line . ![a](b){ #id .a b=c } more . <p><img src="b" alt="a" id="id" b="c" class="a"> more</p> . merging attributes . ![a](b){#a .a}{.b class=x other=h}{#x class="x g" other=a} . <p><img src="b" alt="a" id="x" class="a b x x g" other="a"></p> . spans: simple . [a]{#id .b}c . <p><span id="id" class="b">a</span>c</p> . spans: end of inline before attrs . [a] . <p>[a]</p> . spans: space between brace and attrs . [a] {.b} . <p>[a] {.b}</p> . spans: escaped span start . \[a]{.b} . <p>[a]{.b}</p> . spans: escaped span end . [a\]{.b} . <p>[a]{.b}</p> . spans: escaped span attribute . [a]\{.b} . <p>[a]{.b}</p> . spans: nested text syntax . [*a*]{.b}c . <p><span class="b"><em>a</em></span>c</p> . spans: nested span . *[a]{.b}c* . <p><em><span class="b">a</span>c</em></p> . spans: multi-line . x [a b]{#id b=c} y . <p>x <span id="id" b="c">a b</span> y</p> . spans: nested spans . [[a]{.b}]{.c} . <p><span class="c"><span class="b">a</span></span></p> . spans: short link takes precedence over span . [a]{#id .b} [a]: /url . <p><a href="/url" id="id" class="b">a</a></p> . spans: long link takes precedence over span . [a][a]{#id .b} [a]: /url . <p><a href="/url" id="id" class="b">a</a></p> . spans: link inside span . [[a]]{#id .b} [a]: /url . <p><span id="id" class="b"><a href="/url">a</a></span></p> . spans: merge attributes . [a]{#a .a}{#b .a .b other=c}{other=d} . <p><span id="b" class="a b" other="d">a</span></p> . Indented by 4 spaces . {#a .a b=c} # head . <pre><code>{#a .a b=c} # head </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . {#a .a b=c} # head . <h1 id="a" b="c" class="a">head</h1> . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/colon_fence.md�������������������������������������������������0000664�0000000�0000000�00000010244�14667654733�0022414�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# The initial tests are adapted from the test for normal code fences in tests/test_port/fixtures/commonmark_spec.md src line: 1638 . ::: < > ::: . <pre><code>< > </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1665 . :: foo :: . <p>:: foo ::</p> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1676 . ::: aaa ~~~ ::: . <pre><code>aaa ~~~ </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1688 . ::: aaa ``` ::: . <pre><code>aaa ``` </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1702 . :::: aaa ::: :::::: . <pre><code>aaa ::: </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1729 . ::: . <pre><code></code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1736 . ::::: ::: aaa . <pre><code> ::: aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1749 . > ::: > aaa bbb . <blockquote> <pre><code>aaa </code></pre> </blockquote> <p>bbb</p> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1765 . ::: ::: . <pre><code> </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1779 . ::: ::: . <pre><code></code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1791 . ::: aaa aaa ::: . <pre><code>aaa aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1803 . ::: aaa aaa aaa ::: . <pre><code>aaa aaa aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1817 . ::: aaa aaa aaa ::: . <pre><code>aaa aaa aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1833 . ::: aaa ::: . <pre><code>::: aaa ::: </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1848 . ::: aaa ::: . <pre><code>aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1858 . ::: aaa ::: . <pre><code>aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1870 . ::: aaa ::: . <pre><code>aaa ::: </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1884 . ::: ::: aaa . <pre><code class="block-:::" >aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1907 . foo ::: bar ::: baz . <p>foo</p> <pre><code>bar </code></pre> <p>baz</p> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1946 . :::ruby def foo(x) return 3 end ::: . <pre><code class="block-ruby" >def foo(x) return 3 end </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1974 . ::::; :::: . <pre><code class="block-;" ></code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 1984 . ::: aa ::: foo . <pre><code class="block-aa" >foo </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 2007 . ::: ::: aaa ::: . <pre><code>::: aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src line: 2007 . ::: ::: aaa ::: . <pre><code>::: aaa </code></pre> . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ending marker could be longer . ::::: name ::::: hello world :::::::::::::::: . <pre><code class="block-name" > hello world </code></pre> . Nested blocks . ::::: name :::: name xxx :::: ::::: . <pre><code class="block-name" >:::: name xxx :::: </code></pre> . Name could be adjacent to marker . :::name xxx ::: . <pre><code class="block-name" >xxx </code></pre> . They should terminate paragraphs . blah blah ::: name content ::: . <p>blah blah</p> <pre><code class="block-name" >content </code></pre> . They could be nested in lists . - ::: name - xxx ::: . <ul> <li> <pre><code class="block-name" >- xxx </code></pre> </li> </ul> . Or in blockquotes . > ::: name > xxx >> yyy > zzz > ::: . <blockquote> <pre><code class="block-name" >xxx > yyy zzz </code></pre> </blockquote> . List indentation quirks . - ::: name xxx yyy ::: - ::: name xxx yyy ::: . <ul> <li> <pre><code class="block-name" >xxx yyy </code></pre> </li> </ul> <pre><code> - ::: name xxx yyy </code></pre> . Indented by 4 spaces . :::name foo ::: . <pre><code>:::name foo ::: </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . :::name foo ::: . <pre><code class="block-name" >foo </code></pre> . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/container.md���������������������������������������������������0000664�0000000�0000000�00000005273�14667654733�0022132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Simple container . ::: name *content* ::: . <div class="name"> <p><em>content</em></p> </div> . Delimiters too short . :: name *content* :: . <p>:: name <em>content</em> ::</p> . Could contain block elements too . ::: name ### heading ----------- ::: . <div class="name"> <h3>heading</h3> <hr> </div> . Ending marker could be longer . ::::: name ::::: hello world :::::::::::::::: . <div class="name"> <p>hello world</p> </div> . Nested blocks . ::::: name :::: name xxx :::: ::::: . <div class="name"> <div class="name"> <p>xxx</p> </div> </div> . Incorrectly nested blocks . :::: name this block is closed with 5 markers below ::::: name auto-closed block ::::: :::: . <div class="name"> <p>this block is closed with 5 markers below</p> <div class="name"> <p>auto-closed block</p> </div> </div> <p>::::</p> . Marker could be indented up to 3 spaces . ::: name content ::: ::: . <div class="name"> <p>content :::</p> </div> . But that's a code block . ::: name content ::: . <pre><code>::: name content ::: </code></pre> . Some more indent checks . ::: name not a code block code block ::: . <div class="name"> <p>not a code block</p> <pre><code>code block </code></pre> </div> . Name could be adjacent to marker . :::name xxx ::: . <div class="name"> <p>xxx</p> </div> . Or several spaces apart . ::: name xxx ::: . <div class="name"> <p>xxx</p> </div> . It could contain params . ::: name arg=123 foo=456 xxx ::: . <div class="name"> <p>xxx</p> </div> . But closing marker can't . ::: name xxx ::: arg=123 . <div class="name"> <p>xxx ::: arg=123</p> </div> . This however isn't a valid one . ::: namename xxx ::: . <p>::: namename xxx :::</p> . Containers self-close at the end of the document . ::: name xxx . <div class="name"> <p>xxx</p> </div> . They should terminate paragraphs . blah blah ::: name content ::: . <p>blah blah</p> <div class="name"> <p>content</p> </div> . They could be nested in lists . - ::: name - xxx ::: . <ul> <li> <div class="name"> <ul> <li>xxx</li> </ul> </div> </li> </ul> . Or in blockquotes . > ::: name > xxx >> yyy > zzz > ::: . <blockquote> <div class="name"> <p>xxx</p> <blockquote> <p>yyy zzz</p> </blockquote> </div> </blockquote> . List indentation quirks . - ::: name xxx yyy ::: - ::: name xxx yyy ::: . <ul> <li> <div class="name"> <p>xxx yyy</p> </div> </li> </ul> <p>:::</p> <ul> <li> <div class="name"> <p>xxx</p> </div> </li> </ul> <p>yyy :::</p> . Indented by 4 spaces . ::: name content ::: . <pre><code>::: name content ::: </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . ::: name content ::: . <div class="name"> <p>content</p> </div> . �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/deflist.md�����������������������������������������������������0000664�0000000�0000000�00000005222�14667654733�0021574�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Pandoc (with slightly changed indents): . Term 1 : Definition 1 Term 2 with *inline markup* : Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. . <dl> <dt>Term 1</dt> <dd> <p>Definition 1</p> </dd> <dt>Term 2 with <em>inline markup</em></dt> <dd> <p>Definition 2</p> <pre><code>{ some code, part of Definition 2 } </code></pre> <p>Third paragraph of definition 2.</p> </dd> </dl> . Pandoc again: . Term 1 : Definition with lazy continuation. Second paragraph of the definition. . <dl> <dt>Term 1</dt> <dd> <p>Definition with lazy continuation.</p> <p>Second paragraph of the definition.</p> </dd> </dl> . Well, I might just copy-paste the third one while I'm at it: . Term 1 ~ Definition 1 Term 2 ~ Definition 2a ~ Definition 2b . <dl> <dt>Term 1</dt> <dd>Definition 1</dd> <dt>Term 2</dt> <dd>Definition 2a</dd> <dd>Definition 2b</dd> </dl> . Now, with our custom ones. Spaces after a colon: . Term 1 : paragraph Term 2 : code block . <dl> <dt>Term 1</dt> <dd>paragraph</dd> <dt>Term 2</dt> <dd> <pre><code>code block </code></pre> </dd> </dl> . There should be something after a colon by the way: . Non-term 1 : Non-term 2 : . <p>Non-term 1 :</p> <p>Non-term 2 :</p> . List is tight iff all dts are tight: . Term 1 : foo : bar Term 2 : foo : bar . <dl> <dt>Term 1</dt> <dd> <p>foo</p> </dd> <dd> <p>bar</p> </dd> <dt>Term 2</dt> <dd> <p>foo</p> </dd> <dd> <p>bar</p> </dd> </dl> . Regression test (first paragraphs shouldn't be tight): . Term 1 : foo bar Term 2 : foo . <dl> <dt>Term 1</dt> <dd> <p>foo</p> <p>bar Term 2</p> </dd> <dd> <p>foo</p> </dd> </dl> . Definition lists should be second last in the queue. ExemplΔ« grātiā, this isn't a valid one: . # test : just a paragraph with a colon . <h1>test</h1> <p>: just a paragraph with a colon</p> . Nested definition lists: . test : foo : bar : baz : bar : foo . <dl> <dt>test</dt> <dd> <dl> <dt>foo</dt> <dd> <dl> <dt>bar</dt> <dd>baz</dd> </dl> </dd> <dd>bar</dd> </dl> </dd> <dd>foo</dd> </dl> . Regression test, tabs . Term 1 : code block . <dl> <dt>Term 1</dt> <dd> <pre><code>code block </code></pre> </dd> </dl> . Regression test (blockquote inside deflist) . foo : > bar : baz . <dl> <dt>foo</dt> <dd> <blockquote> <p>bar</p> </blockquote> </dd> <dd>baz</dd> </dl> . Coverage, 1 blank line . test . <p>test</p> . Coverage, 2 blank lines . test . <p>test</p> . Indented by 4 spaces . Term 1 : Definition 1 . <pre><code>Term 1 : Definition 1 </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . Term 1 : Definition 1 . <dl> <dt>Term 1</dt> <dd>Definition 1</dd> </dl> . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/dollar_math.md�������������������������������������������������0000664�0000000�0000000�00000022001�14667654733�0022422�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������single dollar . $ . <p>$</p> . double-dollar . $$ . <p>$$</p> . single character inline equation. (valid=True) . $a$ . <p><span class="math inline">a</span></p> . inline equation with single greek character (valid=True) . $\\varphi$ . <p><span class="math inline">\\varphi</span></p> . simple equation starting and ending with numbers. (valid=True) . $1+1=2$ . <p><span class="math inline">1+1=2</span></p> . simple equation including special html character. (valid=True) . $1+1<3$ . <p><span class="math inline">1+1<3</span></p> . equation including backslashes. (valid=True) . $a \\backslash$ . <p><span class="math inline">a \\backslash</span></p> . use of currency symbol, i.e. digits before/after opening/closing (valid=True) . 3$1+2$ $1+2$3 . <p>3$1+2$ $1+2$3</p> . use of currency symbol (valid=True) . If you solve $1+2$ you get $3 . <p>If you solve <span class="math inline">1+2</span> you get $3</p> . inline fraction (valid=True) . $\\frac{1}{2}$ . <p><span class="math inline">\\frac{1}{2}</span></p> . inline column vector (valid=True) . $\\begin{pmatrix}x\\\\y\\end{pmatrix}$ . <p><span class="math inline">\\begin{pmatrix}x\\\\y\\end{pmatrix}</span></p> . inline bold vector notation (valid=True) . ${\\tilde\\bold e}_\\alpha$ . <p><span class="math inline">{\\tilde\\bold e}_\\alpha</span></p> . exponentiation (valid=True) . $a^{b}$ . <p><span class="math inline">a^{b}</span></p> . conjugate complex (valid=True) . $a^\*b$ with $a^\*$ . <p><span class="math inline">a^\*b</span> with <span class="math inline">a^\*</span></p> . Inline multi-line (valid=True) . a $a \not=1$ b . <p>a <span class="math inline">a \not=1</span> b</p> . Inline multi-line with newline (valid=False) . a $a \not=1$ b . <p>a $a</p> <p>\not=1$ b</p> . single block equation, greek index (valid=True) . $$e_\\alpha$$ . <div class="math block"> e_\\alpha </div> . display equation on its own single line. (valid=True) . $$1+1=2$$ . <div class="math block"> 1+1=2 </div> . display equation with number on its own single line. (valid=True) . $$1+1=2$$ (2) . <div id="2" class="math block"> <a href="#2" class="mathlabel" title="Permalink to this equation">ΒΆ</a> 1+1=2 </div> . inline equation followed by block equation. (valid=True) . ${e}_x$ $$e_\\alpha$$ . <p><span class="math inline">{e}_x</span></p> <div class="math block"> e_\\alpha </div> . underline tests (valid=True) . $$c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha$$ . <div class="math block"> c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha </div> . non-numeric character before opening $ or after closing $ or both is allowed. (valid=True) . a$1+1=2$ $1+1=2$b c$x$d . <p>a<span class="math inline">1+1=2</span> <span class="math inline">1+1=2</span>b c<span class="math inline">x</span>d</p> . following dollar character '$' is allowed. (valid=True) . $x$ $ . <p><span class="math inline">x</span> $</p> . consecutive inline equations. (valid=True) . $x$ $y$ . <p><span class="math inline">x</span> <span class="math inline">y</span></p> . inline equation after '-' sign in text. (valid=True) . so-what is $x$ . <p>so-what is <span class="math inline">x</span></p> . display equation with line breaks. (valid=True) . $$ 1+1=2 $$ . <div class="math block"> 1+1=2 </div> . multiple equations (valid=True) . $$ a = 1 $$ $$ b = 2 $$ . <div class="math block"> a = 1 </div> <div class="math block"> b = 2 </div> . display equation with blank lines. (valid=False) . $$ 1+1=2 $$ . <p>$$ 1+1=2</p> <p>$$</p> . equation followed by a labelled equation (valid=True) . $$ a = 1 $$ $$ b = 2 $$ (1) . <div class="math block"> a = 1 </div> <div id="1" class="math block"> <a href="#1" class="mathlabel" title="Permalink to this equation">ΒΆ</a> b = 2 </div> . multiline equation. (valid=True) . $$\\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix}$$ . <div class="math block"> \\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix} </div> . vector equation. (valid=True) . $$\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}$$ . <div class="math block"> \\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix} </div> . display equation with equation number. (valid=True) . $$f(x) = x^2 - 1$$ (1) . <div id="1" class="math block"> <a href="#1" class="mathlabel" title="Permalink to this equation">ΒΆ</a> f(x) = x^2 - 1 </div> . inline equation following code section. (valid=True) . `code`$a-b$ . <p><code>code</code><span class="math inline">a-b</span></p> . equation following code block. (valid=True) . ``` code ``` $$a+b$$ . <pre><code>code </code></pre> <div class="math block"> a+b </div> . numbered equation following code block. (valid=True) . ``` code ``` $$a+b$$(1) . <pre><code>code </code></pre> <div id="1" class="math block"> <a href="#1" class="mathlabel" title="Permalink to this equation">ΒΆ</a> a+b </div> . Equations in list. (valid=True) . 1. $1+2$ 2. $2+3$ 1. $3+4$ . <ol> <li><span class="math inline">1+2</span></li> <li><span class="math inline">2+3</span> <ol> <li><span class="math inline">3+4</span></li> </ol> </li> </ol> . Inline sum. (valid=True) . $\\sum\_{i=1}^n$ . <p><span class="math inline">\\sum\_{i=1}^n</span></p> . Sum without equation number. (valid=True) . $$\\sum\_{i=1}^n$$ . <div class="math block"> \\sum\_{i=1}^n </div> . Sum with equation number. (valid=True) . $$\\sum\_{i=1}\^n$$ (2) . <div id="2" class="math block"> <a href="#2" class="mathlabel" title="Permalink to this equation">ΒΆ</a> \\sum\_{i=1}\^n </div> . equation number always vertically aligned. (valid=True) . $${\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix}$$ (3) . <div id="3" class="math block"> <a href="#3" class="mathlabel" title="Permalink to this equation">ΒΆ</a> {\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix} </div> . inline equations in blockquote. (valid=True) . > see $a = b + c$ > $c^2=a^2+b^2$ (2) > $c^2=a^2+b^2$ . <blockquote> <p>see <span class="math inline">a = b + c</span> <span class="math inline">c^2=a^2+b^2</span> (2) <span class="math inline">c^2=a^2+b^2</span></p> </blockquote> . display equation in blockquote. (valid=True) . > formula > > $$ a+b=c$$ (2) > > in blockquote. . <blockquote> <p>formula</p> <div id="2" class="math block"> <a href="#2" class="mathlabel" title="Permalink to this equation">ΒΆ</a> a+b=c </div> <p>in blockquote.</p> </blockquote> . mixed syntax: . $$ a=1 \\ b=2 $$ (abc) - ab $c=1$ d . <div id="abc" class="math block"> <a href="#abc" class="mathlabel" title="Permalink to this equation">ΒΆ</a> a=1 \\ b=2 </div> <ul> <li>ab <span class="math inline">c=1</span> d</li> </ul> . escaped dollars '\\$' are interpreted as dollar '$' characters. (valid=True) . \\$1+1=2$ $1+1=2\\$ . <p>\<span class="math inline">1+1=2</span> <span class="math inline">1+1=2\\</span></p> . empty line between text and display formula is required. (valid=False) . some text \$\\$a+b=c\$\$ . <p>some text $\$a+b=c$$</p> . whitespace character after opening $ or before closing $ is not allowed. (valid=False) . $ $ $ x$ $x $ . <p>$ $ $ x$ $x $</p> . new line in blockquote block (valid=False): . > \$\$ a+b\n=c\$\$ . <blockquote> <p>$$ a+b\n=c$$</p> </blockquote> . math-escaping: escaped start $: . \$p_2 = $a . <p>$p_2 = $a</p> . math-escaping: escaped end $: . $p_2 = \$a . <p>$p_2 = $a</p> . math-escaping: internal escaped $: . $p_2 = \$1$ . <p><span class="math inline">p_2 = \$1</span></p> . math-escaping: double-escaped start $: . \\$p_2 = 1$ . <p>\<span class="math inline">p_2 = 1</span></p> . math-escaping: double-escaped end $: . $p_2 = \\$a . <p><span class="math inline">p_2 = \\</span>a</p> . Inline double-dollar start: . $$a=1$$ b . <p><div class="math inline">a=1</div> b</p> . Inline double-dollar end: . a $$a=1$$ . <p>a <div class="math inline">a=1</div></p> . Inline double-dollar enclosed: . a $$a=1$$ (1) b . <p>a <div class="math inline">a=1</div> (1) b</p> . Inline double-dollar, escaped: . a \$$a=1$$ b . <p>a $<span class="math inline">a=1</span>$ b</p> . Inline mixed single/double dollars: . Hence, for $\alpha \in (0, 1)$, $$ \mathbb P (\alpha \bar{X} \ge \mu) \le \alpha; $$ i.e., $[\alpha \bar{X}, \infty)$ is a lower 1-sided $1-\alpha$ confidence bound for $\mu$. . <p>Hence, for <span class="math inline">\alpha \in (0, 1)</span>, <div class="math inline">\mathbb P (\alpha \bar{X} \ge \mu) \le \alpha;</div> i.e., <span class="math inline">[\alpha \bar{X}, \infty)</span> is a lower 1-sided <span class="math inline">1-\alpha</span> confidence bound for <span class="math inline">\mu</span>.</p> . display equation with label containing whitespace. (valid=True) . $$1+1=2$$ (a b) . <div id="a-b" class="math block"> <a href="#a-b" class="mathlabel" title="Permalink to this equation">ΒΆ</a> 1+1=2 </div> . Indented by 4 spaces . $$a$$ . <pre><code>$$a$$ </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . $$a$$ . <div class="math block"> a </div> . �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/field_list.md��������������������������������������������������0000664�0000000�0000000�00000010541�14667654733�0022260�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Docutils example . :Date: 2001-08-16 :Version: 1 :Authors: - Me - Myself - I :Indentation: Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other. :Parameter i: integer . <dl class="field-list"> <dt>Date</dt> <dd> <p>2001-08-16</p> </dd> <dt>Version</dt> <dd> <p>1</p> </dd> <dt>Authors</dt> <dd> <ul> <li>Me</li> <li>Myself</li> <li>I</li> </ul> </dd> <dt>Indentation</dt> <dd> <p>Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other.</p> </dd> <dt>Parameter i</dt> <dd> <p>integer</p> </dd> </dl> . Body alignment: . :no body: :single line: content :paragraph: content running onto new line :body inline: paragraph 1 paragraph 2 paragraph 3 :body less: paragraph 1 paragraph 2 paragraph 3 :body on 2nd line: paragraph 1 paragraph 2 :body on 3rd line: paragraph 1 paragraph 2 . <dl class="field-list"> <dt>no body</dt> <dd></dd> <dt>single line</dt> <dd> <p>content</p> </dd> <dt>paragraph</dt> <dd> <p>content running onto new line</p> </dd> <dt>body inline</dt> <dd> <p>paragraph 1</p> <p>paragraph 2</p> <p>paragraph 3</p> </dd> <dt>body less</dt> <dd> <p>paragraph 1</p> <p>paragraph 2</p> <p>paragraph 3</p> </dd> <dt>body on 2nd line</dt> <dd> <p>paragraph 1</p> <p>paragraph 2</p> </dd> <dt>body on 3rd line</dt> <dd> <p>paragraph 1</p> <p>paragraph 2</p> </dd> </dl> . choose smallest indent . :name: a b c . <dl class="field-list"> <dt>name</dt> <dd> <p>a</p> <p>b</p> <p>c</p> </dd> </dl> . Empty name: . :: . <p>::</p> . Whitespace only name: . : : . <p>: :</p> . Name markup: . :inline *markup*: . <dl class="field-list"> <dt>inline <em>markup</em></dt> <dd></dd> </dl> . Content paragraph markup: . :name: body *markup* . <dl class="field-list"> <dt>name</dt> <dd> <p>body <em>markup</em></p> </dd> </dl> . Body list: . :name: - item 1 - item 2 :name: - item 1 - item 2 . <dl class="field-list"> <dt>name</dt> <dd> <ul> <li>item 1</li> <li>item 2</li> </ul> </dd> <dt>name</dt> <dd> <ul> <li>item 1</li> <li>item 2</li> </ul> </dd> </dl> . Body code block . :name: not code :name: body code . <dl class="field-list"> <dt>name</dt> <dd> <p>not code</p> </dd> <dt>name</dt> <dd> <p>body</p> <pre><code>code </code></pre> </dd> </dl> . Body blockquote: . :name: > item 1 > item 2 :name: > item 1 > item 2 . <dl class="field-list"> <dt>name</dt> <dd> <blockquote> <p>item 1 item 2</p> </blockquote> </dd> <dt>name</dt> <dd> <blockquote> <p>item 1 item 2</p> </blockquote> </dd> </dl> . Body fence: . :name: ```python code ``` . <dl class="field-list"> <dt>name</dt> <dd> <pre><code class="language-python">code </code></pre> </dd> </dl> . Following blocks: . :name: body - item 1 :name: body > block quote :name: body ```python code ``` :name: body more more trailing other . <dl class="field-list"> <dt>name</dt> <dd> <p>body</p> </dd> </dl> <ul> <li>item 1</li> </ul> <dl class="field-list"> <dt>name</dt> <dd> <p>body</p> </dd> </dl> <blockquote> <p>block quote</p> </blockquote> <dl class="field-list"> <dt>name</dt> <dd> <p>body</p> </dd> </dl> <pre><code class="language-python">code </code></pre> <dl class="field-list"> <dt>name</dt> <dd> <p>body more</p> <p>more trailing</p> </dd> </dl> <p>other</p> . In list: . - :name: body - item 2 . <ul> <li> <dl class="field-list"> <dt>name</dt> <dd> <p>body</p> </dd> </dl> </li> <li>item 2</li> </ul> . In blockquote: . > :name: body > :name: body > other > :name: body > > other > :name: body > > other . <blockquote> <dl class="field-list"> <dt>name</dt> <dd> <p>body</p> </dd> <dt>name</dt> <dd> <p>body other</p> </dd> <dt>name</dt> <dd> <p>body</p> <p>other</p> </dd> <dt>name</dt> <dd> <p>body</p> <p>other</p> </dd> </dl> </blockquote> . Indented by 4 spaces . :name: text indented . <pre><code>:name: text indented </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . :name: text indented . <dl class="field-list"> <dt>name</dt> <dd> <p>text indented</p> </dd> </dl> . ���������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/footnote.md����������������������������������������������������0000664�0000000�0000000�00000021246�14667654733�0022003�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Pandoc example: . Here is a footnote reference,[^1] and another.[^longnote] [^1]: Here is the footnote. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous footnote. { some.code } The whole paragraph can be indented, or just the first line. In this way, multi-paragraph footnotes work like multi-paragraph list items. This paragraph won't be part of the note, because it isn't indented. . <p>Here is a footnote reference,<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and another.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> <p>This paragraph won't be part of the note, because it isn't indented.</p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Here is the footnote. <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn2" class="footnote-item"><p>Here's one with multiple blocks.</p> <p>Subsequent paragraphs are indented to show that they belong to the previous footnote.</p> <pre><code>{ some.code } </code></pre> <p>The whole paragraph can be indented, or just the first line. In this way, multi-paragraph footnotes work like multi-paragraph list items. <a href="#fnref2" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . They could terminate each other: . [^1][^2][^3] [^1]: foo [^2]: bar [^3]: baz . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn2" class="footnote-item"><p>bar <a href="#fnref2" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn3" class="footnote-item"><p>baz <a href="#fnref3" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . They could be inside blockquotes, and are lazy: . [^foo] > [^foo]: bar baz . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <blockquote></blockquote> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>bar baz <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Their labels could not contain spaces or newlines: . [^ foo]: bar baz [^foo ]: bar baz . <p>[^ foo]: bar baz</p> <p>[^foo ]: bar baz</p> . We support inline notes too (pandoc example): . Here is an inline note.^[Inlines notes are easier to write, since you don't have to pick an identifier and move down to type the note.] . <p>Here is an inline note.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>Inlines notes are easier to write, since you don't have to pick an identifier and move down to type the note. <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . They could have arbitrary markup: . foo^[ *bar* ] . <p>foo<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p> <em>bar</em> <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Duplicate footnotes: . [^xxxxx] [^xxxxx] [^xxxxx]: foo . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a> <a href="#fnref1:1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Indents: . [^xxxxx] [^yyyyy] [^xxxxx]: foo --- [^yyyyy]: foo --- . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> <hr> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><h2>foo</h2> <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></li> <li id="fn2" class="footnote-item"><p>foo <a href="#fnref2" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Indents for the first line: . [^xxxxx] [^yyyyy] [^xxxxx]: foo [^yyyyy]: foo . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn2" class="footnote-item"><pre><code>foo </code></pre> <a href="#fnref2" class="footnote-backref">↩</a></li> </ol> </section> . Indents for the first line (tabs): . [^xxxxx] [^xxxxx]: foo . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Security 1 . [^__proto__] [^__proto__]: blah . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>blah <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Security 2 . [^hasOwnProperty] [^hasOwnProperty]: blah . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>blah <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Should allow links in inline footnotes . Example^[this is another example https://github.com] . <p>Example<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>this is another example https://github.com <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Nested blocks: . [^a] [^a]: abc def hij - list > block terminates here . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <p>terminates here</p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>abc</p> <p>def hij</p> <ul> <li>list</li> </ul> <blockquote> <p>block</p> </blockquote> <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></li> </ol> </section> . Empty lines after blockquote+footnote (markdown-it-py#133) . > b [^1] Some text > c [^1]: d . <blockquote> <p>b <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> </blockquote> <p>Some text</p> <blockquote> <p>c</p> </blockquote> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>d <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . Newline after footnote identifier . [^a] [^a]: b . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <p>b</p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"> <a href="#fnref1" class="footnote-backref"><-</a></li> </ol> </section> . Indented by 4 spaces . [^1] [^1]: footnote . <pre><code>[^1] [^1]: footnote </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . [^1] [^1]: footnote . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>footnote <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> . refs with no definition standard . [^1] [^1] . <p>[^1] [^1]</p> . refs with no definition, ALWAYS_MATCH-REFS . [^1] [^1] . <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup></p> <hr class="footnotes-sep"> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"> <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a> <a href="#fnref1:1" class="footnote-backref">β†©οΈŽ</a></li> </ol> </section> . ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/front_matter.md������������������������������������������������0000664�0000000�0000000�00000001551�14667654733�0022647�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ should parse empty front matter: . --- --- # Head . <h1>Head</h1> . should parse basic front matter: . --- x: 1 --- # Head . <h1>Head</h1> . should parse until triple dots: . --- x: 1 ... # Head . <h1>Head</h1> . should parse front matter with indentation: . --- title: Associative arrays people: name: John Smith age: 33 morePeople: { name: Grace Jones, age: 21 } --- # Head . <h1>Head</h1> . should ignore spaces after front matter delimiters: . --- title: Associative arrays people: name: John Smith age: 33 morePeople: { name: Grace Jones, age: 21 } --- # Head . <h1>Head</h1> . should ignore front matter with less than 3 opening dashes: . -- x: 1 -- # Head . <h2>-- x: 1</h2> <h1>Head</h1> . should require front matter have matching number of opening and closing dashes: . ---- x: 1 --- # Head . <hr> <h2>x: 1</h2> <h1>Head</h1> . �������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/myst_block.md��������������������������������������������������0000664�0000000�0000000�00000003262�14667654733�0022312�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Block Break: . +++ . <hr class="myst-block"> . Block Break Split Markers: . + + + + xfsdfsdf . <hr class="myst-block"> . Block Break Too Few Markers: . ++ . <p>++</p> . Block Break terminates other blocks: . a +++ - b +++ > c +++ . <p>a</p> <hr class="myst-block"> <ul> <li>b</li> </ul> <hr class="myst-block"> <blockquote> <p>c</p> </blockquote> <hr class="myst-block"> . Target: . (a)= . <div class="myst-target"><a href="#a">(a)=</a></div> . Target characters: . (a bc |@<>*./_-+:)= . <div class="myst-target"><a href="#a bc |@<>*./_-+:">(a bc |@<>*./_-+:)=</a></div> . Empty target: . ()= . <p>()=</p> . Escaped target: . \(a)= . <p>(a)=</p> . Indented target: . (a)= . <div class="myst-target"><a href="#a">(a)=</a></div> . Target terminates other blocks: . a (a-b)= - b (a b)= > c (a)= . <p>a</p> <div class="myst-target"><a href="#a-b">(a-b)=</a></div><ul> <li>b</li> </ul> <div class="myst-target"><a href="#a b">(a b)=</a></div><blockquote> <p>c</p> </blockquote> <div class="myst-target"><a href="#a">(a)=</a></div> . Comment: . % abc . <!-- abc --> . Comment terminates other blocks: . a % abc - b % abc > c % abc . <p>a</p> <!-- abc --><ul> <li>b</li> </ul> <!-- abc --><blockquote> <p>c</p> </blockquote> <!-- abc --> . Multiline comment: . a % abc % def - b % abc %def > c %abc % %def . <p>a</p> <!-- abc def --><ul> <li>b</li> </ul> <!-- abc def --><blockquote> <p>c</p> </blockquote> <!-- abc def --> . Indented by 4 spaces . +++ % abc (a)= . <pre><code>+++ % abc (a)= </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . +++ % abc (a)= . <hr class="myst-block"> <!-- abc --><div class="myst-target"><a href="#a">(a)=</a></div> . ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/myst_role.md���������������������������������������������������0000664�0000000�0000000�00000002236�14667654733�0022161�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Basic: . {abc}`xyz` . <p><code class="myst role">{abc}[xyz]</code></p> . Multiple: . {abc}`xyz`{def}`uvw` . <p><code class="myst role">{abc}[xyz]</code><code class="myst role">{def}[uvw]</code></p> . Surrounding Text: . a {abc}`xyz` b . <p>a <code class="myst role">{abc}[xyz]</code> b</p> . New lines: . {abc}`xy z` `d e` . <p><code class="myst role">{abc}[xy z]</code> <code>d e</code></p> . In Code: . `` {abc}`xyz` `` . <p><code>{abc}`xyz`</code></p> . Empty content: . {name}`` a . <p>{name}`` a</p> . Surrounding Code: . `a` {abc}`xyz` `b` . <p><code>a</code> <code class="myst role">{abc}[xyz]</code> <code>b</code></p> . In list: . - {abc}`xyz` . <ul> <li><code class="myst role">{abc}[xyz]</code></li> </ul> . In Quote: . > {abc}`xyz` b . <blockquote> <p><code class="myst role">{abc}[xyz]</code> b</p> </blockquote> . Multiple ticks: . {abc}``xyz`` . <p><code class="myst role">{abc}[xyz]</code></p> . Inner tick: . {abc}``x`yz`` . <p><code class="myst role">{abc}[x`yz]</code></p> . Unbalanced ticks: . {abc}``xyz` . <p>{abc}``xyz`</p> . Space in name: . {ab c}`xyz` . <p>{ab c}<code>xyz</code></p> . Escaped: . \{abc}`xyz` . <p>{abc}<code>xyz</code></p> . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/span.md��������������������������������������������������������0000664�0000000�0000000�00000000000�14667654733�0021070�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/substitution.md������������������������������������������������0000664�0000000�0000000�00000002625�14667654733�0022722�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Basic (space): . {{ block }} a {{ inline }} b . <div class="substitution" text="block" /> <p>a <span class="substitution" text="inline" /> b</p> . Basic (no space): . {{block}} a {{inline}} b . <div class="substitution" text="block" /> <p>a <span class="substitution" text="inline" /> b</p> . Same line: . {{a}}{{b}} . <p><span class="substitution" text="a" /><span class="substitution" text="b" /></p> . No closing: . {{ a {{b} {{c} } . <p>{{ a</p> <p>{{b}</p> <p>{{c} }</p> . Inside code . `{{ a }}` ```python {{b}} ``` . <p><code>{{ a }}</code></p> <pre><code class="language-python">{{b}} </code></pre> . New line: . {{a}} {{b}} . <div class="substitution" text="a" /> <div class="substitution" text="b" /> . Blocks: . - {{a}} > {{b}} 1. {{c}} . <ul> <li> <div class="substitution" text="a" /> </li> </ul> <blockquote> <div class="substitution" text="b" /> </blockquote> <ol> <li> <div class="substitution" text="c" /> </li> </ol> . Inline: . - {{a}} x > {{b}} y 1. {{c}} z . <ul> <li><span class="substitution" text="a" /> x</li> </ul> <blockquote> <p><span class="substitution" text="b" /> y</p> </blockquote> <ol> <li><span class="substitution" text="c" /> z</li> </ol> . Tables: . | | | |-|-| |{{a}}|{{b}} c| . <table> <thead> <tr> <th></th> <th></th> </tr> </thead> <tbody> <tr> <td><span class="substitution" text="a" /></td> <td><span class="substitution" text="b" /> c</td> </tr> </tbody> </table> . �����������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/tasklists.md���������������������������������������������������0000664�0000000�0000000�00000007263�14667654733�0022172�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ bullet.md: . - [ ] unchecked item 1 - [ ] unchecked item 2 - [ ] unchecked item 3 - [x] checked item 4 . <ul class="contains-task-list"> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 1</li> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 2</li> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 3</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked item 4</li> </ul> . dirty.md: . - [ ] unchecked todo item 1 - [ ] - [ ] not a todo item 2 - [ x] not a todo item 3 - [x ] not a todo item 4 - [ x ] not a todo item 5 - [x] todo item 6 . <ul class="contains-task-list"> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked todo item 1</li> <li>[ ]</li> <li>[ ] not a todo item 2</li> <li>[ x] not a todo item 3</li> <li>[x ] not a todo item 4</li> <li>[ x ] not a todo item 5</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> todo item 6</li> </ul> . mixed-nested.md: . # Test 1 1. foo * [ ] nested unchecked item 1 * not a todo item 2 * not a todo item 3 * [x] nested checked item 4 2. bar 3. spam # Test 2 - foo - [ ] nested unchecked item 1 - [ ] nested unchecked item 2 - [x] nested checked item 3 - [X] nested checked item 4 . <h1>Test 1</h1> <ol> <li>foo <ul class="contains-task-list"> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 1</li> <li>not a todo item 2</li> <li>not a todo item 3</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 4</li> </ul> </li> <li>bar</li> <li>spam</li> </ol> <h1>Test 2</h1> <ul> <li>foo <ul class="contains-task-list"> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 1</li> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 2</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 3</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 4</li> </ul> </li> </ul> . oedered.md: . 1. [x] checked ordered 1 2. [ ] unchecked ordered 2 3. [x] checked ordered 3 4. [ ] unchecked ordered 4 . <ol class="contains-task-list"> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked ordered 1</li> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked ordered 2</li> <li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked ordered 3</li> <li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked ordered 4</li> </ol> . Tab after task list item marker . + [x] item 1 + [ ] item 2 . <ul class="contains-task-list"> <li class="task-list-item"> item 1</li> <li class="task-list-item"> item 2</li> </ul> . Form feed after task list item marker . + [x] item 1 + [ ] item 2 . <ul class="contains-task-list"> <li class="task-list-item"> item 1</li> <li class="task-list-item"> item 2</li> </ul> . ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/texmath_bracket.md���������������������������������������������0000664�0000000�0000000�00000012370�14667654733�0023311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������single character inline equation. (valid=True) . \(a\) . <p><eq>a</eq></p> . inline equation with single greek character (valid=True) . \(\\varphi\) . <p><eq>\\varphi</eq></p> . simple equation starting and ending with numbers. (valid=True) . \(1+1=2\) . <p><eq>1+1=2</eq></p> . simple equation including special html character. (valid=True) . \(1+1<3\) . <p><eq>1+1<3</eq></p> . equation including backslashes. (valid=True) . \(a \\backslash\) . <p><eq>a \\backslash</eq></p> . use of currency symbol (valid=True) . You get 3$ if you solve \(1+2\) . <p>You get 3$ if you solve <eq>1+2</eq></p> . use of currency symbol (valid=True) . If you solve \(1+2\) you get $3 . <p>If you solve <eq>1+2</eq> you get $3</p> . inline fraction (valid=True) . \(\\frac{1}{2}\) . <p><eq>\\frac{1}{2}</eq></p> . inline column vector (valid=True) . \(\\begin{pmatrix}x\\\\y\\end{pmatrix}\) . <p><eq>\\begin{pmatrix}x\\\\y\\end{pmatrix}</eq></p> . inline bold vector notation (valid=True) . \({\\tilde\\bold e}_\\alpha\) . <p><eq>{\\tilde\\bold e}_\\alpha</eq></p> . exponentiation (valid=True) . \(a^{b}\) . <p><eq>a^{b}</eq></p> . conjugate complex (valid=True) . \(a^\*b\) with \(a^\*\) . <p><eq>a^\*b</eq> with <eq>a^\*</eq></p> . Inline multi-line (valid=True) . a \(a \not=1\) b . <p>a <eq>a \not=1</eq> b</p> . Inline multi-line with newline (valid=False) . a \(a \not=1\) b . <p>a (a</p> <p>\not=1) b</p> . single block equation, greek index (valid=True) . \[e_\\alpha\] . <section> <eqn>e_\\alpha</eqn> </section> . display equation on its own single line. (valid=True) . \[1+1=2\] . <section> <eqn>1+1=2</eqn> </section> . inline equation followed by block equation. (valid=True) . \({e}_x\) \[e_\\alpha\] . <p><eq>{e}_x</eq></p> <section> <eqn>e_\\alpha</eqn> </section> . underline tests (valid=True) . \[c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha\] . <section> <eqn>c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha</eqn> </section> . non-numeric character before opening $ or after closing $ or both is allowed. (valid=True) . a\(1+1=2\) \(1+1=2\)b c\(x\)d . <p>a<eq>1+1=2</eq> <eq>1+1=2</eq>b c<eq>x</eq>d</p> . following dollar character '$' is allowed. (valid=True) . \(x\) $ . <p><eq>x</eq> $</p> . consecutive inline equations. (valid=True) . \(x\) \(y\) . <p><eq>x</eq> <eq>y</eq></p> . inline equation after '-' sign in text. (valid=True) . so-what is \(x\) . <p>so-what is <eq>x</eq></p> . display equation with line breaks. (valid=True) . \[ 1+1=2 \] . <section> <eqn> 1+1=2 </eqn> </section> . multiple equations (valid=True) . \[ a = 1 \] \[ b = 2 \] . <section> <eqn> a = 1 </eqn> </section> <section> <eqn> b = 2 </eqn> </section> . equation followed by a labelled equation (valid=True) . \[ a = 1 \] \[ b = 2 \] (1) . <section> <eqn> a = 1 </eqn> </section> <section> <eqn> b = 2 </eqn> </section> . multiline equation. (valid=True) . \[\\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix}\] . <section> <eqn>\\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix}</eqn> </section> . vector equation. (valid=True) . \[\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}\] . <section> <eqn>\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}</eqn> </section> . display equation with equation number. (valid=True) . \[f(x) = x^2 - 1\] (1) . <section> <eqn>f(x) = x^2 - 1</eqn> </section> . inline equation following code section. (valid=True) . `code`\(a-b\) . <p><code>code</code><eq>a-b</eq></p> . equation following code block. (valid=True) . ``` code ``` \[a+b\] . <pre><code>code </code></pre> <section> <eqn>a+b</eqn> </section> . numbered equation following code block. (valid=True) . ``` code ``` \[a+b\](1) . <pre><code>code </code></pre> <section> <eqn>a+b</eqn> </section> . Equations in list. (valid=True) . 1. \(1+2\) 2. \(2+3\) 1. \(3+4\) . <ol> <li><eq>1+2</eq></li> <li><eq>2+3</eq> <ol> <li><eq>3+4</eq></li> </ol> </li> </ol> . Inline sum. (valid=True) . \(\\sum\_{i=1}^n\) . <p><eq>\\sum\_{i=1}^n</eq></p> . Sum without equation number. (valid=True) . \[\\sum\_{i=1}^n\] . <section> <eqn>\\sum\_{i=1}^n</eqn> </section> . Sum with equation number. (valid=True) . \[\\sum\_{i=1}\^n\] \(2\) . <section> <eqn>\\sum\_{i=1}\^n</eqn> </section> . equation number always vertically aligned. (valid=True) . \[{\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix}\] (3) . <section> <eqn>{\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix}</eqn> </section> . inline equations in blockquote. (valid=True) . > see \(a = b + c\) > \(c^2=a^2+b^2\) (2) > \(c^2=a^2+b^2\) . <blockquote> <p>see <eq>a = b + c</eq> <eq>c^2=a^2+b^2</eq> (2) <eq>c^2=a^2+b^2</eq></p> </blockquote> . display equation in blockquote. (valid=True) . > formula > > \[ a+b=c\] (2) > > in blockquote. . <blockquote> <p>formula</p> <section> <eqn> a+b=c</eqn> </section> <p>in blockquote.</p> </blockquote> . Indented by 4 spaces . \[ a = 1 \] . <pre><code>\[ a = 1 \] </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . \[ a = 1 \] . <section> <eqn> a = 1 </eqn> </section> . ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/texmath_dollar.md����������������������������������������������0000664�0000000�0000000�00000013237�14667654733�0023156�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������single character inline equation. (valid=True) . $a$ . <p><eq>a</eq></p> . inline equation with single greek character (valid=True) . $\\varphi$ . <p><eq>\\varphi</eq></p> . simple equation starting and ending with numbers. (valid=True) . $1+1=2$ . <p><eq>1+1=2</eq></p> . simple equation including special html character. (valid=True) . $1+1<3$ . <p><eq>1+1<3</eq></p> . equation including backslashes. (valid=True) . $a \\backslash$ . <p><eq>a \\backslash</eq></p> . use of currency symbol (valid=True) . You get 3$ if you solve $1+2$ . <p>You get 3$ if you solve <eq>1+2</eq></p> . use of currency symbol (valid=True) . If you solve $1+2$ you get $3 . <p>If you solve <eq>1+2</eq> you get $3</p> . inline fraction (valid=True) . $\\frac{1}{2}$ . <p><eq>\\frac{1}{2}</eq></p> . inline column vector (valid=True) . $\\begin{pmatrix}x\\\\y\\end{pmatrix}$ . <p><eq>\\begin{pmatrix}x\\\\y\\end{pmatrix}</eq></p> . inline bold vector notation (valid=True) . ${\\tilde\\bold e}_\\alpha$ . <p><eq>{\\tilde\\bold e}_\\alpha</eq></p> . exponentiation (valid=True) . $a^{b}$ . <p><eq>a^{b}</eq></p> . conjugate complex (valid=True) . $a^\*b$ with $a^\*$ . <p><eq>a^\*b</eq> with <eq>a^\*</eq></p> . Inline multi-line (valid=True) . a $a \not=1$ b . <p>a <eq>a \not=1</eq> b</p> . Inline multi-line with newline (valid=False) . a $a \not=1$ b . <p>a $a</p> <p>\not=1$ b</p> . single block equation, greek index (valid=True) . $$e_\\alpha$$ . <section> <eqn>e_\\alpha</eqn> </section> . display equation on its own single line. (valid=True) . $$1+1=2$$ . <section> <eqn>1+1=2</eqn> </section> . inline equation followed by block equation. (valid=True) . ${e}_x$ $$e_\\alpha$$ . <p><eq>{e}_x</eq></p> <section> <eqn>e_\\alpha</eqn> </section> . underline tests (valid=True) . $$c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha$$ . <section> <eqn>c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha</eqn> </section> . non-numeric character before opening $ or after closing $ or both is allowed. (valid=True) . a$1+1=2$ $1+1=2$b c$x$d . <p>a<eq>1+1=2</eq> <eq>1+1=2</eq>b c<eq>x</eq>d</p> . following dollar character '$' is allowed. (valid=True) . $x$ $ . <p><eq>x</eq> $</p> . consecutive inline equations. (valid=True) . $x$ $y$ . <p><eq>x</eq> <eq>y</eq></p> . inline equation after '-' sign in text. (valid=True) . so-what is $x$ . <p>so-what is <eq>x</eq></p> . display equation with line breaks. (valid=True) . $$ 1+1=2 $$ . <section> <eqn> 1+1=2 </eqn> </section> . multiple equations (valid=True) . $$ a = 1 $$ $$ b = 2 $$ . <section> <eqn> a = 1 </eqn> </section> <section> <eqn> b = 2 </eqn> </section> . equation followed by a labelled equation (valid=True) . $$ a = 1 $$ $$ b = 2 $$ (1) . <section> <eqn> a = 1 </eqn> </section> <section> <eqn> b = 2 </eqn> </section> . multiline equation. (valid=True) . $$\\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix}$$ . <section> <eqn>\\begin{matrix} f & = & 2 + x + 3 \\ & = & 5 + x \\end{matrix}</eqn> </section> . vector equation. (valid=True) . $$\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}$$ . <section> <eqn>\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} = \\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot \\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}</eqn> </section> . display equation with equation number. (valid=True) . $$f(x) = x^2 - 1$$ (1) . <section> <eqn>f(x) = x^2 - 1</eqn> </section> . inline equation following code section. (valid=True) . `code`$a-b$ . <p><code>code</code><eq>a-b</eq></p> . equation following code block. (valid=True) . ``` code ``` $$a+b$$ . <pre><code>code </code></pre> <section> <eqn>a+b</eqn> </section> . numbered equation following code block. (valid=True) . ``` code ``` $$a+b$$(1) . <pre><code>code </code></pre> <section> <eqn>a+b</eqn> </section> . Equations in list. (valid=True) . 1. $1+2$ 2. $2+3$ 1. $3+4$ . <ol> <li><eq>1+2</eq></li> <li><eq>2+3</eq> <ol> <li><eq>3+4</eq></li> </ol> </li> </ol> . Inline sum. (valid=True) . $\\sum\_{i=1}^n$ . <p><eq>\\sum\_{i=1}^n</eq></p> . Sum without equation number. (valid=True) . $$\\sum\_{i=1}^n$$ . <section> <eqn>\\sum\_{i=1}^n</eqn> </section> . Sum with equation number. (valid=True) . $$\\sum\_{i=1}\^n$$ \(2\) . <section> <eqn>\\sum\_{i=1}\^n</eqn> </section> . equation number always vertically aligned. (valid=True) . $${\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix}$$ (3) . <section> <eqn>{\\bold e}(\\varphi) = \\begin{pmatrix} \\cos\\varphi\\\\\\sin\\varphi \\end{pmatrix}</eqn> </section> . inline equations in blockquote. (valid=True) . > see $a = b + c$ > $c^2=a^2+b^2$ (2) > $c^2=a^2+b^2$ . <blockquote> <p>see <eq>a = b + c</eq> <eq>c^2=a^2+b^2</eq> (2) <eq>c^2=a^2+b^2</eq></p> </blockquote> . display equation in blockquote. (valid=True) . > formula > > $$ a+b=c$$ (2) > > in blockquote. . <blockquote> <p>formula</p> <section> <eqn> a+b=c</eqn> </section> <p>in blockquote.</p> </blockquote> . mixed syntax: . $$ a=1 \\ b=2 $$ (abc) - ab $c=1$ d . <section> <eqn> a=1 \\ b=2 </eqn> </section> <ul> <li>ab <eq>c=1</eq> d</li> </ul> . escaped dollars '\\$' are interpreted as dollar '$' characters. (valid=True) . \\$1+1=2$ $1+1=2\\$ . <p>\$1+1=2$ $1+1=2\$</p> . empty line between text and display formula is required. (valid=False) . some text \$\\$a+b=c\$\$ . <p>some text $\$a+b=c$$</p> . whitespace character after opening $ or before closing $ is not allowed. (valid=False) . $ $ $ x$ $x $ . <p>$ $ $ x$ $x $</p> . Indented by 4 spaces . $$a$$ . <pre><code>$$a$$ </code></pre> . Indented by 4 spaces, DISABLE-CODEBLOCKS . $$a$$ . <section> <eqn>a</eqn> </section> . �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/fixtures/wordcount.md���������������������������������������������������0000664�0000000�0000000�00000006562�14667654733�0022176�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������syntax (text) . one two three four - five six > seven eight [nine ten](link) . { "minutes": 0, "text": [ "one two", "three four", "five six", "seven eight", "nine ten" ], "words": 10 } . non-words . Geeksforgeeks, is best @# Computer Science Portal.!!! . { "minutes": 0, "words": 6 } . lore ipsum . Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent imperdiet hendrerit dictum. Etiam diam turpis, cursus in varius dignissim, imperdiet nec nibh. Nulla nec finibus dui. Phasellus fermentum venenatis placerat. Donec ut dui in sem rhoncus molestie. Sed auctor sem dapibus augue varius facilisis. Maecenas at suscipit dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum ornare dui ac tristique ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque arcu erat, ultricies ac lorem at, semper ornare nisl. Donec massa magna, commodo et ultrices ac, rutrum non nulla. Nunc fermentum fringilla ultrices. Morbi ante nibh, accumsan ac viverra quis, gravida rutrum mi. Integer lobortis, purus id laoreet ornare, sapien odio placerat massa, vel vestibulum dolor ante id mi. Donec ex leo, ultricies non ante eget, pharetra dictum orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae tortor ut nisi cursus egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Morbi et nunc posuere, pharetra est aliquet, iaculis libero. Aliquam leo nibh, posuere eget eros a, convallis bibendum nibh. Phasellus vulputate bibendum lacus sit amet varius. Integer ut rutrum dolor, ac finibus neque. Maecenas ultrices pretium augue vitae mollis. Fusce semper lorem eu mauris iaculis pulvinar. Morbi ac pretium nunc, ac faucibus enim. Duis consequat nibh metus, at sodales sem luctus nec. Donec id finibus ante. Duis tincidunt vulputate efficitur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean porttitor augue consectetur, feugiat odio in, rutrum velit. Aliquam et mi lacinia, efficitur nisl nec, rutrum mauris. Mauris efficitur eros in maximus tempor. Suspendisse potenti. Quisque cursus non libero in faucibus. Etiam dignissim urna vel nibh feugiat, at vehicula dui vulputate. Praesent malesuada arcu quis neque condimentum vestibulum. Aliquam pretium eleifend neque, eget vulputate erat faucibus at. Quisque egestas nunc ac hendrerit fringilla. Vestibulum at tristique lacus, eget placerat risus. Aenean a metus ullamcorper, eleifend ante ut, feugiat lacus. Proin eget semper purus, ac vehicula nisl. Suspendisse eu mi enim. Nullam aliquam purus eu orci iaculis suscipit. Mauris dapibus non neque eu hendrerit. Sed eros purus, finibus ut ex ac, ultricies luctus enim. Quisque non lacus arcu. Ut dictum mauris ac tristique pulvinar. Aenean ut nisl massa. Donec nec dui scelerisque, egestas arcu sit amet, tempor eros. Donec sit amet faucibus tellus. Cras auctor mi id quam rhoncus, eget porttitor magna ultrices. Sed tristique ut augue in facilisis. Duis in finibus diam. In hac habitasse platea dictumst. Vestibulum in pulvinar orci. Sed a justo cursus enim ultrices egestas sed sit amet leo. Donec sed auctor urna. Praesent vitae dapibus ipsum. Nulla facilisi. Pellentesque non nisi sem. Sed ac mi rutrum, blandit purus ut, facilisis ipsum. . { "minutes": 2, "words": 458 } . ����������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_admon.py�����������������������������������������������������������0000664�0000000�0000000�00000002002�14667654733�0020447�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.admon import admon_plugin FIXTURE_PATH = Path(__file__).parent @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "admon.md")), ) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(admon_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() @pytest.mark.parametrize("text_idx", (0, 1, 2)) def test_plugin_parse(data_regression, text_idx): texts = [ "!!! note\n content 1", "??? note\n content 2", "???+ note\n content 3", ] md = MarkdownIt().use(admon_plugin) tokens = md.parse(dedent(texts[text_idx])) data_regression.check([t.as_dict() for t in tokens]) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_admon/�������������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020103�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_admon/test_plugin_parse_0_.yml�������������������������������������0000664�0000000�0000000�00000003652�14667654733�0024741�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - admonition note block: true children: null content: Note hidden: false info: ' note' level: 0 map: - 0 - 2 markup: '!!!' meta: tag: note nesting: 1 tag: div type: admonition_open - attrs: - - class - admonition-title block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 1 markup: '!!! note' meta: {} nesting: 1 tag: p type: admonition_title_open - attrs: null block: true children: - attrs: null block: false children: null content: Note hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Note hidden: false info: '' level: 2 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: admonition_title_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: content 1 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: content 1 hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '!!!' meta: {} nesting: -1 tag: div type: admonition_close ��������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_admon/test_plugin_parse_1_.yml�������������������������������������0000664�0000000�0000000�00000003706�14667654733�0024742�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - admonition note is-collapsible collapsible-closed block: true children: null content: Note hidden: false info: ' note' level: 0 map: - 0 - 2 markup: ??? meta: tag: note nesting: 1 tag: div type: admonition_open - attrs: - - class - admonition-title block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 1 markup: ??? note meta: {} nesting: 1 tag: p type: admonition_title_open - attrs: null block: true children: - attrs: null block: false children: null content: Note hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Note hidden: false info: '' level: 2 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: admonition_title_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: content 2 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: content 2 hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: ??? meta: {} nesting: -1 tag: div type: admonition_close ����������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_admon/test_plugin_parse_2_.yml�������������������������������������0000664�0000000�0000000�00000003707�14667654733�0024744�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - admonition note is-collapsible collapsible-open block: true children: null content: Note hidden: false info: ' note' level: 0 map: - 0 - 2 markup: ???+ meta: tag: note nesting: 1 tag: div type: admonition_open - attrs: - - class - admonition-title block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 1 markup: ???+ note meta: {} nesting: 1 tag: p type: admonition_title_open - attrs: null block: true children: - attrs: null block: false children: null content: Note hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Note hidden: false info: '' level: 2 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: admonition_title_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: content 3 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: content 3 hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: ???+ meta: {} nesting: -1 tag: div type: admonition_close ���������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_amsmath.py���������������������������������������������������������0000664�0000000�0000000�00000002516�14667654733�0021015�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.amsmath import amsmath_plugin FIXTURE_PATH = Path(__file__).parent def test_plugin_parse(data_regression): md = MarkdownIt().use(amsmath_plugin) tokens = md.parse( dedent( """\ a \\begin{equation} b=1 c=2 \\end{equation} d """ ) ) data_regression.check([t.as_dict() for t in tokens]) def test_custom_renderer(data_regression): md = MarkdownIt().use(amsmath_plugin, renderer=lambda x: x + "!") output = md.render("\\begin{equation}\na\n\\end{equation}") assert ( output.strip() == dedent( """\ <div class="math amsmath"> \\begin{equation} a \\end{equation}! </div> """ ).strip() ) @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "amsmath.md")), ) def test_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use(amsmath_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_amsmath/�����������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020437�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_amsmath/test_plugin_parse.yml��������������������������������������0000664�0000000�0000000�00000003313�14667654733�0024711�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 0 - 1 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: a hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: a hidden: false info: '' level: 1 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '\begin{equation} b=1 c=2 \end{equation}' hidden: false info: '' level: 0 map: - 1 - 4 markup: '' meta: environment: equation numbered: '' nesting: 0 tag: math type: amsmath - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 5 - 6 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: d hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: d hidden: false info: '' level: 1 map: - 5 - 6 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_anchors.py���������������������������������������������������������0000664�0000000�0000000�00000001161�14667654733�0021013�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.anchors import anchors_plugin FIXTURE_PATH = Path(__file__).parent @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "anchors.md")), ) def test_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use( anchors_plugin, permalink="(permalink" in title, permalinkBefore="before)" in title, ) text = md.render(input) assert text.rstrip() == expected.rstrip() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_attrs.py�����������������������������������������������������������0000664�0000000�0000000�00000002042�14667654733�0020512�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.attrs import attrs_block_plugin, attrs_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures") @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH / "attrs.md") ) def test_attrs(line, title, input, expected): md = MarkdownIt("commonmark").use(attrs_plugin, spans=True).use(attrs_block_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() def test_attrs_allowed(data_regression): allowed = ["safe"] md = ( MarkdownIt("commonmark") .use(attrs_plugin, allowed=allowed) .use(attrs_block_plugin, allowed=allowed) ) tokens = md.parse(""" {danger1=a safe=b} {danger2=c safe=d} # header `inline`{safe=a danger=b} """) data_regression.check([t.as_dict() for t in tokens]) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_attrs/�������������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020142�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_attrs/test_attrs_allowed.yml���������������������������������������0000664�0000000�0000000�00000003143�14667654733�0024571�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - safe - d block: true children: null content: '' hidden: false info: '' level: 0 map: - 3 - 4 markup: '#' meta: insecure_attrs: danger1: a danger2: c nesting: 1 tag: h1 type: heading_open - attrs: null block: true children: - attrs: null block: false children: null content: header hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: header hidden: false info: '' level: 1 map: - 3 - 4 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '#' meta: {} nesting: -1 tag: h1 type: heading_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 5 - 6 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: - - safe - a block: false children: null content: inline hidden: false info: '' level: 0 map: null markup: '`' meta: insecure_attrs: danger: b nesting: 0 tag: code type: code_inline content: '`inline`{safe=a danger=b}' hidden: false info: '' level: 1 map: - 5 - 6 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_colon_fence.py�����������������������������������������������������0000664�0000000�0000000�00000001740�14667654733�0021633�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.colon_fence import colon_fence_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "colon_fence.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use(colon_fence_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) try: assert text.rstrip() == expected.rstrip() except AssertionError: print(text) raise def test_plugin_parse(data_regression): md = MarkdownIt().use(colon_fence_plugin) tokens = md.parse( dedent( """\ ::: name *content* ::: """ ) ) data_regression.check([t.as_dict() for t in tokens]) ��������������������������������mdit-py-plugins-0.4.2/tests/test_colon_fence/�������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021257�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_colon_fence/test_plugin_parse.yml����������������������������������0000664�0000000�0000000�00000000320�14667654733�0025524�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: '*content* ' hidden: false info: ' name' level: 0 map: - 0 - 3 markup: ':::' meta: {} nesting: 0 tag: code type: colon_fence ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_container.py�������������������������������������������������������0000664�0000000�0000000�00000002357�14667654733�0021350�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.container import container_plugin def test_plugin_parse(data_regression): md = MarkdownIt().use(container_plugin, "name") tokens = md.parse( dedent( """\ ::: name *content* ::: """ ) ) data_regression.check([t.as_dict() for t in tokens]) def test_no_new_line_issue(data_regression): """Fixed an IndexError when no newline on final line.""" md = MarkdownIt().use(container_plugin, "name") tokens = md.parse( dedent( """\ ::: name *content* :::""" ) ) data_regression.check([t.as_dict() for t in tokens]) FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "container.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(container_plugin, "name") if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_container/���������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020767�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_container/test_no_new_line_issue.yml�������������������������������0000664�0000000�0000000�00000003004�14667654733�0026252�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: '' hidden: false info: ' name' level: 0 map: - 0 - 2 markup: ':::' meta: {} nesting: 1 tag: div type: container_name_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: '' hidden: false info: '' level: 0 map: null markup: '*' meta: {} nesting: 1 tag: em type: em_open - attrs: null block: false children: null content: content hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: 0 tag: '' type: text - attrs: null block: false children: null content: '' hidden: false info: '' level: 0 map: null markup: '*' meta: {} nesting: -1 tag: em type: em_close content: '*content*' hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: ':::' meta: {} nesting: -1 tag: div type: container_name_close ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_container/test_plugin_parse.yml������������������������������������0000664�0000000�0000000�00000003004�14667654733�0025236�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: '' hidden: false info: ' name' level: 0 map: - 0 - 2 markup: ':::' meta: {} nesting: 1 tag: div type: container_name_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: '' hidden: false info: '' level: 0 map: null markup: '*' meta: {} nesting: 1 tag: em type: em_open - attrs: null block: false children: null content: content hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: 0 tag: '' type: text - attrs: null block: false children: null content: '' hidden: false info: '' level: 0 map: null markup: '*' meta: {} nesting: -1 tag: em type: em_close content: '*content*' hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: ':::' meta: {} nesting: -1 tag: div type: container_name_close ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_deflist.py���������������������������������������������������������0000664�0000000�0000000�00000001701�14667654733�0021010�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.deflist import deflist_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "deflist.md") def test_plugin_parse(data_regression): md = MarkdownIt().use(deflist_plugin) tokens = md.parse( dedent( """\ Term 1 : Definition 1 Term 2 ~ Definition 2a ~ Definition 2b """ ) ) data_regression.check([t.as_dict() for t in tokens]) @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(deflist_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() ���������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_deflist/�����������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020437�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_deflist/test_plugin_parse.yml��������������������������������������0000664�0000000�0000000�00000012014�14667654733�0024707�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 0 - 7 markup: '' meta: {} nesting: 1 tag: dl type: dl_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 0 markup: '' meta: {} nesting: 1 tag: dt type: dt_open - attrs: null block: true children: - attrs: null block: false children: null content: Term 1 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Term 1 hidden: false info: '' level: 2 map: - 0 - 0 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dt type: dt_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 2 - 4 markup: '' meta: {} nesting: 1 tag: dd type: dd_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 2 - 3 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: Definition 1 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Definition 1 hidden: false info: '' level: 3 map: - 2 - 3 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dd type: dd_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 4 - 4 markup: '' meta: {} nesting: 1 tag: dt type: dt_open - attrs: null block: true children: - attrs: null block: false children: null content: Term 2 hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Term 2 hidden: false info: '' level: 2 map: - 4 - 4 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dt type: dt_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 4 - 6 markup: '' meta: {} nesting: 1 tag: dd type: dd_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 5 - 6 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: Definition 2a hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Definition 2a hidden: false info: '' level: 3 map: - 5 - 6 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dd type: dd_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 6 - 7 markup: '' meta: {} nesting: 1 tag: dd type: dd_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 6 - 7 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: Definition 2b hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Definition 2b hidden: false info: '' level: 3 map: - 6 - 7 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dd type: dd_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: dl type: dl_close ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_dollarmath.py������������������������������������������������������0000664�0000000�0000000�00000005147�14667654733�0021515�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.dollarmath import dollarmath_plugin from mdit_py_plugins.dollarmath import index as main FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures") def test_inline_func(): inline_func = main.math_inline_dollar() md = MarkdownIt() src = r"$a=1$ $b=2$" tokens = [] state = StateInline(src, md, {}, tokens) inline_func(state, False) assert tokens[0].as_dict() == { "type": "math_inline", "tag": "math", "nesting": 0, "attrs": None, "map": None, "level": 0, "children": None, "content": "a=1", "markup": "$", "info": "", "meta": {}, "block": False, "hidden": False, } assert state.pos == 5 def test_block_func(): block_func = main.math_block_dollar() md = MarkdownIt() src = r"$$\na=1\n\nc\nb=2$$ (abc)" tokens = [] state = StateBlock(src, md, {}, tokens) block_func(state, 0, 10, False) print(tokens[0].as_dict()) assert tokens[0].as_dict() == { "type": "math_block_label", "tag": "math", "nesting": 0, "attrs": None, "map": [0, 1], "level": 0, "children": None, "content": "\\na=1\\n\\nc\\nb=2", "markup": "$$", "info": "abc", "meta": {}, "block": True, "hidden": False, } def test_plugin_parse(data_regression): md = MarkdownIt().use(dollarmath_plugin) tokens = md.parse( dedent( """\ $$ a=1 b=2 $$ (abc) - ab $c=1$ d """ ) ) data_regression.check([t.as_dict() for t in tokens]) def test_custom_renderer(data_regression): md = MarkdownIt().use(dollarmath_plugin, renderer=lambda x, y: x) assert md.render("$x$").strip() == '<p><span class="math inline">x</span></p>' @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("dollar_math.md")), ) def test_dollarmath_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use( dollarmath_plugin, allow_space=False, allow_digits=False, double_inline=True, allow_blank_lines=False, ) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options.xhtmlOut = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_dollarmath/��������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021134�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_dollarmath/test_plugin_parse.yml�����������������������������������0000664�0000000�0000000�00000004067�14667654733�0025415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: ' a=1 b=2 ' hidden: false info: abc level: 0 map: - 0 - 4 markup: $$ meta: {} nesting: 0 tag: math type: math_block_label - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 5 - 6 markup: '-' meta: {} nesting: 1 tag: ul type: bullet_list_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 5 - 6 markup: '-' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 5 - 6 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: 'ab ' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text - attrs: null block: false children: null content: c=1 hidden: false info: '' level: 0 map: null markup: $ meta: {} nesting: 0 tag: math type: math_inline - attrs: null block: false children: null content: ' d' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ab $c=1$ d hidden: false info: '' level: 3 map: - 5 - 6 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '-' meta: {} nesting: -1 tag: li type: list_item_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '-' meta: {} nesting: -1 tag: ul type: bullet_list_close �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_field_list.py������������������������������������������������������0000664�0000000�0000000�00000001773�14667654733�0021505�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.field_list import fieldlist_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "field_list.md") def test_plugin_parse(data_regression): md = MarkdownIt().use(fieldlist_plugin) tokens = md.parse( dedent( """\ :abc: Content :def: Content """ ) ) data_regression.check([t.as_dict() for t in tokens]) fixtures = read_fixture_file(FIXTURE_PATH) @pytest.mark.parametrize( "line,title,input,expected", fixtures, ids=[f"{f[0]}-{f[1].replace(' ', '_')}" for f in fixtures], ) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(fieldlist_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() �����mdit-py-plugins-0.4.2/tests/test_field_list/��������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021123�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_field_list/test_plugin_parse.yml�����������������������������������0000664�0000000�0000000�00000010043�14667654733�0025373�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - field-list block: true children: null content: '' hidden: false info: '' level: 0 map: - 0 - 2 markup: '' meta: {} nesting: 1 tag: dl type: field_list_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 0 markup: '' meta: {} nesting: 1 tag: dt type: fieldlist_name_open - attrs: null block: true children: - attrs: null block: false children: null content: abc hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: abc hidden: false info: '' level: 2 map: - 0 - 0 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dt type: fieldlist_name_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 1 markup: '' meta: {} nesting: 1 tag: dd type: fieldlist_body_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 2 map: - 0 - 1 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: Content hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Content hidden: false info: '' level: 3 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dd type: fieldlist_body_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 1 markup: '' meta: {} nesting: 1 tag: dt type: fieldlist_name_open - attrs: null block: true children: - attrs: null block: false children: null content: def hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: def hidden: false info: '' level: 2 map: - 1 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dt type: fieldlist_name_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: dd type: fieldlist_body_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: Content hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: Content hidden: false info: '' level: 3 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '' meta: {} nesting: -1 tag: dd type: fieldlist_body_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: dl type: field_list_close ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_footnote.py��������������������������������������������������������0000664�0000000�0000000�00000026703�14667654733�0021224�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from markdown_it.token import Token from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.footnote import footnote_plugin, index FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "footnote.md") def test_footnote_def(): md = MarkdownIt() src = r"[^a]: xyz" tokens = [] state = StateBlock(src, md, {}, tokens) index.footnote_def(state, 0, 1, False) assert [t.as_dict() for t in tokens] == [ { "type": "footnote_reference_open", "tag": "", "nesting": 1, "attrs": None, "map": [0, 1], "level": 0, "children": None, "content": "", "markup": "", "info": "", "meta": {"label": "a"}, "block": False, "hidden": False, }, { "type": "paragraph_open", "tag": "p", "nesting": 1, "attrs": None, "map": [0, 1], "level": 1, "children": None, "content": "", "markup": "", "info": "", "meta": {}, "block": True, "hidden": False, }, { "type": "inline", "tag": "", "nesting": 0, "attrs": None, "map": [0, 1], "level": 2, "children": [], "content": "xyz", "markup": "", "info": "", "meta": {}, "block": True, "hidden": False, }, { "type": "paragraph_close", "tag": "p", "nesting": -1, "attrs": None, "map": None, "level": 1, "children": None, "content": "", "markup": "", "info": "", "meta": {}, "block": True, "hidden": False, }, { "type": "footnote_reference_close", "tag": "", "nesting": -1, "attrs": None, "map": None, "level": 0, "children": None, "content": "", "markup": "", "info": "", "meta": {}, "block": False, "hidden": False, }, ] assert state.env == {"footnotes": {"refs": {":a": -1}, "list": {}}} def test_footnote_ref(): md = MarkdownIt() src = r"[^a]" tokens = [] state = StateInline(src, md, {}, tokens) state.env = {"footnotes": {"refs": {":a": -1}}} index.footnote_ref(state, False) # print([t.as_dict() for t in tokens]) assert [t.as_dict() for t in tokens] == [ { "type": "footnote_ref", "tag": "", "nesting": 0, "attrs": None, "map": None, "level": 0, "children": None, "content": "", "markup": "", "info": "", "meta": {"id": 0, "subId": 0, "label": "a"}, "block": False, "hidden": False, } ] assert state.env == { "footnotes": {"refs": {":a": 0}, "list": {0: {"label": "a", "count": 1}}} } def test_footnote_inline(): md = MarkdownIt().use(footnote_plugin) src = r"^[a]" tokens = [] state = StateInline(src, md, {}, tokens) state.env = {"footnotes": {"refs": {":a": -1}}} index.footnote_inline(state, False) # print([t.as_dict() for t in tokens]) assert [t.as_dict() for t in tokens] == [ { "type": "footnote_ref", "tag": "", "nesting": 0, "attrs": None, "map": None, "level": 0, "children": None, "content": "", "markup": "", "info": "", "meta": {"id": 0}, "block": False, "hidden": False, } ] assert state.env == { "footnotes": { "refs": {":a": -1}, "list": { 0: { "content": "a", "tokens": [ Token( type="text", tag="", nesting=0, attrs=None, map=None, level=0, children=None, content="a", markup="", info="", meta={}, block=False, hidden=False, ) ], } }, } } def test_footnote_tail(): md = MarkdownIt() tokens = [ Token( type="footnote_reference_open", tag="", nesting=1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={"label": "a"}, block=False, hidden=False, ), Token( type="paragraph_open", tag="p", nesting=1, attrs=None, map=[0, 1], level=1, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="inline", tag="", nesting=0, attrs=None, map=[0, 1], level=2, children=[], content="xyz", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="paragraph_close", tag="p", nesting=-1, attrs=None, map=None, level=1, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="footnote_reference_close", tag="", nesting=-1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=False, hidden=False, ), Token("other", "", 0), ] env = {"footnotes": {"refs": {":a": 0}, "list": {0: {"label": "a", "count": 1}}}} state = StateBlock("", md, env, tokens) index.footnote_tail(state) assert state.tokens == [ Token( type="other", tag="", nesting=0, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=False, hidden=False, ), Token( type="footnote_block_open", tag="", nesting=1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=False, hidden=False, ), Token( type="footnote_open", tag="", nesting=1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={"id": 0, "label": "a"}, block=False, hidden=False, ), Token( type="paragraph_open", tag="p", nesting=1, attrs=None, map=[0, 1], level=1, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="inline", tag="", nesting=0, attrs=None, map=[0, 1], level=2, children=[], content="xyz", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="footnote_anchor", tag="", nesting=0, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={"id": 0, "subId": 0, "label": "a"}, block=False, hidden=False, ), Token( type="paragraph_close", tag="p", nesting=-1, attrs=None, map=None, level=1, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="footnote_close", tag="", nesting=-1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=False, hidden=False, ), Token( type="footnote_block_close", tag="", nesting=-1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=False, hidden=False, ), ] def test_plugin_render(): md = MarkdownIt().use(footnote_plugin) text = md.render( dedent( """\ [^1] ^[a] [^a] [^a] [^1]: abc [^a]: xyz """ ) ) assert text == ( dedent( """\ <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> <sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> <sup class="footnote-ref"><a href="#fn3" id="fnref3:1">[3:1]</a></sup></p> <hr class="footnotes-sep" /> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>abc <a href="#fnref1" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn2" class="footnote-item"><p>a <a href="#fnref2" class="footnote-backref">β†©οΈŽ</a></p> </li> <li id="fn3" class="footnote-item"><p>xyz <a href="#fnref3" class="footnote-backref">β†©οΈŽ</a> <a href="#fnref3:1" class="footnote-backref">β†©οΈŽ</a></p> </li> </ol> </section> """ ) ) @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt().use( footnote_plugin, always_match_refs="ALWAYS_MATCH-REFS" in title ) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip().replace("β†©οΈŽ", "<-").replace( "↩", "<-" ) == expected.rstrip().replace("β†©οΈŽ", "<-").replace("↩", "<-") �������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_front_matter.py����������������������������������������������������0000664�0000000�0000000�00000002405�14667654733�0022064�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from markdown_it import MarkdownIt from markdown_it.token import Token from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.front_matter import front_matter_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "front_matter.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(front_matter_plugin) md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() def test_token(): md = MarkdownIt("commonmark").use(front_matter_plugin) tokens = md.parse("---\na: 1\n---") # print(tokens) assert tokens == [ Token( type="front_matter", tag="", nesting=0, attrs=None, map=[0, 3], level=0, children=None, content="a: 1", markup="---", info="", meta={}, block=True, hidden=True, ) ] def test_short_source(): md = MarkdownIt("commonmark").use(front_matter_plugin) # The code should not raise an IndexError. assert md.parse("-") �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_myst_block.py������������������������������������������������������0000664�0000000�0000000�00000004035�14667654733�0021527�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from markdown_it import MarkdownIt from markdown_it.token import Token from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.myst_blocks import myst_block_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "myst_block.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(myst_block_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() def test_block_token(): md = MarkdownIt("commonmark").use(myst_block_plugin) tokens = md.parse("+++") expected_token = Token( type="myst_block_break", tag="hr", nesting=0, map=[0, 1], level=0, children=None, content="", markup="+++", info="", meta={}, block=True, hidden=False, ) expected_token.attrSet("class", "myst-block") assert tokens == [expected_token] tokens = md.parse("\n+ + + abc") expected_token = Token( type="myst_block_break", tag="hr", nesting=0, map=[1, 2], level=0, children=None, content="abc", markup="+++", info="", meta={}, block=True, hidden=False, ) expected_token.attrSet("class", "myst-block") assert tokens == [expected_token] def test_comment_token(): md = MarkdownIt("commonmark").use(myst_block_plugin) tokens = md.parse("\n\n% abc \n%def") expected_token = Token( type="myst_line_comment", tag="", nesting=0, map=[2, 4], level=0, children=None, content=" abc\ndef", markup="%", info="", meta={}, block=True, hidden=False, ) expected_token.attrSet("class", "myst-line-comment") assert tokens == [expected_token] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_myst_role.py�������������������������������������������������������0000664�0000000�0000000�00000004341�14667654733�0021376�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from markdown_it import MarkdownIt from markdown_it.token import Token from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.myst_role import myst_role_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "myst_role.md") def test_basic(): md = MarkdownIt().use(myst_role_plugin) src = "{abc}``` a ```" tokens = md.parse(src) print(tokens) assert tokens == [ Token( type="paragraph_open", tag="p", nesting=1, attrs=None, map=[0, 1], level=0, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="inline", tag="", nesting=0, attrs=None, map=[0, 1], level=1, children=[ Token( type="myst_role", tag="", nesting=0, attrs=None, map=None, level=0, children=None, content=" a ", markup="", info="", meta={"name": "abc"}, block=False, hidden=False, ) ], content="{abc}``` a ```", markup="", info="", meta={}, block=True, hidden=False, ), Token( type="paragraph_close", tag="p", nesting=-1, attrs=None, map=None, level=0, children=None, content="", markup="", info="", meta={}, block=True, hidden=False, ), ] @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(myst_role_plugin) md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_substitution.py����������������������������������������������������0000664�0000000�0000000�00000001572�14667654733�0022140�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest # from markdown_it.token import Token from mdit_py_plugins.substitution import substitution_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "substitution.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").enable("table").use(substitution_plugin) text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() def test_tokens(data_regression): md = MarkdownIt().use(substitution_plugin) tokens = md.parse( dedent( """\ {{ block }} a {{ inline }} b """ ) ) data_regression.check([t.as_dict() for t in tokens]) ��������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_substitution/������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021561�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_substitution/test_tokens.yml���������������������������������������0000664�0000000�0000000�00000002676�14667654733�0024661�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - substitution - - text - block block: true children: null content: block hidden: false info: '' level: 0 map: - 0 - 1 markup: '{}' meta: {} nesting: 0 tag: div type: substitution_block - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 2 - 3 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: 'a ' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text - attrs: - - class - substitution - - text - inline block: false children: null content: inline hidden: false info: '' level: 0 map: null markup: '{}' meta: {} nesting: 0 tag: span type: substitution_inline - attrs: null block: false children: null content: ' b' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: a {{ inline }} b hidden: false info: '' level: 1 map: - 2 - 3 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close ������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_tasklists.py�������������������������������������������������������0000664�0000000�0000000�00000001655�14667654733�0021407�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.tasklists import tasklists_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "tasklists.md") def test_plugin_parse(data_regression): md = MarkdownIt().use(tasklists_plugin) tokens = md.parse( dedent( """\ * [ ] Task incomplete * [x] Task complete * [ ] Indented task incomplete * [x] Indented task complete """ ) ) data_regression.check([t.as_dict() for t in tokens]) @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(tasklists_plugin) md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() �����������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_tasklists/���������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0021026�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_tasklists/test_plugin_parse.yml������������������������������������0000664�0000000�0000000�00000014752�14667654733�0025311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: - - class - contains-task-list block: true children: null content: '' hidden: false info: '' level: 0 map: - 0 - 4 markup: '*' meta: {} nesting: 1 tag: ul type: bullet_list_open - attrs: - - class - task-list-item block: true children: null content: '' hidden: false info: '' level: 1 map: - 0 - 1 markup: '*' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 0 - 1 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: <input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: html_inline - attrs: null block: false children: null content: ' Task incomplete' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ' Task incomplete' hidden: false info: '' level: 3 map: - 0 - 1 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '*' meta: {} nesting: -1 tag: li type: list_item_close - attrs: - - class - task-list-item block: true children: null content: '' hidden: false info: '' level: 1 map: - 1 - 4 markup: '*' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 1 - 2 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: <input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: html_inline - attrs: null block: false children: null content: ' Task complete' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ' Task complete' hidden: false info: '' level: 3 map: - 1 - 2 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: - - class - contains-task-list block: true children: null content: '' hidden: false info: '' level: 2 map: - 2 - 4 markup: '*' meta: {} nesting: 1 tag: ul type: bullet_list_open - attrs: - - class - task-list-item block: true children: null content: '' hidden: false info: '' level: 3 map: - 2 - 3 markup: '*' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 4 map: - 2 - 3 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: <input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: html_inline - attrs: null block: false children: null content: ' Indented task incomplete' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ' Indented task incomplete' hidden: false info: '' level: 5 map: - 2 - 3 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 4 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 3 map: null markup: '*' meta: {} nesting: -1 tag: li type: list_item_close - attrs: - - class - task-list-item block: true children: null content: '' hidden: false info: '' level: 3 map: - 3 - 4 markup: '*' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 4 map: - 3 - 4 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: <input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: html_inline - attrs: null block: false children: null content: ' Indented task complete' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ' Indented task complete' hidden: false info: '' level: 5 map: - 3 - 4 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 4 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 3 map: null markup: '*' meta: {} nesting: -1 tag: li type: list_item_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 2 map: null markup: '*' meta: {} nesting: -1 tag: ul type: bullet_list_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '*' meta: {} nesting: -1 tag: li type: list_item_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '*' meta: {} nesting: -1 tag: ul type: bullet_list_close ����������������������mdit-py-plugins-0.4.2/tests/test_texmath.py���������������������������������������������������������0000664�0000000�0000000�00000005365�14667654733�0021042�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������from pathlib import Path from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock from markdown_it.rules_inline import StateInline from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.texmath import index as main from mdit_py_plugins.texmath import texmath_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures") def test_inline_func(): inline_func = main.make_inline_func(main.rules["dollars"]["inline"][0]) md = MarkdownIt() src = r"$a=1$ $b=2$" tokens = [] state = StateInline(src, md, {}, tokens) inline_func(state, False) assert tokens[0].as_dict() == { "type": "math_inline", "tag": "math", "nesting": 0, "attrs": None, "map": None, "level": 0, "children": None, "content": "a=1", "markup": "$", "info": "", "meta": {}, "block": False, "hidden": False, } assert state.pos == 5 def test_block_func(): block_func = main.make_block_func(main.rules["dollars"]["block"][0]) md = MarkdownIt() src = r"$$\na=1\n\nc\nb=2$$ (abc)" tokens = [] state = StateBlock(src, md, {}, tokens) block_func(state, 0, 10, False) assert tokens[0].as_dict() == { "type": "math_block_eqno", "tag": "math", "nesting": 0, "attrs": None, "map": None, "level": 0, "children": None, "content": "\\na=1\\n\\nc\\nb=2", "markup": "$$", "info": "abc", "meta": {}, "block": True, "hidden": False, } def test_plugin_parse(data_regression): md = MarkdownIt().use(texmath_plugin) tokens = md.parse( dedent( """\ $$ a=1 b=2 $$ (abc) - ab $c=1$ d """ ) ) data_regression.check([t.as_dict() for t in tokens]) @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("texmath_dollar.md")), ) def test_dollar_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use(texmath_plugin) if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() @pytest.mark.parametrize( "line,title,input,expected", read_fixture_file(FIXTURE_PATH.joinpath("texmath_bracket.md")), ) def test_bracket_fixtures(line, title, input, expected): md = MarkdownIt("commonmark").use(texmath_plugin, delimiters="brackets") if "DISABLE-CODEBLOCKS" in title: md.disable("code") md.options["xhtmlOut"] = False text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_texmath/�����������������������������������������������������������0000775�0000000�0000000�00000000000�14667654733�0020457�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_texmath/test_plugin_parse.yml��������������������������������������0000664�0000000�0000000�00000004057�14667654733�0024737�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������- attrs: null block: true children: null content: ' a=1 b=2 ' hidden: false info: abc level: 0 map: null markup: $$ meta: {} nesting: 0 tag: math type: math_block_eqno - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: - 5 - 6 markup: '-' meta: {} nesting: 1 tag: ul type: bullet_list_open - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: - 5 - 6 markup: '-' meta: {} nesting: 1 tag: li type: list_item_open - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: - 5 - 6 markup: '' meta: {} nesting: 1 tag: p type: paragraph_open - attrs: null block: true children: - attrs: null block: false children: null content: 'ab ' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text - attrs: null block: false children: null content: c=1 hidden: false info: '' level: 0 map: null markup: $ meta: {} nesting: 0 tag: math type: math_inline - attrs: null block: false children: null content: ' d' hidden: false info: '' level: 0 map: null markup: '' meta: {} nesting: 0 tag: '' type: text content: ab $c=1$ d hidden: false info: '' level: 3 map: - 5 - 6 markup: '' meta: {} nesting: 0 tag: '' type: inline - attrs: null block: true children: null content: '' hidden: true info: '' level: 2 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 1 map: null markup: '-' meta: {} nesting: -1 tag: li type: list_item_close - attrs: null block: true children: null content: '' hidden: false info: '' level: 0 map: null markup: '-' meta: {} nesting: -1 tag: ul type: bullet_list_close ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tests/test_wordcount.py�������������������������������������������������������0000664�0000000�0000000�00000001304�14667654733�0021401�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������import json from pathlib import Path from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file import pytest from mdit_py_plugins.wordcount import wordcount_plugin FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "wordcount.md") @pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH)) def test_all(line, title, input, expected): md = MarkdownIt("commonmark").use(wordcount_plugin, store_text="(text)" in title) env = {} md.render(input, env) data = json.dumps(env["wordcount"], indent=2, sort_keys=True) try: assert data.strip() == expected.strip() except AssertionError: print(data) raise ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������mdit-py-plugins-0.4.2/tox.ini�����������������������������������������������������������������������0000664�0000000�0000000�00000001031�14667654733�0016112�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# To use tox, see https://tox.readthedocs.io # Simply pip or conda install tox # If you use conda, you may also want to install tox-conda # then run `tox` or `tox -- {pytest args}` # run in parallel using `tox -p` [tox] envlist = py38 [testenv] usedevelop = true [testenv:py{38,39,310,311,312}] extras = testing commands = pytest {posargs} [testenv:docs-{update,clean}] extras = rtd whitelist_externals = rm commands = clean: rm -rf docs/_build sphinx-build -nW --keep-going -b {posargs:html} docs/ docs/_build/{posargs:html} �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������