# Pubcopy [![Tests](https://img.shields.io/github/actions/workflow/status/canartuc/pubcopy/release.yml?label=tests&labelColor=171717&color=2DA44E)](https://github.com/canartuc/pubcopy/actions) [![License: MIT](https://img.shields.io/badge/license-MIT-yellow?labelColor=171717)](https://github.com/canartuc/pubcopy/blob/main/LICENSE) [![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/canartuc/pubcopy?utm_source=oss&utm_medium=github&utm_campaign=canartuc%2Fpubcopy&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews)](https://coderabbit.ai) [![Support](https://img.shields.io/badge/Buy%20me%20a%20coffee-Support-FF5E5B?logo=buymeacoffee&logoColor=white&labelColor=171717)](https://www.canartuc.com/#/portal/support) Obsidian plugin that copies your notes as platform-optimized HTML to clipboard for pasting into Medium and Substack without formatting loss. ## Install ### From Obsidian (recommended) Settings > Community plugins > Browse > Search "Pubcopy" > Install > Enable ### Manual 1. Download `main.js`, `manifest.json`, `styles.css` from the [latest release](https://github.com/canartuc/pubcopy/releases/latest) 2. Create folder: `/.obsidian/plugins/pubcopy/` 3. Copy the 3 files into that folder 4. Restart Obsidian 5. Settings > Community plugins > Enable "Pubcopy" ## Usage Three ways to trigger: | Method | Behavior | |--------|----------| | **Command Palette** (`Cmd/Ctrl+P`) > "Pubcopy" | Copies entire note | | **Right-click** in editor > Pubcopy submenu | Copies selected text (or entire note if no selection) | | **Three-dot menu** (top-right of note) > Pubcopy submenu | Copies entire note | Each method offers two options: - **Copy for Medium** - **Copy for Substack** After copying, paste (`Cmd/Ctrl+V`) into the Medium or Substack editor. ## What gets converted 56 Obsidian markdown elements are handled: | Element | Medium | Substack | |---------|--------|----------| | Bold, italic, strikethrough, inline code | Yes | Yes | | Highlights `==text==` | Converted to bold | Converted to bold | | Headers H1-H4 | Yes | Yes | | Headers H5-H6 | Flattened to H4 | Yes | | Lists (ordered, unordered, nested) | Max 2 levels | Unlimited | | Task lists `- [ ]` | Unicode checkboxes | Unicode checkboxes | | Callouts `> [!note]` | Styled blockquote with label | Styled blockquote with label | | Code blocks (with language) | `
` | `
` |
| Tables | HTML table | HTML table |
| Images (local) | Base64 embedded | Base64 embedded |
| Images (remote URL) | URL passthrough | URL passthrough |
| Image captions | Italic text below image | `
` | | Footnotes | Superscript + Notes section | Native | | Math (LaTeX) | Rendered via KaTeX | Rendered via KaTeX | | Mermaid diagrams | Stripped (not supported) | Stripped (not supported) | | Wikilinks, tags, comments, frontmatter | Stripped | Stripped | | Embeds `![[note]]` | Resolved and inlined | Resolved and inlined | ## Settings Settings > Community plugins > Pubcopy > Settings | Setting | Default | Description | |---------|---------|-------------| | Strip frontmatter | On | Remove YAML frontmatter | | Strip tags | On | Remove `#tag` references | | Strip wikilinks | On | Convert `[[links]]` to plain text | | Mermaid format | SVG | SVG or PNG (for future use) | | Image handling | Auto | Auto: base64 for local, URL for remote | | Show notification | On | Display notice after copying | ## Development ### Prerequisites - Node.js 18+ - npm ### Setup ```bash git clone https://github.com/canartuc/pubcopy.git cd pubcopy npm install ``` ### Build ```bash # Development (watch mode, rebuilds on file change) npm run dev # Production build npm run build ``` ### Test ```bash # Run all tests npm test # Watch mode npm run test:watch ``` ### Deploy to your vault First run asks for your vault path and saves it to `.deploy.json` (gitignored): ```bash npm run deploy # > Obsidian vault path: /path/to/your/vault # > Saved to .deploy.json # > Deployed to .../plugins/pubcopy ``` Every subsequent run just builds and copies: ```bash npm run deploy ``` After deploying, restart Obsidian or reload the plugin. ### Project structure ``` src/ ├── main.ts # Plugin entry, commands, menus ├── settings.ts # Settings interface and tab ├── converter/ │ ├── index.ts # Conversion pipeline orchestrator │ ├── preprocessor.ts # Strip frontmatter, tags, wikilinks, etc. │ ├── html-converter.ts # Markdown to HTML via remark/rehype │ ├── image-handler.ts # Local base64, remote URL, captions │ ├── embed-resolver.ts # Resolve ![[note]] embeds │ ├── footnote-processor.ts # Platform-specific footnotes │ └── math-renderer.ts # LaTeX via KaTeX ├── platforms/ │ ├── index.ts # PlatformProfile interface │ ├── medium.ts # Medium-specific rules │ └── substack.ts # Substack-specific rules ├── clipboard/ │ └── writer.ts # Clipboard API (text/html + text/plain) └── utils/ ├── errors.ts # PubcopyError, WarningCollector └── notifications.ts # Obsidian Notice wrappers ``` ### Release Push a tag to trigger a GitHub Actions release: ```bash # Update version in manifest.json and package.json first git tag X.Y.Z git push origin X.Y.Z ``` GitHub Actions runs tests, builds, and creates a release with `main.js`, `manifest.json`, and `styles.css`. ## License MIT