mdrefine 0.2.0-rc.2 → 0.2.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +577 -0
  2. package/CODE_OF_CONDUCT.md +30 -0
  3. package/CONTRIBUTING.md +189 -16
  4. package/README.md +100 -154
  5. package/SECURITY.md +15 -13
  6. package/config.schema.json +91 -0
  7. package/dist/cli/diff.d.ts +10 -0
  8. package/dist/cli/diff.js +247 -0
  9. package/dist/cli/diff.js.map +1 -0
  10. package/dist/cli/main.js +270 -150
  11. package/dist/cli/main.js.map +1 -1
  12. package/dist/config/load.js +67 -6
  13. package/dist/config/load.js.map +1 -1
  14. package/dist/config/problems.d.ts +7 -0
  15. package/dist/config/problems.js +208 -0
  16. package/dist/config/problems.js.map +1 -0
  17. package/dist/config/resolve.d.ts +42 -109
  18. package/dist/config/resolve.js +193 -52
  19. package/dist/config/resolve.js.map +1 -1
  20. package/dist/core/directives.d.ts +7 -0
  21. package/dist/core/directives.js +25 -13
  22. package/dist/core/directives.js.map +1 -1
  23. package/dist/core/engine.d.ts +42 -4
  24. package/dist/core/engine.js +518 -79
  25. package/dist/core/engine.js.map +1 -1
  26. package/dist/core/frozen.d.ts +6 -0
  27. package/dist/core/frozen.js +15 -0
  28. package/dist/core/frozen.js.map +1 -0
  29. package/dist/core/scope.d.ts +30 -0
  30. package/dist/core/scope.js +122 -0
  31. package/dist/core/scope.js.map +1 -0
  32. package/dist/core/types.d.ts +202 -23
  33. package/dist/core/types.js.map +1 -1
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/node.d.ts +3 -0
  37. package/dist/node.js +4 -0
  38. package/dist/node.js.map +1 -0
  39. package/dist/rules/blocks.d.ts +34 -0
  40. package/dist/rules/blocks.js +550 -0
  41. package/dist/rules/blocks.js.map +1 -0
  42. package/dist/rules/content.d.ts +2 -0
  43. package/dist/rules/content.js +85 -0
  44. package/dist/rules/content.js.map +1 -0
  45. package/dist/rules/dialects.js +10 -6
  46. package/dist/rules/dialects.js.map +1 -1
  47. package/dist/rules/links.js +302 -6
  48. package/dist/rules/links.js.map +1 -1
  49. package/dist/rules/lists.d.ts +2 -0
  50. package/dist/rules/lists.js +924 -0
  51. package/dist/rules/lists.js.map +1 -0
  52. package/dist/rules/structure.js +127 -1
  53. package/dist/rules/structure.js.map +1 -1
  54. package/dist/rules/style.d.ts +8 -2
  55. package/dist/rules/style.js +1137 -165
  56. package/dist/rules/style.js.map +1 -1
  57. package/dist/syntax/block-identifier.d.ts +18 -0
  58. package/dist/syntax/block-identifier.js +24 -0
  59. package/dist/syntax/block-identifier.js.map +1 -0
  60. package/dist/syntax/obsidian.d.ts +29 -11
  61. package/dist/syntax/obsidian.js +9 -10
  62. package/dist/syntax/obsidian.js.map +1 -1
  63. package/dist/syntax/parse.d.ts +87 -3
  64. package/dist/syntax/parse.js +247 -19
  65. package/dist/syntax/parse.js.map +1 -1
  66. package/dist/workspace/access.d.ts +12 -3
  67. package/dist/workspace/access.js +33 -5
  68. package/dist/workspace/access.js.map +1 -1
  69. package/dist/workspace/discovery.d.ts +85 -0
  70. package/dist/workspace/discovery.js +155 -0
  71. package/dist/workspace/discovery.js.map +1 -0
  72. package/dist/workspace/encoding.d.ts +24 -0
  73. package/dist/workspace/encoding.js +113 -0
  74. package/dist/workspace/encoding.js.map +1 -0
  75. package/dist/workspace/files.d.ts +92 -6
  76. package/dist/workspace/files.js +715 -59
  77. package/dist/workspace/files.js.map +1 -1
  78. package/dist/workspace/git.d.ts +54 -0
  79. package/dist/workspace/git.js +198 -0
  80. package/dist/workspace/git.js.map +1 -0
  81. package/dist/workspace/index.d.ts +58 -3
  82. package/dist/workspace/index.js +136 -37
  83. package/dist/workspace/index.js.map +1 -1
  84. package/dist/workspace/selection.d.ts +2 -2
  85. package/dist/workspace/selection.js +3 -3
  86. package/dist/workspace/selection.js.map +1 -1
  87. package/dist/workspace/slug.js +8 -1
  88. package/dist/workspace/slug.js.map +1 -1
  89. package/dist/workspace/vault.js +3 -1
  90. package/dist/workspace/vault.js.map +1 -1
  91. package/docs/api.md +239 -0
  92. package/docs/benchmarks.md +140 -200
  93. package/docs/changelog.md +1 -0
  94. package/docs/cli.md +281 -89
  95. package/docs/configuration.md +193 -480
  96. package/docs/design.md +163 -284
  97. package/docs/dialects.md +169 -0
  98. package/docs/examples.md +151 -109
  99. package/docs/index.md +21 -37
  100. package/docs/integrations.md +144 -0
  101. package/docs/obsidian.md +91 -115
  102. package/docs/plugins.md +147 -212
  103. package/docs/quick-start.md +68 -74
  104. package/docs/rules.md +1237 -0
  105. package/docs/versions.md +56 -0
  106. package/examples/README.md +17 -14
  107. package/examples/automation/summarize-report.mjs +5 -2
  108. package/examples/library/lint-folder.mjs +5 -4
  109. package/examples/library/lint-workspace.mjs +32 -0
  110. package/examples/plugin/notes/release-checklist.md +2 -2
  111. package/examples/plugin/rules.mjs +17 -23
  112. package/examples/workspaces/obsidian-vault/after/mdtools.config.jsonc +2 -2
  113. package/examples/workspaces/obsidian-vault/before/mdtools.config.jsonc +2 -2
  114. package/examples/workspaces/repository-docs/after/README.md +2 -2
  115. package/examples/workspaces/repository-docs/after/mdtools.config.jsonc +0 -2
  116. package/examples/workspaces/repository-docs/before/README.md +2 -2
  117. package/examples/workspaces/repository-docs/before/docs/guide.md +7 -7
  118. package/examples/workspaces/repository-docs/before/docs/reference.md +3 -1
  119. package/examples/workspaces/repository-docs/before/mdtools.config.jsonc +0 -2
  120. package/package.json +38 -12
  121. package/docs/contributing.md +0 -218
  122. package/docs/releases/0.1.0-beta.1.md +0 -39
  123. package/docs/releases/0.1.0-beta.2.md +0 -83
  124. package/docs/releases/0.1.0-beta.3.md +0 -61
  125. package/docs/releases/0.1.0-beta.4.md +0 -50
  126. package/docs/releases/0.1.0-rc.1.md +0 -99
  127. package/docs/releases/0.2.0-rc.1.md +0 -141
  128. package/docs/releases/0.2.0-rc.2.md +0 -225
  129. package/docs/releases.md +0 -144
  130. package/docs/testing.md +0 -93
@@ -0,0 +1,169 @@
1
+ # Dialects
2
+
3
+ A dialect names the renderer whose syntax a document is read in: `commonmark`,
4
+ `github`, `forgejo`, `gitea`, or `obsidian`. `codeberg` is another name for
5
+ `forgejo`, because Codeberg runs Forgejo; the canonical name is what
6
+ `config explain`, rules, and plugins see. The dialect decides what is syntax and
7
+ what is text, and so what formatting has to leave alone. Choose it in the
8
+ [configuration](configuration.md#dialect).
9
+
10
+ ## What each dialect reads
11
+
12
+ | Syntax | CommonMark | GitHub | Forgejo | Gitea | Obsidian |
13
+ | ------------------------------------------------------------------------- | ---------- | ------ | ------- | ----- | -------- |
14
+ | CommonMark, and YAML or TOML front matter | Yes | Yes | Yes | Yes | Yes |
15
+ | Tables, task lists, strikethrough, footnotes, literal autolinks | No | Yes | Yes | Yes | Yes |
16
+ | Math between `$` signs, and display math | No | Yes | Yes | Yes | Yes |
17
+ | Alerts such as `> [!NOTE]` | No | Yes | Yes | Yes | Callouts |
18
+ | Definition lists, `\(…\)` and `\[…\]` math, `[[…]]` shortlinks | No | No | Yes | Yes | No |
19
+ | Heading attributes such as `{#id}` | No | No | Yes | Yes | No |
20
+ | Wikilinks, embeds, highlights (`==…==`), comments (`%%…%%`), `^block-ids` | No | No | No | No | Yes |
21
+
22
+ GitHub's syntax is the common base of the Forgejo, Gitea, and Obsidian dialects,
23
+ and the rules for GitHub Markdown apply to all three. The syntax that only
24
+ Forgejo and Gitea have is protected from formatting rather than parsed; see
25
+ [Forgejo and Gitea](#forgejo-and-gitea). Syntax that no dialect knows, such as
26
+ an Obsidian plugin's, is read as text: use a suppression comment or an `ignore`
27
+ pattern for it. Site-generator syntax is read as text too, but its lines are
28
+ kept: [`style/wrap`](rules.md#stylewrap) leaves a paragraph as written when one
29
+ of its lines starts with a container such as Docusaurus's `:::note` or a
30
+ template tag such as Liquid's `{% tab %}` or `{{ title }}`, because site
31
+ generators read them by line.
32
+
33
+ An alert's or callout's marker is read from the text, as GitHub reads it, so
34
+ `> \[!NOTE]` and `> [!NOTE]` are alerts too. Formatting keeps the line of
35
+ such a marker as written in every dialect; whether Forgejo, Gitea, and Obsidian
36
+ render these forms was not observed.
37
+
38
+ ## The assumed dialect
39
+
40
+ When neither the configuration, its presets and overrides, nor `--dialect` names
41
+ a dialect, the CLI assumes one for each document:
42
+
43
+ - `obsidian` for a document inside an Obsidian vault. A vault is a directory
44
+ that contains a `.obsidian` directory, and a document belongs to the nearest
45
+ vault at or above its own directory: the workspace root, a directory below it,
46
+ or one above it when the root is part of a vault. The search upward stops at a
47
+ directory that contains `.git`, so a repository checked out inside a vault is
48
+ not read as the vault's notes.
49
+ - `github` for every other document, also for text read from stdin.
50
+
51
+ Only the dialect is assumed. The rules of the `github` and `obsidian` presets,
52
+ such as table alignment, still need the preset. For documents that are plain
53
+ CommonMark, name `"dialect": "commonmark"`.
54
+
55
+ The reason for the assumption: formatting checks that a document's meaning is
56
+ unchanged, but it checks in the document's dialect, so a wrong dialect goes
57
+ unnoticed. In CommonMark a table is an ordinary paragraph, and wrapping would
58
+ join its lines. In any dialect but Obsidian's, the lines of a note would be
59
+ joined although Obsidian can show each of them. Assuming GitHub only makes
60
+ formatting more careful for a document that is really CommonMark.
61
+
62
+ ## Math
63
+
64
+ Text between dollar signs is math only under the conditions that the dialect's
65
+ renderer applies, so that sums of money are not taken for a formula. Math is
66
+ never restyled, and no line is broken inside it.
67
+
68
+ - **GitHub, Forgejo, and Gitea:** `$…$` is math only when the opening `$` does
69
+ not follow a letter or digit, and the closing `$` is not followed by a letter,
70
+ a digit, or `_`. `Costs $5 and $6` is prose; `From $5 to 10$` is math.
71
+ - **GitHub** also wants the formula to touch its dollar signs: `$ x $` is math
72
+ on Forgejo and Gitea, and prose on GitHub.
73
+ - **Obsidian:** the opening `$` may not be followed by a space, and a `$` closes
74
+ the formula only when no space stands before it and no digit follows it.
75
+ `$ x $` is prose; `a$x$b` holds a formula, as it does on none of the other
76
+ three.
77
+ - **Display math**, between lines of `$$` or in a `math` code block, is the same
78
+ in every dialect.
79
+
80
+ Where a renderer is stricter, the tool still protects the text: a formula with
81
+ emphasis inside, which GitHub does not render, and one that runs over a line
82
+ break, which Forgejo, Gitea, and Obsidian's Live Preview do not render. Where
83
+ Obsidian's Reading view and Live Preview disagree, the tool follows Reading
84
+ view, which shows more as a formula.
85
+
86
+ ## Heading anchors
87
+
88
+ A link's fragment (`page.md#install`) is checked against the anchors that the
89
+ dialect's renderer generates.
90
+
91
+ | Dialect | Anchor of a heading | Matched |
92
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
93
+ | GitHub, CommonMark | Rendered text, lowercased; punctuation other than `-` and `_` deleted; spaces become `-`; repeated anchors get `-1`, `-2` | Ignoring case |
94
+ | Forgejo, Gitea before 1.26 | Source of the heading's last line as written, Markdown included; every run of characters other than letters, digits, and `_` becomes `-` | Exactly |
95
+ | Gitea 1.26 and later | Rendered text of all lines, as on GitHub, without combining marks; repeated headings share one anchor | Exactly |
96
+ | Obsidian | The heading text itself, or as its source writes it; `#A#B` reaches a heading below another, `#^id` a block identifier | Headings ignoring case, blocks exactly |
97
+
98
+ The Gitea dialect accepts the anchors of both Gitea generations, so it cannot
99
+ promise that a fragment exists on every version. Inline HTML in a heading adds
100
+ its text, but not its tags, to the anchors built from rendered text, except for
101
+ tags that the renderer shows as text, such as `<script>`.
102
+
103
+ | Heading | GitHub | Forgejo | Gitea 1.25 |
104
+ | ------------------------------------------- | ---------------- | ------------------------------------ | -------------------------------- |
105
+ | `## test.0.1` | `#test01` | `#test-0-1` | `#test01` |
106
+ | `## Link [text](https://example.com/p) end` | `#link-text-end` | `#link-text-https-example-com-p-end` | `#link-texthttpsexamplecomp-end` |
107
+ | `## A <span>B</span>` | `#a-b` | `#a-span-b-span` | `#a-spanbspan` |
108
+
109
+ On GitHub, Forgejo, and Gitea, more fragments are valid:
110
+
111
+ - A fragment may carry the `user-content-` prefix that the renderers add to
112
+ every anchor.
113
+ - The `id` of any HTML element and the `name` of an `<a>`, such as
114
+ `<a name="install"></a>`, are anchors. HTML inside comments, code, and
115
+ elements whose content is text, such as `<script>` and `<textarea>`, is not.
116
+ - A heading written as HTML (`<h2>Title</h2>`) gets an anchor on GitHub,
117
+ numbered together with the Markdown headings, and on Gitea 1.26 and later,
118
+ where it is not numbered and an HTML heading with its own `id` gets none.
119
+ Forgejo and earlier Gitea give it none.
120
+
121
+ ## Forgejo and Gitea
122
+
123
+ Both render GitHub Markdown and more. The tool parses their documents as GitHub
124
+ Markdown and protects the rest:
125
+
126
+ - A paragraph with a definition description (a line starting with `: `) or a
127
+ display-math line starting with `\[` is not wrapped.
128
+ - `\(…\)` math and `[[…]]` shortlinks on one line are kept whole; a pair split
129
+ across lines keeps its paragraph from being wrapped. Emphasis markers inside
130
+ `\(…\)` are not changed, and code spans are not joined where that would put
131
+ `\(` and `\)` on one line. Gitea reads backslash math only when its
132
+ administrator enables `MATH_CODE_BLOCK_DETECTION`, which a document cannot
133
+ reveal, so it is protected there too.
134
+ - Shortlinks are not checked as links.
135
+ - If an instance renders line breaks as hard breaks (Gitea's
136
+ `new-line-hard-break` in `RENDER_OPTIONS_REPO_FILE`), disable `style/wrap`.
137
+
138
+ **Heading attributes.** A `{…}` block at the end of a heading is read as
139
+ attributes, not text. `## Install {#setup}` renders as "Install" with the anchor
140
+ `#setup` and no `#install`; `## Usage {.note}` keeps the anchor `#usage`. A
141
+ block holds `#id`, `.class`, and `name=value` items, such as
142
+ `{#setup .note data-level=2}`. It ends the heading's line or, for an underlined
143
+ heading, its last text line, and still counts after a closing `#` sequence
144
+ (`## Install ## {#setup}`). A block that is not valid, that is followed by more
145
+ text, or whose `{` is escaped stays heading text. A custom anchor must be linked
146
+ exactly as written and is never numbered. An `id` that is not text breaks
147
+ rendering; [`forgejo/heading-id`](rules.md#forgejoheading-id) reports it. The
148
+ rules are those of Forgejo 16 and Gitea 1.26 and later.
149
+
150
+ Formatting leaves a block as written, and changes nothing from the first `{` of
151
+ a heading's last text line on: a change of markers there could create or destroy
152
+ a block. Because Forgejo, and Gitea before 1.26, build the anchor from the last
153
+ line as written, `style/emphasis`, `style/strong`, and `links/path` leave that
154
+ line unchanged in a heading without a custom `id`: rewriting
155
+ `## Emph *star* end` to `_star_` would move its anchor and break every link to
156
+ it. `style/inline-code` does not join a code span across the lines of a heading,
157
+ and `style/heading` escapes a `#` run in front of a block (`# Run \## {#id}`)
158
+ and keeps a closing sequence after one (`## Install {#setup} ##`), which Gitea
159
+ before 1.26 reads as attributes too. The semantic check compares these blocks
160
+ and anchors too, so an edit by any rule or plugin that would change them is
161
+ refused.
162
+
163
+ **Gitea and `_.py`.** Gitea 1.26 and later render `__init__.py` literally
164
+ instead of as emphasis, in headings too, whose anchor is then `#__init__py`.
165
+ Whether an underscore delimits emphasis then depends on the rest of the line, so
166
+ on a line containing `_.py` the Gitea dialect leaves emphasis markers and
167
+ multiline code spans as written, and keeps link destinations whose rewrite would
168
+ change their underscores. Such a paragraph is wrapped only when all its
169
+ underscores are inside code spans and it holds no `$` or `\(` math.