python-markdown/0001-Update-th-td-to-use-style-attribute.patch
cao-fei8 b449f1fdc0 Update th/td to use style attribute
Reference:
659a43659c

Signed-off-by: cao-fei8 <caofei@xfusion.com>
2023-01-16 19:25:47 +08:00

1716 lines
42 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 spec][spec4] specifically
+deprecates the use of the `align` attribute and it does not appear at all in the
+[HTML5 spec][spec5]. 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>[!\"\#$%&amp;'()*+,\-./:;&lt;=&gt;?@\[\\\]^_`{|}~]</code></td>
-<td><code>[!\"\#$%&amp;'()*+,\-./:;&lt;=&gt;?@\[\\\]^`_`{|}~]</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>[!\\"\\#$%&amp;'()*+,\\-./:;&lt;=&gt;?@\\[\\\\\\]^_`{|}~]</code></td>
+ <td><code>[!\\"\\#$%&amp;'()*+,\\-./:;&lt;=&gt;?@\\[\\\\\\]^`_`{|}~]</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