formatferry 1.0.35 → 1.0.37
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/index.js +229 -151
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -58515,6 +58515,49 @@ function normalizeAtlassianHTML(html, domParser) {
|
|
|
58515
58515
|
|
|
58516
58516
|
// ../../src/shared/confluence-slack-services.ts
|
|
58517
58517
|
var import_turndown = __toESM(require_turndown_cjs(), 1);
|
|
58518
|
+
|
|
58519
|
+
// ../../src/shared/text-decoration.ts
|
|
58520
|
+
var DECLARATION = /(?:^|;)\s*text-decoration(?:-line)?\s*:([^;]*)/gi;
|
|
58521
|
+
function styleDecorations(style) {
|
|
58522
|
+
const result = { underline: false, strike: false };
|
|
58523
|
+
if (!style) return result;
|
|
58524
|
+
DECLARATION.lastIndex = 0;
|
|
58525
|
+
let match;
|
|
58526
|
+
while ((match = DECLARATION.exec(style)) !== null) {
|
|
58527
|
+
const value = match[1].toLowerCase();
|
|
58528
|
+
result.underline = /\bunderline\b/.test(value);
|
|
58529
|
+
result.strike = /\bline-through\b/.test(value);
|
|
58530
|
+
}
|
|
58531
|
+
return result;
|
|
58532
|
+
}
|
|
58533
|
+
function nodeStyle(node) {
|
|
58534
|
+
const el = node;
|
|
58535
|
+
return typeof el.getAttribute === "function" ? el.getAttribute("style") || "" : "";
|
|
58536
|
+
}
|
|
58537
|
+
function nodeDecorations(node) {
|
|
58538
|
+
const fromStyle = styleDecorations(nodeStyle(node));
|
|
58539
|
+
const name = node.nodeName;
|
|
58540
|
+
return {
|
|
58541
|
+
underline: fromStyle.underline || name === "U" || name === "INS",
|
|
58542
|
+
strike: fromStyle.strike || name === "DEL" || name === "S" || name === "STRIKE"
|
|
58543
|
+
};
|
|
58544
|
+
}
|
|
58545
|
+
function isUnderlineSpan(node) {
|
|
58546
|
+
return node.nodeName === "SPAN" && styleDecorations(nodeStyle(node)).underline;
|
|
58547
|
+
}
|
|
58548
|
+
function isStrikeSpan(node) {
|
|
58549
|
+
return node.nodeName === "SPAN" && styleDecorations(nodeStyle(node)).strike;
|
|
58550
|
+
}
|
|
58551
|
+
function decorate(content, node, syntax) {
|
|
58552
|
+
if (!content.trim()) return content;
|
|
58553
|
+
const d = nodeDecorations(node);
|
|
58554
|
+
let out = content;
|
|
58555
|
+
if (d.underline && syntax.underline) out = syntax.underline[0] + out + syntax.underline[1];
|
|
58556
|
+
if (d.strike && syntax.strike) out = syntax.strike[0] + out + syntax.strike[1];
|
|
58557
|
+
return out;
|
|
58558
|
+
}
|
|
58559
|
+
|
|
58560
|
+
// ../../src/shared/confluence-slack-services.ts
|
|
58518
58561
|
function escapeSlackEntities(text) {
|
|
58519
58562
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
58520
58563
|
}
|
|
@@ -58577,13 +58620,9 @@ function createSlackService(deps) {
|
|
|
58577
58620
|
service.addRule("slackStrikethrough", {
|
|
58578
58621
|
filter: (node) => {
|
|
58579
58622
|
if (["DEL", "S", "STRIKE"].includes(node.nodeName)) return true;
|
|
58580
|
-
|
|
58581
|
-
const style = node.getAttribute("style") || "";
|
|
58582
|
-
return style.includes("text-decoration: line-through") || style.includes("text-decoration:line-through") || style.includes("text-decoration-line: line-through") || style.includes("text-decoration-line:line-through");
|
|
58583
|
-
}
|
|
58584
|
-
return false;
|
|
58623
|
+
return isStrikeSpan(node);
|
|
58585
58624
|
},
|
|
58586
|
-
replacement: (content) => content
|
|
58625
|
+
replacement: (content, node) => decorate(content, node, { underline: null, strike: ["~", "~"] })
|
|
58587
58626
|
});
|
|
58588
58627
|
service.addRule("slackMonospaceCode", {
|
|
58589
58628
|
filter: (node) => {
|
|
@@ -58644,13 +58683,10 @@ ${escapeSlackEntities(code)}
|
|
|
58644
58683
|
service.addRule("slackUnderline", {
|
|
58645
58684
|
filter: (node) => {
|
|
58646
58685
|
if (node.nodeName === "U" || node.nodeName === "INS") return true;
|
|
58647
|
-
|
|
58648
|
-
const style = node.getAttribute("style") || "";
|
|
58649
|
-
return style.includes("text-decoration: underline") || style.includes("text-decoration:underline");
|
|
58650
|
-
}
|
|
58651
|
-
return false;
|
|
58686
|
+
return isUnderlineSpan(node);
|
|
58652
58687
|
},
|
|
58653
|
-
|
|
58688
|
+
// Slack has no underline; keep a strikethrough set on the same span
|
|
58689
|
+
replacement: (content, node) => decorate(content, node, { underline: null, strike: ["~", "~"] })
|
|
58654
58690
|
});
|
|
58655
58691
|
service.addRule("slackLink", {
|
|
58656
58692
|
filter: (node) => node.nodeName === "A" && !!node.getAttribute("href"),
|
|
@@ -58682,34 +58718,38 @@ ${plainText}
|
|
|
58682
58718
|
});
|
|
58683
58719
|
return service;
|
|
58684
58720
|
}
|
|
58685
|
-
function processConfluenceList(list, service,
|
|
58686
|
-
const
|
|
58687
|
-
const marker = (isOrdered ? "#" : "*").repeat(depth);
|
|
58721
|
+
function processConfluenceList(list, service, parentPrefix) {
|
|
58722
|
+
const prefix = parentPrefix + (list.nodeName === "OL" ? "#" : "*");
|
|
58688
58723
|
const items = Array.from(list.children).filter((c) => c.nodeName === "LI");
|
|
58689
|
-
|
|
58724
|
+
const isTop = parentPrefix === "";
|
|
58725
|
+
let result = isTop ? "\n" : "";
|
|
58690
58726
|
items.forEach((item) => {
|
|
58691
|
-
const itemContent = processConfluenceListItem(item, service,
|
|
58692
|
-
result += `${
|
|
58727
|
+
const itemContent = processConfluenceListItem(item, service, prefix);
|
|
58728
|
+
result += `${prefix} ${itemContent}
|
|
58693
58729
|
`;
|
|
58694
58730
|
});
|
|
58695
|
-
return
|
|
58731
|
+
return isTop ? result + "\n" : result;
|
|
58696
58732
|
}
|
|
58697
|
-
function processConfluenceListItem(item, service,
|
|
58698
|
-
let content = "";
|
|
58699
|
-
const TEXT_NODE = 3;
|
|
58733
|
+
function processConfluenceListItem(item, service, prefix) {
|
|
58700
58734
|
const ELEMENT_NODE2 = 1;
|
|
58735
|
+
const doc = item.ownerDocument;
|
|
58736
|
+
let content = "";
|
|
58737
|
+
let buffer = doc.createElement("div");
|
|
58738
|
+
const flush = () => {
|
|
58739
|
+
if (buffer.childNodes.length > 0) {
|
|
58740
|
+
content += service.turndown(buffer).replace(/[ \t]*\n(?:[ \t]*\n)+[ \t]*/g, " \\\\ ");
|
|
58741
|
+
}
|
|
58742
|
+
buffer = doc.createElement("div");
|
|
58743
|
+
};
|
|
58701
58744
|
Array.from(item.childNodes).forEach((child) => {
|
|
58702
|
-
if (child.nodeType ===
|
|
58703
|
-
|
|
58704
|
-
|
|
58705
|
-
|
|
58706
|
-
|
|
58707
|
-
content += "\n" + processConfluenceList(el, service, depth + 1);
|
|
58708
|
-
} else {
|
|
58709
|
-
content += service.turndown(el.outerHTML);
|
|
58710
|
-
}
|
|
58745
|
+
if (child.nodeType === ELEMENT_NODE2 && (child.nodeName === "UL" || child.nodeName === "OL")) {
|
|
58746
|
+
flush();
|
|
58747
|
+
content = content.trimEnd() + "\n" + processConfluenceList(child, service, prefix);
|
|
58748
|
+
} else {
|
|
58749
|
+
buffer.appendChild(child.cloneNode(true));
|
|
58711
58750
|
}
|
|
58712
58751
|
});
|
|
58752
|
+
flush();
|
|
58713
58753
|
return content.trim();
|
|
58714
58754
|
}
|
|
58715
58755
|
function createConfluenceService(deps) {
|
|
@@ -58785,24 +58825,16 @@ ${codeContent}
|
|
|
58785
58825
|
service.addRule("confluenceUnderline", {
|
|
58786
58826
|
filter: (node) => {
|
|
58787
58827
|
if (node.nodeName === "U" || node.nodeName === "INS") return true;
|
|
58788
|
-
|
|
58789
|
-
const style = node.getAttribute("style") || "";
|
|
58790
|
-
return style.includes("text-decoration: underline") || style.includes("text-decoration:underline");
|
|
58791
|
-
}
|
|
58792
|
-
return false;
|
|
58828
|
+
return isUnderlineSpan(node);
|
|
58793
58829
|
},
|
|
58794
|
-
replacement: (content) => content
|
|
58830
|
+
replacement: (content, node) => decorate(content, node, { underline: ["+", "+"], strike: ["-", "-"] })
|
|
58795
58831
|
});
|
|
58796
58832
|
service.addRule("confluenceStrikethrough", {
|
|
58797
58833
|
filter: (node) => {
|
|
58798
58834
|
if (["DEL", "S", "STRIKE"].includes(node.nodeName)) return true;
|
|
58799
|
-
|
|
58800
|
-
const style = node.getAttribute("style") || "";
|
|
58801
|
-
return style.includes("text-decoration: line-through") || style.includes("text-decoration:line-through") || style.includes("text-decoration-line: line-through") || style.includes("text-decoration-line:line-through");
|
|
58802
|
-
}
|
|
58803
|
-
return false;
|
|
58835
|
+
return isStrikeSpan(node);
|
|
58804
58836
|
},
|
|
58805
|
-
replacement: (content) => content
|
|
58837
|
+
replacement: (content, node) => decorate(content, node, { underline: ["+", "+"], strike: ["-", "-"] })
|
|
58806
58838
|
});
|
|
58807
58839
|
service.addRule("confluenceMonospaceCode", {
|
|
58808
58840
|
filter: (node) => {
|
|
@@ -58886,7 +58918,7 @@ h${level}. ${trimmed}
|
|
|
58886
58918
|
service.addRule("confluenceList", {
|
|
58887
58919
|
filter: ["ul", "ol"],
|
|
58888
58920
|
replacement: (_content, node) => {
|
|
58889
|
-
return processConfluenceList(node, service,
|
|
58921
|
+
return processConfluenceList(node, service, "");
|
|
58890
58922
|
}
|
|
58891
58923
|
});
|
|
58892
58924
|
service.addRule("confluenceTable", {
|
|
@@ -58900,7 +58932,7 @@ h${level}. ${trimmed}
|
|
|
58900
58932
|
const cells = Array.from(row.querySelectorAll("th, td"));
|
|
58901
58933
|
const isHeaderRow = cells.some((c) => c.nodeName === "TH");
|
|
58902
58934
|
const delim = isHeaderRow ? "||" : "|";
|
|
58903
|
-
const cellTexts = cells.map((c) => (c.textContent || "").trim());
|
|
58935
|
+
const cellTexts = cells.map((c) => (c.textContent || "").trim().replace(/\|/g, "\\|"));
|
|
58904
58936
|
result += delim + cellTexts.join(delim) + delim + "\n";
|
|
58905
58937
|
});
|
|
58906
58938
|
return result + "\n";
|
|
@@ -58983,7 +59015,7 @@ var ConversionEngine = class {
|
|
|
58983
59015
|
emDelimiter: "_"
|
|
58984
59016
|
});
|
|
58985
59017
|
this.addGoogleDocsRules(this.githubService);
|
|
58986
|
-
this.addGoogleDocsRules(this.commonmarkService);
|
|
59018
|
+
this.addGoogleDocsRules(this.commonmarkService, ["<del>", "</del>"]);
|
|
58987
59019
|
this.addGoogleDocsRules(this.customService);
|
|
58988
59020
|
this.addTableRules(this.githubService);
|
|
58989
59021
|
this.addTableRules(this.commonmarkService);
|
|
@@ -58997,6 +59029,13 @@ var ConversionEngine = class {
|
|
|
58997
59029
|
this.addSupSubMathRules(this.githubService);
|
|
58998
59030
|
this.addSupSubMathRules(this.commonmarkService);
|
|
58999
59031
|
this.addSupSubMathRules(this.customService);
|
|
59032
|
+
this.commonmarkService.addRule("commonmarkStrikethrough", {
|
|
59033
|
+
filter: (node) => {
|
|
59034
|
+
if (["DEL", "S", "STRIKE"].includes(node.nodeName)) return true;
|
|
59035
|
+
return isStrikeSpan(node);
|
|
59036
|
+
},
|
|
59037
|
+
replacement: (content, node) => decorate(content, node, { underline: ["<u>", "</u>"], strike: ["<del>", "</del>"] })
|
|
59038
|
+
});
|
|
59000
59039
|
this.addPdfPageMarkerRules(this.githubService);
|
|
59001
59040
|
this.addPdfPageMarkerRules(this.commonmarkService);
|
|
59002
59041
|
this.addPdfPageMarkerRules(this.customService);
|
|
@@ -59067,8 +59106,10 @@ var ConversionEngine = class {
|
|
|
59067
59106
|
this.addPdfPageMarkerRules(service);
|
|
59068
59107
|
this.addSlideMarkerRules(service);
|
|
59069
59108
|
service.addRule("discordUnderline", {
|
|
59070
|
-
|
|
59071
|
-
|
|
59109
|
+
// Includes Google Docs CSS underline, which the shared rules would
|
|
59110
|
+
// otherwise emit as <u>…</u> (shown literally in Discord)
|
|
59111
|
+
filter: (node) => node.nodeName === "U" || node.nodeName === "INS" || isUnderlineSpan(node),
|
|
59112
|
+
replacement: (content, node) => decorate(content, node, { underline: ["__", "__"], strike: ["~~", "~~"] })
|
|
59072
59113
|
});
|
|
59073
59114
|
service.addRule("discordHeadingLimit", {
|
|
59074
59115
|
filter: ["h4", "h5", "h6"],
|
|
@@ -59151,7 +59192,6 @@ ${plainText}
|
|
|
59151
59192
|
* Converts Unicode superscript to ^text syntax
|
|
59152
59193
|
*/
|
|
59153
59194
|
normalizeRedditUnicode(markdown) {
|
|
59154
|
-
let result = markdown;
|
|
59155
59195
|
const superscriptMap = {
|
|
59156
59196
|
"\u2070": "0",
|
|
59157
59197
|
"\xB9": "1",
|
|
@@ -59166,9 +59206,6 @@ ${plainText}
|
|
|
59166
59206
|
"\u207F": "n",
|
|
59167
59207
|
"\u2071": "i"
|
|
59168
59208
|
};
|
|
59169
|
-
for (const [unicode, digit] of Object.entries(superscriptMap)) {
|
|
59170
|
-
result = result.replace(new RegExp(unicode, "g"), `^${digit}`);
|
|
59171
|
-
}
|
|
59172
59209
|
const subscriptMap = {
|
|
59173
59210
|
"\u2080": "0",
|
|
59174
59211
|
"\u2081": "1",
|
|
@@ -59181,17 +59218,13 @@ ${plainText}
|
|
|
59181
59218
|
"\u2088": "8",
|
|
59182
59219
|
"\u2089": "9"
|
|
59183
59220
|
};
|
|
59184
|
-
|
|
59185
|
-
result = result.replace(new RegExp(unicode, "g"), `[${digit}]`);
|
|
59186
|
-
}
|
|
59187
|
-
return result;
|
|
59221
|
+
return this.replaceOutsideCode(markdown, (text) => text.replace(/[⁰¹²³⁴⁵⁶⁷⁸⁹ⁿⁱ]+/g, (run) => `^(${Array.from(run).map((c) => superscriptMap[c]).join("")})`).replace(/[₀₁₂₃₄₅₆₇₈₉]+/g, (run) => `[${Array.from(run).map((c) => subscriptMap[c]).join("")}]`));
|
|
59188
59222
|
}
|
|
59189
59223
|
/**
|
|
59190
59224
|
* Normalize Unicode for R Markdown format
|
|
59191
59225
|
* Converts Unicode superscript/subscript to Pandoc syntax
|
|
59192
59226
|
*/
|
|
59193
59227
|
normalizeRMarkdownUnicode(markdown) {
|
|
59194
|
-
let result = markdown;
|
|
59195
59228
|
const superscriptMap = {
|
|
59196
59229
|
"\u2070": "0",
|
|
59197
59230
|
"\xB9": "1",
|
|
@@ -59206,9 +59239,6 @@ ${plainText}
|
|
|
59206
59239
|
"\u207F": "n",
|
|
59207
59240
|
"\u2071": "i"
|
|
59208
59241
|
};
|
|
59209
|
-
for (const [unicode, digit] of Object.entries(superscriptMap)) {
|
|
59210
|
-
result = result.replace(new RegExp(unicode, "g"), `^${digit}^`);
|
|
59211
|
-
}
|
|
59212
59242
|
const subscriptMap = {
|
|
59213
59243
|
"\u2080": "0",
|
|
59214
59244
|
"\u2081": "1",
|
|
@@ -59221,10 +59251,7 @@ ${plainText}
|
|
|
59221
59251
|
"\u2088": "8",
|
|
59222
59252
|
"\u2089": "9"
|
|
59223
59253
|
};
|
|
59224
|
-
|
|
59225
|
-
result = result.replace(new RegExp(unicode, "g"), `~${digit}~`);
|
|
59226
|
-
}
|
|
59227
|
-
return result;
|
|
59254
|
+
return this.replaceOutsideCode(markdown, (text) => text.replace(/[⁰¹²³⁴⁵⁶⁷⁸⁹ⁿⁱ]+/g, (run) => `^${Array.from(run).map((c) => superscriptMap[c]).join("")}^`).replace(/[₀₁₂₃₄₅₆₇₈₉]+/g, (run) => `~${Array.from(run).map((c) => subscriptMap[c]).join("")}~`));
|
|
59228
59255
|
}
|
|
59229
59256
|
/**
|
|
59230
59257
|
* Create Reddit-optimized Turndown service
|
|
@@ -59232,6 +59259,104 @@ ${plainText}
|
|
|
59232
59259
|
* - Subscript to bracketed text
|
|
59233
59260
|
* - Fenced code blocks (new Reddit)
|
|
59234
59261
|
*/
|
|
59262
|
+
/**
|
|
59263
|
+
* Reddit's bare ^word superscript runs to the next space, so "x^2y" would
|
|
59264
|
+
* superscript "2y". The parenthesised form ^(…) always ends where it should.
|
|
59265
|
+
*/
|
|
59266
|
+
redditSuperscript(content) {
|
|
59267
|
+
const trimmed = content.trim();
|
|
59268
|
+
return trimmed ? `^(${trimmed.replace(/\)/g, "\\)")})` : "";
|
|
59269
|
+
}
|
|
59270
|
+
/**
|
|
59271
|
+
* Pandoc ^x^ / ~x~ cannot contain bare spaces (they must be backslash-escaped),
|
|
59272
|
+
* and a bare delimiter inside the content would close the span early.
|
|
59273
|
+
*/
|
|
59274
|
+
pandocScript(content, delimiter) {
|
|
59275
|
+
const trimmed = content.trim();
|
|
59276
|
+
if (!trimmed) return "";
|
|
59277
|
+
const escaped = trimmed.replace(delimiter === "^" ? /(?<!\\)\^/g : /(?<!\\)~/g, `\\${delimiter}`).replace(/ /g, "\\ ");
|
|
59278
|
+
return `${delimiter}${escaped}${delimiter}`;
|
|
59279
|
+
}
|
|
59280
|
+
/**
|
|
59281
|
+
* Apply a text transform everywhere except fenced code blocks and inline code spans.
|
|
59282
|
+
*
|
|
59283
|
+
* Fences may use ``` or ~~~ of any length (3+) and may sit behind list
|
|
59284
|
+
* indentation or blockquote markers; a fence closes only on a run of the same
|
|
59285
|
+
* character at least as long as the opener. Inline code spans close on a
|
|
59286
|
+
* backtick run of exactly the opening length (CommonMark), so `` a`b `` is
|
|
59287
|
+
* protected whole.
|
|
59288
|
+
*/
|
|
59289
|
+
replaceOutsideCode(markdown, transform) {
|
|
59290
|
+
const fenceOpen = /^((?:[ \t]*>)*[ \t]*(?:(?:[-*+]|\d+[.)])[ \t]+)?[ \t]*)(`{3,}|~{3,})/;
|
|
59291
|
+
const lines = markdown.split(/(?<=\n)/);
|
|
59292
|
+
const segments = [];
|
|
59293
|
+
const push = (text, code) => {
|
|
59294
|
+
const last = segments[segments.length - 1];
|
|
59295
|
+
if (last && last.code === code) last.text += text;
|
|
59296
|
+
else segments.push({ text, code });
|
|
59297
|
+
};
|
|
59298
|
+
let fence = null;
|
|
59299
|
+
for (const line of lines) {
|
|
59300
|
+
if (fence) {
|
|
59301
|
+
push(line, true);
|
|
59302
|
+
const body = line.replace(/^(?:[ \t]*>)*[ \t]*/, "");
|
|
59303
|
+
const close = body.match(/^(`{3,}|~{3,})[ \t]*\r?\n?$/);
|
|
59304
|
+
if (close && close[1][0] === fence.char && close[1].length >= fence.len) fence = null;
|
|
59305
|
+
continue;
|
|
59306
|
+
}
|
|
59307
|
+
const open = line.match(fenceOpen);
|
|
59308
|
+
if (open && !(open[2][0] === "`" && line.slice(open[0].length).includes("`"))) {
|
|
59309
|
+
fence = { char: open[2][0], len: open[2].length };
|
|
59310
|
+
push(line, true);
|
|
59311
|
+
continue;
|
|
59312
|
+
}
|
|
59313
|
+
push(line, false);
|
|
59314
|
+
}
|
|
59315
|
+
const out = [];
|
|
59316
|
+
for (const seg of segments) {
|
|
59317
|
+
if (seg.code) {
|
|
59318
|
+
out.push(seg.text);
|
|
59319
|
+
continue;
|
|
59320
|
+
}
|
|
59321
|
+
const text = seg.text;
|
|
59322
|
+
let plainStart = 0;
|
|
59323
|
+
let i = 0;
|
|
59324
|
+
while (i < text.length) {
|
|
59325
|
+
if (text[i] !== "`") {
|
|
59326
|
+
i++;
|
|
59327
|
+
continue;
|
|
59328
|
+
}
|
|
59329
|
+
let j = i;
|
|
59330
|
+
while (j < text.length && text[j] === "`") j++;
|
|
59331
|
+
const runLen = j - i;
|
|
59332
|
+
let k = j;
|
|
59333
|
+
let closeAt = -1;
|
|
59334
|
+
while (k < text.length) {
|
|
59335
|
+
if (text[k] !== "`") {
|
|
59336
|
+
k++;
|
|
59337
|
+
continue;
|
|
59338
|
+
}
|
|
59339
|
+
let m = k;
|
|
59340
|
+
while (m < text.length && text[m] === "`") m++;
|
|
59341
|
+
if (m - k === runLen) {
|
|
59342
|
+
closeAt = m;
|
|
59343
|
+
break;
|
|
59344
|
+
}
|
|
59345
|
+
k = m;
|
|
59346
|
+
}
|
|
59347
|
+
if (closeAt === -1) {
|
|
59348
|
+
i = j;
|
|
59349
|
+
continue;
|
|
59350
|
+
}
|
|
59351
|
+
out.push(transform(text.slice(plainStart, i)));
|
|
59352
|
+
out.push(text.slice(i, closeAt));
|
|
59353
|
+
plainStart = closeAt;
|
|
59354
|
+
i = closeAt;
|
|
59355
|
+
}
|
|
59356
|
+
out.push(transform(text.slice(plainStart)));
|
|
59357
|
+
}
|
|
59358
|
+
return out.join("");
|
|
59359
|
+
}
|
|
59235
59360
|
createRedditService() {
|
|
59236
59361
|
const service = new import_turndown2.default({
|
|
59237
59362
|
headingStyle: "atx",
|
|
@@ -59245,13 +59370,15 @@ ${plainText}
|
|
|
59245
59370
|
this.addListRules(service);
|
|
59246
59371
|
this.addPdfPageMarkerRules(service);
|
|
59247
59372
|
this.addSlideMarkerRules(service);
|
|
59373
|
+
service.addRule("redditUnderline", {
|
|
59374
|
+
filter: (node) => node.nodeName === "U" || node.nodeName === "INS" || isUnderlineSpan(node),
|
|
59375
|
+
// Keep a strikethrough set on the same span
|
|
59376
|
+
replacement: (content, node) => decorate(content, node, { underline: null, strike: ["~~", "~~"] })
|
|
59377
|
+
});
|
|
59378
|
+
this.addTaskListRules(service);
|
|
59248
59379
|
service.addRule("redditSuperscript", {
|
|
59249
59380
|
filter: (node) => node.nodeName === "SUP",
|
|
59250
|
-
replacement: (content) =>
|
|
59251
|
-
const trimmed = content.trim();
|
|
59252
|
-
if (!trimmed) return "";
|
|
59253
|
-
return trimmed.includes(" ") ? `^(${trimmed})` : `^${trimmed}`;
|
|
59254
|
-
}
|
|
59381
|
+
replacement: (content) => this.redditSuperscript(content)
|
|
59255
59382
|
});
|
|
59256
59383
|
service.addRule("redditSuperscriptStyle", {
|
|
59257
59384
|
filter: (node) => {
|
|
@@ -59259,11 +59386,7 @@ ${plainText}
|
|
|
59259
59386
|
const style = node.getAttribute("style") || "";
|
|
59260
59387
|
return style.includes("vertical-align: super") || style.includes("vertical-align:super");
|
|
59261
59388
|
},
|
|
59262
|
-
replacement: (content) =>
|
|
59263
|
-
const trimmed = content.trim();
|
|
59264
|
-
if (!trimmed) return "";
|
|
59265
|
-
return trimmed.includes(" ") ? `^(${trimmed})` : `^${trimmed}`;
|
|
59266
|
-
}
|
|
59389
|
+
replacement: (content) => this.redditSuperscript(content)
|
|
59267
59390
|
});
|
|
59268
59391
|
service.addRule("redditSubscript", {
|
|
59269
59392
|
filter: (node) => node.nodeName === "SUB",
|
|
@@ -59304,12 +59427,10 @@ ${plainText}
|
|
|
59304
59427
|
this.addListRules(service);
|
|
59305
59428
|
this.addPdfPageMarkerRules(service);
|
|
59306
59429
|
this.addSlideMarkerRules(service);
|
|
59430
|
+
this.addTaskListRules(service);
|
|
59307
59431
|
service.addRule("rmdSuperscript", {
|
|
59308
59432
|
filter: (node) => node.nodeName === "SUP",
|
|
59309
|
-
replacement: (content) =>
|
|
59310
|
-
const trimmed = content.trim();
|
|
59311
|
-
return trimmed ? `^${trimmed}^` : "";
|
|
59312
|
-
}
|
|
59433
|
+
replacement: (content) => this.pandocScript(content, "^")
|
|
59313
59434
|
});
|
|
59314
59435
|
service.addRule("rmdSuperscriptStyle", {
|
|
59315
59436
|
filter: (node) => {
|
|
@@ -59317,17 +59438,11 @@ ${plainText}
|
|
|
59317
59438
|
const style = node.getAttribute("style") || "";
|
|
59318
59439
|
return style.includes("vertical-align: super") || style.includes("vertical-align:super");
|
|
59319
59440
|
},
|
|
59320
|
-
replacement: (content) =>
|
|
59321
|
-
const trimmed = content.trim();
|
|
59322
|
-
return trimmed ? `^${trimmed}^` : "";
|
|
59323
|
-
}
|
|
59441
|
+
replacement: (content) => this.pandocScript(content, "^")
|
|
59324
59442
|
});
|
|
59325
59443
|
service.addRule("rmdSubscript", {
|
|
59326
59444
|
filter: (node) => node.nodeName === "SUB",
|
|
59327
|
-
replacement: (content) =>
|
|
59328
|
-
const trimmed = content.trim();
|
|
59329
|
-
return trimmed ? `~${trimmed}~` : "";
|
|
59330
|
-
}
|
|
59445
|
+
replacement: (content) => this.pandocScript(content, "~")
|
|
59331
59446
|
});
|
|
59332
59447
|
service.addRule("rmdSubscriptStyle", {
|
|
59333
59448
|
filter: (node) => {
|
|
@@ -59335,10 +59450,7 @@ ${plainText}
|
|
|
59335
59450
|
const style = node.getAttribute("style") || "";
|
|
59336
59451
|
return style.includes("vertical-align: sub") || style.includes("vertical-align:sub");
|
|
59337
59452
|
},
|
|
59338
|
-
replacement: (content) =>
|
|
59339
|
-
const trimmed = content.trim();
|
|
59340
|
-
return trimmed ? `~${trimmed}~` : "";
|
|
59341
|
-
}
|
|
59453
|
+
replacement: (content) => this.pandocScript(content, "~")
|
|
59342
59454
|
});
|
|
59343
59455
|
service.addRule("rmdMath", {
|
|
59344
59456
|
filter: (node) => {
|
|
@@ -59398,7 +59510,7 @@ ${plainText}
|
|
|
59398
59510
|
});
|
|
59399
59511
|
return doc.body.firstElementChild?.innerHTML ?? html;
|
|
59400
59512
|
}
|
|
59401
|
-
addGoogleDocsRules(service) {
|
|
59513
|
+
addGoogleDocsRules(service, strike = ["~~", "~~"]) {
|
|
59402
59514
|
service.addRule("googleDocsBold", {
|
|
59403
59515
|
filter: (node) => {
|
|
59404
59516
|
if (node.nodeName !== "SPAN") return false;
|
|
@@ -59468,16 +59580,9 @@ ${plainText}
|
|
|
59468
59580
|
}
|
|
59469
59581
|
});
|
|
59470
59582
|
service.addRule("googleDocsUnderline", {
|
|
59471
|
-
filter: (node) =>
|
|
59472
|
-
|
|
59473
|
-
|
|
59474
|
-
return style.includes("text-decoration: underline") || style.includes("text-decoration:underline");
|
|
59475
|
-
}
|
|
59476
|
-
return false;
|
|
59477
|
-
},
|
|
59478
|
-
replacement: (content) => {
|
|
59479
|
-
return content.trim() ? `<u>${content}</u>` : content;
|
|
59480
|
-
}
|
|
59583
|
+
filter: (node) => isUnderlineSpan(node),
|
|
59584
|
+
// Also applies a line-through set on the same span
|
|
59585
|
+
replacement: (content, node) => decorate(content, node, { underline: ["<u>", "</u>"], strike })
|
|
59481
59586
|
});
|
|
59482
59587
|
service.addRule("strikethroughTags", {
|
|
59483
59588
|
filter: ["del", "s"],
|
|
@@ -59492,14 +59597,9 @@ ${plainText}
|
|
|
59492
59597
|
}
|
|
59493
59598
|
});
|
|
59494
59599
|
service.addRule("strikethroughStyle", {
|
|
59495
|
-
filter: (node) =>
|
|
59496
|
-
|
|
59497
|
-
|
|
59498
|
-
return style.includes("text-decoration: line-through") || style.includes("text-decoration:line-through") || style.includes("text-decoration-line: line-through") || style.includes("text-decoration-line:line-through");
|
|
59499
|
-
},
|
|
59500
|
-
replacement: (content) => {
|
|
59501
|
-
return content.trim() ? `~~${content}~~` : content;
|
|
59502
|
-
}
|
|
59600
|
+
filter: (node) => isStrikeSpan(node),
|
|
59601
|
+
// Also applies an underline set on the same span
|
|
59602
|
+
replacement: (content, node) => decorate(content, node, { underline: ["<u>", "</u>"], strike })
|
|
59503
59603
|
});
|
|
59504
59604
|
service.addRule("monospaceCode", {
|
|
59505
59605
|
filter: (node) => {
|
|
@@ -59630,48 +59730,26 @@ ${plainText}
|
|
|
59630
59730
|
});
|
|
59631
59731
|
}
|
|
59632
59732
|
/**
|
|
59633
|
-
* FF-IMP-004:
|
|
59634
|
-
* github/commonmark flavours.
|
|
59635
|
-
*
|
|
59636
|
-
*
|
|
59733
|
+
* FF-IMP-004: Superscript, subscript and math span rules for the
|
|
59734
|
+
* github/commonmark/gdocs flavours. Neither GFM nor CommonMark has
|
|
59735
|
+
* superscript/subscript syntax: Pandoc-style ^x^ shows literally, and GitHub
|
|
59736
|
+
* renders ~x~ as strikethrough. Both allow inline HTML and GitHub keeps
|
|
59737
|
+
* <sup>/<sub>, so those are emitted instead.
|
|
59637
59738
|
*/
|
|
59638
59739
|
addSupSubMathRules(service) {
|
|
59639
|
-
|
|
59640
|
-
|
|
59641
|
-
|
|
59642
|
-
|
|
59643
|
-
|
|
59644
|
-
|
|
59645
|
-
|
|
59646
|
-
|
|
59647
|
-
|
|
59648
|
-
|
|
59649
|
-
|
|
59650
|
-
|
|
59651
|
-
|
|
59652
|
-
replacement: (content) => {
|
|
59653
|
-
const trimmed = content.trim();
|
|
59654
|
-
return trimmed ? `^${trimmed}^` : "";
|
|
59655
|
-
}
|
|
59656
|
-
});
|
|
59657
|
-
service.addRule("githubSubscript", {
|
|
59658
|
-
filter: (node) => node.nodeName === "SUB",
|
|
59659
|
-
replacement: (content) => {
|
|
59660
|
-
const trimmed = content.trim();
|
|
59661
|
-
return trimmed ? `~${trimmed}~` : "";
|
|
59662
|
-
}
|
|
59663
|
-
});
|
|
59664
|
-
service.addRule("githubSubscriptStyle", {
|
|
59665
|
-
filter: (node) => {
|
|
59666
|
-
if (node.nodeName !== "SPAN") return false;
|
|
59667
|
-
const style = node.getAttribute("style") || "";
|
|
59668
|
-
return style.includes("vertical-align: sub") || style.includes("vertical-align:sub");
|
|
59669
|
-
},
|
|
59670
|
-
replacement: (content) => {
|
|
59671
|
-
const trimmed = content.trim();
|
|
59672
|
-
return trimmed ? `~${trimmed}~` : "";
|
|
59673
|
-
}
|
|
59674
|
-
});
|
|
59740
|
+
const isStyle = (node, value) => {
|
|
59741
|
+
if (node.nodeName !== "SPAN") return false;
|
|
59742
|
+
const style = node.getAttribute("style") || "";
|
|
59743
|
+
return style.includes(`vertical-align: ${value}`) || style.includes(`vertical-align:${value}`);
|
|
59744
|
+
};
|
|
59745
|
+
const wrap = (tag) => (content) => {
|
|
59746
|
+
const trimmed = content.trim();
|
|
59747
|
+
return trimmed ? `<${tag}>${trimmed}</${tag}>` : "";
|
|
59748
|
+
};
|
|
59749
|
+
service.addRule("githubSuperscript", { filter: (node) => node.nodeName === "SUP", replacement: wrap("sup") });
|
|
59750
|
+
service.addRule("githubSuperscriptStyle", { filter: (node) => isStyle(node, "super"), replacement: wrap("sup") });
|
|
59751
|
+
service.addRule("githubSubscript", { filter: (node) => node.nodeName === "SUB", replacement: wrap("sub") });
|
|
59752
|
+
service.addRule("githubSubscriptStyle", { filter: (node) => isStyle(node, "sub"), replacement: wrap("sub") });
|
|
59675
59753
|
service.addRule("githubMath", {
|
|
59676
59754
|
filter: (node) => {
|
|
59677
59755
|
if (node.nodeName !== "SPAN") return false;
|
|
@@ -64831,8 +64909,8 @@ import { readFileSync as readFileSync5 } from "fs";
|
|
|
64831
64909
|
import { resolve, dirname as dirname3 } from "path";
|
|
64832
64910
|
import { fileURLToPath } from "url";
|
|
64833
64911
|
var getVersion = () => {
|
|
64834
|
-
if ("1.0.
|
|
64835
|
-
return "1.0.
|
|
64912
|
+
if ("1.0.37") {
|
|
64913
|
+
return "1.0.37";
|
|
64836
64914
|
}
|
|
64837
64915
|
try {
|
|
64838
64916
|
const __dirname2 = dirname3(fileURLToPath(import.meta.url));
|