Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f8a797b7a | ||
|
|
ca1e4dfa72 |
+89
-4
@@ -158,7 +158,7 @@ async function main() {
|
|||||||
// DashiAI format: .ppt-deck > .ppt-slide
|
// DashiAI format: .ppt-deck > .ppt-slide
|
||||||
var deck = document.querySelector('.ppt-deck');
|
var deck = document.querySelector('.ppt-deck');
|
||||||
if (deck) {
|
if (deck) {
|
||||||
slides = deck.querySelectorAll('.ppt-slide');
|
slides = deck.querySelectorAll(':scope > .ppt-slide');
|
||||||
}
|
}
|
||||||
if (!slides || slides.length <= 1) {
|
if (!slides || slides.length <= 1) {
|
||||||
slides = document.querySelectorAll(
|
slides = document.querySelectorAll(
|
||||||
@@ -170,9 +170,37 @@ async function main() {
|
|||||||
}
|
}
|
||||||
slides = Array.from(slides).filter(function (s) {
|
slides = Array.from(slides).filter(function (s) {
|
||||||
var r = s.getBoundingClientRect();
|
var r = s.getBoundingClientRect();
|
||||||
return r.width > 0 && r.height > 0;
|
var style = window.getComputedStyle(s);
|
||||||
|
return r.width > 0 && r.height > 0 &&
|
||||||
|
style.opacity !== '0' &&
|
||||||
|
style.display !== 'none' &&
|
||||||
|
style.visibility !== 'hidden';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Recursively extract inline text runs with computed styles
|
||||||
|
function extractRuns(node) {
|
||||||
|
var runs = [];
|
||||||
|
for (var ri = 0; ri < node.childNodes.length; ri++) {
|
||||||
|
var child = node.childNodes[ri];
|
||||||
|
if (child.nodeType === 3) {
|
||||||
|
var t = (child.textContent || '').trim();
|
||||||
|
if (t) runs.push({ text: t });
|
||||||
|
} else if (child.nodeType === 1) {
|
||||||
|
var cs = window.getComputedStyle(child);
|
||||||
|
var childRuns = extractRuns(child);
|
||||||
|
for (var cj = 0; cj < childRuns.length; cj++) {
|
||||||
|
childRuns[cj].bold = childRuns[cj].bold || parseInt(cs.fontWeight) >= 600;
|
||||||
|
childRuns[cj].italic = childRuns[cj].italic || cs.fontStyle === 'italic';
|
||||||
|
childRuns[cj].color = childRuns[cj].color || cs.color;
|
||||||
|
childRuns[cj].fontSize = childRuns[cj].fontSize || parseFloat(cs.fontSize);
|
||||||
|
childRuns[cj].fontFamily = childRuns[cj].fontFamily || cs.fontFamily;
|
||||||
|
}
|
||||||
|
runs = runs.concat(childRuns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return runs.length > 0 ? runs : [{ text: node.textContent || '' }];
|
||||||
|
}
|
||||||
|
|
||||||
// Tags whose full text content should be a single text box
|
// Tags whose full text content should be a single text box
|
||||||
var TEXT_BLOCK_TAGS = new Set([
|
var TEXT_BLOCK_TAGS = new Set([
|
||||||
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||||
@@ -203,7 +231,9 @@ async function main() {
|
|||||||
}
|
}
|
||||||
if (skip) continue;
|
if (skip) continue;
|
||||||
|
|
||||||
var text = (el.textContent || '').trim();
|
var runs = extractRuns(el);
|
||||||
|
if (!runs || runs.length === 0) continue;
|
||||||
|
var text = runs.map(function (r) { return r.text || ''; }).join(' ').trim();
|
||||||
if (!text) continue;
|
if (!text) continue;
|
||||||
|
|
||||||
var rect = el.getBoundingClientRect();
|
var rect = el.getBoundingClientRect();
|
||||||
@@ -211,7 +241,13 @@ async function main() {
|
|||||||
|
|
||||||
var style = window.getComputedStyle(el);
|
var style = window.getComputedStyle(el);
|
||||||
|
|
||||||
|
// Truncate overly long runs
|
||||||
|
runs.forEach(function (r) {
|
||||||
|
if (r.text && r.text.length > 2000) r.text = r.text.substring(0, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
elements.push({
|
elements.push({
|
||||||
|
runs: runs,
|
||||||
text: text.substring(0, 2000),
|
text: text.substring(0, 2000),
|
||||||
x: rect.left - slideRect.left,
|
x: rect.left - slideRect.left,
|
||||||
y: rect.top - slideRect.top,
|
y: rect.top - slideRect.top,
|
||||||
@@ -281,10 +317,58 @@ async function main() {
|
|||||||
var w = Math.max(el.width * scaleX, 0.3);
|
var w = Math.max(el.width * scaleX, 0.3);
|
||||||
var h = Math.max(el.height * scaleY, 0.2);
|
var h = Math.max(el.height * scaleY, 0.2);
|
||||||
|
|
||||||
// Font size: CSS px → pt (1pt = 1/72in, CSS 1px = 1/96in, so px × 72/96 = pt)
|
// Bounds constraints: prevent textbox from overflowing slide
|
||||||
|
var MAX_W = 10 - x;
|
||||||
|
var MAX_H = 5.625 - y;
|
||||||
|
w = Math.min(w, MAX_W);
|
||||||
|
h = Math.min(h, MAX_H);
|
||||||
|
|
||||||
|
// Base font size: CSS px → pt (1pt = 1/72in, CSS 1px = 1/96in)
|
||||||
var fontSize = el.fontSize * 72 / 96;
|
var fontSize = el.fontSize * 72 / 96;
|
||||||
fontSize = Math.max(fontSize, 8);
|
fontSize = Math.max(fontSize, 8);
|
||||||
|
|
||||||
|
// Check if rich text is needed (runs with differing styles)
|
||||||
|
var hasRuns = el.runs && el.runs.length > 0;
|
||||||
|
var isSimpleRun = hasRuns && el.runs.length === 1 &&
|
||||||
|
el.runs[0].bold === undefined &&
|
||||||
|
el.runs[0].italic === undefined &&
|
||||||
|
el.runs[0].color === undefined &&
|
||||||
|
el.runs[0].fontSize === undefined &&
|
||||||
|
el.runs[0].fontFamily === undefined;
|
||||||
|
|
||||||
|
if (hasRuns && !isSimpleRun && el.runs.length > 1) {
|
||||||
|
// Rich text: render each run with its own style
|
||||||
|
var pptxRuns = el.runs.map(function (run) {
|
||||||
|
if (!run.text || !run.text.trim()) return null;
|
||||||
|
var baseSize = el.fontSize * 72 / 96;
|
||||||
|
return {
|
||||||
|
text: run.text,
|
||||||
|
options: {
|
||||||
|
fontSize: run.fontSize ? Math.max(run.fontSize * 72 / 96, 8) : baseSize,
|
||||||
|
bold: run.bold === true || (run.bold === undefined && parseFontWeight(el.fontWeight)),
|
||||||
|
italic: run.italic === true || (run.italic === undefined && (el.fontStyle === 'italic' || el.fontStyle === 'oblique')),
|
||||||
|
color: run.color ? parseCSSColor(run.color, '#000000') : parseCSSColor(el.color, '#000000'),
|
||||||
|
fontFace: run.fontFamily
|
||||||
|
? run.fontFamily.split(',')[0].trim().replace(/['"]/g, '')
|
||||||
|
: (el.fontFamily || 'Arial').split(',')[0].trim().replace(/['"]/g, ''),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}).filter(Boolean);
|
||||||
|
|
||||||
|
if (pptxRuns.length > 0) {
|
||||||
|
slide.addText(pptxRuns, {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
w: w,
|
||||||
|
h: h,
|
||||||
|
align: normalizeAlign(el.textAlign),
|
||||||
|
valign: 'top',
|
||||||
|
wrap: true,
|
||||||
|
margin: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Plain text: original single-style logic
|
||||||
slide.addText(t, {
|
slide.addText(t, {
|
||||||
x: x,
|
x: x,
|
||||||
y: y,
|
y: y,
|
||||||
@@ -300,6 +384,7 @@ async function main() {
|
|||||||
wrap: true,
|
wrap: true,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Skip individual element failure
|
// Skip individual element failure
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user