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.
@@ -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(this.stripEmptyNamespaced(c.children));
590
+ flat = this.cellFlatten(c.children);
588
591
  }
589
592
  catch (e) {
590
593
  if (!(e instanceof Unrepresentable))
591
594
  throw e;
592
- flat = textContent(c.children);
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
- const esc = s.replace(/[\\`*_[\]{}~]/g, (c) => '\\' + c);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "confluence-md-sync",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "Publish Markdown to Confluence (Data Center & Cloud): idempotent page sync, attachment dedup, tables and a pluggable macro system",
5
5
  "keywords": [
6
6
  "confluence",