@emailens/engine 0.9.0 → 0.9.2
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/README.md +27 -8
- package/dist/index.cjs +95 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +95 -36
- package/dist/index.js.map +1 -1
- package/package.json +120 -120
package/dist/index.d.cts
CHANGED
|
@@ -301,7 +301,10 @@ declare function auditEmail(html: string, options?: AuditOptions): AuditReport;
|
|
|
301
301
|
|
|
302
302
|
/**
|
|
303
303
|
* Convert HTML email to plain text suitable for multipart/alternative emails.
|
|
304
|
-
*
|
|
304
|
+
*
|
|
305
|
+
* Walks the DOM tree node-by-node, emitting text content with proper
|
|
306
|
+
* line breaks for block elements. Avoids cheerio's `.text()` which
|
|
307
|
+
* preserves all source whitespace from deeply nested email tables.
|
|
305
308
|
*/
|
|
306
309
|
declare function toPlainText(html: string): string;
|
|
307
310
|
|
package/dist/index.d.ts
CHANGED
|
@@ -301,7 +301,10 @@ declare function auditEmail(html: string, options?: AuditOptions): AuditReport;
|
|
|
301
301
|
|
|
302
302
|
/**
|
|
303
303
|
* Convert HTML email to plain text suitable for multipart/alternative emails.
|
|
304
|
-
*
|
|
304
|
+
*
|
|
305
|
+
* Walks the DOM tree node-by-node, emitting text content with proper
|
|
306
|
+
* line breaks for block elements. Avoids cheerio's `.text()` which
|
|
307
|
+
* preserves all source whitespace from deeply nested email tables.
|
|
305
308
|
*/
|
|
306
309
|
declare function toPlainText(html: string): string;
|
|
307
310
|
|
package/dist/index.js
CHANGED
|
@@ -10015,45 +10015,104 @@ function auditEmail(html, options) {
|
|
|
10015
10015
|
import * as cheerio13 from "cheerio";
|
|
10016
10016
|
function toPlainText(html) {
|
|
10017
10017
|
const $ = cheerio13.load(html);
|
|
10018
|
-
$("style, script").remove();
|
|
10018
|
+
$("style, script, head").remove();
|
|
10019
10019
|
$("[data-skip-in-text='true']").remove();
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
|
|
10035
|
-
|
|
10020
|
+
const lines = [];
|
|
10021
|
+
let currentLine = "";
|
|
10022
|
+
const BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
10023
|
+
"p",
|
|
10024
|
+
"div",
|
|
10025
|
+
"h1",
|
|
10026
|
+
"h2",
|
|
10027
|
+
"h3",
|
|
10028
|
+
"h4",
|
|
10029
|
+
"h5",
|
|
10030
|
+
"h6",
|
|
10031
|
+
"tr",
|
|
10032
|
+
"table",
|
|
10033
|
+
"blockquote",
|
|
10034
|
+
"ul",
|
|
10035
|
+
"ol",
|
|
10036
|
+
"li",
|
|
10037
|
+
"section",
|
|
10038
|
+
"article",
|
|
10039
|
+
"header",
|
|
10040
|
+
"footer",
|
|
10041
|
+
"main",
|
|
10042
|
+
"td",
|
|
10043
|
+
"th"
|
|
10044
|
+
// treat cells as blocks to avoid run-on text
|
|
10045
|
+
]);
|
|
10046
|
+
const SKIP_TAGS = /* @__PURE__ */ new Set(["style", "script", "head"]);
|
|
10047
|
+
function flushLine() {
|
|
10048
|
+
const trimmed = currentLine.trim();
|
|
10049
|
+
if (trimmed) lines.push(trimmed);
|
|
10050
|
+
currentLine = "";
|
|
10051
|
+
}
|
|
10052
|
+
function walk5(node) {
|
|
10053
|
+
var _a;
|
|
10054
|
+
if (node.type === "text") {
|
|
10055
|
+
const text = node.data.replace(/\s+/g, " ");
|
|
10056
|
+
if (text.trim()) {
|
|
10057
|
+
currentLine += text;
|
|
10058
|
+
}
|
|
10059
|
+
return;
|
|
10060
|
+
}
|
|
10061
|
+
if (node.type !== "tag") return;
|
|
10062
|
+
const el = node;
|
|
10063
|
+
const tag = el.tagName.toLowerCase();
|
|
10064
|
+
if (SKIP_TAGS.has(tag)) return;
|
|
10065
|
+
if (tag === "br") {
|
|
10066
|
+
flushLine();
|
|
10067
|
+
return;
|
|
10068
|
+
}
|
|
10069
|
+
if (tag === "hr") {
|
|
10070
|
+
flushLine();
|
|
10071
|
+
lines.push("---");
|
|
10072
|
+
return;
|
|
10073
|
+
}
|
|
10074
|
+
if (tag === "img") {
|
|
10075
|
+
const alt = (_a = $(el).attr("alt")) == null ? void 0 : _a.trim();
|
|
10076
|
+
if (alt) currentLine += alt;
|
|
10077
|
+
return;
|
|
10078
|
+
}
|
|
10079
|
+
if (tag === "a") {
|
|
10080
|
+
const href = $(el).attr("href") || "";
|
|
10081
|
+
const text = $(el).text().trim();
|
|
10082
|
+
if (!href || href === "#" || href === text) {
|
|
10083
|
+
currentLine += text || href;
|
|
10084
|
+
} else if (!text) {
|
|
10085
|
+
currentLine += href;
|
|
10086
|
+
} else {
|
|
10087
|
+
currentLine += `${text} (${href})`;
|
|
10088
|
+
}
|
|
10089
|
+
return;
|
|
10090
|
+
}
|
|
10091
|
+
const isBlock = BLOCK_TAGS.has(tag);
|
|
10092
|
+
if (isBlock) {
|
|
10093
|
+
flushLine();
|
|
10094
|
+
} else if (currentLine && !currentLine.endsWith(" ")) {
|
|
10095
|
+
currentLine += " ";
|
|
10096
|
+
}
|
|
10097
|
+
if (tag === "li") {
|
|
10098
|
+
currentLine = "- ";
|
|
10099
|
+
}
|
|
10100
|
+
for (const child of el.children) {
|
|
10101
|
+
walk5(child);
|
|
10102
|
+
}
|
|
10103
|
+
if (isBlock) flushLine();
|
|
10104
|
+
}
|
|
10105
|
+
const body = $("body");
|
|
10106
|
+
const root = body.length ? body[0] : $.root()[0];
|
|
10107
|
+
if (root && "children" in root) {
|
|
10108
|
+
for (const child of root.children) {
|
|
10109
|
+
walk5(child);
|
|
10036
10110
|
}
|
|
10037
|
-
});
|
|
10038
|
-
$("li").each((_, el) => {
|
|
10039
|
-
const $el = $(el);
|
|
10040
|
-
const text2 = $el.text().trim();
|
|
10041
|
-
$el.replaceWith(`
|
|
10042
|
-
- ${text2}
|
|
10043
|
-
`);
|
|
10044
|
-
});
|
|
10045
|
-
const blockTags = "p, div, h1, h2, h3, h4, h5, h6, tr, blockquote, ul, ol";
|
|
10046
|
-
$(blockTags).each((_, el) => {
|
|
10047
|
-
const $el = $(el);
|
|
10048
|
-
$el.prepend("\n\n");
|
|
10049
|
-
$el.append("\n\n");
|
|
10050
|
-
});
|
|
10051
|
-
let text = $("body").text();
|
|
10052
|
-
if (!text.trim()) {
|
|
10053
|
-
text = $.root().text();
|
|
10054
10111
|
}
|
|
10055
|
-
|
|
10056
|
-
|
|
10112
|
+
flushLine();
|
|
10113
|
+
let result = lines.join("\n");
|
|
10114
|
+
result = result.replace(/\n{3,}/g, "\n\n");
|
|
10115
|
+
return result.trim();
|
|
10057
10116
|
}
|
|
10058
10117
|
|
|
10059
10118
|
// src/session.ts
|