mkforge 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- {mkforge-0.2.0 → mkforge-0.3.0}/PKG-INFO +22 -1
- {mkforge-0.2.0 → mkforge-0.3.0}/README.md +21 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/API_REFERENCE.md +176 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/USER_GUIDE.md +83 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/pyproject.toml +1 -1
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/__init__.py +9 -1
- mkforge-0.3.0/src/mkforge/heading_numbering.py +320 -0
- mkforge-0.3.0/tests/test_heading_numbering.py +263 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/uv.lock +1 -1
- {mkforge-0.2.0 → mkforge-0.3.0}/.github/workflows/ci.yml +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/.github/workflows/publish.yml +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/.gitignore +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/.gitlab-ci.yml +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/.mkforge +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/.python-version +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/AGENTS.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/CLAUDE.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/LICENSE +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/Makefile +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/demo_report.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/demo_validation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/demo_verif.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/doc/adr-001-markdown-conformance-verifier.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/MARKDOWN_RULES.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/SDD.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/SRS.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/adr/ADR-001-asset-management.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/adr/ADR-002-markdown-validation-contracts.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/docs/pypi-publication.md +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/main.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/_metadata.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/assets.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/_base.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/code.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/image.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/lists.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/misc.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/paragraph.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/table.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/content/text.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/document.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/errors.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/input_checks.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/py.typed +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/rendering.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/slugify.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/validation/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/validation/markdown_contracts.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/api.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/diagnostic_pattern.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/policy.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/registry.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/gfm/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/gfm/gfm001_table_delimiter.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/gfm/gfm002_table_column_count.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/gfm/gfm003_task_list_marker.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/_shared.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/markdownlint_remaining.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md001_heading_increment.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md002_first_heading_level.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md003_heading_style.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md004_unordered_list_style.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md005_md006_md007_list_indentation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md009_trailing_spaces.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md010_hard_tabs.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md011_reversed_link_syntax.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md012_multiple_blank_lines.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md013_line_length.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md014_command_prompt.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md018_atx_heading_space.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md019_md021_atx_closed_spaces.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md020_closed_atx_heading_space.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md022_md023_heading_blanks.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md024_md025_duplicate_headings.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md026_heading_punctuation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md027_md028_blockquote.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md029_md030_list_prefix.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md031_md032_fence_list_blanks.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md033_inline_html.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md034_bare_url.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md035_horizontal_rule.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md036_emphasis_heading.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md037_emphasis_marker_space.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md038_code_span_space.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md039_link_text_space.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/md040_md041_md046_md047_blocks.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/rules/markdown/mkf001_local_resource_exists.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/settings.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/src/mkforge/verification/source_scan.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/__init__.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/conftest.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/expectations.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_assets.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_e2e.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_e2e_verification.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_helpers.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_markdown_validation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_markdown_verification.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_metadata.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_report_generation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_slugify.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/tests/test_validation.py +0 -0
- {mkforge-0.2.0 → mkforge-0.3.0}/work/.gitkeep +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkforge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Programmatic Markdown report generation for Python.
|
|
5
5
|
Project-URL: Homepage, https://github.com/antoinebarre/mkforge
|
|
6
6
|
Project-URL: Repository, https://github.com/antoinebarre/mkforge
|
|
@@ -161,6 +161,27 @@ collapsed to a single hyphen, leading/trailing hyphens trimmed. Unicode
|
|
|
161
161
|
letters are preserved (case-folded, not transliterated), which keeps slugs
|
|
162
162
|
consistent with the anchors GitHub generates for the same heading.
|
|
163
163
|
|
|
164
|
+
## Heading Numbering
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from mkforge import renumber_markdown_headings, strip_markdown_heading_numbering
|
|
168
|
+
|
|
169
|
+
markdown = "# 9. Document\n## 4. Titre 1\n### 8. Tritre niveau 2\n"
|
|
170
|
+
|
|
171
|
+
strip_markdown_heading_numbering(markdown)
|
|
172
|
+
# "# Document\n## Titre 1\n### Tritre niveau 2\n"
|
|
173
|
+
|
|
174
|
+
renumber_markdown_headings(markdown, start_level=2)
|
|
175
|
+
# "# Document\n## 1. Titre 1\n### 1.1. Tritre niveau 2\n"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
`strip_markdown_heading_numbering` and `renumber_markdown_headings` are pure
|
|
179
|
+
Markdown helpers for doc-as-code pipelines. They modify only ATX headings
|
|
180
|
+
outside fenced code blocks, preserve heading levels, and can start numbering
|
|
181
|
+
at a chosen level with `start_level`. Use `first_number` to start a fragment
|
|
182
|
+
at a later number, and `separator` to control the text between number and
|
|
183
|
+
title.
|
|
184
|
+
|
|
164
185
|
## Relationship With Scribpy
|
|
165
186
|
|
|
166
187
|
MkForge is intended to be independent from Scribpy.
|
|
@@ -146,6 +146,27 @@ collapsed to a single hyphen, leading/trailing hyphens trimmed. Unicode
|
|
|
146
146
|
letters are preserved (case-folded, not transliterated), which keeps slugs
|
|
147
147
|
consistent with the anchors GitHub generates for the same heading.
|
|
148
148
|
|
|
149
|
+
## Heading Numbering
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from mkforge import renumber_markdown_headings, strip_markdown_heading_numbering
|
|
153
|
+
|
|
154
|
+
markdown = "# 9. Document\n## 4. Titre 1\n### 8. Tritre niveau 2\n"
|
|
155
|
+
|
|
156
|
+
strip_markdown_heading_numbering(markdown)
|
|
157
|
+
# "# Document\n## Titre 1\n### Tritre niveau 2\n"
|
|
158
|
+
|
|
159
|
+
renumber_markdown_headings(markdown, start_level=2)
|
|
160
|
+
# "# Document\n## 1. Titre 1\n### 1.1. Tritre niveau 2\n"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`strip_markdown_heading_numbering` and `renumber_markdown_headings` are pure
|
|
164
|
+
Markdown helpers for doc-as-code pipelines. They modify only ATX headings
|
|
165
|
+
outside fenced code blocks, preserve heading levels, and can start numbering
|
|
166
|
+
at a chosen level with `start_level`. Use `first_number` to start a fragment
|
|
167
|
+
at a later number, and `separator` to control the text between number and
|
|
168
|
+
title.
|
|
169
|
+
|
|
149
170
|
## Relationship With Scribpy
|
|
150
171
|
|
|
151
172
|
MkForge is intended to be independent from Scribpy.
|
|
@@ -21,7 +21,10 @@ from mkforge import (
|
|
|
21
21
|
Report,
|
|
22
22
|
Section,
|
|
23
23
|
Table,
|
|
24
|
+
renumber_markdown_headings,
|
|
24
25
|
slugify_heading,
|
|
26
|
+
strip_heading_numbering_text,
|
|
27
|
+
strip_markdown_heading_numbering,
|
|
25
28
|
validate_markdown_chapters,
|
|
26
29
|
validate_markdown_headings,
|
|
27
30
|
validate_markdown_images,
|
|
@@ -97,6 +100,9 @@ Module-level helpers are documented for advanced integrations and tests.
|
|
|
97
100
|
| `validate_markdown_headings` | `mkforge` | validation | Check level/title heading contract |
|
|
98
101
|
| `validate_markdown_images` | `mkforge` | validation/assets | Check Markdown image targets |
|
|
99
102
|
| `slugify_heading` | `mkforge` | text | Convert a heading title to a GitHub-style anchor slug |
|
|
103
|
+
| `strip_heading_numbering_text` | `mkforge` | text | Remove a numeric prefix from heading text |
|
|
104
|
+
| `strip_markdown_heading_numbering` | `mkforge` | text | Remove numeric prefixes from ATX headings |
|
|
105
|
+
| `renumber_markdown_headings` | `mkforge` | text | Rebuild ATX heading numbering by hierarchy |
|
|
100
106
|
| `InvalidChildError` | `mkforge` | errors | Unsupported report-tree child |
|
|
101
107
|
| `InvalidTableError` | `mkforge` | errors | Invalid table shape |
|
|
102
108
|
| `ReportDepthError` | `mkforge` | errors | Section nesting below H6 |
|
|
@@ -1108,6 +1114,176 @@ separator). Use `slugify_heading` for anchors shared with external tools;
|
|
|
1108
1114
|
|
|
1109
1115
|
---
|
|
1110
1116
|
|
|
1117
|
+
## 6.8 `mkforge.heading_numbering` Helpers
|
|
1118
|
+
|
|
1119
|
+
These helpers normalize numeric prefixes on Markdown headings. They are pure,
|
|
1120
|
+
deterministic, perform no I/O, and are useful for doc-as-code assemblers that
|
|
1121
|
+
merge Markdown fragments before publishing.
|
|
1122
|
+
|
|
1123
|
+
All document-level helpers:
|
|
1124
|
+
|
|
1125
|
+
- modify only ATX headings (`#` through `######`);
|
|
1126
|
+
- ignore fenced code blocks;
|
|
1127
|
+
- preserve non-heading lines;
|
|
1128
|
+
- preserve heading levels;
|
|
1129
|
+
- strip old numeric prefixes before adding new ones.
|
|
1130
|
+
|
|
1131
|
+
### 6.8.1 `strip_heading_numbering_text`
|
|
1132
|
+
|
|
1133
|
+
Module: `mkforge.heading_numbering`
|
|
1134
|
+
|
|
1135
|
+
Exported by: `mkforge`
|
|
1136
|
+
|
|
1137
|
+
Signature:
|
|
1138
|
+
|
|
1139
|
+
```python
|
|
1140
|
+
strip_heading_numbering_text(text: str) -> str
|
|
1141
|
+
```
|
|
1142
|
+
|
|
1143
|
+
Removes one leading numeric heading prefix from a heading title.
|
|
1144
|
+
|
|
1145
|
+
Examples:
|
|
1146
|
+
|
|
1147
|
+
```python
|
|
1148
|
+
from mkforge import strip_heading_numbering_text
|
|
1149
|
+
|
|
1150
|
+
strip_heading_numbering_text("1. Introduction") # "Introduction"
|
|
1151
|
+
strip_heading_numbering_text("1.2 Architecture") # "Architecture"
|
|
1152
|
+
strip_heading_numbering_text("1.2.3 - Design") # "Design"
|
|
1153
|
+
strip_heading_numbering_text("2026 Roadmap") # "2026 Roadmap"
|
|
1154
|
+
strip_heading_numbering_text("Version 2.0") # "Version 2.0"
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
Raises:
|
|
1158
|
+
|
|
1159
|
+
| Condition | Exception |
|
|
1160
|
+
|---|---|
|
|
1161
|
+
| `text` is not a string | `TypeError` |
|
|
1162
|
+
|
|
1163
|
+
### 6.8.2 `strip_markdown_heading_numbering`
|
|
1164
|
+
|
|
1165
|
+
Module: `mkforge.heading_numbering`
|
|
1166
|
+
|
|
1167
|
+
Exported by: `mkforge`
|
|
1168
|
+
|
|
1169
|
+
Signature:
|
|
1170
|
+
|
|
1171
|
+
```python
|
|
1172
|
+
strip_markdown_heading_numbering(markdown: str) -> str
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
Removes numeric prefixes from ATX headings in a complete Markdown document.
|
|
1176
|
+
|
|
1177
|
+
Example:
|
|
1178
|
+
|
|
1179
|
+
````python
|
|
1180
|
+
from mkforge import strip_markdown_heading_numbering
|
|
1181
|
+
|
|
1182
|
+
markdown = """# 1. Introduction
|
|
1183
|
+
|
|
1184
|
+
## 1.3 Architecture
|
|
1185
|
+
|
|
1186
|
+
```python
|
|
1187
|
+
# 1. This must not change
|
|
1188
|
+
```
|
|
1189
|
+
"""
|
|
1190
|
+
|
|
1191
|
+
strip_markdown_heading_numbering(markdown)
|
|
1192
|
+
````
|
|
1193
|
+
|
|
1194
|
+
Result:
|
|
1195
|
+
|
|
1196
|
+
````markdown
|
|
1197
|
+
# Introduction
|
|
1198
|
+
|
|
1199
|
+
## Architecture
|
|
1200
|
+
|
|
1201
|
+
```python
|
|
1202
|
+
# 1. This must not change
|
|
1203
|
+
```
|
|
1204
|
+
````
|
|
1205
|
+
|
|
1206
|
+
Raises:
|
|
1207
|
+
|
|
1208
|
+
| Condition | Exception |
|
|
1209
|
+
|---|---|
|
|
1210
|
+
| `markdown` is not a string | `TypeError` |
|
|
1211
|
+
|
|
1212
|
+
### 6.8.3 `renumber_markdown_headings`
|
|
1213
|
+
|
|
1214
|
+
Module: `mkforge.heading_numbering`
|
|
1215
|
+
|
|
1216
|
+
Exported by: `mkforge`
|
|
1217
|
+
|
|
1218
|
+
Signature:
|
|
1219
|
+
|
|
1220
|
+
```python
|
|
1221
|
+
renumber_markdown_headings(
|
|
1222
|
+
markdown: str,
|
|
1223
|
+
*,
|
|
1224
|
+
separator: str = ". ",
|
|
1225
|
+
first_number: int = 1,
|
|
1226
|
+
start_level: int = 1,
|
|
1227
|
+
) -> str
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
Removes old numeric prefixes from ATX headings, then generates coherent
|
|
1231
|
+
hierarchical numbering.
|
|
1232
|
+
|
|
1233
|
+
Parameters:
|
|
1234
|
+
|
|
1235
|
+
| Parameter | Type | Default | Description |
|
|
1236
|
+
|---|---|---|---|
|
|
1237
|
+
| `markdown` | `str` | required | Markdown source text |
|
|
1238
|
+
| `separator` | `str` | `". "` | Text inserted between the number and title |
|
|
1239
|
+
| `first_number` | `int` | `1` | First number generated at the configured root level |
|
|
1240
|
+
| `start_level` | `int` | `1` | First heading level that receives generated numbering |
|
|
1241
|
+
|
|
1242
|
+
Examples:
|
|
1243
|
+
|
|
1244
|
+
```python
|
|
1245
|
+
from mkforge import renumber_markdown_headings
|
|
1246
|
+
|
|
1247
|
+
renumber_markdown_headings("# 9. Intro\n## 4. Detail\n")
|
|
1248
|
+
# "# 1. Intro\n## 1.1. Detail\n"
|
|
1249
|
+
|
|
1250
|
+
renumber_markdown_headings("# Intro\n## Detail\n", first_number=4)
|
|
1251
|
+
# "# 4. Intro\n## 4.1. Detail\n"
|
|
1252
|
+
|
|
1253
|
+
renumber_markdown_headings("# Document\n## Titre\n### Détail\n", start_level=2)
|
|
1254
|
+
# "# Document\n## 1. Titre\n### 1.1. Détail\n"
|
|
1255
|
+
|
|
1256
|
+
renumber_markdown_headings("## Titre\n### Détail\n", first_number=4, start_level=2)
|
|
1257
|
+
# "## 4. Titre\n### 4.1. Détail\n"
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
The `separator` controls only the text between the generated number and the
|
|
1261
|
+
title:
|
|
1262
|
+
|
|
1263
|
+
| `separator` | Heading output |
|
|
1264
|
+
|---|---|
|
|
1265
|
+
| `". "` | `# 1. Title` |
|
|
1266
|
+
| `" "` | `# 1 Title` |
|
|
1267
|
+
| `" - "` | `# 1 - Title` |
|
|
1268
|
+
| `""` | `# 1Title` |
|
|
1269
|
+
|
|
1270
|
+
When `start_level=2`, H1 headings are cleaned but not numbered. H2 headings
|
|
1271
|
+
become numeric roots (`1`, `2`, ...), and H3 headings become children
|
|
1272
|
+
(`1.1`, `1.2`, ...).
|
|
1273
|
+
|
|
1274
|
+
Raises:
|
|
1275
|
+
|
|
1276
|
+
| Condition | Exception |
|
|
1277
|
+
|---|---|
|
|
1278
|
+
| `markdown` is not a string | `TypeError` |
|
|
1279
|
+
| `separator` is not a string | `TypeError` |
|
|
1280
|
+
| `first_number` is not an integer | `TypeError` |
|
|
1281
|
+
| `start_level` is not an integer | `TypeError` |
|
|
1282
|
+
| `first_number` is less than 1 | `ValueError` |
|
|
1283
|
+
| `start_level` is outside 1-6 | `ValueError` |
|
|
1284
|
+
|
|
1285
|
+
---
|
|
1286
|
+
|
|
1111
1287
|
## 7. Metadata Reference
|
|
1112
1288
|
|
|
1113
1289
|
Metadata is a free-form dictionary. MkForge does not define allowed keys.
|
|
@@ -29,6 +29,7 @@ For exhaustive class, function, helper, rule, and feature contracts, see
|
|
|
29
29
|
- [Verification](#verification)
|
|
30
30
|
- [Validation](#validation)
|
|
31
31
|
- [Heading Slugification](#heading-slugification)
|
|
32
|
+
- [Heading Numbering](#heading-numbering)
|
|
32
33
|
- [Assets](#assets)
|
|
33
34
|
- [Errors](#errors)
|
|
34
35
|
- [Patterns And Recommendations](#patterns-and-recommendations)
|
|
@@ -91,6 +92,16 @@ For heading anchor slugs:
|
|
|
91
92
|
from mkforge import slugify_heading
|
|
92
93
|
```
|
|
93
94
|
|
|
95
|
+
For cleaning and rebuilding Markdown heading numbering:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from mkforge import (
|
|
99
|
+
renumber_markdown_headings,
|
|
100
|
+
strip_heading_numbering_text,
|
|
101
|
+
strip_markdown_heading_numbering,
|
|
102
|
+
)
|
|
103
|
+
```
|
|
104
|
+
|
|
94
105
|
## How To Think About MkForge
|
|
95
106
|
|
|
96
107
|
MkForge has three jobs:
|
|
@@ -1009,6 +1020,78 @@ Behavior:
|
|
|
1009
1020
|
This matches the anchors GitHub generates for the same heading text, so a
|
|
1010
1021
|
link such as `[Analyse des Risques](#analyse-des-risques)` stays valid.
|
|
1011
1022
|
|
|
1023
|
+
## Heading Numbering
|
|
1024
|
+
|
|
1025
|
+
Use the heading numbering helpers when a documentation pipeline assembles
|
|
1026
|
+
Markdown fragments and must clean or rebuild heading numbers before publishing.
|
|
1027
|
+
|
|
1028
|
+
````python
|
|
1029
|
+
from mkforge import (
|
|
1030
|
+
renumber_markdown_headings,
|
|
1031
|
+
strip_markdown_heading_numbering,
|
|
1032
|
+
)
|
|
1033
|
+
|
|
1034
|
+
markdown = """# 9. Document
|
|
1035
|
+
## 4. Titre 1
|
|
1036
|
+
### 8. Tritre niveau 2
|
|
1037
|
+
|
|
1038
|
+
```markdown
|
|
1039
|
+
## 99. This must not change
|
|
1040
|
+
```
|
|
1041
|
+
"""
|
|
1042
|
+
|
|
1043
|
+
strip_markdown_heading_numbering(markdown)
|
|
1044
|
+
renumber_markdown_headings(markdown, start_level=2)
|
|
1045
|
+
````
|
|
1046
|
+
|
|
1047
|
+
With `start_level=2`, H1 headings are cleaned but not numbered, H2 headings
|
|
1048
|
+
become numeric roots, and H3 headings become their children:
|
|
1049
|
+
|
|
1050
|
+
````markdown
|
|
1051
|
+
# Document
|
|
1052
|
+
## 1. Titre 1
|
|
1053
|
+
### 1.1. Tritre niveau 2
|
|
1054
|
+
|
|
1055
|
+
```markdown
|
|
1056
|
+
## 99. This must not change
|
|
1057
|
+
```
|
|
1058
|
+
````
|
|
1059
|
+
|
|
1060
|
+
The document-level helpers:
|
|
1061
|
+
|
|
1062
|
+
- modify only ATX headings (`#` through `######`);
|
|
1063
|
+
- ignore fenced code blocks;
|
|
1064
|
+
- preserve non-heading lines;
|
|
1065
|
+
- preserve heading levels;
|
|
1066
|
+
- strip old numbering before adding new numbering.
|
|
1067
|
+
|
|
1068
|
+
Use `first_number` when the fragment belongs later in a larger document:
|
|
1069
|
+
|
|
1070
|
+
```python
|
|
1071
|
+
renumber_markdown_headings(markdown, first_number=4, start_level=2)
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
That starts numbering at the configured root level:
|
|
1075
|
+
|
|
1076
|
+
```markdown
|
|
1077
|
+
## 4. Titre 1
|
|
1078
|
+
### 4.1. Tritre niveau 2
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
Use `separator` to control the text between the generated number and the
|
|
1082
|
+
title:
|
|
1083
|
+
|
|
1084
|
+
```python
|
|
1085
|
+
renumber_markdown_headings(markdown, separator=" - ")
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
Examples:
|
|
1089
|
+
|
|
1090
|
+
- `separator=". "` renders `# 1. Title`;
|
|
1091
|
+
- `separator=" "` renders `# 1 Title`;
|
|
1092
|
+
- `separator=" - "` renders `# 1 - Title`;
|
|
1093
|
+
- `separator=""` renders `# 1Title`.
|
|
1094
|
+
|
|
1012
1095
|
## Assets
|
|
1013
1096
|
|
|
1014
1097
|
MkForge treats image references carefully:
|
|
@@ -22,6 +22,11 @@ from mkforge.errors import (
|
|
|
22
22
|
MissingAssetError,
|
|
23
23
|
ReportDepthError,
|
|
24
24
|
)
|
|
25
|
+
from mkforge.heading_numbering import (
|
|
26
|
+
renumber_markdown_headings,
|
|
27
|
+
strip_heading_numbering_text,
|
|
28
|
+
strip_markdown_heading_numbering,
|
|
29
|
+
)
|
|
25
30
|
from mkforge.slugify import slugify_heading
|
|
26
31
|
from mkforge.validation import (
|
|
27
32
|
validate_markdown_chapters,
|
|
@@ -68,7 +73,10 @@ __all__ = [
|
|
|
68
73
|
"Text",
|
|
69
74
|
"VerificationReport",
|
|
70
75
|
"VerificationSettings",
|
|
76
|
+
"renumber_markdown_headings",
|
|
71
77
|
"slugify_heading",
|
|
78
|
+
"strip_heading_numbering_text",
|
|
79
|
+
"strip_markdown_heading_numbering",
|
|
72
80
|
"validate_markdown_chapters",
|
|
73
81
|
"validate_markdown_headings",
|
|
74
82
|
"validate_markdown_images",
|
|
@@ -77,4 +85,4 @@ __all__ = [
|
|
|
77
85
|
"verify_markdown_file",
|
|
78
86
|
]
|
|
79
87
|
|
|
80
|
-
__version__ = "0.
|
|
88
|
+
__version__ = "0.3.0"
|