feat(export): themable PDF/Word exports; Windows CI green (v4.7.1)

Export themes:
- Six presets in the export dialog (basic + advanced modes) for PDF/DOCX:
  Default, Modern, Classic, Sepia, Minimal, Elegant
- PDF: LaTeX header (xcolor/titlesec) recolors headings, adds section
  rules and colored links — core-TeX packages only, hex-literal only
  (no injection surface)
- DOCX: styles.xml surgery recolors Heading1-6/Title/Subtitle/Hyperlink
  and swaps heading/body fonts; verified end-to-end against a real
  pandoc-produced docx
- Themes ride along in export presets (unknown ids fall back to Default)

Windows CI fixes:
- pdfjs standardFontDataUrl now a file:// URL (backslash paths failed
  pdfjs's trailing-slash validation, breaking extractText/extractImages)
- sharp temp cleanup EPERM retries; path-separator assertions; pdfjs
  test timeouts raised; batch suite testTimeout 30s

648/648 tests green; 4.7.1 linux+win artifacts rebuilt.
This commit is contained in:
2026-09-05 23:59:53 +05:30
parent 1b2ab7b55c
commit a2455c3f8a
12 changed files with 590 additions and 35 deletions
+26
View File
@@ -2964,6 +2964,26 @@ function initializeExportForm(format) {
document.getElementById('custom-geometry').style.display = 'none';
}
// Export theme picker: shown for the formats that support theming; options
// come straight from the shared theme definitions (labels + descriptions)
const themeRow = document.getElementById('export-theme-row');
const themeSelect = document.getElementById('export-theme');
if (themeRow && themeSelect) {
const themeable = format === 'pdf' || format === 'docx';
themeRow.style.display = themeable ? 'flex' : 'none';
if (themeSelect.options.length === 0) {
const { listThemes } = require('./main/ExportThemes');
for (const theme of listThemes()) {
const option = document.createElement('option');
option.value = theme.id;
option.textContent = theme.label;
option.title = theme.description;
themeSelect.appendChild(option);
}
}
themeSelect.value = 'default';
}
// Toggle and reset Reveal.js-specific fields
const revealjsOnly = document.querySelector('.revealjs-only');
if (revealjsOnly) {
@@ -3076,6 +3096,12 @@ function collectExportOptions() {
}
}
// Export theme is available in basic mode too (PDF + DOCX)
const themeSelect = document.getElementById('export-theme');
if (themeSelect && (currentExportFormat === 'pdf' || currentExportFormat === 'docx')) {
options.theme = themeSelect.value || 'default';
}
// Collect page size and orientation (always collected, from basic options)
const pageSize = document.getElementById('page-size').value;
const pageOrientation = document.getElementById('page-orientation').value;