mkdocs-treeblocks 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mkdocs_treeblocks/__init__.py +1 -0
- mkdocs_treeblocks/parser.py +101 -0
- mkdocs_treeblocks/plugin.py +30 -0
- mkdocs_treeblocks/renderer.py +38 -0
- mkdocs_treeblocks/transform.py +54 -0
- mkdocs_treeblocks-0.1.0.dist-info/METADATA +241 -0
- mkdocs_treeblocks-0.1.0.dist-info/RECORD +10 -0
- mkdocs_treeblocks-0.1.0.dist-info/WHEEL +4 -0
- mkdocs_treeblocks-0.1.0.dist-info/entry_points.txt +2 -0
- mkdocs_treeblocks-0.1.0.dist-info/licenses/LICENSE.md +21 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Tree block support for MkDocs."""
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TreeParseError(ValueError):
|
|
7
|
+
"""Raised when tree block text cannot be parsed."""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class TreeNode:
|
|
12
|
+
text: str
|
|
13
|
+
children: list["TreeNode"] = field(default_factory=list)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def parse_tree(text: str) -> TreeNode:
|
|
17
|
+
"""Parse indented tree block text into a TreeNode hierarchy."""
|
|
18
|
+
parsed_lines = _parse_lines(text)
|
|
19
|
+
|
|
20
|
+
if not parsed_lines:
|
|
21
|
+
raise TreeParseError("Tree block is empty.")
|
|
22
|
+
|
|
23
|
+
root_depth, root_text = parsed_lines[0]
|
|
24
|
+
|
|
25
|
+
if root_depth != 0:
|
|
26
|
+
raise TreeParseError("The first tree node must not be indented.")
|
|
27
|
+
|
|
28
|
+
root = TreeNode(root_text)
|
|
29
|
+
stack: list[tuple[int, TreeNode]] = [(root_depth, root)]
|
|
30
|
+
|
|
31
|
+
for depth, node_text in parsed_lines[1:]:
|
|
32
|
+
if depth > stack[-1][0] + 1:
|
|
33
|
+
raise TreeParseError("Tree indentation cannot skip levels.")
|
|
34
|
+
|
|
35
|
+
while stack and stack[-1][0] >= depth:
|
|
36
|
+
stack.pop()
|
|
37
|
+
|
|
38
|
+
if not stack:
|
|
39
|
+
raise TreeParseError("Tree contains more than one root node.")
|
|
40
|
+
|
|
41
|
+
node = TreeNode(node_text)
|
|
42
|
+
stack[-1][1].children.append(node)
|
|
43
|
+
stack.append((depth, node))
|
|
44
|
+
|
|
45
|
+
return root
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _parse_lines(text: str) -> list[tuple[int, str]]:
|
|
49
|
+
indent_style: str | None = None
|
|
50
|
+
parsed_lines: list[tuple[int, str]] = []
|
|
51
|
+
|
|
52
|
+
for line in text.splitlines():
|
|
53
|
+
if not line.strip():
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
indent, node_text = _split_indent(line)
|
|
57
|
+
|
|
58
|
+
if indent:
|
|
59
|
+
line_indent_style = _detect_indent_style(indent)
|
|
60
|
+
|
|
61
|
+
if indent_style is None:
|
|
62
|
+
indent_style = line_indent_style
|
|
63
|
+
elif indent_style != line_indent_style:
|
|
64
|
+
raise TreeParseError("Tree block cannot mix tabs and spaces for indentation.")
|
|
65
|
+
|
|
66
|
+
depth = _indent_depth(indent, line_indent_style)
|
|
67
|
+
else:
|
|
68
|
+
depth = 0
|
|
69
|
+
|
|
70
|
+
parsed_lines.append((depth, node_text))
|
|
71
|
+
|
|
72
|
+
return parsed_lines
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _split_indent(line: str) -> tuple[str, str]:
|
|
76
|
+
stripped = line.lstrip(" \t")
|
|
77
|
+
indent_length = len(line) - len(stripped)
|
|
78
|
+
return line[:indent_length], stripped
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _detect_indent_style(indent: str) -> str:
|
|
82
|
+
has_spaces = " " in indent
|
|
83
|
+
has_tabs = "\t" in indent
|
|
84
|
+
|
|
85
|
+
if has_spaces and has_tabs:
|
|
86
|
+
raise TreeParseError("Tree block cannot mix tabs and spaces for indentation.")
|
|
87
|
+
|
|
88
|
+
if has_tabs:
|
|
89
|
+
return "tabs"
|
|
90
|
+
|
|
91
|
+
return "spaces"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _indent_depth(indent: str, indent_style: str) -> int:
|
|
95
|
+
if indent_style == "tabs":
|
|
96
|
+
return len(indent)
|
|
97
|
+
|
|
98
|
+
if len(indent) % 4 != 0:
|
|
99
|
+
raise TreeParseError("Space indentation must use multiples of four spaces.")
|
|
100
|
+
|
|
101
|
+
return len(indent) // 4
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""MkDocs plugin integration for mkdocs-treeblocks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from mkdocs.exceptions import PluginError
|
|
6
|
+
from mkdocs.plugins import BasePlugin
|
|
7
|
+
|
|
8
|
+
from mkdocs_treeblocks.parser import TreeParseError
|
|
9
|
+
from mkdocs_treeblocks.transform import transform_markdown
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TreeblocksPlugin(BasePlugin):
|
|
13
|
+
"""MkDocs plugin that transforms fenced tree blocks before Markdown rendering."""
|
|
14
|
+
|
|
15
|
+
def on_page_markdown(self, markdown: str, **kwargs: object) -> str:
|
|
16
|
+
"""Transform tree blocks in a page's Markdown source."""
|
|
17
|
+
try:
|
|
18
|
+
return transform_markdown(markdown)
|
|
19
|
+
except TreeParseError as error:
|
|
20
|
+
page = kwargs.get("page")
|
|
21
|
+
page_file = getattr(page, "file", None)
|
|
22
|
+
source_path = getattr(page_file, "src_path", None)
|
|
23
|
+
|
|
24
|
+
if source_path:
|
|
25
|
+
message = f"treeblocks failed in {source_path}: {error}"
|
|
26
|
+
else:
|
|
27
|
+
message = f"treeblocks failed: {error}"
|
|
28
|
+
|
|
29
|
+
raise PluginError(message) from error
|
|
30
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from mkdocs_treeblocks.parser import TreeNode
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def render_tree(root: TreeNode) -> str:
|
|
5
|
+
"""Render a parsed tree as plain text using Unicode tree connectors."""
|
|
6
|
+
lines = [root.text]
|
|
7
|
+
|
|
8
|
+
for index, child in enumerate(root.children):
|
|
9
|
+
is_last = index == len(root.children) - 1
|
|
10
|
+
_render_child(
|
|
11
|
+
child,
|
|
12
|
+
lines,
|
|
13
|
+
prefix="",
|
|
14
|
+
is_last=is_last,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
return "\n".join(lines)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _render_child(
|
|
21
|
+
node: TreeNode,
|
|
22
|
+
lines: list[str],
|
|
23
|
+
*,
|
|
24
|
+
prefix: str,
|
|
25
|
+
is_last: bool,
|
|
26
|
+
) -> None:
|
|
27
|
+
connector = "└── " if is_last else "├── "
|
|
28
|
+
lines.append(f"{prefix}{connector}{node.text}")
|
|
29
|
+
|
|
30
|
+
child_prefix = f"{prefix}{' ' if is_last else '│ '}"
|
|
31
|
+
|
|
32
|
+
for index, child in enumerate(node.children):
|
|
33
|
+
_render_child(
|
|
34
|
+
child,
|
|
35
|
+
lines,
|
|
36
|
+
prefix=child_prefix,
|
|
37
|
+
is_last=index == len(node.children) - 1,
|
|
38
|
+
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Markdown transformation helpers for mkdocs-treeblocks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
from mkdocs_treeblocks.parser import TreeParseError, parse_tree
|
|
8
|
+
from mkdocs_treeblocks.renderer import render_tree
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_TREE_FENCE_RE = re.compile(
|
|
12
|
+
r"(?P<opening>^```tree[ \t]*\n)"
|
|
13
|
+
r"(?P<body>.*?)"
|
|
14
|
+
r"(?P<closing>^```[ \t]*$)",
|
|
15
|
+
re.MULTILINE | re.DOTALL,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def transform_markdown(markdown: str) -> str:
|
|
20
|
+
"""Transform fenced tree blocks into rendered fenced text blocks.
|
|
21
|
+
|
|
22
|
+
The source block:
|
|
23
|
+
|
|
24
|
+
```tree
|
|
25
|
+
docs
|
|
26
|
+
index.md
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
becomes:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
docs/
|
|
33
|
+
└── index.md
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Non-tree fenced code blocks are left unchanged.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def replace_tree_block(match: re.Match[str]) -> str:
|
|
40
|
+
tree_source = match.group("body")
|
|
41
|
+
block_line = markdown.count("\n", 0, match.start()) + 1
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
root_nodes = parse_tree(tree_source)
|
|
45
|
+
except TreeParseError as error:
|
|
46
|
+
raise TreeParseError(
|
|
47
|
+
f"tree block starting at line {block_line}: {error}"
|
|
48
|
+
) from error
|
|
49
|
+
|
|
50
|
+
rendered_tree = render_tree(root_nodes)
|
|
51
|
+
|
|
52
|
+
return f"```text\n{rendered_tree}\n```"
|
|
53
|
+
|
|
54
|
+
return _TREE_FENCE_RE.sub(replace_tree_block, markdown)
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mkdocs-treeblocks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A MkDocs extension for rendering tree-style code blocks and directory structures.
|
|
5
|
+
Author: Joshua Mullenberg
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) [2026] [Joshua Mullenberg]
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
License-File: LICENSE.md
|
|
28
|
+
Keywords: directory-structure,documentation,markdown,mkdocs,tree
|
|
29
|
+
Classifier: Development Status :: 3 - Alpha
|
|
30
|
+
Classifier: Framework :: MkDocs
|
|
31
|
+
Classifier: Intended Audience :: Developers
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Topic :: Documentation
|
|
38
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
39
|
+
Requires-Python: >=3.10
|
|
40
|
+
Requires-Dist: markdown>=3.6
|
|
41
|
+
Requires-Dist: mkdocs>=1.6
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
44
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
46
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# mkdocs-treeblocks
|
|
50
|
+
_Revised on: 06-13-2026 by: Joshua Mullenberg_
|
|
51
|
+
|
|
52
|
+
`mkdocs-treeblocks` is a MkDocs plugin for rendering readable tree-style blocks in documentation.
|
|
53
|
+
|
|
54
|
+
The goal is to make directory structures, file trees, project layouts, and related hierarchy examples easier to write, read, and maintain in MkDocs documentation.
|
|
55
|
+
|
|
56
|
+
> [!NOTE]
|
|
57
|
+
> This project is currently in development. Syntax, behavior, and package interfaces are still subject to change.
|
|
58
|
+
|
|
59
|
+
## Initial purpose
|
|
60
|
+
|
|
61
|
+
This project grew from a need to create clean, text-based tree-style blocks directly in documentation using simple Markdown syntax.
|
|
62
|
+
|
|
63
|
+
The goal is to avoid switching to a separate app, copying output from a web tool, manually inserting Unicode tree characters, or wrestling with tree command filters just to produce a curated directory structure for documentation.
|
|
64
|
+
|
|
65
|
+
mkdocs-treeblocks provides a small, predictable syntax that renders tree structures consistently in MkDocs sites.
|
|
66
|
+
|
|
67
|
+
## Syntax
|
|
68
|
+
|
|
69
|
+
Tree blocks are written as fenced Markdown code blocks. Use three backticks (` ``` `) to open and close the block, with `tree` as the language identifier.
|
|
70
|
+
|
|
71
|
+
The plugin converts the indentation into a tree structure, and then formats that structure into a fenced text-block using Unicode tree connectors.
|
|
72
|
+
|
|
73
|
+
Indentation may use either four spaces or one tab per level, but cannot use both indentation styles within the same tree block. Text and spacing after the structural indentation are preserved, allowing filenames, comments, and annotations to remain aligned.
|
|
74
|
+
|
|
75
|
+
Only one root node is allowed per tree block.
|
|
76
|
+
|
|
77
|
+
<table>
|
|
78
|
+
<tr>
|
|
79
|
+
<th>Syntax by example</th>
|
|
80
|
+
<th>Rendered output</th>
|
|
81
|
+
</tr>
|
|
82
|
+
<tr>
|
|
83
|
+
<td>
|
|
84
|
+
<pre><code>
|
|
85
|
+
```tree
|
|
86
|
+
mkdocs-project/
|
|
87
|
+
docs/
|
|
88
|
+
index.md
|
|
89
|
+
...
|
|
90
|
+
mkdocs.yml # mkdocs config
|
|
91
|
+
README.md
|
|
92
|
+
requirements.txt # dependencies
|
|
93
|
+
site/
|
|
94
|
+
404.html
|
|
95
|
+
assets/
|
|
96
|
+
index.html
|
|
97
|
+
...
|
|
98
|
+
```
|
|
99
|
+
</code></pre>
|
|
100
|
+
</td>
|
|
101
|
+
<td>
|
|
102
|
+
<pre><code>
|
|
103
|
+
```text
|
|
104
|
+
mkdocs-project/
|
|
105
|
+
├── docs/
|
|
106
|
+
│ ├── index.md
|
|
107
|
+
│ └── ...
|
|
108
|
+
├── mkdocs.yml # mkdocs config
|
|
109
|
+
├── README.md
|
|
110
|
+
├── requirements.txt # dependencies
|
|
111
|
+
└── site/
|
|
112
|
+
├── 404.html
|
|
113
|
+
├── assets/
|
|
114
|
+
├── index.html
|
|
115
|
+
└── ...
|
|
116
|
+
```
|
|
117
|
+
</code></pre>
|
|
118
|
+
</td>
|
|
119
|
+
</tr>
|
|
120
|
+
</table>
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Installation, testing, and usage
|
|
125
|
+
|
|
126
|
+
Clone the repository, create and activate a virtual environment, then install the project in editable mode with its development dependencies:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
python3 -m venv .venv
|
|
130
|
+
source .venv/bin/activate
|
|
131
|
+
python -m pip install --upgrade pip
|
|
132
|
+
python -m pip install -e ".[dev]"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The editable install registers the treeblocks plugin with MkDocs and allows local source changes to take effect without reinstalling the package.
|
|
136
|
+
|
|
137
|
+
Run the test suite:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
python -m pytest
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Enable the plugin in mkdocs.yml:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
plugins:
|
|
147
|
+
- treeblocks
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Then write a fenced tree block in a Markdown page:
|
|
151
|
+
|
|
152
|
+
````
|
|
153
|
+
```tree
|
|
154
|
+
docs/
|
|
155
|
+
index.md
|
|
156
|
+
guides/
|
|
157
|
+
install.md
|
|
158
|
+
```
|
|
159
|
+
````
|
|
160
|
+
|
|
161
|
+
During the MkDocs build, the plugin transforms the source into a fenced text block containing the rendered tree.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
## Current implementation status
|
|
165
|
+
|
|
166
|
+
Implemented:
|
|
167
|
+
|
|
168
|
+
- Parse indented text into a tree structure with `parse_tree()`.
|
|
169
|
+
- Render a parsed tree as plain text with `render_tree()`.
|
|
170
|
+
- Use Unicode tree connectors such as `├──`, `└──`, and `│`.
|
|
171
|
+
- Preserve original node text, including aligned comments and annotations.
|
|
172
|
+
- Transform fenced Markdown `tree` blocks into rendered fenced `text` blocks with `transform_markdown()`.
|
|
173
|
+
- Leave non-`tree` fenced code blocks unchanged.
|
|
174
|
+
- Integrate with MkDocs through the `treeblocks` plugin.
|
|
175
|
+
- Raise MkDocs `PluginError` for invalid tree blocks.
|
|
176
|
+
- Include the source file and tree-block starting line in MkDocs parse errors when page context is available.
|
|
177
|
+
- Test parser, renderer, Markdown transformer, MkDocs plugin behavior, and Material for MkDocs compatibility with `pytest`.
|
|
178
|
+
- Material for Mkdocs compatibility testing.
|
|
179
|
+
|
|
180
|
+
Potential future enhancements:
|
|
181
|
+
|
|
182
|
+
- Error messages include exact malformed line inside the tree block.
|
|
183
|
+
- Custom HTML rendering.
|
|
184
|
+
- Dedicated CSS styling.
|
|
185
|
+
- Optional automatic directory slash handling.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
## Project Roadmap
|
|
189
|
+
|
|
190
|
+
#### <s>Phase 1: Scaffold and concept</s>
|
|
191
|
+
- <s>Create the project</s>
|
|
192
|
+
- <s>Set up the GitHub repository</s>
|
|
193
|
+
- <s>Document the purpose and syntax</s>
|
|
194
|
+
- <s>Add placeholder tests</s>
|
|
195
|
+
- <s>Create the initial README</s>
|
|
196
|
+
- <s>Make the first commit</s>
|
|
197
|
+
|
|
198
|
+
#### <s>Phase 2: Parser MVP</s>
|
|
199
|
+
- <s>Choose the first supported syntax</s>
|
|
200
|
+
- <s>Parse a small indented tree</s>
|
|
201
|
+
- <s>Add parser tests</s>
|
|
202
|
+
- <s>Add incremental documentation in /docs/</s>
|
|
203
|
+
|
|
204
|
+
#### <s>Phase 3: Renderer MVP</s>
|
|
205
|
+
- <s>Define renderer MVP behavior</s>
|
|
206
|
+
- <s>Add renderer tests</s>
|
|
207
|
+
- <s>Implement a plain Python renderer</s>
|
|
208
|
+
- <s>Document renderer behavior</s>
|
|
209
|
+
|
|
210
|
+
#### <s>Phase 4: Markdown transform MVP</s>
|
|
211
|
+
- <s>Choose fenced `tree` blocks as the first supported Markdown source syntax</s>
|
|
212
|
+
- <s>Detect and transform tree blocks in Markdown</s>
|
|
213
|
+
- <s>Replace transformed tree blocks with fenced `text` blocks</s>
|
|
214
|
+
- <s>Keep the transformer independent from MkDocs integration</s>
|
|
215
|
+
|
|
216
|
+
#### </s>Phase 5: MkDocs plugin MVP</s>
|
|
217
|
+
- <s>Add a minimal MkDocs plugin</s>
|
|
218
|
+
- <s>Register the plugin with MkDocs</s>
|
|
219
|
+
- <s>Add a minimal MkDocs fixture.</s>
|
|
220
|
+
- <s>Add MkDocs integration tests.</s>
|
|
221
|
+
- <s>Wrap parser failures as MkDocs `PluginError`</s>
|
|
222
|
+
|
|
223
|
+
#### <s>Phase 6: Error handling & testing</s>
|
|
224
|
+
- <s>Add source file and tree-block starting line diagnostics for parse errors.</s>
|
|
225
|
+
- <s>Test with Material for MkDocs.</s>
|
|
226
|
+
|
|
227
|
+
#### Phase 7: Publish initial release
|
|
228
|
+
- Finalize package metadata in `pyproject.toml`.
|
|
229
|
+
- Install build tooling and create distribution packages.
|
|
230
|
+
- Test the built wheel in a clean virtual environment
|
|
231
|
+
- Publish the release to PyPI
|
|
232
|
+
|
|
233
|
+
#### Phase 8: Documentation Polish
|
|
234
|
+
- Update current documentation.
|
|
235
|
+
- Verify documentation includes installation, usage, and examples.
|
|
236
|
+
- Document limitations and troubleshooting notes.
|
|
237
|
+
- Set up GitHub issue and feature-request tracking.
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
mkdocs_treeblocks/__init__.py,sha256=r8eHWhFTpL4M3lcba_HyM67OZ_4Tz2-2GXh1zIexCAg,37
|
|
2
|
+
mkdocs_treeblocks/parser.py,sha256=3ZC_GUpGqABoqthYMSUrbbhY1y3jpwrdOZuDEf4W6UA,2679
|
|
3
|
+
mkdocs_treeblocks/plugin.py,sha256=saO1lODV5ofi9mQ_vBm2MY6mjTY5oBjbdxA8uYAvbUE,1039
|
|
4
|
+
mkdocs_treeblocks/renderer.py,sha256=R6m6UaJZD4g9SyGjFgxZUiHTce17Z3Q1rYnzpT8czd8,940
|
|
5
|
+
mkdocs_treeblocks/transform.py,sha256=uk7T1EUO4CB-Cr9SOx6qaNsgWWV38GEuxiq3wEynTmQ,1280
|
|
6
|
+
mkdocs_treeblocks-0.1.0.dist-info/METADATA,sha256=CHdoYP5TjWaG5r2HkmdPSN2H01j2OUhWv7WFaTMKHpw,8428
|
|
7
|
+
mkdocs_treeblocks-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
8
|
+
mkdocs_treeblocks-0.1.0.dist-info/entry_points.txt,sha256=YqYCqZeMF-toHM7cVnEslaJ0QGOgGUostWEfe0Lifv8,72
|
|
9
|
+
mkdocs_treeblocks-0.1.0.dist-info/licenses/LICENSE.md,sha256=DA7SnOsKY-fPaE3w7WZ--yEDWFo5gC4sVoSKuwWqlkY,1078
|
|
10
|
+
mkdocs_treeblocks-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2026] [Joshua Mullenberg]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|