Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
env:
GH_TOKEN: ${{ github.token }} # enables online audits (known-vulnerable-actions, impostor-commit)
run: uv run zizmor --format=github .
- run: uv run mypy

test:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
- Lowest supported Markdown: `uv run --isolated --python 3.10 --with "markdown==3.2.*" pytest`
- Lint/format (CI fails on either): `uv run ruff check .` and `uv run ruff format --check .`
- Workflow audit (also in CI): `GH_TOKEN=$(gh auth token) uv run zizmor .`. Config in `.github/zizmor.yml` (its Dependabot cooldown must match `.github/dependabot.yml`).
- Type check (also in CI): `uv run mypy` (strict, covers `md_condition` and `tests`). The package ships `py.typed`.
- Build: `uv build`. The version comes from the latest git tag via setuptools-scm; there is no version field to edit.

## Code
Expand Down
4 changes: 3 additions & 1 deletion md_condition/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from typing import Any

from md_condition.extension import ConditionExtension
from md_condition.preprocessor import ConditionSyntaxError

__all__ = ["ConditionExtension", "ConditionSyntaxError", "makeExtension"]


def makeExtension(**kwargs) -> ConditionExtension:
def makeExtension(**kwargs: Any) -> ConditionExtension:
return ConditionExtension(**kwargs)
4 changes: 3 additions & 1 deletion md_condition/extension.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from typing import Any

from markdown import Markdown
from markdown.extensions import Extension

from md_condition.preprocessor import ConditionPreprocessor


class ConditionExtension(Extension):
def __init__(self, **kwargs) -> None:
def __init__(self, **kwargs: Any) -> None:
self.config = {
"symbol": ["", "Defined symbol(s): a string separated by spaces/`|`, or a list"],
}
Expand Down
11 changes: 6 additions & 5 deletions md_condition/preprocessor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import re
from collections.abc import Iterable
from typing import TYPE_CHECKING

from markdown import Markdown
Expand Down Expand Up @@ -42,6 +43,7 @@ def __init__(self, md: Markdown, extension: ConditionExtension) -> None:
# `symbol` is a string ("DEBUG", "DEBUG RELEASE", "DEBUG|RELEASE"), a list of them,
# or a YAML scalar such as 2024 (stringified)
symbol = extension.getConfig("symbol")
values: Iterable[object]
if symbol is None:
values = []
elif isinstance(symbol, (list, tuple, set, frozenset)):
Expand Down Expand Up @@ -161,8 +163,7 @@ def _error(number: int, line: str, message: str) -> ConditionSyntaxError:
def _closes_fence(cls, line: str, fence: str) -> bool:
# CommonMark: same character, at least as long, nothing else on the line
closing = cls.RE_FENCE_CLOSE.match(line)
return (
bool(closing)
and closing.group(1)[0] == fence[0]
and len(closing.group(1)) >= len(fence)
)
if closing is None:
return False
marker = closing.group(1)
return marker[0] == fence[0] and len(marker) >= len(fence)
Empty file added md_condition/py.typed
Empty file.
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies = ["Markdown>=3.2"]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Typing :: Typed",
"Topic :: Text Processing :: Markup :: Markdown",
]

Expand All @@ -23,8 +24,10 @@ Homepage = "https://github.com/cssho/md-condition"

[dependency-groups]
dev = [
"mypy>=2.4.0",
"pytest>=8",
"ruff>=0.14",
"types-markdown>=3.10.2.20261007",
"zizmor>=1.30.1",
]

Expand All @@ -42,3 +45,7 @@ select = ["E", "F", "W", "I", "UP", "B"]

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.mypy]
strict = true
files = ["md_condition", "tests"]
2 changes: 1 addition & 1 deletion tests/test_condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def test_symbol_is_matched_as_whole_name(symbol: str, condition: str, kept: bool
pytest.param(None, False, False, id="none"),
],
)
def test_multiple_symbols(symbol, debug: bool, release: bool) -> None:
def test_multiple_symbols(symbol: object, debug: bool, release: bool) -> None:
md = markdown.Markdown(extensions=[ConditionExtension(symbol=symbol)])
expected = "<h1>1</h1>\n<p>{}</p>\n<h1>2</h1>\n<p>{}</p>".format(
"DEBUG" if debug else "No DEBUG", "RELEASE" if release else "No RELEASE"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_fences.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from md_condition import ConditionExtension, ConditionSyntaxError


def preprocess(source: str, symbol="DEBUG") -> str:
def preprocess(source: str, symbol: object = "DEBUG") -> str:
md = markdown.Markdown(extensions=[ConditionExtension(symbol=symbol)])
lines = textwrap.dedent(source).split("\n")
return "\n".join(md.preprocessors["condition"].run(lines))
Expand Down Expand Up @@ -152,7 +152,7 @@ def test_error_message_includes_the_line() -> None:
pytest.param([2024, "DEBUG"], "2024", id="int_in_list"),
],
)
def test_yaml_scalar_symbols(symbol, condition: str) -> None:
def test_yaml_scalar_symbols(symbol: object, condition: str) -> None:
# YAML turns `symbol: 2024` / `symbol: yes` into int / bool
assert preprocess(f"<!--- #if {condition} -->\nyes\n<!--- #endif -->", symbol=symbol) == "yes"

Expand Down
Loading
Loading