markdown-codec 6.7.5 → 7.0.0
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 +10 -0
- package/dist/block/block.cjs +19 -37
- package/dist/block/block.js +20 -38
- package/dist/block/node.cjs +3 -3
- package/dist/block/node.d.cts +2 -2
- package/dist/block/node.d.ts +2 -2
- package/dist/block/node.js +3 -3
- package/dist/codec.d.cts +36 -36
- package/dist/codec.d.ts +36 -36
- package/dist/emit/emit.cjs +24 -26
- package/dist/emit/emit.js +24 -26
- package/dist/emit/inline.cjs +18 -12
- package/dist/emit/inline.js +18 -12
- package/dist/html/html-table.cjs +14 -22
- package/dist/html/html-table.js +14 -22
- package/dist/image/image.cjs +8 -8
- package/dist/image/image.js +8 -8
- package/dist/inline/delimiter.cjs +0 -4
- package/dist/inline/delimiter.d.cts +1 -2
- package/dist/inline/delimiter.d.ts +1 -2
- package/dist/inline/delimiter.js +1 -4
- package/dist/inline/gfm-autolink.cjs +20 -19
- package/dist/inline/gfm-autolink.js +20 -19
- package/dist/inline/inline.cjs +29 -39
- package/dist/inline/inline.js +30 -40
- package/dist/lower/lower.cjs +7 -10
- package/dist/lower/lower.js +7 -10
- package/package.json +2 -2
package/dist/emit/inline.cjs
CHANGED
|
@@ -39,11 +39,12 @@ const ESCAPE_CHARS = /* @__PURE__ */ new Set([
|
|
|
39
39
|
function escapeMarkdownText(text) {
|
|
40
40
|
let out = "";
|
|
41
41
|
let index = 0;
|
|
42
|
-
|
|
43
|
-
const char = text
|
|
42
|
+
for (;;) {
|
|
43
|
+
const char = text[index];
|
|
44
|
+
if (char === void 0) break;
|
|
44
45
|
if (char === "\n" || char === "\r") {
|
|
45
46
|
out += "\\\n";
|
|
46
|
-
index += char === "\r" && text
|
|
47
|
+
index += char === "\r" && text[index + 1] === "\n" ? 2 : 1;
|
|
47
48
|
continue;
|
|
48
49
|
}
|
|
49
50
|
if (ESCAPE_CHARS.has(char)) {
|
|
@@ -64,9 +65,8 @@ function renderCodeSpan(text) {
|
|
|
64
65
|
longestBacktickRun = Math.max(longestBacktickRun, current);
|
|
65
66
|
} else current = 0;
|
|
66
67
|
const fence = "`".repeat(longestBacktickRun + 1);
|
|
67
|
-
const isAllSpaces = text.length > 0 && text.trim().length === 0;
|
|
68
68
|
const risksFenceCollision = text.startsWith("`") || text.endsWith("`");
|
|
69
|
-
const wouldBeStrippedOnReparse =
|
|
69
|
+
const wouldBeStrippedOnReparse = text.startsWith(" ") && text.endsWith(" ") && text.trim().length > 0;
|
|
70
70
|
return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
|
|
71
71
|
}
|
|
72
72
|
function footnoteReferenceAt(constructs, index) {
|
|
@@ -102,12 +102,11 @@ function styleActive(run, key) {
|
|
|
102
102
|
}
|
|
103
103
|
const WORD_CHAR_PATTERN = /[\p{L}\p{N}]/u;
|
|
104
104
|
function isIntrawordRisk(body) {
|
|
105
|
-
if (body.length === 0) return false;
|
|
106
105
|
return WORD_CHAR_PATTERN.test(body.charAt(0)) || WORD_CHAR_PATTERN.test(body.charAt(body.length - 1));
|
|
107
106
|
}
|
|
108
107
|
function hasMarkerConflict(body, candidate, precedingText) {
|
|
109
108
|
if (candidate === "_" && isIntrawordRisk(body)) return true;
|
|
110
|
-
if (body.
|
|
109
|
+
if (body.startsWith(candidate) || body.endsWith(candidate)) return true;
|
|
111
110
|
return precedingText.endsWith(candidate);
|
|
112
111
|
}
|
|
113
112
|
function pickEmphasisMarker(body, configured, precedingText) {
|
|
@@ -135,7 +134,7 @@ function groupCount(runs, key) {
|
|
|
135
134
|
function pickSplitKey(runs, remaining) {
|
|
136
135
|
let best = remaining[0];
|
|
137
136
|
let bestCount = groupCount(runs, best);
|
|
138
|
-
for (const key of remaining
|
|
137
|
+
for (const key of remaining) {
|
|
139
138
|
const count = groupCount(runs, key);
|
|
140
139
|
if (count < bestCount) {
|
|
141
140
|
best = key;
|
|
@@ -150,7 +149,7 @@ function renderNestedStyles(runs, remainingKeys, context, base, constructs) {
|
|
|
150
149
|
const rest = remainingKeys.filter((candidate) => candidate !== key);
|
|
151
150
|
let out = "";
|
|
152
151
|
let index = 0;
|
|
153
|
-
|
|
152
|
+
for (;;) {
|
|
154
153
|
const current = runs[index];
|
|
155
154
|
if (current === void 0) break;
|
|
156
155
|
const active = styleActive(current, key);
|
|
@@ -186,19 +185,26 @@ function linkTitleCovering(constructs, start, end) {
|
|
|
186
185
|
function emitRuns(runs, context, constructs) {
|
|
187
186
|
let out = "";
|
|
188
187
|
let index = 0;
|
|
189
|
-
|
|
188
|
+
for (;;) {
|
|
190
189
|
const run = runs[index];
|
|
191
190
|
if (run === void 0) break;
|
|
192
191
|
if (run.hyperlink === void 0) {
|
|
193
192
|
let end = index + 1;
|
|
194
|
-
|
|
193
|
+
for (;;) {
|
|
194
|
+
const next = runs[end];
|
|
195
|
+
if (next === void 0 || next.hyperlink !== void 0) break;
|
|
196
|
+
end += 1;
|
|
197
|
+
}
|
|
195
198
|
out += renderNestedStyles(runs.slice(index, end), STYLE_KEYS, context, index, constructs);
|
|
196
199
|
index = end;
|
|
197
200
|
continue;
|
|
198
201
|
}
|
|
199
202
|
const hyperlink = run.hyperlink;
|
|
200
203
|
let groupEnd = index + 1;
|
|
201
|
-
|
|
204
|
+
for (;;) {
|
|
205
|
+
if (runs[groupEnd]?.hyperlink !== hyperlink) break;
|
|
206
|
+
groupEnd += 1;
|
|
207
|
+
}
|
|
202
208
|
const group = runs.slice(index, groupEnd);
|
|
203
209
|
if (group.length > 1) context.sink({
|
|
204
210
|
code: require_diagnostics_diagnostics.MarkdownDiagnosticCodes.ADJACENT_LINKS_MERGED,
|
package/dist/emit/inline.js
CHANGED
|
@@ -38,11 +38,12 @@ const ESCAPE_CHARS = /* @__PURE__ */ new Set([
|
|
|
38
38
|
function escapeMarkdownText(text) {
|
|
39
39
|
let out = "";
|
|
40
40
|
let index = 0;
|
|
41
|
-
|
|
42
|
-
const char = text
|
|
41
|
+
for (;;) {
|
|
42
|
+
const char = text[index];
|
|
43
|
+
if (char === void 0) break;
|
|
43
44
|
if (char === "\n" || char === "\r") {
|
|
44
45
|
out += "\\\n";
|
|
45
|
-
index += char === "\r" && text
|
|
46
|
+
index += char === "\r" && text[index + 1] === "\n" ? 2 : 1;
|
|
46
47
|
continue;
|
|
47
48
|
}
|
|
48
49
|
if (ESCAPE_CHARS.has(char)) {
|
|
@@ -63,9 +64,8 @@ function renderCodeSpan(text) {
|
|
|
63
64
|
longestBacktickRun = Math.max(longestBacktickRun, current);
|
|
64
65
|
} else current = 0;
|
|
65
66
|
const fence = "`".repeat(longestBacktickRun + 1);
|
|
66
|
-
const isAllSpaces = text.length > 0 && text.trim().length === 0;
|
|
67
67
|
const risksFenceCollision = text.startsWith("`") || text.endsWith("`");
|
|
68
|
-
const wouldBeStrippedOnReparse =
|
|
68
|
+
const wouldBeStrippedOnReparse = text.startsWith(" ") && text.endsWith(" ") && text.trim().length > 0;
|
|
69
69
|
return risksFenceCollision || wouldBeStrippedOnReparse ? `${fence} ${text} ${fence}` : `${fence}${text}${fence}`;
|
|
70
70
|
}
|
|
71
71
|
function footnoteReferenceAt(constructs, index) {
|
|
@@ -101,12 +101,11 @@ function styleActive(run, key) {
|
|
|
101
101
|
}
|
|
102
102
|
const WORD_CHAR_PATTERN = /[\p{L}\p{N}]/u;
|
|
103
103
|
function isIntrawordRisk(body) {
|
|
104
|
-
if (body.length === 0) return false;
|
|
105
104
|
return WORD_CHAR_PATTERN.test(body.charAt(0)) || WORD_CHAR_PATTERN.test(body.charAt(body.length - 1));
|
|
106
105
|
}
|
|
107
106
|
function hasMarkerConflict(body, candidate, precedingText) {
|
|
108
107
|
if (candidate === "_" && isIntrawordRisk(body)) return true;
|
|
109
|
-
if (body.
|
|
108
|
+
if (body.startsWith(candidate) || body.endsWith(candidate)) return true;
|
|
110
109
|
return precedingText.endsWith(candidate);
|
|
111
110
|
}
|
|
112
111
|
function pickEmphasisMarker(body, configured, precedingText) {
|
|
@@ -134,7 +133,7 @@ function groupCount(runs, key) {
|
|
|
134
133
|
function pickSplitKey(runs, remaining) {
|
|
135
134
|
let best = remaining[0];
|
|
136
135
|
let bestCount = groupCount(runs, best);
|
|
137
|
-
for (const key of remaining
|
|
136
|
+
for (const key of remaining) {
|
|
138
137
|
const count = groupCount(runs, key);
|
|
139
138
|
if (count < bestCount) {
|
|
140
139
|
best = key;
|
|
@@ -149,7 +148,7 @@ function renderNestedStyles(runs, remainingKeys, context, base, constructs) {
|
|
|
149
148
|
const rest = remainingKeys.filter((candidate) => candidate !== key);
|
|
150
149
|
let out = "";
|
|
151
150
|
let index = 0;
|
|
152
|
-
|
|
151
|
+
for (;;) {
|
|
153
152
|
const current = runs[index];
|
|
154
153
|
if (current === void 0) break;
|
|
155
154
|
const active = styleActive(current, key);
|
|
@@ -185,19 +184,26 @@ function linkTitleCovering(constructs, start, end) {
|
|
|
185
184
|
function emitRuns(runs, context, constructs) {
|
|
186
185
|
let out = "";
|
|
187
186
|
let index = 0;
|
|
188
|
-
|
|
187
|
+
for (;;) {
|
|
189
188
|
const run = runs[index];
|
|
190
189
|
if (run === void 0) break;
|
|
191
190
|
if (run.hyperlink === void 0) {
|
|
192
191
|
let end = index + 1;
|
|
193
|
-
|
|
192
|
+
for (;;) {
|
|
193
|
+
const next = runs[end];
|
|
194
|
+
if (next === void 0 || next.hyperlink !== void 0) break;
|
|
195
|
+
end += 1;
|
|
196
|
+
}
|
|
194
197
|
out += renderNestedStyles(runs.slice(index, end), STYLE_KEYS, context, index, constructs);
|
|
195
198
|
index = end;
|
|
196
199
|
continue;
|
|
197
200
|
}
|
|
198
201
|
const hyperlink = run.hyperlink;
|
|
199
202
|
let groupEnd = index + 1;
|
|
200
|
-
|
|
203
|
+
for (;;) {
|
|
204
|
+
if (runs[groupEnd]?.hyperlink !== hyperlink) break;
|
|
205
|
+
groupEnd += 1;
|
|
206
|
+
}
|
|
201
207
|
const group = runs.slice(index, groupEnd);
|
|
202
208
|
if (group.length > 1) context.sink({
|
|
203
209
|
code: MarkdownDiagnosticCodes.ADJACENT_LINKS_MERGED,
|
package/dist/html/html-table.cjs
CHANGED
|
@@ -5,25 +5,21 @@ let document_schema_js = require("document-schema.js");
|
|
|
5
5
|
//#region src/html/html-table.ts
|
|
6
6
|
function findBalancedClose(text, openEnd, tagNames) {
|
|
7
7
|
const names = tagNames.join("|");
|
|
8
|
-
const
|
|
9
|
-
const closePattern = new RegExp(`</(?:${names})\\s*>`, "gi");
|
|
8
|
+
const tagPattern = new RegExp(`</(?:${names})\\s*>|<(?:${names})(?=[\\s/>])`, "gi");
|
|
10
9
|
let depth = 1;
|
|
11
10
|
let pos = openEnd;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
if (openMatch !== null && openMatch.index < closeMatch.index) {
|
|
11
|
+
for (;;) {
|
|
12
|
+
tagPattern.lastIndex = pos;
|
|
13
|
+
const match = tagPattern.exec(text);
|
|
14
|
+
if (match === null) return;
|
|
15
|
+
pos = match.index + match[0].length;
|
|
16
|
+
if (!match[0].startsWith("</")) {
|
|
19
17
|
depth += 1;
|
|
20
|
-
pos = openMatch.index + openMatch[0].length;
|
|
21
18
|
continue;
|
|
22
19
|
}
|
|
23
20
|
depth -= 1;
|
|
24
|
-
pos = closeMatch.index + closeMatch[0].length;
|
|
25
21
|
if (depth === 0) return {
|
|
26
|
-
start:
|
|
22
|
+
start: match.index,
|
|
27
23
|
end: pos
|
|
28
24
|
};
|
|
29
25
|
}
|
|
@@ -37,7 +33,7 @@ function extractTopLevelElements(text, tagNames) {
|
|
|
37
33
|
const match = openPattern.exec(text);
|
|
38
34
|
if (match === null) break;
|
|
39
35
|
if (text.slice(pos, match.index).trim().length > 0) return;
|
|
40
|
-
const attrs = match[1]
|
|
36
|
+
const attrs = match[1];
|
|
41
37
|
const openEnd = match.index + match[0].length;
|
|
42
38
|
const close = findBalancedClose(text, openEnd, tagNames);
|
|
43
39
|
if (close === void 0) return;
|
|
@@ -136,15 +132,15 @@ function parseInlineHtml(text, style) {
|
|
|
136
132
|
pushPlainRun(runs, rest, style);
|
|
137
133
|
return runs;
|
|
138
134
|
}
|
|
139
|
-
pushPlainRun(runs, rest.slice(0, match.index), style);
|
|
140
135
|
const tagName = match[1].toLowerCase();
|
|
141
|
-
const attrs = match[2]
|
|
136
|
+
const attrs = match[2];
|
|
142
137
|
const openEnd = pos + match.index + match[0].length;
|
|
143
138
|
const close = findBalancedClose(text, openEnd, [tagName]);
|
|
144
139
|
if (close === void 0) {
|
|
145
140
|
pushPlainRun(runs, rest, style);
|
|
146
141
|
return runs;
|
|
147
142
|
}
|
|
143
|
+
pushPlainRun(runs, rest.slice(0, match.index), style);
|
|
148
144
|
runs.push(...parseInlineHtml(text.slice(openEnd, close.start), applyTagStyle(style, tagName, attrs)));
|
|
149
145
|
pos = close.end;
|
|
150
146
|
}
|
|
@@ -168,12 +164,10 @@ function parseHtmlImage(piece) {
|
|
|
168
164
|
};
|
|
169
165
|
}
|
|
170
166
|
function parseCellBlocks(inner, contentWidthPt) {
|
|
171
|
-
const
|
|
172
|
-
if (trimmed.length === 0) return [];
|
|
173
|
-
const nestedTable = parseWholeTable(trimmed, contentWidthPt);
|
|
167
|
+
const nestedTable = parseWholeTable(inner, contentWidthPt);
|
|
174
168
|
if (nestedTable !== void 0) return [nestedTable];
|
|
175
169
|
const blocks = [];
|
|
176
|
-
for (const segment of
|
|
170
|
+
for (const segment of inner.split(/<br\s*\/?>/i)) {
|
|
177
171
|
const piece = segment.trim();
|
|
178
172
|
if (piece.length === 0) continue;
|
|
179
173
|
const image = parseHtmlImage(piece);
|
|
@@ -235,9 +229,7 @@ function parseWholeTable(text, contentWidthPt) {
|
|
|
235
229
|
return rows === void 0 ? void 0 : buildContentTable(rows, contentWidthPt);
|
|
236
230
|
}
|
|
237
231
|
function parseHtmlTable(literal, contentWidthPt) {
|
|
238
|
-
|
|
239
|
-
if (!/^<table\b/i.test(trimmed)) return;
|
|
240
|
-
return parseWholeTable(trimmed, contentWidthPt);
|
|
232
|
+
return parseWholeTable(literal, contentWidthPt);
|
|
241
233
|
}
|
|
242
234
|
//#endregion
|
|
243
235
|
exports.parseHtmlTable = parseHtmlTable;
|
package/dist/html/html-table.js
CHANGED
|
@@ -4,25 +4,21 @@ import { rgbHexToColor } from "document-schema.js";
|
|
|
4
4
|
//#region src/html/html-table.ts
|
|
5
5
|
function findBalancedClose(text, openEnd, tagNames) {
|
|
6
6
|
const names = tagNames.join("|");
|
|
7
|
-
const
|
|
8
|
-
const closePattern = new RegExp(`</(?:${names})\\s*>`, "gi");
|
|
7
|
+
const tagPattern = new RegExp(`</(?:${names})\\s*>|<(?:${names})(?=[\\s/>])`, "gi");
|
|
9
8
|
let depth = 1;
|
|
10
9
|
let pos = openEnd;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
if (openMatch !== null && openMatch.index < closeMatch.index) {
|
|
10
|
+
for (;;) {
|
|
11
|
+
tagPattern.lastIndex = pos;
|
|
12
|
+
const match = tagPattern.exec(text);
|
|
13
|
+
if (match === null) return;
|
|
14
|
+
pos = match.index + match[0].length;
|
|
15
|
+
if (!match[0].startsWith("</")) {
|
|
18
16
|
depth += 1;
|
|
19
|
-
pos = openMatch.index + openMatch[0].length;
|
|
20
17
|
continue;
|
|
21
18
|
}
|
|
22
19
|
depth -= 1;
|
|
23
|
-
pos = closeMatch.index + closeMatch[0].length;
|
|
24
20
|
if (depth === 0) return {
|
|
25
|
-
start:
|
|
21
|
+
start: match.index,
|
|
26
22
|
end: pos
|
|
27
23
|
};
|
|
28
24
|
}
|
|
@@ -36,7 +32,7 @@ function extractTopLevelElements(text, tagNames) {
|
|
|
36
32
|
const match = openPattern.exec(text);
|
|
37
33
|
if (match === null) break;
|
|
38
34
|
if (text.slice(pos, match.index).trim().length > 0) return;
|
|
39
|
-
const attrs = match[1]
|
|
35
|
+
const attrs = match[1];
|
|
40
36
|
const openEnd = match.index + match[0].length;
|
|
41
37
|
const close = findBalancedClose(text, openEnd, tagNames);
|
|
42
38
|
if (close === void 0) return;
|
|
@@ -135,15 +131,15 @@ function parseInlineHtml(text, style) {
|
|
|
135
131
|
pushPlainRun(runs, rest, style);
|
|
136
132
|
return runs;
|
|
137
133
|
}
|
|
138
|
-
pushPlainRun(runs, rest.slice(0, match.index), style);
|
|
139
134
|
const tagName = match[1].toLowerCase();
|
|
140
|
-
const attrs = match[2]
|
|
135
|
+
const attrs = match[2];
|
|
141
136
|
const openEnd = pos + match.index + match[0].length;
|
|
142
137
|
const close = findBalancedClose(text, openEnd, [tagName]);
|
|
143
138
|
if (close === void 0) {
|
|
144
139
|
pushPlainRun(runs, rest, style);
|
|
145
140
|
return runs;
|
|
146
141
|
}
|
|
142
|
+
pushPlainRun(runs, rest.slice(0, match.index), style);
|
|
147
143
|
runs.push(...parseInlineHtml(text.slice(openEnd, close.start), applyTagStyle(style, tagName, attrs)));
|
|
148
144
|
pos = close.end;
|
|
149
145
|
}
|
|
@@ -167,12 +163,10 @@ function parseHtmlImage(piece) {
|
|
|
167
163
|
};
|
|
168
164
|
}
|
|
169
165
|
function parseCellBlocks(inner, contentWidthPt) {
|
|
170
|
-
const
|
|
171
|
-
if (trimmed.length === 0) return [];
|
|
172
|
-
const nestedTable = parseWholeTable(trimmed, contentWidthPt);
|
|
166
|
+
const nestedTable = parseWholeTable(inner, contentWidthPt);
|
|
173
167
|
if (nestedTable !== void 0) return [nestedTable];
|
|
174
168
|
const blocks = [];
|
|
175
|
-
for (const segment of
|
|
169
|
+
for (const segment of inner.split(/<br\s*\/?>/i)) {
|
|
176
170
|
const piece = segment.trim();
|
|
177
171
|
if (piece.length === 0) continue;
|
|
178
172
|
const image = parseHtmlImage(piece);
|
|
@@ -234,9 +228,7 @@ function parseWholeTable(text, contentWidthPt) {
|
|
|
234
228
|
return rows === void 0 ? void 0 : buildContentTable(rows, contentWidthPt);
|
|
235
229
|
}
|
|
236
230
|
function parseHtmlTable(literal, contentWidthPt) {
|
|
237
|
-
|
|
238
|
-
if (!/^<table\b/i.test(trimmed)) return;
|
|
239
|
-
return parseWholeTable(trimmed, contentWidthPt);
|
|
231
|
+
return parseWholeTable(literal, contentWidthPt);
|
|
240
232
|
}
|
|
241
233
|
//#endregion
|
|
242
234
|
export { parseHtmlTable };
|
package/dist/image/image.cjs
CHANGED
|
@@ -18,9 +18,11 @@ const PNG_SIGNATURE = [
|
|
|
18
18
|
];
|
|
19
19
|
const PNG_HEADER_BYTES = 24;
|
|
20
20
|
function isPng(bytes) {
|
|
21
|
-
if (bytes.length < PNG_SIGNATURE.length) return false;
|
|
22
21
|
return PNG_SIGNATURE.every((byte, index) => bytes[index] === byte);
|
|
23
22
|
}
|
|
23
|
+
function isJpeg(bytes) {
|
|
24
|
+
return bytes[0] === 255 && bytes[1] === 216;
|
|
25
|
+
}
|
|
24
26
|
function readPngDimensions(bytes) {
|
|
25
27
|
if (bytes.length < PNG_HEADER_BYTES) return;
|
|
26
28
|
if (bytes[12] !== 73 || bytes[13] !== 72 || bytes[14] !== 68 || bytes[15] !== 82) return;
|
|
@@ -37,10 +39,12 @@ function hasNoLengthField(marker) {
|
|
|
37
39
|
return marker === 216 || marker === 217 || marker === 1 || marker >= 208 && marker <= 215;
|
|
38
40
|
}
|
|
39
41
|
function readJpegDimensions(bytes) {
|
|
40
|
-
if (bytes
|
|
42
|
+
if (!isJpeg(bytes)) return;
|
|
41
43
|
let offset = 2;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
for (;;) {
|
|
45
|
+
const byte = bytes[offset];
|
|
46
|
+
if (byte === void 0) return;
|
|
47
|
+
if (byte !== 255) {
|
|
44
48
|
offset += 1;
|
|
45
49
|
continue;
|
|
46
50
|
}
|
|
@@ -50,7 +54,6 @@ function readJpegDimensions(bytes) {
|
|
|
50
54
|
if (marker === void 0) return;
|
|
51
55
|
offset = markerOffset + 1;
|
|
52
56
|
if (hasNoLengthField(marker)) continue;
|
|
53
|
-
if (offset + 2 > bytes.length) return;
|
|
54
57
|
const length = readUint16BE(bytes, offset);
|
|
55
58
|
if (isStartOfFrameMarker(marker)) {
|
|
56
59
|
if (offset + 7 > bytes.length) return;
|
|
@@ -64,9 +67,6 @@ function readJpegDimensions(bytes) {
|
|
|
64
67
|
offset += length;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
|
-
function isJpeg(bytes) {
|
|
68
|
-
return bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 216;
|
|
69
|
-
}
|
|
70
70
|
function detectImageFormat(bytes) {
|
|
71
71
|
if (isPng(bytes)) return "png";
|
|
72
72
|
return isJpeg(bytes) ? "jpeg" : void 0;
|
package/dist/image/image.js
CHANGED
|
@@ -17,9 +17,11 @@ const PNG_SIGNATURE = [
|
|
|
17
17
|
];
|
|
18
18
|
const PNG_HEADER_BYTES = 24;
|
|
19
19
|
function isPng(bytes) {
|
|
20
|
-
if (bytes.length < PNG_SIGNATURE.length) return false;
|
|
21
20
|
return PNG_SIGNATURE.every((byte, index) => bytes[index] === byte);
|
|
22
21
|
}
|
|
22
|
+
function isJpeg(bytes) {
|
|
23
|
+
return bytes[0] === 255 && bytes[1] === 216;
|
|
24
|
+
}
|
|
23
25
|
function readPngDimensions(bytes) {
|
|
24
26
|
if (bytes.length < PNG_HEADER_BYTES) return;
|
|
25
27
|
if (bytes[12] !== 73 || bytes[13] !== 72 || bytes[14] !== 68 || bytes[15] !== 82) return;
|
|
@@ -36,10 +38,12 @@ function hasNoLengthField(marker) {
|
|
|
36
38
|
return marker === 216 || marker === 217 || marker === 1 || marker >= 208 && marker <= 215;
|
|
37
39
|
}
|
|
38
40
|
function readJpegDimensions(bytes) {
|
|
39
|
-
if (bytes
|
|
41
|
+
if (!isJpeg(bytes)) return;
|
|
40
42
|
let offset = 2;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
for (;;) {
|
|
44
|
+
const byte = bytes[offset];
|
|
45
|
+
if (byte === void 0) return;
|
|
46
|
+
if (byte !== 255) {
|
|
43
47
|
offset += 1;
|
|
44
48
|
continue;
|
|
45
49
|
}
|
|
@@ -49,7 +53,6 @@ function readJpegDimensions(bytes) {
|
|
|
49
53
|
if (marker === void 0) return;
|
|
50
54
|
offset = markerOffset + 1;
|
|
51
55
|
if (hasNoLengthField(marker)) continue;
|
|
52
|
-
if (offset + 2 > bytes.length) return;
|
|
53
56
|
const length = readUint16BE(bytes, offset);
|
|
54
57
|
if (isStartOfFrameMarker(marker)) {
|
|
55
58
|
if (offset + 7 > bytes.length) return;
|
|
@@ -63,9 +66,6 @@ function readJpegDimensions(bytes) {
|
|
|
63
66
|
offset += length;
|
|
64
67
|
}
|
|
65
68
|
}
|
|
66
|
-
function isJpeg(bytes) {
|
|
67
|
-
return bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 216;
|
|
68
|
-
}
|
|
69
69
|
function detectImageFormat(bytes) {
|
|
70
70
|
if (isPng(bytes)) return "png";
|
|
71
71
|
return isJpeg(bytes) ? "jpeg" : void 0;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_inline_chars = require("./chars.cjs");
|
|
3
3
|
//#region src/inline/delimiter.ts
|
|
4
|
-
function isDelimiterChar(char) {
|
|
5
|
-
return char === "*" || char === "_" || char === "~";
|
|
6
|
-
}
|
|
7
4
|
const MAX_STRIKETHROUGH_RUN = 2;
|
|
8
5
|
function scanDelimiterRun(text, start, char) {
|
|
9
6
|
let count = 0;
|
|
@@ -124,6 +121,5 @@ function processEmphasis(stack, stackBottom, createWrapper) {
|
|
|
124
121
|
//#endregion
|
|
125
122
|
exports.DelimiterStack = DelimiterStack;
|
|
126
123
|
exports.closerSignature = closerSignature;
|
|
127
|
-
exports.isDelimiterChar = isDelimiterChar;
|
|
128
124
|
exports.processEmphasis = processEmphasis;
|
|
129
125
|
exports.scanDelimiterRun = scanDelimiterRun;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { InlineNode } from "./node.cjs";
|
|
2
2
|
//#region src/inline/delimiter.d.ts
|
|
3
3
|
type DelimiterChar = "*" | "_" | "~";
|
|
4
|
-
declare function isDelimiterChar(char: string): char is DelimiterChar;
|
|
5
4
|
interface Delimiter {
|
|
6
5
|
readonly char: DelimiterChar;
|
|
7
6
|
count: number;
|
|
@@ -27,4 +26,4 @@ declare function closerSignature(closer: Delimiter): string;
|
|
|
27
26
|
type EmphasisWrapperFactory = (kind: "emphasis" | "strong" | "strikethrough", marker: DelimiterChar) => InlineNode;
|
|
28
27
|
declare function processEmphasis(stack: DelimiterStack, stackBottom: Delimiter | undefined, createWrapper: EmphasisWrapperFactory): void;
|
|
29
28
|
//#endregion
|
|
30
|
-
export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature,
|
|
29
|
+
export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, processEmphasis, scanDelimiterRun };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { InlineNode } from "./node.js";
|
|
2
2
|
//#region src/inline/delimiter.d.ts
|
|
3
3
|
type DelimiterChar = "*" | "_" | "~";
|
|
4
|
-
declare function isDelimiterChar(char: string): char is DelimiterChar;
|
|
5
4
|
interface Delimiter {
|
|
6
5
|
readonly char: DelimiterChar;
|
|
7
6
|
count: number;
|
|
@@ -27,4 +26,4 @@ declare function closerSignature(closer: Delimiter): string;
|
|
|
27
26
|
type EmphasisWrapperFactory = (kind: "emphasis" | "strong" | "strikethrough", marker: DelimiterChar) => InlineNode;
|
|
28
27
|
declare function processEmphasis(stack: DelimiterStack, stackBottom: Delimiter | undefined, createWrapper: EmphasisWrapperFactory): void;
|
|
29
28
|
//#endregion
|
|
30
|
-
export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature,
|
|
29
|
+
export { Delimiter, DelimiterChar, DelimiterRun, DelimiterStack, EmphasisWrapperFactory, closerSignature, processEmphasis, scanDelimiterRun };
|
package/dist/inline/delimiter.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { codePointAt, codePointBefore, isUnicodePunctuation, isUnicodeWhitespace } from "./chars.js";
|
|
2
2
|
//#region src/inline/delimiter.ts
|
|
3
|
-
function isDelimiterChar(char) {
|
|
4
|
-
return char === "*" || char === "_" || char === "~";
|
|
5
|
-
}
|
|
6
3
|
const MAX_STRIKETHROUGH_RUN = 2;
|
|
7
4
|
function scanDelimiterRun(text, start, char) {
|
|
8
5
|
let count = 0;
|
|
@@ -121,4 +118,4 @@ function processEmphasis(stack, stackBottom, createWrapper) {
|
|
|
121
118
|
while (stack.top !== void 0 && stack.top !== stackBottom) stack.remove(stack.top);
|
|
122
119
|
}
|
|
123
120
|
//#endregion
|
|
124
|
-
export { DelimiterStack, closerSignature,
|
|
121
|
+
export { DelimiterStack, closerSignature, processEmphasis, scanDelimiterRun };
|
|
@@ -37,7 +37,7 @@ const OPAQUE_KINDS = /* @__PURE__ */ new Set([
|
|
|
37
37
|
"autolink"
|
|
38
38
|
]);
|
|
39
39
|
function isWhitespace(char) {
|
|
40
|
-
return char === "
|
|
40
|
+
return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
|
|
41
41
|
}
|
|
42
42
|
function isValidStartBoundary(text, index) {
|
|
43
43
|
if (index === 0) return true;
|
|
@@ -54,28 +54,31 @@ function trimTrailingPunctuation(candidate) {
|
|
|
54
54
|
let end = candidate.length;
|
|
55
55
|
for (;;) {
|
|
56
56
|
const before = end;
|
|
57
|
-
while (
|
|
58
|
-
if (
|
|
57
|
+
while (TRAILING_PUNCTUATION.has(candidate.charAt(end - 1))) end -= 1;
|
|
58
|
+
if (candidate.charAt(end - 1) === ")") {
|
|
59
59
|
const slice = candidate.slice(0, end);
|
|
60
60
|
if (slice.split(")").length > slice.split("(").length) end -= 1;
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (entityTail !== null) end -= entityTail[0].length;
|
|
65
|
-
}
|
|
62
|
+
const entityTail = ENTITY_TAIL_PATTERN.exec(candidate.slice(0, end));
|
|
63
|
+
if (entityTail !== null) end -= entityTail[0].length;
|
|
66
64
|
if (end === before) return candidate.slice(0, end);
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
function scanRawCandidate(text, start) {
|
|
70
68
|
let end = start;
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
for (;;) {
|
|
70
|
+
const char = text.charAt(end);
|
|
71
|
+
if (char === "" || isWhitespace(char) || char === "<") return text.slice(start, end);
|
|
72
|
+
end += 1;
|
|
73
|
+
}
|
|
73
74
|
}
|
|
74
75
|
function matchPrefixed(text, index, prefixLength, destinationPrefix, requireValidDomain) {
|
|
75
76
|
const trimmed = trimTrailingPunctuation(scanRawCandidate(text, index));
|
|
76
|
-
|
|
77
|
+
const afterPrefix = trimmed.slice(prefixLength);
|
|
78
|
+
if (afterPrefix === "") return;
|
|
77
79
|
if (requireValidDomain) {
|
|
78
|
-
|
|
80
|
+
const domain = afterPrefix.split(/[/?#]/)[0];
|
|
81
|
+
if (!isValidDomain(domain)) return;
|
|
79
82
|
}
|
|
80
83
|
return {
|
|
81
84
|
text: trimmed,
|
|
@@ -85,17 +88,17 @@ function matchPrefixed(text, index, prefixLength, destinationPrefix, requireVali
|
|
|
85
88
|
}
|
|
86
89
|
function scanEmailDomain(text, start) {
|
|
87
90
|
let end = start;
|
|
88
|
-
while (
|
|
91
|
+
while (EMAIL_DOMAIN_PATTERN.test(text.charAt(end))) end += 1;
|
|
89
92
|
return text.slice(start, end);
|
|
90
93
|
}
|
|
91
94
|
function matchEmailAt(text, atIndex) {
|
|
92
95
|
let start = atIndex;
|
|
93
|
-
while (
|
|
96
|
+
while (EMAIL_LOCAL_PART_PATTERN.test(text.charAt(start - 1))) start -= 1;
|
|
94
97
|
if (start === atIndex || !isValidStartBoundary(text, start)) return;
|
|
95
98
|
const local = text.slice(start, atIndex);
|
|
96
99
|
if (local.startsWith(".") || local.endsWith(".")) return;
|
|
97
100
|
const domain = scanEmailDomain(text, atIndex + 1).replace(/\.+$/, "");
|
|
98
|
-
if (domain.endsWith("-") ||
|
|
101
|
+
if (domain.endsWith("-") || !isValidDomain(domain)) return;
|
|
99
102
|
const address = `${local}@${domain}`;
|
|
100
103
|
return {
|
|
101
104
|
text: address,
|
|
@@ -117,11 +120,10 @@ function expandTextNode(node) {
|
|
|
117
120
|
const text = node.literal;
|
|
118
121
|
let cursor = 0;
|
|
119
122
|
let anchor = node;
|
|
120
|
-
let matches = 0;
|
|
121
123
|
let index = 0;
|
|
122
|
-
while (index
|
|
124
|
+
while (text.charAt(index) !== "") {
|
|
123
125
|
const found = findAutolinkAt(text, index);
|
|
124
|
-
if (found === void 0
|
|
126
|
+
if (found === void 0) {
|
|
125
127
|
index += 1;
|
|
126
128
|
continue;
|
|
127
129
|
}
|
|
@@ -136,10 +138,9 @@ function expandTextNode(node) {
|
|
|
136
138
|
anchor.insertAfter(link);
|
|
137
139
|
anchor = link;
|
|
138
140
|
cursor = found.start + found.text.length;
|
|
139
|
-
matches += 1;
|
|
140
141
|
index = cursor;
|
|
141
142
|
}
|
|
142
|
-
if (
|
|
143
|
+
if (anchor === node) return;
|
|
143
144
|
if (cursor < text.length) anchor.insertAfter(require_inline_node.createTextNode(text.slice(cursor)));
|
|
144
145
|
node.unlink();
|
|
145
146
|
}
|