confluence-md-sync 0.8.2 → 0.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/export/to-markdown.js +37 -3
- package/package.json +1 -1
|
@@ -582,14 +582,24 @@ class Converter {
|
|
|
582
582
|
const grid = trs.map((tr) => elements(tr.children)
|
|
583
583
|
.filter((c) => c.name === 'td' || c.name === 'th')
|
|
584
584
|
.map((c) => {
|
|
585
|
+
// Сначала честная конвертация (page-ссылки → {{page:…}}); стрип пустых
|
|
586
|
+
// ac:/ri:-вставок — только если она не удалась (иначе теряются ссылки
|
|
587
|
+
// без текста тела: у них подпись — заголовок страницы).
|
|
585
588
|
let flat;
|
|
586
589
|
try {
|
|
587
|
-
flat = this.cellFlatten(
|
|
590
|
+
flat = this.cellFlatten(c.children);
|
|
588
591
|
}
|
|
589
592
|
catch (e) {
|
|
590
593
|
if (!(e instanceof Unrepresentable))
|
|
591
594
|
throw e;
|
|
592
|
-
|
|
595
|
+
try {
|
|
596
|
+
flat = this.cellFlatten(this.stripEmptyNamespaced(c.children));
|
|
597
|
+
}
|
|
598
|
+
catch (e2) {
|
|
599
|
+
if (!(e2 instanceof Unrepresentable))
|
|
600
|
+
throw e2;
|
|
601
|
+
flat = textContent(c.children);
|
|
602
|
+
}
|
|
593
603
|
}
|
|
594
604
|
return flat.replace(/\s+/g, ' ').trim();
|
|
595
605
|
}));
|
|
@@ -1472,8 +1482,32 @@ function escapeMdText(raw, ctx, readable = false) {
|
|
|
1472
1482
|
out += escapePlain(collapsed.slice(last), ctx, readable);
|
|
1473
1483
|
return out;
|
|
1474
1484
|
}
|
|
1485
|
+
const ESCAPE_SPECIALS = '\\`*[]{}~';
|
|
1486
|
+
// Буква/цифра любого алфавита (вкл. кириллицу). Внутрисловное `_` между двумя
|
|
1487
|
+
// такими символами по CommonMark не открывает и не закрывает акцент, поэтому
|
|
1488
|
+
// экранировать его НЕ нужно.
|
|
1489
|
+
const WORDCHAR_RE = /[\p{L}\p{N}]/u;
|
|
1475
1490
|
function escapePlain(s, _ctx, readable = false) {
|
|
1476
|
-
|
|
1491
|
+
let esc = '';
|
|
1492
|
+
for (let i = 0; i < s.length; i++) {
|
|
1493
|
+
const c = s[i];
|
|
1494
|
+
if (c === '_') {
|
|
1495
|
+
// Экранируем `_` только на границе слова (snake_case НЕ трогаем — иначе
|
|
1496
|
+
// выходят уродливые `BA\_M1\_…`). Внутрисловное `_` литерально и в
|
|
1497
|
+
// CommonMark, round-trip остаётся канонически эквивалентным.
|
|
1498
|
+
const prev = s[i - 1];
|
|
1499
|
+
const next = s[i + 1];
|
|
1500
|
+
const intraword = prev !== undefined && next !== undefined &&
|
|
1501
|
+
WORDCHAR_RE.test(prev) && WORDCHAR_RE.test(next);
|
|
1502
|
+
esc += intraword ? '_' : '\\_';
|
|
1503
|
+
}
|
|
1504
|
+
else if (ESCAPE_SPECIALS.includes(c)) {
|
|
1505
|
+
esc += '\\' + c;
|
|
1506
|
+
}
|
|
1507
|
+
else {
|
|
1508
|
+
esc += c;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1477
1511
|
// Пайпы здесь НЕ трогаем — они экранируются один раз на границе ячейки
|
|
1478
1512
|
// (cellMd / readableTable), иначе плейсхолдеры {{img:…|…}} двоились бы.
|
|
1479
1513
|
// readable: неразрывный пробел → обычный; faithful: → entity (переживает
|
package/package.json
CHANGED