Skip to main content

A pure-Python library for programmatically generating Markdown files.

Project description

MarkdownPal

A pure-Python library for programmatically generating Markdown (.md) files via a clean, block-based document builder API.

Python License: MIT


Features

  • Block-based API — compose documents from typed, self-contained block objects
  • Inline formatting helpersbold(), italic(), code(), strikethrough()
  • Full block support — headings, paragraphs, quotes, code, lists, tables, images, links
  • Save to file — UTF-8 output with full support for international characters and emoji
  • Zero dependencies — no third-party packages required
  • Python 3.9+

Installation

pip3 install markdownpal

Quick Start

from markdownpal import Document
from markdownpal.blocks import H1Block, H2Block, TextBlock, CodeBlock, ULBlock
from markdownpal.inline import bold

doc = Document()

doc.append(H1Block("My Project"))
doc.append(TextBlock(f"A {bold('simple')} example of MarkdownPal."))
doc.append(H2Block("Installation"))
doc.append(CodeBlock("pip install markdownpal", lang="bash"))
doc.append(H2Block("Features"))
doc.append(ULBlock(["Zero dependencies", "Clean API", "Python 3.9+"]))

doc.save("output.md")

Output (output.md):

# My Project

A **simple** example of MarkdownPal.

## Installation

```bash
pip install markdownpal

Features

  • Zero dependencies
  • Clean API
  • Python 3.9+

---

## Block Reference

### Headings

```python
from markdownpal.blocks import H1Block, H2Block, H3Block, H4Block, H5Block, H6Block

doc.append(H1Block("Title"))       # # Title
doc.append(H2Block("Section"))     # ## Section
doc.append(H3Block("Subsection"))  # ### Subsection

Text

from markdownpal.blocks import TextBlock, QuoteBlock, HRBlock, CommentBlock

doc.append(TextBlock("A plain paragraph."))
doc.append(QuoteBlock("A blockquote.\nSpanning multiple lines."))
doc.append(HRBlock())                               # ---
doc.append(CommentBlock("Hidden in rendered output."))  # <!-- ... -->

Code

from markdownpal.blocks import CodeBlock

doc.append(CodeBlock("print('hello')", lang="python"))
doc.append(CodeBlock("SELECT * FROM users;", lang="sql"))
doc.append(CodeBlock("no language specified"))

Lists

from markdownpal.blocks import ULBlock, OLBlock, TaskListBlock

doc.append(ULBlock(["Apples", "Bananas", "Cherries"]))

doc.append(OLBlock(["Install", "Configure", "Run"]))

doc.append(TaskListBlock([
    ("Write tests", True),
    ("Write code", True),
    ("Deploy",      False),
]))

Table

from markdownpal.blocks import TableBlock

doc.append(TableBlock(
    headers=["Name", "Role", "Status"],
    rows=[
        ["Alice", "Engineer", "Active"],
        ["Bob",   "Designer", "Active"],
    ]
))

Images & Links

from markdownpal.blocks import ImageBlock, LinkBlock

doc.append(ImageBlock(src="logo.png", alt="Project Logo"))
doc.append(LinkBlock(text="Documentation", url="https://example.com/docs"))

Inline Helpers

Inline helpers return plain strings and can be embedded inside any block content:

from markdownpal.inline import bold, italic, code, strikethrough

bold("important")            # **important**
italic("note")               # *note*
code("os.path.join()")       # `os.path.join()`
strikethrough("deprecated")  # ~~deprecated~~

# Composable
bold(italic("emphasis"))     # ***emphasis***

# Embed in blocks
doc.append(TextBlock(f"Call {code('render()')} to get the output string."))

Document API

doc = Document()
doc.append(block)   # Add a Block instance
doc.render()        # Returns the full Markdown string
doc.save("out.md")  # Writes UTF-8 Markdown file to disk

append() raises TypeError if the argument is not a Block instance.
render() joins all blocks with a blank line (\n\n) between them.


Project Structure

markdownpal/
├── __init__.py          # Top-level public API
├── document.py          # Document class
├── inline.py            # Inline format helpers
└── blocks/
    ├── base.py          # Block abstract base class
    ├── heading.py       # H1Block ~ H6Block
    ├── text.py          # TextBlock, QuoteBlock, HRBlock, CommentBlock
    ├── code.py          # CodeBlock
    ├── list_.py         # ULBlock, OLBlock, TaskListBlock
    ├── table.py         # TableBlock
    └── media.py         # ImageBlock, LinkBlock

Development

# Clone the repository
git clone https://github.com/rogerstacker/markdownpal.git
cd markdownpal

# Install dev dependencies
pip3 install -e ".[dev]"

# Run tests
pytest

License

MIT © 2026 Rogerstacker

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markdownpal-0.1.0.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markdownpal-0.1.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file markdownpal-0.1.0.tar.gz.

File metadata

  • Download URL: markdownpal-0.1.0.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for markdownpal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ced132280f316c8bbbad9dfeb4b8bbdd651489654d0ffdbdfe75a0a93c56d8a1
MD5 34aaf642e66ccefb3427d9e8bcfb0bdd
BLAKE2b-256 3e347e09269eb01aab74a3dda5ec58f065ef61ae771fb6f7c156bbe597a20170

See more details on using hashes here.

File details

Details for the file markdownpal-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: markdownpal-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for markdownpal-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cb21547577bbee7515109ae3ae92b80a4d9c1daf23a9dca681b3ed09b93d2f19
MD5 0c0e0287d747558198e7032be108b157
BLAKE2b-256 d60832a6fe9dfd322d5042a76cf929daef2fb68f1dabdb7d4e3afc370efe0a8e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page