reamkit 1.26.0 → 1.27.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.
Files changed (50) hide show
  1. package/README.md +9 -4
  2. package/dist/esm/pdf-reader/annot-draw.d.ts +65 -0
  3. package/dist/esm/pdf-reader/annot-draw.js +374 -0
  4. package/dist/esm/pdf-reader/annots.d.ts +3 -1
  5. package/dist/esm/pdf-reader/annots.js +18 -4
  6. package/dist/esm/pdf-reader/ccitt.d.ts +18 -0
  7. package/dist/esm/pdf-reader/ccitt.js +70 -2
  8. package/dist/esm/pdf-reader/cie-color.d.ts +33 -0
  9. package/dist/esm/pdf-reader/cie-color.js +112 -0
  10. package/dist/esm/pdf-reader/content.d.ts +47 -3
  11. package/dist/esm/pdf-reader/content.js +108 -13
  12. package/dist/esm/pdf-reader/display.d.ts +1 -1
  13. package/dist/esm/pdf-reader/display.js +21 -6
  14. package/dist/esm/pdf-reader/document.d.ts +6 -0
  15. package/dist/esm/pdf-reader/document.js +29 -1
  16. package/dist/esm/pdf-reader/embedded-fonts.d.ts +12 -3
  17. package/dist/esm/pdf-reader/embedded-fonts.js +22 -3
  18. package/dist/esm/pdf-reader/flow-build.d.ts +12 -4
  19. package/dist/esm/pdf-reader/flow-build.js +102 -8
  20. package/dist/esm/pdf-reader/font.js +77 -16
  21. package/dist/esm/pdf-reader/function.d.ts +16 -0
  22. package/dist/esm/pdf-reader/function.js +414 -0
  23. package/dist/esm/pdf-reader/image-decode.d.ts +8 -4
  24. package/dist/esm/pdf-reader/image-decode.js +192 -11
  25. package/dist/esm/pdf-reader/images.d.ts +12 -0
  26. package/dist/esm/pdf-reader/images.js +109 -9
  27. package/dist/esm/pdf-reader/jbig2.d.ts +23 -0
  28. package/dist/esm/pdf-reader/jbig2.js +23 -14
  29. package/dist/esm/pdf-reader/layout.d.ts +32 -0
  30. package/dist/esm/pdf-reader/layout.js +189 -40
  31. package/dist/esm/pdf-reader/lexer.d.ts +2 -0
  32. package/dist/esm/pdf-reader/lexer.js +4 -0
  33. package/dist/esm/pdf-reader/optional-content.d.ts +36 -0
  34. package/dist/esm/pdf-reader/optional-content.js +93 -0
  35. package/dist/esm/pdf-reader/reader.d.ts +5 -2
  36. package/dist/esm/pdf-reader/reader.js +80 -7
  37. package/dist/esm/pdf-reader/shading.d.ts +60 -8
  38. package/dist/esm/pdf-reader/shading.js +124 -20
  39. package/dist/esm/pdf-reader/standard-metrics.d.ts +8 -0
  40. package/dist/esm/pdf-reader/standard-metrics.js +18 -0
  41. package/dist/esm/pdf-reader/standard-widths.d.ts +20 -0
  42. package/dist/esm/pdf-reader/standard-widths.js +62 -0
  43. package/dist/esm/pdf-reader/tagged.js +204 -32
  44. package/dist/esm/pdf-reader/text-rules.d.ts +16 -0
  45. package/dist/esm/pdf-reader/text-rules.js +112 -0
  46. package/dist/esm/pdf-reader/text.js +78 -4
  47. package/dist/esm/pdf-reader/vector.d.ts +5 -0
  48. package/dist/esm/pdf-reader/vector.js +39 -26
  49. package/dist/esm/word/docx-writer.js +73 -11
  50. package/package.json +1 -1
@@ -616,8 +616,8 @@ function geomXml(g) {
616
616
  case "close": return "<a:close/>";
617
617
  }
618
618
  }).join("");
619
- const w = c1(g.custom.pathWidth);
620
- const h = c1(g.custom.pathHeight);
619
+ const w = Math.max(1, c1(g.custom.pathWidth));
620
+ const h = Math.max(1, c1(g.custom.pathHeight));
621
621
  return `<a:custGeom><a:avLst/><a:gdLst/><a:rect l="0" t="0" r="${w}" b="${h}"/><a:pathLst><a:path w="${w}" h="${h}">${cmds}</a:path></a:pathLst></a:custGeom>`;
622
622
  }
623
623
  const gds = g.adjust && g.adjust.size > 0 ? [...g.adjust].map(([n, v]) => `<a:gd name="${escapeAttr(n)}" fmla="val ${v}"/>`).join("") : "";
@@ -826,19 +826,27 @@ function runXml(run, state, scope) {
826
826
  }
827
827
  function rPrXml(r) {
828
828
  const out = [];
829
+ const fonts = rFontsXml(r.fontFamily);
830
+ if (fonts) out.push(fonts);
829
831
  if (r.bold !== DEFAULT_RUN.bold) out.push(toggle("w:b", r.bold));
830
832
  if (r.italic !== DEFAULT_RUN.italic) out.push(toggle("w:i", r.italic));
831
833
  if (r.strike !== DEFAULT_RUN.strike) out.push(toggle("w:strike", r.strike));
832
- if (r.underline !== DEFAULT_RUN.underline) out.push(`<w:u w:val="${r.underline}"/>`);
833
- const fonts = rFontsXml(r.fontFamily);
834
- if (fonts) out.push(fonts);
835
- if (r.fontSizePt !== DEFAULT_RUN.fontSizePt) out.push(`<w:sz w:val="${Math.round(r.fontSizePt * 2)}"/>`);
836
834
  if (r.colorHex !== DEFAULT_RUN.colorHex) out.push(`<w:color w:val="${r.colorHex}"/>`);
835
+ if (r.fontSizePt !== DEFAULT_RUN.fontSizePt) out.push(`<w:sz w:val="${Math.round(r.fontSizePt * 2)}"/>`);
836
+ if (r.underline !== DEFAULT_RUN.underline) out.push(underlineXml(r));
837
+ if (r.shadingColorHex !== void 0) out.push(runShdXml(r.shadingColorHex));
837
838
  if (r.verticalAlign !== DEFAULT_RUN.verticalAlign) out.push(`<w:vertAlign w:val="${r.verticalAlign}"/>`);
838
839
  if (r.rtl !== DEFAULT_RUN.rtl) out.push(toggle("w:rtl", r.rtl));
839
840
  if (r.lang !== void 0) out.push(`<w:lang w:val="${escapeAttr(r.lang)}"/>`);
840
841
  return out.length > 0 ? `<w:rPr>${out.join("")}</w:rPr>` : "";
841
842
  }
843
+ function underlineXml(r) {
844
+ const color = r.underlineColorHex !== void 0 ? ` w:color="${r.underlineColorHex}"` : "";
845
+ return `<w:u w:val="${r.underline}"${color}/>`;
846
+ }
847
+ function runShdXml(fill) {
848
+ return `<w:shd w:val="clear" w:color="auto" w:fill="${fill}"/>`;
849
+ }
842
850
  function pPrBody(p) {
843
851
  const out = [];
844
852
  if (p.numbering) out.push(`<w:numPr><w:ilvl w:val="${p.numbering.ilvl}"/><w:numId w:val="${escapeAttr(p.numbering.numId)}"/></w:numPr>`);
@@ -942,14 +950,18 @@ function rawParaPrXml(p) {
942
950
  }
943
951
  function rawRunPrXml(r) {
944
952
  const out = [];
953
+ const fonts = r.fontFamily ? rawRFontsXml(r.fontFamily) : "";
954
+ if (fonts) out.push(fonts);
945
955
  if (r.bold !== void 0) out.push(toggle("w:b", r.bold));
946
956
  if (r.italic !== void 0) out.push(toggle("w:i", r.italic));
947
957
  if (r.strike !== void 0) out.push(toggle("w:strike", r.strike));
948
- if (r.underline !== void 0) out.push(`<w:u w:val="${r.underline}"/>`);
949
- const fonts = r.fontFamily ? rawRFontsXml(r.fontFamily) : "";
950
- if (fonts) out.push(fonts);
951
- if (r.fontSizePt !== void 0) out.push(`<w:sz w:val="${Math.round(r.fontSizePt * 2)}"/>`);
952
958
  if (r.colorHex !== void 0) out.push(`<w:color w:val="${r.colorHex}"/>`);
959
+ if (r.fontSizePt !== void 0) out.push(`<w:sz w:val="${Math.round(r.fontSizePt * 2)}"/>`);
960
+ if (r.underline !== void 0) out.push(underlineXml({
961
+ ...r,
962
+ underline: r.underline
963
+ }));
964
+ if (r.shadingColorHex !== void 0) out.push(runShdXml(r.shadingColorHex));
953
965
  if (r.verticalAlign !== void 0) out.push(`<w:vertAlign w:val="${r.verticalAlign}"/>`);
954
966
  return out.length > 0 ? `<w:rPr>${out.join("")}</w:rPr>` : "";
955
967
  }
@@ -987,8 +999,58 @@ function colsXml(cols) {
987
999
  return `<w:cols w:num="${cols.count}" w:space="${twips(cols.spacePt)}"/>`;
988
1000
  }
989
1001
  var twips = (pt) => Math.round(pt * 20);
1002
+ /**
1003
+ * XML 1.0 §2.2 — the characters a document may contain at all.
1004
+ *
1005
+ * Everything below U+0020 except tab, newline and return is FORBIDDEN, and no
1006
+ * escape exists for them: `&#2;` is as ill-formed as the byte. A package with
1007
+ * one in it is not a document — LibreOffice says "source file could not be
1008
+ * loaded" and Word says nothing useful either.
1009
+ *
1010
+ * They reach here from the PDF reader. A subset font that states neither a
1011
+ * `/ToUnicode` nor an `/Encoding /Differences` says nothing about what its
1012
+ * codes mean, and the codes of a subset start at 1, 2, 3 — so the last-resort
1013
+ * Latin-1 reading turns a page of text into control characters. Reading it
1014
+ * better is `font.ts`'s business; what this must guarantee is that nothing the
1015
+ * reader believes can produce a package that will not open.
1016
+ *
1017
+ * A lone surrogate is the same case: a half of a pair is not a character.
1018
+ */
1019
+ /**
1020
+ * XML 1.0 §2.2 — whether a code point may appear in a document at all.
1021
+ *
1022
+ * Everything below U+0020 except tab, newline and return is forbidden, and no
1023
+ * escape exists for them: `&#2;` is as ill-formed as the byte itself. So is a
1024
+ * lone surrogate — half a pair is not a character — and so are U+FFFE/U+FFFF.
1025
+ */
1026
+ function xmlAllows(cp) {
1027
+ if (cp === 9 || cp === 10 || cp === 13) return true;
1028
+ if (cp < 32) return false;
1029
+ if (cp >= 55296 && cp <= 57343) return false;
1030
+ if (cp === 65534 || cp === 65535) return false;
1031
+ return cp <= 1114111;
1032
+ }
1033
+ /**
1034
+ * Escape text for XML, and drop what XML cannot carry.
1035
+ *
1036
+ * The dropping is not fussiness: a package with one control character in it is
1037
+ * not a document. LibreOffice answers "source file could not be loaded" and
1038
+ * Word refuses it too, so the whole conversion is lost over one byte.
1039
+ *
1040
+ * They reach here from the PDF reader. A subset font that states neither a
1041
+ * `/ToUnicode` nor an `/Encoding /Differences` says nothing about what its
1042
+ * codes mean, and a subset's codes start at 1, 2, 3 — so the last-resort
1043
+ * Latin-1 reading turns a page of prose into control characters. Reading such
1044
+ * a font better is `font.ts`'s business; what this guarantees is that nothing
1045
+ * the reader believes can produce a package that will not open.
1046
+ */
990
1047
  function escapeXml(s) {
991
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1048
+ let out = "";
1049
+ for (const ch of s) {
1050
+ if (!xmlAllows(ch.codePointAt(0) ?? 0)) continue;
1051
+ out += ch === "&" ? "&amp;" : ch === "<" ? "&lt;" : ch === ">" ? "&gt;" : ch;
1052
+ }
1053
+ return out;
992
1054
  }
993
1055
  function escapeAttr(s) {
994
1056
  return escapeXml(s).replace(/"/g, "&quot;");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reamkit",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "description": "Ream — convert DOCX, XLSX, PPTX and PDF to PDF, SVG, HTML, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
5
5
  "license": "MIT",
6
6
  "author": "Alex Krassavin <info@reamkit.dev>",