Revised README.md

This commit is contained in:
Wesley R. Elsberry 2025-10-07 19:12:41 -04:00
parent 24d91bd755
commit 7c25d2a20f
1 changed files with 273 additions and 8 deletions

281
README.md
View File

@ -1,10 +1,275 @@
# PyOrgPatcher
PyOrgPatcher is a Python command-line utility that aid in workflows involving Emacs Org-Mode documents, as used in the PolyPaper project.
Functions:
- List Org-Mode elements in an Org-Mode file that can be modified or extracted.
- Replace the content of an Org-Mode element with text from STDIN or from a file.
- With a JSON configuration, either extract multiple Org-Mode elements to associated files (without noweb substitution) or update an Org-Mode document's specified elements with the contents of files.
- Dry-run capability.
**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.”
```
---