├── .babelrc ├── .codecov.yml ├── .coveragerc ├── .eslintrc ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature.yml ├── dependabot.yml ├── labels.yml └── workflows │ ├── build.yml │ └── deploy.yml ├── .gitignore ├── .pyspelling.yml ├── .stylelintrc ├── LICENSE.md ├── README.md ├── SECURITY.md ├── docs ├── src │ ├── dictionary │ │ ├── en-custom.txt │ │ ├── en-javascript.txt │ │ └── en-python.txt │ ├── html │ │ ├── footer.html │ │ ├── header.html │ │ └── libs.html │ ├── js │ │ ├── arithmatex.js │ │ ├── extra-loader.js │ │ ├── material-extra-3rdparty.js │ │ ├── material-extra-theme.js │ │ └── uml.js │ ├── markdown │ │ ├── .snippets │ │ │ ├── abbr.md │ │ │ ├── blocksbeta.md │ │ │ ├── links.md │ │ │ ├── refs.md │ │ │ └── uml.md │ │ ├── about │ │ │ ├── changelog.md │ │ │ ├── contributing.md │ │ │ ├── development.md │ │ │ ├── license.md │ │ │ ├── releases │ │ │ │ ├── 6.0.md │ │ │ │ ├── 7.0.md │ │ │ │ ├── 8.0.md │ │ │ │ └── 9.0.md │ │ │ └── security.md │ │ ├── extensions │ │ │ ├── arithmatex.md │ │ │ ├── b64.md │ │ │ ├── betterem.md │ │ │ ├── blocks │ │ │ │ ├── api.md │ │ │ │ ├── index.md │ │ │ │ └── plugins │ │ │ │ │ ├── admonition.md │ │ │ │ │ ├── definition.md │ │ │ │ │ ├── details.md │ │ │ │ │ ├── html.md │ │ │ │ │ └── tab.md │ │ │ ├── caret.md │ │ │ ├── critic.md │ │ │ ├── details.md │ │ │ ├── emoji.md │ │ │ ├── escapeall.md │ │ │ ├── extra.md │ │ │ ├── highlight.md │ │ │ ├── inlinehilite.md │ │ │ ├── keys.md │ │ │ ├── magiclink.md │ │ │ ├── mark.md │ │ │ ├── pathconverter.md │ │ │ ├── progressbar.md │ │ │ ├── saneheaders.md │ │ │ ├── smartsymbols.md │ │ │ ├── snippets.md │ │ │ ├── striphtml.md │ │ │ ├── superfences.md │ │ │ ├── tabbed.md │ │ │ ├── tasklist.md │ │ │ └── tilde.md │ │ ├── extras │ │ │ ├── mermaid.md │ │ │ └── slugs.md │ │ ├── faq.md │ │ ├── images │ │ │ ├── mermaid-diagram.png │ │ │ ├── progress.png │ │ │ ├── tabbed-alternate.png │ │ │ ├── tabbed-default-narrow.png │ │ │ └── tabbed-default.png │ │ ├── index.md │ │ ├── installation.md │ │ └── usage_notes.md │ ├── mkdocs.yml │ └── scss │ │ ├── _config.scss │ │ ├── _general.scss │ │ ├── _material.scss │ │ ├── extensions │ │ ├── _admonition.scss │ │ ├── _arithmatex.scss │ │ ├── _critic.scss │ │ ├── _details.scss │ │ ├── _highlight.scss │ │ ├── _keys.scss │ │ ├── _magiclink.scss │ │ ├── _mark.scss │ │ ├── _progressbar.scss │ │ ├── _superfences.scss │ │ ├── _tabbed.scss │ │ ├── _tables.scss │ │ ├── _tasklist.scss │ │ └── _toc.scss │ │ ├── extra.scss │ │ ├── palette │ │ ├── _colors.scss │ │ └── _dracula.scss │ │ └── utilities │ │ ├── _break.scss │ │ ├── _color_tools.scss │ │ └── _convert.scss └── theme │ ├── announce.html │ ├── assets │ └── pymdownx-extras │ │ ├── extra-8611f6c398.css │ │ ├── extra-8611f6c398.css.map │ │ ├── extra-loader-iLQ-keay.js │ │ ├── extra-loader-iLQ-keay.js.map │ │ ├── material-extra-3rdparty-BUCF4rjN.js │ │ ├── material-extra-3rdparty-BUCF4rjN.js.map │ │ ├── material-extra-theme-2ek1P7jT.js │ │ └── material-extra-theme-2ek1P7jT.js.map │ ├── main.html │ └── partials │ ├── footer.html │ ├── header.html │ └── libs.html ├── gulpfile.babel.js ├── hatch_build.py ├── mkdocs.yml ├── package-lock.json ├── package.json ├── pymdownx ├── __init__.py ├── __meta__.py ├── _bypassnorm.py ├── arithmatex.py ├── b64.py ├── betterem.py ├── blocks │ ├── __init__.py │ ├── admonition.py │ ├── block.py │ ├── definition.py │ ├── details.py │ ├── html.py │ └── tab.py ├── caret.py ├── critic.py ├── details.py ├── emoji.py ├── emoji1_db.py ├── escapeall.py ├── extra.py ├── gemoji_db.py ├── highlight.py ├── inlinehilite.py ├── keymap_db.py ├── keys.py ├── magiclink.py ├── mark.py ├── pathconverter.py ├── progressbar.py ├── saneheaders.py ├── slugs.py ├── smartsymbols.py ├── snippets.py ├── striphtml.py ├── superfences.py ├── tabbed.py ├── tasklist.py ├── tilde.py ├── twemoji_db.py └── util.py ├── pyproject.toml ├── requirements ├── dev.txt ├── docs.txt ├── lint.txt ├── test.txt └── tools.txt ├── run_tests.py ├── tests ├── __init__.py ├── extensions │ ├── _assets │ │ ├── bg.png │ │ ├── headeranchor.css │ │ ├── progressbar.css │ │ ├── tabs.css │ │ ├── tasklist.css │ │ └── tasklist_custom.css │ ├── arithmatex │ │ ├── arithmatex (disable).html │ │ ├── arithmatex (disable).txt │ │ ├── arithmatex (dumb dollar).html │ │ ├── arithmatex (dumb dollar).txt │ │ ├── arithmatex (generic).html │ │ ├── arithmatex (generic).txt │ │ ├── arithmatex (no-preview).html │ │ ├── arithmatex (no-preview).txt │ │ ├── arithmatex.html │ │ ├── arithmatex.txt │ │ └── tests.yml │ ├── betterem │ │ ├── betterem (normal).html │ │ ├── betterem (normal).txt │ │ ├── betterem (reverse).html │ │ ├── betterem (reverse).txt │ │ └── tests.yml │ ├── caret │ │ ├── caret (dumb no sup).html │ │ ├── caret (dumb no sup).txt │ │ ├── caret (dumb).html │ │ ├── caret (dumb).txt │ │ ├── caret (no insert).html │ │ ├── caret (no insert).txt │ │ ├── caret (no sup).html │ │ ├── caret (no sup).txt │ │ ├── caret.html │ │ ├── caret.txt │ │ └── tests.yml │ ├── critic │ │ ├── critic (accept).html │ │ ├── critic (accept).txt │ │ ├── critic (reject).html │ │ ├── critic (reject).txt │ │ ├── critic (view).html │ │ ├── critic (view).txt │ │ └── tests.yml │ ├── emoji │ │ ├── emoji1 (entities).html │ │ ├── emoji1 (entities).txt │ │ ├── emoji1 (escaped).html │ │ ├── emoji1 (escaped).txt │ │ ├── emoji1 (long title).html │ │ ├── emoji1 (long title).txt │ │ ├── emoji1 (no title).html │ │ ├── emoji1 (no title).txt │ │ ├── emoji1 (png sprite).html │ │ ├── emoji1 (png sprite).txt │ │ ├── emoji1 (png).html │ │ ├── emoji1 (png).txt │ │ ├── emoji1 (svg sprite).html │ │ ├── emoji1 (svg sprite).txt │ │ ├── emoji1 (svg).html │ │ ├── emoji1 (svg).txt │ │ ├── gemoji (entities).html │ │ ├── gemoji (entities).txt │ │ ├── gemoji (png).html │ │ ├── gemoji (png).txt │ │ ├── tests.yml │ │ ├── twemoji (entities).html │ │ ├── twemoji (entities).txt │ │ ├── twemoji (png).html │ │ ├── twemoji (png).txt │ │ ├── twemoji (svg).html │ │ └── twemoji (svg).txt │ ├── escapeall │ │ ├── escapeall (critic).html │ │ ├── escapeall (critic).txt │ │ ├── escapeall (ws normal).html │ │ ├── escapeall (ws normal).txt │ │ ├── escapeall.html │ │ ├── escapeall.txt │ │ └── tests.yml │ ├── extra │ │ ├── extra (config).html │ │ ├── extra (config).txt │ │ ├── extra.html │ │ ├── extra.txt │ │ └── tests.yml │ ├── keys │ │ ├── keys (camel).html │ │ ├── keys (camel).txt │ │ ├── keys.html │ │ ├── keys.txt │ │ └── tests.yml │ ├── magiclink │ │ ├── magiclink (bitbucket).html │ │ ├── magiclink (bitbucket).txt │ │ ├── magiclink (extensions).html │ │ ├── magiclink (extensions).txt │ │ ├── magiclink (gitlab).html │ │ ├── magiclink (gitlab).txt │ │ ├── magiclink (invalid).html │ │ ├── magiclink (invalid).txt │ │ ├── magiclink (shorthand).html │ │ ├── magiclink (shorthand).txt │ │ ├── magiclink (shorthand-social).html │ │ ├── magiclink (shorthand-social).txt │ │ ├── magiclink.html │ │ ├── magiclink.txt │ │ ├── magiclink_hide_protocol.html │ │ ├── magiclink_hide_protocol.txt │ │ └── tests.yml │ ├── mark │ │ ├── mark (dumb).html │ │ ├── mark (dumb).txt │ │ ├── mark.html │ │ ├── mark.txt │ │ └── tests.yml │ ├── progressbar │ │ ├── progressbar.html │ │ ├── progressbar.txt │ │ └── tests.yml │ ├── striphtml │ │ ├── striphtml (no attr strip).html │ │ ├── striphtml (no attr strip).txt │ │ ├── striphtml.html │ │ ├── striphtml.txt │ │ └── tests.yml │ ├── superfences │ │ ├── superfences (custom).html │ │ ├── superfences (custom).txt │ │ ├── superfences (failures).html │ │ ├── superfences (failures).txt │ │ ├── superfences (no indent blocks).html │ │ ├── superfences (no indent blocks).txt │ │ ├── superfences (no pygments).html │ │ ├── superfences (no pygments).txt │ │ ├── superfences (normal).html │ │ ├── superfences (normal).txt │ │ ├── superfences (preserve tabs).html │ │ ├── superfences (preserve tabs).txt │ │ └── tests.yml │ ├── tasklist │ │ ├── tasklist (checkable).html │ │ ├── tasklist (checkable).txt │ │ ├── tasklist (custom checkable).html │ │ ├── tasklist (custom checkable).txt │ │ ├── tasklist (custom).html │ │ ├── tasklist (custom).txt │ │ ├── tasklist.html │ │ ├── tasklist.txt │ │ └── tests.yml │ └── tilde │ │ ├── tests.yml │ │ ├── tilde (dumb no sub).html │ │ ├── tilde (dumb no sub).txt │ │ ├── tilde (dumb).html │ │ ├── tilde (dumb).txt │ │ ├── tilde (no delete).html │ │ ├── tilde (no delete).txt │ │ ├── tilde (no sub).html │ │ ├── tilde (no sub).txt │ │ ├── tilde.html │ │ └── tilde.txt ├── test_extensions │ ├── __init__.py │ ├── _assets │ │ └── bg.png │ ├── _snippets │ │ ├── a.txt │ │ ├── b.txt │ │ ├── c.txt │ │ ├── d.txt │ │ ├── indented.txt │ │ ├── lines.txt │ │ ├── loop.txt │ │ ├── loop_block.txt │ │ ├── missing.txt │ │ ├── nested │ │ │ └── nested.txt │ │ ├── section.txt │ │ └── section_nested.txt │ ├── test_arithmatex.py │ ├── test_b64.py │ ├── test_betterem.py │ ├── test_blocks │ │ ├── __init__.py │ │ ├── test_admonitions.py │ │ ├── test_definition.py │ │ ├── test_details.py │ │ ├── test_general_blocks.py │ │ ├── test_html.py │ │ ├── test_legacy_tab.py │ │ └── test_tab.py │ ├── test_details.py │ ├── test_emoji.py │ ├── test_escapeall.py │ ├── test_highlight.py │ ├── test_inlinehilite.py │ ├── test_keys.py │ ├── test_legacy_slugs.py │ ├── test_magiclink.py │ ├── test_pathconverter.py │ ├── test_saneheaders.py │ ├── test_slugs.py │ ├── test_smartsymbols.py │ ├── test_snippets.py │ ├── test_striphmtl.py │ ├── test_superfences.py │ ├── test_tabbed.py │ └── test_tabbed_alternate.py ├── test_syntax.py ├── test_targeted.py ├── test_versions.py └── util.py └── tools ├── __init__.py ├── collapse_code.py ├── gen_emoji.py ├── gen_emoji1.py ├── gen_gemoji.py ├── gen_joypixels.py ├── gen_twemoji.py └── pymdownx_md_render.py /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | patch: false 6 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit= 3 | pymdownx/plainhtml.py 4 | 5 | [report] 6 | omit= 7 | pymdownx/plainhtml.py 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | tests/extensions/** linguist-vendored 2 | doc_theme/** linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: facelessuser 2 | custom: 3 | - "https://www.paypal.me/facelessuser" 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a bug 3 | labels: 4 | - 'T: bug' 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: A clear and concise description of the problem 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: reproduction 15 | attributes: 16 | label: Minimal Reproduction 17 | description: Provide steps to reproduce the problem 18 | placeholder: |- 19 | 1. ... 20 | 2. ... 21 | 3. ... 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: versions 26 | attributes: 27 | label: Version(s) & System Info 28 | description: >- 29 | Please provide problematic package version, Python version, operating 30 | system, etc. 31 | value: |- 32 | - Operating System: ... 33 | - Python Version: ... 34 | - Package Version: ... 35 | validations: 36 | required: true 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Question 4 | url: https://github.com/facelessuser/pymdown-extensions/discussions 5 | about: Ask a question 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Request a feature 3 | labels: 4 | - 'T: feature' 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: A clear and concise description of the problem or missing capability 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: benefits 15 | attributes: 16 | label: Benefits 17 | description: How would this benefit users in general? 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: solution-idea 22 | attributes: 23 | label: Solution Idea 24 | description: >- 25 | Do you have an idea of how this might work? If so, provide details, 26 | examples, references, etc. 27 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | 10 | documents: 11 | strategy: 12 | max-parallel: 4 13 | matrix: 14 | python-version: ['3.11'] 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | - name: Set up Python ${{ matrix.python-version }} 23 | uses: actions/setup-python@v5 24 | with: 25 | python-version: ${{ matrix.python-version }} 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip build 29 | python -m pip install -r requirements/docs.txt 30 | - name: Deploy documents 31 | run: | 32 | git config user.name ${{ secrets.GH_USER }} 33 | git config user.email "${{ secrets.GH_EMAIL }}" 34 | git remote add gh-token "https://${{ secrets.GH_TOKEN }}@github.com/facelessuser/pymdown-extensions.git" 35 | git fetch gh-token && git fetch gh-token gh-pages:gh-pages 36 | python -m mkdocs gh-deploy -v --clean --remote-name gh-token 37 | git push gh-token gh-pages 38 | 39 | pypi: 40 | runs-on: ubuntu-latest 41 | 42 | steps: 43 | - uses: actions/checkout@v4 44 | - uses: actions/setup-python@v5 45 | with: 46 | python-version: '3.11' 47 | - name: Package 48 | run: | 49 | pip install --upgrade build 50 | python -m build -s -w 51 | - name: Publish 52 | uses: pypa/gh-action-pypi-publish@release/v1 53 | with: 54 | user: __token__ 55 | password: ${{ secrets.PYPI_TOKEN }} 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | tools/emoji.md 60 | 61 | site/ 62 | 63 | tools/tags/ 64 | 65 | tmp* 66 | 67 | node_modules/ 68 | 69 | manifest*.json 70 | *.dic 71 | 72 | # IDE 73 | .vscode/ 74 | 75 | # cache 76 | .pytest_cache 77 | 78 | # Patches 79 | *.patch 80 | docs/src/dictionary/hunspell/ 81 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-recommended", 4 | "stylelint-config-rational-order" 5 | ], 6 | "plugins": [ 7 | "stylelint-order", 8 | "stylelint-scss" 9 | ], 10 | "rules": { 11 | "at-rule-empty-line-before": null, 12 | "at-rule-no-unknown": null, 13 | "at-rule-no-vendor-prefix": true, 14 | "color-hex-length": "long", 15 | "color-named": "never", 16 | "comment-empty-line-before": ["always", { 17 | "ignore": ["stylelint-commands"] 18 | }], 19 | "font-family-name-quotes": "always-where-recommended", 20 | "font-weight-notation": "numeric", 21 | "function-url-quotes": "always", 22 | "media-query-no-invalid": null, 23 | "no-descending-specificity": null, 24 | "no-unknown-animations": true, 25 | "property-no-vendor-prefix": true, 26 | "selector-class-pattern": "^[a-z0-9]+(-[a-z0-9]+)*(__[a-z]+)?(--[a-z]+)?$", 27 | "selector-type-no-unknown": [true, {"ignore": ["custom-elements"]}], 28 | "unit-allowed-list": ["px", "em", "deg", "ms", "%", "mm", "vh", "dppx", "s"], 29 | "value-keyword-case": "lower", 30 | "value-no-vendor-prefix": true, 31 | "function-no-unknown": null, 32 | "annotation-no-unknown": [true, {"ignoreAnnotations": ["default"]}] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Donate via PayPal][donate-image]][donate-link] 2 | [![Build][github-ci-image]][github-ci-link] 3 | [![Coverage Status][codecov-image]][codecov-link] 4 | [![PyPI Version][pypi-image]][pypi-link] 5 | [![PyPI Downloads][pypi-down]][pypi-link] 6 | [![PyPI - Python Version][python-image]][pypi-link] 7 | ![License][license-image-mit] 8 | 9 | # PyMdown Extensions 10 | 11 | Extensions for [Python Markdown](https://python-markdown.github.io). 12 | 13 | # Documentation 14 | 15 | Extension documentation is found here: https://facelessuser.github.io/pymdown-extensions/. 16 | 17 | # License 18 | 19 | License is MIT. See [LICENSE](https://github.com/facelessuser/pymdown-extensions/blob/master/LICENSE.md) for more info. 20 | 21 | [github-ci-image]: https://github.com/facelessuser/pymdown-extensions/workflows/build/badge.svg?branch=main&event=push 22 | [github-ci-link]: https://github.com/facelessuser/pymdown-extensions/actions?query=workflow%3Abuild+branch%3Amain 23 | [codecov-image]: https://img.shields.io/codecov/c/github/facelessuser/pymdown-extensions/main.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333 24 | [codecov-link]: https://codecov.io/github/facelessuser/pymdown-extensions 25 | [pypi-image]: https://img.shields.io/pypi/v/pymdown-extensions.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333 26 | [pypi-link]: https://pypi.python.org/pypi/pymdown-extensions 27 | [python-image]: https://img.shields.io/pypi/pyversions/pymdown-extensions?logo=python&logoColor=aaaaaa&labelColor=333333 28 | [pypi-down]: https://img.shields.io/pypi/dm/pymdown-extensions.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333 29 | [license-image-mit]: https://img.shields.io/badge/license-MIT-blue.svg?labelColor=333333 30 | [donate-image]: https://img.shields.io/badge/Donate-PayPal-3fabd1?logo=paypal 31 | [donate-link]: https://www.paypal.me/facelessuser 32 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Vulnerabilities 2 | 3 | Our policy for security related issues is to fix related issues within our power on the most recent major release. 4 | 5 | ## Versioning 6 | 7 | Versioning follows [PEP440](https://peps.python.org/pep-0440/): `major.minior.patch`. 8 | 9 | Versions | Description 10 | -------- | ----------- 11 | Major | This reserved for releases that introduce breaking features. 12 | Minor | This reserved for releases that introduce new functionality. 13 | Patch | This is reserved for releases that only include bug fixes. 14 | 15 | Example 16 | 17 | ``` 18 | 8.0 19 | 8.1 20 | 8.1.3 21 | ``` 22 | 23 | ## Create Security Vulnerability Report 24 | 25 | If you have found a security vulnerability, you can create a draft "security advisory" on the GitHub repository, 26 | [instructions here](https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/creating-a-repository-security-advisory). 27 | Such advisories are kept private as the issue is explored. 28 | 29 | ## Security Vulnerability Workflow 30 | 31 | We will strive to acknowledge the report in about two business days. 32 | 33 | Reports will be kept private until the issue is properly understood. 34 | 35 | If the report is accepted we will notify Tidelift (who we've partnered with), request a CVE from GitHub, and work with 36 | the reporter to find a resolution. Work will be done privately, and the final commit will not mention the security 37 | issue. 38 | 39 | The fix, announcement, and release will be negotiated with the reporter. 40 | 41 | Afterwards, a release will be made and the vulnerability will be made public as close to each other as possible. 42 | -------------------------------------------------------------------------------- /docs/src/dictionary/en-javascript.txt: -------------------------------------------------------------------------------- 1 | className 2 | param 3 | -------------------------------------------------------------------------------- /docs/src/dictionary/en-python.txt: -------------------------------------------------------------------------------- 1 | BOM 2 | BOMs 3 | Dedent 4 | LLC 5 | StackOverflow 6 | Twardoch 7 | UrlParse 8 | arithmatex 9 | autogen 10 | betterem 11 | bowtie 12 | bypassnorm 13 | chunking 14 | dedent 15 | escapeall 16 | extrarawhtml 17 | feelsgood 18 | finnadie 19 | fu 20 | goberserk 21 | godmode 22 | hurtrealbad 23 | inlinehilite 24 | magiclink 25 | neckbeard 26 | netpath 27 | octocat 28 | ord 29 | pathconverter 30 | plainhtml 31 | progressbar 32 | shipit 33 | smartstrong 34 | smartsymbols 35 | striphtml 36 | tasklist 37 | tasklists 38 | trollface 39 | tuple 40 | wildcard 41 | -------------------------------------------------------------------------------- /docs/src/html/libs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /docs/src/js/arithmatex.js: -------------------------------------------------------------------------------- 1 | export default (className, mode) => { 2 | if (mode === 'katex') { 3 | const maths = document.querySelectorAll(`.${className}`) 4 | 5 | for (let i = 0; i < maths.length; i++) { 6 | const tex = maths[i].textContent || maths[i].innerText 7 | 8 | if (tex.startsWith('\\(') && tex.endsWith('\\)')) { 9 | katex.render(tex.slice(2, -2), maths[i], {'displayMode': false}) 10 | } else if (tex.startsWith('\\[') && tex.endsWith('\\]')) { 11 | katex.render(tex.slice(2, -2), maths[i], {'displayMode': true}) 12 | } 13 | } 14 | } else if (mode === 'mathjax') { 15 | MathJax.startup.output.clearCache() 16 | MathJax.typesetClear() 17 | MathJax.texReset() 18 | MathJax.typesetPromise() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/src/js/extra-loader.js: -------------------------------------------------------------------------------- 1 | import uml from "./uml" 2 | import arithmatex from "./arithmatex" 3 | 4 | // Main function 5 | (() => { 6 | let umlPromise = Promise.resolve() 7 | let mathPromise = Promise.resolve() 8 | 9 | const observer = new MutationObserver(mutations => { 10 | mutations.forEach(mutation => { 11 | if (mutation.type === "attributes") { 12 | let scheme = mutation.target.getAttribute("data-md-color-scheme") 13 | if (!scheme) { 14 | scheme = "default" 15 | } 16 | localStorage.setItem("data-md-color-scheme", scheme) 17 | if (typeof mermaid !== "undefined") { 18 | uml("diagram") 19 | } 20 | } 21 | }) 22 | }) 23 | 24 | const main = () => { 25 | observer.observe(document.querySelector("body"), {attributeFilter: ["data-md-color-scheme"]}) 26 | 27 | if (typeof mermaid !== "undefined") { 28 | umlPromise = umlPromise.then(() => { 29 | uml("diagram") 30 | }).catch(err => { 31 | console.log(`UML loading failed...${err}`) // eslint-disable-line no-console 32 | }) 33 | } 34 | 35 | if (typeof katex !== "undefined") { 36 | mathPromise = mathPromise.then(() => { 37 | arithmatex("arithmatex", "katex") 38 | }).catch(err => { 39 | console.log(`Math loading failed...${err}`) // eslint-disable-line no-console 40 | }) 41 | } else if (typeof MathJax !== "undefined" && 'typesetPromise' in MathJax) { 42 | mathPromise = mathPromise.then(() => { 43 | arithmatex("arithmatex", "mathjax") 44 | }).catch(err => { 45 | console.log(`Math loading failed...${err}`) // eslint-disable-line no-console 46 | }) 47 | } 48 | } 49 | 50 | if (window.document$) { 51 | // Material specific hook 52 | window.document$.subscribe(main) 53 | } else { 54 | // Normal non-Material specific hook 55 | document.addEventListener("DOMContentLoaded", main) 56 | } 57 | })() 58 | -------------------------------------------------------------------------------- /docs/src/js/material-extra-theme.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | 3 | const preferToggle = e => { 4 | if (localStorage.getItem("data-md-prefers-color-scheme") === "true") { 5 | document.querySelector("body").setAttribute("data-md-color-scheme", (e.matches) ? "dracula" : "default") 6 | } 7 | } 8 | 9 | const setupTheme = body => { 10 | const preferSupported = window.matchMedia("(prefers-color-scheme)").media !== "not all" 11 | let scheme = localStorage.getItem("data-md-color-scheme") 12 | let prefers = localStorage.getItem("data-md-prefers-color-scheme") 13 | 14 | if (!scheme) { 15 | scheme = "dracula" 16 | } 17 | if (!prefers) { 18 | prefers = "false" 19 | } 20 | 21 | if (prefers === "true" && preferSupported) { 22 | scheme = (window.matchMedia("(prefers-color-scheme: dark)").matches) ? "dracula" : "default" 23 | } else { 24 | prefers = "false" 25 | } 26 | 27 | body.setAttribute("data-md-prefers-color-scheme", prefers) 28 | body.setAttribute("data-md-color-scheme", scheme) 29 | 30 | if (preferSupported) { 31 | const matchListener = window.matchMedia("(prefers-color-scheme: dark)") 32 | matchListener.addListener(preferToggle) 33 | } 34 | } 35 | 36 | const observer = new MutationObserver(mutations => { 37 | mutations.forEach(mutation => { 38 | if (mutation.type === "childList") { 39 | if (mutation.addedNodes.length) { 40 | for (let i = 0; i < mutation.addedNodes.length; i++) { 41 | const el = mutation.addedNodes[i] 42 | 43 | if (el.nodeType === 1 && el.tagName.toLowerCase() === "body") { 44 | setupTheme(el) 45 | break 46 | } 47 | } 48 | } 49 | } 50 | }) 51 | }) 52 | 53 | observer.observe(document.querySelector("html"), {childList: true}) 54 | })() 55 | 56 | window.toggleScheme = () => { 57 | const body = document.querySelector("body") 58 | const preferSupported = window.matchMedia("(prefers-color-scheme)").media !== "not all" 59 | let scheme = body.getAttribute("data-md-color-scheme") 60 | let prefer = body.getAttribute("data-md-prefers-color-scheme") 61 | 62 | if (preferSupported && scheme === "default" && prefer !== "true") { 63 | prefer = "true" 64 | scheme = (window.matchMedia("(prefers-color-scheme: dark)").matches) ? "dracula" : "default" 65 | } else if (preferSupported && prefer === "true") { 66 | prefer = "false" 67 | scheme = "dracula" 68 | } else if (scheme === "dracula") { 69 | prefer = "false" 70 | scheme = "default" 71 | } else { 72 | prefer = "false" 73 | scheme = "dracula" 74 | } 75 | localStorage.setItem("data-md-prefers-color-scheme", prefer) 76 | body.setAttribute("data-md-prefers-color-scheme", prefer) 77 | body.setAttribute("data-md-color-scheme", scheme) 78 | } 79 | -------------------------------------------------------------------------------- /docs/src/markdown/.snippets/abbr.md: -------------------------------------------------------------------------------- 1 | *[Toc]: Table of Contents 2 | *[GFM]: GitHub Flavored Markdown 3 | *[FAQ]: Frequent Asked Questions 4 | -------------------------------------------------------------------------------- /docs/src/markdown/.snippets/blocksbeta.md: -------------------------------------------------------------------------------- 1 | /// new | 9.10 New Experimental Feature 2 | Blocks is currently a new, experimental extension type available in Pymdown Extensions that allows for writing a new 3 | kind of block extension in Python Markdown. With this new addition, we've added a number of new extensions utilizing 4 | this new extension type. While its intention is to hopefully replace extensions like Details and Tabbed, there are 5 | currently no immediate plans to deprecate those plugins. 6 | 7 | Any and all feedback regarding these new, experimental blocks is appreciated. Please provide feedback here: 8 | https://github.com/facelessuser/pymdown-extensions/discussions/1973. 9 | /// 10 | -------------------------------------------------------------------------------- /docs/src/markdown/.snippets/refs.md: -------------------------------------------------------------------------------- 1 | --8<-- 2 | links.md 3 | abbr.md 4 | --8<-- 5 | -------------------------------------------------------------------------------- /docs/src/markdown/about/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing & Support 2 | 3 | ## Become a Sponsor :octicons-heart-fill-16:{: .heart-throb} 4 | 5 | Open source projects take time and money. Help support the project by becoming a sponsor. You can add your support at 6 | any tier you feel comfortable with. No amount is too little. We also accept one time contributions via PayPal. 7 | 8 | [:octicons-mark-github-16: GitHub Sponsors](https://github.com/sponsors/facelessuser){: .md-button .md-button--primary } 9 | [:fontawesome-brands-paypal: PayPal](https://www.paypal.me/facelessuser){ .md-button} 10 | 11 | ## Bug Reports :material-bug: 12 | 13 | 1. Please **read the documentation** and **search the issue tracker** to try and find the answer to your question 14 | **before** posting an issue. 15 | 16 | 2. When creating an issue on the repository, please provide as much info as possible: 17 | 18 | - Version being used. 19 | - Operating system. 20 | - Version of Python. 21 | - Errors in console. 22 | - Detailed description of the problem. 23 | - Examples for reproducing the error. You can post pictures, but if specific text or code is required to 24 | reproduce the issue, please provide the text in a plain text format for easy copy/paste. 25 | 26 | The more info provided, the greater the chance someone will take the time to answer, implement, or fix the issue. 27 | 28 | 3. Be prepared to answer questions and provide additional information if required. Issues in which the creator refuses 29 | to respond to follow up questions will be marked as stale and closed. 30 | 31 | ## Reviewing Code :material-glasses: 32 | 33 | Take part in reviewing pull requests and/or reviewing direct commits. Make suggestions to improve the code and discuss 34 | solutions to overcome weakness in the algorithm. 35 | 36 | ## Answer Questions in Issues :material-comment-question: 37 | 38 | Take time and answer questions and offer suggestions to people who've created issues in the issue tracker. Often people 39 | will have questions that you might have an answer for. Or maybe you know how to help them accomplish a specific task 40 | they are asking about. Feel free to share your experience to help others out. 41 | 42 | ## Pull Requests :octicons-git-pull-request-24: 43 | 44 | Pull requests are welcome, and a great way to help fix bugs and add new features. If you you are interested in directly 45 | contributing to the code, please check out [Development](./development.md) for more info on the environment and process. 46 | 47 | ## Documentation Improvements :material-pencil: 48 | 49 | A ton of time has been spent not only creating and supporting this tool and related extensions, but also spent making 50 | this documentation. If you feel it is still lacking, show your appreciation for the tool and/or extensions by helping 51 | to improve the documentation. Check out [Development](./development.md) for more info on documentation. 52 | -------------------------------------------------------------------------------- /docs/src/markdown/about/license.md: -------------------------------------------------------------------------------- 1 | --8<-- "LICENSE.md" 2 | -------------------------------------------------------------------------------- /docs/src/markdown/about/releases/6.0.md: -------------------------------------------------------------------------------- 1 | # 6.0 Migration Notes {: #\6.0} 2 | 3 | ## Overview 4 | 5 | While there are a number of new features and bug fixes, the only backwards incompatible changes are with SuperFences' 6 | custom fences. In an effort to make custom fences more useful, we wanted to be able to pass the `Markdown` object to the 7 | formatters. This gives custom formats access to things like metadata if required. 8 | 9 | The format of custom fence formatters already had two different versions: ones without custom options and one with 10 | custom options. As adding yet another parameter would cause more complexity behind the scenes, we decided to introduce 11 | the breaking change of creating a unified format for formatters with custom options and without. In addition to unifying 12 | the format, we also now pass the `Markdown` object to the formatters as an additional parameter. 13 | 14 | While we were breaking custom formats, it seemed like a good time to go ahead and change the defaults for the 15 | `custom_fences` options. Most people who are using SuperFences aren't even using the default, niche `flow` and 16 | `sequence` custom fences. Instead of hijacking fence names that most people aren't even using, it seemed more 17 | appropriate to define no custom fences. 18 | 19 | Below are instructions on how to upgrade if you were relying on the either the default settings of `custom_fences` or if 20 | you had written your own custom fence formatters. 21 | 22 | 1. If you've written your own custom fence formatters, the number of parameters needed has changed, so you must update 23 | your existing formatters. The needed parameters are the same regardless of whether you are using an options 24 | validator or not. 25 | 26 | ```py3 27 | def custom_formatter(source, language, css_class, options, md): 28 | return string 29 | ``` 30 | 31 | 2. `flow` and `sequence` are no longer defined by default. If you were relying on the default custom fences, you will 32 | have to define them manually now. The needed settings are found below: 33 | 34 | ```py3 35 | extension_configs = { 36 | "pymdownx.superfences": { 37 | "custom_fences": [ 38 | { 39 | 'name': 'flow', 40 | 'class': 'uml-flowchart', 41 | 'format': pymdownx.superfences.fence_code_format 42 | }, 43 | { 44 | 'name': 'sequence', 45 | 'class': 'uml-sequence-diagram', 46 | 'format': pymdownx.superfences.fence_code_format 47 | } 48 | ] 49 | } 50 | } 51 | ``` 52 | 53 | If you are attempting to configure these options in a YAML based configuration (like in [MkDocs][mkdocs]), please 54 | see the [FAQ](../../faq.md#function-references-in-yaml) to see how to specify function references in YAML. 55 | -------------------------------------------------------------------------------- /docs/src/markdown/about/security.md: -------------------------------------------------------------------------------- 1 | --8<-- "SECURITY.md" 2 | -------------------------------------------------------------------------------- /docs/src/markdown/extensions/b64.md: -------------------------------------------------------------------------------- 1 | [:octicons-file-code-24:][_b64]{: .source-link } 2 | 3 | # B64 4 | 5 | ## Overview 6 | 7 | B64 allows for the embedding of local PNG, JPEG, and GIF image references with base64 encoding. It simply needs a base 8 | path to resolve relative links in the Markdown source. The base path is the assumed location of the Markdown source at 9 | time of conversion. Using the base path, B64 will search and find the actual `img` tag references (both absolute and 10 | relative) and base64 encode and embed them in the HTML output. 11 | 12 | If you would like to distribute a Markdown output without having to also distribute the images separately, B64 can help. 13 | In a normal website, this would probably not be desired. 14 | 15 | ```text title="B64 Image" 16 |  17 | ``` 18 | 19 | /// html | div.result 20 | ```html 21 |
22 | ```
23 | ///
24 |
25 | The B64 extension can be included in Python Markdown by using the following:
26 |
27 | ```py3
28 | import markdown
29 | md = markdown.Markdown(extensions=['pymdownx.b64'])
30 | ```
31 |
32 | ## Options
33 |
34 | Option | Type | Default | Description
35 | ----------- | ------ | ----------- |------------
36 | `base_path` | string | `#!py3 '.'` | A string indicating a base path to be used to resolve relative links.
37 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/caret.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_caret]{: .source-link }
2 |
3 | # Caret
4 |
5 | ## Overview
6 |
7 | Caret optionally adds two different features which are syntactically built around the `^` character. The first is
8 | **insert** which inserts `#!html ` tags. The second is **superscript** which inserts `#!html `
9 | tags.
10 |
11 | The Caret extension can be included in Python Markdown by using the following:
12 |
13 | ```py3
14 | import markdown
15 | md = markdown.Markdown(extensions=['pymdownx.caret'])
16 | ```
17 |
18 | ## Insert
19 |
20 | To wrap content in an **insert** tag, simply surround the text with double `^`. You can also enable `smart_insert` in
21 | the [options](#options). Smart behavior of **insert** models that of [BetterEm](betterem.md#differences).
22 |
23 | ```text title="Insert"
24 | ^^Insert me^^
25 | ```
26 |
27 | /// html | div.result
28 | ^^Insert me^^
29 | ///
30 |
31 | ## Superscript
32 |
33 | To denote a superscript, you can surround the desired content in single `^`. It uses Pandoc style logic, so if your
34 | superscript needs to have spaces, you must escape the spaces.
35 |
36 | ```text title="Superscript"
37 | H^2^0
38 |
39 | text^a\ superscript^
40 | ```
41 |
42 | /// html | div.result
43 | H^2^0
44 |
45 | text^a\ superscript^
46 | ///
47 |
48 | ## Options
49 |
50 | Option | Type | Default | Description
51 | -------------- | ---- | ------------ | -----------
52 | `smart_insert` | bool | `#!py3 True` | Use smart logic with insert characters.
53 | `insert` | bool | `#!py3 True` | Enable insert feature.
54 | `superscript` | bool | `#!py3 True` | Enable superscript feature.
55 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/escapeall.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_escapeall]{: .source-link }
2 |
3 | # EscapeAll
4 |
5 | ## Overview
6 |
7 | If you ever have to stop and try to remember, *Can I escape this char?* or *Will a backslash escape this?*, you are not
8 | alone. EscapeAll makes `\` escape everything making such questions moot. Now instead of questioning or looking up what
9 | can be escaped, you can expect that `\` will escape the character following it. So if you need a literal `\`, just
10 | escape it: `\\`. Keep in mind this will not escape things in code blocks of any kind.
11 |
12 | ```text title="Escaping"
13 | \W\e\ \c\a\n\ \e\s\c\a\p\e
14 | \e\v\e\r\y\t\h\i\n\g\!\ \
15 | \❤\😄
16 | ```
17 |
18 | /// html | div.result
19 | \W\e\ \c\a\n\ \e\s\c\a\p\e
20 | \e\v\e\r\y\t\h\i\n\g\!\ \
21 | \❤\😄
22 | ///
23 |
24 | There are two special escapes among all of these escapes though: escaping "space" characters and escaping "newline"
25 | characters. If `nbsp` is enabled, an escaped space will be converted into a non-breaking space: `#!html `. If
26 | `hardbreak` is enabled, an escaped newline will be converted to a hard break `#!html
`. The advantage of `hardbreak`
27 | is that you can visually see the hard break opposed to Markdown's default method of two spaces at the end of a line.
28 |
29 | So in short, EscapeAll escapes all inline characters.
30 |
31 | /// question | Q & A
32 | **So all ASCII characters?**
33 |
34 | _It escapes everything._
35 |
36 | **What about Unicode?**
37 |
38 | _It escapes everything!_
39 |
40 | **What about...**
41 |
42 | _EVERYTHING! IT ESCAPES EVERYTHING!_
43 | ///
44 |
45 | The EscapeAll extension can be included in Python Markdown by using the following:
46 |
47 | ```py3
48 | import markdown
49 | md = markdown.Markdown(extensions=['pymdownx.escapeall'])
50 | ```
51 |
52 | ## Options
53 |
54 | Option | Type | Default | Description
55 | ----------- | ---- | --------------- | ----------
56 | `hardbreak` | bool | `#!py3 False` | Escaped newlines will be hard breaks: `#!html
`.
57 | `nbsp` | bool | `#!py3 False` | Escaped spaces will be non-breaking spaces: `#!html `.
58 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/extra.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_extra]{: .source-link }
2 |
3 | # Extra
4 |
5 | ## Overview
6 |
7 | Python Markdown has an `extra` extension that provides features similar to PHP Markdown Extra. PyMdown Extensions aims
8 | to provide not only new features, but to improve behavior in Python Markdown's existing feature set. Some of these
9 | things can be at odds. Python Markdown's `smartstrong` and `fenced_code` are not compatible with PyMdown Extensions'
10 | `betterem` and `superfences`. `smartstrong` should never be loaded at the same time as `betterem`, and `superfences`
11 | should not be loaded at the same time as `fenced_code`. For these reasons, it is not possible to use Python Markdown's
12 | `extra` and PyMdown Extensions' `superfences` and `betterem` at the same time. To make this less frustrating, PyMdown
13 | Extensions provides it's own implementation of `extra`.
14 |
15 | PyMdown Extensions' `extra` is just like Python Markdown's extra except `smartstrong` is replaced by `betterem` and
16 | `fenced_code` is replaced by `superfences`. All other features and extensions should be identical because we are using
17 | the same ones.
18 |
19 | This extension is a convenience extension, and it currently provides no other additional features. But remember **don't
20 | use `pymdownx.extra` while also using `markdown.extensions.extra`**!
21 |
22 | /// danger | Reminder
23 | Remember to read the [Usage Notes](../usage_notes.md) for information that may be relevant when using this
24 | extension!
25 | ///
26 |
27 | Extensions:
28 |
29 | Extension | Name
30 | ---------------------------------- |--------
31 | [BetterEm](./betterem.md) | `pymdownx.betterem`
32 | [SuperFences](./superfences.md) | `pymdownx.superfences`
33 | [Footnotes][footnotes] | `markdown.extensions.footnotes`
34 | [Attribute Lists][attr-list] | `markdown.extensions.attr_list`
35 | [Definition Lists][def-list] | `markdown.extensions.def_list`
36 | [Tables][tables] | `markdown.extensions.tables`
37 | [Abbreviations][abbreviations] | `markdown.extensions.abbr`
38 | [Markdown in HTML][md-in-html] | `markdown.extensions.md_in_html`
39 |
40 | The Extra extension can be included in Python Markdown by using the following:
41 |
42 | ```py3
43 | import markdown
44 | md = markdown.Markdown(extensions=['pymdownx.extra'])
45 | ```
46 |
47 | ## Options
48 |
49 | If you wish to configure the individual extensions included via this extensions, you can configure them by placing that
50 | sub extension's settings under a setting value that equals the sub extensions name.
51 |
52 | ```py3
53 | extension_configs = {
54 | 'pymdownx.extra': {
55 | 'markdown.extensions.footnotes': {
56 | 'BACKLINK_TEXT': 'link'
57 | }
58 | }
59 | }
60 | ```
61 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/mark.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_mark]{: .source-link }
2 |
3 | # Mark
4 |
5 | ## Overview
6 |
7 | Mark adds the ability to insert `#!html ` tags. The syntax requires the text to be surrounded by double
8 | equal signs. It can optionally be configured to use smart logic. Syntax behavior for smart and non-smart variants of
9 | **mark** models that of [BetterEm](betterem.md#differences).
10 |
11 | To Mark some text, simply surround the text with double `=`.
12 |
13 | ```text title="Marking"
14 | ==mark me==
15 |
16 | ==smart==mark==
17 | ```
18 |
19 | /// html | div.result
20 | ==mark me==
21 |
22 | ==smart==mark==
23 | ///
24 |
25 | The Mark extension can be included in Python Markdown by using the following:
26 |
27 | ```py3
28 | import markdown
29 | md = markdown.Markdown(extensions=['pymdownx.mark'])
30 | ```
31 |
32 | ## Options
33 |
34 | Option | Type | Default | Description
35 | ------------ | ---- | ----------- |------------
36 | `smart_mark` | bool | `#!py3 True` | Use smart logic with mark characters.
37 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/saneheaders.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_saneheaders]{: .source-link }
2 |
3 | # SaneHeaders
4 |
5 | ## Overview
6 |
7 | SaneHeaders is an extension that alters the default hashed headers extension to require headers to have spaces after the
8 | hashes (`#`) in order to be recognized as headers. This allows for other extension syntaxes to use `#` in their syntaxes
9 | as long as no spaces follow the `#` at the beginning of a line. For instance,
10 | [MagicLink's issue syntax](./magiclink.md#issues-and-pull-requests) issue syntax uses hashes followed by numbers
11 | (`#998`) to represent issue links. There may be extensions that use names after hashes to provide tags (`#tag`). With
12 | SaneHeaders, these syntaxes can coexist. Those familiar with CommonMark may recognize this behavior.
13 |
14 | ```py3
15 | import markdown
16 | md = markdown.Markdown(extensions=['pymdownx.saneheaders'])
17 | ```
18 |
19 | ## Syntax
20 |
21 | The syntax when using SaneHeaders is exactly like Python Markdown's default logic with the only exception being that
22 | SaneHeaders will not treat hashes at the beginning of a line as a header if they do not have space after them.
23 |
24 | In Python Markdown, both of these are treated as headers:
25 |
26 | ```
27 | ## Header
28 |
29 | ##Also a Header
30 | ```
31 |
32 | With SaneHeaders, only the first is a header:
33 |
34 | ```
35 | ## Header
36 |
37 | ##Not a Header
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/smartsymbols.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_smartsymbols]{: .source-link }
2 |
3 | # SmartSymbols
4 |
5 | ## Overview
6 |
7 | SmartSymbols adds syntax for creating special characters such as trademarks, arrows, fractions, etc. It basically
8 | allows for more "smarty-pants" like replacements. It is meant to be used along side Python Markdown's `smarty`
9 | extension not to replace.
10 |
11 | Markdown | Result
12 | -------------- |--------
13 | `(tm)` | (tm)
14 | `(c)` | (c)
15 | `(r)` | (r)
16 | `c/o` | c/o
17 | `+/-` | +/-
18 | `-->` | -->
19 | `<--` | <--
20 | `<-->` | <-->
21 | `=/=` | =/=
22 | `1/4, etc.` | 1/4, etc.
23 | `1st 2nd etc.` |1st 2nd etc.
24 |
25 | The SmartSymbols extension can be included in Python Markdown by using the following:
26 |
27 | ```py3
28 | import markdown
29 | md = markdown.Markdown(extensions=['pymdownx.smartsymbols'])
30 | ```
31 |
32 | ## Options
33 |
34 | Option | Type | Default | Description
35 | ----------------- | ---- | ----------- |------------
36 | `trademark` | bool | `#!py3 True` | Add syntax for trademark symbol.
37 | `copyright` | bool | `#!py3 True` | Add syntax for copyright symbol.
38 | `registered` | bool | `#!py3 True` | Add syntax for registered symbol.
39 | `care_of` | bool | `#!py3 True` | Add syntax for care / of.
40 | `plusminus` | bool | `#!py3 True` | Add syntax for plus / minus.
41 | `arrows` | bool | `#!py3 True` | Add syntax for creating arrows.
42 | `notequal` | bool | `#!py3 True` | Add syntax for not equal symbol.
43 | `fractions` | bool | `#!py3 True` | Add syntax for common fractions.
44 | `ordinal_numbers` | bool | `#!py3 True` | Add syntax for ordinal numbers.
45 |
--------------------------------------------------------------------------------
/docs/src/markdown/extensions/striphtml.md:
--------------------------------------------------------------------------------
1 | [:octicons-file-code-24:][_striphtml]{: .source-link }
2 |
3 | # StripHTML
4 |
5 | ## Overview
6 |
7 | StripHTML (formally known as PlainHTML) is a simple extension that is run at the end of post-processing. It searches
8 | the final output stripping out unwanted comments and/or tag attributes. Though it does its best to be loaded at the very
9 | end of the process, it helps to include this one last when loading up your extensions.
10 |
11 | ```text title="Stripping Comments"
12 |
14 |
15 | Here is a test.
16 | ```
17 |
18 | /// html | div.result
19 | ```html
20 |
Here is a test.
21 | ``` 22 | /// 23 | 24 | Because comments aren't stripped until the end in a post-processing step, they are present throughout the entire 25 | Markdown conversion process and could possibly affect parsing, so be careful how you generally insert comments. 26 | 27 | /// warning 28 | This is not meant to be a sanitizer for HTML. This is just meant to try and strip out style, script, classes, etc. 29 | to provide a plain HTML output for the times this is desired; this is not meant as a security extension. If you 30 | want something to secure the output, you should consider running a sanitizer like [Bleach][bleach]. 31 | /// 32 | 33 | The StripHTML extension can be included in Python Markdown by using the following: 34 | 35 | ```py3 36 | import markdown 37 | md = markdown.Markdown(extensions=['pymdownx.striphtml']) 38 | ``` 39 | 40 | ## Options 41 | 42 | By default, StripHTML strips the following attributes: `style`, `id`, `class`, and `onA link https://google.com
' 19 | ``` 20 | 21 | Check out documentation on each extension to learn more about how to configure and use each one. 22 | 23 | /// danger | Reminder 24 | Please read the [Usage Notes](usage_notes.md) for information on extension compatibility and general notes to be 25 | aware of when using these extensions. 26 | /// 27 | 28 | ## Extensions 29 | 30 | | Extensions | 31 | -------------------------------------------- | ---------------------------------------- | ------ 32 | [Arithmatex](extensions/arithmatex.md) | [B64](extensions/b64.md) | [BetterEm](extensions/betterem.md) 33 | [Blocks](extensions/blocks/index.md) | [Caret](extensions/caret.md) | [Critic](extensions/critic.md) 34 | [Details](extensions/details.md) | [Emoji](extensions/emoji.md) | [EscapeAll](extensions/escapeall.md) 35 | [Extra](extensions/extra.md) | [Highlight](extensions/highlight.md) | [InlineHilite](extensions/inlinehilite.md) 36 | [Keys](extensions/keys.md) | [MagicLink](extensions/magiclink.md) | [Mark](extensions/mark.md) 37 | [PathConverter](extensions/pathconverter.md) | [ProgressBar](extensions/progressbar.md) | [SaneHeaders](extensions/saneheaders.md) 38 | [SmartSymbols](extensions/smartsymbols.md) | [Snippets](extensions/snippets.md) | [StripHTML](extensions/striphtml.md) 39 | [SuperFences](extensions/superfences.md) | [Tabbed](extensions/tabbed.md) | [Tasklist](extensions/tasklist.md) 40 | [Tilde](extensions/tilde.md) | | 41 | -------------------------------------------------------------------------------- /docs/src/markdown/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Requirements 4 | 5 | In order for PyMdown Extensions to work, there are a couple of prerequisites. 6 | 7 | Name | Required | Details 8 | ---------------------------------- | -------- | ------- 9 | [Python Markdown][python-markdown] | Yes | Python Markdown must be installed as it is the Markdown parser that is being used. 10 | [Pygments (optional)][pygments] | No | If Pygments Syntax highlighting is desired, Pygments must be installed. This can be omitted, and code blocks will be formatted for use with JavaScript code highlighters. 11 | 12 | ## Installation 13 | 14 | Installation is easy with pip: 15 | 16 | ```console 17 | $ pip install pymdown-extensions 18 | ``` 19 | 20 | If you want to manually install it, run: 21 | 22 | ```console 23 | $ python setup.py build 24 | $ python setup.py install 25 | ``` 26 | 27 | After installing, you should be able to access the extensions in Python Markdown under the namespace 28 | `pymdownx.$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j$
2 |(3+3) 3 | \(3+3) 4 | \(3+3)
5 |$$ 6 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j 7 | $$
8 |[ 9 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j 10 | ]
11 |$$ 12 | \begin{align} 13 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \ 14 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) 15 | \end{align} 16 | $$
17 | 27 | -------------------------------------------------------------------------------- /tests/extensions/arithmatex/arithmatex (disable).txt: -------------------------------------------------------------------------------- 1 | \$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j\$ 2 | 3 | \(3+3\) 4 | \\(3+3\) 5 | \\\(3+3\) 6 | 7 | $$ 8 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j 9 | $$ 10 | 11 | \[ 12 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j 13 | \] 14 | 15 | $$ 16 | \begin{align} 17 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\ 18 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) 19 | \end{align} 20 | $$ 21 | 22 | 32 | 33 | -------------------------------------------------------------------------------- /tests/extensions/arithmatex/arithmatex (generic).html: -------------------------------------------------------------------------------- 1 |I have $3.00 and you have $5.00.
3 |$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j$
5 |\\(3+3\)
7 |\$3+3$
9 |\(\$3.00 + \$5.00 = \$8.00\)
11 |\(3+3\) 13 | \(3+3) 14 | \\(3+3\)
15 |Here are some more equations:
25 |Inline equations: \(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\), \(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\).
34 |$$
38 | \begin{align}
39 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
40 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
41 | \end{align}
42 | $$
$$
45 | \begin{align}
46 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
47 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
48 | \end{align}
49 | $$
50 |
51 |
65 |
--------------------------------------------------------------------------------
/tests/extensions/arithmatex/arithmatex (generic).txt:
--------------------------------------------------------------------------------
1 | # Dollar Sign Not Trigger
2 | I have $3.00 and you have $5.00.
3 |
4 | # Dollar Sign Escape
5 | \$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j\$
6 |
7 | # Dollar Sign Escaped Escape
8 | \\$3+3$
9 |
10 | # Dollar Double escaped escape
11 | \\\$3+3$
12 |
13 | # Use Dollar sign
14 | $\$3.00 + \$5.00 = \$8.00$
15 |
16 | # Keep equations separate
17 |
18 | \(3+3\)
19 | \\(3+3\)
20 | \\\(3+3\)
21 |
22 | # Equations
23 |
24 | $$
25 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
26 | $$
27 |
28 | \[
29 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
30 | \]
31 |
32 | - Here are some more equations:
33 |
34 | $$
35 | \begin{align}
36 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
37 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
38 | \end{align}
39 | $$
40 |
41 | - Inline equations: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$, \(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\).
42 |
43 | # Code
44 |
45 | ```
46 | $$
47 | \begin{align}
48 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
49 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
50 | \end{align}
51 | $$
52 | ```
53 |
54 |
55 | # Indented Code
56 |
57 | $$
58 | \begin{align}
59 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
60 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
61 | \end{align}
62 | $$
63 |
64 |
78 |
79 |
--------------------------------------------------------------------------------
/tests/extensions/arithmatex/arithmatex (no-preview).html:
--------------------------------------------------------------------------------
1 | I have $3.00 and you have $5.00.
3 |$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j$
5 |7 |
\
9 |\$3+3$
11 |13 | \(3+3) 14 | \
15 |Here are some more equations:
29 |Inline equations: , .
40 |$$
44 | \begin{align}
45 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
46 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
47 | \end{align}
48 | $$
$$
51 | \begin{align}
52 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
53 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
54 | \end{align}
55 | $$
56 |
57 |
67 |
--------------------------------------------------------------------------------
/tests/extensions/arithmatex/arithmatex (no-preview).txt:
--------------------------------------------------------------------------------
1 | # Dollar Sign Not Trigger
2 | I have $3.00 and you have $5.00.
3 |
4 | # Dollar Sign Escape
5 | \$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j\$
6 |
7 | # Use Dollar sign
8 | $\$3.00 + \$5.00 = \$8.00$
9 |
10 | # Dollar Sign Escaped Escape
11 | \\$3+3$
12 |
13 | # Dollar Double escaped escape
14 | \\\$3+3$
15 |
16 | # Keep equations separate
17 |
18 | \(3+3\)
19 | \\(3+3\)
20 | \\\(3+3\)
21 |
22 | # Equations
23 |
24 | $$
25 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
26 | $$
27 |
28 | \[
29 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
30 | \]
31 |
32 | - Here are some more equations:
33 |
34 | $$
35 | \begin{align}
36 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
37 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
38 | \end{align}
39 | $$
40 |
41 | - Inline equations: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$, \(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\).
42 |
43 | # Code
44 |
45 | ```
46 | $$
47 | \begin{align}
48 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
49 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
50 | \end{align}
51 | $$
52 | ```
53 |
54 |
55 | # Indented Code
56 |
57 | $$
58 | \begin{align}
59 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
60 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
61 | \end{align}
62 | $$
63 |
64 |
74 |
75 |
--------------------------------------------------------------------------------
/tests/extensions/arithmatex/arithmatex.txt:
--------------------------------------------------------------------------------
1 | # Dollar Sign Not Trigger
2 | I have $3.00 and you have $5.00.
3 |
4 | # Dollar Sign Escape
5 | \$E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j\$
6 |
7 | # Dollar Sign Escaped Escape
8 | \\$3+3$
9 |
10 | # Dollar Double escaped escape
11 | \\\$3+3$
12 |
13 | # Use Dollar sign
14 | $\$3.00 + \$5.00 = \$8.00$
15 |
16 | # Keep equations separate
17 |
18 | \(3+3\)
19 | \\(3+3\)
20 | \\\(3+3\)
21 |
22 | # Equations
23 |
24 | $$
25 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
26 | $$
27 |
28 | \[
29 | E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j
30 | \]
31 |
32 | - Here are some more equations:
33 |
34 | $$
35 | \begin{align}
36 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
37 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
38 | \end{align}
39 | $$
40 |
41 | - Inline equations: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$, \(p(x|y) = \frac{p(y|x)p(x)}{p(y)}\).
42 |
43 | # Code
44 |
45 | ```
46 | $$
47 | \begin{align}
48 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
49 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
50 | \end{align}
51 | $$
52 | ```
53 |
54 |
55 | # Indented Code
56 |
57 | $$
58 | \begin{align}
59 | p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\
60 | p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right)
61 | \end{align}
62 | $$
63 |
64 |
74 |
75 |
--------------------------------------------------------------------------------
/tests/extensions/arithmatex/tests.yml:
--------------------------------------------------------------------------------
1 | __default__: {}
2 |
3 | arithmatex:
4 | extensions:
5 | pymdownx.arithmatex:
6 |
7 | arithmatex (dumb dollar):
8 | extensions:
9 | pymdownx.arithmatex:
10 | generic: true
11 | smart_dollar: false
12 |
13 | arithmatex (generic):
14 | extensions:
15 | pymdownx.arithmatex:
16 | generic: true
17 |
18 | arithmatex (disable):
19 | extensions:
20 | pymdownx.arithmatex:
21 | block_syntax: []
22 | inline_syntax: []
23 |
24 | arithmatex (no-preview):
25 | extensions:
26 | pymdownx.arithmatex:
27 | preview: false
28 |
--------------------------------------------------------------------------------
/tests/extensions/betterem/betterem (normal).html:
--------------------------------------------------------------------------------
1 | Test: * Won't highlight *
2 |Test: Will highlight
3 |Test: I'm italic and bold I am just bold.
4 |Test: I'm bold and italic! I am just italic.
5 |Test: A lot of underscores____________is okay
6 |Test: This will all be bold __because of the placement of the center underscores.
7 |Test: This will all be bold __ because of the placement of the center underscores.
8 |Test: This will NOT all be bold because of the placement of the center underscores.__
9 |Test: This will all be bold_ because the token is less than that of the surrounding.
10 |Test: This is text bold italic bold with more text
11 |Test: All will * be italic
12 |Test: All will *be italic
13 |Test: All will not be italic*
14 |Test: All will not ** be italic
15 |Test: All will * be bold
16 |Test: All will *be italic*
17 |Test: All will not* be bold**
18 |Test: All will not *** be bold
19 |Test: This is text bold italic bold with more text
20 |Test: test test test test
21 |Test: test test *test*
22 |Test: test * test
23 |Test: test ** test
24 |Test: test test test test
25 |Test: test_ test _test
26 |Test: test _ test
27 |Test: test __ test
28 |Test: test (test) test
29 |Test: test (test) test
30 |One asterisk: *
31 |One underscore: _
32 |Two asterisks: **
33 |With spaces: * *
34 |Two underscores __
35 |with spaces: _ _
36 |three asterisks: ***
37 |with spaces: * * *
38 |three underscores: ___
39 |with spaces: _ _ _
40 |One char: a
-------------------------------------------------------------------------------- /tests/extensions/betterem/betterem (normal).txt: -------------------------------------------------------------------------------- 1 | Test: * Won't highlight * 2 | 3 | Test: *Will highlight* 4 | 5 | Test: ***I'm italic and bold* I am just bold.** 6 | 7 | Test: ***I'm bold and italic!** I am just italic.* 8 | 9 | Test: ___A lot of underscores____________is okay___ 10 | 11 | Test: __This will all be bold __because of the placement of the center underscores.__ 12 | 13 | Test: __This will all be bold __ because of the placement of the center underscores.__ 14 | 15 | Test: __This will NOT all be bold__ because of the placement of the center underscores.__ 16 | 17 | Test: __This will all be bold_ because the token is less than that of the surrounding.__ 18 | 19 | Test: This is text __bold _italic bold___ with more text 20 | 21 | Test: *All will * be italic* 22 | 23 | Test: *All will *be italic* 24 | 25 | Test: *All will not* be italic* 26 | 27 | Test: *All will not ** be italic* 28 | 29 | Test: **All will * be bold** 30 | 31 | Test: *All will *be italic** 32 | 33 | Test: **All will not*** be bold** 34 | 35 | Test: **All will not *** be bold** 36 | 37 | Test: This is text **bold *italic bold*** with more text 38 | 39 | Test: **test *test* *test* test** 40 | 41 | Test: ***test* test *test*** 42 | 43 | Test: *test * test* 44 | 45 | Test: **test ** test** 46 | 47 | Test: __test _test_ _test_ test__ 48 | 49 | Test: ___test_ test _test___ 50 | 51 | Test: _test _ test_ 52 | 53 | Test: __test __ test__ 54 | 55 | Test: **test *(test)* test** 56 | 57 | Test: __test _(test)_ test__ 58 | 59 | One asterisk: * 60 | 61 | One underscore: _ 62 | 63 | Two asterisks: ** 64 | 65 | With spaces: * * 66 | 67 | Two underscores __ 68 | 69 | with spaces: _ _ 70 | 71 | three asterisks: *** 72 | 73 | with spaces: * * * 74 | 75 | three underscores: ___ 76 | 77 | with spaces: _ _ _ 78 | 79 | One char: _a_ 80 | -------------------------------------------------------------------------------- /tests/extensions/betterem/betterem (reverse).html: -------------------------------------------------------------------------------- 1 |Test: _ Won't highlight _
2 |Test: Will highlight
3 |Test: I'm italic and bold I am just bold.
4 |Test: I'm bold and italic! I am just italic.
5 |Test: A lot of asterisks************is okay
6 |Test: This will all be bold **because of the placement of the center asterisk.
7 |Test: This will all be bold ** because of the placement of the center asterisk.
8 |Test: This will NOT all be bold because of the placement of the center asterisk.**
9 |Test: This will all be bold* because the token is less than that of the surrounding.
10 |Test: This is text bold italic bold with more text
11 |Test: All will _ be italic
12 |Test: All will _be italic
13 |Test: All will not be italic_
14 |Test: All will not __ be italic
15 |Test: All will _ be bold
16 |Test: All will _be italic_
17 |Test: All will not_ be bold__
18 |Test: All will not ___ be bold
19 |Test: This is text bold italic bold with more text
20 |Test: test test test test
21 |Test: test* test *test
22 |Test: test * test
23 |Test: test ** test
24 |Test: test test test test
25 |Test: test test _test_
26 |Test: test _ test
27 |Test: test __ test
28 |Test: test (test) test
29 |Test: test (test) test
-------------------------------------------------------------------------------- /tests/extensions/betterem/betterem (reverse).txt: -------------------------------------------------------------------------------- 1 | Test: _ Won't highlight _ 2 | 3 | Test: _Will highlight_ 4 | 5 | Test: ___I'm italic and bold_ I am just bold.__ 6 | 7 | Test: ___I'm bold and italic!__ I am just italic._ 8 | 9 | Test: ***A lot of asterisks************is okay*** 10 | 11 | Test: **This will all be bold **because of the placement of the center asterisk.** 12 | 13 | Test: **This will all be bold ** because of the placement of the center asterisk.** 14 | 15 | Test: **This will NOT all be bold** because of the placement of the center asterisk.** 16 | 17 | Test: **This will all be bold* because the token is less than that of the surrounding.** 18 | 19 | Test: This is text **bold *italic bold*** with more text 20 | 21 | Test: _All will _ be italic_ 22 | 23 | Test: _All will _be italic_ 24 | 25 | Test: _All will not_ be italic_ 26 | 27 | Test: _All will not __ be italic_ 28 | 29 | Test: __All will _ be bold__ 30 | 31 | Test: _All will _be italic__ 32 | 33 | Test: __All will not___ be bold__ 34 | 35 | Test: __All will not ___ be bold__ 36 | 37 | Test: This is text __bold _italic bold___ with more text 38 | 39 | Test: **test *test* *test* test** 40 | 41 | Test: ***test* test *test*** 42 | 43 | Test: *test * test* 44 | 45 | Test: **test ** test** 46 | 47 | Test: __test _test_ _test_ test__ 48 | 49 | Test: ___test_ test _test___ 50 | 51 | Test: _test _ test_ 52 | 53 | Test: __test __ test__ 54 | 55 | Test: **test *(test)* test** 56 | 57 | Test: __test _(test)_ test__ 58 | -------------------------------------------------------------------------------- /tests/extensions/betterem/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | betterem (normal): 4 | extensions: 5 | pymdownx.betterem: 6 | 7 | betterem (reverse): 8 | extensions: 9 | pymdownx.betterem: 10 | smart_enable: asterisk 11 | -------------------------------------------------------------------------------- /tests/extensions/caret/caret (dumb no sup).html: -------------------------------------------------------------------------------- 1 |Test: ^^ Won't insert ^^
2 |Test: Will insert
3 |Test: ^^Escaped^^
4 |Test: All will ^ be insert
5 |Test: All will^ not be insert^^
6 |Test: All will ^^^ be insert
-------------------------------------------------------------------------------- /tests/extensions/caret/caret (dumb no sup).txt: -------------------------------------------------------------------------------- 1 | Test: ^^ Won't insert ^^ 2 | 3 | Test: ^^Will insert^^ 4 | 5 | Test: \^\^Escaped\^\^ 6 | 7 | Test: ^^All will ^ be insert^^ 8 | 9 | Test: ^^All will^^^ not be insert^^ 10 | 11 | Test: ^^All will ^^^ be insert^^ 12 | -------------------------------------------------------------------------------- /tests/extensions/caret/caret (dumb).html: -------------------------------------------------------------------------------- 1 |x2 + y2 = 4
2 |Textsuperscript
3 |Text^superscript failed^
4 |Textsuperscript success
5 |Test: ^^ Won't insert ^^
6 |Test: Will insert
7 |Test: ^^Escaped^^
8 |Test: All will ^ be insert
9 |Test: All will^ be insert with superscript in middle
10 |Test: All will ^ be insert with superscript in middle
-------------------------------------------------------------------------------- /tests/extensions/caret/caret (dumb).txt: -------------------------------------------------------------------------------- 1 | x^2^ + y^2^ = 4 2 | 3 | Text^superscript^ 4 | 5 | Text^superscript failed^ 6 | 7 | Text^superscript\ success^ 8 | 9 | Test: ^^ Won't insert ^^ 10 | 11 | Test: ^^Will insert^^ 12 | 13 | Test: \^\^Escaped\^\^ 14 | 15 | Test: ^^All will ^ be insert^^ 16 | 17 | Test: ^^All will^\^^ be insert with superscript in middle^^ 18 | 19 | Test: ^^All will ^\^^ be insert with superscript in middle^^ 20 | -------------------------------------------------------------------------------- /tests/extensions/caret/caret (no insert).html: -------------------------------------------------------------------------------- 1 |x2 + y2 = 4
2 |Textsuperscript
3 |Text^superscript failed^
4 |Textsuperscript success
5 |Test: ^^Won't insert^^
-------------------------------------------------------------------------------- /tests/extensions/caret/caret (no insert).txt: -------------------------------------------------------------------------------- 1 | x^2^ + y^2^ = 4 2 | 3 | Text^superscript^ 4 | 5 | Text^superscript failed^ 6 | 7 | Text^superscript\ success^ 8 | 9 | Test: ^^Won't insert^^ 10 | -------------------------------------------------------------------------------- /tests/extensions/caret/caret (no sup).html: -------------------------------------------------------------------------------- 1 |Test: ^^ Won't insert ^^
2 |Test: Will insert
3 |Test: ^^Escaped^^
4 |Test: This will all be inserted ^^because of the placement of the center carets.
5 |Test: This will all be inserted ^^ because of the placement of the center carets.
6 |Test: This will NOT all be inserted because of the placement of the center caret.^^
7 |Test: This will all be inserted^ because of the token is less than that of the caret.
-------------------------------------------------------------------------------- /tests/extensions/caret/caret (no sup).txt: -------------------------------------------------------------------------------- 1 | Test: ^^ Won't insert ^^ 2 | 3 | Test: ^^Will insert^^ 4 | 5 | Test: \^\^Escaped\^\^ 6 | 7 | Test: ^^This will all be inserted ^^because of the placement of the center carets.^^ 8 | 9 | Test: ^^This will all be inserted ^^ because of the placement of the center carets.^^ 10 | 11 | Test: ^^This will NOT all be inserted^^ because of the placement of the center caret.^^ 12 | 13 | Test: ^^This will all be inserted^ because of the token is less than that of the caret.^^ 14 | -------------------------------------------------------------------------------- /tests/extensions/caret/caret.html: -------------------------------------------------------------------------------- 1 |x2 + y2 = 4
2 |Textsuperscript
3 |Text^superscript failed^
4 |Textsuperscript success
5 |Test: ^^ Won't insert ^^
6 |Test: Will insert
7 |Test: ^^Escaped^^
8 |Test: This will all be inserted ^^because of the placement of the center carets.
9 |Test: This will all be inserted ^^ because of the placement of the center carets.
10 |Test: This will NOT all be inserted because of the placement of the center caret.^^
11 |Test: This will all be inserted^ because of the token is less than that of the caret.
-------------------------------------------------------------------------------- /tests/extensions/caret/caret.txt: -------------------------------------------------------------------------------- 1 | x^2^ + y^2^ = 4 2 | 3 | Text^superscript^ 4 | 5 | Text^superscript failed^ 6 | 7 | Text^superscript\ success^ 8 | 9 | Test: ^^ Won't insert ^^ 10 | 11 | Test: ^^Will insert^^ 12 | 13 | Test: \^\^Escaped\^\^ 14 | 15 | Test: ^^This will all be inserted ^^because of the placement of the center carets.^^ 16 | 17 | Test: ^^This will all be inserted ^^ because of the placement of the center carets.^^ 18 | 19 | Test: ^^This will NOT all be inserted^^ because of the placement of the center caret.^^ 20 | 21 | Test: ^^This will all be inserted^ because of the token is less than that of the caret.^^ 22 | -------------------------------------------------------------------------------- /tests/extensions/caret/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | caret: 4 | extensions: 5 | pymdownx.caret: 6 | 7 | caret (dumb): 8 | extensions: 9 | pymdownx.caret: 10 | smart_insert: false 11 | 12 | caret (dumb no sup): 13 | extensions: 14 | pymdownx.caret: 15 | smart_insert: false 16 | superscript: false 17 | 18 | caret (no insert): 19 | extensions: 20 | pymdownx.caret: 21 | insert: false 22 | 23 | caret (no sup): 24 | extensions: 25 | pymdownx.caret: 26 | superscript: false 27 | -------------------------------------------------------------------------------- /tests/extensions/critic/critic (accept).html: -------------------------------------------------------------------------------- 1 |Here is some Markdown. I am adding this here.. Here is some more text. And here is even more text that I 2 | am adding. Paragraph was deleted and replaced with some spaces.
3 |Spaces were removed and a paragraph was added.
4 |And here is a comment on some 5 | ==text== . Substitutions are great!
6 |General block handling.
7 |Here is some incorrect Markdown. I am adding this. Here is some more text 2 | that I am removingtext. And here is even more adding.
3 |Paragraph was deleted and replaced with some spaces. Spaces were removed and a paragraph was added.
4 |And here is a comment on some 5 | ==text== . Substitutions is great!
6 |General block handling.
7 |Here is some incorrect Markdown. I am adding this here.. Here is some more text
2 | that I am removingtext. And here is even more text that I
3 | am adding. Paragraph was deleted and replaced with some spaces.
Spaces were removed and a paragraph was added.
6 |And here is a comment on some
7 | ==text== This works quite well. I just wanted to comment on it.. Substitutions isare great!
General block handling.
9 |100 💯
3 | 1234 🔢
4 | 8ball 🎱
5 | a 🅰
6 | ab 🆎
7 | abc 🔤
8 | abcd 🔡
9 | accept 🉑
10 | aerial_tramway 🚡
11 | airplane ✈
:
3 |
4 | :smile:
5 | \
6 | \:smile:
100
3 | 1234
4 | 8ball
5 | a
6 | ab
7 | abc
8 | abcd
9 | accept
10 | aerial_tramway
11 | airplane
100
3 | 1234
4 | 8ball
5 | a
6 | ab
7 | abc
8 | abcd
9 | accept
10 | aerial_tramway
11 | airplane
100 💯
10 | 1234 🔢
11 | 8ball 🎱
12 | a 🅰
13 | ab 🆎
14 | abc 🔤
15 | abcd 🔡
16 | accept 🉑
17 | aerial_tramway 🚡
18 | airplane ✈️
100
3 | 1234
4 | 8ball
5 | a
6 | ab
7 | abc
8 | abcd
9 | accept
10 | aerial_tramway
11 | airplane
100
10 | 1234
11 | 8ball
12 | a
13 | ab
14 | abc
15 | abcd
16 | accept
17 | aerial_tramway
18 | airplane
+1 👍
3 | -1 👎
4 | 100 💯
5 | 1234 🔢
6 | 1st_place_medal 🥇
7 | 2nd_place_medal 🥈
8 | 3rd_place_medal 🥉
9 | 8ball 🎱
10 | a 🅰️
11 | ab 🆎
100 💯
3 | 1234 🔢
4 | 8ball 🎱
5 | a 🅰
6 | ab 🆎
7 | abacus 🧮
8 | abc 🔤
9 | abcd 🔡
10 | accept 🉑
11 | accordion 🪗
100
3 | 1234
4 | 8ball
5 | a
6 | ab
7 | abacus
8 | abc
9 | abcd
10 | accept
11 | accordion
We shouldn't escape STX and ETX characters:
2 |Don't escape crtiic placeholder: comment
-------------------------------------------------------------------------------- /tests/extensions/escapeall/escapeall (critic).txt: -------------------------------------------------------------------------------- 1 | We shouldn't escape STX and ETX characters: 2 | 3 | Don't escape crtiic placeholder: \{>>comment<<} 4 | -------------------------------------------------------------------------------- /tests/extensions/escapeall/escapeall (ws normal).html: -------------------------------------------------------------------------------- 1 |We can escape everything 2 | 3 | ❤✓☀☆☂♞☯☭☢€☎∞❄♫ 4 | 😄 5 | \
-------------------------------------------------------------------------------- /tests/extensions/escapeall/escapeall (ws normal).txt: -------------------------------------------------------------------------------- 1 | \W\e\ \c\a\n\ \e\s\c\a\p\e\ \e\v\e\r\y\t\h\i\n\g 2 | \ 3 | \❤\✓\☀\☆\☂\♞\☯\☭\☢\€\☎\∞\❄\♫ 4 | \😄 5 | \\ 6 | -------------------------------------------------------------------------------- /tests/extensions/escapeall/escapeall.html: -------------------------------------------------------------------------------- 1 |We can escape everything
2 |
3 | ❤✓☀☆☂♞☯☭☢€☎∞❄♫
4 | 😄
5 | \
Footnotes1 have a label2 and the footnote's content.
2 |Col1 | 5 |Col2 | 6 |
---|---|
Abbreviations | 11 |abr | 12 |
Emphasis | 15 |emphasis works | 16 |
Footnote1 | 19 |20 | |
Attr List | 23 |Test | 24 |
This will be processed.
29 |This is a footnote. ↩
39 |Alt
3 |Down
4 |Left
5 |Right
6 |Num +
8 |Menu
9 |Backspace
10 |Win+Shift+S
12 |Cmd+Ctrl+D
13 |Ctrl+Alt+Page Down
-------------------------------------------------------------------------------- /tests/extensions/keys/keys (camel).txt: -------------------------------------------------------------------------------- 1 | ## Keys 2 | 3 | ++Alt++ 4 | 5 | ++ArrowDown++ 6 | 7 | ++ArrowLeft++ 8 | 9 | ++ArrowRight++ 10 | 11 | ## Aliases 12 | ++Add++ 13 | 14 | ++Apps++ 15 | 16 | ++Back++ 17 | 18 | ## Combos 19 | 20 | ++Win+Shift+s++ 21 | 22 | ++cmd+ctrl+d++ 23 | 24 | ++Ctrl+Alt+PgDn++ 25 | -------------------------------------------------------------------------------- /tests/extensions/keys/keys.txt: -------------------------------------------------------------------------------- 1 | ## Keys 2 | 3 | ++alt++ 4 | 5 | ++arrow-down++ 6 | 7 | ++arrow-left++ 8 | 9 | ++arrow-right++ 10 | 11 | ++arrow-up++ 12 | 13 | ++backslash++ 14 | 15 | ++backspace++ 16 | 17 | ++backtab++ 18 | 19 | ++bar++ 20 | 21 | ++brace-left++ 22 | 23 | ++brace-right++ 24 | 25 | ++bracket-left++ 26 | 27 | ++bracket-right++ 28 | 29 | ++break++ 30 | 31 | ++browser-back++ 32 | 33 | ++browser-favorites++ 34 | 35 | ++browser-forward++ 36 | 37 | ++browser-home++ 38 | 39 | ++browser-refresh++ 40 | 41 | ++browser-search++ 42 | 43 | ++browser-stop++ 44 | 45 | ## Aliases 46 | ++add++ 47 | 48 | ++apps++ 49 | 50 | ++back++ 51 | 52 | ++bksp++ 53 | 54 | ++bktab++ 55 | 56 | ++cancel++ 57 | 58 | ## Combos 59 | 60 | ++win+shift+s++ 61 | 62 | ++cmd+ctrl+d++ 63 | 64 | ## On the Fly Special Key 65 | 66 | ++ctrl+alt+"Special"++ 67 | 68 | ## Special Key Added to Key Map 69 | 70 | ++ctrl+alt+custom++ 71 | 72 | ## Override Original 73 | 74 | ++option+shift+s++ 75 | 76 | ## Escape Plus 77 | 78 | ++ctrl+alt+"Special with \+ sign"++ 79 | 80 | \++ctrl+alt+delete++ 81 | 82 | \\++ctrl+alt+delete++ 83 | 84 | \\\++ctrl+alt+delete++ 85 | 86 | ++ctrl+alt+delete\++ 87 | 88 | ++ctrl\+alt+delete++ 89 | 90 | ## Bad Key 91 | 92 | ++ctrl+alt+bad++ 93 | -------------------------------------------------------------------------------- /tests/extensions/keys/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | keys: 4 | extensions: 5 | pymdownx.keys: 6 | key_map: { 7 | 'custom': 'Custom Key', 8 | 'option': 'Opt' 9 | } 10 | 11 | keys (camel): 12 | extensions: 13 | pymdownx.keys: 14 | camel_case: true 15 | -------------------------------------------------------------------------------- /tests/extensions/magiclink/magiclink (bitbucket).txt: -------------------------------------------------------------------------------- 1 | Mention @some-bodies_name 2 | 3 | Commit some-bodies_name/some_repository@3f6b07a8eeaa9d606115758d90f55fec565d4e2a 4 | 5 | Compare some-bodies_name/some_repository@e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90b6fb8711e75732f987982cc024e9bb0111beac 6 | 7 | Issue some-bodies_name/some_repository#33 8 | 9 | Pull request some-bodies_name/some_repository!33 10 | 11 | Commit 3f6b07a8eeaa9d606115758d90f55fec565d4e2a 12 | 13 | Compare e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90b6fb8711e75732f987982cc024e9bb0111beac 14 | 15 | Issue #33 16 | 17 | Pull request !33 18 | 19 | Commit MyRepo@3f6b07a8eeaa9d606115758d90f55fec565d4e2a 20 | 21 | Compare e2ed7e0b3973f3f9eb7a26b8ef7ae514eebfe0d2...90b6fb8711e75732f987982cc024e9bb0111beac 22 | 23 | Issue MyRepo#33 24 | 25 | Pull MyRepo!33 26 | -------------------------------------------------------------------------------- /tests/extensions/magiclink/magiclink (extensions).html: -------------------------------------------------------------------------------- 1 |Magic link mixed with other extensions
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |These aren't guarunteed to work without being enclosed as 11 | we allow links to trail with = and emails can lead with _.
12 | 13 | -------------------------------------------------------------------------------- /tests/extensions/magiclink/magiclink (extensions).txt: -------------------------------------------------------------------------------- 1 | Magic link mixed with other extensions 2 | 3 | ~~http://www.google.com~~ 4 | 5 | **http://www.google.com** 6 | 7 | __http://www.google.com__ 8 | 9 | ^^http://www.google.com^^ 10 | 11 | ~~fake.mail@gmail.com~~ 12 | 13 | **fake.mail@gmail.com** 14 | 15 | ^^fake.mail@gmail.com^^ 16 | 17 | ==fake.mail@gmail.com== 18 | 19 | These aren't guarunteed to work without being enclosed as 20 | we allow links to trail with = and emails can lead with _. 21 | 22 | ==Test: == Won't mark ==
2 |Test: Will mark
3 |Test: All will = be marked
4 |Test: All will not= be marked==
5 |Test: All will === be marked
-------------------------------------------------------------------------------- /tests/extensions/mark/mark (dumb).txt: -------------------------------------------------------------------------------- 1 | Test: == Won't mark == 2 | 3 | Test: ==Will mark== 4 | 5 | Test: ==All will = be marked== 6 | 7 | Test: ==All will not=== be marked== 8 | 9 | Test: ==All will === be marked== 10 | -------------------------------------------------------------------------------- /tests/extensions/mark/mark.html: -------------------------------------------------------------------------------- 1 |Test: == Won't mark ==
2 |Test: Will mark
3 |Test: A lot of equals=============is okay
4 |Test: This will all be marked ==because of the placement of the center equal signs.
5 |Test: This will all be marked == because of the placement of the center equal sings.
6 |Test: This will NOT all be marked because of the placement of the center equal sings.==
7 |Test: This will all be marked= because of the token is less than that of the surrounding.
-------------------------------------------------------------------------------- /tests/extensions/mark/mark.txt: -------------------------------------------------------------------------------- 1 | Test: == Won't mark == 2 | 3 | Test: ==Will mark== 4 | 5 | Test: ==A lot of equals=============is okay== 6 | 7 | Test: ==This will all be marked ==because of the placement of the center equal signs.== 8 | 9 | Test: ==This will all be marked == because of the placement of the center equal sings.== 10 | 11 | Test: ==This will NOT all be marked== because of the placement of the center equal sings.== 12 | 13 | Test: ==This will all be marked= because of the token is less than that of the surrounding.== 14 | -------------------------------------------------------------------------------- /tests/extensions/mark/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | mark: 4 | extensions: 5 | pymdownx.mark: 6 | 7 | mark (dumb): 8 | extensions: 9 | pymdownx.mark: 10 | smart_mark: false 11 | -------------------------------------------------------------------------------- /tests/extensions/progressbar/progressbar.txt: -------------------------------------------------------------------------------- 1 | [=0% "0%"]{: .candystripe-animate} 2 | 3 | [=5% "5%"]{: .candystripe-animate} 4 | 5 | [=25% "25%"]{: .candystripe-animate} 6 | 7 | [=45% "45%"]{: .candystripe-animate} 8 | 9 | [=65% "65%"]{: .candystripe-animate} 10 | 11 | [=85% "85%"]{: .candystripe-animate} 12 | 13 | [=100% "100%"]{: .candystripe-animate} 14 | 15 | [= 212.2/537 "212.2/537 Testing division"] 16 | 17 | [=== 50%] 18 | 19 | Before[= 50% "I'm a block!"]After 20 | 21 | [= 50% "Glossy"]{: .candystripe-animate .gloss} 22 | 23 | [= 0%] 24 | 25 | [= 3/0 "Divide by 0"] 26 | 27 | [= 300/100 "Greater than 0"] 28 | -------------------------------------------------------------------------------- /tests/extensions/progressbar/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | progressbar: 4 | css: 5 | - ../_assets/progressbar.css 6 | extensions: 7 | pymdownx.progressbar: 8 | markdown.extensions.attr_list: 9 | -------------------------------------------------------------------------------- /tests/extensions/striphtml/striphtml (no attr strip).html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 |15 | 16 | 17 | 18 | 19 |
20 |link 21 | 26 | Some text 27 |
-------------------------------------------------------------------------------- /tests/extensions/striphtml/striphtml (no attr strip).txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | link 28 | 33 | Some text 34 | 35 | -------------------------------------------------------------------------------- /tests/extensions/striphtml/striphtml.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 |15 | 16 | 17 | 18 | 19 |
20 |link 21 | 22 | Some text 23 |
-------------------------------------------------------------------------------- /tests/extensions/striphtml/striphtml.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | link 28 | 33 | Some text 34 | 35 | -------------------------------------------------------------------------------- /tests/extensions/striphtml/tests.yml: -------------------------------------------------------------------------------- 1 | __default__: {} 2 | 3 | striphtml: 4 | extensions: 5 | pymdownx.striphtml: 6 | strip_attributes: 7 | - id 8 | - style 9 | - class 10 | 11 | striphtml (no attr strip): 12 | extensions: 13 | pymdownx.striphtml: 14 | strip_js_on_attributes: false 15 | -------------------------------------------------------------------------------- /tests/extensions/superfences/superfences (custom).html: -------------------------------------------------------------------------------- 1 |content
--------------------------------------------------------------------------------
/tests/extensions/superfences/superfences (custom).txt:
--------------------------------------------------------------------------------
1 | ```test
2 | content
3 | ```
4 |
5 | ```{.test .class #id}
6 | content
7 | ```
8 |
9 | ```{.test2 .class #id}
10 | content
11 | ```
12 |
--------------------------------------------------------------------------------
/tests/extensions/superfences/superfences (failures).html:
--------------------------------------------------------------------------------
1 | ```
3 |
4 | Here is some text. 5 | ```
6 |Test bad indentation 2:
12 |Here is some text.
Test bad indentation 3:
19 |Here is some text.
Test bad indentation 4:
26 |Here is some text.
This will not work.
35 |38 |``` 36 | Test
37 |
will break. 39 | ```
40 |Test bad indentation blockquote
44 |45 |48 |47 |
Test 46 | will break
Test block quote exceeding start level
54 |55 |63 |``` 56 | Test
57 |58 |62 |will 59 | break 60 | ```
61 |
Unexpected block quote
69 |``` 70 | Test 71 | will
72 |73 |76 |break 74 | ```
75 |
Block quote unalignment
82 |83 |87 |86 |
Test 84 | Will 85 | break
Block quote unalignment
93 |94 |98 |97 |
Test 95 | Will 96 | break
Bad attribute list
104 |import test
105 |
Missing closing bracket
112 |{ .python
113 | import test
Missing opening bracket
120 |.python }
121 | import test
Additional class outside of attribute list
128 |python .class
129 | import test
This will not be parsed 2 | as a normal indented code block. 3 | It will be parsed as a fenced block.
-------------------------------------------------------------------------------- /tests/extensions/superfences/superfences (no indent blocks).txt: -------------------------------------------------------------------------------- 1 | This will not be parsed 2 | as a normal indented code block. 3 | It will be parsed as a fenced block. 4 | -------------------------------------------------------------------------------- /tests/extensions/superfences/superfences (no pygments).html: -------------------------------------------------------------------------------- 1 |import test
2 | Text after code.
3 |import test
4 | """Some file."""
6 | import foo.bar
7 | import boo.baz
8 | import foo.bar.baz
--------------------------------------------------------------------------------
/tests/extensions/superfences/superfences (no pygments).txt:
--------------------------------------------------------------------------------
1 | ```python
2 | import test
3 | ```
4 |
5 | Text after code.
6 |
7 | ```python
8 | import test
9 | ```
10 |
11 | # Attribute List
12 |
13 | ```{ .python #id .another-class linenums="1" }
14 | """Some file."""
15 | import foo.bar
16 | import boo.baz
17 | import foo.bar.baz
18 | ```
19 |
--------------------------------------------------------------------------------
/tests/extensions/superfences/superfences (preserve tabs).txt:
--------------------------------------------------------------------------------
1 | # Neseted Fences:
2 |
3 | ```
4 | This will still be parsed
5 | as a normal indented code block.
6 | ```
7 |
8 | ```
9 | This will still be parsed
10 | as a fenced code block.
11 | ```
12 |
13 | -
14 | ```
15 | This will work.
16 | ```
17 |
18 | - This is a list that contains multiple code blocks.
19 |
20 | - Here is an indented block
21 |
22 | ```
23 | This will still be parsed
24 | as a normal indented code block.
25 | ```
26 |
27 | - Here is a fenced code block:
28 |
29 | ```
30 | This will still be parsed
31 | as a fenced code block.
32 | ```
33 |
34 | > ```
35 | > Blockquotes?
36 |
37 | > Not a problem!
38 | > ```
39 |
40 | - Fenced block with lesser child fence.
41 |
42 | ````
43 | ```
44 | Fenced block containing fenced syntax.
45 | ```
46 | ````
47 |
48 | ````
49 | ```
50 | Fenced block containing fenced syntax.
51 | ```
52 | ````
53 |
54 | - Fenced block with greater child fence:
55 |
56 | ```
57 | ````
58 | Fenced block containing fenced syntax.
59 | ````
60 | ```
61 |
62 | ```
63 | ````
64 | Fenced block containing fenced syntax.
65 | ````
66 | ```
67 |
68 | - Fenced block with indented child fence:
69 |
70 | ```
71 | ```
72 | Fenced block containing fenced syntax.
73 | ```
74 | ```
75 |
76 | - Tabs
77 |
78 | ```
79 | Test with tabs.
80 | Test with tabs.
81 | Test tabs.
82 | ```
83 |
84 | ```
85 | ============================================================
86 | T Tp Sp D Dp S D7 T
87 | ------------------------------------------------------------
88 | A F#m Bm E C#m D E7 A
89 | A# Gm Cm F Dm D# F7 A#
90 | B♭ Gm Cm F Dm E♭m F7 B♭
91 | ```
92 |
93 | - Here is a highlighted code block with line numbers:
94 |
95 | ```python linenums="1"
96 | """Some file."""
97 | import foo.bar
98 | import boo.baz
99 | import foo.bar.baz
100 | ```
101 |
102 | - Here is a highlighted code block with line numbers and line highlighting:
103 |
104 | ```python hl_lines="2 3" linenums="1"
105 | """Some file."""
106 | import foo.bar
107 | import boo.baz
108 | import foo.bar.baz
109 | ```
110 |
111 | - Highlight extended language:
112 |
113 | ```php-inline
114 | $a = array("foo" => 0, "bar" => 1);
115 | ```
116 |
117 | # UML Flow Charts
118 |
119 | ```flow
120 | st=>start: Start:>http://www.google.com[blank]
121 | e=>end:>http://www.google.com
122 | op1=>operation: My Operation
123 | sub1=>subroutine: My Subroutine
124 | cond=>condition: Yes
125 | or No?:>http://www.google.com
126 | io=>inputoutput: catch something...
127 |
128 | st->op1->cond
129 | cond(yes)->io->e
130 | cond(no)->sub1(right)->op1
131 | ```
132 |
133 | # UML Sequence Diagrams
134 |
135 | ```sequence
136 | Title: Here is a title
137 | A->B: Normal line
138 | B-->C: Dashed line
139 | C->>D: Open arrow
140 | D-->>A: Dashed open arrow
141 | ```
142 |
--------------------------------------------------------------------------------
/tests/extensions/tasklist/tasklist (checkable).html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | item 1
63 |item A
66 |item a
69 |Test: ~~ Won't delete ~~
2 |Test: Will delete
Test: ~~Escaped~~
4 |Test: All will ~ be deleted
Test: All will~ not be deleted~~
Test: All will ~~~ be deleted
CH3CH2OH
2 |Textsubscript
3 |Text~subscript failed~
4 |Textsubscript success
5 |Test: ~~ Won't delete ~~
6 |Test: Will delete
Test: ~~Escaped~~
8 |Test: All will ~ be deleted
Test: All will~ be deleted with subscript in middle
Test: All will ~ be deleted with subscript in middle
Test: Subscript ~~~
-------------------------------------------------------------------------------- /tests/extensions/tilde/tilde (dumb).txt: -------------------------------------------------------------------------------- 1 | CH~3~CH~2~OH 2 | 3 | Text~subscript~ 4 | 5 | Text~subscript failed~ 6 | 7 | Text~subscript\ success~ 8 | 9 | Test: ~~ Won't delete ~~ 10 | 11 | Test: ~~Will delete~~ 12 | 13 | Test: \~\~Escaped\~\~ 14 | 15 | Test: ~~All will ~ be deleted~~ 16 | 17 | Test: ~~All will~\~~ be deleted with subscript in middle~~ 18 | 19 | Test: ~~All will ~\~~ be deleted with subscript in middle~~ 20 | 21 | Test: Subscript ~~~ 22 | -------------------------------------------------------------------------------- /tests/extensions/tilde/tilde (no delete).html: -------------------------------------------------------------------------------- 1 |CH3CH2OH
2 |Textsubscript
3 |Text~subscript failed~
4 |Textsubscript success
5 |Test: ~~Won't delete~~
-------------------------------------------------------------------------------- /tests/extensions/tilde/tilde (no delete).txt: -------------------------------------------------------------------------------- 1 | CH~3~CH~2~OH 2 | 3 | Text~subscript~ 4 | 5 | Text~subscript failed~ 6 | 7 | Text~subscript\ success~ 8 | 9 | Test: ~~Won't delete~~ 10 | -------------------------------------------------------------------------------- /tests/extensions/tilde/tilde (no sub).html: -------------------------------------------------------------------------------- 1 |Test: ~~ Won't delete ~~
2 |Test: Will delete
Test: ~~Escaped~~
4 |Test: This will all be deleted ~~because of the placement of the center tilde.
Test: This will all be deleted ~~ because of the placement of the center tilde.
Test: This will NOT all be deleted because of the placement of the center tilde.~~
Test: This will all be deleted~ because of the token is less than that of the tilde.
CH3CH2OH
2 |Textsubscript
3 |Text~subscript failed~
4 |Textsubscript success
5 |Test: ~~ Won't delete ~~
6 |Test: Will delete
Test: ~~Escaped~~
8 |Test: This will all be deleted ~~because of the placement of the center tilde.
Test: This will all be deleted ~~ because of the placement of the center tilde.
Test: This will NOT all be deleted because of the placement of the center tilde.~~
Test: This will all be deleted~ because of the token is less than that of the tilde.
content
content
foo', 18 | '<pre>foo
' 19 | ) 20 | 21 | def test_html_special_char_gt(self): 22 | """Test `>`.""" 23 | 24 | self.check_markdown( 25 | r'foo', 26 | '<span>foo
' 27 | ) 28 | 29 | def test_html_special_char_amp(self): 30 | """Test `&`.""" 31 | 32 | self.check_markdown( 33 | r'This \& that', 34 | 'This & that
' 35 | ) 36 | 37 | def test_normal_escape(self): 38 | """Test normal escapes.""" 39 | 40 | self.check_markdown( 41 | r'This & \that', 42 | 'This & that
' 43 | ) 44 | -------------------------------------------------------------------------------- /tests/test_extensions/test_keys.py: -------------------------------------------------------------------------------- 1 | """Test cases for Keys.""" 2 | from .. import util 3 | 4 | 5 | class TestKeys(util.MdCase): 6 | """Tests for Keys.""" 7 | 8 | extension = [ 9 | 'pymdownx.keys' 10 | ] 11 | 12 | def test_avoid_base64(self): 13 | """Test complex case where `**text*text***` may be detected on accident.""" 14 | 15 | self.check_markdown( 16 | " ++ctrl+a++ ++ctrl+'custom'++", 17 | '' # noqa: E501 18 | ) 19 | -------------------------------------------------------------------------------- /tests/test_extensions/test_saneheaders.py: -------------------------------------------------------------------------------- 1 | """Test cases for SaneHeaders.""" 2 | from .. import util 3 | 4 | 5 | class TestSaneHeadersWithMagicLink(util.MdCase): 6 | """Test cases for SaneHeaders and MagicLink (the motivation behind creating SaneHeaders).""" 7 | 8 | extension = [ 9 | 'pymdownx.saneheaders', 10 | 'pymdownx.magiclink', 11 | ] 12 | 13 | extension_configs = { 14 | 'pymdownx.magiclink': { 15 | 'repo_url_shorthand': True, 16 | 'user': 'facelessuser', 17 | 'repo': 'pymdown-extensions' 18 | } 19 | } 20 | 21 | def test_header1(self): 22 | """Test header level 1.""" 23 | 24 | self.check_markdown( 25 | r'# Header', 26 | r'
Ctrl+A Ctrl+custom
Header
' 27 | ) 28 | 29 | def test_header2(self): 30 | """Test header level 2.""" 31 | 32 | self.check_markdown( 33 | r'## Header', 34 | r'Header
' 35 | ) 36 | 37 | def test_header3(self): 38 | """Test header level 3.""" 39 | 40 | self.check_markdown( 41 | r'### Header', 42 | r'Header
' 43 | ) 44 | 45 | def test_header4(self): 46 | """Test header level 4.""" 47 | 48 | self.check_markdown( 49 | r'#### Header', 50 | r'Header
' 51 | ) 52 | 53 | def test_header5(self): 54 | """Test header level 5.""" 55 | 56 | self.check_markdown( 57 | r'##### Header', 58 | r'Header
' 59 | ) 60 | 61 | def test_header6(self): 62 | """Test header level 6.""" 63 | 64 | self.check_markdown( 65 | r'###### Header', 66 | r'Header
' 67 | ) 68 | 69 | def test_header_trailing(self): 70 | """Test header trailing hashes.""" 71 | 72 | self.check_markdown( 73 | r'## Header ##', 74 | r'Header
' 75 | ) 76 | 77 | def test_too_many_hashes(self): 78 | """Test header with too many hashes.""" 79 | 80 | self.check_markdown( 81 | r'####### Header', 82 | r'####### Header
' 83 | ) 84 | 85 | def test_no_header(self): 86 | """Test no header match.""" 87 | 88 | self.check_markdown( 89 | r'##Header', 90 | r'##Header
' 91 | ) 92 | 93 | def test_header_with_magiclink(self): 94 | """Test no header match.""" 95 | 96 | self.check_markdown( 97 | r'#3', 98 | r'' # noqa: E501 99 | ) 100 | -------------------------------------------------------------------------------- /tests/test_extensions/test_striphmtl.py: -------------------------------------------------------------------------------- 1 | """Test cases for StripHTML.""" 2 | from .. import util 3 | 4 | 5 | class TestStripHTML(util.MdCase): 6 | """Test legacy stripping in HTML.""" 7 | 8 | extension = ['pymdownx.striphtml'] 9 | extension_configs = {} 10 | 11 | def test_multiple_inline(self): 12 | """Test multiple inline.""" 13 | 14 | self.check_markdown( 15 | r''' 16 | Comments test: 17 | 18 | 19 | - One 20 | - Two 21 | - Three 22 | 23 | 24 | ## Paragraph 25 | 26 | 27 | - One 28 | - Two 29 | - Three 30 | 31 | Comments test end 32 | ''', 33 | r''' 34 |Comments test:
35 |36 |
40 |- One
37 |- Two
38 |- Three
39 |Paragraph
41 |42 |
46 |- One
43 |- Two
44 |- Three
45 |Comments test end
47 | ''', 48 | True 49 | ) 50 | -------------------------------------------------------------------------------- /tools/__init__.py: -------------------------------------------------------------------------------- 1 | """Tools.""" 2 | -------------------------------------------------------------------------------- /tools/gen_emoji1.py: -------------------------------------------------------------------------------- 1 | """Generate emojione data.""" 2 | import os 3 | import json 4 | current_dir = os.path.dirname(os.path.abspath(__file__)) 5 | LICENSE = """ 6 | MIT license. 7 | 8 | Copyright (c) http://www.emojione.com 9 | """ 10 | 11 | 12 | def get_unicode_alt(value): 13 | """Get alternate Unicode form or return the original.""" 14 | 15 | return value['unicode_alt'] 16 | 17 | 18 | def parse(repo, tag): 19 | """Save test files.""" 20 | # Load emoji database 21 | with open(os.path.join(current_dir, 'tags', repo, repo, 'emoji.json')) as f: 22 | emojis = json.loads(f.read()) 23 | 24 | emoji_db = {} 25 | shortnames = set() 26 | aliases = {} 27 | for v in emojis.values(): 28 | shortnames.add(v['shortname']) 29 | emoji_db[v['shortname']] = { 30 | 'name': v['name'], 31 | 'unicode': v['unicode'], 32 | 'category': v['category'] 33 | } 34 | alt = get_unicode_alt(v) 35 | if alt: 36 | emoji_db[v['shortname']]['unicode_alt'] = alt 37 | 38 | for alias in v['aliases']: 39 | aliases[alias] = v['shortname'] 40 | 41 | # Save test files 42 | for test in ('png', 'png sprite', 'svg', 'svg sprite', 'entities', 'long title', 'no title'): 43 | with open('../tests/extensions/emoji/emoji1 (%s).txt' % test, 'w') as f: 44 | f.write('# Emojis\n') 45 | count = 0 46 | for emoji in sorted(shortnames): 47 | f.write(''.join('{} {}
\n'.format(emoji[1:-1], emoji))) 48 | count += 1 49 | if test != 'png' and count == 10: 50 | break 51 | 52 | # Write out essential info 53 | with open('../pymdownx/emoji1_db.py', 'w') as f: 54 | # Dump emoji db to file and strip out PY2 unicode specifiers 55 | f.write('"""Emojione autogen.\n\nGenerated from emojione source. Do not edit by hand.\n%s"""\n' % LICENSE) 56 | f.write('version = "%s"\n' % tag) 57 | f.write('name = "emojione"\n') 58 | f.write('emoji = %s\n' % json.dumps(emoji_db, sort_keys=True, indent=4, separators=(',', ': '))) 59 | f.write('aliases = %s\n' % json.dumps(aliases, sort_keys=True, indent=4, separators=(',', ': '))) 60 | -------------------------------------------------------------------------------- /tools/gen_joypixels.py: -------------------------------------------------------------------------------- 1 | """Generate emojione data.""" 2 | import os 3 | import json 4 | current_dir = os.path.dirname(os.path.abspath(__file__)) 5 | LICENSE = """ 6 | MIT license. 7 | 8 | Copyright (c) http://www.emojione.com 9 | """ 10 | 11 | 12 | def get_unicode_alt(value): 13 | """Get alternate Unicode form or return the original.""" 14 | 15 | return value['code_points']['fully_qualified'] 16 | 17 | 18 | def parse(repo, tag): 19 | """Save test files.""" 20 | # Load emoji database 21 | with open(os.path.join(current_dir, 'tags', repo, repo, 'emoji.json')) as f: 22 | emojis = json.loads(f.read()) 23 | 24 | emoji_db = {} 25 | shortnames = set() 26 | aliases = {} 27 | for v in emojis.values(): 28 | shortnames.add(v['shortname']) 29 | emoji_db[v['shortname']] = { 30 | 'name': v['name'], 31 | 'unicode': v['code_points']['base'], 32 | 'category': v['category'] 33 | } 34 | alt = get_unicode_alt(v) 35 | if alt and alt != v['code_points']['base']: 36 | emoji_db[v['shortname']]['unicode_alt'] = alt 37 | 38 | for alias in v['shortname_alternates']: 39 | aliases[alias] = v['shortname'] 40 | 41 | return emoji_db, aliases 42 | -------------------------------------------------------------------------------- /tools/pymdownx_md_render.py: -------------------------------------------------------------------------------- 1 | """Generate Markdown isolated from our current document options.""" 2 | import markdown 3 | import yaml 4 | import re 5 | from collections import OrderedDict 6 | 7 | 8 | def yaml_load(stream, loader=yaml.Loader): 9 | """ 10 | Custom YAML loader. 11 | 12 | Load all strings as Unicode. 13 | http://stackoverflow.com/a/2967461/3609487 14 | """ 15 | 16 | def construct_yaml_str(self, node): 17 | """Override the default string handling function to always return Unicode objects.""" 18 | 19 | return self.construct_scalar(node) 20 | 21 | class Loader(loader): 22 | """Custom Loader.""" 23 | 24 | Loader.add_constructor( 25 | 'tag:yaml.org,2002:str', 26 | construct_yaml_str 27 | ) 28 | 29 | return yaml.load(stream, Loader) 30 | 31 | 32 | def get_frontmatter(text): 33 | """Get front matter from string.""" 34 | 35 | frontmatter = OrderedDict() 36 | 37 | if text.startswith("---"): 38 | m = re.search(r'^(-{3}\r?\n(?!\r?\n)(.*?)(?<=\n)(?:-{3}|\.{3})\r?\n)', text, re.DOTALL) 39 | if m: 40 | yaml_okay = True 41 | try: 42 | frontmatter = yaml_load(m.group(2)) 43 | if frontmatter is None: 44 | frontmatter = OrderedDict() 45 | # If we didn't get a dictionary, we don't want this as it isn't front matter. 46 | assert isinstance(frontmatter, (dict, OrderedDict)), TypeError 47 | except Exception: 48 | # We had a parsing error. This is not the YAML we are looking for. 49 | yaml_okay = False 50 | frontmatter = OrderedDict() 51 | 52 | if yaml_okay: 53 | text = text[m.end(1):] 54 | 55 | return frontmatter, text 56 | 57 | 58 | def md_sub_render(src="", language="", class_name=None, options=None, md="", **kwargs): 59 | """Formatter wrapper.""" 60 | try: 61 | fm, text = get_frontmatter(src) 62 | md = markdown.markdown( 63 | text, 64 | extensions=fm.get('extensions', []), 65 | extension_configs=fm.get('extension_configs', {}) 66 | ) 67 | return md 68 | except Exception: 69 | import traceback 70 | print(traceback.format_exc()) 71 | raise 72 | --------------------------------------------------------------------------------