@geml/geml 1.8.3 → 1.8.4
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/geml.js +36 -4
- package/dist/serialize.js +7 -1
- package/dist/to-md.js +8 -1
- package/package.json +1 -1
package/dist/geml.js
CHANGED
|
@@ -309,14 +309,32 @@ function matchMarker(line) {
|
|
|
309
309
|
mk.start = parseInt(m[2], 10);
|
|
310
310
|
return mk;
|
|
311
311
|
}
|
|
312
|
+
// Leading indentation in COLUMNS (a tab counts as 4), the same measure the
|
|
313
|
+
// marker regex feeds into nesting decisions.
|
|
314
|
+
function indentColumns(line) {
|
|
315
|
+
let n = 0;
|
|
316
|
+
for (const ch of line) {
|
|
317
|
+
if (ch === " ")
|
|
318
|
+
n += 1;
|
|
319
|
+
else if (ch === "\t")
|
|
320
|
+
n += 4;
|
|
321
|
+
else
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
return n;
|
|
325
|
+
}
|
|
312
326
|
function makeListItem(mk, lineNo, ctx) {
|
|
313
327
|
let text = interpolate(mk.rest, lineNo, ctx);
|
|
314
|
-
// Task list item: a leading `[ ]` (open) or `[x]`/`[X]` (done) marker
|
|
315
|
-
|
|
328
|
+
// Task list item: a leading `[ ]` (open) or `[x]`/`[X]` (done) marker — on
|
|
329
|
+
// the item's FIRST line; continuation lines (§2.2) are already joined in,
|
|
330
|
+
// and a `[x]` there is content.
|
|
331
|
+
const nl = text.indexOf("\n");
|
|
332
|
+
const first = nl === -1 ? text : text.slice(0, nl);
|
|
333
|
+
const task = /^\[([ xX])\](?:[ \t]+(.*))?$/.exec(first);
|
|
316
334
|
const item = { text, inlines: [] };
|
|
317
335
|
if (task) {
|
|
318
336
|
item.checked = task[1] !== " ";
|
|
319
|
-
text = task[2] ?? "";
|
|
337
|
+
text = (task[2] ?? "") + (nl === -1 ? "" : text.slice(nl));
|
|
320
338
|
item.text = text;
|
|
321
339
|
}
|
|
322
340
|
item.inlines = parseInline(text, lineNo, ctx);
|
|
@@ -380,9 +398,23 @@ function parseList(lines, i, base, ctx) {
|
|
|
380
398
|
}
|
|
381
399
|
if (prevBlank && cur.items.length > 0)
|
|
382
400
|
cur.loose = true;
|
|
401
|
+
// §2.2 continuation lines: a non-blank line directly below the
|
|
402
|
+
// item, indented past its MARKER, that is neither an item line nor a `%%`
|
|
403
|
+
// comment, continues the item's inline content as a soft wrap — the same
|
|
404
|
+
// join a paragraph gives its lines. A blank line still ends the item, so
|
|
405
|
+
// multi-paragraph items remain outside the language.
|
|
406
|
+
let j = i + 1;
|
|
407
|
+
while (j < lines.length) {
|
|
408
|
+
const cand = lines[j];
|
|
409
|
+
const body = cand.trim();
|
|
410
|
+
if (body === "" || body.startsWith("%%") || matchMarker(cand) !== null || indentColumns(cand) <= mk.indent)
|
|
411
|
+
break;
|
|
412
|
+
mk.rest += "\n" + body;
|
|
413
|
+
j++;
|
|
414
|
+
}
|
|
383
415
|
cur.items.push(makeListItem(mk, base + i + 1, ctx));
|
|
384
416
|
prevBlank = false;
|
|
385
|
-
i
|
|
417
|
+
i = j;
|
|
386
418
|
}
|
|
387
419
|
return { block: root, next: i };
|
|
388
420
|
}
|
package/dist/serialize.js
CHANGED
|
@@ -157,7 +157,13 @@ function serList(list, indent) {
|
|
|
157
157
|
list.items.forEach((item, k) => {
|
|
158
158
|
const marker = list.ordered ? `${start + k}. ` : "- ";
|
|
159
159
|
const task = item.checked === undefined ? "" : item.checked ? "[x] " : "[ ] ";
|
|
160
|
-
|
|
160
|
+
// A soft-wrapped item (§2.2) serializes as continuation lines aligned under
|
|
161
|
+
// its content, so the emission re-parses to the same item.
|
|
162
|
+
const [head, ...cont] = serInlines(item.inlines).split("\n");
|
|
163
|
+
out.push(indent + marker + task + head);
|
|
164
|
+
const contIndent = indent + " ".repeat(marker.length + task.length);
|
|
165
|
+
for (const l of cont)
|
|
166
|
+
out.push(contIndent + l);
|
|
161
167
|
for (const child of item.children ?? []) {
|
|
162
168
|
out.push(child.kind === "list" ? serList(child, indent + " ") : serBlock(child));
|
|
163
169
|
}
|
package/dist/to-md.js
CHANGED
|
@@ -116,7 +116,14 @@ function listToMd(b, indent, notes) {
|
|
|
116
116
|
b.items.forEach((item, k) => {
|
|
117
117
|
const marker = b.ordered ? `${start + k}. ` : "- ";
|
|
118
118
|
const task = item.checked === undefined ? "" : item.checked ? "[x] " : "[ ] ";
|
|
119
|
-
|
|
119
|
+
// A soft-wrapped item (§2.2) keeps its wrap: continuation lines indented to
|
|
120
|
+
// the content column, which both GFM and a GEML re-parse read as the same
|
|
121
|
+
// single item.
|
|
122
|
+
const [head, ...cont] = seq(item.inlines).split("\n");
|
|
123
|
+
out.push(indent + marker + task + head);
|
|
124
|
+
const contIndent = indent + " ".repeat(marker.length + task.length);
|
|
125
|
+
for (const l of cont)
|
|
126
|
+
out.push(contIndent + l);
|
|
120
127
|
for (const child of item.children ?? []) {
|
|
121
128
|
out.push(child.kind === "list" ? listToMd(child, indent + " ", notes) : block(child, notes));
|
|
122
129
|
}
|