MkForge
Programmatic Markdown report generation for Python.
MkForge is a small Python toolkit for building structured, reproducible Markdown reports from code.
It provides composable report primitives such as sections, paragraphs, tables, figures, metadata, checksums, and renderers so automation scripts can produce readable Markdown artifacts without hand-written string assembly.
Use Cases
- Quality gate reports
- CI and release summaries
- Code metrics reports
- Dependency audit reports
- Generated technical appendices
- Reproducible Markdown artifacts for documentation pipelines
Scope
MkForge focuses on generating Markdown documents from structured Python data.
It is not:
- a Markdown project compiler;
- a static site generator;
- a CI runner;
- a replacement for documentation tools such as MkDocs.
Those tools can use MkForge as their reporting layer.
Installation
uv sync
Development
make check
make check runs formatting, Ruff, Flake8, docstring checks, Mypy, code
metrics, security checks, tests, and 100% coverage validation.
For CI-style non-mutating checks:
make ci
For package validation before publishing:
make check-dist
Temporary quality reports are written under work/reports/. Packaging checks
build distributions under work/dist/. The work/ directory is kept in the
repository with work/.gitkeep.
Example
from mkforge import Chapter, Paragraph, Report, Section, Table
report = Report(
title="Quality Report",
metadata={"title": "Quality Report", "tags": ["quality", "ci"]},
toc=True,
).add(
Chapter("Summary").add(
Section("Checks").add(
Paragraph("All checks passed."),
Table.from_columns(
{
"Check": ("format", "lint", "tests"),
"Status": ("pass", "pass", "pass"),
},
),
),
),
)
markdown = report.render()
Markdown Verification
from mkforge import verify_markdown
report = verify_markdown("# Title\n\n| A | B |\n| --- | --- |\n")
Verification covers pure Markdown and GitHub Flavored Markdown conformance in a single pass. Custom rule callables can be appended for one verification call without mutating the built-in policy.
Markdown Validation
from mkforge import (
validate_markdown_chapters,
validate_markdown_headings,
validate_markdown_images,
validate_markdown_yaml,
)
ok = (
validate_markdown_yaml(markdown, {"draft": False})
and validate_markdown_chapters(markdown, ("Summary", "Details"))
and validate_markdown_headings(markdown, ((2, "Summary"), (3, "Checks")))
and validate_markdown_images(markdown, base_path="docs/report.md")
)
Validation answers project-specific boolean questions: expected YAML
frontmatter, required H2 chapters in order, heading level/title sequences, and
local or HTTP(S) image existence. Use strict=True for exact YAML keys or exact
heading and chapter sequences.
Runnable demos:
uv run python demo_report.py
uv run python demo_verif.py
uv run python demo_validation.py
Heading Slugification
from mkforge import slugify_heading
slugify_heading("Analyse des Risques") # "analyse-des-risques"
slugify_heading("`code` inline") # "code-inline"
slugify_heading converts a raw heading title into a GitHub-style anchor
slug: lowercase, inline Markdown markers removed, non-alphanumeric runs
collapsed to a single hyphen, leading/trailing hyphens trimmed. Unicode
letters are preserved (case-folded, not transliterated), which keeps slugs
consistent with the anchors GitHub generates for the same heading.
Heading Numbering
from mkforge import renumber_markdown_headings, strip_markdown_heading_numbering
markdown = "# 9. Document\n## 4. Titre 1\n### 8. Tritre niveau 2\n"
strip_markdown_heading_numbering(markdown)
# "# Document\n## Titre 1\n### Tritre niveau 2\n"
renumber_markdown_headings(markdown, start_level=2)
# "# Document\n## 1. Titre 1\n### 1.1. Tritre niveau 2\n"
strip_markdown_heading_numbering and renumber_markdown_headings are pure
Markdown helpers for doc-as-code pipelines. They modify only ATX headings
outside fenced code blocks, preserve heading levels, and can start numbering
at a chosen level with start_level. Use first_number to start a fragment
at a later number, and separator to control the text between number and
title.
Relationship With Scribpy
MkForge is intended to be independent from Scribpy.
mkforgegenerates Markdown reports from Python data.scribpyassembles and builds Markdown documentation projects.yggtoolsinitializes and runs quality gates for Python packages usinguv.
Scribpy and yggtools may depend on MkForge for generated reports, but MkForge should not depend on either of them.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mkforge-0.4.0.tar.gz.
File metadata
- Download URL: mkforge-0.4.0.tar.gz
- Upload date:
- Size: 202.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc6e95030195daf486dc0166f7564343d35778cc05f7de4d39eb935dea78d9e3
|
|
| MD5 |
c57e67925ac13c65dc349d4a65cc77a1
|
|
| BLAKE2b-256 |
dc29078ca65fcc1ec3ba6c3d67c3cf24153fe02d04b61992aba7e547cb9695dd
|
Provenance
The following attestation bundles were made for mkforge-0.4.0.tar.gz:
Publisher:
publish.yml on antoinebarre/mkforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mkforge-0.4.0.tar.gz -
Subject digest:
cc6e95030195daf486dc0166f7564343d35778cc05f7de4d39eb935dea78d9e3 - Sigstore transparency entry: 2169019605
- Sigstore integration time:
-
Permalink:
antoinebarre/mkforge@aba63ab8b0f6b255ba0f5a02242f8c1721b28101 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/antoinebarre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aba63ab8b0f6b255ba0f5a02242f8c1721b28101 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mkforge-0.4.0-py3-none-any.whl.
File metadata
- Download URL: mkforge-0.4.0-py3-none-any.whl
- Upload date:
- Size: 80.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc1616a2c7cf19bce499a86f74b45b68f35e74b4b7fb23fef56259dcc15bcd55
|
|
| MD5 |
1ead21a7cb45ff418e128c570cb44ea2
|
|
| BLAKE2b-256 |
9b721f96c0ae8bb43360ac65b4e38b8ed30934343f96b590bfc11bdd58dc1858
|
Provenance
The following attestation bundles were made for mkforge-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on antoinebarre/mkforge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mkforge-0.4.0-py3-none-any.whl -
Subject digest:
cc1616a2c7cf19bce499a86f74b45b68f35e74b4b7fb23fef56259dcc15bcd55 - Sigstore transparency entry: 2169019626
- Sigstore integration time:
-
Permalink:
antoinebarre/mkforge@aba63ab8b0f6b255ba0f5a02242f8c1721b28101 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/antoinebarre
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aba63ab8b0f6b255ba0f5a02242f8c1721b28101 -
Trigger Event:
push
-
Statement type: