joplin-plugin-markdown-formatter 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Markdown Formatter
2
+
3
+ A Joplin plugin that formats the current note's Markdown with configurable, conservative rules.
4
+
5
+ The formatter is designed for note cleanup rather than wholesale rewriting: it parses Markdown to find
6
+ known structures, then applies targeted edits to the original text. Syntax it does not explicitly
7
+ understand is left alone.
8
+
9
+ ![formatting example](./images/format_example.gif)
10
+
11
+ ## Features
12
+
13
+ - Normalize unordered list markers to `-` or `*`.
14
+ - Renumber ordered lists sequentially while preserving the first item's number.
15
+ - Normalize emphasis and bold delimiters.
16
+ - Preserve, tighten (when list doesn't contain block content), or loosen list spacing.
17
+ - Normalize nested list indentation with tabs, 2 spaces, or 4 spaces.
18
+ - Normalize Horizontal rule format and spacing above/below.
19
+ - Optionally align GitHub Flavored Markdown tables.
20
+ - Collapse repeated blank lines outside protected content.
21
+ - Ensure the note ends with exactly one trailing newline.
22
+ - Apply changes through CodeMirror so formatting is undoable with Joplin's normal undo command.
23
+
24
+ ## Usage
25
+
26
+ Install the plugin, open a Markdown note, then run:
27
+
28
+ - `Edit -> Format Markdown`
29
+ - `Ctrl+Alt+F` on Windows/Linux
30
+ - `Cmd+Alt+F` on macOS
31
+
32
+ The command formats the selected note body. If the note is already formatted, it does not write the note
33
+ back.
34
+
35
+ ## Settings
36
+
37
+ Settings are available under `Markdown Formatter` in Joplin's plugin settings.
38
+
39
+ | Setting | Default | Description |
40
+ | -------------------------------- | ------------------- | ----------------------------------------------------------------------- |
41
+ | Unordered list marker | `-` | Rewrite unordered bullets to dash or asterisk. |
42
+ | Normalize ordered list numbering | On | Renumber ordered lists sequentially, keeping the first item number. |
43
+ | Emphasis (italic) marker | `*emphasis*` | Prefer `*` or `_` for emphasis delimiters. |
44
+ | Bold marker | `**bold**` | Prefer `**` or `__` for strong delimiters. |
45
+ | List spacing | Preserve as written | Preserve, tighten, or loosen spacing between list items. |
46
+ | List indentation | Tabs | Indentation used before nested list markers. |
47
+ | Align table columns | Off | Pad table cells so pipes line up. |
48
+ | Collapse consecutive blank lines | On | Reduce runs of blank lines to one blank line outside protected content. |
49
+ | Ensure trailing newline | On | End the note with exactly one newline. |
50
+
51
+ ## Safety Model
52
+
53
+ The formatter follows a "parse for analysis, edit the original text" model. Each rule runs as a separate
54
+ pass:
55
+
56
+ 1. Parse the current Markdown.
57
+ 2. Locate structures the rule understands.
58
+ 3. Apply small string edits to the original source.
59
+ 4. Parse again and verify that the document structure still matches.
60
+
61
+ If a rule's edits would change the parsed document structure in an unexpected way, that rule is skipped
62
+ and the note is left with the last safe output. If formatting fails, the plugin leaves the original note
63
+ unchanged.
64
+
65
+ Protected content such as fenced code blocks, indented code blocks, inline code, YAML front matter, and
66
+ HTML blocks is preserved by whitespace-oriented rules.
67
+
68
+ ## Known Limitations
69
+
70
+ - Lists inside blockquotes are not reindented and their tight/loose spacing is not changed. Their list
71
+ markers and ordered numbering can still be normalized.
72
+ - Tables inside blockquotes are not aligned.
73
+ - Lists inside footnote definitions are not reindented.
74
+ - Table alignment counts UTF-16 code units, so CJK and emoji content may not line up visually in every
75
+ editor font.
76
+ - Emphasis conversion to `_` skips cases where CommonMark would reinterpret intraword underscores or
77
+ merge adjacent delimiter runs.
78
+
79
+ ## Development
80
+
81
+ Install dependencies:
82
+
83
+ ```bash
84
+ npm install
85
+ ```
86
+
87
+ Run tests:
88
+
89
+ ```bash
90
+ npm test
91
+ ```
92
+
93
+ Lint TypeScript:
94
+
95
+ ```bash
96
+ npm run lint
97
+ ```
98
+
99
+ Build the plugin archive:
100
+
101
+ ```bash
102
+ npm run dist
103
+ ```
104
+
105
+ The distributable `.jpl` archive is created under `publish/`.
106
+
107
+ ## License
108
+
109
+ MIT
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "joplin-plugin-markdown-formatter",
3
+ "version": "1.0.0",
4
+ "scripts": {
5
+ "dist": "webpack --env joplin-plugin-config=buildMain && webpack --env joplin-plugin-config=buildExtraScripts && webpack --env joplin-plugin-config=createArchive",
6
+ "prepare": "npm run dist",
7
+ "updateVersion": "webpack --env joplin-plugin-config=updateVersion",
8
+ "update": "npm install -g generator-joplin && yo joplin --node-package-manager npm --update --force",
9
+ "lint": "eslint --ext .ts src/",
10
+ "lint:fix": "eslint --ext .ts src/ --fix",
11
+ "format": "prettier --write \"src/**/*.ts\"",
12
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
13
+ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
14
+ },
15
+ "license": "MIT",
16
+ "keywords": [
17
+ "joplin-plugin"
18
+ ],
19
+ "files": [
20
+ "publish"
21
+ ],
22
+ "devDependencies": {
23
+ "@eslint/js": "^10.0.1",
24
+ "@types/jest": "^30.0.0",
25
+ "@types/mdast": "^4.0.4",
26
+ "@types/node": "^25.6.2",
27
+ "@types/unist": "^3.0.3",
28
+ "@typescript-eslint/eslint-plugin": "^8.62.1",
29
+ "@typescript-eslint/parser": "^8.62.1",
30
+ "chalk": "^4.1.0",
31
+ "copy-webpack-plugin": "^14.0.0",
32
+ "eslint": "^10.6.0",
33
+ "eslint-config-prettier": "^10.1.8",
34
+ "eslint-plugin-import-x": "^4.17.1",
35
+ "fs-extra": "^10.1.0",
36
+ "glob": "^8.0.3",
37
+ "globals": "^17.6.0",
38
+ "jest": "^30.4.2",
39
+ "jest-environment-jsdom": "^30.4.1",
40
+ "prettier": "^3.8.4",
41
+ "tar": "^7.5.9",
42
+ "ts-jest": "^29.4.11",
43
+ "ts-loader": "^9.6.2",
44
+ "typescript": "^6.0.3",
45
+ "webpack": "^5.108.3",
46
+ "webpack-cli": "^7.1.0"
47
+ },
48
+ "dependencies": {
49
+ "mdast-util-from-markdown": "^2.0.3",
50
+ "mdast-util-frontmatter": "^2.0.1",
51
+ "mdast-util-gfm": "^3.1.0",
52
+ "micromark-extension-frontmatter": "^2.0.0",
53
+ "micromark-extension-gfm": "^3.0.0"
54
+ }
55
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "id": "com.bwat47.joplin-markdown-formatter",
4
+ "app_min_version": "3.5",
5
+ "version": "1.0.0",
6
+ "platforms": [
7
+ "desktop",
8
+ "mobile"
9
+ ],
10
+ "name": "Markdown Formatter",
11
+ "description": "Reformat/Normalize markdown with some configurable settings",
12
+ "author": "bwat47",
13
+ "homepage_url": "https://github.com/bwat47/joplin-markdown-formatter",
14
+ "repository_url": "https://github.com/bwat47/joplin-markdown-formatter",
15
+ "keywords": [
16
+ "markdown",
17
+ "format",
18
+ "normalize",
19
+ "formatter",
20
+ "prettify"
21
+ ],
22
+ "categories": [
23
+ "editor",
24
+ "productivity"
25
+ ],
26
+ "screenshots": [],
27
+ "icons": {},
28
+ "promo_tile": {
29
+ "src": "images/markdown-formatter-promo.png",
30
+ "label": "Markdown Formatter Promo Tile"
31
+ },
32
+ "_publish_hash": "sha256:f8488bb81828de4f3d33183208baf1b3e0c03e3326137d2b582633f6de3481e5",
33
+ "_publish_commit": "main:5616e2ef5f0dee3562f19b010e56a82969fc393f"
34
+ }