@speajus/markdown-to-pdf 1.0.20 → 1.0.21
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/package.json +2 -1
- package/scripts/patch-fontkit-colr.js +105 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speajus/markdown-to-pdf",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "A new project created with Intent by Augment.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
|
+
"scripts",
|
|
29
30
|
"README.md"
|
|
30
31
|
],
|
|
31
32
|
"scripts": {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patches fontkit's COLRGlyph class to guard against null baseGlyphRecord.
|
|
3
|
+
*
|
|
4
|
+
* Some emoji fonts have a COLR table but null/missing baseGlyphRecord,
|
|
5
|
+
* causing `TypeError: Cannot read properties of null (reading 'length')`
|
|
6
|
+
* when fontkit's COLRGlyph.layers getter is called.
|
|
7
|
+
*
|
|
8
|
+
* This script patches both the src and dist files of fontkit in node_modules.
|
|
9
|
+
*/
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
const nmDir = path.join(__dirname, '..', 'node_modules');
|
|
14
|
+
|
|
15
|
+
function patchFile(filePath, patches) {
|
|
16
|
+
if (!fs.existsSync(filePath)) return false;
|
|
17
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
18
|
+
let changed = false;
|
|
19
|
+
for (const [search, replace] of patches) {
|
|
20
|
+
if (content.includes(search) && !content.includes(replace)) {
|
|
21
|
+
// Replace ALL occurrences (some bundled files may have multiple copies)
|
|
22
|
+
content = content.split(search).join(replace);
|
|
23
|
+
changed = true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (changed) {
|
|
27
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
28
|
+
console.log(` Patched: ${filePath}`);
|
|
29
|
+
}
|
|
30
|
+
return changed;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Patch 1: Guard against null baseGlyphRecord in COLRGlyph.layers getter
|
|
34
|
+
const layersGetterPatch = [
|
|
35
|
+
'let high = colr.baseGlyphRecord.length - 1;',
|
|
36
|
+
'if (!colr || !colr.baseGlyphRecord) { return null; } let high = colr.baseGlyphRecord.length - 1;',
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
// Patch 2: Don't create COLRGlyph for COLR v1 fonts (no v0 baseGlyphRecord)
|
|
40
|
+
// COLR v1 uses a different paint-based structure that fontkit doesn't support.
|
|
41
|
+
// Without this, COLR v1 glyphs (e.g. OpenMoji) get typed as COLR but can't
|
|
42
|
+
// render, and they also won't fall back to SBIX/CBDT/SVG alternatives.
|
|
43
|
+
const getGlyphPatch = [
|
|
44
|
+
'this.directory.tables.COLR && this.directory.tables.CPAL)',
|
|
45
|
+
'this.directory.tables.COLR && this.directory.tables.CPAL && this.COLR && this.COLR.baseGlyphRecord)',
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// Patch 3: Fix _getContours crash for composite glyphs in COLR fonts
|
|
49
|
+
// When a composite TTF glyph references a component that is a COLRGlyph,
|
|
50
|
+
// calling _getContours() on it crashes because COLRGlyph doesn't have that method.
|
|
51
|
+
// Use _getBaseGlyph to get the TTF outline instead.
|
|
52
|
+
const getContoursPatch = [
|
|
53
|
+
'this._font.getGlyph(component.glyphID)._getContours()',
|
|
54
|
+
'((g) => { if (!g || typeof g._getContours !== "function") return []; return g._getContours(); })(this._font._getBaseGlyph(component.glyphID) || this._font.getGlyph(component.glyphID))',
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
// Patch 4: Fix _decode crash in TTF subsetter for COLR glyphs
|
|
58
|
+
// COLRGlyph doesn't have _decode() method. The subsetter needs to handle
|
|
59
|
+
// COLR glyphs gracefully by treating them as simple (non-compound) glyphs.
|
|
60
|
+
const decodePatch = [
|
|
61
|
+
'let glyf = glyph._decode();',
|
|
62
|
+
'let glyf = typeof glyph._decode === "function" ? glyph._decode() : null;',
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const allPatches = [layersGetterPatch, getGlyphPatch, getContoursPatch, decodePatch];
|
|
66
|
+
|
|
67
|
+
let patchCount = 0;
|
|
68
|
+
|
|
69
|
+
// 1. Patch fontkit dist/src files directly
|
|
70
|
+
const fontkitPaths = [
|
|
71
|
+
path.join(nmDir, 'fontkit'),
|
|
72
|
+
path.join(nmDir, 'pdfkit', 'node_modules', 'fontkit'),
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
for (const fontkitDir of fontkitPaths) {
|
|
76
|
+
if (!fs.existsSync(fontkitDir)) continue;
|
|
77
|
+
for (const distFile of ['dist/browser-module.mjs', 'dist/main.cjs']) {
|
|
78
|
+
if (patchFile(path.join(fontkitDir, distFile), allPatches)) patchCount++;
|
|
79
|
+
}
|
|
80
|
+
if (patchFile(path.join(fontkitDir, 'src', 'glyph', 'COLRGlyph.js'), [layersGetterPatch])) patchCount++;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 2. Patch pdfkit standalone bundles (these embed fontkit inline)
|
|
84
|
+
const pdfkitBundles = [
|
|
85
|
+
path.join(nmDir, 'pdfkit', 'js', 'pdfkit.standalone.js'),
|
|
86
|
+
path.join(nmDir, 'pdfkit', 'js', 'pdfkit.js'),
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
for (const bundle of pdfkitBundles) {
|
|
90
|
+
if (patchFile(bundle, allPatches)) patchCount++;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 3. Clear Vite dep cache so it re-bundles with patched files
|
|
94
|
+
const viteCacheDir = path.join(nmDir, '.vite');
|
|
95
|
+
if (fs.existsSync(viteCacheDir)) {
|
|
96
|
+
fs.rmSync(viteCacheDir, { recursive: true, force: true });
|
|
97
|
+
console.log(' Cleared Vite dep cache (.vite)');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (patchCount > 0) {
|
|
101
|
+
console.log(`fontkit COLR patch: ${patchCount} file(s) patched.`);
|
|
102
|
+
} else {
|
|
103
|
+
console.log('fontkit COLR patch: already applied or fontkit not found.');
|
|
104
|
+
}
|
|
105
|
+
|