@jxsuite/parser 3.0.0 → 4.0.1

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.
@@ -33786,7 +33786,7 @@ function walkFiles(root, accept, exclude) {
33786
33786
  var init_walk = () => {};
33787
33787
 
33788
33788
  // src/content-loader.ts
33789
- import { existsSync, readFileSync, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
33789
+ import { existsSync, readFileSync, readdirSync as readdirSync2, realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
33790
33790
  import { basename, dirname, extname, relative, resolve } from "node:path";
33791
33791
 
33792
33792
  // ../../packages/schema/src/asset-paths.ts
@@ -34418,11 +34418,21 @@ function discoverJSONFiles(resolvedSource, exclude) {
34418
34418
  function localesForExpansion(projectConfig) {
34419
34419
  return resolveI18n(projectConfig ?? {}).i18n?.locales ?? [];
34420
34420
  }
34421
+ function existsWithSpelling(root, path) {
34422
+ const full = resolve(root, path);
34423
+ if (!existsSync(full)) {
34424
+ return false;
34425
+ }
34426
+ const wanted = full.split(/[\\/]/).filter(Boolean);
34427
+ const actual = realpathSync2.native(full).split(/[\\/]/).filter(Boolean);
34428
+ const tail = actual.slice(-wanted.length);
34429
+ return wanted.every((segment, index) => segment === tail[index]);
34430
+ }
34421
34431
  function localeSource(root, source, locale) {
34422
34432
  const candidates = [locale, locale.toLowerCase()];
34423
34433
  for (const spelling of candidates) {
34424
34434
  const path = source.split(LOCALE_PLACEHOLDER).join(spelling);
34425
- if (existsSync(resolve(root, path))) {
34435
+ if (existsWithSpelling(root, path)) {
34426
34436
  return path;
34427
34437
  }
34428
34438
  }
package/dist/markdown.js CHANGED
@@ -40742,6 +40742,143 @@ var init_dist3 = __esm(() => {
40742
40742
  $visitAsync = visit2.visitAsync;
40743
40743
  });
40744
40744
 
40745
+ // src/source-style.ts
40746
+ function frontmatterText(source) {
40747
+ const match = FRONTMATTER_RE.exec(source);
40748
+ if (!match) {
40749
+ return null;
40750
+ }
40751
+ return match[1] ?? "";
40752
+ }
40753
+ function bodyText(source) {
40754
+ return source.replace(FRONTMATTER_RE, "");
40755
+ }
40756
+ function sameValue2(a, b) {
40757
+ if (a === b) {
40758
+ return true;
40759
+ }
40760
+ if (Array.isArray(a) || Array.isArray(b)) {
40761
+ return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, index) => sameValue2(item, b[index]));
40762
+ }
40763
+ if (!isJsonObject(a) || !isJsonObject(b)) {
40764
+ return false;
40765
+ }
40766
+ const keys = Object.keys(a).filter((key) => a[key] !== undefined);
40767
+ const otherKeys = Object.keys(b).filter((key) => b[key] !== undefined);
40768
+ return keys.length === otherKeys.length && keys.every((key) => sameValue2(a[key], b[key]));
40769
+ }
40770
+ function lineStart(text, offset) {
40771
+ return text.lastIndexOf(`
40772
+ `, offset - 1) + 1;
40773
+ }
40774
+ function lineEnd(text, offset) {
40775
+ const newline = text.indexOf(`
40776
+ `, offset);
40777
+ return newline === -1 ? text.length : newline + 1;
40778
+ }
40779
+ function sourceEntries(text) {
40780
+ const doc = $parseDocument(text);
40781
+ if (doc.errors.length > 0 || doc.warnings.length > 0) {
40782
+ return null;
40783
+ }
40784
+ const { contents } = doc;
40785
+ if (!$isMap(contents) || contents.flow === true) {
40786
+ return null;
40787
+ }
40788
+ const pairs = contents.items;
40789
+ const keys = [];
40790
+ for (const { key } of pairs) {
40791
+ if (!$isScalar(key) || !key.range || !isString(key.value)) {
40792
+ return null;
40793
+ }
40794
+ keys.push({ name: key.value, range: key.range });
40795
+ }
40796
+ const js = doc.toJS();
40797
+ const values = isJsonObject(js) ? js : {};
40798
+ const entries = [];
40799
+ for (const [index, { name, range }] of keys.entries()) {
40800
+ const end = pairs[index]?.value?.range?.[1] ?? range[1];
40801
+ entries.push({
40802
+ key: name,
40803
+ start: lineStart(text, range[0]),
40804
+ value: values[name],
40805
+ valueEnd: lineEnd(text, Math.max(end - 1, range[0]))
40806
+ });
40807
+ }
40808
+ return entries;
40809
+ }
40810
+ function spliceFrontmatter(frontmatter, source, write) {
40811
+ const entries = sourceEntries(source);
40812
+ if (!entries) {
40813
+ return null;
40814
+ }
40815
+ const present = (key) => Object.hasOwn(frontmatter, key) && frontmatter[key] !== undefined;
40816
+ const segments = [];
40817
+ const head = source.slice(0, entries[0]?.start ?? source.length);
40818
+ if (head.trim().length > 0) {
40819
+ segments.push(head);
40820
+ }
40821
+ for (const [index, entry] of entries.entries()) {
40822
+ const chunkEnd = entries[index + 1]?.start ?? source.length;
40823
+ if (!present(entry.key)) {
40824
+ continue;
40825
+ }
40826
+ if (sameValue2(entry.value, frontmatter[entry.key])) {
40827
+ segments.push(source.slice(entry.start, chunkEnd));
40828
+ continue;
40829
+ }
40830
+ const tail = source.slice(Math.min(entry.valueEnd, chunkEnd), chunkEnd);
40831
+ segments.push(`${write({ [entry.key]: frontmatter[entry.key] })}
40832
+ ${tail}`);
40833
+ }
40834
+ const known = new Set(entries.map((entry) => entry.key));
40835
+ const added = {};
40836
+ for (const [key, value] of Object.entries(frontmatter)) {
40837
+ if (!known.has(key) && value !== undefined) {
40838
+ added[key] = value;
40839
+ }
40840
+ }
40841
+ if (Object.keys(added).length > 0) {
40842
+ segments.push(write(added));
40843
+ }
40844
+ return segments.map((segment) => segment.endsWith(`
40845
+ `) ? segment : `${segment}
40846
+ `).join("").replace(/\s+$/u, "");
40847
+ }
40848
+ function startOffset(node) {
40849
+ const position = node.position;
40850
+ const offset = position?.start?.offset;
40851
+ return isNumber(offset) ? offset : null;
40852
+ }
40853
+ function markdownMarkers(tree, source) {
40854
+ const markers = { bullet: "-", emphasis: "*", strong: "*" };
40855
+ const seen = new Set;
40856
+ const visit = (node) => {
40857
+ const offset = startOffset(node);
40858
+ if (offset !== null && !seen.has(node.type)) {
40859
+ const char = source[offset];
40860
+ if ((node.type === "emphasis" || node.type === "strong") && (char === "*" || char === "_")) {
40861
+ markers[node.type] = char;
40862
+ seen.add(node.type);
40863
+ } else if (node.type === "listItem" && (char === "-" || char === "*" || char === "+")) {
40864
+ markers.bullet = char;
40865
+ seen.add(node.type);
40866
+ }
40867
+ }
40868
+ for (const child of node.children ?? []) {
40869
+ visit(child);
40870
+ }
40871
+ };
40872
+ visit(tree);
40873
+ return markers;
40874
+ }
40875
+ var FRONTMATTER_RE;
40876
+ var init_source_style = __esm(() => {
40877
+ init_dist3();
40878
+ init_guards();
40879
+ FRONTMATTER_RE = /^---\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/u;
40880
+ });
40881
+
40745
40882
  // src/serialize.ts
40746
40883
  function textOf(el) {
40747
40884
  return el && isString(el.textContent) ? el.textContent : undefined;
@@ -40952,6 +41089,72 @@ function hasJxProps(el) {
40952
41089
  }
40953
41090
  return false;
40954
41091
  }
41092
+ function hasOnlyMarkdownAttributes(el, tag) {
41093
+ const allowed = MD_ATTRIBUTES.get(tag);
41094
+ return Object.keys(el.attributes ?? {}).every((name) => allowed?.has(name) ?? false);
41095
+ }
41096
+ function partChildren(el) {
41097
+ return childList(el).filter((child) => !isString(child) || child.trim() !== "");
41098
+ }
41099
+ function plainPart(slot, tag) {
41100
+ if (slot === undefined || isString(slot) || slot.tagName !== tag) {
41101
+ return null;
41102
+ }
41103
+ const attributes = Object.keys(slot.attributes ?? {});
41104
+ return attributes.length === 0 && !hasJxProps(slot) ? slot : null;
41105
+ }
41106
+ function isGfmCell(cell) {
41107
+ if (cell.textContent != null) {
41108
+ return !String(cell.textContent).includes(`
41109
+ `);
41110
+ }
41111
+ return childList(cell).every((child) => isString(child) ? !child.includes(`
41112
+ `) : isString(child.tagName) && (MD_INLINE.has(child.tagName) || child.tagName === "span"));
41113
+ }
41114
+ function gfmRowCells(row, cellTag) {
41115
+ const tr = plainPart(row, "tr");
41116
+ if (!tr || tr.textContent != null) {
41117
+ return null;
41118
+ }
41119
+ const cells = [];
41120
+ for (const slot of partChildren(tr)) {
41121
+ const cell = plainPart(slot, cellTag);
41122
+ if (!cell || !isGfmCell(cell)) {
41123
+ return null;
41124
+ }
41125
+ cells.push(cell);
41126
+ }
41127
+ return cells.length > 0 ? cells : null;
41128
+ }
41129
+ function gfmTableRows(el) {
41130
+ if (el.textContent != null) {
41131
+ return null;
41132
+ }
41133
+ const [headSlot, bodySlot, ...rest] = partChildren(el);
41134
+ const thead = plainPart(headSlot, "thead");
41135
+ if (!thead || rest.length > 0) {
41136
+ return null;
41137
+ }
41138
+ const headRows = partChildren(thead);
41139
+ const head = headRows.length === 1 ? gfmRowCells(headRows[0], "th") : null;
41140
+ if (!head) {
41141
+ return null;
41142
+ }
41143
+ if (bodySlot === undefined) {
41144
+ return { body: [], head };
41145
+ }
41146
+ const tbody = plainPart(bodySlot, "tbody");
41147
+ const rows = tbody ? partChildren(tbody) : [];
41148
+ const body = [];
41149
+ for (const row of rows) {
41150
+ const cells = gfmRowCells(row, "td");
41151
+ if (!cells || cells.length !== head.length) {
41152
+ return null;
41153
+ }
41154
+ body.push(cells);
41155
+ }
41156
+ return body.length > 0 ? { body, head } : null;
41157
+ }
40955
41158
  function convertJxNode(slot, isBlock, allowlist) {
40956
41159
  if (isString(slot) || isNumber(slot)) {
40957
41160
  return { type: "text", value: String(slot) };
@@ -40961,7 +41164,8 @@ function convertJxNode(slot, isBlock, allowlist) {
40961
41164
  }
40962
41165
  const el = slot;
40963
41166
  const tag = serializableTag(el.tagName) || "div";
40964
- if (!allowlist.has(tag) || hasJxProps(el)) {
41167
+ const tableRows = tag === "table" ? gfmTableRows(el) : null;
41168
+ if (!allowlist.has(tag) || hasJxProps(el) || !hasOnlyMarkdownAttributes(el, tag) || TABLE_PARTS.has(tag) || tag === "table" && tableRows === null || isBlock && tag === "img") {
40965
41169
  return convertToDirective(el, isBlock, allowlist);
40966
41170
  }
40967
41171
  const mdastType = hasMdastType(tag) ? TAG_MDAST_MAP[tag] : undefined;
@@ -41054,36 +41258,20 @@ function convertJxNode(slot, isBlock, allowlist) {
41054
41258
  return { type: "break" };
41055
41259
  }
41056
41260
  case "table": {
41057
- const rows = [];
41058
- for (const section of childList(el)) {
41059
- if (isString(section)) {
41060
- continue;
41061
- }
41062
- if (section.tagName === "thead" || section.tagName === "tbody") {
41063
- for (const row of childList(section)) {
41064
- const mdRow = convertJxNode(row, true, allowlist);
41065
- if (mdRow) {
41066
- if (section.tagName === "thead") {
41067
- for (const cell of mdRow.children ?? []) {
41068
- cell.isHeader = true;
41069
- }
41070
- }
41071
- rows.push(mdRow);
41072
- }
41073
- }
41074
- }
41075
- }
41076
- return { children: rows, type: "table" };
41077
- }
41078
- case "tableRow": {
41079
- return {
41080
- children: convertJxChildren(childList(el), false, allowlist),
41261
+ const { body, head } = tableRows ?? { body: [], head: [] };
41262
+ const row = (cells, isHeader) => ({
41263
+ children: cells.map((cell) => ({
41264
+ children: inline(cell),
41265
+ type: "tableCell",
41266
+ ...isHeader && { isHeader: true }
41267
+ })),
41081
41268
  type: "tableRow"
41269
+ });
41270
+ return {
41271
+ children: [row(head, true), ...body.map((cells) => row(cells, false))],
41272
+ type: "table"
41082
41273
  };
41083
41274
  }
41084
- case "tableCell": {
41085
- return { children: inline(el), type: "tableCell" };
41086
- }
41087
41275
  default: {
41088
41276
  break;
41089
41277
  }
@@ -41782,21 +41970,31 @@ function serializeRoundtrip(doc, opts) {
41782
41970
  frontmatter[key] = value;
41783
41971
  }
41784
41972
  if (Object.keys(frontmatter).length > 0) {
41785
- lines.push("---", $stringify(frontmatter).trim(), "---", "");
41973
+ const sourceYaml = opts.source === undefined ? null : frontmatterText(opts.source);
41974
+ const spliced = sourceYaml === null ? null : spliceFrontmatter(frontmatter, sourceYaml, (values) => stringifyFrontmatter(values));
41975
+ lines.push("---", spliced ?? stringifyFrontmatter(frontmatter), "---", "");
41786
41976
  }
41787
41977
  }
41788
41978
  if (Array.isArray(doc.children) && doc.children.length > 0) {
41789
41979
  const mdast = jxToMdast(doc, opts);
41790
- const processor = createProcessor().use(remarkGfm).use(remarkDirective).use(remarkStringifyPlugin, { bullet: "-", emphasis: "*", strong: "*" });
41791
- const md = processor.stringify(mdast);
41792
- lines.push(md);
41980
+ const markers = opts.source === undefined ? { bullet: "-", emphasis: "*", strong: "*" } : sourceMarkers(opts.source);
41981
+ const processor = createProcessor().use(remarkGfm).use(remarkDirective).use(remarkStringifyPlugin, { ...markers });
41982
+ lines.push(processor.stringify(mdast).replaceAll(/\n{3,}/g, `
41983
+
41984
+ `));
41793
41985
  }
41794
41986
  return `${lines.join(`
41795
- `).replaceAll(/\n{3,}/g, `
41796
-
41797
41987
  `).trim()}
41798
41988
  `;
41799
41989
  }
41990
+ function sourceMarkers(source) {
41991
+ const body = bodyText(source);
41992
+ const tree = createProcessor().use(remarkParsePlugin).use(remarkGfm).use(remarkDirective).parse(body);
41993
+ return markdownMarkers(tree, body);
41994
+ }
41995
+ function stringifyFrontmatter(frontmatter) {
41996
+ return $stringify(frontmatter, { lineWidth: 0, version: "1.1" }).trim();
41997
+ }
41800
41998
  function serializeExport(doc, opts) {
41801
41999
  if (!Array.isArray(doc.children) || doc.children.length === 0) {
41802
42000
  return "";
@@ -41841,16 +42039,18 @@ function serializeExport(doc, opts) {
41841
42039
  `).trim()}
41842
42040
  `;
41843
42041
  }
41844
- var MD_ELEMENTS, MD_BLOCK, MD_INLINE, MD_ALL, MD_VOID, MD_TEXT_ONLY, TAG_MDAST_MAP, WRAPPER_TAGS, INLINE_CONTENT_TAGS, MDAST_TAG_MAP, CSS_PSEUDO_NAMES2, JX_DOLLAR_KEYS2, PROTOTYPE_DIRECTIVE_NAMES2, JX_ANNOTATION_KEYS2, remarkStringifyPlugin;
42042
+ var MD_ELEMENTS, MD_BLOCK, MD_INLINE, MD_ALL, MD_VOID, MD_TEXT_ONLY, TAG_MDAST_MAP, WRAPPER_TAGS, INLINE_CONTENT_TAGS, MDAST_TAG_MAP, MD_ATTRIBUTES, TABLE_PARTS, CSS_PSEUDO_NAMES2, JX_DOLLAR_KEYS2, PROTOTYPE_DIRECTIVE_NAMES2, JX_ANNOTATION_KEYS2, remarkStringifyPlugin, remarkParsePlugin;
41845
42043
  var init_serialize = __esm(() => {
41846
42044
  init_unified();
41847
42045
  init_guards();
42046
+ init_remark_parse();
41848
42047
  init_remark_stringify();
41849
42048
  init_remark_directive();
41850
42049
  init_remark_gfm();
41851
42050
  init_dist3();
41852
42051
  init_html_to_jx();
41853
42052
  init_transpile();
42053
+ init_source_style();
41854
42054
  MD_ELEMENTS = {
41855
42055
  block: [
41856
42056
  "h1",
@@ -41985,6 +42185,12 @@ var init_serialize = __esm(() => {
41985
42185
  text: () => "span",
41986
42186
  thematicBreak: () => "hr"
41987
42187
  };
42188
+ MD_ATTRIBUTES = new Map([
42189
+ ["a", new Set(["href", "title"])],
42190
+ ["img", new Set(["alt", "src", "title"])],
42191
+ ["ol", new Set(["start"])]
42192
+ ]);
42193
+ TABLE_PARTS = new Set(["tbody", "td", "th", "thead", "tr"]);
41988
42194
  CSS_PSEUDO_NAMES2 = new Set([
41989
42195
  "hover",
41990
42196
  "focus",
@@ -42016,6 +42222,7 @@ var init_serialize = __esm(() => {
42016
42222
  PROTOTYPE_DIRECTIVE_NAMES2 = new Set(["Array"]);
42017
42223
  JX_ANNOTATION_KEYS2 = new Set(["$title", "$description"]);
42018
42224
  remarkStringifyPlugin = remarkStringify;
42225
+ remarkParsePlugin = remarkParse;
42019
42226
  });
42020
42227
 
42021
42228
  // src/walk.ts
@@ -53964,6 +54171,11 @@ function getHighlighter() {
53964
54171
  ],
53965
54172
  themes: [github_light_default_default, github_dark_default_default]
53966
54173
  });
54174
+ _highlighter.codeToTokens("const a = 1;", {
54175
+ defaultColor: false,
54176
+ lang: "javascript",
54177
+ themes: THEMES
54178
+ });
53967
54179
  return _highlighter;
53968
54180
  }
53969
54181
  function highlightFence(code, info) {
@@ -53972,7 +54184,12 @@ function highlightFence(code, info) {
53972
54184
  if (!h.getLoadedLanguages().includes(lang)) {
53973
54185
  return null;
53974
54186
  }
53975
- const { tokens } = h.codeToTokens(code, { defaultColor: false, lang, themes: THEMES });
54187
+ const { tokens } = h.codeToTokens(code, {
54188
+ defaultColor: false,
54189
+ lang,
54190
+ themes: THEMES,
54191
+ tokenizeTimeLimit: 0
54192
+ });
53976
54193
  const out = [];
53977
54194
  for (const [i, line] of tokens.entries()) {
53978
54195
  if (i > 0) {