Projects
openEuler:Mainline
python-markdown
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
_service:tar_scm:python-markdown.spec
Changed
@@ -1,14 +1,12 @@ %{!?python3_version: %global python3_version %(%{__python3} -c "import sys; sys.stdout.write(sys.version:3)")} Name: python-markdown -Version: 3.3.7 -Release: 2 +Version: 3.4.1 +Release: 1 Summary: A Python implementation of John Gruber’s Markdown License: BSD-3-Clause URL: https://pypi.org/project/Markdown/ -Source0: https://pypi.python.org/packages/source/M/Markdown/Markdown-%{version}.tar.gz - -Patch0: 0001-Update-th-td-to-use-style-attribute.patch +Source0: %{pypi_source Markdown} BuildArch: noarch @@ -49,6 +47,9 @@ %{_bindir}/markdown_py %changelog +* Wed May 31 2023 chenchen <chen_aka_jan@163.com> - 3.4.1-1 +- Upgrade to 3.4.1 + * Tue Jan 17 2023 caofei <caofei@xfusion.com> - 3.3.7-2 - Update th/td to use style attribute
View file
_service:tar_scm:0001-Update-th-td-to-use-style-attribute.patch
Deleted
@@ -1,1715 +0,0 @@ -From 659a43659c6012df8d8ceb4a3681d2ddb1cb7540 Mon Sep 17 00:00:00 2001 -From: Gaige B Paulsen <github@gbp.gaige.net> -Date: Thu, 5 May 2022 15:32:07 -0400 -Subject: PATCH Update th/td to use style attribute - -This allows better interoperation with CSS style sheets, as the align -object on the TH is skipped if the css uses 'text-align: inherit' and -the previous 'text-align' is used instead (or the default: left). - -Added an override to restore the original `align` behavior -Moved existing tests to the new test infrastructure -Added new tests to test the configuration parameter -Updated documentation to document the configuration parameter. ---- - docs/change_log/index.md | 2 + - docs/change_log/release-3.4.md | 44 + - docs/extensions/tables.md | 22 +- - markdown/extensions/tables.py | 19 +- - tests/extensions/extra/tables.html | 466 ----------- - tests/extensions/extra/tables.txt | 169 ---- - tests/test_legacy.py | 2 - - tests/test_syntax/extensions/test_tables.py | 860 ++++++++++++++++++++ - 8 files changed, 943 insertions(+), 641 deletions(-) - create mode 100644 docs/change_log/release-3.4.md - delete mode 100644 tests/extensions/extra/tables.html - delete mode 100644 tests/extensions/extra/tables.txt - -diff --git a/docs/change_log/index.md b/docs/change_log/index.md -index 09ace62..fc78087 100644 ---- a/docs/change_log/index.md -+++ b/docs/change_log/index.md -@@ -3,6 +3,8 @@ title: Change Log - Python-Markdown Change Log - ========================= - -+Under development: version 3.4.0 (Notes(release-3.4.md)). -+ - May 5, 2022: version 3.3.7 (a bug-fix release). - - * Disallow square brackets in reference link ids (#1209). -diff --git a/docs/change_log/release-3.4.md b/docs/change_log/release-3.4.md -new file mode 100644 -index 0000000..0070da9 ---- /dev/null -+++ b/docs/change_log/release-3.4.md -@@ -0,0 +1,44 @@ -+title: Release Notes for v3.4 -+ -+# Python-Markdown 3.4 Release Notes -+ -+Python-Markdown version 3.4 supports Python versions 3.6, 3.7, 3.8, 3.9 and PyPy3. -+ -+## Backwards-incompatible changes -+ -+### The `table` extension now uses a `style` attribute instead of `align` attribute for alignment. -+ -+The HTML4 specspec4 specifically -+deprecates the use of the `align` attribute and it does not appear at all in the -+HTML5 specspec5. Therefore, by default, the table extension will now use the `style` -+attribute (setting just the `text-align` property) in `td` and `th` blocks. -+ -+spec4: https://www.w3.org/TR/html4/present/graphics.html#h-15.1.2 -+spec5: https://www.w3.org/TR/html53/tabular-data.html#attributes-common-to-td-and-th-elements -+ -+The former behavior is available by setting the setting `use_align_attribute` configuration -+option to `True` when adding the extension. -+ -+For example, to configure the old `align` behavior: -+ -+```python -+from markdown.extensions.tables import TableExtension -+ -+markdown.markdown(src, extensions=TableExtension(use_align_attribute=True)) -+``` -+ -+In addition, tests were moved to the modern test environment. -+ -+## New features -+ -+The following new features have been included in the 3.3 release: -+ -+* Use `style` attribute in tables for alignment instead of `align` for better CSS -+ inter-operation. The old behavior is available by setting `use_align_attribute=True` when -+ adding the extension. -+ -+## Bug fixes -+ -+The following bug fixes are included in the 3.4 release: -+ -+ -diff --git a/docs/extensions/tables.md b/docs/extensions/tables.md -index 30b7636..aaffc09 100644 ---- a/docs/extensions/tables.md -+++ b/docs/extensions/tables.md -@@ -58,10 +58,30 @@ Usage - See Extensions(index.md) for general extension usage. Use `tables` as the - name of the extension. - --This extension does not accept any special configuration options. -+See the Library Reference(../reference.md#extensions) for information about -+configuring extensions. -+ -+The following options are provided to change the default behavior: -+ -+* **`use_align_attribute`**: Set to `True` to use `align` instead of an appropriate `style` attribute -+ -+ Default: `'False'` -+ - - A trivial example: - - ```python - markdown.markdown(some_text, extensions='tables') - ``` -+ -+### Examples -+ -+For an example, let us suppose that alignment should be controlled by the legacy `align` -+attribute. -+ -+```pycon -+>>> from markdown.extensions.tables import TableExtension -+>>> html = markdown.markdown(text, -+... extensions=TableExtension(use_align_attribute=True) -+... ) -+``` -diff --git a/markdown/extensions/tables.py b/markdown/extensions/tables.py -index 0a9d084..c8b1024 100644 ---- a/markdown/extensions/tables.py -+++ b/markdown/extensions/tables.py -@@ -30,9 +30,11 @@ class TableProcessor(BlockProcessor): - RE_CODE_PIPES = re.compile(r'(?:(\\\\)|(\\`+)|(`+)|(\\\|)|(\|))') - RE_END_BORDER = re.compile(r'(?<!\\)(?:\\\\)*\|$') - -- def __init__(self, parser): -+ def __init__(self, parser, config): - self.border = False - self.separator = '' -+ self.config = config -+ - super().__init__(parser) - - def test(self, parent, block): -@@ -126,7 +128,10 @@ class TableProcessor(BlockProcessor): - except IndexError: # pragma: no cover - c.text = "" - if a: -- c.set('align', a) -+ if self.config'use_align_attribute': -+ c.set('align', a) -+ else: -+ c.set('style', f'text-align: {a};') - - def _split_row(self, row): - """ split a row of text into list of cells. """ -@@ -212,11 +217,19 @@ class TableProcessor(BlockProcessor): - class TableExtension(Extension): - """ Add tables to Markdown. """ - -+ def __init__(self, **kwargs): -+ self.config = { -+ 'use_align_attribute': False, 'True to use align attribute instead of style.', -+ } -+ -+ super().__init__(**kwargs) -+ - def extendMarkdown(self, md): - """ Add an instance of TableProcessor to BlockParser. """ - if '|' not in md.ESCAPED_CHARS: - md.ESCAPED_CHARS.append('|') -- md.parser.blockprocessors.register(TableProcessor(md.parser), 'table', 75) -+ processor = TableProcessor(md.parser, self.getConfigs()) -+ md.parser.blockprocessors.register(processor, 'table', 75) - - - def makeExtension(**kwargs): # pragma: no cover -diff --git a/tests/extensions/extra/tables.html b/tests/extensions/extra/tables.html -deleted file mode 100644 -index 25dee48..0000000 ---- a/tests/extensions/extra/tables.html -+++ /dev/null -@@ -1,466 +0,0 @@ --<h2>Table Tests</h2> --<table> --<thead> --<tr> --<th>First Header</th> --<th>Second Header</th> --</tr> --</thead> --<tbody> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>First Header</th> --<th>Second Header</th> --</tr> --</thead> --<tbody> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th align="left">Item</th> --<th align="right">Value</th> --</tr> --</thead> --<tbody> --<tr> --<td align="left">Computer</td> --<td align="right">$1600</td> --</tr> --<tr> --<td align="left">Phone</td> --<td align="right">$12</td> --</tr> --<tr> --<td align="left">Pipe</td> --<td align="right">$1</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Function name</th> --<th>Description</th> --</tr> --</thead> --<tbody> --<tr> --<td><code>help()</code></td> --<td>Display the help window.</td> --</tr> --<tr> --<td><code>destroy()</code></td> --<td><strong>Destroy your computer!</strong></td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th align="left">foo</th> --<th align="center">bar</th> --<th align="right">baz</th> --</tr> --</thead> --<tbody> --<tr> --<td align="left"></td> --<td align="center">Q</td> --<td align="right"></td> --</tr> --<tr> --<td align="left">W</td> --<td align="center"></td> --<td align="right">W</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>foo</th> --<th>bar</th> --<th>baz</th> --</tr> --</thead> --<tbody> --<tr> --<td></td> --<td>Q</td> --<td></td> --</tr> --<tr> --<td>W</td> --<td></td> --<td>W</td> --</tr> --</tbody> --</table> --<p>Three spaces in front of a table:</p> --<table> --<thead> --<tr> --<th>First Header</th> --<th>Second Header</th> --</tr> --</thead> --<tbody> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>First Header</th> --<th>Second Header</th> --</tr> --</thead> --<tbody> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --<tr> --<td>Content Cell</td> --<td>Content Cell</td> --</tr> --</tbody> --</table> --<p>Four spaces is a code block:</p> --<pre><code>First Header | Second Header -------------- | ------------- --Content Cell | Content Cell --Content Cell | Content Cell --</code></pre> --<table> --<thead> --<tr> --<th>First Header</th> --<th>Second Header</th> --</tr> --</thead> --<tbody> --<tr> --<td></td> --<td></td> --</tr> --</tbody> --</table> --<p>More inline code block tests</p> --<table> --<thead> --<tr> --<th>Column 1</th> --<th>Column 2</th> --<th>Column 3</th> --</tr> --</thead> --<tbody> --<tr> --<td>word 1</td> --<td>word 2</td> --<td>word 3</td> --</tr> --<tr> --<td>word 1</td> --<td><code>word 2</code></td> --<td>word 3</td> --</tr> --<tr> --<td>word 1</td> --<td>`word 2</td> --<td>word 3</td> --</tr> --<tr> --<td>word 1</td> --<td>`word 2</td> --<td>word 3</td> --</tr> --<tr> --<td>word 1</td> --<td><code>word |2</code></td> --<td>word 3</td> --</tr> --<tr> --<td>words</td> --<td><code>some | code</code></td> --<td>more words</td> --</tr> --<tr> --<td>words</td> --<td><code>some | code</code></td> --<td>more words</td> --</tr> --<tr> --<td>words</td> --<td><code>some | code</code></td> --<td>more words</td> --</tr> --<tr> --<td>words</td> --<td><code>some ` | ` code</code></td> --<td>more words</td> --</tr> --<tr> --<td>words</td> --<td><code>some ` | ` code</code></td> --<td>more words</td> --</tr> --<tr> --<td>words</td> --<td><code>some ` | ` code</code></td> --<td>more words</td> --</tr> --</tbody> --</table> --<p>A test for issue #440:</p> --<table> --<thead> --<tr> --<th>foo</th> --<th>bar</th> --</tr> --</thead> --<tbody> --<tr> --<td>foo</td> --<td>(<code>bar</code>) and <code>baz</code>.</td> --</tr> --</tbody> --</table> --<p>Lists are not tables</p> --<ul> --<li>this | should | not</li> --<li>be | a | table</li> --</ul> --<p>Add tests for issue #449</p> --<table> --<thead> --<tr> --<th>Odd backticks</th> --<th>Even backticks</th> --</tr> --</thead> --<tbody> --<tr> --<td><code>!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~</code></td> --<td><code>!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~</code></td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Escapes</th> --<th>More Escapes</th> --</tr> --</thead> --<tbody> --<tr> --<td><code>`\</code></td> --<td><code>\</code></td> --</tr> --</tbody> --</table> --<p>Only the first backtick can be escaped</p> --<table> --<thead> --<tr> --<th>Escaped</th> --<th>Bacticks</th> --</tr> --</thead> --<tbody> --<tr> --<td>`<code>\</code></td> --<td>``</td> --</tr> --</tbody> --</table> --<p>Test escaped pipes</p> --<table> --<thead> --<tr> --<th>Column 1</th> --<th>Column 2</th> --</tr> --</thead> --<tbody> --<tr> --<td><code>|</code> |</td> --<td>Pipes are okay in code and escaped. |</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Column 1</th> --<th>Column 2</th> --</tr> --</thead> --<tbody> --<tr> --<td>row1</td> --<td>row1 |</td> --</tr> --<tr> --<td>row2</td> --<td>row2</td> --</tr> --</tbody> --</table> --<p>Test header escapes</p> --<table> --<thead> --<tr> --<th><code>`\</code> |</th> --<th><code>\</code> |</th> --</tr> --</thead> --<tbody> --<tr> --<td>row1</td> --<td>row1</td> --</tr> --<tr> --<td>row2</td> --<td>row2</td> --</tr> --</tbody> --</table> --<p>Escaped pipes in format row should not be a table</p> --<p>| Column1 | Column2 | --| ------- || ------- | --| row1 | row1 | --| row2 | row2 |</p> --<p>Test escaped code in Table</p> --<table> --<thead> --<tr> --<th>Should not be code</th> --<th>Should be code</th> --</tr> --</thead> --<tbody> --<tr> --<td>`Not code`</td> --<td>\<code>code</code></td> --</tr> --<tr> --<td>\`Not code\`</td> --<td>\\<code>code</code></td> --</tr> --</tbody> --</table> --<p>Single column tables</p> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td></td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td></td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td></td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td>row</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td>row</td> --</tr> --</tbody> --</table> --<table> --<thead> --<tr> --<th>Is a Table</th> --</tr> --</thead> --<tbody> --<tr> --<td>row</td> --</tr> --</tbody> --</table> --<h2>| Is not a Table</h2> --<p>| row</p> --<h2>Is not a Table |</h2> --<p>row |</p> --<p>| Is not a Table --| -------------- --row</p> --<p>Is not a Table | ---------------- | --row</p> -\ No newline at end of file -diff --git a/tests/extensions/extra/tables.txt b/tests/extensions/extra/tables.txt -deleted file mode 100644 -index 2dc4967..0000000 ---- a/tests/extensions/extra/tables.txt -+++ /dev/null -@@ -1,169 +0,0 @@ --Table Tests ------------- -- --First Header | Second Header --------------- | ------------- --Content Cell | Content Cell --Content Cell | Content Cell -- --| First Header | Second Header | --| ------------- | ------------- | --| Content Cell | Content Cell | --| Content Cell | Content Cell | -- --| Item | Value | --| :-------- | -----:| --| Computer | $1600 | --| Phone | $12 | --| Pipe | $1 | -- --| Function name | Description | --| ------------- | ------------------------------ | --| `help()` | Display the help window. | --| `destroy()` | **Destroy your computer!** | -- --|foo|bar|baz| --|:--|:-:|--:| --| | Q | | --|W | | W| -- --foo|bar|baz -----|---|--- -- | Q | -- W | | W -- --Three spaces in front of a table: -- -- First Header | Second Header -- ------------ | ------------- -- Content Cell | Content Cell -- Content Cell | Content Cell -- -- | First Header | Second Header | -- | ------------ | ------------- | -- | Content Cell | Content Cell | -- | Content Cell | Content Cell | -- --Four spaces is a code block: -- -- First Header | Second Header -- ------------ | ------------- -- Content Cell | Content Cell -- Content Cell | Content Cell -- --| First Header | Second Header | --| ------------ | ------------- | -- --More inline code block tests -- --Column 1 | Column 2 | Column 3 -----------|----------|--------- --word 1 | word 2 | word 3 --word 1 | `word 2` | word 3 --word 1 | \`word 2 | word 3 --word 1 | `word 2 | word 3 --word 1 | `word |2` | word 3 --words |`` some | code `` | more words --words |``` some | code ``` | more words --words |```` some | code ```` | more words --words |`` some ` | ` code `` | more words --words |``` some ` | ` code ``` | more words --words |```` some ` | ` code ```` | more words -- --A test for issue #440: -- --foo | bar ----- | --- --foo | (`bar`) and `baz`. -- --Lists are not tables -- -- - this | should | not -- - be | a | table -- --Add tests for issue #449 -- --Odd backticks | Even backticks -------------- | ------------- --``!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~`` | ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~`` -- --Escapes | More Escapes --------- | ------ --`` `\`` | `\` -- --Only the first backtick can be escaped -- --Escaped | Bacticks --------- | ------ --\`` \` | \`\` -- --Test escaped pipes -- --Column 1 | Column 2 ---------- | -------- --`|` \| | Pipes are okay in code and escaped. \| -- --| Column 1 | Column 2 | --| -------- | -------- | --| row1 | row1 \| --| row2 | row2 | -- --Test header escapes -- --| `` `\`` \| | `\` \| --| ---------- | ---- | --| row1 | row1 | --| row2 | row2 | -- --Escaped pipes in format row should not be a table -- --| Column1 | Column2 | --| ------- \|| ------- | --| row1 | row1 | --| row2 | row2 | -- --Test escaped code in Table -- --Should not be code | Should be code -------------------- | -------------- --\`Not code\` | \\`code` --\\\`Not code\\\` | \\\\`code` -- --Single column tables -- --| Is a Table | --| ---------- | -- --| Is a Table --| ---------- -- --Is a Table | ------------ | -- --| Is a Table | --| ---------- | --| row | -- --| Is a Table --| ---------- --| row -- --Is a Table | ------------ | --row | -- --| Is not a Table ---------------- --| row -- --Is not a Table | ---------------- --row | -- --| Is not a Table --| -------------- --row -- --Is not a Table | ---------------- | --row -diff --git a/tests/test_legacy.py b/tests/test_legacy.py -index 363161a..62bc075 100644 ---- a/tests/test_legacy.py -+++ b/tests/test_legacy.py -@@ -182,8 +182,6 @@ class TestExtensionsExtra(LegacyTestCase): - - footnotes = Kwargs(extensions='footnotes') - -- tables = Kwargs(extensions='tables') -- - extra_config = Kwargs( - extensions='extra', - extension_configs={ -diff --git a/tests/test_syntax/extensions/test_tables.py b/tests/test_syntax/extensions/test_tables.py -index b01ea0c..cd3fbe4 100644 ---- a/tests/test_syntax/extensions/test_tables.py -+++ b/tests/test_syntax/extensions/test_tables.py -@@ -20,6 +20,7 @@ License: BSD (see LICENSE.md for details). - """ - - from markdown.test_tools import TestCase -+from markdown.extensions.tables import TableExtension - - - class TestTableBlocks(TestCase): -@@ -60,3 +61,862 @@ Content Cell | - ), - extensions='tables' - ) -+ -+ def test_no_sides(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ First Header | Second Header -+ ------------- | ------------- -+ Content Cell | Content Cell -+ Content Cell | Content Cell -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th>First Header</th> -+ <th>Second Header</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_both_sides(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ | First Header | Second Header | -+ | ------------- | ------------- | -+ | Content Cell | Content Cell | -+ | Content Cell | Content Cell | -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th>First Header</th> -+ <th>Second Header</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_align_columns(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ | Item | Value | -+ | :-------- | -----:| -+ | Computer | $1600 | -+ | Phone | $12 | -+ | Pipe | $1 | -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th style="text-align: left;">Item</th> -+ <th style="text-align: right;">Value</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td style="text-align: left;">Computer</td> -+ <td style="text-align: right;">$1600</td> -+ </tr> -+ <tr> -+ <td style="text-align: left;">Phone</td> -+ <td style="text-align: right;">$12</td> -+ </tr> -+ <tr> -+ <td style="text-align: left;">Pipe</td> -+ <td style="text-align: right;">$1</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_styles_in_tables(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ | Function name | Description | -+ | ------------- | ------------------------------ | -+ | `help()` | Display the help window. | -+ | `destroy()` | **Destroy your computer!** | -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th>Function name</th> -+ <th>Description</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td><code>help()</code></td> -+ <td>Display the help window.</td> -+ </tr> -+ <tr> -+ <td><code>destroy()</code></td> -+ <td><strong>Destroy your computer!</strong></td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_align_three(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ |foo|bar|baz| -+ |:--|:-:|--:| -+ | | Q | | -+ |W | | W| -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th style="text-align: left;">foo</th> -+ <th style="text-align: center;">bar</th> -+ <th style="text-align: right;">baz</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td style="text-align: left;"></td> -+ <td style="text-align: center;">Q</td> -+ <td style="text-align: right;"></td> -+ </tr> -+ <tr> -+ <td style="text-align: left;">W</td> -+ <td style="text-align: center;"></td> -+ <td style="text-align: right;">W</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_three_columns(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ foo|bar|baz -+ ---|---|--- -+ | Q | -+ W | | W -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th>foo</th> -+ <th>bar</th> -+ <th>baz</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td></td> -+ <td>Q</td> -+ <td></td> -+ </tr> -+ <tr> -+ <td>W</td> -+ <td></td> -+ <td>W</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_three_spaces_prefix(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ Three spaces in front of a table: -+ -+ First Header | Second Header -+ ------------ | ------------- -+ Content Cell | Content Cell -+ Content Cell | Content Cell -+ -+ | First Header | Second Header | -+ | ------------ | ------------- | -+ | Content Cell | Content Cell | -+ | Content Cell | Content Cell | -+ """), -+ self.dedent( -+ """ -+ <p>Three spaces in front of a table:</p> -+ <table> -+ <thead> -+ <tr> -+ <th>First Header</th> -+ <th>Second Header</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>First Header</th> -+ <th>Second Header</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ <tr> -+ <td>Content Cell</td> -+ <td>Content Cell</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_code_block_table(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ Four spaces is a code block: -+ -+ First Header | Second Header -+ ------------ | ------------- -+ Content Cell | Content Cell -+ Content Cell | Content Cell -+ -+ | First Header | Second Header | -+ | ------------ | ------------- | -+ """), -+ self.dedent( -+ """ -+ <p>Four spaces is a code block:</p> -+ <pre><code>First Header | Second Header -+ ------------ | ------------- -+ Content Cell | Content Cell -+ Content Cell | Content Cell -+ </code></pre> -+ <table> -+ <thead> -+ <tr> -+ <th>First Header</th> -+ <th>Second Header</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td></td> -+ <td></td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_inline_code_blocks(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ More inline code block tests -+ -+ Column 1 | Column 2 | Column 3 -+ ---------|----------|--------- -+ word 1 | word 2 | word 3 -+ word 1 | `word 2` | word 3 -+ word 1 | \\`word 2 | word 3 -+ word 1 | `word 2 | word 3 -+ word 1 | `word |2` | word 3 -+ words |`` some | code `` | more words -+ words |``` some | code ``` | more words -+ words |```` some | code ```` | more words -+ words |`` some ` | ` code `` | more words -+ words |``` some ` | ` code ``` | more words -+ words |```` some ` | ` code ```` | more words -+ """), -+ self.dedent( -+ """ -+ <p>More inline code block tests</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Column 1</th> -+ <th>Column 2</th> -+ <th>Column 3</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>word 1</td> -+ <td>word 2</td> -+ <td>word 3</td> -+ </tr> -+ <tr> -+ <td>word 1</td> -+ <td><code>word 2</code></td> -+ <td>word 3</td> -+ </tr> -+ <tr> -+ <td>word 1</td> -+ <td>`word 2</td> -+ <td>word 3</td> -+ </tr> -+ <tr> -+ <td>word 1</td> -+ <td>`word 2</td> -+ <td>word 3</td> -+ </tr> -+ <tr> -+ <td>word 1</td> -+ <td><code>word |2</code></td> -+ <td>word 3</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some | code</code></td> -+ <td>more words</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some | code</code></td> -+ <td>more words</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some | code</code></td> -+ <td>more words</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some ` | ` code</code></td> -+ <td>more words</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some ` | ` code</code></td> -+ <td>more words</td> -+ </tr> -+ <tr> -+ <td>words</td> -+ <td><code>some ` | ` code</code></td> -+ <td>more words</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_issue_440(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ A test for issue #440: -+ -+ foo | bar -+ --- | --- -+ foo | (`bar`) and `baz`. -+ """), -+ self.dedent( -+ """ -+ <p>A test for issue #440:</p> -+ <table> -+ <thead> -+ <tr> -+ <th>foo</th> -+ <th>bar</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>foo</td> -+ <td>(<code>bar</code>) and <code>baz</code>.</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_lists_not_tables(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ Lists are not tables -+ -+ - this | should | not -+ - be | a | table -+ """), -+ self.dedent( -+ """ -+ <p>Lists are not tables</p> -+ <ul> -+ <li>this | should | not</li> -+ <li>be | a | table</li> -+ </ul> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_issue_449(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ r""" -+ Add tests for issue #449 -+ -+ Odd backticks | Even backticks -+ ------------ | ------------- -+ ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~`` | ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~`` -+ -+ Escapes | More Escapes -+ ------- | ------ -+ `` `\`` | `\` -+ -+ Only the first backtick can be escaped -+ -+ Escaped | Bacticks -+ ------- | ------ -+ \`` \` | \`\` -+ -+ Test escaped pipes -+ -+ Column 1 | Column 2 -+ -------- | -------- -+ `|` \| | Pipes are okay in code and escaped. \| -+ -+ | Column 1 | Column 2 | -+ | -------- | -------- | -+ | row1 | row1 \| -+ | row2 | row2 | -+ -+ Test header escapes -+ -+ | `` `\`` \| | `\` \| -+ | ---------- | ---- | -+ | row1 | row1 | -+ | row2 | row2 | -+ -+ Escaped pipes in format row should not be a table -+ -+ | Column1 | Column2 | -+ | ------- \|| ------- | -+ | row1 | row1 | -+ | row2 | row2 | -+ -+ Test escaped code in Table -+ -+ Should not be code | Should be code -+ ------------------ | -------------- -+ \`Not code\` | \\`code` -+ \\\`Not code\\\` | \\\\`code` -+ """), -+ self.dedent( -+ """ -+ <p>Add tests for issue #449</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Odd backticks</th> -+ <th>Even backticks</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td><code>!\\"\\#$%&'()*+,\\-./:;<=>?@\\\\\\\\^_`{|}~</code></td> -+ <td><code>!\\"\\#$%&'()*+,\\-./:;<=>?@\\\\\\\\^`_`{|}~</code></td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Escapes</th> -+ <th>More Escapes</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td><code>`\\</code></td> -+ <td><code>\\</code></td> -+ </tr> -+ </tbody> -+ </table> -+ <p>Only the first backtick can be escaped</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Escaped</th> -+ <th>Bacticks</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>`<code>\\</code></td> -+ <td>``</td> -+ </tr> -+ </tbody> -+ </table> -+ <p>Test escaped pipes</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Column 1</th> -+ <th>Column 2</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td><code>|</code> |</td> -+ <td>Pipes are okay in code and escaped. |</td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Column 1</th> -+ <th>Column 2</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>row1</td> -+ <td>row1 |</td> -+ </tr> -+ <tr> -+ <td>row2</td> -+ <td>row2</td> -+ </tr> -+ </tbody> -+ </table> -+ <p>Test header escapes</p> -+ <table> -+ <thead> -+ <tr> -+ <th><code>`\\</code> |</th> -+ <th><code>\\</code> |</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>row1</td> -+ <td>row1</td> -+ </tr> -+ <tr> -+ <td>row2</td> -+ <td>row2</td> -+ </tr> -+ </tbody> -+ </table> -+ <p>Escaped pipes in format row should not be a table</p> -+ <p>| Column1 | Column2 | -+ | ------- || ------- | -+ | row1 | row1 | -+ | row2 | row2 |</p> -+ <p>Test escaped code in Table</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Should not be code</th> -+ <th>Should be code</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>`Not code`</td> -+ <td>\\<code>code</code></td> -+ </tr> -+ <tr> -+ <td>\\`Not code\\`</td> -+ <td>\\\\<code>code</code></td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_single_column_tables(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ Single column tables -+ -+ | Is a Table | -+ | ---------- | -+ -+ | Is a Table -+ | ---------- -+ -+ Is a Table | -+ ---------- | -+ -+ | Is a Table | -+ | ---------- | -+ | row | -+ -+ | Is a Table -+ | ---------- -+ | row -+ -+ Is a Table | -+ ---------- | -+ row | -+ -+ | Is not a Table -+ -------------- -+ | row -+ -+ Is not a Table | -+ -------------- -+ row | -+ -+ | Is not a Table -+ | -------------- -+ row -+ -+ Is not a Table | -+ -------------- | -+ row -+ """), -+ self.dedent( -+ """ -+ <p>Single column tables</p> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td></td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td></td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td></td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>row</td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>row</td> -+ </tr> -+ </tbody> -+ </table> -+ <table> -+ <thead> -+ <tr> -+ <th>Is a Table</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td>row</td> -+ </tr> -+ </tbody> -+ </table> -+ <h2>| Is not a Table</h2> -+ <p>| row</p> -+ <h2>Is not a Table |</h2> -+ <p>row |</p> -+ <p>| Is not a Table -+ | -------------- -+ row</p> -+ <p>Is not a Table | -+ -------------- | -+ row</p> -+ """ -+ ), -+ extensions='tables' -+ ) -+ -+ def test_align_columns_legacy(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ | Item | Value | -+ | :-------- | -----:| -+ | Computer | $1600 | -+ | Phone | $12 | -+ | Pipe | $1 | -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th align="left">Item</th> -+ <th align="right">Value</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td align="left">Computer</td> -+ <td align="right">$1600</td> -+ </tr> -+ <tr> -+ <td align="left">Phone</td> -+ <td align="right">$12</td> -+ </tr> -+ <tr> -+ <td align="left">Pipe</td> -+ <td align="right">$1</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions=TableExtension(use_align_attribute=True) -+ ) -+ -+ def test_align_three_legacy(self): -+ self.assertMarkdownRenders( -+ self.dedent( -+ """ -+ |foo|bar|baz| -+ |:--|:-:|--:| -+ | | Q | | -+ |W | | W| -+ """ -+ ), -+ self.dedent( -+ """ -+ <table> -+ <thead> -+ <tr> -+ <th align="left">foo</th> -+ <th align="center">bar</th> -+ <th align="right">baz</th> -+ </tr> -+ </thead> -+ <tbody> -+ <tr> -+ <td align="left"></td> -+ <td align="center">Q</td> -+ <td align="right"></td> -+ </tr> -+ <tr> -+ <td align="left">W</td> -+ <td align="center"></td> -+ <td align="right">W</td> -+ </tr> -+ </tbody> -+ </table> -+ """ -+ ), -+ extensions=TableExtension(use_align_attribute=True) -+ ) --- -2.33.0 -
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/pep562.py
Deleted
@@ -1,245 +0,0 @@ -""" -Backport of PEP 562. - -https://pypi.org/search/?q=pep562 - -Licensed under MIT -Copyright (c) 2018 Isaac Muse <isaacmuse@gmail.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. -""" -import sys -from collections import namedtuple -import re - -__all__ = ('Pep562',) - -RE_VER = re.compile( - r'''(?x) - (?P<major>\d+)(?:\.(?P<minor>\d+))?(?:\.(?P<micro>\d+))? - (?:(?P<type>a|b|rc)(?P<pre>\d+))? - (?:\.post(?P<post>\d+))? - (?:\.dev(?P<dev>\d+))? - ''' -) - -REL_MAP = { - ".dev": "", - ".dev-alpha": "a", - ".dev-beta": "b", - ".dev-candidate": "rc", - "alpha": "a", - "beta": "b", - "candidate": "rc", - "final": "" -} - -DEV_STATUS = { - ".dev": "2 - Pre-Alpha", - ".dev-alpha": "2 - Pre-Alpha", - ".dev-beta": "2 - Pre-Alpha", - ".dev-candidate": "2 - Pre-Alpha", - "alpha": "3 - Alpha", - "beta": "4 - Beta", - "candidate": "4 - Beta", - "final": "5 - Production/Stable" -} - -PRE_REL_MAP = {"a": 'alpha', "b": 'beta', "rc": 'candidate'} - - -class Version(namedtuple("Version", "major", "minor", "micro", "release", "pre", "post", "dev")): - """ - Get the version (PEP 440). - - A biased approach to the PEP 440 semantic version. - - Provides a tuple structure which is sorted for comparisons `v1 > v2` etc. - (major, minor, micro, release type, pre-release build, post-release build, development release build) - Release types are named in is such a way they are comparable with ease. - Accessors to check if a development, pre-release, or post-release build. Also provides accessor to get - development status for setup files. - - How it works (currently): - - - You must specify a release type as either `final`, `alpha`, `beta`, or `candidate`. - - To define a development release, you can use either `.dev`, `.dev-alpha`, `.dev-beta`, or `.dev-candidate`. - The dot is used to ensure all development specifiers are sorted before `alpha`. - You can specify a `dev` number for development builds, but do not have to as implicit development releases - are allowed. - - You must specify a `pre` value greater than zero if using a prerelease as this project (not PEP 440) does not - allow implicit prereleases. - - You can optionally set `post` to a value greater than zero to make the build a post release. While post releases - are technically allowed in prereleases, it is strongly discouraged, so we are rejecting them. It should be - noted that we do not allow `post0` even though PEP 440 does not restrict this. This project specifically - does not allow implicit post releases. - - It should be noted that we do not support epochs `1!` or local versions `+some-custom.version-1`. - - Acceptable version releases: - - ``` - Version(1, 0, 0, "final") 1.0 - Version(1, 2, 0, "final") 1.2 - Version(1, 2, 3, "final") 1.2.3 - Version(1, 2, 0, ".dev-alpha", pre=4) 1.2a4 - Version(1, 2, 0, ".dev-beta", pre=4) 1.2b4 - Version(1, 2, 0, ".dev-candidate", pre=4) 1.2rc4 - Version(1, 2, 0, "final", post=1) 1.2.post1 - Version(1, 2, 3, ".dev") 1.2.3.dev0 - Version(1, 2, 3, ".dev", dev=1) 1.2.3.dev1 - ``` - - """ - - def __new__(cls, major, minor, micro, release="final", pre=0, post=0, dev=0): - """Validate version info.""" - - # Ensure all parts are positive integers. - for value in (major, minor, micro, pre, post): - if not (isinstance(value, int) and value >= 0): - raise ValueError("All version parts except 'release' should be integers.") - - if release not in REL_MAP: - raise ValueError("'{}' is not a valid release type.".format(release)) - - # Ensure valid pre-release (we do not allow implicit pre-releases). - if ".dev-candidate" < release < "final": - if pre == 0: - raise ValueError("Implicit pre-releases not allowed.") - elif dev: - raise ValueError("Version is not a development release.") - elif post: - raise ValueError("Post-releases are not allowed with pre-releases.") - - # Ensure valid development or development/pre release - elif release < "alpha": - if release > ".dev" and pre == 0: - raise ValueError("Implicit pre-release not allowed.") - elif post: - raise ValueError("Post-releases are not allowed with pre-releases.") - - # Ensure a valid normal release - else: - if pre: - raise ValueError("Version is not a pre-release.") - elif dev: - raise ValueError("Version is not a development release.") - - return super().__new__(cls, major, minor, micro, release, pre, post, dev) - - def _is_pre(self): - """Is prerelease.""" - - return self.pre > 0 - - def _is_dev(self): - """Is development.""" - - return bool(self.release < "alpha") - - def _is_post(self): - """Is post.""" - - return self.post > 0 - - def _get_dev_status(self): # pragma: no cover - """Get development status string.""" - - return DEV_STATUSself.release - - def _get_canonical(self): - """Get the canonical output string.""" - - # Assemble major, minor, micro version and append `pre`, `post`, or `dev` if needed.. - if self.micro == 0: - ver = "{}.{}".format(self.major, self.minor) - else: - ver = "{}.{}.{}".format(self.major, self.minor, self.micro) - if self._is_pre(): - ver += '{}{}'.format(REL_MAPself.release, self.pre) - if self._is_post(): - ver += ".post{}".format(self.post) - if self._is_dev(): - ver += ".dev{}".format(self.dev) - - return ver - - -def parse_version(ver, pre=False): - """Parse version into a comparable Version tuple.""" - - m = RE_VER.match(ver) - - # Handle major, minor, micro - major = int(m.group('major')) - minor = int(m.group('minor')) if m.group('minor') else 0 - micro = int(m.group('micro')) if m.group('micro') else 0 - - # Handle pre releases - if m.group('type'): - release = PRE_REL_MAPm.group('type') - pre = int(m.group('pre')) - else: - release = "final" - pre = 0 - - # Handle development releases - dev = m.group('dev') if m.group('dev') else 0 - if m.group('dev'): - dev = int(m.group('dev')) - release = '.dev-' + release if pre else '.dev' - else: - dev = 0 - - # Handle post - post = int(m.group('post')) if m.group('post') else 0 - - return Version(major, minor, micro, release, pre, post, dev) - - -class Pep562: - """ - Backport of PEP 562 <https://pypi.org/search/?q=pep562>. - - Wraps the module in a class that exposes the mechanics to override `__dir__` and `__getattr__`. - The given module will be searched for overrides of `__dir__` and `__getattr__` and use them when needed. - """ - - def __init__(self, name): - """Acquire `__getattr__` and `__dir__`, but only replace module for versions less than Python 3.7.""" - - self._module = sys.modulesname - self._get_attr = getattr(self._module, '__getattr__', None) - self._get_dir = getattr(self._module, '__dir__', None) - sys.modulesname = self - - def __dir__(self): - """Return the overridden `dir` if one was provided, else apply `dir` to the module.""" - - return self._get_dir() if self._get_dir else dir(self._module) - - def __getattr__(self, name): - """Attempt to retrieve the attribute from the module, and if missing, use the overridden function if present.""" - - try: - return getattr(self._module, name) - except AttributeError: - if self._get_attr: - return self._get_attr(name) - raise - - -__version_info__ = Version(1, 0, 0, "final") -__version__ = __version_info__._get_canonical()
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/extensions/extra/tables.html
Deleted
@@ -1,466 +0,0 @@ -<h2>Table Tests</h2> -<table> -<thead> -<tr> -<th>First Header</th> -<th>Second Header</th> -</tr> -</thead> -<tbody> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>First Header</th> -<th>Second Header</th> -</tr> -</thead> -<tbody> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th align="left">Item</th> -<th align="right">Value</th> -</tr> -</thead> -<tbody> -<tr> -<td align="left">Computer</td> -<td align="right">$1600</td> -</tr> -<tr> -<td align="left">Phone</td> -<td align="right">$12</td> -</tr> -<tr> -<td align="left">Pipe</td> -<td align="right">$1</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Function name</th> -<th>Description</th> -</tr> -</thead> -<tbody> -<tr> -<td><code>help()</code></td> -<td>Display the help window.</td> -</tr> -<tr> -<td><code>destroy()</code></td> -<td><strong>Destroy your computer!</strong></td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th align="left">foo</th> -<th align="center">bar</th> -<th align="right">baz</th> -</tr> -</thead> -<tbody> -<tr> -<td align="left"></td> -<td align="center">Q</td> -<td align="right"></td> -</tr> -<tr> -<td align="left">W</td> -<td align="center"></td> -<td align="right">W</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>foo</th> -<th>bar</th> -<th>baz</th> -</tr> -</thead> -<tbody> -<tr> -<td></td> -<td>Q</td> -<td></td> -</tr> -<tr> -<td>W</td> -<td></td> -<td>W</td> -</tr> -</tbody> -</table> -<p>Three spaces in front of a table:</p> -<table> -<thead> -<tr> -<th>First Header</th> -<th>Second Header</th> -</tr> -</thead> -<tbody> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>First Header</th> -<th>Second Header</th> -</tr> -</thead> -<tbody> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -<tr> -<td>Content Cell</td> -<td>Content Cell</td> -</tr> -</tbody> -</table> -<p>Four spaces is a code block:</p> -<pre><code>First Header | Second Header ------------- | ------------- -Content Cell | Content Cell -Content Cell | Content Cell -</code></pre> -<table> -<thead> -<tr> -<th>First Header</th> -<th>Second Header</th> -</tr> -</thead> -<tbody> -<tr> -<td></td> -<td></td> -</tr> -</tbody> -</table> -<p>More inline code block tests</p> -<table> -<thead> -<tr> -<th>Column 1</th> -<th>Column 2</th> -<th>Column 3</th> -</tr> -</thead> -<tbody> -<tr> -<td>word 1</td> -<td>word 2</td> -<td>word 3</td> -</tr> -<tr> -<td>word 1</td> -<td><code>word 2</code></td> -<td>word 3</td> -</tr> -<tr> -<td>word 1</td> -<td>`word 2</td> -<td>word 3</td> -</tr> -<tr> -<td>word 1</td> -<td>`word 2</td> -<td>word 3</td> -</tr> -<tr> -<td>word 1</td> -<td><code>word |2</code></td> -<td>word 3</td> -</tr> -<tr> -<td>words</td> -<td><code>some | code</code></td> -<td>more words</td> -</tr> -<tr> -<td>words</td> -<td><code>some | code</code></td> -<td>more words</td> -</tr> -<tr> -<td>words</td> -<td><code>some | code</code></td> -<td>more words</td> -</tr> -<tr> -<td>words</td> -<td><code>some ` | ` code</code></td> -<td>more words</td> -</tr> -<tr> -<td>words</td> -<td><code>some ` | ` code</code></td> -<td>more words</td> -</tr> -<tr> -<td>words</td> -<td><code>some ` | ` code</code></td> -<td>more words</td> -</tr> -</tbody> -</table> -<p>A test for issue #440:</p> -<table> -<thead> -<tr> -<th>foo</th> -<th>bar</th> -</tr> -</thead> -<tbody> -<tr> -<td>foo</td> -<td>(<code>bar</code>) and <code>baz</code>.</td> -</tr> -</tbody> -</table> -<p>Lists are not tables</p> -<ul> -<li>this | should | not</li> -<li>be | a | table</li> -</ul> -<p>Add tests for issue #449</p> -<table> -<thead> -<tr> -<th>Odd backticks</th> -<th>Even backticks</th> -</tr> -</thead> -<tbody> -<tr> -<td><code>!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~</code></td> -<td><code>!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~</code></td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Escapes</th> -<th>More Escapes</th> -</tr> -</thead> -<tbody> -<tr> -<td><code>`\</code></td> -<td><code>\</code></td> -</tr> -</tbody> -</table> -<p>Only the first backtick can be escaped</p> -<table> -<thead> -<tr> -<th>Escaped</th> -<th>Bacticks</th> -</tr> -</thead> -<tbody> -<tr> -<td>`<code>\</code></td> -<td>``</td> -</tr> -</tbody> -</table> -<p>Test escaped pipes</p> -<table> -<thead> -<tr> -<th>Column 1</th> -<th>Column 2</th> -</tr> -</thead> -<tbody> -<tr> -<td><code>|</code> |</td> -<td>Pipes are okay in code and escaped. |</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Column 1</th> -<th>Column 2</th> -</tr> -</thead> -<tbody> -<tr> -<td>row1</td> -<td>row1 |</td> -</tr> -<tr> -<td>row2</td> -<td>row2</td> -</tr> -</tbody> -</table> -<p>Test header escapes</p> -<table> -<thead> -<tr> -<th><code>`\</code> |</th> -<th><code>\</code> |</th> -</tr> -</thead> -<tbody> -<tr> -<td>row1</td> -<td>row1</td> -</tr> -<tr> -<td>row2</td> -<td>row2</td> -</tr> -</tbody> -</table> -<p>Escaped pipes in format row should not be a table</p> -<p>| Column1 | Column2 | -| ------- || ------- | -| row1 | row1 | -| row2 | row2 |</p> -<p>Test escaped code in Table</p> -<table> -<thead> -<tr> -<th>Should not be code</th> -<th>Should be code</th> -</tr> -</thead> -<tbody> -<tr> -<td>`Not code`</td> -<td>\<code>code</code></td> -</tr> -<tr> -<td>\`Not code\`</td> -<td>\\<code>code</code></td> -</tr> -</tbody> -</table> -<p>Single column tables</p> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td></td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td></td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td></td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td>row</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td>row</td> -</tr> -</tbody> -</table> -<table> -<thead> -<tr> -<th>Is a Table</th> -</tr> -</thead> -<tbody> -<tr> -<td>row</td> -</tr> -</tbody> -</table> -<h2>| Is not a Table</h2> -<p>| row</p> -<h2>Is not a Table |</h2> -<p>row |</p> -<p>| Is not a Table -| -------------- -row</p> -<p>Is not a Table | --------------- | -row</p> \ No newline at end of file
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/extensions/extra/tables.txt
Deleted
@@ -1,169 +0,0 @@ -Table Tests ------------ - -First Header | Second Header -------------- | ------------- -Content Cell | Content Cell -Content Cell | Content Cell - -| First Header | Second Header | -| ------------- | ------------- | -| Content Cell | Content Cell | -| Content Cell | Content Cell | - -| Item | Value | -| :-------- | -----:| -| Computer | $1600 | -| Phone | $12 | -| Pipe | $1 | - -| Function name | Description | -| ------------- | ------------------------------ | -| `help()` | Display the help window. | -| `destroy()` | **Destroy your computer!** | - -|foo|bar|baz| -|:--|:-:|--:| -| | Q | | -|W | | W| - -foo|bar|baz ----|---|--- - | Q | - W | | W - -Three spaces in front of a table: - - First Header | Second Header - ------------ | ------------- - Content Cell | Content Cell - Content Cell | Content Cell - - | First Header | Second Header | - | ------------ | ------------- | - | Content Cell | Content Cell | - | Content Cell | Content Cell | - -Four spaces is a code block: - - First Header | Second Header - ------------ | ------------- - Content Cell | Content Cell - Content Cell | Content Cell - -| First Header | Second Header | -| ------------ | ------------- | - -More inline code block tests - -Column 1 | Column 2 | Column 3 ----------|----------|--------- -word 1 | word 2 | word 3 -word 1 | `word 2` | word 3 -word 1 | \`word 2 | word 3 -word 1 | `word 2 | word 3 -word 1 | `word |2` | word 3 -words |`` some | code `` | more words -words |``` some | code ``` | more words -words |```` some | code ```` | more words -words |`` some ` | ` code `` | more words -words |``` some ` | ` code ``` | more words -words |```` some ` | ` code ```` | more words - -A test for issue #440: - -foo | bar ---- | --- -foo | (`bar`) and `baz`. - -Lists are not tables - - - this | should | not - - be | a | table - -Add tests for issue #449 - -Odd backticks | Even backticks ------------- | ------------- -``!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~`` | ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~`` - -Escapes | More Escapes -------- | ------ -`` `\`` | `\` - -Only the first backtick can be escaped - -Escaped | Bacticks -------- | ------ -\`` \` | \`\` - -Test escaped pipes - -Column 1 | Column 2 --------- | -------- -`|` \| | Pipes are okay in code and escaped. \| - -| Column 1 | Column 2 | -| -------- | -------- | -| row1 | row1 \| -| row2 | row2 | - -Test header escapes - -| `` `\`` \| | `\` \| -| ---------- | ---- | -| row1 | row1 | -| row2 | row2 | - -Escaped pipes in format row should not be a table - -| Column1 | Column2 | -| ------- \|| ------- | -| row1 | row1 | -| row2 | row2 | - -Test escaped code in Table - -Should not be code | Should be code ------------------- | -------------- -\`Not code\` | \\`code` -\\\`Not code\\\` | \\\\`code` - -Single column tables - -| Is a Table | -| ---------- | - -| Is a Table -| ---------- - -Is a Table | ----------- | - -| Is a Table | -| ---------- | -| row | - -| Is a Table -| ---------- -| row - -Is a Table | ----------- | -row | - -| Is not a Table --------------- -| row - -Is not a Table | --------------- -row | - -| Is not a Table -| -------------- -row - -Is not a Table | --------------- | -row
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/Markdown.egg-info/PKG-INFO -> _service:tar_scm:Markdown-3.4.1.tar.gz/Markdown.egg-info/PKG-INFO
Changed
@@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Markdown -Version: 3.3.7 +Version: 3.4.1 Summary: Python implementation of Markdown. Home-page: https://Python-Markdown.github.io/ Author: Manfred Stienstra, Yuri takhteyev and Waylan limberg @@ -11,13 +11,11 @@ Project-URL: Documentation, https://Python-Markdown.github.io/ Project-URL: GitHub Project, https://github.com/Python-Markdown/markdown Project-URL: Issue Tracker, https://github.com/Python-Markdown/markdown/issues -Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 @@ -33,7 +31,7 @@ Classifier: Topic :: Text Processing :: Filters Classifier: Topic :: Text Processing :: Markup :: HTML Classifier: Topic :: Text Processing :: Markup :: Markdown -Requires-Python: >=3.6 +Requires-Python: >=3.7 Description-Content-Type: text/markdown Provides-Extra: testing License-File: LICENSE.md @@ -100,7 +98,5 @@ Code of Conduct --------------- -Everyone interacting in the Python-Markdown project's codebases, issue trackers, +Everyone interacting in the Python-Markdown project's code bases, issue trackers, and mailing lists is expected to follow the Code of Conduct. - -
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/Markdown.egg-info/SOURCES.txt -> _service:tar_scm:Markdown-3.4.1.tar.gz/Markdown.egg-info/SOURCES.txt
Changed
@@ -35,6 +35,7 @@ docs/change_log/release-3.1.md docs/change_log/release-3.2.md docs/change_log/release-3.3.md +docs/change_log/release-3.4.md docs/extensions/abbreviations.md docs/extensions/admonition.md docs/extensions/api.md @@ -63,7 +64,6 @@ markdown/core.py markdown/htmlparser.py markdown/inlinepatterns.py -markdown/pep562.py markdown/postprocessors.py markdown/preprocessors.py markdown/serializers.py @@ -180,8 +180,6 @@ tests/extensions/extra/raw-html.txt tests/extensions/extra/simple_def-lists.html tests/extensions/extra/simple_def-lists.txt -tests/extensions/extra/tables.html -tests/extensions/extra/tables.txt tests/misc/CRLF_line_ends.html tests/misc/CRLF_line_ends.txt tests/misc/adjacent-headers.html @@ -371,6 +369,7 @@ tests/test_syntax/extensions/test_legacy_attrs.py tests/test_syntax/extensions/test_legacy_em.py tests/test_syntax/extensions/test_md_in_html.py +tests/test_syntax/extensions/test_smarty.py tests/test_syntax/extensions/test_tables.py tests/test_syntax/extensions/test_toc.py tests/test_syntax/inline/__init__.py
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/PKG-INFO -> _service:tar_scm:Markdown-3.4.1.tar.gz/PKG-INFO
Changed
@@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Markdown -Version: 3.3.7 +Version: 3.4.1 Summary: Python implementation of Markdown. Home-page: https://Python-Markdown.github.io/ Author: Manfred Stienstra, Yuri takhteyev and Waylan limberg @@ -11,13 +11,11 @@ Project-URL: Documentation, https://Python-Markdown.github.io/ Project-URL: GitHub Project, https://github.com/Python-Markdown/markdown Project-URL: Issue Tracker, https://github.com/Python-Markdown/markdown/issues -Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 @@ -33,7 +31,7 @@ Classifier: Topic :: Text Processing :: Filters Classifier: Topic :: Text Processing :: Markup :: HTML Classifier: Topic :: Text Processing :: Markup :: Markdown -Requires-Python: >=3.6 +Requires-Python: >=3.7 Description-Content-Type: text/markdown Provides-Extra: testing License-File: LICENSE.md @@ -100,7 +98,5 @@ Code of Conduct --------------- -Everyone interacting in the Python-Markdown project's codebases, issue trackers, +Everyone interacting in the Python-Markdown project's code bases, issue trackers, and mailing lists is expected to follow the Code of Conduct. - -
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/README.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/README.md
Changed
@@ -60,5 +60,5 @@ Code of Conduct --------------- -Everyone interacting in the Python-Markdown project's codebases, issue trackers, +Everyone interacting in the Python-Markdown project's code bases, issue trackers, and mailing lists is expected to follow the Code of Conduct.
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/change_log/index.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/change_log/index.md
Changed
@@ -3,6 +3,12 @@ Python-Markdown Change Log ========================= +July 15, 2022: version 3.4.1 (a bug-fix release). + +* Fix an import issue with `importlib.util` (#1274). + +July 15, 2022: version 3.4 (Notes(release-3.4.md)). + May 5, 2022: version 3.3.7 (a bug-fix release). * Disallow square brackets in reference link ids (#1209).
View file
_service:tar_scm:Markdown-3.4.1.tar.gz/docs/change_log/release-3.4.md
Added
@@ -0,0 +1,113 @@ +title: Release Notes for v3.4 + +# Python-Markdown 3.4 Release Notes + +Python-Markdown version 3.4 supports Python versions 3.7, 3.8, 3.9, 3.10 and +PyPy3. + +## Backwards-incompatible changes + +### The `tables` extension now uses a `style` attribute instead of an `align` attribute for alignment. + +The HTML4 specspec4 specifically deprecates the use of the `align` attribute +and it does not appear at all in the HTML5 specspec5. Therefore, by default, +the tables extension will now use the `style` attribute (setting just the +`text-align` property) in `td` and `th` blocks. + +spec4: https://www.w3.org/TR/html4/present/graphics.html#h-15.1.2 +spec5: https://www.w3.org/TR/html53/tabular-data.html#attributes-common-to-td-and-th-elements +tables: ../extensions/tables.md + +The former behavior is available by setting the `use_align_attribute` +configuration option to `True` when enabling the extension. + +For example, to configure the old `align` behavior: + +```python +from markdown.extensions.tables import TableExtension + +markdown.markdown(src, extensions=TableExtension(use_align_attribute=True)) +``` + +### Backslash unescaping moved to Treeprocessor (#1131). + +Unescaping backslash escapes has been moved to a Treeprocessor, which enables +proper HTML escaping during serialization. However, it is recognized that +various third-party extensions may be calling the old class at +`postprocessors.UnescapePostprocessor`. Therefore, the old class remains in the +code base, but has been deprecated and will be removed in a future release. The +new class `treeprocessors.UnescapeTreeprocessor` should be used instead. + +### Previously deprecated objects have been removed + +Various objects were deprecated in version 3.0 and began raising deprecation +warnings (see the version 3.0 release notes for details). Any of those objects +which remained in version 3.3 have been removed from the code base in version 3.4 +and will now raise errors. The relevant objects are listed below. + +version 3.0 release notes: release-3.0.md + +| Deprecated Object | Replacement Object | +|----------------------------------------|-------------------------------------| +| `markdown.version` | `markdown.__version__` | +| `markdown.version_info` | `markdown.__version_info__` | +| `markdown.util.etree` | `xml.etree.ElementTree` | +| `markdown.util.string_type` | `str` | +| `markdown.util.text_type` | `str` | +| `markdown.util.int2str` | `chr` | +| `markdown.util.iterrange` | `range` | +| `markdown.util.isBlockLevel` | `markdown.Markdown().is_block_level`| +| `markdown.util.Processor().markdown` | `markdown.util.Processor().md` | +| `markdown.util.Registry().__setitem__` | `markdown.util.Registry().register` | +| `markdown.util.Registry().__delitem__` |`markdown.util.Registry().deregister`| +| `markdown.util.Registry().add` | `markdown.util.Registry().register` | + +In addition, the `md_globals` parameter of +`Markdown.extensions.Extension.extendMarkdown()` is no longer recognized as a +valid parameter and will raise an error if provided. + +## New features + +The following new features have been included in the 3.4 release: + + +* Some new configuration options have been added to the + footnotes(../extensions/footnotes.md) extension (#1218): + + * Small refactor of the `BACKLINK_TITLE` option; The use of `format()` + instead of "old" `%d` formatter allows one to specify text without the + need to have the number of the footnote in it (like footnotes on + Wikipedia for example). The modification is backward compatible so no + configuration change is required. + + * Addition of a new option `SUPERSCRIPT_TEXT` that allows one to specify a + custom placeholder for the footnote itself in the text. + Ex: `{}` will give `<sup>1</sup>`, `({})` will give `<sup>(1)</sup>`, + or by default, the current behavior: `<sup>1</sup>`. + +* The Table of Contents(../extensions/toc.md) extension now accepts a + `toc_class` parameter which can be used to set the CSS class(es) on the + `<div>` that contains the Table of Contents (#1224). + +* The CodeHilite extension now supports a `pygments_formatter` option that can + be set to a custom formatter class (#1187). + + - If `pygments_formatter` is set to a string (ex: `'html'`), Pygments' + default formatter by that name is used. + - If `pygments_formatter` is set to a formatter class (or any callable + which returns a formatter instance), then an instance of that class is + used. + + The formatter class is now passed an additional option, `lang_str`, to + denote the language of the code block (#1258). While Pygments' built-in + formatters will ignore the option, a custom formatter assigned to the + `pygments_formatter` option can make use of the `lang_str` to include the + code block's language in the output. + +## Bug fixes + +The following bug fixes are included in the 3.4 release: + +* Extension entry-points are only loaded if needed (#1216). +* Added additional checks to the `<pre><code>` handling of + `PrettifyTreeprocessor` (#1261, #1263).
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/extensions/admonition.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/extensions/admonition.md
Changed
@@ -99,7 +99,7 @@ There is no CSS included as part of this extension. Check out the default Sphinxsphinx theme for inspiration. -sphinx: https://www.sphinx-doc.org/en/stable/ +sphinx: https://www.sphinx-doc.org/en/master/ ## Usage
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/extensions/code_hilite.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/extensions/code_hilite.md
Changed
@@ -231,9 +231,20 @@ * **`lang_prefix`**{ #lang_prefix }: The prefix prepended to the language class assigned to the HTML `<code>` tag. Default: `language-`. - This option only applies when `use_pygments` is `False` as Pygments does not provide an option to include a - language prefix. +* **`pygments_formatter`**{ #pygments_formatter }: + This option can be used to change the Pygments formatter used for highlighting code blocks. By default, this + is set to the string `'html'`, which means it'll use the default `HtmlFormatter` provided by Pygments. + This can be set to a string representing any of the other default formatters, or set to a formatter class (or + any callable). + + The code's language is always passed to the formatter as an extra option `lang_str`, with the value formatted as + `{lang_prefix}{lang}`. If the language is unspecified, the language guessed by Pygments will be used. While + this option has no effect to the Pygments's builtin formatters, a user can make use of the language in their custom + formatter. See an example below. + + To see what formatters are available and how to subclass an existing formatter, please visit Pygments + documentation on this topicpygments formatters. * Any other Pygments' options: @@ -247,6 +258,51 @@ markdown.markdown(some_text, extensions='codehilite') ``` +To keep the code block's language in the Pygments generated HTML output, one can provide a custom Pygments formatter +that takes the `lang_str` option. For example, + +```python +from pygments.formatters import HtmlFormatter +from markdown.extensions.codehilite import CodeHiliteExtension + + +class CustomHtmlFormatter(HtmlFormatter): + def __init__(self, lang_str='', **options): + super().__init__(**options) + # lang_str has the value {lang_prefix}{lang} + # specified by the CodeHilite's options + self.lang_str = lang_str + + def _wrap_code(self, source): + yield 0, f'<code class="{self.lang_str}">' + yield from source + yield 0, '</code>' + + +some_text = '''\ + :::python + print('hellow world') +''' + +markdown.markdown( + some_text, + extensions=CodeHiliteExtension(pygments_formatter=CustomHtmlFormatter), +) +``` + +The formatter above will output the following HTML structure for a code block: + +```html +<div class="codehilite"> + <pre> + <code class="language-python"> + ... + </code> + </pre> +</div> +``` + html formatter: https://pygments.org/docs/formatters/#HtmlFormatter lexer: https://pygments.org/docs/lexers/ spec: https://www.w3.org/TR/html5/text-level-semantics.html#the-code-element +pygments formatters: https://pygments.org/docs/formatters/
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/extensions/footnotes.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/extensions/footnotes.md
Changed
@@ -86,10 +86,14 @@ The text string that links from the footnote definition back to the position in the document. Defaults to `↩`. +* **`SUPERSCRIPT_TEXT`**: + The text string that links from the position in the document to the footnote + definition. Defaults to `{}`, i.e. only the footnote's number. + * **`BACKLINK_TITLE`**: The text string for the `title` HTML attribute of the footnote definition link. - `%d` will be replaced by the footnote number. Defaults to `Jump back to - footnote %d in the text` + The placeholder `{}` will be replaced by the footnote number. Defaults to + `Jump back to footnote {} in the text`. * **`SEPARATOR`**: The text string used to set the footnote separator. Defaults to `:`.
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/extensions/tables.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/extensions/tables.md
Changed
@@ -58,10 +58,30 @@ See Extensions(index.md) for general extension usage. Use `tables` as the name of the extension. -This extension does not accept any special configuration options. +See the Library Reference(../reference.md#extensions) for information about +configuring extensions. + +The following options are provided to change the default behavior: + +* **`use_align_attribute`**: Set to `True` to use `align` instead of an appropriate `style` attribute + + Default: `'False'` + A trivial example: ```python markdown.markdown(some_text, extensions='tables') ``` + +### Examples + +For an example, let us suppose that alignment should be controlled by the legacy `align` +attribute. + +```pycon +>>> from markdown.extensions.tables import TableExtension +>>> html = markdown.markdown(text, +... extensions=TableExtension(use_align_attribute=True) +... ) +```
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/docs/extensions/toc.md -> _service:tar_scm:Markdown-3.4.1.tar.gz/docs/extensions/toc.md
Changed
@@ -151,6 +151,9 @@ * **`title`**: Title to insert in the Table of Contents' `<div>`. Defaults to `None`. +* **`toc_class`**: + CSS class(es) used for the `<div>` containing the Table of Contents. Defaults to `toc`. + * **`anchorlink`**: Set to `True` to cause all headers to link to themselves. Default is `False`.
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/__init__.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/__init__.py
Changed
@@ -19,43 +19,10 @@ License: BSD (see LICENSE.md for details). """ -import sys - -# TODO: Remove this check at some point in the future. -# (also remove flake8's 'ignore E402' comments below) -if sys.version_info0 < 3: # pragma: no cover - raise ImportError('A recent version of Python 3 is required.') - -from .core import Markdown, markdown, markdownFromFile # noqa: E402 -from .util import PY37 # noqa: E402 -from .pep562 import Pep562 # noqa: E402 -from .__meta__ import __version__, __version_info__ # noqa: E402 -import warnings # noqa: E402 +from .core import Markdown, markdown, markdownFromFile +from .__meta__ import __version__, __version_info__ # noqa # For backward compatibility as some extensions expect it... from .extensions import Extension # noqa __all__ = 'Markdown', 'markdown', 'markdownFromFile' - -__deprecated__ = { - "version": ("__version__", __version__), - "version_info": ("__version_info__", __version_info__) -} - - -def __getattr__(name): - """Get attribute.""" - - deprecated = __deprecated__.get(name) - if deprecated: - warnings.warn( - "'{}' is deprecated. Use '{}' instead.".format(name, deprecated0), - category=DeprecationWarning, - stacklevel=(3 if PY37 else 4) - ) - return deprecated1 - raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name)) - - -if not PY37: - Pep562(__name__)
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/__meta__.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/__meta__.py
Changed
@@ -26,7 +26,7 @@ # (1, 2, 0, 'beta', 2) => "1.2b2" # (1, 2, 0, 'rc', 4) => "1.2rc4" # (1, 2, 0, 'final', 0) => "1.2" -__version_info__ = (3, 3, 7, 'final', 0) +__version_info__ = (3, 4, 1, 'final', 0) def _get_version(version_info):
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/blockparser.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/blockparser.py
Changed
@@ -69,12 +69,6 @@ self.state = State() self.md = md - @property - @util.deprecated("Use 'md' instead.") - def markdown(self): - # TODO: remove this later - return self.md - def parseDocument(self, lines): """ Parse a markdown document into an ElementTree.
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/core.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/core.py
Changed
@@ -122,7 +122,7 @@ if isinstance(ext, str): ext = self.build_extension(ext, configs.get(ext, {})) if isinstance(ext, Extension): - ext._extendMarkdown(self) + ext.extendMarkdown(self) logger.debug( 'Successfully loaded extension "%s.%s".' % (ext.__class__.__module__, ext.__class__.__name__) @@ -150,7 +150,7 @@ """ configs = dict(configs) - entry_points = ep for ep in util.INSTALLED_EXTENSIONS if ep.name == ext_name + entry_points = ep for ep in util.get_installed_extensions() if ep.name == ext_name if entry_points: ext = entry_points0.load() return ext(**configs)
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/__init__.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/__init__.py
Changed
@@ -19,7 +19,6 @@ License: BSD (see LICENSE.md for details). """ -import warnings from ..util import parseBoolValue @@ -70,24 +69,6 @@ for key, value in items: self.setConfig(key, value) - def _extendMarkdown(self, *args): - """ Private wrapper around extendMarkdown. """ - md = args0 - try: - self.extendMarkdown(md) - except TypeError as e: - if "missing 1 required positional argument" in str(e): - # Must be a 2.x extension. Pass in a dumby md_globals. - self.extendMarkdown(md, {}) - warnings.warn( - "The 'md_globals' parameter of '{}.{}.extendMarkdown' is " - "deprecated.".format(self.__class__.__module__, self.__class__.__name__), - category=DeprecationWarning, - stacklevel=2 - ) - else: - raise - def extendMarkdown(self, md): """ Add the various processors and patterns to the Markdown Instance. @@ -98,8 +79,6 @@ * md: The Markdown instance. - * md_globals: Global variables in the markdown module namespace. - """ raise NotImplementedError( 'Extension "%s.%s" must define an "extendMarkdown"'
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/codehilite.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/codehilite.py
Changed
@@ -23,6 +23,7 @@ from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer from pygments.formatters import get_formatter_by_name + from pygments.util import ClassNotFound pygments = True except ImportError: # pragma: no cover pygments = False @@ -63,12 +64,14 @@ * use_pygments: Pass code to pygments for code highlighting. If `False`, the code is instead wrapped for highlighting by a JavaScript library. Default: `True`. + * pygments_formatter: The name of a Pygments formatter or a formatter class used for + highlighting the code blocks. Default: `html`. + * linenums: An alias to Pygments `linenos` formatter option. Default: `None`. * css_class: An alias to Pygments `cssclass` formatter option. Default: 'codehilite'. - * lang_prefix: Prefix prepended to the language when `use_pygments` is `False`. - Default: "language-". + * lang_prefix: Prefix prepended to the language. Default: "language-". Other Options: Any other options are accepted and passed on to the lexer and formatter. Therefore, @@ -80,6 +83,10 @@ Formatter options: https://pygments.org/docs/formatters/#HtmlFormatter Lexer Options: https://pygments.org/docs/lexers/ + Additionally, when Pygments is enabled, the code's language is passed to the + formatter as an extra option `lang_str`, whose value being `{lang_prefix}{lang}`. + This option has no effect to the Pygments's builtin formatters. + Advanced Usage: code = CodeHilite( src = some_code, @@ -99,6 +106,7 @@ self.guess_lang = options.pop('guess_lang', True) self.use_pygments = options.pop('use_pygments', True) self.lang_prefix = options.pop('lang_prefix', 'language-') + self.pygments_formatter = options.pop('pygments_formatter', 'html') if 'linenos' not in options: options'linenos' = options.pop('linenums', None) @@ -139,7 +147,17 @@ lexer = get_lexer_by_name('text', **self.options) except ValueError: # pragma: no cover lexer = get_lexer_by_name('text', **self.options) - formatter = get_formatter_by_name('html', **self.options) + if not self.lang: + # Use the guessed lexer's language instead + self.lang = lexer.aliases0 + lang_str = f'{self.lang_prefix}{self.lang}' + if isinstance(self.pygments_formatter, str): + try: + formatter = get_formatter_by_name(self.pygments_formatter, **self.options) + except ClassNotFound: + formatter = get_formatter_by_name('html', **self.options) + else: + formatter = self.pygments_formatter(lang_str=lang_str, **self.options) return highlight(self.src, lexer, formatter) else: # just escape and build markup usable by JS highlighting libs @@ -279,7 +297,11 @@ 'lang_prefix': 'language-', 'Prefix prepended to the language when use_pygments is false. Default: "language-"' - + , + 'pygments_formatter': 'html', + 'Use a specific formatter for Pygments highlighting.' + 'Default: "html"', + , } for key, value in kwargs.items():
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/footnotes.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/footnotes.py
Changed
@@ -47,6 +47,10 @@ "↩", "The text string that links from the footnote " "to the reader's place.", + "SUPERSCRIPT_TEXT": + "{}", + "The text string that links from the reader's place " + "to the footnote.", "BACKLINK_TITLE": "Jump back to footnote %d in the text", "The text string used for the title HTML attribute " @@ -170,6 +174,9 @@ ol = etree.SubElement(div, "ol") surrogate_parent = etree.Element("div") + # Backward compatibility with old '%d' placeholder + backlink_title = self.getConfig("BACKLINK_TITLE").replace("%d", "{}") + for index, id in enumerate(self.footnotes.keys(), start=1): li = etree.SubElement(ol, "li") li.set("id", self.makeFootnoteId(id)) @@ -185,7 +192,7 @@ backlink.set("class", "footnote-backref") backlink.set( "title", - self.getConfig("BACKLINK_TITLE") % (index) + backlink_title.format(index) ) backlink.text = FN_BACKLINK_TEXT @@ -303,7 +310,9 @@ sup.set('id', self.footnotes.makeFootnoteRefId(id, found=True)) a.set('href', '#' + self.footnotes.makeFootnoteId(id)) a.set('class', 'footnote-ref') - a.text = str(list(self.footnotes.footnotes.keys()).index(id) + 1) + a.text = self.footnotes.getConfig("SUPERSCRIPT_TEXT").format( + list(self.footnotes.footnotes.keys()).index(id) + 1 + ) return sup, m.start(0), m.end(0) else: return None, None, None
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/smarty.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/smarty.py
Changed
@@ -83,7 +83,7 @@ from . import Extension from ..inlinepatterns import HtmlInlineProcessor, HTML_RE from ..treeprocessors import InlineProcessor -from ..util import Registry, deprecated +from ..util import Registry # Constants for quote education. @@ -155,12 +155,6 @@ self.replace = replace self.md = md - @property - @deprecated("Use 'md' instead.") - def markdown(self): - # TODO: remove this later - return self.md - def handleMatch(self, m, data): result = '' for part in self.replace:
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/tables.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/tables.py
Changed
@@ -30,9 +30,11 @@ RE_CODE_PIPES = re.compile(r'(?:(\\\\)|(\\`+)|(`+)|(\\\|)|(\|))') RE_END_BORDER = re.compile(r'(?<!\\)(?:\\\\)*\|$') - def __init__(self, parser): + def __init__(self, parser, config): self.border = False self.separator = '' + self.config = config + super().__init__(parser) def test(self, parent, block): @@ -126,7 +128,10 @@ except IndexError: # pragma: no cover c.text = "" if a: - c.set('align', a) + if self.config'use_align_attribute': + c.set('align', a) + else: + c.set('style', f'text-align: {a};') def _split_row(self, row): """ split a row of text into list of cells. """ @@ -212,11 +217,19 @@ class TableExtension(Extension): """ Add tables to Markdown. """ + def __init__(self, **kwargs): + self.config = { + 'use_align_attribute': False, 'True to use align attribute instead of style.', + } + + super().__init__(**kwargs) + def extendMarkdown(self, md): """ Add an instance of TableProcessor to BlockParser. """ if '|' not in md.ESCAPED_CHARS: md.ESCAPED_CHARS.append('|') - md.parser.blockprocessors.register(TableProcessor(md.parser), 'table', 75) + processor = TableProcessor(md.parser, self.getConfigs()) + md.parser.blockprocessors.register(processor, 'table', 75) def makeExtension(**kwargs): # pragma: no cover
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/extensions/toc.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/extensions/toc.py
Changed
@@ -16,7 +16,7 @@ from . import Extension from ..treeprocessors import Treeprocessor from ..util import code_escape, parseBoolValue, AMP_SUBSTITUTE, HTML_PLACEHOLDER_RE, AtomicString -from ..postprocessors import UnescapePostprocessor +from ..treeprocessors import UnescapeTreeprocessor import re import html import unicodedata @@ -84,8 +84,8 @@ def unescape(text): """ Unescape escaped text. """ - c = UnescapePostprocessor() - return c.run(text) + c = UnescapeTreeprocessor() + return c.unescape(text) def nest_toc_tokens(toc_list): @@ -160,6 +160,7 @@ self.base_level = int(config"baselevel") - 1 self.slugify = config"slugify" self.sep = config"separator" + self.toc_class = config"toc_class" self.use_anchors = parseBoolValue(config"anchorlink") self.anchorlink_class = config"anchorlink_class" self.use_permalinks = parseBoolValue(config"permalink", False) @@ -239,7 +240,7 @@ def build_toc_div(self, toc_list): """ Return a string div given a toc list. """ div = etree.Element("div") - div.attrib"class" = "toc" + div.attrib"class" = self.toc_class # Add title to the div if self.title: @@ -288,10 +289,10 @@ toc_tokens.append({ 'level': int(el.tag-1), 'id': el.attrib"id", - 'name': unescape(stashedHTML2text( + 'name': stashedHTML2text( code_escape(el.attrib.get('data-toc-label', text)), self.md, strip_entities=False - )) + ) }) # Remove the data-toc-label attribute as it is no longer needed @@ -328,6 +329,9 @@ "title": "", "Title to insert into TOC <div> - " "Defaults to an empty string", + "toc_class": 'toc', + 'CSS class(es) used for the link. ' + 'Defaults to "toclink"', "anchorlink": False, "True if header should be a self link - " "Defaults to False",
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/htmlparser.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/htmlparser.py
Changed
@@ -20,7 +20,7 @@ """ import re -import importlib +import importlib.util import sys
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/inlinepatterns.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/inlinepatterns.py
Changed
@@ -211,12 +211,6 @@ self.md = md - @property - @util.deprecated("Use 'md' instead.") - def markdown(self): - # TODO: remove this later - return self.md - def getCompiledRegExp(self): """ Return a compiled regular expression. """ return self.compiled_re
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/postprocessors.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/postprocessors.py
Changed
@@ -37,7 +37,6 @@ postprocessors = util.Registry() postprocessors.register(RawHtmlPostprocessor(md), 'raw_html', 30) postprocessors.register(AndSubstitutePostprocessor(), 'amp_substitute', 20) - postprocessors.register(UnescapePostprocessor(), 'unescape', 10) return postprocessors @@ -122,6 +121,10 @@ return text +@util.deprecated( + "This class will be removed in the future; " + "use 'treeprocessors.UnescapeTreeprocessor' instead." +) class UnescapePostprocessor(Postprocessor): """ Restore escaped chars """
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/treeprocessors.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/treeprocessors.py
Changed
@@ -19,6 +19,7 @@ License: BSD (see LICENSE.md for details). """ +import re import xml.etree.ElementTree as etree from . import util from . import inlinepatterns @@ -29,6 +30,7 @@ treeprocessors = util.Registry() treeprocessors.register(InlineProcessor(md), 'inline', 20) treeprocessors.register(PrettifyTreeprocessor(md), 'prettify', 10) + treeprocessors.register(UnescapeTreeprocessor(md), 'unescape', 0) return treeprocessors @@ -75,12 +77,6 @@ self.inlinePatterns = md.inlinePatterns self.ancestors = - @property - @util.deprecated("Use 'md' instead.") - def markdown(self): - # TODO: remove this later - return self.md - def __makePlaceholder(self, type): """ Generate a placeholder """ id = "%04d" % len(self.stashed_nodes) @@ -412,8 +408,6 @@ for e in elem: if self.md.is_block_level(e.tag): self._prettifyETree(e) - if not elem.tail or not elem.tail.strip(): - elem.tail = i if not elem.tail or not elem.tail.strip(): elem.tail = i @@ -433,4 +427,32 @@ pres = root.iter('pre') for pre in pres: if len(pre) and pre0.tag == 'code': - pre0.text = util.AtomicString(pre0.text.rstrip() + '\n') + code = pre0 + # Only prettify code containing text only + if not len(code) and code.text is not None: + code.text = util.AtomicString(code.text.rstrip() + '\n') + + +class UnescapeTreeprocessor(Treeprocessor): + """ Restore escaped chars """ + + RE = re.compile(r'{}(\d+){}'.format(util.STX, util.ETX)) + + def _unescape(self, m): + return chr(int(m.group(1))) + + def unescape(self, text): + return self.RE.sub(self._unescape, text) + + def run(self, root): + """ Loop over all elements and unescape all text. """ + for elem in root.iter(): + # Unescape text content + if elem.text and not elem.tag == 'code': + elem.text = self.unescape(elem.text) + # Unescape tail content + if elem.tail: + elem.tail = self.unescape(elem.tail) + # Unescape attribute values + for key, value in elem.items(): + elem.set(key, self.unescape(value))
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/markdown/util.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/markdown/util.py
Changed
@@ -22,31 +22,10 @@ import re import sys import warnings -import xml.etree.ElementTree from collections import namedtuple -from functools import wraps +from functools import wraps, lru_cache from itertools import count -from .pep562 import Pep562 - -if sys.version_info >= (3, 10): - from importlib import metadata -else: - # <PY310 use backport - import importlib_metadata as metadata - -PY37 = (3, 7) <= sys.version_info - - -# TODO: Remove deprecated variables in a future release. -__deprecated__ = { - 'etree': ('xml.etree.ElementTree', xml.etree.ElementTree), - 'string_type': ('str', str), - 'text_type': ('str', str), - 'int2str': ('chr', chr), - 'iterrange': ('range', range) -} - """ Constants you might want to modify @@ -84,8 +63,6 @@ ----------------------------------------------------------------------------- """ -# Only load extension entry_points once. -INSTALLED_EXTENSIONS = metadata.entry_points(group='markdown.extensions') RTL_BIDI_RANGES = ( ('\u0590', '\u07FF'), # Hebrew (0590-05FF), Arabic (0600-06FF), @@ -101,6 +78,16 @@ """ +@lru_cache(maxsize=None) +def get_installed_extensions(): + if sys.version_info >= (3, 10): + from importlib import metadata + else: # <PY310 use backport + import importlib_metadata as metadata + # Only load extension entry_points once. + return metadata.entry_points(group='markdown.extensions') + + def deprecated(message, stacklevel=2): """ Raise a DeprecationWarning when wrapped function/method is called. @@ -123,15 +110,6 @@ return wrapper -@deprecated("Use 'Markdown.is_block_level' instead.") -def isBlockLevel(tag): - """Check if the tag is a block level HTML tag.""" - if isinstance(tag, str): - return tag.lower().rstrip('/') in BLOCK_LEVEL_ELEMENTS - # Some ElementTree tags are not strings, so return False. - return False - - def parseBoolValue(value, fail_on_errors=True, preserve_none=False): """Parses a string representing bool value. If parsing was successful, returns True or False. If preserve_none=True, returns True, False, @@ -193,12 +171,6 @@ def __init__(self, md=None): self.md = md - @property - @deprecated("Use 'md' instead.") - def markdown(self): - # TODO: remove this later - return self.md - class HtmlStash: """ @@ -384,102 +356,3 @@ if not self._is_sorted: self._priority.sort(key=lambda item: item.priority, reverse=True) self._is_sorted = True - - # Deprecated Methods which provide a smooth transition from OrderedDict - - def __setitem__(self, key, value): - """ Register item with priority 5 less than lowest existing priority. """ - if isinstance(key, str): - warnings.warn( - 'Using setitem to register a processor or pattern is deprecated. ' - 'Use the `register` method instead.', - DeprecationWarning, - stacklevel=2, - ) - if key in self: - # Key already exists, replace without altering priority - self._datakey = value - return - if len(self) == 0: - # This is the first item. Set priority to 50. - priority = 50 - else: - self._sort() - priority = self._priority-1.priority - 5 - self.register(value, key, priority) - else: - raise TypeError - - def __delitem__(self, key): - """ Deregister an item by name. """ - if key in self: - self.deregister(key) - warnings.warn( - 'Using del to remove a processor or pattern is deprecated. ' - 'Use the `deregister` method instead.', - DeprecationWarning, - stacklevel=2, - ) - else: - raise KeyError('Cannot delete key {}, not registered.'.format(key)) - - def add(self, key, value, location): - """ Register a key by location. """ - if len(self) == 0: - # This is the first item. Set priority to 50. - priority = 50 - elif location == '_begin': - self._sort() - # Set priority 5 greater than highest existing priority - priority = self._priority0.priority + 5 - elif location == '_end': - self._sort() - # Set priority 5 less than lowest existing priority - priority = self._priority-1.priority - 5 - elif location.startswith('<') or location.startswith('>'): - # Set priority halfway between existing priorities. - i = self.get_index_for_name(location1:) - if location.startswith('<'): - after = self._priorityi.priority - if i > 0: - before = self._priorityi-1.priority - else: - # Location is first item` - before = after + 10 - else: - # location.startswith('>') - before = self._priorityi.priority - if i < len(self) - 1: - after = self._priorityi+1.priority - else: - # location is last item - after = before - 10 - priority = before - ((before - after) / 2) - else: - raise ValueError('Not a valid location: "%s". Location key ' - 'must start with a ">" or "<".' % location) - self.register(value, key, priority) - warnings.warn( - 'Using the add method to register a processor or pattern is deprecated. ' - 'Use the `register` method instead.', - DeprecationWarning, - stacklevel=2, - ) - - -def __getattr__(name): - """Get attribute.""" - - deprecated = __deprecated__.get(name) - if deprecated: - warnings.warn( - "'{}' is deprecated. Use '{}' instead.".format(name, deprecated0), - category=DeprecationWarning, - stacklevel=(3 if PY37 else 4) - ) - return deprecated1 - raise AttributeError("module '{}' has no attribute '{}'".format(__name__, name)) - - -if not PY37: - Pep562(__name__)
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/mkdocs.yml -> _service:tar_scm:Markdown-3.4.1.tar.gz/mkdocs.yml
Changed
@@ -41,6 +41,7 @@ - Test Tools: test_tools.md - Contributing to Python-Markdown: contributing.md - Change Log: change_log/index.md + - Release Notes for v.3.4: change_log/release-3.4.md - Release Notes for v.3.3: change_log/release-3.3.md - Release Notes for v.3.2: change_log/release-3.2.md - Release Notes for v.3.1: change_log/release-3.1.md
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/setup.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/setup.py
Changed
@@ -73,7 +73,7 @@ maintainer_email='python.markdown@gmail.com', license='BSD License', packages='markdown', 'markdown.extensions', - python_requires='>=3.6', + python_requires='>=3.7', install_requires="importlib-metadata>=4.4;python_version<'3.10'", extras_require={ 'testing': @@ -113,7 +113,6 @@ 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9',
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/basic/backlash-escapes.html -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/basic/backlash-escapes.html
Changed
@@ -9,7 +9,7 @@ <p>Right bracket: </p> <p>Left paren: (</p> <p>Right paren: )</p> -<p>Greater-than: ></p> +<p>Greater-than: ></p> <p>Hash: #</p> <p>Period: .</p> <p>Bang: !</p>
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/basic/markdown-documentation-basics.html -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/basic/markdown-documentation-basics.html
Changed
@@ -211,7 +211,7 @@ <pre><code>I strongly recommend against using any `<blink>` tags. I wish SmartyPants used named entities like `&mdash;` -instead of decimal-encoded entites like `&#8212;`. +instead of decimal-encoded entities like `&#8212;`. </code></pre> <p>Output:</p> <pre><code><p>I strongly recommend against using any @@ -219,7 +219,7 @@ <p>I wish SmartyPants used named entities like <code>&amp;mdash;</code> instead of decimal-encoded -entites like <code>&amp;#8212;</code>.</p> +entities like <code>&amp;#8212;</code>.</p> </code></pre> <p>To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>,
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/basic/markdown-documentation-basics.txt -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/basic/markdown-documentation-basics.txt
Changed
@@ -270,7 +270,7 @@ I strongly recommend against using any `<blink>` tags. I wish SmartyPants used named entities like `—` - instead of decimal-encoded entites like `—`. + instead of decimal-encoded entities like `—`. Output: @@ -279,7 +279,7 @@ <p>I wish SmartyPants used named entities like <code>&mdash;</code> instead of decimal-encoded - entites like <code>&#8212;</code>.</p> + entities like <code>&#8212;</code>.</p> To specify an entire block of pre-formatted code, indent every line of
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_apis.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_apis.py
Changed
@@ -316,50 +316,16 @@ r = markdown.util.Registry() with self.assertRaises(TypeError): r0 = 'a' - # TODO: restore this when deprecated __setitem__ is removed. - # with self.assertRaises(TypeError): - # r'a' = 'a' - # TODO: remove this when deprecated __setitem__ is removed. - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - - r'a' = Item('a') - self.assertEqual(list(r), 'a') - r'b' = Item('b') - self.assertEqual(list(r), 'a', 'b') - r'a' = Item('a1') - self.assertEqual(list(r), 'a1', 'b') - - # Check the warnings - self.assertEqual(len(w), 3) - self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w)) + with self.assertRaises(TypeError): + r'a' = 'a' def testRegistryDelItem(self): r = markdown.util.Registry() r.register(Item('a'), 'a', 20) - with self.assertRaises(KeyError): + with self.assertRaises(TypeError): del r0 - # TODO: restore this when deprecated __del__ is removed. - # with self.assertRaises(TypeError): - # del r'a' - # TODO: remove this when deprecated __del__ is removed. - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - - r.register(Item('b'), 'b', 15) - r.register(Item('c'), 'c', 10) - del r'b' - self.assertEqual(list(r), 'a', 'c') + with self.assertRaises(TypeError): del r'a' - self.assertEqual(list(r), 'c') - with self.assertRaises(KeyError): - del r'badname' - del r'c' - self.assertEqual(list(r), ) - - # Check the warnings - self.assertEqual(len(w), 3) - self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w)) def testRegistrySlice(self): r = markdown.util.Registry() @@ -390,39 +356,6 @@ self.assertEqual(len(r), 2) self.assertEqual(list(r), 'b2', 'a') - def testRegistryDeprecatedAdd(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - - r = markdown.util.Registry() - # Add first item - r.add('c', Item('c'), '_begin') - self.assertEqual(list(r), 'c') - # Added to beginning - r.add('b', Item('b'), '_begin') - self.assertEqual(list(r), 'b', 'c') - # Add before first item - r.add('a', Item('a'), '<b') - self.assertEqual(list(r), 'a', 'b', 'c') - # Add before non-first item - r.add('a1', Item('a1'), '<b') - self.assertEqual(list(r), 'a', 'a1', 'b', 'c') - # Add after non-last item - r.add('b1', Item('b1'), '>b') - self.assertEqual(list(r), 'a', 'a1', 'b', 'b1', 'c') - # Add after last item - r.add('d', Item('d'), '>c') - self.assertEqual(list(r), 'a', 'a1', 'b', 'b1', 'c', 'd') - # Add to end - r.add('e', Item('e'), '_end') - self.assertEqual(list(r), 'a', 'a1', 'b', 'b1', 'c', 'd', 'e') - with self.assertRaises(ValueError): - r.add('f', Item('f'), 'badlocation') - - # Check the warnings - self.assertEqual(len(w), 7) - self.assertTrue(all(issubclass(x.category, DeprecationWarning) for x in w)) - class TestErrors(unittest.TestCase): """ Test Error Reporting. """ @@ -525,6 +458,43 @@ self.assertEqual(br.tail, "\n") +class testElementPreCodeTests(unittest.TestCase): + """ Element PreCode Tests """ + def setUp(self): + md = markdown.Markdown() + self.pretty = markdown.treeprocessors.PrettifyTreeprocessor(md) + + def prettify(self, xml): + root = etree.fromstring(xml) + self.pretty.run(root) + return etree.tostring(root, encoding="unicode", short_empty_elements=False) + + def testPreCodeEmpty(self): + xml = "<pre><code></code></pre>" + expected = "<pre><code></code></pre>\n" + self.assertEqual(expected, self.prettify(xml)) + + def testPreCodeWithChildren(self): + xml = "<pre><code> <span /></code></pre>" + expected = "<pre><code> <span></span></code></pre>\n" + self.assertEqual(expected, self.prettify(xml)) + + def testPreCodeWithSpaceOnly(self): + xml = "<pre><code> </code></pre>" + expected = "<pre><code>\n</code></pre>\n" + self.assertEqual(expected, self.prettify(xml)) + + def testPreCodeWithText(self): + xml = "<pre><code> hello</code></pre>" + expected = "<pre><code> hello\n</code></pre>\n" + self.assertEqual(expected, self.prettify(xml)) + + def testPreCodeWithTrailingSpace(self): + xml = "<pre><code> hello </code></pre>" + expected = "<pre><code> hello\n</code></pre>\n" + self.assertEqual(expected, self.prettify(xml)) + + class testSerializers(unittest.TestCase): """ Test the html and xhtml serializers. """ @@ -985,42 +955,3 @@ self.md.reset() self.assertEqual(self.md.convert(test), result) - - -class TestGeneralDeprecations(unittest.TestCase): - """Test general deprecations.""" - - def test_version_deprecation(self): - """Test that version is deprecated.""" - - with warnings.catch_warnings(record=True) as w: - # Cause all warnings to always be triggered. - warnings.simplefilter("always") - # Trigger a warning. - version = markdown.version - # Verify some things - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w-1.category, DeprecationWarning)) - self.assertEqual(version, markdown.__version__) - - def test_version_info_deprecation(self): - """Test that version info is deprecated.""" - - with warnings.catch_warnings(record=True) as w: - # Cause all warnings to always be triggered. - warnings.simplefilter("always") - # Trigger a warning. - version_info = markdown.version_info - # Verify some things - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w-1.category, DeprecationWarning)) - self.assertEqual(version_info, markdown.__version_info__) - - def test_deprecation_wrapper_dir(self): - """Tests the `__dir__` attribute of the class as it replaces the module's.""" - - dir_attr = dir(markdown) - self.assertNotIn('version', dir_attr) - self.assertIn('__version__', dir_attr) - self.assertNotIn('version_info', dir_attr) - self.assertIn('__version_info__', dir_attr)
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_legacy.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_legacy.py
Changed
@@ -182,8 +182,6 @@ footnotes = Kwargs(extensions='footnotes') - tables = Kwargs(extensions='tables') - extra_config = Kwargs( extensions='extra', extension_configs={
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_syntax/extensions/test_code_hilite.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_code_hilite.py
Changed
@@ -354,6 +354,22 @@ if has_pygments and pygments.__version__ != required_pygments_version: self.skipTest(f'Pygments=={required_pygments_version} is required') + # Define a custom Pygments formatter (same example in the documentation) + if has_pygments: + class CustomAddLangHtmlFormatter(pygments.formatters.HtmlFormatter): + def __init__(self, lang_str='', **options): + super().__init__(**options) + self.lang_str = lang_str + + def _wrap_code(self, source): + yield 0, f'<code class="{self.lang_str}">' + yield from source + yield 0, '</code>' + else: + CustomAddLangHtmlFormatter = None + + self.custom_pygments_formatter = CustomAddLangHtmlFormatter + maxDiff = None def testBasicCodeHilite(self): @@ -676,3 +692,73 @@ expected, extensions=CodeHiliteExtension(pygments_style="native", noclasses=True) ) + + def testFormatterLangStr(self): + if has_pygments: + expected = ( + '<div class="codehilite"><pre><span></span><code class="language-python">' + '<span class="c1"># A Code Comment</span>\n' + '</code></pre></div>' + ) + else: + expected = ( + '<pre class="codehilite"><code class="language-python"># A Code Comment\n' + '</code></pre>' + ) + + self.assertMarkdownRenders( + '\t:::Python\n' + '\t# A Code Comment', + expected, + extensions= + CodeHiliteExtension( + guess_lang=False, + pygments_formatter=self.custom_pygments_formatter + ) + + ) + + def testFormatterLangStrGuessLang(self): + if has_pygments: + expected = ( + '<div class="codehilite"><pre><span></span>' + '<code class="language-js+php"><span class="cp"><?php</span> ' + '<span class="k">print</span><span class="p">(</span>' + '<span class="s2">"Hello World"</span>' + '<span class="p">);</span> <span class="cp">?></span>\n' + '</code></pre></div>' + ) + else: + expected = ( + '<pre class="codehilite"><code><?php print("Hello World"); ?>\n' + '</code></pre>' + ) + # Use PHP as the the starting `<?php` tag ensures an accurate guess. + self.assertMarkdownRenders( + '\t<?php print("Hello World"); ?>', + expected, + extensions=CodeHiliteExtension(pygments_formatter=self.custom_pygments_formatter) + ) + + def testFormatterLangStrEmptyLang(self): + if has_pygments: + expected = ( + '<div class="codehilite"><pre><span></span>' + '<code class="language-text"># A Code Comment\n' + '</code></pre></div>' + ) + else: + expected = ( + '<pre class="codehilite"><code># A Code Comment\n' + '</code></pre>' + ) + self.assertMarkdownRenders( + '\t# A Code Comment', + expected, + extensions= + CodeHiliteExtension( + guess_lang=False, + pygments_formatter=self.custom_pygments_formatter, + ) + + )
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_syntax/extensions/test_fenced_code.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_fenced_code.py
Changed
@@ -21,10 +21,12 @@ from markdown.test_tools import TestCase import markdown +import markdown.extensions.codehilite import os try: import pygments # noqa + import pygments.formatters # noqa has_pygments = True except ImportError: has_pygments = False @@ -800,7 +802,7 @@ extensions='codehilite', 'fenced_code' ) - def testFencedMultpleBlocksSameStyle(self): + def testFencedMultipleBlocksSameStyle(self): if has_pygments: # See also: https://github.com/Python-Markdown/markdown/issues/1240 expected = ( @@ -844,3 +846,175 @@ 'fenced_code' ) + + def testCustomPygmentsFormatter(self): + if has_pygments: + class CustomFormatter(pygments.formatters.HtmlFormatter): + def wrap(self, source, outfile): + return self._wrap_div(self._wrap_code(source)) + + def _wrap_code(self, source): + yield 0, '<code>' + for i, t in source: + if i == 1: + t += '<br>' + yield i, t + yield 0, '</code>' + + expected = ''' + <div class="codehilite"><code>hello world + <br>hello another world + <br></code></div> + ''' + + else: + CustomFormatter = None + expected = ''' + <pre class="codehilite"><code>hello world + hello another world + </code></pre> + ''' + + self.assertMarkdownRenders( + self.dedent( + ''' + ``` + hello world + hello another world + ``` + ''' + ), + self.dedent( + expected + ), + extensions= + markdown.extensions.codehilite.CodeHiliteExtension( + pygments_formatter=CustomFormatter, + guess_lang=False, + ), + 'fenced_code' + + ) + + def testPygmentsAddLangClassFormatter(self): + if has_pygments: + class CustomAddLangHtmlFormatter(pygments.formatters.HtmlFormatter): + def __init__(self, lang_str='', **options): + super().__init__(**options) + self.lang_str = lang_str + + def _wrap_code(self, source): + yield 0, f'<code class="{self.lang_str}">' + yield from source + yield 0, '</code>' + + expected = ''' + <div class="codehilite"><pre><span></span><code class="language-text">hello world + hello another world + </code></pre></div> + ''' + else: + CustomAddLangHtmlFormatter = None + expected = ''' + <pre class="codehilite"><code class="language-text">hello world + hello another world + </code></pre> + ''' + + self.assertMarkdownRenders( + self.dedent( + ''' + ```text + hello world + hello another world + ``` + ''' + ), + self.dedent( + expected + ), + extensions= + markdown.extensions.codehilite.CodeHiliteExtension( + guess_lang=False, + pygments_formatter=CustomAddLangHtmlFormatter, + ), + 'fenced_code' + + ) + + def testSvgCustomPygmentsFormatter(self): + if has_pygments: + expected = ''' + <?xml version="1.0"?> + <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> + <svg xmlns="http://www.w3.org/2000/svg"> + <g font-family="monospace" font-size="14px"> + <text x="0" y="14" xml:space="preserve">hello world</text> + <text x="0" y="33" xml:space="preserve">hello another world</text> + <text x="0" y="52" xml:space="preserve"></text></g></svg> + ''' + + else: + expected = ''' + <pre class="codehilite"><code>hello world + hello another world + </code></pre> + ''' + + self.assertMarkdownRenders( + self.dedent( + ''' + ``` + hello world + hello another world + ``` + ''' + ), + self.dedent( + expected + ), + extensions= + markdown.extensions.codehilite.CodeHiliteExtension( + pygments_formatter='svg', + linenos=False, + guess_lang=False, + ), + 'fenced_code' + + ) + + def testInvalidCustomPygmentsFormatter(self): + if has_pygments: + expected = ''' + <div class="codehilite"><pre><span></span><code>hello world + hello another world + </code></pre></div> + ''' + + else: + expected = ''' + <pre class="codehilite"><code>hello world + hello another world + </code></pre> + ''' + + self.assertMarkdownRenders( + self.dedent( + ''' + ``` + hello world + hello another world + ``` + ''' + ), + self.dedent( + expected + ), + extensions= + markdown.extensions.codehilite.CodeHiliteExtension( + pygments_formatter='invalid', + guess_lang=False, + ), + 'fenced_code' + + )
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_syntax/extensions/test_footnotes.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_footnotes.py
Changed
@@ -300,3 +300,39 @@ '</div>', extension_configs={'footnotes': {'SEPARATOR': '-'}} ) + + def test_backlink_title(self): + """Test backlink title configuration without placeholder.""" + + self.assertMarkdownRenders( + 'paragraph^1\n\n^1: A Footnote', + '<p>paragraph<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></p>\n' + '<div class="footnote">\n' + '<hr />\n' + '<ol>\n' + '<li id="fn:1">\n' + '<p>A Footnote <a class="footnote-backref" href="#fnref:1"' + ' title="Jump back to footnote">↩</a></p>\n' + '</li>\n' + '</ol>\n' + '</div>', + extension_configs={'footnotes': {'BACKLINK_TITLE': 'Jump back to footnote'}} + ) + + def test_superscript_text(self): + """Test superscript text configuration.""" + + self.assertMarkdownRenders( + 'paragraph^1\n\n^1: A Footnote', + '<p>paragraph<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></p>\n' + '<div class="footnote">\n' + '<hr />\n' + '<ol>\n' + '<li id="fn:1">\n' + '<p>A Footnote <a class="footnote-backref" href="#fnref:1"' + ' title="Jump back to footnote 1 in the text">↩</a></p>\n' + '</li>\n' + '</ol>\n' + '</div>', + extension_configs={'footnotes': {'SUPERSCRIPT_TEXT': '{}'}} + )
View file
_service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_smarty.py
Added
@@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +Python Markdown + +A Python implementation of John Gruber's Markdown. + +Documentation: https://python-markdown.github.io/ +GitHub: https://github.com/Python-Markdown/markdown/ +PyPI: https://pypi.org/project/Markdown/ + +Started by Manfred Stienstra (http://www.dwerg.net/). +Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +Currently maintained by Waylan Limberg (https://github.com/waylan), +Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +Copyright 2007-2022 The Python Markdown Project (v. 1.7 and later) +Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +Copyright 2004 Manfred Stienstra (the original version) + +License: BSD (see LICENSE.md for details). +""" + +from markdown.test_tools import TestCase + + +class TestSmarty(TestCase): + + default_kwargs = {'extensions': 'smarty'} + + def test_escaped_attr(self): + self.assertMarkdownRenders( + '!x\"x(x)', + '<p><img alt="x"x" src="x" /></p>' + ) + + # TODO: Move rest of smarty tests here.
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_syntax/extensions/test_tables.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_tables.py
Changed
@@ -20,6 +20,7 @@ """ from markdown.test_tools import TestCase +from markdown.extensions.tables import TableExtension class TestTableBlocks(TestCase): @@ -60,3 +61,862 @@ ), extensions='tables' ) + + def test_no_sides(self): + self.assertMarkdownRenders( + self.dedent( + """ + First Header | Second Header + ------------- | ------------- + Content Cell | Content Cell + Content Cell | Content Cell + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th>First Header</th> + <th>Second Header</th> + </tr> + </thead> + <tbody> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_both_sides(self): + self.assertMarkdownRenders( + self.dedent( + """ + | First Header | Second Header | + | ------------- | ------------- | + | Content Cell | Content Cell | + | Content Cell | Content Cell | + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th>First Header</th> + <th>Second Header</th> + </tr> + </thead> + <tbody> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_align_columns(self): + self.assertMarkdownRenders( + self.dedent( + """ + | Item | Value | + | :-------- | -----:| + | Computer | $1600 | + | Phone | $12 | + | Pipe | $1 | + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th style="text-align: left;">Item</th> + <th style="text-align: right;">Value</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left;">Computer</td> + <td style="text-align: right;">$1600</td> + </tr> + <tr> + <td style="text-align: left;">Phone</td> + <td style="text-align: right;">$12</td> + </tr> + <tr> + <td style="text-align: left;">Pipe</td> + <td style="text-align: right;">$1</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_styles_in_tables(self): + self.assertMarkdownRenders( + self.dedent( + """ + | Function name | Description | + | ------------- | ------------------------------ | + | `help()` | Display the help window. | + | `destroy()` | **Destroy your computer!** | + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th>Function name</th> + <th>Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>help()</code></td> + <td>Display the help window.</td> + </tr> + <tr> + <td><code>destroy()</code></td> + <td><strong>Destroy your computer!</strong></td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_align_three(self): + self.assertMarkdownRenders( + self.dedent( + """ + |foo|bar|baz| + |:--|:-:|--:| + | | Q | | + |W | | W| + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th style="text-align: left;">foo</th> + <th style="text-align: center;">bar</th> + <th style="text-align: right;">baz</th> + </tr> + </thead> + <tbody> + <tr> + <td style="text-align: left;"></td> + <td style="text-align: center;">Q</td> + <td style="text-align: right;"></td> + </tr> + <tr> + <td style="text-align: left;">W</td> + <td style="text-align: center;"></td> + <td style="text-align: right;">W</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_three_columns(self): + self.assertMarkdownRenders( + self.dedent( + """ + foo|bar|baz + ---|---|--- + | Q | + W | | W + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th>foo</th> + <th>bar</th> + <th>baz</th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + <td>Q</td> + <td></td> + </tr> + <tr> + <td>W</td> + <td></td> + <td>W</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_three_spaces_prefix(self): + self.assertMarkdownRenders( + self.dedent( + """ + Three spaces in front of a table: + + First Header | Second Header + ------------ | ------------- + Content Cell | Content Cell + Content Cell | Content Cell + + | First Header | Second Header | + | ------------ | ------------- | + | Content Cell | Content Cell | + | Content Cell | Content Cell | + """), + self.dedent( + """ + <p>Three spaces in front of a table:</p> + <table> + <thead> + <tr> + <th>First Header</th> + <th>Second Header</th> + </tr> + </thead> + <tbody> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>First Header</th> + <th>Second Header</th> + </tr> + </thead> + <tbody> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + <tr> + <td>Content Cell</td> + <td>Content Cell</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_code_block_table(self): + self.assertMarkdownRenders( + self.dedent( + """ + Four spaces is a code block: + + First Header | Second Header + ------------ | ------------- + Content Cell | Content Cell + Content Cell | Content Cell + + | First Header | Second Header | + | ------------ | ------------- | + """), + self.dedent( + """ + <p>Four spaces is a code block:</p> + <pre><code>First Header | Second Header + ------------ | ------------- + Content Cell | Content Cell + Content Cell | Content Cell + </code></pre> + <table> + <thead> + <tr> + <th>First Header</th> + <th>Second Header</th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + <td></td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_inline_code_blocks(self): + self.assertMarkdownRenders( + self.dedent( + """ + More inline code block tests + + Column 1 | Column 2 | Column 3 + ---------|----------|--------- + word 1 | word 2 | word 3 + word 1 | `word 2` | word 3 + word 1 | \\`word 2 | word 3 + word 1 | `word 2 | word 3 + word 1 | `word |2` | word 3 + words |`` some | code `` | more words + words |``` some | code ``` | more words + words |```` some | code ```` | more words + words |`` some ` | ` code `` | more words + words |``` some ` | ` code ``` | more words + words |```` some ` | ` code ```` | more words + """), + self.dedent( + """ + <p>More inline code block tests</p> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + <th>Column 3</th> + </tr> + </thead> + <tbody> + <tr> + <td>word 1</td> + <td>word 2</td> + <td>word 3</td> + </tr> + <tr> + <td>word 1</td> + <td><code>word 2</code></td> + <td>word 3</td> + </tr> + <tr> + <td>word 1</td> + <td>`word 2</td> + <td>word 3</td> + </tr> + <tr> + <td>word 1</td> + <td>`word 2</td> + <td>word 3</td> + </tr> + <tr> + <td>word 1</td> + <td><code>word |2</code></td> + <td>word 3</td> + </tr> + <tr> + <td>words</td> + <td><code>some | code</code></td> + <td>more words</td> + </tr> + <tr> + <td>words</td> + <td><code>some | code</code></td> + <td>more words</td> + </tr> + <tr> + <td>words</td> + <td><code>some | code</code></td> + <td>more words</td> + </tr> + <tr> + <td>words</td> + <td><code>some ` | ` code</code></td> + <td>more words</td> + </tr> + <tr> + <td>words</td> + <td><code>some ` | ` code</code></td> + <td>more words</td> + </tr> + <tr> + <td>words</td> + <td><code>some ` | ` code</code></td> + <td>more words</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_issue_440(self): + self.assertMarkdownRenders( + self.dedent( + """ + A test for issue #440: + + foo | bar + --- | --- + foo | (`bar`) and `baz`. + """), + self.dedent( + """ + <p>A test for issue #440:</p> + <table> + <thead> + <tr> + <th>foo</th> + <th>bar</th> + </tr> + </thead> + <tbody> + <tr> + <td>foo</td> + <td>(<code>bar</code>) and <code>baz</code>.</td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_lists_not_tables(self): + self.assertMarkdownRenders( + self.dedent( + """ + Lists are not tables + + - this | should | not + - be | a | table + """), + self.dedent( + """ + <p>Lists are not tables</p> + <ul> + <li>this | should | not</li> + <li>be | a | table</li> + </ul> + """ + ), + extensions='tables' + ) + + def test_issue_449(self): + self.assertMarkdownRenders( + self.dedent( + r""" + Add tests for issue #449 + + Odd backticks | Even backticks + ------------ | ------------- + ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^_`{|}~`` | ``!\"\#$%&'()*+,\-./:;<=>?@\\\\^`_`{|}~`` + + Escapes | More Escapes + ------- | ------ + `` `\`` | `\` + + Only the first backtick can be escaped + + Escaped | Bacticks + ------- | ------ + \`` \` | \`\` + + Test escaped pipes + + Column 1 | Column 2 + -------- | -------- + `|` \| | Pipes are okay in code and escaped. \| + + | Column 1 | Column 2 | + | -------- | -------- | + | row1 | row1 \| + | row2 | row2 | + + Test header escapes + + | `` `\`` \| | `\` \| + | ---------- | ---- | + | row1 | row1 | + | row2 | row2 | + + Escaped pipes in format row should not be a table + + | Column1 | Column2 | + | ------- \|| ------- | + | row1 | row1 | + | row2 | row2 | + + Test escaped code in Table + + Should not be code | Should be code + ------------------ | -------------- + \`Not code\` | \\`code` + \\\`Not code\\\` | \\\\`code` + """), + self.dedent( + """ + <p>Add tests for issue #449</p> + <table> + <thead> + <tr> + <th>Odd backticks</th> + <th>Even backticks</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>!\\"\\#$%&'()*+,\\-./:;<=>?@\\\\\\\\^_`{|}~</code></td> + <td><code>!\\"\\#$%&'()*+,\\-./:;<=>?@\\\\\\\\^`_`{|}~</code></td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Escapes</th> + <th>More Escapes</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>`\\</code></td> + <td><code>\\</code></td> + </tr> + </tbody> + </table> + <p>Only the first backtick can be escaped</p> + <table> + <thead> + <tr> + <th>Escaped</th> + <th>Bacticks</th> + </tr> + </thead> + <tbody> + <tr> + <td>`<code>\\</code></td> + <td>``</td> + </tr> + </tbody> + </table> + <p>Test escaped pipes</p> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>|</code> |</td> + <td>Pipes are okay in code and escaped. |</td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Column 1</th> + <th>Column 2</th> + </tr> + </thead> + <tbody> + <tr> + <td>row1</td> + <td>row1 |</td> + </tr> + <tr> + <td>row2</td> + <td>row2</td> + </tr> + </tbody> + </table> + <p>Test header escapes</p> + <table> + <thead> + <tr> + <th><code>`\\</code> |</th> + <th><code>\\</code> |</th> + </tr> + </thead> + <tbody> + <tr> + <td>row1</td> + <td>row1</td> + </tr> + <tr> + <td>row2</td> + <td>row2</td> + </tr> + </tbody> + </table> + <p>Escaped pipes in format row should not be a table</p> + <p>| Column1 | Column2 | + | ------- || ------- | + | row1 | row1 | + | row2 | row2 |</p> + <p>Test escaped code in Table</p> + <table> + <thead> + <tr> + <th>Should not be code</th> + <th>Should be code</th> + </tr> + </thead> + <tbody> + <tr> + <td>`Not code`</td> + <td>\\<code>code</code></td> + </tr> + <tr> + <td>\\`Not code\\`</td> + <td>\\\\<code>code</code></td> + </tr> + </tbody> + </table> + """ + ), + extensions='tables' + ) + + def test_single_column_tables(self): + self.assertMarkdownRenders( + self.dedent( + """ + Single column tables + + | Is a Table | + | ---------- | + + | Is a Table + | ---------- + + Is a Table | + ---------- | + + | Is a Table | + | ---------- | + | row | + + | Is a Table + | ---------- + | row + + Is a Table | + ---------- | + row | + + | Is not a Table + -------------- + | row + + Is not a Table | + -------------- + row | + + | Is not a Table + | -------------- + row + + Is not a Table | + -------------- | + row + """), + self.dedent( + """ + <p>Single column tables</p> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td></td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td>row</td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td>row</td> + </tr> + </tbody> + </table> + <table> + <thead> + <tr> + <th>Is a Table</th> + </tr> + </thead> + <tbody> + <tr> + <td>row</td> + </tr> + </tbody> + </table> + <h2>| Is not a Table</h2> + <p>| row</p> + <h2>Is not a Table |</h2> + <p>row |</p> + <p>| Is not a Table + | -------------- + row</p> + <p>Is not a Table | + -------------- | + row</p> + """ + ), + extensions='tables' + ) + + def test_align_columns_legacy(self): + self.assertMarkdownRenders( + self.dedent( + """ + | Item | Value | + | :-------- | -----:| + | Computer | $1600 | + | Phone | $12 | + | Pipe | $1 | + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th align="left">Item</th> + <th align="right">Value</th> + </tr> + </thead> + <tbody> + <tr> + <td align="left">Computer</td> + <td align="right">$1600</td> + </tr> + <tr> + <td align="left">Phone</td> + <td align="right">$12</td> + </tr> + <tr> + <td align="left">Pipe</td> + <td align="right">$1</td> + </tr> + </tbody> + </table> + """ + ), + extensions=TableExtension(use_align_attribute=True) + ) + + def test_align_three_legacy(self): + self.assertMarkdownRenders( + self.dedent( + """ + |foo|bar|baz| + |:--|:-:|--:| + | | Q | | + |W | | W| + """ + ), + self.dedent( + """ + <table> + <thead> + <tr> + <th align="left">foo</th> + <th align="center">bar</th> + <th align="right">baz</th> + </tr> + </thead> + <tbody> + <tr> + <td align="left"></td> + <td align="center">Q</td> + <td align="right"></td> + </tr> + <tr> + <td align="left">W</td> + <td align="center"></td> + <td align="right">W</td> + </tr> + </tbody> + </table> + """ + ), + extensions=TableExtension(use_align_attribute=True) + )
View file
_service:tar_scm:Markdown-3.3.7.tar.gz/tests/test_syntax/extensions/test_toc.py -> _service:tar_scm:Markdown-3.4.1.tar.gz/tests/test_syntax/extensions/test_toc.py
Changed
@@ -569,3 +569,46 @@ '<p>TOC<br />\ntext</p>', extensions=TocExtension(), Nl2BrExtension() ) + + def testTOCWithCustomClass(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + TOC + # Header + ''' + ), + self.dedent( + ''' + <div class="custom"> + <ul> + <li><a href="#header">Header</a></li> + </ul> + </div> + <h1 id="header">Header</h1> + ''' + ), + extensions=TocExtension(toc_class="custom") + ) + + def testTOCWithCustomClasses(self): + self.assertMarkdownRenders( + self.dedent( + ''' + TOC + # Header + ''' + ), + self.dedent( + ''' + <div class="custom1 custom2"> + <ul> + <li><a href="#header">Header</a></li> + </ul> + </div> + <h1 id="header">Header</h1> + ''' + ), + extensions=TocExtension(toc_class="custom1 custom2") + )
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2