pptx-glimpse 0.11.0 → 0.11.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.
- package/dist/index.cjs +56 -16
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +56 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1962,25 +1962,48 @@ var LazyMediaMap = class {
|
|
|
1962
1962
|
return data;
|
|
1963
1963
|
}
|
|
1964
1964
|
};
|
|
1965
|
+
var LazyXmlMap = class {
|
|
1966
|
+
rawInput;
|
|
1967
|
+
cache = /* @__PURE__ */ new Map();
|
|
1968
|
+
entryIndex;
|
|
1969
|
+
constructor(rawInput, xmlEntryNames) {
|
|
1970
|
+
this.rawInput = rawInput;
|
|
1971
|
+
this.entryIndex = xmlEntryNames;
|
|
1972
|
+
}
|
|
1973
|
+
has(path) {
|
|
1974
|
+
return this.entryIndex.has(path);
|
|
1975
|
+
}
|
|
1976
|
+
get(path) {
|
|
1977
|
+
if (!this.entryIndex.has(path)) return void 0;
|
|
1978
|
+
const cached = this.cache.get(path);
|
|
1979
|
+
if (cached !== void 0) return cached;
|
|
1980
|
+
const result = (0, import_fflate.unzipSync)(this.rawInput, {
|
|
1981
|
+
filter: (file) => file.name === path
|
|
1982
|
+
});
|
|
1983
|
+
const data = result[path];
|
|
1984
|
+
if (data) {
|
|
1985
|
+
const str = (0, import_fflate.strFromU8)(data);
|
|
1986
|
+
this.cache.set(path, str);
|
|
1987
|
+
return str;
|
|
1988
|
+
}
|
|
1989
|
+
return void 0;
|
|
1990
|
+
}
|
|
1991
|
+
};
|
|
1965
1992
|
function readPptx(input) {
|
|
1966
1993
|
const rawInput = new Uint8Array(input);
|
|
1994
|
+
const xmlEntryNames = /* @__PURE__ */ new Set();
|
|
1967
1995
|
const mediaEntryNames = /* @__PURE__ */ new Set();
|
|
1968
|
-
|
|
1996
|
+
(0, import_fflate.unzipSync)(rawInput, {
|
|
1969
1997
|
filter: (file) => {
|
|
1970
1998
|
if (file.name.startsWith("ppt/media/")) {
|
|
1971
1999
|
mediaEntryNames.add(file.name);
|
|
1972
|
-
|
|
2000
|
+
} else if (file.name.endsWith(".xml") || file.name.endsWith(".rels") || file.name === "[Content_Types].xml") {
|
|
2001
|
+
xmlEntryNames.add(file.name);
|
|
1973
2002
|
}
|
|
1974
|
-
return
|
|
2003
|
+
return false;
|
|
1975
2004
|
}
|
|
1976
2005
|
});
|
|
1977
|
-
const files =
|
|
1978
|
-
for (const [relativePath, data] of Object.entries(unzipped)) {
|
|
1979
|
-
if (relativePath.endsWith("/")) continue;
|
|
1980
|
-
if (relativePath.endsWith(".xml") || relativePath.endsWith(".rels") || relativePath === "[Content_Types].xml") {
|
|
1981
|
-
files.set(relativePath, (0, import_fflate.strFromU8)(data));
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
2006
|
+
const files = new LazyXmlMap(rawInput, xmlEntryNames);
|
|
1984
2007
|
const media = new LazyMediaMap(rawInput, mediaEntryNames);
|
|
1985
2008
|
return { files, media };
|
|
1986
2009
|
}
|
|
@@ -3176,6 +3199,10 @@ function createDefaultBorders() {
|
|
|
3176
3199
|
|
|
3177
3200
|
// src/parser/slide-parser.ts
|
|
3178
3201
|
var SHAPE_TAGS = /* @__PURE__ */ new Set(["sp", "pic", "cxnSp", "grpSp", "graphicFrame"]);
|
|
3202
|
+
var SMARTART_DIAGRAM_URIS = /* @__PURE__ */ new Set([
|
|
3203
|
+
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
3204
|
+
"http://purl.oclc.org/ooxml/drawingml/diagram"
|
|
3205
|
+
]);
|
|
3179
3206
|
function navigateOrdered(ordered, path) {
|
|
3180
3207
|
let current = ordered;
|
|
3181
3208
|
for (const key of path) {
|
|
@@ -3723,7 +3750,7 @@ function parseGraphicFrame(gf, rels, slidePath, archive, colorResolver, fontSche
|
|
|
3723
3750
|
if (!tableData) return null;
|
|
3724
3751
|
return { type: "table", transform, table: tableData };
|
|
3725
3752
|
}
|
|
3726
|
-
if (graphicData["@_uri"]
|
|
3753
|
+
if (SMARTART_DIAGRAM_URIS.has(graphicData["@_uri"])) {
|
|
3727
3754
|
return parseSmartArt(
|
|
3728
3755
|
graphicData,
|
|
3729
3756
|
transform,
|
|
@@ -8475,10 +8502,23 @@ function computePathLineX(alignment, textStartX, effectiveTextWidth, width, marg
|
|
|
8475
8502
|
return textStartX;
|
|
8476
8503
|
}
|
|
8477
8504
|
}
|
|
8478
|
-
function measureLineWidth(segments, defaultFontSize, fontScale) {
|
|
8505
|
+
function measureLineWidth(segments, defaultFontSize, fontScale, fontResolver) {
|
|
8479
8506
|
let totalWidth = 0;
|
|
8507
|
+
const jpanFallback = fontResolver ? getJpanFallbackFont() : null;
|
|
8480
8508
|
for (const seg of segments) {
|
|
8481
8509
|
const fontSize = (seg.properties.fontSize ?? defaultFontSize) * fontScale;
|
|
8510
|
+
if (fontResolver) {
|
|
8511
|
+
const fontSizePx = fontSize * PX_PER_PT3;
|
|
8512
|
+
const font = fontResolver.resolveFont(
|
|
8513
|
+
seg.properties.fontFamily,
|
|
8514
|
+
seg.properties.fontFamilyEa,
|
|
8515
|
+
jpanFallback
|
|
8516
|
+
);
|
|
8517
|
+
if (font) {
|
|
8518
|
+
totalWidth += font.getAdvanceWidth(seg.text, fontSizePx);
|
|
8519
|
+
continue;
|
|
8520
|
+
}
|
|
8521
|
+
}
|
|
8482
8522
|
totalWidth += getTextMeasurer().measureTextWidth(
|
|
8483
8523
|
seg.text,
|
|
8484
8524
|
fontSize,
|
|
@@ -8534,7 +8574,7 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
|
|
|
8534
8574
|
const processSegment = (segText, fontFamily, fontFamilyEa) => {
|
|
8535
8575
|
if (segText.length === 0) return;
|
|
8536
8576
|
const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
|
|
8537
|
-
const segWidth = getTextMeasurer().measureTextWidth(
|
|
8577
|
+
const segWidth = font ? font.getAdvanceWidth(segText, fontSizePx) : getTextMeasurer().measureTextWidth(
|
|
8538
8578
|
segText,
|
|
8539
8579
|
fontSize,
|
|
8540
8580
|
props.bold,
|
|
@@ -8559,7 +8599,7 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
|
|
|
8559
8599
|
const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
|
|
8560
8600
|
const fillAttrs = buildPathFillAttrs(props);
|
|
8561
8601
|
for (const char of segText) {
|
|
8562
|
-
const charWidth = getTextMeasurer().measureTextWidth(
|
|
8602
|
+
const charWidth = font ? font.getAdvanceWidth(char, fontSizePx) : getTextMeasurer().measureTextWidth(
|
|
8563
8603
|
char,
|
|
8564
8604
|
fontSize,
|
|
8565
8605
|
props.bold,
|
|
@@ -8731,7 +8771,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
8731
8771
|
if (!isFirstLine) {
|
|
8732
8772
|
currentY += lineNaturalHeightPt * PX_PER_PT3 * getLineSpacing(para, lnSpcReduction) + lineGapPx;
|
|
8733
8773
|
}
|
|
8734
|
-
const lineWidth = measureLineWidth(line.segments, defaultFontSize, fontScale);
|
|
8774
|
+
const lineWidth = measureLineWidth(line.segments, defaultFontSize, fontScale, fontResolver);
|
|
8735
8775
|
const lineStartX = computePathLineX(
|
|
8736
8776
|
para.properties.alignment,
|
|
8737
8777
|
textStartX,
|
|
@@ -8780,7 +8820,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
8780
8820
|
currentY += naturalHeightPt * PX_PER_PT3 * getLineSpacing(para, lnSpcReduction) + paragraphGapPx;
|
|
8781
8821
|
}
|
|
8782
8822
|
const runsAsSegments = para.runs.filter((r) => r.text.length > 0).map((r) => ({ text: r.text, properties: r.properties }));
|
|
8783
|
-
const lineWidth = measureLineWidth(runsAsSegments, defaultFontSize, fontScale);
|
|
8823
|
+
const lineWidth = measureLineWidth(runsAsSegments, defaultFontSize, fontScale, fontResolver);
|
|
8784
8824
|
const lineStartX = computePathLineX(
|
|
8785
8825
|
para.properties.alignment,
|
|
8786
8826
|
textStartX,
|
package/dist/index.d.cts
CHANGED
|
@@ -151,6 +151,7 @@ interface OpentypeFullFont {
|
|
|
151
151
|
ascender: number;
|
|
152
152
|
descender: number;
|
|
153
153
|
getPath(text: string, x: number, y: number, fontSize: number): OpentypePath;
|
|
154
|
+
getAdvanceWidth(text: string, fontSize: number): number;
|
|
154
155
|
}
|
|
155
156
|
interface TextPathFontResolver {
|
|
156
157
|
resolveFont(fontFamily: string | null | undefined, fontFamilyEa: string | null | undefined, jpanFallback?: string | null): OpentypeFullFont | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ interface OpentypeFullFont {
|
|
|
151
151
|
ascender: number;
|
|
152
152
|
descender: number;
|
|
153
153
|
getPath(text: string, x: number, y: number, fontSize: number): OpentypePath;
|
|
154
|
+
getAdvanceWidth(text: string, fontSize: number): number;
|
|
154
155
|
}
|
|
155
156
|
interface TextPathFontResolver {
|
|
156
157
|
resolveFont(fontFamily: string | null | undefined, fontFamilyEa: string | null | undefined, jpanFallback?: string | null): OpentypeFullFont | null;
|
package/dist/index.js
CHANGED
|
@@ -1924,25 +1924,48 @@ var LazyMediaMap = class {
|
|
|
1924
1924
|
return data;
|
|
1925
1925
|
}
|
|
1926
1926
|
};
|
|
1927
|
+
var LazyXmlMap = class {
|
|
1928
|
+
rawInput;
|
|
1929
|
+
cache = /* @__PURE__ */ new Map();
|
|
1930
|
+
entryIndex;
|
|
1931
|
+
constructor(rawInput, xmlEntryNames) {
|
|
1932
|
+
this.rawInput = rawInput;
|
|
1933
|
+
this.entryIndex = xmlEntryNames;
|
|
1934
|
+
}
|
|
1935
|
+
has(path) {
|
|
1936
|
+
return this.entryIndex.has(path);
|
|
1937
|
+
}
|
|
1938
|
+
get(path) {
|
|
1939
|
+
if (!this.entryIndex.has(path)) return void 0;
|
|
1940
|
+
const cached = this.cache.get(path);
|
|
1941
|
+
if (cached !== void 0) return cached;
|
|
1942
|
+
const result = unzipSync(this.rawInput, {
|
|
1943
|
+
filter: (file) => file.name === path
|
|
1944
|
+
});
|
|
1945
|
+
const data = result[path];
|
|
1946
|
+
if (data) {
|
|
1947
|
+
const str = strFromU8(data);
|
|
1948
|
+
this.cache.set(path, str);
|
|
1949
|
+
return str;
|
|
1950
|
+
}
|
|
1951
|
+
return void 0;
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1927
1954
|
function readPptx(input) {
|
|
1928
1955
|
const rawInput = new Uint8Array(input);
|
|
1956
|
+
const xmlEntryNames = /* @__PURE__ */ new Set();
|
|
1929
1957
|
const mediaEntryNames = /* @__PURE__ */ new Set();
|
|
1930
|
-
|
|
1958
|
+
unzipSync(rawInput, {
|
|
1931
1959
|
filter: (file) => {
|
|
1932
1960
|
if (file.name.startsWith("ppt/media/")) {
|
|
1933
1961
|
mediaEntryNames.add(file.name);
|
|
1934
|
-
|
|
1962
|
+
} else if (file.name.endsWith(".xml") || file.name.endsWith(".rels") || file.name === "[Content_Types].xml") {
|
|
1963
|
+
xmlEntryNames.add(file.name);
|
|
1935
1964
|
}
|
|
1936
|
-
return
|
|
1965
|
+
return false;
|
|
1937
1966
|
}
|
|
1938
1967
|
});
|
|
1939
|
-
const files =
|
|
1940
|
-
for (const [relativePath, data] of Object.entries(unzipped)) {
|
|
1941
|
-
if (relativePath.endsWith("/")) continue;
|
|
1942
|
-
if (relativePath.endsWith(".xml") || relativePath.endsWith(".rels") || relativePath === "[Content_Types].xml") {
|
|
1943
|
-
files.set(relativePath, strFromU8(data));
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1968
|
+
const files = new LazyXmlMap(rawInput, xmlEntryNames);
|
|
1946
1969
|
const media = new LazyMediaMap(rawInput, mediaEntryNames);
|
|
1947
1970
|
return { files, media };
|
|
1948
1971
|
}
|
|
@@ -3138,6 +3161,10 @@ function createDefaultBorders() {
|
|
|
3138
3161
|
|
|
3139
3162
|
// src/parser/slide-parser.ts
|
|
3140
3163
|
var SHAPE_TAGS = /* @__PURE__ */ new Set(["sp", "pic", "cxnSp", "grpSp", "graphicFrame"]);
|
|
3164
|
+
var SMARTART_DIAGRAM_URIS = /* @__PURE__ */ new Set([
|
|
3165
|
+
"http://schemas.openxmlformats.org/drawingml/2006/diagram",
|
|
3166
|
+
"http://purl.oclc.org/ooxml/drawingml/diagram"
|
|
3167
|
+
]);
|
|
3141
3168
|
function navigateOrdered(ordered, path) {
|
|
3142
3169
|
let current = ordered;
|
|
3143
3170
|
for (const key of path) {
|
|
@@ -3685,7 +3712,7 @@ function parseGraphicFrame(gf, rels, slidePath, archive, colorResolver, fontSche
|
|
|
3685
3712
|
if (!tableData) return null;
|
|
3686
3713
|
return { type: "table", transform, table: tableData };
|
|
3687
3714
|
}
|
|
3688
|
-
if (graphicData["@_uri"]
|
|
3715
|
+
if (SMARTART_DIAGRAM_URIS.has(graphicData["@_uri"])) {
|
|
3689
3716
|
return parseSmartArt(
|
|
3690
3717
|
graphicData,
|
|
3691
3718
|
transform,
|
|
@@ -8437,10 +8464,23 @@ function computePathLineX(alignment, textStartX, effectiveTextWidth, width, marg
|
|
|
8437
8464
|
return textStartX;
|
|
8438
8465
|
}
|
|
8439
8466
|
}
|
|
8440
|
-
function measureLineWidth(segments, defaultFontSize, fontScale) {
|
|
8467
|
+
function measureLineWidth(segments, defaultFontSize, fontScale, fontResolver) {
|
|
8441
8468
|
let totalWidth = 0;
|
|
8469
|
+
const jpanFallback = fontResolver ? getJpanFallbackFont() : null;
|
|
8442
8470
|
for (const seg of segments) {
|
|
8443
8471
|
const fontSize = (seg.properties.fontSize ?? defaultFontSize) * fontScale;
|
|
8472
|
+
if (fontResolver) {
|
|
8473
|
+
const fontSizePx = fontSize * PX_PER_PT3;
|
|
8474
|
+
const font = fontResolver.resolveFont(
|
|
8475
|
+
seg.properties.fontFamily,
|
|
8476
|
+
seg.properties.fontFamilyEa,
|
|
8477
|
+
jpanFallback
|
|
8478
|
+
);
|
|
8479
|
+
if (font) {
|
|
8480
|
+
totalWidth += font.getAdvanceWidth(seg.text, fontSizePx);
|
|
8481
|
+
continue;
|
|
8482
|
+
}
|
|
8483
|
+
}
|
|
8444
8484
|
totalWidth += getTextMeasurer().measureTextWidth(
|
|
8445
8485
|
seg.text,
|
|
8446
8486
|
fontSize,
|
|
@@ -8496,7 +8536,7 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
|
|
|
8496
8536
|
const processSegment = (segText, fontFamily, fontFamilyEa) => {
|
|
8497
8537
|
if (segText.length === 0) return;
|
|
8498
8538
|
const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
|
|
8499
|
-
const segWidth = getTextMeasurer().measureTextWidth(
|
|
8539
|
+
const segWidth = font ? font.getAdvanceWidth(segText, fontSizePx) : getTextMeasurer().measureTextWidth(
|
|
8500
8540
|
segText,
|
|
8501
8541
|
fontSize,
|
|
8502
8542
|
props.bold,
|
|
@@ -8521,7 +8561,7 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
|
|
|
8521
8561
|
const font = fontResolver.resolveFont(fontFamily, fontFamilyEa, jpanFallback);
|
|
8522
8562
|
const fillAttrs = buildPathFillAttrs(props);
|
|
8523
8563
|
for (const char of segText) {
|
|
8524
|
-
const charWidth = getTextMeasurer().measureTextWidth(
|
|
8564
|
+
const charWidth = font ? font.getAdvanceWidth(char, fontSizePx) : getTextMeasurer().measureTextWidth(
|
|
8525
8565
|
char,
|
|
8526
8566
|
fontSize,
|
|
8527
8567
|
props.bold,
|
|
@@ -8693,7 +8733,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
8693
8733
|
if (!isFirstLine) {
|
|
8694
8734
|
currentY += lineNaturalHeightPt * PX_PER_PT3 * getLineSpacing(para, lnSpcReduction) + lineGapPx;
|
|
8695
8735
|
}
|
|
8696
|
-
const lineWidth = measureLineWidth(line.segments, defaultFontSize, fontScale);
|
|
8736
|
+
const lineWidth = measureLineWidth(line.segments, defaultFontSize, fontScale, fontResolver);
|
|
8697
8737
|
const lineStartX = computePathLineX(
|
|
8698
8738
|
para.properties.alignment,
|
|
8699
8739
|
textStartX,
|
|
@@ -8742,7 +8782,7 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
8742
8782
|
currentY += naturalHeightPt * PX_PER_PT3 * getLineSpacing(para, lnSpcReduction) + paragraphGapPx;
|
|
8743
8783
|
}
|
|
8744
8784
|
const runsAsSegments = para.runs.filter((r) => r.text.length > 0).map((r) => ({ text: r.text, properties: r.properties }));
|
|
8745
|
-
const lineWidth = measureLineWidth(runsAsSegments, defaultFontSize, fontScale);
|
|
8785
|
+
const lineWidth = measureLineWidth(runsAsSegments, defaultFontSize, fontScale, fontResolver);
|
|
8746
8786
|
const lineStartX = computePathLineX(
|
|
8747
8787
|
para.properties.alignment,
|
|
8748
8788
|
textStartX,
|
package/package.json
CHANGED