Skip to content

Commit

Permalink
✨ NEW: Add --compact-tables CLI argument (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleKing authored Aug 23, 2024
1 parent d146c1f commit 2d168d6
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 31 deletions.
7 changes: 7 additions & 0 deletions .pre-commit-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,10 @@ repos:
files: "tests/pre-commit-test.md"
types: [markdown]
language: system
- id: mdformat-compact
name: mdformat-no-venv
entry: mdformat
args: ["--compact-tables"]
files: "tests/pre-commit-test-compact.md"
types: [markdown]
language: system
7 changes: 6 additions & 1 deletion mdformat_tables/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

__version__ = "0.4.1"

from .plugin import POSTPROCESSORS, RENDERERS, update_mdit # noqa: F401
from .plugin import ( # noqa: F401
POSTPROCESSORS,
RENDERERS,
add_cli_options,
update_mdit,
)
76 changes: 46 additions & 30 deletions mdformat_tables/plugin.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@
from typing import List, Mapping, Sequence
import argparse
from typing import Iterable, List, Mapping, Sequence, Union

from markdown_it import MarkdownIt
from mdformat.renderer import RenderContext, RenderTreeNode
from mdformat.renderer.typing import Postprocess, Render

_COMPACT_TABLES = False
"""user-specified flag for toggling compact tables."""


def add_cli_options(parser: argparse.ArgumentParser) -> None:
"""Add options to the mdformat CLI, to be stored in `mdit.options["mdformat"]`."""
parser.add_argument(
"--compact-tables",
action="store_true",
help="If specified, do not add padding to table cells.",
)


def update_mdit(mdit: MarkdownIt) -> None:
"""Update the parser, e.g. by adding a plugin: `mdit.use(myplugin)`"""
mdit.enable("table")

global _COMPACT_TABLES
_COMPACT_TABLES = mdit.options["mdformat"].get("compact_tables", False)


def _to_string(
rows: Sequence[Sequence[str]], align: Sequence[Sequence[str]], widths: Sequence[int]
) -> List[str]:
lines = []
lines.append(
"| "
+ " | ".join(
f"{{:{al or '<'}{widths[i]}}}".format(text)
for i, (text, al) in enumerate(zip(rows[0], align[0]))
def join_row(items: Union[Iterable[str], Sequence[str]]) -> str:
return "| " + " | ".join(items) + " |"

def format_delimiter_cell(index: int, align: str) -> str:
delim = (
(":" if align in ("<", "^") else "-")
+ ("-" * max(0, widths[index] - 2))
+ (":" if align in (">", "^") else "-")
)
+ " |"
return ":-:" if delim == "::" else delim

header = join_row(
f"{{:{al or '<'}{widths[i]}}}".format(text)
for i, (text, al) in enumerate(zip(rows[0], align[0]))
)
lines.append(
"| "
+ " | ".join(
(":" if al in ("<", "^") else "-")
+ "-" * (widths[i] - 2)
+ (":" if al in (">", "^") else "-")
for i, al in enumerate(align[0])
)
+ " |"
delimiter = join_row(
(format_delimiter_cell(i, al) for i, al in enumerate(align[0]))
)
for row, als in zip(rows[1:], align[1:]):
lines.append(
"| "
+ " | ".join(
f"{{:{al or '<'}{widths[i]}}}".format(text)
for i, (text, al) in enumerate(zip(row, als))
)
+ " |"
rows = [
join_row(
f"{{:{al or '<'}{widths[i]}}}".format(text)
for i, (text, al) in enumerate(zip(row, als))
)
return lines
for row, als in zip(rows[1:], align[1:])
]
return [header, delimiter, *rows]


def _render_table(node: RenderTreeNode, context: RenderContext) -> str:
Expand All @@ -66,10 +79,13 @@ def _render_table(node: RenderTreeNode, context: RenderContext) -> str:
align[-1].append("")
rows[-1].append(descendant.render(context))

# work out the widths for each column
widths = [
max(3, *(len(row[col_idx]) for row in rows)) for col_idx in range(len(rows[0]))
]
def _calculate_width(col_idx: int) -> int:
"""Work out the widths for each column."""
if _COMPACT_TABLES:
return 0
return max(3, *(len(row[col_idx]) for row in rows))

widths = [_calculate_width(col_idx) for col_idx in range(len(rows[0]))]

# write content
# note: assuming always one header row
Expand Down
137 changes: 137 additions & 0 deletions tests/fixtures-compact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
simple
.
a | bb
| - | -
1 | 2
.
| a | bb |
| -- | -- |
| 1 | 2 |
.

empty headers
.
| | |
|- | -
|1 | 2
.
| | |
| -- | -- |
| 1 | 2 |
.

no body
.
| | |
|- | -
.
| | |
| -- | -- |
.

alignment
.
a | b | c
:- | -: | :-:
1 | 2 | 3
xxxxxx | yyyyyy | zzzzzz
.
| a | b | c |
| :- | -: | :-: |
| 1 | 2 | 3 |
| xxxxxx | yyyyyy | zzzzzz |
.

nested syntax
.
*a* | [b](link)
| - | -
`c` | [d](link)
.
| *a* | [b](link) |
| -- | -- |
| `c` | [d](link) |
.

A list takes precedence in case of ambiguity
.
a | b
- | -
1 | 2
.
a | b

- | \-
1 | 2
.

paragraph before/after
.
x
a | bb
-- | -
1 | 2
y
.
x

| a | bb |
| -- | -- |
| 1 | 2 |
| y | |
.

Nested tables in blockquotes:
.
> a|b
> ---|---
> bar|baz
.
> | a | b |
> | -- | -- |
> | bar | baz |
.

references
.
| [![a][b]][c] |
| - |
| [![a][b]][c] |

[b]: link1
[c]: link2
.
| [![a][b]][c] |
| -- |
| [![a][b]][c] |

[b]: link1
[c]: link2
.

Escaped table 1
.
| a |
\| - |
.
| a |
| \- |
.

Escaped table 2
.
a
-\:
.
a
\-:
.

Escaped table 3
.
a
:\-
.
a
:\-
.
15 changes: 15 additions & 0 deletions tests/pre-commit-test-compact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# hallo

here's a table:

| a | b | c |
| :- | -: | :-: |
| 1 | 2 | 3 |
| xxxxxx | yyyyyy | zzzzzz |

And a larger one (from: https://github.com/hukkin/mdformat-gfm/issues/33)

| | option 1 | option 2 | option 3 | ... |
| :- | :-: | :-: | -: | :-: |
| comparison 1 | On am we offices expense thought. Its hence ten smile age means. Seven chief sight far point any. Of so high into easy. Dashwoods eagerness oh extensive as discourse sportsman frankness. Husbands see disposed surprise likewise humoured yet pleasure. Fifteen no inquiry cordial so resolve garrets as. Impression was estimating surrounded solicitude indulgence son shy. | asd | asd | asda |
| comparison 2 | asdasd | On am we offices expense thought. Its hence ten smile age means. Seven chief sight far point any. Of so high into easy. Dashwoods eagerness oh extensive as discourse sportsman frankness. Husbands see disposed surprise likewise humoured yet pleasure. Fifteen no inquiry cordial so resolve garrets as. Impression was estimating surrounded solicitude indulgence son shy. | asd | |
7 changes: 7 additions & 0 deletions tests/pre-commit-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ here's a table:
| :----- | -----: | :----: |
| 1 | 2 | 3 |
| xxxxxx | yyyyyy | zzzzzz |

And a larger one (from: https://github.com/hukkin/mdformat-gfm/issues/33)

| | option 1 | option 2 | option 3 | ... |
| :----------- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -------: | :--: |
| comparison 1 | On am we offices expense thought. Its hence ten smile age means. Seven chief sight far point any. Of so high into easy. Dashwoods eagerness oh extensive as discourse sportsman frankness. Husbands see disposed surprise likewise humoured yet pleasure. Fifteen no inquiry cordial so resolve garrets as. Impression was estimating surrounded solicitude indulgence son shy. | asd | asd | asda |
| comparison 2 | asdasd | On am we offices expense thought. Its hence ten smile age means. Seven chief sight far point any. Of so high into easy. Dashwoods eagerness oh extensive as discourse sportsman frankness. Husbands see disposed surprise likewise humoured yet pleasure. Fifteen no inquiry cordial so resolve garrets as. Impression was estimating surrounded solicitude indulgence son shy. | asd | |
15 changes: 15 additions & 0 deletions tests/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,18 @@ def test_fixtures(line, title, text, expected):
output = mdformat.text(text, extensions={"tables"})
print(output)
assert output.rstrip() == expected.rstrip(), output


FIXTURES_COMPACT_PATH = Path(__file__).parent / "fixtures-compact.md"
fixtures_compact = read_fixture_file(FIXTURES_COMPACT_PATH)


@pytest.mark.parametrize(
"line,title,text,expected", fixtures_compact, ids=[f[1] for f in fixtures_compact]
)
def test_fixtures_compact(line, title, text, expected):
output = mdformat.text(
text, extensions={"tables"}, options={"compact_tables": True}
)
print(output)
assert output.rstrip() == expected.rstrip(), output

0 comments on commit 2d168d6

Please sign in to comment.