PyOrgPatcher/README.md

276 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PyOrgPatcher
**PyOrgPatcher** is a lightweight command-line utility and Python library for **programmatically editing, extracting, and synchronizing parts of Org-mode documents** — all without Emacs.
It provides a simple way to patch Org files from scripts, CI/CD jobs, or AI agents, making it ideal for:
- Collaborators who work with Org files but dont use Emacs.
- Reproducible research pipelines using literate programming.
- AI systems (e.g., LangChain, LangGraph, or MCP agents) that maintain structured text and code artifacts.
All components are under:
```
./code/
├── orgpatch.py # main tool
├── example.org # demonstration Org file
└── test_orgpatch.py # pytest unit tests
````
---
## 🔧 Installation & Setup
### 1. Requirements
- **Python 3.8+**
- **pytest** (for testing)
Install dependencies:
```bash
python3 -m venv venv
source venv/bin/activate
pip install pytest
````
### 2. Clone or Copy the Tool
```bash
git clone https://git,cns.fyi/welsberr/PyOrgPatcher.git
cd PyOrgPatcher/code
```
You can also copy just `orgpatch.py` to any project — its self-contained and requires no external libraries.
---
## 🧩 Example Org File
[`example.org`](./example.org) demonstrates the types of elements PyOrgPatcher understands:
```org
* Main Title
** Introduction
Some intro text.
#+NAME: intro-para
This is a named paragraph that will be replaced.
** Data
#+NAME: mytable
| Item | Value |
|------+-------|
| A | 1 |
| B | 2 |
** Code
#+NAME: code-snippet
#+BEGIN_SRC python
print("hello world")
#+END_SRC
** My Section
This section body will be replaced.
```
---
## 🚀 Basic Command-Line Usage
List available patch targets:
```bash
./orgpatch.py list example.org
```
Replace a section body:
```bash
./orgpatch.py replace example.org --section "** My Section" --from section.txt
```
Replace a named block or table:
```bash
./orgpatch.py replace example.org --name code-snippet --from code.py
```
Or from standard input:
```bash
printf "| X | 42 |\n" | ./orgpatch.py replace example.org --name mytable --stdin
```
Use `--backup` to create `example.org.bak`.
---
## 🔄 JSON Sync Mode
Batch operations for multiple elements are defined via JSON mappings.
### Example: `mapping.json`
```json
[
{"name": "code-snippet", "file": "code.py"},
{"name": "mytable", "file": "table.org"},
{"section": "** My Section", "file": "section.txt"}
]
```
### Apply Updates *into* the Org File (files → Org)
```bash
./orgpatch.py sync example.org --map mapping.json --direction in --backup
```
### Export Org Elements *to* Files (Org → files)
```bash
./orgpatch.py sync example.org --map mapping.json --direction out --mkdirs
```
Options:
* `--dry-run` — preview only
* `--backup` — create a backup before modifying
* `--mkdirs` — create destination folders automatically
* `--no-overwrite` — skip existing files on export
---
## 🧪 Running Unit Tests
A complete [pytest](https://docs.pytest.org) test suite is included:
```bash
pytest -q
```
This validates:
* Parsing of headings and `#+NAME:` blocks
* Section replacement
* Named block/table/paragraph replacement
* JSON mapping synchronization (`sync in` and `sync out`)
---
## 🧠 Integrating with AI Agent Tooling
### Why It Matters
Org-mode provides a **hierarchical, semantic structure** perfect for literate programming, documentation, and multi-language code notebooks — but until now, most AI systems couldnt safely manipulate it without Emacs or brittle regex hacks.
**PyOrgPatcher** changes that:
It gives AI agents and LLM-based systems a structured interface to read, patch, and synchronize `.org` files, **treating them as composable data artifacts**.
### Example: Agent Workflow
Imagine an **AI documentation agent** that:
1. Reads `mapping.json` to identify relevant files and blocks.
2. Rebuilds code snippets or analyses (e.g., retraining results, data summaries).
3. Calls `orgpatch.py` (or its Python API) to update the corresponding Org blocks.
This lets an AI system manage “literate” files safely without needing to regenerate the entire Org document.
### In LangChain / LangGraph
Within a LangChain or LangGraph workflow, you can use `PyOrgPatcher` as a tool node:
```python
from langchain.tools import tool
import subprocess, json
@tool("update_org_block")
def update_org_block(name: str, content: str):
"""Update a named Org-mode block in example.org."""
cmd = [
"python3", "orgpatch.py", "replace", "example.org",
"--name", name, "--stdin"
]
subprocess.run(cmd, input=content.encode("utf-8"), check=True)
return f"Updated block '{name}' successfully."
```
Agents can then call this tool directly:
```python
update_org_block("analysis-results", "Mean=42\nStd=7.5\n")
```
Similarly, a chain could:
* Use `sync in` to load generated files into an Org document.
* Use `sync out` to extract tables or code for downstream tasks (e.g., testing, publishing, or compiling).
### Multi-Component Patch (MCP) Integration
In MCP-style systems — where AI agents patch **specific parts of multi-file projects**
PyOrgPatcher acts as the **Org-layer patcher**:
* `sync in` = inject AI-generated code, results, or summaries.
* `sync out` = extract training data, code snippets, or narrative text.
* `replace` = fine-grained control of a single element in context.
This makes it ideal for **AI-assisted research notebooks**, **literate AI model reports**, and **collaborative documentation systems**.
---
## 🧰 Python Library Usage
PyOrgPatcher can also be used as a Python module:
```python
import orgpatch as op
lines = op.read_lines("example.org")
new_lines = op.replace_named(lines, "code-snippet", "print('updated via API')\n")
op.write_lines("example.org", new_lines)
```
This makes it easy to integrate into scripts or notebooks.
---
## 🧬 Example Use Case: Non-Emacs Collaboration
Researchers, engineers, or students who use VS Code, Sublime, or other editors can:
* Edit external files (`.py`, `.csv`, `.txt`) directly.
* Let an automated process update `main.org` via `sync in`.
* Keep the literate record synchronized without ever opening Emacs.
This lowers the barrier for collaboration in mixed-editor teams.
---
## 🏁 Summary
| Feature | Description |
| -------------------------- | ---------------------------------------------------- |
| **CLI + Library** | Command-line and Python module usage |
| **Emacs-Free Editing** | Safely patch `.org` files without Emacs |
| **JSON Batch Mode** | Bulk updates and exports |
| **AI/Automation Ready** | Ideal for LangChain, LangGraph, or MCP agents |
| **Fully Tested** | Comprehensive pytest suite included |
| **Collaboration-Friendly** | Perfect for teams mixing Org-mode with other editors |
---
**Author:** Wesley R. Elsberry
**Project:** PyOrgPatcher
**License:** MIT
**Location:** `./code/`
> “PyOrgPatcher bridges human-readable structure and machine-editable precision — empowering both collaborators and intelligent agents to work fluently with Org-mode documents.”
```
---