Skip to content

Commit 1245ed9

Browse files
committed
refactor: Sync API and docs
1 parent b132e78 commit 1245ed9

26 files changed

+308
-29
lines changed

duties.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def check_quality(ctx: Context) -> None:
9393
)
9494

9595

96-
@duty(skip_if=sys.version_info[:2] != (3, 12), skip_reason="Docs build only on Python 3.12")
96+
@duty(skip_if=sys.version_info[:2] != (3, 12), skip_reason=pyprefix("Docs build only on Python 3.12"))
9797
def check_docs(ctx: Context) -> None:
9898
"""Check if the documentation builds correctly."""
9999
Path("htmlcov").mkdir(parents=True, exist_ok=True)

mkdocs.yml

-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ plugins:
141141
docstring_options:
142142
ignore_init_summary: true
143143
docstring_section_style: list
144-
filters: ["!^_"]
145144
heading_level: 1
146145
inherited_members: true
147146
merge_init_into_class: true

src/markdown_exec/_internal/formatters/base.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
from markdown.core import Markdown
2020

21-
logger = get_logger(__name__)
21+
_logger = get_logger(__name__)
22+
2223
default_tabs = ("Source", "Result")
24+
"""Default tab titles."""
2325

2426

2527
@contextmanager
@@ -74,6 +76,7 @@ class ExecutionError(Exception):
7476
def __init__(self, message: str, returncode: int | None = None) -> None:
7577
super().__init__(message)
7678
self.returncode = returncode
79+
"""The code returned by the execution of the code block."""
7780

7881

7982
def _format_log_details(details: str, *, strip_fences: bool = False) -> str:
@@ -151,7 +154,7 @@ def base_format(
151154
f"Code block is:\n\n{_format_log_details(source_input)}\n\n"
152155
f"Output is:\n\n{_format_log_details(str(error), strip_fences=True)}\n"
153156
)
154-
logger.warning(log_message)
157+
_logger.warning(log_message)
155158
return markdown.convert(str(error))
156159

157160
if not output and not source:

src/markdown_exec/_internal/formatters/console.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
if TYPE_CHECKING:
1313
from markupsafe import Markup
1414

15-
logger = get_logger(__name__)
15+
_logger = get_logger(__name__)
1616

1717

1818
def _transform_source(code: str) -> tuple[str, str]:

src/markdown_exec/_internal/formatters/pycon.py

-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66

77
from markdown_exec._internal.formatters.base import base_format
88
from markdown_exec._internal.formatters.python import _run_python
9-
from markdown_exec._internal.logger import get_logger
109

1110
if TYPE_CHECKING:
1211
from markupsafe import Markup
1312

14-
logger = get_logger(__name__)
15-
1613

1714
def _transform_source(code: str) -> tuple[str, str]:
1815
python_lines = []

src/markdown_exec/_internal/formatters/pyodide.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,20 @@
1010
# All Ace.js themes listed here:
1111
# https://github.com/ajaxorg/ace/tree/master/src/theme
1212

13-
play_emoji = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7Z"></path></svg>'
14-
clear_emoji = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.14 3c-.51 0-1.02.2-1.41.59L2.59 14.73c-.78.77-.78 2.04 0 2.83L5.03 20h7.66l8.72-8.73c.79-.77.79-2.04 0-2.83l-4.85-4.85c-.39-.39-.91-.59-1.42-.59M17 18l-2 2h7v-2"></path></svg>'
13+
_play_emoji = (
14+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7Z"></path></svg>'
15+
)
16+
_clear_emoji = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.14 3c-.51 0-1.02.2-1.41.59L2.59 14.73c-.78.77-.78 2.04 0 2.83L5.03 20h7.66l8.72-8.73c.79-.77.79-2.04 0-2.83l-4.85-4.85c-.39-.39-.91-.59-1.42-.59M17 18l-2 2h7v-2"></path></svg>'
1517

16-
assets = """
18+
_assets = """
1719
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.16.0/ace.js"></script>
1820
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
1921
<script type="text/javascript" src="https://cdn.jsdelivr.net/pyodide/v{version}/full/pyodide.js"></script>
2022
<link title="light" rel="alternate stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/tomorrow.min.css" disabled="disabled">
2123
<link title="dark" rel="alternate stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/tomorrow-night-blue.min.css" disabled="disabled">
2224
"""
2325

24-
template = """
26+
_template = """
2527
<div class="pyodide">
2628
<div class="pyodide-editor-bar">
2729
<span class="pyodide-bar-item">Editor (session: %(session)s)</span><span id="%(id_prefix)srun" title="Run: press Ctrl-Enter" class="pyodide-bar-item pyodide-clickable"><span class="twemoji">%(play_emoji)s</span> Run</span>
@@ -62,10 +64,10 @@ def _format_pyodide(code: str, md: Markdown, session: str, extra: dict, **option
6264
"theme_light": theme_light.strip(),
6365
"theme_dark": theme_dark.strip(),
6466
"session": session or "default",
65-
"play_emoji": play_emoji,
66-
"clear_emoji": clear_emoji,
67+
"play_emoji": _play_emoji,
68+
"clear_emoji": _clear_emoji,
6769
}
68-
rendered = template % data
70+
rendered = _template % data
6971
if exclude_assets:
7072
return rendered
71-
return assets.format(version=version) + rendered
73+
return _assets.format(version=version) + rendered

src/markdown_exec/_internal/mkdocs_plugin.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from mkdocs.plugins import BasePlugin
1414
from mkdocs.utils import write_file
1515

16-
from markdown_exec import formatter, formatters, validator
1716
from markdown_exec._internal.logger import patch_loggers
17+
from markdown_exec._internal.main import formatter, formatters, validator
1818
from markdown_exec._internal.rendering import MarkdownConverter, markdown_config
1919

2020
if TYPE_CHECKING:
@@ -27,9 +27,9 @@
2727
try:
2828
__import__("pygments_ansi_color")
2929
except ImportError:
30-
ansi_ok = False
30+
_ansi_ok = False
3131
else:
32-
ansi_ok = True
32+
_ansi_ok = True
3333

3434

3535
class _LoggerAdapter(logging.LoggerAdapter):
@@ -71,7 +71,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
7171
In this hook, we add custom fences for all the supported languages.
7272
7373
We also save the Markdown extensions configuration
74-
into [`markdown_config`][markdown_exec.rendering.markdown_config].
74+
into [`markdown_config`][markdown_exec.markdown_config].
7575
7676
Arguments:
7777
config: The MkDocs config object.
@@ -82,7 +82,7 @@ def on_config(self, config: MkDocsConfig) -> MkDocsConfig | None:
8282
if "pymdownx.superfences" not in config["markdown_extensions"]:
8383
message = "The 'markdown-exec' plugin requires the 'pymdownx.superfences' Markdown extension to work."
8484
raise PluginError(message)
85-
if self.config.ansi in ("required", True) and not ansi_ok:
85+
if self.config.ansi in ("required", True) and not _ansi_ok:
8686
raise PluginError(
8787
"The configuration for the 'markdown-exec' plugin requires "
8888
"that it is installed with the 'ansi' extra. "
@@ -113,14 +113,16 @@ def on_env(
113113
config: MkDocsConfig,
114114
files: Files, # noqa: ARG002
115115
) -> Environment | None:
116-
if self.config.ansi in ("required", True) or (self.config.ansi == "auto" and ansi_ok):
116+
"""Add assets to the environment."""
117+
if self.config.ansi in ("required", True) or (self.config.ansi == "auto" and _ansi_ok):
117118
self._add_css(config, "ansi.css")
118119
if "pyodide" in self.languages:
119120
self._add_css(config, "pyodide.css")
120121
self._add_js(config, "pyodide.js")
121122
return env
122123

123124
def on_post_build(self, *, config: MkDocsConfig) -> None: # noqa: ARG002
125+
"""Reset the plugin state."""
124126
MarkdownConverter.counter = 0
125127
markdown_config.reset()
126128
if self.mkdocs_config_dir is None:
@@ -130,7 +132,7 @@ def on_post_build(self, *, config: MkDocsConfig) -> None: # noqa: ARG002
130132

131133
def _add_asset(self, config: MkDocsConfig, asset_file: str, asset_type: str) -> None:
132134
asset_filename = f"assets/_markdown_exec_{asset_file}"
133-
asset_content = Path(__file__).parent.joinpath("assets", asset_file).read_text()
135+
asset_content = Path(__file__).parent.parent.joinpath("assets", asset_file).read_text()
134136
write_file(asset_content.encode("utf-8"), os.path.join(config.site_dir, asset_filename))
135137
config[f"extra_{asset_type}"].insert(0, asset_filename)
136138

src/markdown_exec/_internal/processors.py

+12
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ class IdPrependingTreeprocessor(Treeprocessor):
2121
"""Prepend the configured prefix to IDs of all HTML elements."""
2222

2323
name = "markdown_exec_ids"
24+
"""The name of the treeprocessor."""
2425

2526
def __init__(self, md: Markdown, id_prefix: str) -> None:
2627
super().__init__(md)
2728
self.id_prefix = id_prefix
29+
"""The prefix to prepend to IDs."""
2830

2931
def run(self, root: Element) -> None:
32+
"""Run the treeprocessor."""
3033
if not self.id_prefix:
3134
return
3235
for el in root.iter():
@@ -53,13 +56,17 @@ class HeadingReportingTreeprocessor(Treeprocessor):
5356
"""Records the heading elements encountered in the document."""
5457

5558
name = "markdown_exec_record_headings"
59+
"""The name of the treeprocessor."""
5660
regex = re.compile("[Hh][1-6]")
61+
"""The regex to match heading tags."""
5762

5863
def __init__(self, md: Markdown, headings: list[Element]):
5964
super().__init__(md)
6065
self.headings = headings
66+
"""The list of heading elements."""
6167

6268
def run(self, root: Element) -> None:
69+
"""Run the treeprocessor."""
6370
for el in root.iter():
6471
if self.regex.fullmatch(el.tag):
6572
el = copy.copy(el) # noqa: PLW2901
@@ -74,6 +81,7 @@ class InsertHeadings(Treeprocessor):
7481
"""Our headings insertor."""
7582

7683
name = "markdown_exec_insert_headings"
84+
"""The name of the treeprocessor."""
7785

7886
def __init__(self, md: Markdown):
7987
"""Initialize the object.
@@ -83,8 +91,10 @@ def __init__(self, md: Markdown):
8391
"""
8492
super().__init__(md)
8593
self.headings: dict[Markup, list[Element]] = {}
94+
"""The dictionary of headings."""
8695

8796
def run(self, root: Element) -> None:
97+
"""Run the treeprocessor."""
8898
if not self.headings:
8999
return
90100

@@ -103,8 +113,10 @@ class RemoveHeadings(Treeprocessor):
103113
"""Our headings remover."""
104114

105115
name = "markdown_exec_remove_headings"
116+
"""The name of the treeprocessor."""
106117

107118
def run(self, root: Element) -> None:
119+
"""Run the treeprocessor."""
108120
self._remove_duplicated_headings(root)
109121

110122
def _remove_duplicated_headings(self, parent: Element) -> None:

src/markdown_exec/_internal/rendering.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,22 @@ class MarkdownConfig:
113113
"""This class returns a singleton used to store Markdown extensions configuration.
114114
115115
You don't have to instantiate the singleton yourself:
116-
we provide it as [`markdown_config`][markdown_exec.rendering.markdown_config].
116+
we provide it as [`markdown_config`][markdown_exec.markdown_config].
117117
"""
118118

119119
_singleton: MarkdownConfig | None = None
120120

121121
def __new__(cls) -> MarkdownConfig: # noqa: PYI034
122+
"""Return the singleton instance."""
122123
if cls._singleton is None:
123124
cls._singleton = super().__new__(cls)
124125
return cls._singleton
125126

126127
def __init__(self) -> None:
127128
self.exts: list[str] | None = None
129+
"""The Markdown extensions."""
128130
self.exts_config: dict[str, dict[str, Any]] | None = None
131+
"""The extensions configuration."""
129132

130133
def save(self, exts: list[str], exts_config: dict[str, dict[str, Any]]) -> None:
131134
"""Save Markdown extensions and their configuration.
@@ -156,9 +159,9 @@ def reset(self) -> None:
156159
markdown_config.save(extensions, extensions_config)
157160
```
158161
159-
See the actual event hook: [`on_config`][markdown_exec.mkdocs_plugin.MarkdownExecPlugin.on_config].
160-
See the [`save`][markdown_exec.rendering.MarkdownConfig.save]
161-
and [`reset`][markdown_exec.rendering.MarkdownConfig.reset] methods.
162+
See the actual event hook: [`on_config`][markdown_exec.MarkdownExecPlugin.on_config].
163+
See the [`save`][markdown_exec.MarkdownConfig.save]
164+
and [`reset`][markdown_exec.MarkdownConfig.reset] methods.
162165
163166
Without it, Markdown Exec will rely on the `registeredExtensions` attribute
164167
of the original Markdown instance, which does not forward everything
@@ -233,6 +236,7 @@ class MarkdownConverter:
233236
"""Helper class to avoid breaking the original Markdown instance state."""
234237

235238
counter: int = 0
239+
"""A counter to generate unique IDs for code blocks."""
236240

237241
def __init__(self, md: Markdown, *, update_toc: bool = True) -> None:
238242
self._md_ref: Markdown = md
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal import formatters
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(formatters, name)

src/markdown_exec/formatters/base.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal.formatters import base
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters.base` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(base, name)

src/markdown_exec/formatters/bash.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal.formatters import bash
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters.bash` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(bash, name)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal.formatters import console
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters.console` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(console, name)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal.formatters import markdown
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters.markdown` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(markdown, name)

src/markdown_exec/formatters/pycon.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Deprecated. Import from `markdown_exec` directly."""
2+
3+
# YORE: Bump 2: Remove file.
4+
5+
import warnings
6+
from typing import Any
7+
8+
from markdown_exec._internal.formatters import pycon
9+
10+
11+
def __getattr__(name: str) -> Any:
12+
warnings.warn(
13+
"Importing from `markdown_exec.formatters.pycon` is deprecated. Import from `markdown_exec` directly.",
14+
DeprecationWarning,
15+
stacklevel=2,
16+
)
17+
return getattr(pycon, name)

0 commit comments

Comments
 (0)