Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Tests and build

on:
pull_request:
push:
branches: [main]

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22.x'
cache: npm
- run: npm ci
- run: npm test
- run: npm run build
- run: npm run test:startup
- run: npm run test:browser:build
10 changes: 6 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: "14.x"
node-version: "22.x"

- name: Build
id: build
run: |
npm install
npm ci
npm test
npm run build
npm run test:startup
mkdir ${{ env.PLUGIN_NAME }}
cp main.js manifest.json styles.css ${{ env.PLUGIN_NAME }}
zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,4 @@ main.js

# obsidian
data.json
test/.out/
137 changes: 137 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,140 @@ should be raised again and the plugin should be authorized.

**Note**, the plugin fetched wordpress.com token might be expired in two weeks by default. If publishes
failed some day, 'Refresh' button should be clicked in order to get a new token.

## Obsidian syntax support

The following Obsidian syntax is converted while publishing:

* **Wikilinks** `[[note]]`, `[[note|alias]]` and `[[note#heading]]`: if the target note
has been published with the same profile, the link becomes a permalink of the
published post. Otherwise it is rendered as plain text and a notice is shown.
* **Note embeds** `![[note]]` and `![[note#heading]]`: the embedded note content is
expanded into the published post (up to 5 levels deep, cyclic embeds are skipped).
* **Callouts** `> [!note] Title`: rendered as `<div class="callout callout-note">`
with the type icon. Callouts with a fold marker (`-` or `+`) become collapsible
`<details>`/`<summary>` elements. Style them with CSS on your WordPress site.
* **Task lists** `- [ ]` / `- [x]`: rendered as HTML checkboxes.
* **Highlights** `==text==`: rendered as `<mark>text</mark>`.
* **Footnotes** `[^1]`: rendered as HTML footnotes.
* **Code blocks**: highlighted at publish time with highlight.js
(common languages bundled). The matching stylesheet is embedded into
the post, so no WordPress plugin is needed.
* **Mermaid** diagrams: rendered to standalone SVG at publish time and
embedded in a protected container which prevents WordPress's automatic
paragraph formatting from damaging the diagram. They display without any WordPress-side
mermaid plugin. Diagrams which fail to render keep their original
code fence.
* **Comments** `%%...%%`: single-line and multi-line comment blocks are supported.
* **Math** `$...$` and `$$...$$`: rendered as SVG or TeX depending on the
MathJax output format setting.

Posts which use callouts, task lists, highlights, footnotes or
highlighted code get a small stylesheet embedded into the post content,
so they look right with any WordPress theme without extra plugins.

## Batch publishing

Use the **Batch publish notes or a folder** command, or select multiple notes in
Obsidian's File Explorer and use the WordPress item in the right-click menu.
The same menu on a folder selects all Markdown notes in that folder, including
subfolders. The batch window also supports searching, checkboxes and folder
selection.

Opening the batch window from the context menu automatically checks the selected
notes. A folder context also selects that folder in the dropdown and checks its
descendant Markdown notes. Checked notes appear first so the initial selection
remains visible even when the vault has more than 200 notes.

Choose one target account and an article status, then click **Preview publish
list**. This read-only scan lists the selected articles, additional referenced
articles and attachments before any uploads or publications occur. Referenced
and embedded Markdown notes are included recursively, even outside the selected
folder, and will be published **in full**. Existing articles on the target account
are updated. Notes associated with another account create new articles on the
selected account and receive new local publishing metadata; these are listed
separately in the confirmation window.

Batch publishing includes references automatically, independently of the
single-note `Auto publish linked notes` setting. Wiki links, note embeds and
ordinary/reference-style Markdown links are supported. Code and comments are
excluded. Images and linked attachments are uploaded automatically, with shared
files using the upload cache. Referenced articles are published before their
parents when possible; cyclic references receive a link update after their
article IDs exist, without duplicate creation.

The confirmed scan uses a snapshot of the note contents. Changes made after the
preview cannot silently add articles to the batch; go back and preview again to
include edits. All articles share the chosen status and use their own frontmatter
for titles, tags and categories, falling back to account defaults. Per-note
publishing and browser-edit dialogs are suppressed. The progress window can stop
remaining tasks; the current article finishes and completed articles/uploads
are kept. Closing the batch window or unloading the plugin also stops subsequent
tasks. A summary lists successful, failed and unexecuted articles, including
any links still needing an update. Attachment upload failures fail the affected
article. Independent articles continue; articles that depend on a failed article
are reported as failed too.

## Linked notes

When the `Auto publish linked notes` setting is enabled (off by default), notes
referenced by wikilinks in the current note which have not been
published yet are published first — with the default publish options,
recursively and cycle-safe. The wikilinks then resolve to the
permalinks of the freshly published notes. Notes which already have a
`postId` in their frontmatter are not published again. Linked notes are only
published after submitting the main note's publish dialog; cancelling the
dialog does not publish them. Links in comments, escaped text and code are ignored.

Heading and block links have corresponding anchors in the generated HTML.
Embedded notes retain their own directory for resolving images and links.
Missing sections, cyclic embeds and embeds beyond the depth limit produce a
warning and a text placeholder; they never expand to the whole note or upload
the original Markdown file as an attachment.

## Media files and attachments

Local images and other media files referenced by a note are uploaded to the
WordPress media library before publishing, and the links are rewritten to the
uploaded URLs. Both Obsidian wiki embeds (`![[image.png]]`,
`![[image.png|300]]`, `![[image.png|some alt]]`) and markdown images
(`![alt](image.png)`) are supported. Media files with paths relative to the
note are resolved correctly. Non-image attachments such as PDFs are uploaded
and linked.

Uploaded media files are remembered separately for each site/account, so publishing the same note again does
not upload the same files again. The cache can be cleared with the
`Clear media upload cache` button in the plugin settings.

**Replace media links**: if enabled, the media links in the note itself are
replaced with the WordPress URLs after uploading. It is disabled by default
since the uploaded files are remembered anyway.

The profile's remember username/password switches control what is saved on
disk. Credentials entered with those switches off remain in memory only.

## Development

Use Node.js 22.12 or later, then run `npm ci`, `npm test` and `npm run build`.
The tests exercise both Markdown conversion and publication regressions with
mocked Obsidian/WordPress interfaces.

For real browser rendering, run `npm run test:browser:build` and open
`test/.out/mermaid-browser-test.html` in a browser. It checks actual Mermaid
SVG generation, re-rendering, syntax-error fallback and timeout cleanup.

## Frontmatter properties

The following note properties are recognized while publishing:

* `title`: overrides the post title.
* `postId`: updates the existing WordPress post with this id.
* `profileName`, `postType`, `categories`, `tags`: same as before.
Tags could be a list or a comma-separated string.
* `excerpt`: the post excerpt.
* `slug`: the post slug (permalink name).
* `date`: the post date, e.g. `2026-10-02 12:00:00`.

After publishing, the plugin writes back `profileName`, `postId`, `postType`,
`categories` and `postLink` (the permalink of the published post, used for
converting wikilinks from other notes).
3 changes: 2 additions & 1 deletion esbuild.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ const context = await esbuild.context({
"@lezer/lr",
...builtins],
format: "cjs",
target: "es2018",
target: "es2020",
minify: prod,
logLevel: "info",
sourcemap: prod ? false : "inline",
treeShaking: true,
Expand Down
Loading