diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e7f705b..f24ef30 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -43,15 +43,19 @@ jobs: uses: actions/configure-pages@v5 - name: Install dependencies run: npm install - - name: Run Build Script - # Outputs to the './_site' directory by default + - name: Build API docs + # typedoc outputs to './docs/' (see typedoc.json) run: npm run docs + - name: Assemble site + # Landing page at the root, typedoc API docs under /api/ + run: | + mkdir -p _site/api + cp -R site/. _site/ + cp -R docs/. _site/api/ - name: Upload artifact - # Automatically uploads an artifact from the './_site' directory by default uses: actions/upload-pages-artifact@v3 with: - # Upload entire repository - path: "./docs/" + path: "./_site/" # Deployment job deploy: diff --git a/README.md b/README.md index 74f522c..732d84f 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The same edit from a shell, with the bundled `mdpatch` CLI: echo "Decided: we ship on Thursday." | mdpatch patch append heading "Weekly Sync::Notes" notes.md ``` -**API docs:** https://coddingtonbear.github.io/markdown-patch/ +**Website:** https://coddingtonbear.github.io/markdown-patch/ ยท **API docs:** https://coddingtonbear.github.io/markdown-patch/api/ **Contents** diff --git a/package.json b/package.json index 69898f0..ffb7b08 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "bugs": { "url": "https://github.com/coddingtonbear/markdown-patch/issues" }, - "homepage": "https://github.com/coddingtonbear/markdown-patch#readme", + "homepage": "https://coddingtonbear.github.io/markdown-patch/", "keywords": [ "markdown", "patch", diff --git a/site/index.html b/site/index.html new file mode 100644 index 0000000..dea6ce8 --- /dev/null +++ b/site/index.html @@ -0,0 +1,472 @@ + + + + + +markdown-patch โ€” structure-aware edits to Markdown documents + + + + + + + + + +
+ + +
+
+

Structure-aware edits to Markdown documents.

+

Address a heading, block, or frontmatter field โ€” then read it back, or append, replace, and move content. No line numbers, no regex, no sed.

+
$ npm install markdown-patch
+
+ Use the library + Use the CLI + One engine, two front doors โ€” mdpatch ships in the box. +
+
+ +
+
โ— Try it pick an operation, watch it land
+
+
+
+

The instruction

+
+

+
+
+

notes.md โ€” after

+

+        
+
+
+
+
+ +
+
+

The failure modes you already know, closed off.

+

The obvious ways to edit Markdown programmatically all break on contact with real documents. Each one is handled by the engine, not by your code.

+
+
+

Whitespace is library-owned

+

The engine supplies every separator, so "X", "X\n", and "\nX\n" all produce the same document. One missing newline can never merge two paragraphs again.

+
+
+

Heading levels are relative

+

A # Section in your content lands as a direct child of wherever it's written โ€” the engine rebases levels, so pasted subtrees always fit their new depth.

+
+
+

Stale writes fail cleanly

+

Pass ifMatch with the document's version token. If the file changed under you, the patch throws instead of landing in the wrong place.

+
+
+

Duplicates are addressable

+

Two identical ### Fixed headings? The document map hands each occurrence a distinct address โ€” a regex matches both, a path names exactly one.

+
+
+

Tables are structured

+

Append rows as string[][] โ€” cells are content, not source. Pipes are escaped for you and column counts are checked.

+
+
+

Reads mirror writes

+

readTarget takes the same address as patch. Read at a scope, replace at that scope with the value unchanged: a guaranteed no-op.

+
+
+
+
+ +
+
+

Write it โ€” or just read it.

+

Every address you can patch, you can also query. The bundled mdpatch CLI and the TypeScript API drive the same engine: two commands write, two retrieve.

+
+ + + + + +
commandwhat it does
mdpatch patchwritequick flag-based form for common single edits
mdpatch applywritefull instruction JSON โ€” moves, table rows, ifMatch pipelines
mdpatch queryreadprint a target's content: a section, a block, a frontmatter value
mdpatch print-mapreadshow everything addressable โ€” headings, blocks, fields, version token
+

In the library, readTarget is the mirror image of patch โ€” the same (targetType, target) address, read instead of written. Pull one section out of a note without parsing anything yourself.

+
+
+ +
+
+

Built for editors that aren't people.

+

An LLM agent shouldn't re-emit a 4,000-token file to add one paragraph โ€” and with markdown-patch it can't mangle the 3,900 tokens it had no business touching. This is the engine behind Obsidian Local REST API's PATCH endpoints and MCP tools, where exactly that kind of client is the norm.

+ +
+

Output tokens to add one paragraph to a 4,000-token note

+
+ Re-emit the whole file +
+ ~4,000 +
+
+ Re-emit the section +
+ ~950 +
+
+ One patch instruction +
+ ~60 +
+

Illustrative counts for a typical meeting note. Retrieval is cheap too: the agent reads the compact document map, not the whole file.

+
+ +
+
+

1 ยท Map

+

print-map hands the model a few dozen tokens describing everything addressable โ€” including distinct addresses for duplicate headings โ€” plus a version token.

+
+
+

2 ยท Target

+

The model picks an address straight off the map and, if it needs context, query-reads just that section โ€” no full-file round trips.

+
+
+

3 ยท Patch

+

One small instruction lands the edit. Sent with ifMatch, a stale write throws instead of landing in the wrong place โ€” and retrying from a fresh map is the agent's native gesture.

+
+
+
+
+ + + + + +