diff --git a/pyproject.toml b/pyproject.toml index 4be8ec3..506c2f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,16 @@ addopts = ["--strict-config", "--strict-markers"] xfail_strict = true [tool.ruff] +line-length = 80 +preview = true +target-version = "py37" + +[tool.ruff.format] +docstring-code-format = true +line-ending = "lf" +skip-magic-trailing-comma = true + +[tool.ruff.lint] ignore = [ "ANN101", "ANN102", @@ -123,31 +133,21 @@ ignore = [ "TRY400", ] ignore-init-module-imports = true -line-length = 80 -preview = true select = ["ALL"] -target-version = "py37" -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/*" = ["FBT001", "S101"] -[tool.ruff.flake8-self] +[tool.ruff.lint.flake8-self] ignore-names = ["_name_", "_value_"] -[tool.ruff.flake8-unused-arguments] -ignore-variadic-names = true - -[tool.ruff.format] -line-ending = "lf" -skip-magic-trailing-comma = true - -[tool.ruff.isort] +[tool.ruff.lint.isort] combine-as-imports = true required-imports = ["from __future__ import annotations"] split-on-trailing-comma = false -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" -[tool.ruff.pyupgrade] +[tool.ruff.lint.pyupgrade] keep-runtime-typing = true diff --git a/python/pyromark/__main__.py b/python/pyromark/__main__.py index 185faab..aa36b38 100644 --- a/python/pyromark/__main__.py +++ b/python/pyromark/__main__.py @@ -14,11 +14,10 @@ def parse_args(args: Optional[Sequence[str]]) -> argparse.Namespace: parser.add_argument( "-v", "--version", action="version", version=pyromark.__version__ ) - for extension in pyromark.Extensions: - name = extension._name_.lower().replace( # type: ignore[union-attr] - "_", "-" + for ext_name in pyromark.Extensions.__members__: + parser.add_argument( + "--" + ext_name.lower().replace("_", "-"), action="store_true" ) - parser.add_argument(f"--{name}", action="store_true") parser.add_argument( "file", type=argparse.FileType(), @@ -33,16 +32,13 @@ def main(args: Optional[Sequence[str]] = None) -> None: with parsed_args.file as f: content = f.read() - extensions = pyromark.Extensions(0) - for extension in pyromark.Extensions: - extension_enabled = getattr( - parsed_args, - extension._name_.lower(), # type: ignore[union-attr] - ) - if extension_enabled: - extensions |= extension + exts = pyromark.Extensions(0) + for ext_name, ext in pyromark.Extensions.__members__.items(): + ext_enabled = getattr(parsed_args, ext_name.lower()) + if ext_enabled: + exts |= ext - html = pyromark.markdown(content, extensions=extensions) + html = pyromark.markdown(content, extensions=exts) print(html, end="") diff --git a/python/pyromark/_extensions.py b/python/pyromark/_extensions.py index 5a88685..e06a251 100644 --- a/python/pyromark/_extensions.py +++ b/python/pyromark/_extensions.py @@ -17,6 +17,9 @@ class Extensions(IntFlag): | pyromark.Extensions.ENABLE_TASKLISTS | pyromark.Extensions.ENABLE_SMART_PUNCTUATION | pyromark.Extensions.ENABLE_HEADING_ATTRIBUTES + | pyromark.Extensions.ENABLE_YAML_STYLE_METADATA_BLOCKS + | pyromark.Extensions.ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS + | pyromark.Extensions.ENABLE_OLD_FOOTNOTES ) ``` """ @@ -24,7 +27,7 @@ class Extensions(IntFlag): ENABLE_TABLES = 1 << 1 """""" ENABLE_FOOTNOTES = 1 << 2 - """""" + """""" ENABLE_STRIKETHROUGH = 1 << 3 """""" ENABLE_TASKLISTS = 1 << 4 @@ -41,7 +44,10 @@ class Extensions(IntFlag): | --- | — | """ ENABLE_HEADING_ATTRIBUTES = 1 << 6 - """""" + """""" ENABLE_YAML_STYLE_METADATA_BLOCKS = 1 << 7 + """""" ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS = 1 << 8 + """""" ENABLE_OLD_FOOTNOTES = (1 << 9) | (1 << 2) + """""" diff --git a/src/lib.rs b/src/lib.rs index fd0dc68..662afff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,9 @@ use pyo3::prelude::*; /// | pyromark.Extensions.ENABLE_TASKLISTS /// | pyromark.Extensions.ENABLE_SMART_PUNCTUATION /// | pyromark.Extensions.ENABLE_HEADING_ATTRIBUTES +/// | pyromark.Extensions.ENABLE_YAML_STYLE_METADATA_BLOCKS +/// | pyromark.Extensions.ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS +/// | pyromark.Extensions.ENABLE_OLD_FOOTNOTES /// ) /// ) /// ``` @@ -52,6 +55,9 @@ impl Markdown { /// | pyromark.Extensions.ENABLE_TASKLISTS /// | pyromark.Extensions.ENABLE_SMART_PUNCTUATION /// | pyromark.Extensions.ENABLE_HEADING_ATTRIBUTES +/// | pyromark.Extensions.ENABLE_YAML_STYLE_METADATA_BLOCKS +/// | pyromark.Extensions.ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS +/// | pyromark.Extensions.ENABLE_OLD_FOOTNOTES /// ) /// ) /// print(html) #

Hello world

\n diff --git a/tests/test_pyromark.py b/tests/test_pyromark.py index 1a7718f..f719941 100644 --- a/tests/test_pyromark.py +++ b/tests/test_pyromark.py @@ -1,5 +1,8 @@ +# ruff: noqa: E501 from __future__ import annotations +import functools +import operator from pathlib import Path from typing import Sequence @@ -8,23 +11,30 @@ from pyromark.__main__ import main as pyromark_cli # noqa: PLC2701 TABLE = """\ -| a | b | +| foo | bar | | --- | --- | -| c | d |\ +| baz | bim |\ """ FOOTNOTE = """\ -Here's a sentence with a footnote. [^1] +[^1]: In new syntax, this is two footnote definitions. +[^2]: In old syntax, this is a single footnote definition with two lines. -[^1]: This is the footnote.\ +[^3]: + + In new syntax, this is a footnote with two paragraphs. + + In old syntax, this is a footnote followed by a code block. + +In new syntax, this undefined footnote definition renders as +literal text [^4]. In old syntax, it creates a dangling link.\ """ -STRIKETHROUGH = "~~The world is flat.~~" +STRIKETHROUGH = "~~Hi~~ Hello, ~there~ world!" TASKLIST = """\ -- [x] Write the press release -- [ ] Update the website -- [ ] Contact the media\ +- [ ] foo +- [x] bar\ """ SMART_PUNCTUATION = """\ @@ -35,7 +45,19 @@ Wow... Becky is so 'mean'!\ """ -HEADING_ATTRIBUTES = "# text { #id .class1 .class2 }" +HEADING_ATTRIBUTES = "# text { #id .class1 .class2 myattr, other_attr=myvalue }" + +YAML_STYLE_METADATA_BLOCKS = """\ +--- +title: Metadata +---\ +""" + +PLUSES_DELIMITED_METADATA_BLOCKS = """\ ++++ +title: Metadata ++++\ +""" BAD_BITS = 2 << 1 @@ -44,69 +66,151 @@ TABLE, pyromark.Extensions.ENABLE_TABLES, ("--enable-tables",), - "

| a | b |\n| --- | --- |\n| c | d |

\n", - "\n\n
ab
cd
\n", + """\ +

| foo | bar | +| --- | --- | +| baz | bim |

+""", + """\ + + +
foobar
bazbim
+""", ), ( FOOTNOTE, pyromark.Extensions.ENABLE_FOOTNOTES, ("--enable-footnotes",), - ( - "

Here's a sentence with a footnote. [^1]

\n

[^1]: This" - " is the footnote.

\n" - ), - ( - "

Here's a sentence with a footnote. 1

\n1\n

This is the' - " footnote.

\n\n" - ), + """\ +

[^1]: In new syntax, this is two footnote definitions. +[^2]: In old syntax, this is a single footnote definition with two lines.

+

[^3]:

+
In new syntax, this is a footnote with two paragraphs.
+
+In old syntax, this is a footnote followed by a code block.
+
+

In new syntax, this undefined footnote definition renders as +literal text [^4]. In old syntax, it creates a dangling link.

+""", + """\ +
1 +

In new syntax, this is two footnote definitions.

+
+
2 +

In old syntax, this is a single footnote definition with two lines.

+
+
3 +

In new syntax, this is a footnote with two paragraphs.

+

In old syntax, this is a footnote followed by a code block.

+
+

In new syntax, this undefined footnote definition renders as +literal text [^4]. In old syntax, it creates a dangling link.

+""", ), ( STRIKETHROUGH, pyromark.Extensions.ENABLE_STRIKETHROUGH, ("--enable-strikethrough",), - "

~~The world is flat.~~

\n", - "

The world is flat.

\n", + """\ +

~~Hi~~ Hello, ~there~ world!

+""", + """\ +

Hi Hello, there world!

+""", ), ( TASKLIST, pyromark.Extensions.ENABLE_TASKLISTS, ("--enable-tasklists",), - ( - "
    \n
  • [x] Write the press release
  • \n
  • [ ] Update the" - " website
  • \n
  • [ ] Contact the media
  • \n
\n" - ), - ( - '
    \n
  • \nWrite the press release
  • \n
  • \nUpdate the' - ' website
  • \n
  • \nContact the media
  • \n
\n' - ), + """\ +
    +
  • [ ] foo
  • +
  • [x] bar
  • +
+""", + """\ +
    +
  • +foo
  • +
  • +bar
  • +
+""", ), ( SMART_PUNCTUATION, pyromark.Extensions.ENABLE_SMART_PUNCTUATION, ("--enable-smart-punctuation",), - ( - "

'This here a real "quote"'

\n

And -- if" - " you're interested -- some em-dashes. Wait --- she actually" - " said that?

\n

Wow... Becky is so 'mean'!

\n" - ), - ( - "

‘This here a real “quote”’

\n

And – if you’re" - " interested – some em-dashes. Wait — she actually said" - " that?

\n

Wow… Becky is so ‘mean’!

\n" - ), + """\ +

'This here a real "quote"'

+

And -- if you're interested -- some em-dashes. Wait --- she actually said that?

+

Wow... Becky is so 'mean'!

+""", + """\ +

‘This here a real “quote”’

+

And – if you’re interested – some em-dashes. Wait — she actually said that?

+

Wow… Becky is so ‘mean’!

+""", ), ( HEADING_ATTRIBUTES, pyromark.Extensions.ENABLE_HEADING_ATTRIBUTES, ("--enable-heading-attributes",), - "

text { #id .class1 .class2 }

\n", - '

text

\n', + """\ +

text { #id .class1 .class2 myattr, other_attr=myvalue }

+""", + """

text

+""", + ), + ( + YAML_STYLE_METADATA_BLOCKS, + pyromark.Extensions.ENABLE_YAML_STYLE_METADATA_BLOCKS, + ("--enable-yaml-style-metadata-blocks",), + """\ +
+

title: Metadata

+""", + "", + ), + ( + PLUSES_DELIMITED_METADATA_BLOCKS, + pyromark.Extensions.ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS, + ("--enable-pluses-delimited-metadata-blocks",), + """\ +

+++ +title: Metadata ++++

+""", + "", + ), + ( + FOOTNOTE, + pyromark.Extensions.ENABLE_OLD_FOOTNOTES, + ("--enable-old-footnotes",), + """\ +

[^1]: In new syntax, this is two footnote definitions. +[^2]: In old syntax, this is a single footnote definition with two lines.

+

[^3]:

+
In new syntax, this is a footnote with two paragraphs.
+
+In old syntax, this is a footnote followed by a code block.
+
+

In new syntax, this undefined footnote definition renders as +literal text [^4]. In old syntax, it creates a dangling link.

+""", + """\ +
1 +

In new syntax, this is two footnote definitions. +2: In old syntax, this is a single footnote definition with two lines.

+
+
3
+
In new syntax, this is a footnote with two paragraphs.
+
+In old syntax, this is a footnote followed by a code block.
+
+

In new syntax, this undefined footnote definition renders as +literal text 4. In old syntax, it creates a dangling link.

+""", ), ( "\n\n".join( # noqa: FLY002 @@ -117,50 +221,72 @@ TASKLIST, SMART_PUNCTUATION, HEADING_ATTRIBUTES, + YAML_STYLE_METADATA_BLOCKS, + PLUSES_DELIMITED_METADATA_BLOCKS, ) ), - ( - pyromark.Extensions.ENABLE_TABLES - | pyromark.Extensions.ENABLE_FOOTNOTES - | pyromark.Extensions.ENABLE_STRIKETHROUGH - | pyromark.Extensions.ENABLE_TASKLISTS - | pyromark.Extensions.ENABLE_SMART_PUNCTUATION - | pyromark.Extensions.ENABLE_HEADING_ATTRIBUTES - ), - ( - "--enable-tables", - "--enable-footnotes", - "--enable-strikethrough", - "--enable-tasklists", - "--enable-smart-punctuation", - "--enable-heading-attributes", - ), - ( - "

| a | b |\n| --- | --- |\n| c | d |

\n

Here's" - " a sentence with a footnote. [^1]

\n

[^1]: This is the" - " footnote.

\n

~~The world is flat.~~

\n
    \n
  • [x]" - " Write the press release
  • \n
  • [ ] Update the" - " website
  • \n
  • [ ] Contact the media
  • \n
\n

'This" - " here a real "quote"'

\n

And -- if you're" - " interested -- some em-dashes. Wait --- she actually said" - " that?

\n

Wow... Becky is so 'mean'!

\n

text { #id" - " .class1 .class2 }

\n" + functools.reduce( + operator.or_, pyromark.Extensions.__members__.values() ), - ( - "\n\n
ab
cd
\n

Here’s" - ' a sentence with a footnote. 1

\n
1\n

This is' - " the footnote.

\n
\n

The world is" - ' flat.

\n
    \n
  • \nWrite the press release
  • \n
  • \nUpdate the' - ' website
  • \n
  • \nContact' - " the media
  • \n
\n

‘This here a real “quote”’

\n

And" - " – if you’re interested – some em-dashes. Wait — she actually said" - ' that?

\n

Wow… Becky is so ‘mean’!

\n

text

\n' + tuple( + "--" + ext_name.lower().replace("_", "-") + for ext_name in pyromark.Extensions.__members__ ), + """\ +

| foo | bar | +| --- | --- | +| baz | bim |

+

[^1]: In new syntax, this is two footnote definitions. +[^2]: In old syntax, this is a single footnote definition with two lines.

+

[^3]:

+
In new syntax, this is a footnote with two paragraphs.
+
+In old syntax, this is a footnote followed by a code block.
+
+

In new syntax, this undefined footnote definition renders as +literal text [^4]. In old syntax, it creates a dangling link.

+

~~Hi~~ Hello, ~there~ world!

+
    +
  • [ ] foo
  • +
  • [x] bar
  • +
+

'This here a real "quote"'

+

And -- if you're interested -- some em-dashes. Wait --- she actually said that?

+

Wow... Becky is so 'mean'!

+

text { #id .class1 .class2 myattr, other_attr=myvalue }

+
+

title: Metadata

+

+++ +title: Metadata ++++

+""", + """\ + + +
foobar
bazbim
+
1 +

In new syntax, this is two footnote definitions. +2: In old syntax, this is a single footnote definition with two lines.

+
+
3
+
In new syntax, this is a footnote with two paragraphs.
+
+In old syntax, this is a footnote followed by a code block.
+
+

In new syntax, this undefined footnote definition renders as +literal text 4. In old syntax, it creates a dangling link.

+

Hi Hello, there world!

+
    +
  • +foo
  • +
  • +bar
  • +
+

‘This here a real “quote”’

+

And – if you’re interested – some em-dashes. Wait — she actually said that?

+

Wow… Becky is so ‘mean’!

+

text

+""", ), ]