Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mdpaste

Convert a markdown article into paste-ready rich text for Medium, Substack, and Ghost. These editors ignore pasted markdown but honor the text/html clipboard flavor, so mdpaste converts markdown to HTML (with per-platform quirk fixes) and puts it on the clipboard. Paste into the editor; formatting survives.

Note: Medium's API is closed to new integrations (since 2025), so fully automated publishing isn't possible. mdpaste owns the format step; you paste (or use a platform's "import from URL" against timbeach.com).

Usage

mdpaste article.md                 # copy Medium-flavored HTML to clipboard
mdpaste -t substack article.md     # Substack profile (see Substack section)
mdpaste -t ghost article.md        # Ghost profile
cat article.md | mdpaste           # read stdin
mdpaste --stdout article.md        # print HTML instead of copying
mdpaste -b https://example.com article.md   # rewrite relative images to a different host

Relative image paths (e.g. pix/a.png, ../pix/a.png) are rewritten to <base-url>/pix/a.png. Absolute http(s):// images are left untouched. Lone links to embed hosts (YouTube, gist, etc.) become bare URLs so the editor auto-embeds them.

The --base-url default is https://timbeach.com (the author's site). If your images are hosted elsewhere, pass your own host with -b/--base-url (a configurable default is on the roadmap).

Substack

mdpaste -t substack applies extra quirk fixes for Substack's editor:

  • Tables become aligned monospace text inside a code block (Substack has no table block; pasted <table> HTML flattens unpredictably and renders differently in email). A table cell containing a link keeps its text and drops the URL, with a warning.
  • Footnotes ([^1] syntax) become plain [n] markers with a numbered endnotes list at the bottom, separated by a rule. (This flattening applies to every target: no editor's paste sanitizer keeps HTML footnote anchors. Substack's native footnotes can only be created by hand in its editor.)
  • A leading H1 is removed from the body and printed as title: ... on stderr, ready to paste into Substack's separate title field.
  • Task list items are converted to [ ] and [x] text markers, because Substack's paste sanitizer strips the checkbox <input> elements and the state would otherwise be lost.
  • A lone embed URL (YouTube etc.) auto-expands into a full embed card on paste; no manual step needed.

Known manual steps after pasting:

  • A code fence's language tag does not produce syntax highlighting in Substack's editor on paste. The block pastes correctly as a code block, it just arrives unhighlighted; pick a language in Substack's own UI if you want highlighting.

The one-liner

For a quick-and-dirty conversion without quirk handling, add to your zsh config:

mdclip() { pandoc -f gfm -t html "${1:-/dev/stdin}" | xclip -selection clipboard -t text/html; }

Requirements

  • xclip (X11) or wl-clipboard (Wayland) for clipboard access.

Install

cargo build --release
cp target/release/mdpaste ~/.local/bin/

Limitations

  • Raw inline HTML in your markdown is dropped (comrak's safe default emits <!-- raw HTML omitted -->). An opt-in --allow-html flag is on the roadmap.
  • URL scheme/host matching is case-sensitive (markdown URLs are virtually always lowercase, so this is rarely an issue).

Roadmap

  • User-configurable image-path mapping (~/.config/mdpaste/config.toml) with multiple local-path -> public-URL rules, so any user can map their own hosting layout (v1 ships only --base-url).
  • --allow-html to pass raw inline HTML through untouched.

License

MIT, see LICENSE.

About

Convert markdown into paste-ready rich text for Medium, Substack, and Ghost via the text/html clipboard flavor.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages