Name | markdown-parser-py JSON |
Version |
1.0.0
JSON |
| download |
home_page | None |
Summary | Parse, Manipulate, and Merge Markdown Heading Trees Programmatically. |
upload_time | 2025-08-30 15:40:22 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | MIT |
keywords |
markdown
parser
tree
document
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
<div align="center">
# markdown-parser-py
Turn raw Markdown into a manipulable heading tree, edit it programmatically, then emit valid Markdown again.


</div>
## β¨ Features
- Parse Markdown into a hierarchical tree of headings (levels 1β6)
- Preserve and roundβtrip section body content
- Query sections via simple dot paths (e.g. `Introduction.Installation.Windows`)
- Add / remove sections dynamically
- Attach (merge) whole subtrees across different Markdown documents with automatic heading level adjustment
- Dump back to Markdown or visualize structure in a `tree`-like ASCII output
## π¦ Installation
```bash
pip install markdown-parser-py
```
or, for an editable install
```bash
git clone https://github.com/VarunGumma/markdown-parser-py
cd markdown-parser-py
pip install -e ./
```
## π§ Core Concepts
The model is minimal:
```text
MarkdownTree
βββ root (MarkdownNode level=0, title="ROOT")
βββ Child heading (level=1 => '#')
β βββ Grandchild (level=2 => '##')
βββ ...
```
Each `MarkdownNode` stores:
- `level`: 0 for synthetic root; 1β6 for real headings
- `title`: heading text
- `content`: list of raw paragraph / code / list text blocks under that heading (excluding child headings)
- `children`: nested headings
## π Quick Start
```python
from markdown_parser import MarkdownTree
doc = """
# Intro
Some intro text.
## Install
Run `pip install x`.
## Usage
Basic usage here.
### CLI
Run `tool`.
"""
tree = MarkdownTree()
tree.parse(doc)
print('\n=== Visualize ===')
tree.visualize()
print('\n=== Dump Round Trip ===')
print(tree.dump())
```
Output (visualize):
```text
βββ # Intro
βββ ## Install
βββ ## Usage
βββ ### CLI
```
## π Finding Sections
```python
node = tree.find_node_by_path('Intro.Install') # '# Intro' > '## Install'
if node:
print('Found:', node.title, 'level', node.level)
```
Dot paths walk downward by titles. A single component path refers to a topβlevel heading (level 1). Returns `None` if not found.
## β Adding Sections
```python
new = tree.add_section('Intro', 'Advanced', content='Deep dive coming soon.')
print('Added at level', new.level)
```
If `parent_path` is `""` or `"ROOT"`, the new section becomes a topβlevel heading.
## β Removing Sections
```python
tree.remove_section('Intro.Advanced') # removes that subtree
```
## π Attaching / Merging Subtrees
You can merge content from another parsed Markdown document. Levels auto-adjust so the attached subtree root sits exactly one level below the chosen parent.
```python
from markdown_parser import MarkdownTree
base = MarkdownTree()
base.parse('# A\nIntro text.')
other = MarkdownTree()
other.parse('# Extra\nStuff here.\n\n## Deep\nDetails.')
# Attach ALL top-level sections from other under 'A'
base.attach_subtree('A', other) # Equivalent to source_path=None
# Or attach only a specific subsection
# base.attach_subtree('A', other, source_path='Extra.Deep')
base.visualize()
print(base.dump())
```
If you attach the full tree (`source_path=None` / `'ROOT'`), each top-level section in the source is cloned with level adjusted: `new_level = parent.level + original_level`.
## π§ͺ Advanced Example: Composing Documents
```python
def compose(product_readme: str, appendix_md: str) -> str:
main_tree = MarkdownTree()
main_tree.parse(product_readme)
appendix_tree = MarkdownTree()
appendix_tree.parse(appendix_md)
# Ensure an Appendix section exists
if not main_tree.find_node_by_path('Appendix'):
main_tree.add_section('', 'Appendix')
# Attach all appendix top-level sections under Appendix
main_tree.attach_subtree('Appendix', appendix_tree)
return main_tree.dump()
```
## π Disclaimer
This is an early/experimental utility. Edge cases (nested fenced code blocks, Setext headings, ATX heading oddities, HTML blocks) are not fully supported yet.
Raw data
{
"_id": null,
"home_page": null,
"name": "markdown-parser-py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "markdown, parser, tree, document",
"author": null,
"author_email": "Varun Gumma <varun230999@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/07/2a/621698ebde3f546e6a8756838bdb81a0c55c8a805b7e34ace972284440ac/markdown_parser_py-1.0.0.tar.gz",
"platform": null,
"description": "<div align=\"center\">\n\n# markdown-parser-py\n\nTurn raw Markdown into a manipulable heading tree, edit it programmatically, then emit valid Markdown again.\n\n\n\n\n</div>\n\n## \u2728 Features\n\n- Parse Markdown into a hierarchical tree of headings (levels 1\u20136)\n- Preserve and round\u2011trip section body content\n- Query sections via simple dot paths (e.g. `Introduction.Installation.Windows`)\n- Add / remove sections dynamically\n- Attach (merge) whole subtrees across different Markdown documents with automatic heading level adjustment\n- Dump back to Markdown or visualize structure in a `tree`-like ASCII output\n\n## \ud83d\udce6 Installation\n\n```bash\npip install markdown-parser-py\n```\n\nor, for an editable install\n\n```bash\ngit clone https://github.com/VarunGumma/markdown-parser-py\ncd markdown-parser-py\npip install -e ./\n```\n\n## \ud83e\udde0 Core Concepts\n\nThe model is minimal:\n\n```text\nMarkdownTree\n\u2514\u2500\u2500 root (MarkdownNode level=0, title=\"ROOT\")\n\t\u251c\u2500\u2500 Child heading (level=1 => '#')\n\t\u2502 \u2514\u2500\u2500 Grandchild (level=2 => '##')\n\t\u2514\u2500\u2500 ...\n```\n\nEach `MarkdownNode` stores:\n\n- `level`: 0 for synthetic root; 1\u20136 for real headings\n- `title`: heading text\n- `content`: list of raw paragraph / code / list text blocks under that heading (excluding child headings)\n- `children`: nested headings\n\n## \ud83d\ude80 Quick Start\n\n```python\nfrom markdown_parser import MarkdownTree\n\ndoc = \"\"\"\n# Intro\nSome intro text.\n\n## Install\nRun `pip install x`.\n\n## Usage\nBasic usage here.\n\n### CLI\nRun `tool`.\n\"\"\"\n\ntree = MarkdownTree()\ntree.parse(doc)\n\nprint('\\n=== Visualize ===')\ntree.visualize()\n\nprint('\\n=== Dump Round Trip ===')\nprint(tree.dump())\n```\n\nOutput (visualize):\n\n```text\n\u2514\u2500\u2500 # Intro\n\t\u251c\u2500\u2500 ## Install\n\t\u2514\u2500\u2500 ## Usage\n\t\t\u2514\u2500\u2500 ### CLI\n```\n\n## \ud83d\udd0d Finding Sections\n\n```python\nnode = tree.find_node_by_path('Intro.Install') # '# Intro' > '## Install'\nif node:\n\tprint('Found:', node.title, 'level', node.level)\n```\n\nDot paths walk downward by titles. A single component path refers to a top\u2011level heading (level 1). Returns `None` if not found.\n\n## \u2795 Adding Sections\n\n```python\nnew = tree.add_section('Intro', 'Advanced', content='Deep dive coming soon.')\nprint('Added at level', new.level)\n```\n\nIf `parent_path` is `\"\"` or `\"ROOT\"`, the new section becomes a top\u2011level heading.\n\n## \u2796 Removing Sections\n\n```python\ntree.remove_section('Intro.Advanced') # removes that subtree\n```\n\n## \ud83d\udd17 Attaching / Merging Subtrees\n\nYou can merge content from another parsed Markdown document. Levels auto-adjust so the attached subtree root sits exactly one level below the chosen parent.\n\n```python\nfrom markdown_parser import MarkdownTree\n\nbase = MarkdownTree()\nbase.parse('# A\\nIntro text.')\n\nother = MarkdownTree()\nother.parse('# Extra\\nStuff here.\\n\\n## Deep\\nDetails.')\n\n# Attach ALL top-level sections from other under 'A'\nbase.attach_subtree('A', other) # Equivalent to source_path=None\n\n# Or attach only a specific subsection\n# base.attach_subtree('A', other, source_path='Extra.Deep')\n\nbase.visualize()\nprint(base.dump())\n```\n\nIf you attach the full tree (`source_path=None` / `'ROOT'`), each top-level section in the source is cloned with level adjusted: `new_level = parent.level + original_level`.\n\n## \ud83e\uddea Advanced Example: Composing Documents\n\n```python\ndef compose(product_readme: str, appendix_md: str) -> str:\n\tmain_tree = MarkdownTree()\n\tmain_tree.parse(product_readme)\n\n\tappendix_tree = MarkdownTree()\n\tappendix_tree.parse(appendix_md)\n\n\t# Ensure an Appendix section exists\n\tif not main_tree.find_node_by_path('Appendix'):\n\t\tmain_tree.add_section('', 'Appendix')\n\n\t# Attach all appendix top-level sections under Appendix\n\tmain_tree.attach_subtree('Appendix', appendix_tree)\n\treturn main_tree.dump()\n```\n\n## \ud83d\udcdd Disclaimer\n\nThis is an early/experimental utility. Edge cases (nested fenced code blocks, Setext headings, ATX heading oddities, HTML blocks) are not fully supported yet.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Parse, Manipulate, and Merge Markdown Heading Trees Programmatically.",
"version": "1.0.0",
"project_urls": {
"Homepage": "https://github.com/VarunGumma/markdown-parser-py",
"Issues": "https://github.com/VarunGumma/markdown-parser-py/issues",
"Repository": "https://github.com/VarunGumma/markdown-parser-py"
},
"split_keywords": [
"markdown",
" parser",
" tree",
" document"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "eb82718cd67b73513727b59d37be8cc0d7a323db4b6309fd4a3baa3c01354413",
"md5": "3fb6a3731b021389a0d97edfab674332",
"sha256": "d7de3ccd6a18c38b49a0c52b30c3493afca58670fbb2ef31633c8cc43a6e00d7"
},
"downloads": -1,
"filename": "markdown_parser_py-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3fb6a3731b021389a0d97edfab674332",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7119,
"upload_time": "2025-08-30T15:40:16",
"upload_time_iso_8601": "2025-08-30T15:40:16.411380Z",
"url": "https://files.pythonhosted.org/packages/eb/82/718cd67b73513727b59d37be8cc0d7a323db4b6309fd4a3baa3c01354413/markdown_parser_py-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "072a621698ebde3f546e6a8756838bdb81a0c55c8a805b7e34ace972284440ac",
"md5": "b20c9f8d88af02b847e2390b43dbe178",
"sha256": "aee2fce3dc15de4f716b51886986b70eb531f49498e223459ba636135bcc273e"
},
"downloads": -1,
"filename": "markdown_parser_py-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "b20c9f8d88af02b847e2390b43dbe178",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 6548,
"upload_time": "2025-08-30T15:40:22",
"upload_time_iso_8601": "2025-08-30T15:40:22.601589Z",
"url": "https://files.pythonhosted.org/packages/07/2a/621698ebde3f546e6a8756838bdb81a0c55c8a805b7e34ace972284440ac/markdown_parser_py-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-30 15:40:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "VarunGumma",
"github_project": "markdown-parser-py",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "markdown-parser-py"
}