reladraw 0.18.0 → 0.19.1

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 CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  reladraw is a text language for diagrams where you say where things go.
4
4
 
5
- **[Try it in your browser →](https://reladraw.github.io/reladraw/)**
5
+ > The language is changing frequently. The playground always runs the newest syntax, so a diagram that draws there today may need a small edit later. An installed copy from npm changes only when you upgrade it.
6
+
7
+ **[Try it in your browser in the reladraw playground →](https://reladraw.github.io/reladraw/)**
6
8
 
7
9
  I wanted to be able to create custom, expressive diagrams where I decided how to arrange the diagram, but without the inefficiency of manually drawing in draw.io. For example, this is a diagram drawn in draw.io:
8
10
 
@@ -43,7 +45,7 @@ npm install -g reladraw
43
45
  reladraw render diagram.reladraw -o diagram.svg
44
46
  ```
45
47
 
46
- `reladraw check diagram.reladraw` prints the warnings without writing a picture.
48
+ `reladraw check diagram.reladraw` prints the warnings without writing a picture, and `reladraw format diagram.reladraw` lines its statements up in columns.
47
49
 
48
50
  Or from a clone, which also gets you the examples:
49
51
 
@@ -86,9 +88,7 @@ That gets you a copy of the skill at the time you run it, so you'll need to re-r
86
88
 
87
89
  ## Status
88
90
 
89
- Version 0.18.0. Early stage, but works. The parser, layout engine, and SVG renderer are written in TypeScript, with zero runtime dependencies. There is a command-line tool that turns a .reladraw text file into an SVG, and an element that does the same inside a web page.
90
-
91
- The language isn't stable yet, so expect the syntax to change.
91
+ Version 0.19.1. Early stage, but works. The parser, layout engine, and SVG renderer are written in TypeScript, with zero runtime dependencies. There is a command-line tool that turns a .reladraw text file into an SVG, and an element that does the same inside a web page.
92
92
 
93
93
  ## License
94
94
 
package/SYNTAX.md CHANGED
@@ -1,4 +1,4 @@
1
- # Syntax reference — 0.18.0
1
+ # Syntax reference — 0.19.1
2
2
 
3
3
  What the language accepts. The changelog at the end lists what changed in each published version; 0.17.0's changes are large, and its entry has a table of every old spelling and what to write instead.
4
4
 
@@ -55,7 +55,7 @@ What every statement of a kind has is positional; what is optional is a key. A w
55
55
 
56
56
  **A value ends when its own shape is complete.** `height: 0.5 group height right of a` reads a size, then a placement. `to: top, right of z` keeps `right of z` inside `to:`, because it is part of that value. So word order stays free and nothing is ambiguous.
57
57
 
58
- **A bracket modifies the one thing it follows.** A setting that belongs to one part of a statement is written in brackets right after that part: a placement's `(gap: wide)`, a text's `(size: small, wrap: 30)`, a line's `line: (path: square)`, a layout's `layout: column (gap: none)`, a waypoint's `b top (gap: wide)`. The scope is visible instead of inferred. Inside a bracket the comma is optional.
58
+ **A bracket modifies the one thing it follows.** A setting that belongs to one part of a statement is written in brackets right after that part: a placement's `(gap: wide)`, a text's `(size: small, wrap: 30)`, a line's `line: (path: square)`, a layout's `layout: column (gap: none)`, a waypoint's `b top (gap: wide)`. The scope is visible instead of inferred. Inside a bracket the comma is optional, and spaces around it don't matter: `(corners: rounded,path: square)` and `(corners: rounded , path: square)` are both `(corners: rounded, path: square)`.
59
59
 
60
60
  ### Names and words
61
61
 
@@ -842,7 +842,7 @@ A line named `req` has parts. `req start` and `req end` are where it was written
842
842
 
843
843
  ### Copies fan out
844
844
 
845
- Copies are lines with the same two boxes on the same sides, in either direction, with nothing stated about their path. Texts and colors don't count, so a request and its response are copies. Copies are drawn as one shape, each shifted sideways from it by a fixed step like lanes on a road, so they never cross. Straight copies with no side named run parallel, a `tight` gap apart, each end landing where its lane meets the border. A line whose landing is stated, such as `to: top, right of z`, is no longer a copy, which is how to override the fan.
845
+ Copies are lines with the same two boxes on the same sides, in either direction, with nothing stated about their path. Texts and colors don't count, so a request and its response are copies. Copies are drawn as one shape, each shifted sideways from it by a fixed step like lanes on a road, so they never cross. Straight copies with no side named run parallel, a `tight` gap apart, each end landing where its lane meets the border. A line that says anything about where it goes is no longer a copy, and is drawn as written: a stated landing (`to: top, right of z`), a place in a side's `right-edge-order:` list, or a `step-out:` or `turn:` in its own bracket. That is how to override the fan. A `step-out:` or `turn:` from `default edge` or a style says the same for every line, so copies sharing it still fan, each taking it from the first.
846
846
 
847
847
  ```
848
848
  node client
@@ -1162,6 +1162,59 @@ reladraw check diagram.reladraw
1162
1162
 
1163
1163
  The output is a standalone SVG: every picture is drawn into it as path data, never from a font or a linked file. A web page can draw a diagram in place with `<reladraw-diagram>`; see "In a web page" in the README.
1164
1164
 
1165
+ ### Formatting
1166
+
1167
+ ```
1168
+ reladraw format diagram.reladraw other.reladraw
1169
+ reladraw format --check diagram.reladraw
1170
+ reladraw format - < diagram.reladraw
1171
+ reladraw format --init
1172
+ ```
1173
+
1174
+ `format` lays each file out again in place. By default every statement is on one line, and neighboring statements with the same keyword line their clauses up in columns, each as wide as its longest clause plus two spaces; a blank line or a new keyword starts a new set of columns, and a comment line between them doesn't. A comment at the end of a line lines up with the others in its set. A statement written over several lines with a comment among them keeps its lines, with the indent tidied. Blank lines stay as written, and so do Windows line endings.
1175
+
1176
+ Inside a clause, spacing comes out as these pages write it, whatever was typed: one space after a key's colon and between words, none just inside a bracket, and a comma against the word before it, so `line:( corners:rounded , path:square )` becomes `line: (corners: rounded, path: square)`.
1177
+
1178
+ Only whitespace changes, and the order of clauses when `clause-order` asks: every word is copied as it was written, and the result is checked to draw exactly what the original did. A file that doesn't parse is reported and left alone, and the other files still run. `--check` changes nothing, prints each file that would change, and fails if there is one, for a pre-commit hook or CI. A shell expands `*.reladraw` into the files; folders aren't searched.
1179
+
1180
+ `-` in place of the files reads the diagram from standard input and prints it formatted, touching no file. That is how an editor formats a buffer, saved or not: Vim's `:%!reladraw format -`, or the command a format-on-save package runs. Its settings come from the nearest `.reladraw-format` to the current folder.
1181
+
1182
+ The settings are in the nearest `.reladraw-format`, in the file's folder or a folder above it; with none, the defaults. A project that puts one at its top keeps everyone's formatting the same. `reladraw format --init` writes one in the current folder with every setting at its default and a comment on what each value does, and refuses if one is there already. One setting a line, as in a diagram:
1183
+
1184
+ ```
1185
+ // keep each clause straight after the last
1186
+ columns: off
1187
+ clause-gap: 2
1188
+ ```
1189
+
1190
+ | setting | values, default first |
1191
+ |---|---|
1192
+ | `wrap-at` | `off`, or a number of characters: past it, a statement wraps onto as few lines as fit |
1193
+ | `clause-per-line-at` | `off`, a number of characters, or `always`: past it, every clause gets its own line |
1194
+ | `first-line` | `text` (keyword, name and texts), `name`: where a broken statement's first line ends |
1195
+ | `clause-order` | `as-written`, or a list of kinds: `placement`, and keys by name, such as `style, placement, fill` |
1196
+ | `columns` | `aligned`, `off` |
1197
+ | `columns-shared-by` | `same-keyword-neighbors`, `neighbors`, `same-keyword` (across blank lines), `file` |
1198
+ | `clause-gap` | a number of spaces, `2`; or `tab`, with `columns: off` only |
1199
+ | `trailing-comments` | `shared-column`, `after-statement` |
1200
+ | `comments-inside` | `keep-lines`, `move-above` (joined, comments above it), `refuse` (left alone, comment named) |
1201
+ | `continued-lines-indent` | where a broken or kept statement's later lines start: `4` or another number, `tab`, `under-name`, `under-name + 2`, `under-text` (under the name when there's no text) |
1202
+ | `blank-lines` | `as-written`, `exactly 2`, `at-most 3` |
1203
+ | `edge-name-and-ends` | `one-column`, `own-columns` (name, each end and the arrow a column each) |
1204
+
1205
+ An unknown setting, one written twice, or a value it doesn't take is an error naming it.
1206
+
1207
+ **Breaking a long statement.** With both at a number, a statement up to `wrap-at` stays on one line, one up to `clause-per-line-at` wraps, and a longer one goes one clause to a line. Its length is measured on its own, before columns, so whether it breaks never depends on its neighbors; its first line still lines up with theirs. A break falls only between clauses, never inside one or inside a bracket, so a clause longer than the width stands alone on its line, past it. A statement broken by hand is broken again by these rules, or joined when they leave it short enough; one kept on its lines for a comment among them is left as it is. A comment at the end of a broken statement follows its last line.
1208
+
1209
+ ```
1210
+ // wrap-at: 60
1211
+ node confirm "Confirm"
1212
+ below accept (gap: tight) left of accept (gap: wide)
1213
+ style: plain
1214
+ ```
1215
+
1216
+ **Ordering clauses.** `clause-order` lists the kinds of clause in the order they are written: `placement` for every relation, and a key by its name (`style`, `fill`, `via`). Kinds it leaves out follow, in the order written, and clauses of one kind keep theirs. A node's or edge's texts never move, since the language takes them only straight after the name; `text` in the list means a style's `text:` key. A clause never moves where moving it would change what the statement says.
1217
+
1165
1218
  ## Attributes
1166
1219
 
1167
1220
  Every attribute, and what takes one. A node's kind is what its body is: a box (`shape:`), a picture (`icon:`) or bare text (`shape: none`).
@@ -1228,6 +1281,20 @@ Designed and absent from the code.
1228
1281
 
1229
1282
  Pre-1.0, so the minor number is where a breaking change goes. Every removal is refused by name with the replacement quoted, rather than dropped in silence: an older file stops with an error saying what to write instead.
1230
1283
 
1284
+ **0.19.1**
1285
+
1286
+ - **A copy that states its own `step-out:` or `turn:` keeps it.** Lines between the same two sides of the same two boxes fan into lanes, and each used to be drawn as the first one's shape shifted over, so a `step-out:` or `turn:` written on any later line was ignored. A line naming either is now drawn as written and leaves the fan, and so does a line named in its side's `right-edge-order:` list. Where that puts two lines on one run, it is reported as `edge-overlap`. Prompted by #19.
1287
+ - **Errors and findings name a named line by its name**, as written: `line e2 b.1 -- b.2 runs on line e1 b.1 -- b.2`. Two lines between the same boxes used to read identically.
1288
+
1289
+ **0.19.0**
1290
+
1291
+ - **`reladraw format`** lays a file out again: each statement on one line, neighboring statements with the same keyword lined up in columns, comments kept beside what they are about. No word is respelled, and the result is checked to draw what the original did. `--check` fails on a file that would change, and `.reladraw-format` holds a project's settings; `reladraw format --init` writes one with every setting explained. `reladraw format -` reads standard input and prints the result, for editors. A long statement can wrap past a width (`wrap-at`) or go one clause to a line (`clause-per-line-at`), and `clause-order` puts placements and keys in a chosen order. The playground has a Format button (Shift+Alt+F, undone with Ctrl+Z) and a panel for its settings, which can copy them as a `.reladraw-format`. Spacing inside a clause is evened out too: `gap:tight` becomes `gap: tight`, `( gap: tight )` becomes `(gap: tight)`. Prompted by #14, where a long statement was hard to read in a plain editor.
1292
+ - **A comma may touch the next word or stand apart from both.** `(corners: rounded,path: square)` used to be refused with "`corners` has no value", and `(at: start , above edge)` was refused in a text's bracket; both now read as `rounded, path:` and `start, above` do.
1293
+ - **The playground opens and saves `.reladraw` files**, with Open… and Save… above the source. Save suggests the name of the file last opened or saved; Chrome and Edge ask where to put it, other browsers save it with the downloads. Opening a file over edits that haven't been saved to one asks first.
1294
+ - **The playground's error message can be copied**, with a Copy button beside it or by selecting it. Only the underlined line number jumps to the line now; a click anywhere on the message used to, which took a selection away.
1295
+ - **The playground no longer fails on some diagrams with 0.18.0's shapes**, which stopped with "insidePolygon is not defined". The command line was unaffected.
1296
+ - **The agent skill checks it matches the installed tool.** It compares its own version with `reladraw --version` and tells the user which of the two to update.
1297
+
1231
1298
  **0.18.0**
1232
1299
 
1233
1300
  - **More shapes, for flowcharts and the rest** (#18): `diamond`, `pill`, `parallelogram`, `hexagon`, `trapezoid`, `triangle` and `cylinder`, named for how they look, and the flowchart standard's shapes that have no geometric name as `flow-` and what they mean, from `flow-subprocess` and `flow-delay` to `flow-collate`. A shape's settings go in a bracket after its name: `shape: parallelogram (slant: 2, lean: left)`, `shape: cylinder (lying)`, `shape: document (fold: 1.5)`.
package/dist/cli.js CHANGED
@@ -4,17 +4,32 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
4
4
  import { dirname, resolve as resolvePath } from 'node:path';
5
5
  import { nearMatch, readChecks } from './checks.js';
6
6
  import { SourceError } from './errors.js';
7
+ import { format } from './format.js';
8
+ import { DEFAULT_FORMAT, readFormatSettings, SETTINGS_FILE, settingsFileText } from './format-settings.js';
7
9
  import { draw } from './index.js';
8
10
  import { THEME_NAMES, THEMES } from './themes.js';
9
11
  const USAGE = `reladraw — draw a diagram from stated placement
10
12
 
11
13
  reladraw render <input.reladraw> [-o <output.svg>] [options]
12
14
  reladraw check <input.reladraw> [options]
15
+ reladraw format <input.reladraw>... [--check]
16
+ reladraw format - [--check]
17
+ reladraw format --init
13
18
 
14
19
  render draw the diagram to an SVG, and print any findings: places
15
20
  where the picture, drawn as written, may not read as meant.
16
21
  check lay the diagram out and print only the findings. No SVG is
17
22
  written, so a good one is left alone while you iterate.
23
+ format lay each file out again in place: spacing, columns, comments
24
+ and blank lines. No word is respelled, and a file that
25
+ doesn't parse is left alone. The nearest .reladraw-format, in
26
+ the file's folder or one above it, holds the settings.
27
+ --check changes nothing, and fails if a file would change.
28
+ - reads the diagram from standard input and prints it
29
+ formatted, for an editor; settings come from the current
30
+ folder up.
31
+ --init writes a .reladraw-format here, every setting at its
32
+ default with what it does.
18
33
 
19
34
  -o, --out where render writes the SVG. Defaults to the input path with
20
35
  its extension replaced by .svg. Use - for standard output.
@@ -29,7 +44,7 @@ const USAGE = `reladraw — draw a diagram from stated placement
29
44
  print the version.
30
45
  -h, --help print this.
31
46
  `;
32
- const COMMANDS = ['render', 'check'];
47
+ const COMMANDS = ['render', 'check', 'format'];
33
48
  async function main(argv) {
34
49
  if (argv.length === 0 || argv.includes('-h') || argv.includes('--help')) {
35
50
  process.stdout.write(USAGE);
@@ -56,6 +71,8 @@ async function main(argv) {
56
71
  return 1;
57
72
  }
58
73
  const command = verb;
74
+ if (command === 'format')
75
+ return formatFiles(argv.slice(1));
59
76
  let input;
60
77
  let out;
61
78
  let theme;
@@ -172,6 +189,176 @@ async function main(argv) {
172
189
  process.stderr.write(`${target}\n`);
173
190
  return 0;
174
191
  }
192
+ /**
193
+ * `reladraw format`: each file laid out again in place, by the settings in
194
+ * the nearest `.reladraw-format`. A file that fails is reported and the rest
195
+ * still run, so one broken file doesn't hide the state of the others.
196
+ */
197
+ async function formatFiles(args) {
198
+ const files = [];
199
+ let check = false;
200
+ let init = false;
201
+ for (const arg of args) {
202
+ if (arg === '--check')
203
+ check = true;
204
+ else if (arg === '--init')
205
+ init = true;
206
+ else if (arg.startsWith('-') && arg !== '-') {
207
+ process.stderr.write(`reladraw: format takes --check and --init, not ${arg}\n`);
208
+ return 1;
209
+ }
210
+ else
211
+ files.push(arg);
212
+ }
213
+ if (init) {
214
+ if (check || files.length > 0) {
215
+ process.stderr.write('reladraw: --init writes a settings file and formats nothing — run reladraw format --init on its own\n');
216
+ return 1;
217
+ }
218
+ if (existsSync(SETTINGS_FILE)) {
219
+ process.stderr.write(`reladraw: there is already a ${SETTINGS_FILE} here — delete it first to write a fresh one\n`);
220
+ return 1;
221
+ }
222
+ await writeFile(SETTINGS_FILE, settingsFileText(), 'utf8');
223
+ process.stderr.write(`${resolvePath(SETTINGS_FILE)}\n`);
224
+ return 0;
225
+ }
226
+ if (files.length === 0) {
227
+ process.stderr.write('reladraw: no input file — reladraw format <input.reladraw>..., or - to read standard input\n');
228
+ return 1;
229
+ }
230
+ if (files.includes('-'))
231
+ return formatStandardInput(files, check);
232
+ let status = 0;
233
+ const found = new Map();
234
+ for (const file of files) {
235
+ let settings = DEFAULT_FORMAT;
236
+ try {
237
+ const nearest = nearestSettings(dirname(resolvePath(file)), found);
238
+ if (nearest)
239
+ settings = nearest.settings;
240
+ }
241
+ catch (error) {
242
+ if (!(error instanceof SettingsError))
243
+ throw error;
244
+ process.stderr.write(`${error.cause.format(error.path)}\n`);
245
+ status = 1;
246
+ continue;
247
+ }
248
+ let source;
249
+ try {
250
+ source = await readFile(file, 'utf8');
251
+ }
252
+ catch {
253
+ process.stderr.write(`reladraw: can't read ${file}\n`);
254
+ status = 1;
255
+ continue;
256
+ }
257
+ let laid;
258
+ try {
259
+ laid = format(source, settings);
260
+ }
261
+ catch (error) {
262
+ process.stderr.write(error instanceof SourceError ? `${error.format(file)}\n` : `reladraw: ${file}: ${error.message}\n`);
263
+ status = 1;
264
+ continue;
265
+ }
266
+ if (laid === source)
267
+ continue;
268
+ if (check) {
269
+ process.stderr.write(`${file}: not formatted — reladraw format ${file} lays it out\n`);
270
+ status = 1;
271
+ continue;
272
+ }
273
+ await writeFile(file, laid, 'utf8');
274
+ process.stderr.write(`formatted ${file}\n`);
275
+ }
276
+ return status;
277
+ }
278
+ /**
279
+ * `reladraw format -`: the diagram read from standard input and printed
280
+ * formatted, which is how an editor formats a buffer it hasn't saved. The
281
+ * settings are the nearest `.reladraw-format` from the current folder. With
282
+ * `--check` nothing is printed, and it fails if the text would change.
283
+ */
284
+ async function formatStandardInput(files, check) {
285
+ if (files.length > 1) {
286
+ process.stderr.write('reladraw: - reads standard input, so it goes on its own — reladraw format -\n');
287
+ return 1;
288
+ }
289
+ if (process.stdin.isTTY) {
290
+ process.stderr.write('reladraw: format - reads a diagram from standard input — pipe one in: reladraw format - < diagram.reladraw\n');
291
+ return 1;
292
+ }
293
+ let settings = DEFAULT_FORMAT;
294
+ try {
295
+ settings = nearestSettings(process.cwd(), new Map())?.settings ?? DEFAULT_FORMAT;
296
+ }
297
+ catch (error) {
298
+ if (!(error instanceof SettingsError))
299
+ throw error;
300
+ process.stderr.write(`${error.cause.format(error.path)}\n`);
301
+ return 1;
302
+ }
303
+ const chunks = [];
304
+ for await (const chunk of process.stdin)
305
+ chunks.push(chunk);
306
+ const source = Buffer.concat(chunks).toString('utf8');
307
+ let laid;
308
+ try {
309
+ laid = format(source, settings);
310
+ }
311
+ catch (error) {
312
+ process.stderr.write(error instanceof SourceError ? `${error.format('<stdin>')}\n` : `reladraw: <stdin>: ${error.message}\n`);
313
+ return 1;
314
+ }
315
+ if (check) {
316
+ if (laid === source)
317
+ return 0;
318
+ process.stderr.write('<stdin>: not formatted\n');
319
+ return 1;
320
+ }
321
+ process.stdout.write(laid);
322
+ return 0;
323
+ }
324
+ /** A `.reladraw-format` that doesn't read, and where it is. */
325
+ class SettingsError extends Error {
326
+ path;
327
+ cause;
328
+ constructor(path, cause) {
329
+ super(cause.message);
330
+ this.path = path;
331
+ this.cause = cause;
332
+ }
333
+ }
334
+ /**
335
+ * The settings in the nearest `.reladraw-format`, looking in `folder` and
336
+ * then each folder above it, or nothing when there is none. Each folder is
337
+ * looked in once however many files share it.
338
+ */
339
+ function nearestSettings(folder, found) {
340
+ const known = found.get(folder);
341
+ if (known !== undefined)
342
+ return known;
343
+ const path = resolvePath(folder, SETTINGS_FILE);
344
+ let result;
345
+ if (existsSync(path)) {
346
+ try {
347
+ result = { path, settings: readFormatSettings(readFileSync(path, 'utf8')) };
348
+ }
349
+ catch (error) {
350
+ if (error instanceof SourceError)
351
+ throw new SettingsError(path, error);
352
+ throw error;
353
+ }
354
+ }
355
+ else {
356
+ const parent = dirname(folder);
357
+ result = parent === folder ? null : nearestSettings(parent, found);
358
+ }
359
+ found.set(folder, result);
360
+ return result;
361
+ }
175
362
  main(process.argv.slice(2)).then((code) => process.exit(code), (error) => {
176
363
  process.stderr.write(`reladraw: ${error instanceof Error ? error.message : String(error)}\n`);
177
364
  process.exit(1);
@@ -0,0 +1,60 @@
1
+ /**
2
+ * How `reladraw format` lays a file out. Each key is a setting as it is
3
+ * written in a `.reladraw-format` file, so an error, the generated file and
4
+ * the code all use one name for each.
5
+ */
6
+ export interface FormatSettings {
7
+ 'wrap-at': 'off' | number;
8
+ 'clause-per-line-at': 'off' | 'always' | number;
9
+ 'first-line': 'text' | 'name';
10
+ 'continued-lines-indent': number | 'tab' | 'under-name' | 'under-text' | {
11
+ underName: number;
12
+ };
13
+ 'clause-order': 'as-written' | string[];
14
+ 'clause-gap': number | 'tab';
15
+ columns: 'aligned' | 'off';
16
+ 'columns-shared-by': 'same-keyword-neighbors' | 'neighbors' | 'same-keyword' | 'file';
17
+ 'comments-inside': 'keep-lines' | 'move-above' | 'refuse';
18
+ 'trailing-comments': 'shared-column' | 'after-statement';
19
+ 'blank-lines': 'as-written' | {
20
+ exactly: number;
21
+ } | {
22
+ atMost: number;
23
+ };
24
+ 'edge-name-and-ends': 'one-column' | 'own-columns';
25
+ }
26
+ /** One setting: what it controls, its values in words, and how to read one. */
27
+ interface Setting {
28
+ name: keyof FormatSettings;
29
+ /** One sentence for the generated file: what the setting controls. */
30
+ about: string;
31
+ /** Each value as written, and what it means. The first is the default. */
32
+ values: [string, string][];
33
+ /** The default, as written. */
34
+ written: string;
35
+ /** The value as written, read; a string thrown is the reason it is refused. */
36
+ read: (value: string) => FormatSettings[keyof FormatSettings];
37
+ }
38
+ /**
39
+ * The kinds of clause `clause-order` can list: a statement's texts, its
40
+ * placements, and each key by its own name. `text` is also a style's `text:`
41
+ * key, which is a style's way of saying what a text says.
42
+ */
43
+ export declare const CLAUSE_KINDS: readonly string[];
44
+ export declare const SETTINGS: Setting[];
45
+ export declare const DEFAULT_FORMAT: FormatSettings;
46
+ /** The file a project's settings are written in. */
47
+ export declare const SETTINGS_FILE = ".reladraw-format";
48
+ /**
49
+ * Read a `.reladraw-format` file: one `key: value` setting a line, `//`
50
+ * comments, blank lines. An unknown setting, one written twice, or a value it
51
+ * doesn't take is refused by name, with the line.
52
+ */
53
+ export declare function readFormatSettings(text: string): FormatSettings;
54
+ /**
55
+ * The `.reladraw-format` that `reladraw format --init` writes: every setting
56
+ * at its default, each under a comment saying what it controls and what each
57
+ * of its values means.
58
+ */
59
+ export declare function settingsFileText(): string;
60
+ export {};