mmdfmt 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.ja.md +429 -0
- package/README.md +394 -2
- package/lib/cli.mjs +794 -0
- package/package.json +47 -3
package/README.md
CHANGED
|
@@ -1,3 +1,395 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mmdfmt
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Japanese version: [README.ja.md](./README.ja.md)
|
|
4
|
+
|
|
5
|
+
Format the [Mermaid](https://mermaid.js.org/) diagrams in your Markdown and
|
|
6
|
+
`.mmd` files, and leave everything else as you wrote it.
|
|
7
|
+
|
|
8
|
+
`mmdfmt` formats `.mmd` and `.mermaid` files, and the `mermaid` and `mmd` code
|
|
9
|
+
blocks of `.md` and `.markdown` files. The rest of a Markdown file stays byte
|
|
10
|
+
for byte as it is. The diagrams are formatted by
|
|
11
|
+
[Prettier](https://prettier.io/) with
|
|
12
|
+
[`prettier-plugin-mmd`](../prettier-plugin-mmd), the Mermaid plugin for
|
|
13
|
+
Prettier, so they come out as that plugin prints them, apart from the two cases
|
|
14
|
+
in [If you know Prettier](#if-you-know-prettier).
|
|
15
|
+
|
|
16
|
+
This is a third-party project, not affiliated with
|
|
17
|
+
[mermaid-js](https://mermaid.js.org/). The
|
|
18
|
+
[mmdfmt guide](https://mmd-toolkit.github.io/mmd-toolkit/formatter/mmdfmt.html)
|
|
19
|
+
is on the documentation site.
|
|
20
|
+
|
|
21
|
+
## When to use it
|
|
22
|
+
|
|
23
|
+
Use `mmdfmt` when you want your diagrams formatted but do not let Prettier
|
|
24
|
+
format your Markdown:
|
|
25
|
+
|
|
26
|
+
- You format Markdown with another formatter, such as `markdownlint --fix` or
|
|
27
|
+
dprint. Prettier would rewrite the same text its own way.
|
|
28
|
+
- You keep your Markdown as you write it, on purpose.
|
|
29
|
+
- You use Prettier for other files, and keep it off your Markdown.
|
|
30
|
+
|
|
31
|
+
If Prettier already formats your Markdown, add `prettier-plugin-mmd` to it
|
|
32
|
+
instead: Prettier then formats the diagrams in the same run, and you do not need
|
|
33
|
+
`mmdfmt`.
|
|
34
|
+
|
|
35
|
+
`mmdfmt` needs no Prettier setup; it is one command.
|
|
36
|
+
|
|
37
|
+
## What it does not do
|
|
38
|
+
|
|
39
|
+
- It formats nothing but diagrams.
|
|
40
|
+
- It reports no mistakes in a diagram beyond what mermaid.js rejects;
|
|
41
|
+
[`@mmd-toolkit/eslint-plugin`](../eslint-plugin) does that.
|
|
42
|
+
|
|
43
|
+
## Quick start
|
|
44
|
+
|
|
45
|
+
`mmdfmt` needs Node.js `^22.13.0 || >=24`. `--write` rewrites files in place, so
|
|
46
|
+
commit your work first, or see which files would change with
|
|
47
|
+
`npx mmdfmt --check .`. To format every diagram under the current directory:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npx mmdfmt --write .
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Only the diagrams change. This `notes.md`:
|
|
54
|
+
|
|
55
|
+
<!-- prettier-ignore -->
|
|
56
|
+
````md
|
|
57
|
+
# Notes
|
|
58
|
+
|
|
59
|
+
* A list item that mmdfmt leaves as it is.
|
|
60
|
+
|
|
61
|
+
```mermaid
|
|
62
|
+
flowchart LR
|
|
63
|
+
A --> B; B --> C
|
|
64
|
+
```
|
|
65
|
+
````
|
|
66
|
+
|
|
67
|
+
becomes:
|
|
68
|
+
|
|
69
|
+
<!-- prettier-ignore -->
|
|
70
|
+
````md
|
|
71
|
+
# Notes
|
|
72
|
+
|
|
73
|
+
* A list item that mmdfmt leaves as it is.
|
|
74
|
+
|
|
75
|
+
```mermaid
|
|
76
|
+
flowchart LR
|
|
77
|
+
A --> B
|
|
78
|
+
B --> C
|
|
79
|
+
```
|
|
80
|
+
````
|
|
81
|
+
|
|
82
|
+
Without `mmdfmt` installed, `npx` asks to download it and runs its latest
|
|
83
|
+
version; to keep using one version, [install it](#installation).
|
|
84
|
+
|
|
85
|
+
## Installation
|
|
86
|
+
|
|
87
|
+
A new version of `mmdfmt` can format a diagram a little differently. Pin an
|
|
88
|
+
exact version in your project, so that everyone who works on it, and your CI,
|
|
89
|
+
format the same way:
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
npm install --save-dev --save-exact mmdfmt
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
With pnpm, `pnpm add --save-dev --save-exact mmdfmt`. `npx mmdfmt` (or
|
|
96
|
+
`pnpm exec mmdfmt`) then runs that version.
|
|
97
|
+
|
|
98
|
+
To use it yourself across many repositories, install it globally, and run it as
|
|
99
|
+
`mmdfmt`:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npm install --global mmdfmt
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A global install is not pinned to a project, so two machines can format a
|
|
106
|
+
diagram differently.
|
|
107
|
+
|
|
108
|
+
## Usage
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
mmdfmt --write <pattern>...
|
|
112
|
+
mmdfmt --check <pattern>...
|
|
113
|
+
mmdfmt --stdin-filepath <path>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| Option | What it does |
|
|
117
|
+
| ------------------------- | -------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `--write` | Formats the files in place, and lists on standard output the ones that changed. |
|
|
119
|
+
| `--check` | Changes nothing. Lists on standard output the files that `--write` would change. |
|
|
120
|
+
| `--stdin-filepath <path>` | Formats standard input as if it were the file at `<path>`, and writes it to standard output. |
|
|
121
|
+
| `-h`, `--help` | Prints the usage on standard output. |
|
|
122
|
+
| `-v`, `--version` | Prints the version on standard output. |
|
|
123
|
+
|
|
124
|
+
Give patterns with either `--write` or `--check`, or give `--stdin-filepath`
|
|
125
|
+
alone. `--help` and `--version` only print, whatever else of this table is given
|
|
126
|
+
with them. Any other combination is an error. With no argument at all, `mmdfmt`
|
|
127
|
+
prints the usage on standard error and exits with `2`.
|
|
128
|
+
|
|
129
|
+
There are no other options: no formatting options, no configuration file of its
|
|
130
|
+
own, and no option for an ignore file. An option that takes no value ignores a
|
|
131
|
+
value written after `=`: `--write=false` is read as `--write`, as the argument
|
|
132
|
+
library [gunshi](https://gunshi.dev) reads it.
|
|
133
|
+
|
|
134
|
+
When the reader of standard output goes away, as `head` does once it has its
|
|
135
|
+
lines, `mmdfmt` writes no more there and says nothing, and finishes the run:
|
|
136
|
+
`--write` still rewrites every file, and the exit code still tells the result.
|
|
137
|
+
|
|
138
|
+
### Patterns
|
|
139
|
+
|
|
140
|
+
- The path of a file selects that file.
|
|
141
|
+
- The path of a directory, such as `.`, selects the files under it.
|
|
142
|
+
- Any other pattern is a glob, which also matches names that start with a dot.
|
|
143
|
+
Quote it, so that `mmdfmt` expands it rather than your shell:
|
|
144
|
+
`npx mmdfmt --write "docs/**/*.md"`. On Windows, a `\` in a glob is read as
|
|
145
|
+
`/`.
|
|
146
|
+
- A pattern that starts with `!` takes the files it matches out of the others.
|
|
147
|
+
See [Excluding files](#excluding-files).
|
|
148
|
+
- After `--`, every argument is a pattern, so a file whose name starts with `-`
|
|
149
|
+
can be given: `mmdfmt --write -- -a.md`.
|
|
150
|
+
|
|
151
|
+
Of the selected files, those ending in `.md`, `.markdown`, `.mmd`, or `.mermaid`
|
|
152
|
+
are formatted, each once, however many patterns select it. A pattern that
|
|
153
|
+
selects none of them is an error: `mmdfmt --check .` fails in a project without
|
|
154
|
+
such a file, and so does a file with another ending given by name. A pattern
|
|
155
|
+
whose files a `!` pattern all takes out is an error too, as in Prettier's CLI. A
|
|
156
|
+
pattern that selects only files that the `.gitignore` lists is not an error.
|
|
157
|
+
|
|
158
|
+
As Prettier's CLI does, `mmdfmt` skips without a word a pattern that names a
|
|
159
|
+
path in `node_modules` or in a directory of version control, whether a file, a
|
|
160
|
+
directory, or a glob, such as `node_modules/pkg` or `"node_modules/**/*.md"`.
|
|
161
|
+
When no pattern is left to select files, that is an error.
|
|
162
|
+
|
|
163
|
+
## Excluding files
|
|
164
|
+
|
|
165
|
+
`mmdfmt` leaves out:
|
|
166
|
+
|
|
167
|
+
- the files under `node_modules`, and under the directories of version control
|
|
168
|
+
(`.git`, `.hg`, `.jj`, `.sl`, `.svn`), also when a pattern names them
|
|
169
|
+
([Patterns](#patterns));
|
|
170
|
+
- the files that the `.gitignore` in the directory where you run `mmdfmt` lists.
|
|
171
|
+
Other `.gitignore` files, in subdirectories or above, are not read;
|
|
172
|
+
- the files that a `!` pattern matches. In bash, put such a pattern in single
|
|
173
|
+
quotes, since `!` in double quotes starts a history expansion:
|
|
174
|
+
`npx mmdfmt --write . '!vendor/**'`. In the Windows command prompt, use double
|
|
175
|
+
quotes.
|
|
176
|
+
|
|
177
|
+
`mmdfmt` does not read `.prettierignore`. A project that keeps Prettier off its
|
|
178
|
+
Markdown by listing it there still gets its diagrams formatted.
|
|
179
|
+
|
|
180
|
+
To leave one diagram in a Markdown file as it is, put `<!-- prettier-ignore -->`
|
|
181
|
+
before its code block, with nothing between them but blank lines. Outside lists
|
|
182
|
+
and block quotes, `<!-- prettier-ignore-start -->` and
|
|
183
|
+
`<!-- prettier-ignore-end -->` leave every diagram between them. These are the
|
|
184
|
+
comments that Prettier reads. To leave a whole `.mmd` file as it is, exclude it
|
|
185
|
+
with a `!` pattern or `.gitignore`.
|
|
186
|
+
|
|
187
|
+
## Checking in CI
|
|
188
|
+
|
|
189
|
+
Install `mmdfmt` in the project, install the dependencies in CI (`npm ci`), and
|
|
190
|
+
run:
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
npx mmdfmt --check .
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
When a file is not formatted, `--check` lists it on standard output and exits
|
|
197
|
+
with `1`. When every file is formatted, it prints nothing and exits with `0`.
|
|
198
|
+
Without the dependencies installed, `npx` would run the latest version instead
|
|
199
|
+
of the pinned one.
|
|
200
|
+
|
|
201
|
+
A `.mmd` or `.mermaid` file whose diagram mermaid.js rejects fails the check
|
|
202
|
+
with `2`. A diagram in Markdown that mermaid.js rejects gives only a warning,
|
|
203
|
+
because a document can show a broken diagram on purpose, and `mmdfmt` has no
|
|
204
|
+
option to fail on it. To fail CI on such a diagram, lint the Markdown with
|
|
205
|
+
[`@mmd-toolkit/eslint-plugin`](../eslint-plugin), which reports it.
|
|
206
|
+
|
|
207
|
+
In a project without any diagram file, `--check .` fails with `2`; give the
|
|
208
|
+
directories that hold diagrams instead of `.`.
|
|
209
|
+
|
|
210
|
+
## Formatting before a commit
|
|
211
|
+
|
|
212
|
+
With [lint-staged](https://github.com/lint-staged/lint-staged), which a Git hook
|
|
213
|
+
manager such as husky or simple-git-hooks runs on each commit, add this to
|
|
214
|
+
`package.json`:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"lint-staged": {
|
|
219
|
+
"*.{md,markdown,mmd,mermaid}": "mmdfmt --write"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Keep the glob to these four endings: `mmdfmt` has no option such as Prettier's
|
|
225
|
+
`--ignore-unknown`, and a file with another ending is an error. lint-staged
|
|
226
|
+
passes absolute paths, which `mmdfmt` accepts.
|
|
227
|
+
|
|
228
|
+
## From an editor or another tool
|
|
229
|
+
|
|
230
|
+
`mmdfmt` has no editor extension. An editor or a tool that runs a formatter on
|
|
231
|
+
standard input can run:
|
|
232
|
+
|
|
233
|
+
```sh
|
|
234
|
+
mmdfmt --stdin-filepath docs/guide.md
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
with the text of the file on standard input, and take the formatted text from
|
|
238
|
+
standard output. The file at the path is neither read nor written. The path, if
|
|
239
|
+
relative, is resolved against the directory where `mmdfmt` runs; its ending says
|
|
240
|
+
whether the text is a diagram or Markdown, and its directory says which
|
|
241
|
+
`.editorconfig` and Prettier configuration apply.
|
|
242
|
+
|
|
243
|
+
- A Markdown text is written out in full, formatted or already formatted, and
|
|
244
|
+
the exit code is `0`, also when a diagram in it is rejected; the warning goes
|
|
245
|
+
to standard error.
|
|
246
|
+
- A diagram whose text mermaid.js rejects gets nothing on standard output, an
|
|
247
|
+
error on standard error, and the exit code `2`.
|
|
248
|
+
- A path under `node_modules` or a directory of version control, or listed in
|
|
249
|
+
the `.gitignore` of the directory where `mmdfmt` runs, gets its text back
|
|
250
|
+
unchanged.
|
|
251
|
+
- A path with another ending is an error.
|
|
252
|
+
|
|
253
|
+
## Indentation
|
|
254
|
+
|
|
255
|
+
A diagram is indented by two spaces. When an `.editorconfig` or a Prettier
|
|
256
|
+
configuration applies to the file, its indentation is used: `indent_style`,
|
|
257
|
+
`indent_size`, and `tab_width` of `.editorconfig`, or `useTabs` and `tabWidth`
|
|
258
|
+
of a [Prettier configuration file](https://prettier.io/docs/configuration),
|
|
259
|
+
found as Prettier's CLI finds them, `overrides` included. For a code block, the
|
|
260
|
+
file is the Markdown file. A configuration file that cannot be read is an error.
|
|
261
|
+
For example, this `.editorconfig` indents diagrams by four spaces:
|
|
262
|
+
|
|
263
|
+
```ini
|
|
264
|
+
[*.{md,mmd,mermaid}]
|
|
265
|
+
indent_style = space
|
|
266
|
+
indent_size = 4
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Nothing else of a configuration is used.
|
|
270
|
+
|
|
271
|
+
## Errors and exit codes
|
|
272
|
+
|
|
273
|
+
A diagram that mermaid.js rejects is left as it is, and reported on standard
|
|
274
|
+
error with its line and column. The other files, and the other diagrams of the
|
|
275
|
+
file, are still formatted:
|
|
276
|
+
|
|
277
|
+
```txt
|
|
278
|
+
docs/flow.mmd:3:1: error: Unexpected end of text
|
|
279
|
+
notes.md:6:1: warning: Unexpected end of text
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
In a `.mmd` or `.mermaid` file, it is an error. In a Markdown code block, it is
|
|
283
|
+
a warning. With `--write` and `--stdin-filepath`, the position of a warning is
|
|
284
|
+
in the text after formatting, where the diagrams above it may have gained or
|
|
285
|
+
lost lines, so that it points at the block in what you open after the run. With
|
|
286
|
+
`--check`, which writes nothing, it is in the file as it is. Lines and columns
|
|
287
|
+
count from 1, and a column counts UTF-16 code units, as most editors do.
|
|
288
|
+
[Formatter compatibility](https://mmd-toolkit.github.io/mmd-toolkit/formatter/compatibility.html)
|
|
289
|
+
explains which diagrams are rejected.
|
|
290
|
+
|
|
291
|
+
| Code | Meaning |
|
|
292
|
+
| ---- | ------------------------------------------------------------- |
|
|
293
|
+
| `0` | No errors, and with `--check`, every file is formatted. |
|
|
294
|
+
| `1` | With `--check`, a file would change, and there are no errors. |
|
|
295
|
+
| `2` | An error. |
|
|
296
|
+
|
|
297
|
+
An error is a rejected diagram in a `.mmd` or `.mermaid` file, a file that
|
|
298
|
+
cannot be read or written, a pattern that selects no file, a configuration that
|
|
299
|
+
cannot be read, or a wrong use of the options. With an error, the code is `2`
|
|
300
|
+
even when a file would change.
|
|
301
|
+
|
|
302
|
+
## If you know Prettier
|
|
303
|
+
|
|
304
|
+
The diagrams are formatted by Prettier with `prettier-plugin-mmd`, so the rules
|
|
305
|
+
of the plugin apply. Two results differ from running Prettier with the plugin on
|
|
306
|
+
Markdown:
|
|
307
|
+
|
|
308
|
+
- Prettier removes the whitespace at the end of the last line of a code block,
|
|
309
|
+
even where mermaid.js treats it as part of the diagram
|
|
310
|
+
([Markdown code blocks](../prettier-plugin-mmd/docs/compatibility.md#markdown-code-blocks)).
|
|
311
|
+
`mmdfmt` replaces only the text of the block, so that whitespace stays.
|
|
312
|
+
- Prettier formats a code block of Markdown, such as one marked `md`, as a
|
|
313
|
+
Markdown document, and with it the diagrams in its code blocks. `mmdfmt`
|
|
314
|
+
leaves every other code block as it is.
|
|
315
|
+
|
|
316
|
+
The command differs from Prettier's CLI too: it does not read `.prettierignore`,
|
|
317
|
+
has no `--ignore-path`, `--ignore-unknown`, or formatting options, and uses only
|
|
318
|
+
the indentation of a configuration.
|
|
319
|
+
|
|
320
|
+
## Code blocks in detail
|
|
321
|
+
|
|
322
|
+
The code blocks are those whose info string has `mermaid` or `mmd` as its first
|
|
323
|
+
word, case-sensitively, found as Prettier's Markdown parser finds them. A fence
|
|
324
|
+
inside another code block is not taken for a diagram, and a block inside a list
|
|
325
|
+
or a block quote is found.
|
|
326
|
+
|
|
327
|
+
Only the lines between the fences change. Each line that `mmdfmt` writes starts
|
|
328
|
+
with what stands before the opening fence on its line, with a list marker turned
|
|
329
|
+
into spaces, so that the diagram stays in its list item and its block quote. An
|
|
330
|
+
empty line gets that start without the spaces at its end, so that in a block
|
|
331
|
+
quote it is a `>` alone. For example, this block:
|
|
332
|
+
|
|
333
|
+
<!-- prettier-ignore -->
|
|
334
|
+
````md
|
|
335
|
+
> - ```mermaid
|
|
336
|
+
> flowchart LR
|
|
337
|
+
> A-->B
|
|
338
|
+
>
|
|
339
|
+
> B-->C
|
|
340
|
+
> ```
|
|
341
|
+
````
|
|
342
|
+
|
|
343
|
+
becomes:
|
|
344
|
+
|
|
345
|
+
<!-- prettier-ignore -->
|
|
346
|
+
````md
|
|
347
|
+
> - ```mermaid
|
|
348
|
+
> flowchart LR
|
|
349
|
+
> A --> B
|
|
350
|
+
>
|
|
351
|
+
> B --> C
|
|
352
|
+
> ```
|
|
353
|
+
````
|
|
354
|
+
|
|
355
|
+
When the opening fence follows a `>` at once, as in `>```mermaid`, the lines get
|
|
356
|
+
a space after the `>`. A block quote reads one space after its `>` as part of
|
|
357
|
+
its marker, so a line of the diagram that starts with a space would lose it
|
|
358
|
+
otherwise.
|
|
359
|
+
|
|
360
|
+
A block that is not closed runs to the end of its list item, its block quote, or
|
|
361
|
+
the file, and is formatted all the same. When it ends the file without a line
|
|
362
|
+
ending, its last line still has none. The lines at its end that are empty or
|
|
363
|
+
hold only spaces and tabs are left as written, and so is a block that holds
|
|
364
|
+
nothing else. Markdown reads them as part of the block, but they also part it
|
|
365
|
+
from what follows, as an empty line between two items keeps a list loose, with
|
|
366
|
+
space between its items.
|
|
367
|
+
|
|
368
|
+
Two kinds of block are left as written, with a warning that gives the position:
|
|
369
|
+
|
|
370
|
+
- a block with a tab in its indentation that is read partly as indentation and
|
|
371
|
+
partly as the diagram, as at the start of a line in a list item indented by
|
|
372
|
+
two spaces;
|
|
373
|
+
- a block whose opening fence stands on the line of a footnote label, as in
|
|
374
|
+
`[^1]: ```mermaid`.
|
|
375
|
+
|
|
376
|
+
A diagram that is empty or only whitespace between its fences becomes empty.
|
|
377
|
+
|
|
378
|
+
A file keeps its line endings. Each line that `mmdfmt` writes ends as the first
|
|
379
|
+
line of the file ends, or with `\n` in a file of one line, except the last,
|
|
380
|
+
which ends as the last line of the diagram ended before formatting. The line
|
|
381
|
+
after the lines written then follows the same line ending as before; another one
|
|
382
|
+
could join with that line's into one, as a `\r` before an empty line that ends
|
|
383
|
+
with `\n` is read as one `\r\n`, and the number of lines would change. When the
|
|
384
|
+
diagram becomes empty, the line of the opening fence ends that way in place of
|
|
385
|
+
its own: the one change outside the lines between the fences. In a Markdown
|
|
386
|
+
file, only the lines of the diagrams that change are written. For the line and
|
|
387
|
+
the column of an error or a warning, a line ends at `\n`, `\r\n`, or `\r`.
|
|
388
|
+
|
|
389
|
+
## Documentation
|
|
390
|
+
|
|
391
|
+
- [Formatter options](https://mmd-toolkit.github.io/mmd-toolkit/formatter/options.html):
|
|
392
|
+
how the indentation applies to diagrams.
|
|
393
|
+
- [Formatter compatibility](https://mmd-toolkit.github.io/mmd-toolkit/formatter/compatibility.html):
|
|
394
|
+
rejected diagrams, differences from mermaid.js, and what the formatting
|
|
395
|
+
guarantees.
|