@diagrammo/dgmo 0.40.0 → 0.41.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/dist/advanced.cjs +48 -46
- package/dist/advanced.js +48 -46
- package/dist/auto.cjs +49 -47
- package/dist/auto.js +3 -3
- package/dist/auto.mjs +49 -47
- package/dist/cli.cjs +41 -41
- package/dist/index.cjs +48 -46
- package/dist/index.js +48 -46
- package/docs/language-reference.md +17 -0
- package/gallery/fixtures/event-line.dgmo +12 -12
- package/package.json +1 -1
- package/src/event-line/parser.ts +64 -54
package/dist/index.cjs
CHANGED
|
@@ -15099,6 +15099,8 @@ function parseEventLine(content, palette) {
|
|
|
15099
15099
|
let currentTagGroup = null;
|
|
15100
15100
|
let currentEvent = null;
|
|
15101
15101
|
let currentEra = null;
|
|
15102
|
+
let eraIndent = -1;
|
|
15103
|
+
let currentEventIndent = 0;
|
|
15102
15104
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
15103
15105
|
for (let i = 0; i < lines.length; i++) {
|
|
15104
15106
|
const line11 = lines[i];
|
|
@@ -15173,52 +15175,15 @@ function parseEventLine(content, palette) {
|
|
|
15173
15175
|
});
|
|
15174
15176
|
continue;
|
|
15175
15177
|
}
|
|
15176
|
-
if (indent >
|
|
15177
|
-
if (!currentEvent) {
|
|
15178
|
-
pushWarning(
|
|
15179
|
-
lineNumber,
|
|
15180
|
-
`Indented description "${trimmed}" has no event above it \u2014 add an event line first. (\xA728)`
|
|
15181
|
-
);
|
|
15182
|
-
continue;
|
|
15183
|
-
}
|
|
15178
|
+
if (currentEvent && indent > currentEventIndent) {
|
|
15184
15179
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
15185
15180
|
currentEvent.description.push(descLine);
|
|
15186
15181
|
continue;
|
|
15187
15182
|
}
|
|
15188
|
-
currentTagGroup = null;
|
|
15189
|
-
if (trimmed.toLowerCase() === "no-scale") {
|
|
15190
|
-
options.scale = false;
|
|
15191
|
-
continue;
|
|
15192
|
-
}
|
|
15193
|
-
const sideMatch = trimmed.match(SIDE_RE);
|
|
15194
|
-
if (sideMatch) {
|
|
15195
|
-
options.side = sideMatch[1].toLowerCase();
|
|
15196
|
-
continue;
|
|
15197
|
-
}
|
|
15198
|
-
if (trimmed.toLowerCase() === "no-box") {
|
|
15199
|
-
options.noBox = true;
|
|
15200
|
-
continue;
|
|
15201
|
-
}
|
|
15202
|
-
if (trimmed.toLowerCase() === "no-legend") {
|
|
15203
|
-
options.noLegend = true;
|
|
15204
|
-
continue;
|
|
15205
|
-
}
|
|
15206
|
-
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15207
|
-
if (dirMatch) {
|
|
15208
|
-
const dir = dirMatch[1].toUpperCase();
|
|
15209
|
-
if (dir !== "LR") {
|
|
15210
|
-
pushWarning(
|
|
15211
|
-
lineNumber,
|
|
15212
|
-
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15213
|
-
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15214
|
-
);
|
|
15215
|
-
}
|
|
15216
|
-
continue;
|
|
15217
|
-
}
|
|
15218
|
-
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15219
15183
|
const eraMatch = trimmed.match(ERA_RE);
|
|
15220
15184
|
if (eraMatch) {
|
|
15221
15185
|
contentStarted = true;
|
|
15186
|
+
currentTagGroup = null;
|
|
15222
15187
|
currentEvent = null;
|
|
15223
15188
|
const name = eraMatch[1].trim();
|
|
15224
15189
|
let rest = (eraMatch[2] ?? "").trim();
|
|
@@ -15242,16 +15207,52 @@ function parseEventLine(content, palette) {
|
|
|
15242
15207
|
const era = { name, color, collapsed, lineNumber };
|
|
15243
15208
|
result.eras.push(era);
|
|
15244
15209
|
currentEra = name;
|
|
15210
|
+
eraIndent = indent;
|
|
15245
15211
|
continue;
|
|
15246
15212
|
}
|
|
15247
|
-
if (
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15213
|
+
if (indent === 0) {
|
|
15214
|
+
currentTagGroup = null;
|
|
15215
|
+
if (trimmed.toLowerCase() === "no-scale") {
|
|
15216
|
+
options.scale = false;
|
|
15217
|
+
continue;
|
|
15218
|
+
}
|
|
15219
|
+
const sideMatch = trimmed.match(SIDE_RE);
|
|
15220
|
+
if (sideMatch) {
|
|
15221
|
+
options.side = sideMatch[1].toLowerCase();
|
|
15222
|
+
continue;
|
|
15223
|
+
}
|
|
15224
|
+
if (trimmed.toLowerCase() === "no-box") {
|
|
15225
|
+
options.noBox = true;
|
|
15226
|
+
continue;
|
|
15227
|
+
}
|
|
15228
|
+
if (trimmed.toLowerCase() === "no-legend") {
|
|
15229
|
+
options.noLegend = true;
|
|
15230
|
+
continue;
|
|
15231
|
+
}
|
|
15232
|
+
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15233
|
+
if (dirMatch) {
|
|
15234
|
+
const dir = dirMatch[1].toUpperCase();
|
|
15235
|
+
if (dir !== "LR") {
|
|
15236
|
+
pushWarning(
|
|
15237
|
+
lineNumber,
|
|
15238
|
+
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15239
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15240
|
+
);
|
|
15241
|
+
}
|
|
15242
|
+
continue;
|
|
15243
|
+
}
|
|
15244
|
+
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15245
|
+
if (SECTION_SEAM_RE.test(trimmed)) {
|
|
15246
|
+
pushWarning(
|
|
15247
|
+
lineNumber,
|
|
15248
|
+
"Group events with `[Name]` era brackets (\xA728.6a), not `section`.",
|
|
15249
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15250
|
+
);
|
|
15251
|
+
continue;
|
|
15252
|
+
}
|
|
15254
15253
|
}
|
|
15254
|
+
const inEra = currentEra !== null && indent > eraIndent;
|
|
15255
|
+
if (!inEra) currentEra = null;
|
|
15255
15256
|
contentStarted = true;
|
|
15256
15257
|
const event = parseEventHeader(
|
|
15257
15258
|
trimmed,
|
|
@@ -15263,6 +15264,7 @@ function parseEventLine(content, palette) {
|
|
|
15263
15264
|
);
|
|
15264
15265
|
result.events.push(event);
|
|
15265
15266
|
currentEvent = event;
|
|
15267
|
+
currentEventIndent = indent;
|
|
15266
15268
|
}
|
|
15267
15269
|
options.noTitle = sharedOptions["no-title"] === "on";
|
|
15268
15270
|
finalizeAutoTagColors(result.tagGroups, palette);
|
package/dist/index.js
CHANGED
|
@@ -15115,6 +15115,8 @@ function parseEventLine(content, palette) {
|
|
|
15115
15115
|
let currentTagGroup = null;
|
|
15116
15116
|
let currentEvent = null;
|
|
15117
15117
|
let currentEra = null;
|
|
15118
|
+
let eraIndent = -1;
|
|
15119
|
+
let currentEventIndent = 0;
|
|
15118
15120
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
15119
15121
|
for (let i = 0; i < lines.length; i++) {
|
|
15120
15122
|
const line11 = lines[i];
|
|
@@ -15189,52 +15191,15 @@ function parseEventLine(content, palette) {
|
|
|
15189
15191
|
});
|
|
15190
15192
|
continue;
|
|
15191
15193
|
}
|
|
15192
|
-
if (indent >
|
|
15193
|
-
if (!currentEvent) {
|
|
15194
|
-
pushWarning(
|
|
15195
|
-
lineNumber,
|
|
15196
|
-
`Indented description "${trimmed}" has no event above it \u2014 add an event line first. (\xA728)`
|
|
15197
|
-
);
|
|
15198
|
-
continue;
|
|
15199
|
-
}
|
|
15194
|
+
if (currentEvent && indent > currentEventIndent) {
|
|
15200
15195
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
15201
15196
|
currentEvent.description.push(descLine);
|
|
15202
15197
|
continue;
|
|
15203
15198
|
}
|
|
15204
|
-
currentTagGroup = null;
|
|
15205
|
-
if (trimmed.toLowerCase() === "no-scale") {
|
|
15206
|
-
options.scale = false;
|
|
15207
|
-
continue;
|
|
15208
|
-
}
|
|
15209
|
-
const sideMatch = trimmed.match(SIDE_RE);
|
|
15210
|
-
if (sideMatch) {
|
|
15211
|
-
options.side = sideMatch[1].toLowerCase();
|
|
15212
|
-
continue;
|
|
15213
|
-
}
|
|
15214
|
-
if (trimmed.toLowerCase() === "no-box") {
|
|
15215
|
-
options.noBox = true;
|
|
15216
|
-
continue;
|
|
15217
|
-
}
|
|
15218
|
-
if (trimmed.toLowerCase() === "no-legend") {
|
|
15219
|
-
options.noLegend = true;
|
|
15220
|
-
continue;
|
|
15221
|
-
}
|
|
15222
|
-
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15223
|
-
if (dirMatch) {
|
|
15224
|
-
const dir = dirMatch[1].toUpperCase();
|
|
15225
|
-
if (dir !== "LR") {
|
|
15226
|
-
pushWarning(
|
|
15227
|
-
lineNumber,
|
|
15228
|
-
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15229
|
-
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15230
|
-
);
|
|
15231
|
-
}
|
|
15232
|
-
continue;
|
|
15233
|
-
}
|
|
15234
|
-
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15235
15199
|
const eraMatch = trimmed.match(ERA_RE);
|
|
15236
15200
|
if (eraMatch) {
|
|
15237
15201
|
contentStarted = true;
|
|
15202
|
+
currentTagGroup = null;
|
|
15238
15203
|
currentEvent = null;
|
|
15239
15204
|
const name = eraMatch[1].trim();
|
|
15240
15205
|
let rest = (eraMatch[2] ?? "").trim();
|
|
@@ -15258,16 +15223,52 @@ function parseEventLine(content, palette) {
|
|
|
15258
15223
|
const era = { name, color, collapsed, lineNumber };
|
|
15259
15224
|
result.eras.push(era);
|
|
15260
15225
|
currentEra = name;
|
|
15226
|
+
eraIndent = indent;
|
|
15261
15227
|
continue;
|
|
15262
15228
|
}
|
|
15263
|
-
if (
|
|
15264
|
-
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
|
|
15229
|
+
if (indent === 0) {
|
|
15230
|
+
currentTagGroup = null;
|
|
15231
|
+
if (trimmed.toLowerCase() === "no-scale") {
|
|
15232
|
+
options.scale = false;
|
|
15233
|
+
continue;
|
|
15234
|
+
}
|
|
15235
|
+
const sideMatch = trimmed.match(SIDE_RE);
|
|
15236
|
+
if (sideMatch) {
|
|
15237
|
+
options.side = sideMatch[1].toLowerCase();
|
|
15238
|
+
continue;
|
|
15239
|
+
}
|
|
15240
|
+
if (trimmed.toLowerCase() === "no-box") {
|
|
15241
|
+
options.noBox = true;
|
|
15242
|
+
continue;
|
|
15243
|
+
}
|
|
15244
|
+
if (trimmed.toLowerCase() === "no-legend") {
|
|
15245
|
+
options.noLegend = true;
|
|
15246
|
+
continue;
|
|
15247
|
+
}
|
|
15248
|
+
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15249
|
+
if (dirMatch) {
|
|
15250
|
+
const dir = dirMatch[1].toUpperCase();
|
|
15251
|
+
if (dir !== "LR") {
|
|
15252
|
+
pushWarning(
|
|
15253
|
+
lineNumber,
|
|
15254
|
+
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15255
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15256
|
+
);
|
|
15257
|
+
}
|
|
15258
|
+
continue;
|
|
15259
|
+
}
|
|
15260
|
+
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15261
|
+
if (SECTION_SEAM_RE.test(trimmed)) {
|
|
15262
|
+
pushWarning(
|
|
15263
|
+
lineNumber,
|
|
15264
|
+
"Group events with `[Name]` era brackets (\xA728.6a), not `section`.",
|
|
15265
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15266
|
+
);
|
|
15267
|
+
continue;
|
|
15268
|
+
}
|
|
15270
15269
|
}
|
|
15270
|
+
const inEra = currentEra !== null && indent > eraIndent;
|
|
15271
|
+
if (!inEra) currentEra = null;
|
|
15271
15272
|
contentStarted = true;
|
|
15272
15273
|
const event = parseEventHeader(
|
|
15273
15274
|
trimmed,
|
|
@@ -15279,6 +15280,7 @@ function parseEventLine(content, palette) {
|
|
|
15279
15280
|
);
|
|
15280
15281
|
result.events.push(event);
|
|
15281
15282
|
currentEvent = event;
|
|
15283
|
+
currentEventIndent = indent;
|
|
15282
15284
|
}
|
|
15283
15285
|
options.noTitle = sharedOptions["no-title"] === "on";
|
|
15284
15286
|
finalizeAutoTagColors(result.tagGroups, palette);
|
|
@@ -2399,6 +2399,23 @@ tag Genre as g
|
|
|
2399
2399
|
- **Tag** — trailing same-line metadata (`g: Pop`), like timeline; colors the dot, leader, and card.
|
|
2400
2400
|
- **Description** — bare indented body lines (like `pyramid`/`ring`); `- ` makes a bullet; inline markdown (`**bold**`, `*italic*`, `` `code` ``) supported.
|
|
2401
2401
|
|
|
2402
|
+
#### Eras
|
|
2403
|
+
|
|
2404
|
+
Group a run of events into a labeled section with a `[Name]` bracket, then **indent the events beneath it** (the org / version-control nesting idiom). An event belongs to the era it is indented under; its description sits one level deeper still. An event at indent 0 sits **outside** any era.
|
|
2405
|
+
|
|
2406
|
+
```
|
|
2407
|
+
[The Early Web]
|
|
2408
|
+
1991 WorldWideWeb t: Protocol
|
|
2409
|
+
Tim Berners-Lee publishes the first site.
|
|
2410
|
+
1993 Mosaic t: Browser
|
|
2411
|
+
|
|
2412
|
+
[The App Era] collapsed: true
|
|
2413
|
+
2005 Ajax t: Platform
|
|
2414
|
+
```
|
|
2415
|
+
|
|
2416
|
+
- **Trailing metadata** after `]` — optional `collapsed: true` and/or a named color (`[The 1960s] collapsed: true blue`).
|
|
2417
|
+
- **`collapsed: true`** folds the era into a single summary card (its name + a bulleted list of member events) while a bracket stays on the spine; in the app a reader toggles it live.
|
|
2418
|
+
|
|
2402
2419
|
#### Directives
|
|
2403
2420
|
|
|
2404
2421
|
- `no-scale` — space events evenly instead of by date (dates become captions).
|
|
@@ -8,19 +8,19 @@ tag Theme as t
|
|
|
8
8
|
Standard orange
|
|
9
9
|
|
|
10
10
|
[The Early Web]
|
|
11
|
-
1991 WorldWideWeb t: Protocol
|
|
12
|
-
|
|
13
|
-
1993 Mosaic t: Browser
|
|
14
|
-
|
|
11
|
+
1991 WorldWideWeb t: Protocol
|
|
12
|
+
Tim Berners-Lee publishes the first website at **CERN**.
|
|
13
|
+
1993 Mosaic t: Browser
|
|
14
|
+
The first popular *graphical* browser.
|
|
15
15
|
|
|
16
16
|
[The Standards Era] collapsed: true
|
|
17
|
-
1995 JavaScript t: Platform
|
|
18
|
-
|
|
19
|
-
1996 CSS t: Standard
|
|
20
|
-
|
|
17
|
+
1995 JavaScript t: Platform
|
|
18
|
+
Brendan Eich writes the language in ten days.
|
|
19
|
+
1996 CSS t: Standard
|
|
20
|
+
Styling splits from structure.
|
|
21
21
|
|
|
22
22
|
[The App Era]
|
|
23
|
-
2005 Ajax t: Platform
|
|
24
|
-
|
|
25
|
-
2014 HTML5 t: Standard
|
|
26
|
-
|
|
23
|
+
2005 Ajax t: Platform
|
|
24
|
+
`XMLHttpRequest` updates pages without a reload.
|
|
25
|
+
2014 HTML5 t: Standard
|
|
26
|
+
The living standard — video, canvas, semantics.
|
package/package.json
CHANGED
package/src/event-line/parser.ts
CHANGED
|
@@ -203,15 +203,17 @@ export function parseEventLine(
|
|
|
203
203
|
continue;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
// ──
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
206
|
+
// ── Content phase: indentation classifies each line. ──
|
|
207
|
+
//
|
|
208
|
+
// Eras are top-level `[Name]` section headers whose member events are
|
|
209
|
+
// INDENTED beneath them (the org §7 / version-control §29 idiom); an event
|
|
210
|
+
// at indent 0 sits OUTSIDE any era. A line indented deeper than its event
|
|
211
|
+
// is that event's description body (§28.4).
|
|
212
|
+
|
|
213
|
+
// Description body — any line indented deeper than its event. Checked
|
|
214
|
+
// before the era bracket so a bracketed prose line (` [aside]`) under an
|
|
215
|
+
// event stays a description rather than opening a spurious era.
|
|
216
|
+
if (currentEvent && indent > currentEventIndent) {
|
|
215
217
|
const descLine = trimmed.startsWith('- ')
|
|
216
218
|
? `• ${trimmed.substring(2)}`
|
|
217
219
|
: trimmed;
|
|
@@ -219,47 +221,14 @@ export function parseEventLine(
|
|
|
219
221
|
continue;
|
|
220
222
|
}
|
|
221
223
|
|
|
222
|
-
// ──
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
options.scale = false;
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
const sideMatch = trimmed.match(SIDE_RE);
|
|
230
|
-
if (sideMatch) {
|
|
231
|
-
options.side = sideMatch[1]!.toLowerCase() as EventLineOptions['side'];
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
if (trimmed.toLowerCase() === 'no-box') {
|
|
235
|
-
options.noBox = true;
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
if (trimmed.toLowerCase() === 'no-legend') {
|
|
239
|
-
options.noLegend = true;
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
243
|
-
if (dirMatch) {
|
|
244
|
-
const dir = dirMatch[1]!.toUpperCase();
|
|
245
|
-
if (dir !== 'LR') {
|
|
246
|
-
pushWarning(
|
|
247
|
-
lineNumber,
|
|
248
|
-
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
249
|
-
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
255
|
-
|
|
256
|
-
// ── Era run delimiter: `[Name]` opens a section that runs to the next
|
|
257
|
-
// `[Name]` or EOF (§28.6a). NOT an indentation container — events stay at
|
|
258
|
-
// indent 0, so flat bare-body descriptions are preserved. Optional trailing
|
|
259
|
-
// `collapsed: true` and/or a color name tint/fold the era.
|
|
224
|
+
// ── Era run delimiter: `[Name]` (§28.6a) — a section header whose member
|
|
225
|
+
// events are indented beneath it. Dedenting to (or past) the bracket's
|
|
226
|
+
// own indent leaves the era. Optional trailing `collapsed: true` and/or
|
|
227
|
+
// a color name tint/fold the era.
|
|
260
228
|
const eraMatch = trimmed.match(ERA_RE);
|
|
261
229
|
if (eraMatch) {
|
|
262
230
|
contentStarted = true;
|
|
231
|
+
currentTagGroup = null;
|
|
263
232
|
currentEvent = null;
|
|
264
233
|
const name = eraMatch[1]!.trim();
|
|
265
234
|
let rest = (eraMatch[2] ?? '').trim();
|
|
@@ -288,19 +257,59 @@ export function parseEventLine(
|
|
|
288
257
|
const era: EventLineEra = { name, color, collapsed, lineNumber };
|
|
289
258
|
result.eras.push(era);
|
|
290
259
|
currentEra = name;
|
|
260
|
+
eraIndent = indent;
|
|
291
261
|
continue;
|
|
292
262
|
}
|
|
293
263
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
264
|
+
// ── Top-level (indent 0) directives and reserved seams. ──
|
|
265
|
+
if (indent === 0) {
|
|
266
|
+
currentTagGroup = null;
|
|
267
|
+
if (trimmed.toLowerCase() === 'no-scale') {
|
|
268
|
+
options.scale = false;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const sideMatch = trimmed.match(SIDE_RE);
|
|
272
|
+
if (sideMatch) {
|
|
273
|
+
options.side = sideMatch[1]!.toLowerCase() as EventLineOptions['side'];
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (trimmed.toLowerCase() === 'no-box') {
|
|
277
|
+
options.noBox = true;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (trimmed.toLowerCase() === 'no-legend') {
|
|
281
|
+
options.noLegend = true;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
285
|
+
if (dirMatch) {
|
|
286
|
+
const dir = dirMatch[1]!.toUpperCase();
|
|
287
|
+
if (dir !== 'LR') {
|
|
288
|
+
pushWarning(
|
|
289
|
+
lineNumber,
|
|
290
|
+
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
291
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
297
|
+
if (SECTION_SEAM_RE.test(trimmed)) {
|
|
298
|
+
pushWarning(
|
|
299
|
+
lineNumber,
|
|
300
|
+
'Group events with `[Name]` era brackets (§28.6a), not `section`.',
|
|
301
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
302
|
+
);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
301
305
|
}
|
|
302
306
|
|
|
303
307
|
// ── Event line ──
|
|
308
|
+
// An event belongs to the open era only when indented beneath that era's
|
|
309
|
+
// bracket; an indent-0 event sits outside any era and closes the run
|
|
310
|
+
// (events outside eras are fully supported — they simply have `era: null`).
|
|
311
|
+
const inEra = currentEra !== null && indent > eraIndent;
|
|
312
|
+
if (!inEra) currentEra = null;
|
|
304
313
|
contentStarted = true;
|
|
305
314
|
const event = parseEventHeader(
|
|
306
315
|
trimmed,
|
|
@@ -312,6 +321,7 @@ export function parseEventLine(
|
|
|
312
321
|
);
|
|
313
322
|
result.events.push(event);
|
|
314
323
|
currentEvent = event;
|
|
324
|
+
currentEventIndent = indent;
|
|
315
325
|
}
|
|
316
326
|
|
|
317
327
|
options.noTitle = sharedOptions['no-title'] === 'on';
|