@taloswork/ose-shared 0.1.6 → 0.1.7
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 +3 -3
- package/skills/document/SKILL.md +32 -17
- package/skills/document/art-directions/base.css +23 -0
- package/skills/document/art-directions/cinematic-depth.css +6 -0
- package/skills/document/art-directions/collage-paper.css +8 -0
- package/skills/document/art-directions/editorial-cut.css +8 -0
- package/skills/document/art-directions/geometric-pop.css +9 -0
- package/skills/document/art-directions/gradient-mesh.css +6 -0
- package/skills/document/art-directions/illustrated-doodle.css +8 -0
- package/skills/document/art-directions/luxury-ornament.css +6 -0
- package/skills/document/art-directions/maximalist-blocks.css +9 -0
- package/skills/document/art-directions/technical-grid.css +6 -0
- package/skills/document/assets/fonts/fonts.json +2 -2
- package/skills/document/bin/deck-build.cjs +266 -10
- package/skills/document/bin/doc-convert.cjs +66 -28
- package/skills/document/bin/doc-gen.cjs +6 -4
- package/skills/document/bin/html2pptx.cjs +231 -20
- package/skills/document/catalog.json +11 -0
- package/skills/document/components/base.css +45 -0
- package/skills/document/components/profiles/clean.css +2 -0
- package/skills/document/components/profiles/editorial.css +3 -0
- package/skills/document/components/profiles/glass.css +2 -0
- package/skills/document/components/profiles/luxury.css +3 -0
- package/skills/document/components/profiles/organic.css +2 -0
- package/skills/document/components/profiles/poster.css +3 -0
- package/skills/document/content-pipeline.md +55 -48
- package/skills/document/deck-design.md +24 -15
- package/skills/document/layouts/README.md +33 -12
- package/skills/document/layouts/business-model.tpl +6 -0
- package/skills/document/layouts/customer-proof.tpl +6 -0
- package/skills/document/layouts/funding-ask.tpl +5 -0
- package/skills/document/layouts/market-rings.tpl +5 -0
- package/skills/document/layouts/pitch-problem.tpl +6 -0
- package/skills/document/layouts/pitch-solution.tpl +5 -0
- package/skills/document/layouts/pricing-tiers.tpl +5 -0
- package/skills/document/layouts/product-device.tpl +6 -0
- package/skills/document/layouts/profiles.json +24 -0
- package/skills/document/layouts/slots.json +1 -1
- package/skills/document/layouts/team-founders.tpl +5 -0
- package/skills/document/layouts/traction-milestones.tpl +6 -0
- package/skills/document/media-styles/cinematic.css +2 -0
- package/skills/document/media-styles/clean-product.css +2 -0
- package/skills/document/media-styles/cutout-collage.css +3 -0
- package/skills/document/media-styles/device-stage.css +3 -0
- package/skills/document/media-styles/editorial-photo.css +3 -0
- package/skills/document/media-styles/illustrated.css +2 -0
- package/skills/document/media-styles/spatial-3d.css +3 -0
- package/skills/document/motion/mckinsey-photo.json +22 -0
- package/skills/document/motion/prismatic-3d.json +31 -0
- package/skills/document/packs/README.md +7 -3
- package/skills/document/packs/mckinsey-photo/backdrop.html +6 -0
- package/skills/document/packs/mckinsey-photo/layouts/cover-image.tpl +5 -0
- package/skills/document/packs/mckinsey-photo/layouts/cover.tpl +5 -0
- package/skills/document/packs/mckinsey-photo/layouts/image-left.tpl +5 -0
- package/skills/document/packs/mckinsey-photo/layouts/numbered-brief.tpl +5 -0
- package/skills/document/packs/mckinsey-photo/pack.css +27 -0
- package/skills/document/packs/prismatic-3d/backdrop.html +4 -0
- package/skills/document/packs/prismatic-3d/layouts/big-stat.tpl +6 -0
- package/skills/document/packs/prismatic-3d/layouts/cover.tpl +9 -0
- package/skills/document/packs/prismatic-3d/layouts/section-image.tpl +6 -0
- package/skills/document/packs/prismatic-3d/pack.css +28 -0
- package/skills/document/recipes/agency-pitch.json +13 -0
- package/skills/document/recipes/product-launch.json +13 -0
- package/skills/document/recipes/startup-fundraising.json +19 -0
- package/skills/document/styles/README.md +13 -6
- package/skills/document/styles/_contract-defaults.css +1 -1
- package/skills/document/styles/_samples/_groups/biz-premium.webp +0 -0
- package/skills/document/styles/_samples/_groups/creative.webp +0 -0
- package/skills/document/styles/_samples/_groups/editorial.webp +0 -0
- package/skills/document/styles/_samples/_groups/minimal.webp +0 -0
- package/skills/document/styles/_samples/_groups/natural.webp +0 -0
- package/skills/document/styles/_samples/_groups/tech-future.webp +0 -0
- package/skills/document/styles/_samples/bistro-warm.webp +0 -0
- package/skills/document/styles/_samples/board-brief.webp +0 -0
- package/skills/document/styles/_samples/bold-clash.webp +0 -0
- package/skills/document/styles/_samples/campus-teal.webp +0 -0
- package/skills/document/styles/_samples/clinic-care.webp +0 -0
- package/skills/document/styles/_samples/dark-glass.webp +0 -0
- package/skills/document/styles/_samples/gov-brief.webp +0 -0
- package/skills/document/styles/_samples/grid-tech.webp +0 -0
- package/skills/document/styles/_samples/legal-slate.webp +0 -0
- package/skills/document/styles/_samples/mckinsey-photo.webp +0 -0
- package/skills/document/styles/_samples/memphis.webp +0 -0
- package/skills/document/styles/_samples/neon-cyber.webp +0 -0
- package/skills/document/styles/_samples/organic-earth.webp +0 -0
- package/skills/document/styles/_samples/pastel-saas.webp +0 -0
- package/skills/document/styles/_samples/portfolio-noir.webp +0 -0
- package/skills/document/styles/_samples/press-room.webp +0 -0
- package/skills/document/styles/_samples/prismatic-3d.webp +0 -0
- package/skills/document/styles/_samples/retro-press.webp +0 -0
- package/skills/document/styles/_samples/sport-arena.webp +0 -0
- package/skills/document/styles/_samples/wedding-blush.webp +0 -0
- package/skills/document/styles/dark-glass/backdrop.html +7 -3
- package/skills/document/styles/dark-glass/skin.css +1 -0
- package/skills/document/styles/portfolio-noir/skin.css +3 -0
- package/skills/document/theme-system.json +68 -0
- package/skills/document/theme-system.md +101 -0
|
@@ -159,12 +159,61 @@ function derivePins(rows, warnings) {
|
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
+
// packages/core/dist/document/html-escape.js
|
|
163
|
+
function escapeHtml(value) {
|
|
164
|
+
return String(value).replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
165
|
+
}
|
|
166
|
+
|
|
162
167
|
// packages/core/dist/document/deck-build.js
|
|
168
|
+
var SCENES = /* @__PURE__ */ new Set(["hero", "content", "data", "media", "closing"]);
|
|
169
|
+
var DECOR_DENSITIES = /* @__PURE__ */ new Set(["low", "medium", "high"]);
|
|
170
|
+
var SCENE_VARIANTS = ["a", "b", "c"];
|
|
171
|
+
var DEFAULT_SCENE_DENSITY = {
|
|
172
|
+
hero: "high",
|
|
173
|
+
content: "low",
|
|
174
|
+
data: "medium",
|
|
175
|
+
media: "medium",
|
|
176
|
+
closing: "high"
|
|
177
|
+
};
|
|
178
|
+
function planDeckVisualRhythm(slides, profiles = {}, rhythm = "auto") {
|
|
179
|
+
const errors = [];
|
|
180
|
+
const sceneCounts = /* @__PURE__ */ new Map();
|
|
181
|
+
const planned = [];
|
|
182
|
+
const densities = [];
|
|
183
|
+
slides.forEach((slide, index) => {
|
|
184
|
+
const profile = slide.intent ? profiles[slide.intent] : void 0;
|
|
185
|
+
const scene = slide.scene ?? profile?.scene ?? "content";
|
|
186
|
+
if (!SCENES.has(scene)) {
|
|
187
|
+
errors.push(`slide ${index + 1}: invalid scene "${scene}"`);
|
|
188
|
+
planned.push(slide);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
let density = slide.decorDensity ?? profile?.decorDensity ?? DEFAULT_SCENE_DENSITY[scene];
|
|
192
|
+
if (!DECOR_DENSITIES.has(density)) {
|
|
193
|
+
errors.push(`slide ${index + 1}: invalid decorDensity "${density}"`);
|
|
194
|
+
planned.push(slide);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (rhythm === "auto" && slide.decorDensity === void 0) {
|
|
198
|
+
const prev = densities.at(-1);
|
|
199
|
+
const prev2 = densities.at(-2);
|
|
200
|
+
if (density === "high" && prev === "high" && scene !== "closing")
|
|
201
|
+
density = "medium";
|
|
202
|
+
else if (density === "medium" && prev === "medium" && prev2 === "medium")
|
|
203
|
+
density = "low";
|
|
204
|
+
else if (density === "low" && prev === "low")
|
|
205
|
+
density = "medium";
|
|
206
|
+
}
|
|
207
|
+
const occurrence = sceneCounts.get(scene) ?? 0;
|
|
208
|
+
sceneCounts.set(scene, occurrence + 1);
|
|
209
|
+
const sceneVariant = slide.sceneVariant ?? SCENE_VARIANTS[occurrence % SCENE_VARIANTS.length];
|
|
210
|
+
densities.push(density);
|
|
211
|
+
planned.push({ ...slide, scene, decorDensity: density, sceneVariant });
|
|
212
|
+
});
|
|
213
|
+
return { slides: planned, errors };
|
|
214
|
+
}
|
|
163
215
|
var SLOT_RE = /\{\{(?![#/])([^{}]*)\}\}/g;
|
|
164
216
|
var BLOCK_RE = /\{\{#([A-Za-z_][\w-]*)\}\}([\s\S]*?)\{\{\/\1\}\}/g;
|
|
165
|
-
function escapeHtml(s) {
|
|
166
|
-
return String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
167
|
-
}
|
|
168
217
|
var slotName = (inner) => {
|
|
169
218
|
const bar = inner.indexOf("|");
|
|
170
219
|
return (bar >= 0 ? inner.slice(0, bar) : inner).trim();
|
|
@@ -247,6 +296,11 @@ function injectCharts(html, chart, layout, problems) {
|
|
|
247
296
|
function stripLeadComment(tpl) {
|
|
248
297
|
return tpl.replace(/^\s*<!--[\s\S]*?-->\s*/, "");
|
|
249
298
|
}
|
|
299
|
+
function injectVisualScene(html, slide) {
|
|
300
|
+
if (!slide.scene || !slide.decorDensity || !slide.sceneVariant)
|
|
301
|
+
return html;
|
|
302
|
+
return html.replace(/<section\b/, `<section data-scene="${slide.scene}" data-decor-density="${slide.decorDensity}" data-scene-variant="${slide.sceneVariant}"`);
|
|
303
|
+
}
|
|
250
304
|
function assembleDeck(spec, readLayout) {
|
|
251
305
|
const problems = { warnings: [], errors: [] };
|
|
252
306
|
const sections = [];
|
|
@@ -279,6 +333,8 @@ function assembleDeck(spec, readLayout) {
|
|
|
279
333
|
const chart = figures.chart ?? slide.chart;
|
|
280
334
|
if (chart !== void 0 && !local.errors.length)
|
|
281
335
|
html = injectCharts(html, chart, where, local);
|
|
336
|
+
if (!local.errors.length)
|
|
337
|
+
html = injectVisualScene(html, slide);
|
|
282
338
|
problems.warnings.push(...local.warnings);
|
|
283
339
|
problems.errors.push(...local.errors);
|
|
284
340
|
if (!local.errors.length)
|
|
@@ -290,7 +346,9 @@ function assembleDeck(spec, readLayout) {
|
|
|
290
346
|
// packages/core/dist/document/deck-catalog.js
|
|
291
347
|
var KINDS = ["skin", "pack"];
|
|
292
348
|
var MODES = ["light", "dark"];
|
|
349
|
+
var RENDER_MODES = ["classic-v1", "theme-v2"];
|
|
293
350
|
var ID_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
351
|
+
var COMMIT_RE = /^[0-9a-f]{7,40}$/;
|
|
294
352
|
function isStr(v) {
|
|
295
353
|
return typeof v === "string" && v.length > 0;
|
|
296
354
|
}
|
|
@@ -320,6 +378,35 @@ function parseCatalog(raw) {
|
|
|
320
378
|
groups.push({ id: g.id, name_cn: g.name_cn, sample: g.sample, scenarios: g.scenarios });
|
|
321
379
|
}
|
|
322
380
|
});
|
|
381
|
+
const collections = [];
|
|
382
|
+
const rawCollections = o.collections === void 0 ? [] : Array.isArray(o.collections) ? o.collections : [];
|
|
383
|
+
if (o.collections !== void 0 && !Array.isArray(o.collections))
|
|
384
|
+
errors.push("catalog.collections must be an array when present");
|
|
385
|
+
rawCollections.forEach((c, i) => {
|
|
386
|
+
const at = `collection[${i}]`;
|
|
387
|
+
const before = errors.length;
|
|
388
|
+
if (!isStr(c?.id) || !ID_RE.test(c.id))
|
|
389
|
+
errors.push(`${at}: bad id`);
|
|
390
|
+
if (!isStr(c?.name_cn))
|
|
391
|
+
errors.push(`${at}: missing name_cn`);
|
|
392
|
+
if (!isStr(c?.renderMode) || !RENDER_MODES.includes(c.renderMode))
|
|
393
|
+
errors.push(`${at}: bad renderMode`);
|
|
394
|
+
if (!isStrArr(c?.entryIds) || c.entryIds.length === 0)
|
|
395
|
+
errors.push(`${at}: entryIds must be a non-empty string array`);
|
|
396
|
+
if (c?.sourceCommit !== void 0 && (!isStr(c.sourceCommit) || !COMMIT_RE.test(c.sourceCommit)))
|
|
397
|
+
errors.push(`${at}: bad sourceCommit`);
|
|
398
|
+
if (c?.renderMode === "classic-v1" && c?.sourceCommit === void 0)
|
|
399
|
+
errors.push(`${at}: classic-v1 requires sourceCommit`);
|
|
400
|
+
if (errors.length === before) {
|
|
401
|
+
collections.push({
|
|
402
|
+
id: c.id,
|
|
403
|
+
name_cn: c.name_cn,
|
|
404
|
+
renderMode: c.renderMode,
|
|
405
|
+
entryIds: c.entryIds,
|
|
406
|
+
...c.sourceCommit !== void 0 ? { sourceCommit: c.sourceCommit } : {}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
});
|
|
323
410
|
const entries = [];
|
|
324
411
|
const rawEntries = Array.isArray(o.entries) ? o.entries : [];
|
|
325
412
|
if (!Array.isArray(o.entries))
|
|
@@ -359,11 +446,116 @@ function parseCatalog(raw) {
|
|
|
359
446
|
});
|
|
360
447
|
}
|
|
361
448
|
});
|
|
362
|
-
return { catalog: errors.length ? null : { groups, entries }, errors };
|
|
449
|
+
return { catalog: errors.length ? null : { groups, ...collections.length ? { collections } : {}, entries }, errors };
|
|
363
450
|
}
|
|
364
451
|
function resolveEntry(catalog, id) {
|
|
365
452
|
return catalog.entries.find((e) => e.id === id) ?? null;
|
|
366
453
|
}
|
|
454
|
+
function renderModeOf(catalog, id) {
|
|
455
|
+
return catalog.collections?.find((c) => c.entryIds.includes(id))?.renderMode ?? "theme-v2";
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// packages/core/dist/shared/guards.js
|
|
459
|
+
function isRecord(value) {
|
|
460
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// packages/core/dist/document/deck-theme-system.js
|
|
464
|
+
var ID_RE2 = /^[a-z0-9][a-z0-9-]*$/;
|
|
465
|
+
var PATH_RE = /^[a-z0-9_./-]+\.css$/i;
|
|
466
|
+
function isSafeCssPath(v) {
|
|
467
|
+
return typeof v === "string" && PATH_RE.test(v) && !v.startsWith("/") && !v.includes("..");
|
|
468
|
+
}
|
|
469
|
+
function parsePathMap(value, at, errors) {
|
|
470
|
+
if (!isRecord(value)) {
|
|
471
|
+
errors.push(`${at} must be an object`);
|
|
472
|
+
return {};
|
|
473
|
+
}
|
|
474
|
+
const out = {};
|
|
475
|
+
for (const [id, path] of Object.entries(value)) {
|
|
476
|
+
if (!ID_RE2.test(id))
|
|
477
|
+
errors.push(`${at}.${id}: bad id`);
|
|
478
|
+
if (!isSafeCssPath(path)) {
|
|
479
|
+
errors.push(`${at}.${id}: must be a safe relative .css path`);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
out[id] = path;
|
|
483
|
+
}
|
|
484
|
+
return out;
|
|
485
|
+
}
|
|
486
|
+
function parseThemeSystem(raw) {
|
|
487
|
+
const errors = [];
|
|
488
|
+
if (!isRecord(raw))
|
|
489
|
+
return { system: null, errors: ["theme system is not an object"] };
|
|
490
|
+
if (raw.version !== 2)
|
|
491
|
+
errors.push("theme system version must be 2");
|
|
492
|
+
if (!isSafeCssPath(raw.componentBase)) {
|
|
493
|
+
errors.push("componentBase must be a safe relative .css path");
|
|
494
|
+
}
|
|
495
|
+
if (!isSafeCssPath(raw.artBase)) {
|
|
496
|
+
errors.push("artBase must be a safe relative .css path");
|
|
497
|
+
}
|
|
498
|
+
const componentProfiles = parsePathMap(raw.componentProfiles, "componentProfiles", errors);
|
|
499
|
+
const mediaStyles = parsePathMap(raw.mediaStyles, "mediaStyles", errors);
|
|
500
|
+
const artDirections = parsePathMap(raw.artDirections, "artDirections", errors);
|
|
501
|
+
const bindings = {};
|
|
502
|
+
if (!isRecord(raw.bindings))
|
|
503
|
+
errors.push("bindings must be an object");
|
|
504
|
+
else {
|
|
505
|
+
for (const [id, value] of Object.entries(raw.bindings)) {
|
|
506
|
+
const at = `bindings.${id}`;
|
|
507
|
+
if (!ID_RE2.test(id))
|
|
508
|
+
errors.push(`${at}: bad id`);
|
|
509
|
+
if (!isRecord(value)) {
|
|
510
|
+
errors.push(`${at} must be an object`);
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
const componentProfile = value.componentProfile;
|
|
514
|
+
const mediaStyle = value.mediaStyle;
|
|
515
|
+
const artDirection = value.artDirection;
|
|
516
|
+
if (typeof componentProfile !== "string" || !ID_RE2.test(componentProfile))
|
|
517
|
+
errors.push(`${at}: bad componentProfile`);
|
|
518
|
+
if (typeof mediaStyle !== "string" || !ID_RE2.test(mediaStyle))
|
|
519
|
+
errors.push(`${at}: bad mediaStyle`);
|
|
520
|
+
if (typeof artDirection !== "string" || !ID_RE2.test(artDirection))
|
|
521
|
+
errors.push(`${at}: bad artDirection`);
|
|
522
|
+
if (typeof componentProfile === "string" && typeof mediaStyle === "string" && typeof artDirection === "string") {
|
|
523
|
+
bindings[id] = { componentProfile, mediaStyle, artDirection };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (errors.length)
|
|
528
|
+
return { system: null, errors };
|
|
529
|
+
return {
|
|
530
|
+
system: {
|
|
531
|
+
version: 2,
|
|
532
|
+
componentBase: raw.componentBase,
|
|
533
|
+
artBase: raw.artBase,
|
|
534
|
+
componentProfiles,
|
|
535
|
+
mediaStyles,
|
|
536
|
+
artDirections,
|
|
537
|
+
bindings
|
|
538
|
+
},
|
|
539
|
+
errors
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
function resolveThemeLayers(system, styleId, mediaOverride) {
|
|
543
|
+
const binding = system.bindings[styleId];
|
|
544
|
+
if (!binding)
|
|
545
|
+
return null;
|
|
546
|
+
const mediaStyle = mediaOverride ?? binding.mediaStyle;
|
|
547
|
+
const componentPath = system.componentProfiles[binding.componentProfile];
|
|
548
|
+
const mediaPath = system.mediaStyles[mediaStyle];
|
|
549
|
+
const artPath = system.artDirections[binding.artDirection];
|
|
550
|
+
if (!componentPath || !mediaPath || !artPath)
|
|
551
|
+
return null;
|
|
552
|
+
return {
|
|
553
|
+
paths: [system.componentBase, componentPath, mediaPath, system.artBase, artPath],
|
|
554
|
+
componentProfile: binding.componentProfile,
|
|
555
|
+
mediaStyle,
|
|
556
|
+
artDirection: binding.artDirection
|
|
557
|
+
};
|
|
558
|
+
}
|
|
367
559
|
|
|
368
560
|
// packages/core/dist/document/deck-motion.js
|
|
369
561
|
var ANIM_EFFECTS = [
|
|
@@ -513,20 +705,61 @@ async function main() {
|
|
|
513
705
|
}
|
|
514
706
|
const skillDir = (0, import_node_path.dirname)((0, import_node_path.dirname)(process.argv[1] || ""));
|
|
515
707
|
const layoutsDir = (0, import_node_path.join)(skillDir, "layouts");
|
|
708
|
+
if (spec?.themeVersion !== void 0 && spec.themeVersion !== 2) die("themeVersion must be 2 when present", 64);
|
|
709
|
+
if (spec?.themeVersion === 2 && typeof spec?.style !== "string") die("themeVersion: 2 requires a catalog style id", 64);
|
|
710
|
+
if (spec?.mediaStyle !== void 0 && (spec.themeVersion !== 2 || typeof spec.mediaStyle !== "string")) {
|
|
711
|
+
die("mediaStyle must be a string and requires themeVersion: 2", 64);
|
|
712
|
+
}
|
|
713
|
+
if (spec?.layoutPack !== void 0 && typeof spec.layoutPack !== "string") die('layoutPack must be a pack id or "none"', 64);
|
|
714
|
+
if (spec?.decorRhythm !== void 0 && (spec.themeVersion !== 2 || !["auto", "steady"].includes(spec.decorRhythm))) {
|
|
715
|
+
die("decorRhythm must be auto|steady and requires themeVersion: 2", 64);
|
|
716
|
+
}
|
|
717
|
+
if (spec?.themeVersion !== 2 && Array.isArray(spec?.slides) && spec.slides.some((s) => s?.scene !== void 0 || s?.decorDensity !== void 0)) {
|
|
718
|
+
die("slide scene/decorDensity requires themeVersion: 2", 64);
|
|
719
|
+
}
|
|
516
720
|
let catalogEntry = null;
|
|
517
721
|
let packLayoutsDir = null;
|
|
518
722
|
const styleId = typeof spec?.style === "string" ? spec.style : null;
|
|
519
|
-
|
|
723
|
+
let catalog = null;
|
|
724
|
+
if (styleId || typeof spec?.layoutPack === "string" && spec.layoutPack !== "none") {
|
|
520
725
|
const catalogPath = (0, import_node_path.join)(skillDir, "catalog.json");
|
|
521
726
|
if ((0, import_node_fs.existsSync)(catalogPath)) {
|
|
522
727
|
try {
|
|
523
|
-
|
|
728
|
+
({ catalog } = parseCatalog(JSON.parse((0, import_node_fs.readFileSync)(catalogPath, "utf8"))));
|
|
524
729
|
catalogEntry = catalog ? resolveEntry(catalog, styleId) : null;
|
|
525
|
-
if (catalogEntry?.kind === "pack") packLayoutsDir = (0, import_node_path.join)(skillDir, "packs", catalogEntry.id, "layouts");
|
|
526
730
|
} catch {
|
|
527
731
|
}
|
|
528
732
|
}
|
|
529
733
|
}
|
|
734
|
+
let layoutPackEntry = null;
|
|
735
|
+
if (spec?.layoutPack === "none") {
|
|
736
|
+
layoutPackEntry = null;
|
|
737
|
+
} else if (typeof spec?.layoutPack === "string") {
|
|
738
|
+
layoutPackEntry = catalog ? resolveEntry(catalog, spec.layoutPack) : null;
|
|
739
|
+
if (!layoutPackEntry || layoutPackEntry.kind !== "pack") die(`layoutPack "${spec.layoutPack}" is not a registered pack`, 64);
|
|
740
|
+
} else if (catalogEntry?.kind === "pack") {
|
|
741
|
+
layoutPackEntry = catalogEntry;
|
|
742
|
+
process.stderr.write(`deck-build: legacy compatibility \u2014 style "${styleId}" implicitly enables layoutPack "${styleId}"; set layoutPack:"none" to use shared layouts only
|
|
743
|
+
`);
|
|
744
|
+
}
|
|
745
|
+
if (layoutPackEntry) packLayoutsDir = (0, import_node_path.join)(skillDir, "packs", layoutPackEntry.id, "layouts");
|
|
746
|
+
if (spec?.themeVersion === 2) {
|
|
747
|
+
if (!catalogEntry) die(`Theme V2 style "${styleId}" is not registered in catalog.json`, 64);
|
|
748
|
+
if (catalog && renderModeOf(catalog, catalogEntry.id) === "classic-v1") {
|
|
749
|
+
die(`style "${catalogEntry.id}" is frozen in collection "original-13" as classic-v1; omit themeVersion/mediaStyle/decorRhythm and use a V1 layout`, 64);
|
|
750
|
+
}
|
|
751
|
+
const registryPath = (0, import_node_path.join)(skillDir, "theme-system.json");
|
|
752
|
+
let parsed;
|
|
753
|
+
try {
|
|
754
|
+
parsed = parseThemeSystem(JSON.parse((0, import_node_fs.readFileSync)(registryPath, "utf8")));
|
|
755
|
+
} catch (e) {
|
|
756
|
+
die(`cannot read Theme V2 registry ${registryPath}: ${e.message}`, 66);
|
|
757
|
+
}
|
|
758
|
+
if (!parsed.system) die(`invalid Theme V2 registry: ${parsed.errors.join("; ")}`, 66);
|
|
759
|
+
if (!resolveThemeLayers(parsed.system, catalogEntry.id, spec.mediaStyle)) {
|
|
760
|
+
die(`Theme V2 cannot resolve style "${catalogEntry.id}"${spec.mediaStyle ? ` with media style "${spec.mediaStyle}"` : ""}`, 64);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
530
763
|
let fromPack = 0, fromShared = 0;
|
|
531
764
|
const readLayout = (id) => {
|
|
532
765
|
if (!/^[a-z0-9-]+$/i.test(id)) return null;
|
|
@@ -542,7 +775,30 @@ async function main() {
|
|
|
542
775
|
if (packLayoutsDir) fromShared++;
|
|
543
776
|
return (0, import_node_fs.readFileSync)(p, "utf8");
|
|
544
777
|
};
|
|
545
|
-
const
|
|
778
|
+
const profilesPath = (0, import_node_path.join)(layoutsDir, "profiles.json");
|
|
779
|
+
const profiles = (0, import_node_fs.existsSync)(profilesPath) ? JSON.parse((0, import_node_fs.readFileSync)(profilesPath, "utf8")) : null;
|
|
780
|
+
let buildSpec = spec;
|
|
781
|
+
let rhythmErrors = [];
|
|
782
|
+
if (spec?.themeVersion === 2 && Array.isArray(spec?.slides)) {
|
|
783
|
+
const planned = planDeckVisualRhythm(spec.slides, profiles?.intents ?? {}, spec.decorRhythm ?? "auto");
|
|
784
|
+
buildSpec = { ...spec, slides: planned.slides };
|
|
785
|
+
rhythmErrors = planned.errors;
|
|
786
|
+
}
|
|
787
|
+
const { html, warnings, errors } = assembleDeck(buildSpec, readLayout);
|
|
788
|
+
errors.push(...rhythmErrors);
|
|
789
|
+
if (profiles) {
|
|
790
|
+
for (const [i, slide] of (Array.isArray(spec?.slides) ? spec.slides : []).entries()) {
|
|
791
|
+
if (profiles.themeV2Layouts?.includes(slide?.layout) && spec?.themeVersion !== 2) {
|
|
792
|
+
errors.push(`slide ${i + 1} (${slide.layout}): this layout requires themeVersion: 2`);
|
|
793
|
+
}
|
|
794
|
+
if (slide?.intent === void 0) continue;
|
|
795
|
+
const profile = profiles?.intents?.[slide.intent];
|
|
796
|
+
if (!profile) errors.push(`slide ${i + 1}: unknown intent "${slide.intent}"`);
|
|
797
|
+
else if (!profile.candidates?.includes(slide.layout)) {
|
|
798
|
+
warnings.push(`slide ${i + 1} (${slide.layout}): intent "${slide.intent}" recommends ${profile.candidates.join(", ")}`);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
546
802
|
for (const w of warnings) process.stderr.write(`deck-build: ${w}
|
|
547
803
|
`);
|
|
548
804
|
if (errors.length) {
|
|
@@ -555,7 +811,7 @@ async function main() {
|
|
|
555
811
|
const ratio = fromShared / resolved;
|
|
556
812
|
if (ratio > 0.4) {
|
|
557
813
|
process.stderr.write(
|
|
558
|
-
`deck-build: pack-dilution \u2014 ${fromShared}/${resolved} \u9875\uFF08${Math.round(ratio * 100)}%\uFF09\u56DE\u843D\u5230\u5171\u4EAB\u7248\u5F0F\uFF0C\u8D85\u8FC7 40% \u9608\u503C\u3002\u5305 "${
|
|
814
|
+
`deck-build: pack-dilution \u2014 ${fromShared}/${resolved} \u9875\uFF08${Math.round(ratio * 100)}%\uFF09\u56DE\u843D\u5230\u5171\u4EAB\u7248\u5F0F\uFF0C\u8D85\u8FC7 40% \u9608\u503C\u3002\u7248\u5F0F\u5305 "${layoutPackEntry?.id}" \u7684\u9875\u9762\u6E05\u5355\u76F8\u5BF9\u672C\u6B21\u5185\u5BB9\u91CF\u504F\u8584\uFF0C\u8003\u8651\u6269\u5305\u6216\u4F7F\u7528\u5171\u4EAB\u7248\u5F0F\u3002
|
|
559
815
|
`
|
|
560
816
|
);
|
|
561
817
|
}
|
|
@@ -592,7 +848,7 @@ async function main() {
|
|
|
592
848
|
out: outPath,
|
|
593
849
|
slides: Array.isArray(spec?.slides) ? spec.slides.length : 0,
|
|
594
850
|
warnings,
|
|
595
|
-
next: `html2pptx ${outPath} out.pptx${styleId ? ` --style ${styleId}` : " --style <skin>"}`
|
|
851
|
+
next: `html2pptx ${outPath} out.pptx${styleId ? ` --style ${styleId}` : " --style <skin>"}${spec?.themeVersion === 2 ? " --theme-v2" : ""}${spec?.mediaStyle ? ` --media-style ${spec.mediaStyle}` : ""}`
|
|
596
852
|
}, null, 1) + "\n");
|
|
597
853
|
}
|
|
598
854
|
main().catch((e) => die(e.message, 1));
|
|
@@ -315,7 +315,7 @@ var require_BufferList = __commonJS({
|
|
|
315
315
|
this.head = this.tail = null;
|
|
316
316
|
this.length = 0;
|
|
317
317
|
};
|
|
318
|
-
BufferList.prototype.join = function
|
|
318
|
+
BufferList.prototype.join = function join3(s) {
|
|
319
319
|
if (this.length === 0) return "";
|
|
320
320
|
var p = this.head;
|
|
321
321
|
var ret2 = "" + p.data;
|
|
@@ -35136,7 +35136,7 @@ var require_buffer_list2 = __commonJS({
|
|
|
35136
35136
|
}
|
|
35137
35137
|
}, {
|
|
35138
35138
|
key: "join",
|
|
35139
|
-
value: function
|
|
35139
|
+
value: function join3(s) {
|
|
35140
35140
|
if (this.length === 0) return "";
|
|
35141
35141
|
var p = this.head;
|
|
35142
35142
|
var ret2 = "" + p.data;
|
|
@@ -57654,7 +57654,7 @@ var require_polyfills = __commonJS({
|
|
|
57654
57654
|
}
|
|
57655
57655
|
if (platform === "win32") {
|
|
57656
57656
|
fs.rename = typeof fs.rename !== "function" ? fs.rename : (function(fs$rename) {
|
|
57657
|
-
function
|
|
57657
|
+
function rename2(from, to, cb2) {
|
|
57658
57658
|
var start = Date.now();
|
|
57659
57659
|
var backoff = 0;
|
|
57660
57660
|
fs$rename(from, to, function CB(er) {
|
|
@@ -57674,8 +57674,8 @@ var require_polyfills = __commonJS({
|
|
|
57674
57674
|
if (cb2) cb2(er);
|
|
57675
57675
|
});
|
|
57676
57676
|
}
|
|
57677
|
-
if (Object.setPrototypeOf) Object.setPrototypeOf(
|
|
57678
|
-
return
|
|
57677
|
+
if (Object.setPrototypeOf) Object.setPrototypeOf(rename2, fs$rename);
|
|
57678
|
+
return rename2;
|
|
57679
57679
|
})(fs.rename);
|
|
57680
57680
|
}
|
|
57681
57681
|
fs.read = typeof fs.read !== "function" ? fs.read : (function(fs$read) {
|
|
@@ -62361,7 +62361,7 @@ var require_buffer_list3 = __commonJS({
|
|
|
62361
62361
|
}
|
|
62362
62362
|
}, {
|
|
62363
62363
|
key: "join",
|
|
62364
|
-
value: function
|
|
62364
|
+
value: function join3(s) {
|
|
62365
62365
|
if (this.length === 0) return "";
|
|
62366
62366
|
var p = this.head;
|
|
62367
62367
|
var ret2 = "" + p.data;
|
|
@@ -65727,7 +65727,7 @@ var require_buffer_list4 = __commonJS({
|
|
|
65727
65727
|
}
|
|
65728
65728
|
}, {
|
|
65729
65729
|
key: "join",
|
|
65730
|
-
value: function
|
|
65730
|
+
value: function join3(s) {
|
|
65731
65731
|
if (this.length === 0) return "";
|
|
65732
65732
|
var p = this.head;
|
|
65733
65733
|
var ret2 = "" + p.data;
|
|
@@ -68523,7 +68523,7 @@ var require_buffer_list5 = __commonJS({
|
|
|
68523
68523
|
}
|
|
68524
68524
|
}, {
|
|
68525
68525
|
key: "join",
|
|
68526
|
-
value: function
|
|
68526
|
+
value: function join3(s) {
|
|
68527
68527
|
if (this.length === 0) return "";
|
|
68528
68528
|
var p = this.head;
|
|
68529
68529
|
var ret2 = "" + p.data;
|
|
@@ -71393,7 +71393,7 @@ var require_buffer_list6 = __commonJS({
|
|
|
71393
71393
|
}
|
|
71394
71394
|
}, {
|
|
71395
71395
|
key: "join",
|
|
71396
|
-
value: function
|
|
71396
|
+
value: function join3(s) {
|
|
71397
71397
|
if (this.length === 0) return "";
|
|
71398
71398
|
var p = this.head;
|
|
71399
71399
|
var ret2 = "" + p.data;
|
|
@@ -74182,7 +74182,7 @@ var require_buffer_list7 = __commonJS({
|
|
|
74182
74182
|
}
|
|
74183
74183
|
}, {
|
|
74184
74184
|
key: "join",
|
|
74185
|
-
value: function
|
|
74185
|
+
value: function join3(s) {
|
|
74186
74186
|
if (this.length === 0) return "";
|
|
74187
74187
|
var p = this.head;
|
|
74188
74188
|
var ret2 = "" + p.data;
|
|
@@ -77172,7 +77172,7 @@ var require_buffer_list8 = __commonJS({
|
|
|
77172
77172
|
}
|
|
77173
77173
|
}, {
|
|
77174
77174
|
key: "join",
|
|
77175
|
-
value: function
|
|
77175
|
+
value: function join3(s) {
|
|
77176
77176
|
if (this.length === 0) return "";
|
|
77177
77177
|
var p = this.head;
|
|
77178
77178
|
var ret2 = "" + p.data;
|
|
@@ -82364,7 +82364,7 @@ var require_BufferList3 = __commonJS({
|
|
|
82364
82364
|
this.head = this.tail = null;
|
|
82365
82365
|
this.length = 0;
|
|
82366
82366
|
};
|
|
82367
|
-
BufferList.prototype.join = function
|
|
82367
|
+
BufferList.prototype.join = function join3(s) {
|
|
82368
82368
|
if (this.length === 0) return "";
|
|
82369
82369
|
var p = this.head;
|
|
82370
82370
|
var ret2 = "" + p.data;
|
|
@@ -85503,7 +85503,7 @@ var require_dir_writer = __commonJS({
|
|
|
85503
85503
|
module2.exports = DirWriter;
|
|
85504
85504
|
var Writer = require_writer2();
|
|
85505
85505
|
var inherits2 = require_inherits();
|
|
85506
|
-
var
|
|
85506
|
+
var mkdir2 = require_mkdirp();
|
|
85507
85507
|
var path = require("path");
|
|
85508
85508
|
var collect = require_collect();
|
|
85509
85509
|
inherits2(DirWriter, Writer);
|
|
@@ -85519,7 +85519,7 @@ var require_dir_writer = __commonJS({
|
|
|
85519
85519
|
}
|
|
85520
85520
|
DirWriter.prototype._create = function() {
|
|
85521
85521
|
var self2 = this;
|
|
85522
|
-
|
|
85522
|
+
mkdir2(self2._path, Writer.dirmode, function(er) {
|
|
85523
85523
|
if (er) return self2.error(er);
|
|
85524
85524
|
self2.ready = true;
|
|
85525
85525
|
self2.emit("ready");
|
|
@@ -85864,7 +85864,7 @@ var require_writer2 = __commonJS({
|
|
|
85864
85864
|
var fs = require_graceful_fs();
|
|
85865
85865
|
var inherits2 = require_inherits();
|
|
85866
85866
|
var rimraf = require_rimraf();
|
|
85867
|
-
var
|
|
85867
|
+
var mkdir2 = require_mkdirp();
|
|
85868
85868
|
var path = require("path");
|
|
85869
85869
|
var umask = process.platform === "win32" ? 0 : process.umask();
|
|
85870
85870
|
var getType = require_get_type();
|
|
@@ -85970,7 +85970,7 @@ var require_writer2 = __commonJS({
|
|
|
85970
85970
|
}
|
|
85971
85971
|
};
|
|
85972
85972
|
function create2(self2) {
|
|
85973
|
-
|
|
85973
|
+
mkdir2(path.dirname(self2._path), Writer.dirmode, function(er, made) {
|
|
85974
85974
|
if (er) return self2.error(er);
|
|
85975
85975
|
self2._madeDir = made;
|
|
85976
85976
|
return self2._create();
|
|
@@ -148973,6 +148973,7 @@ var require_fontkit_umd = __commonJS({
|
|
|
148973
148973
|
});
|
|
148974
148974
|
|
|
148975
148975
|
// apps/admin/data/skills.lib/document/bin-src/doc-convert.mjs
|
|
148976
|
+
var import_node_crypto = require("node:crypto");
|
|
148976
148977
|
var import_node_path2 = require("node:path");
|
|
148977
148978
|
var import_promises2 = require("node:fs/promises");
|
|
148978
148979
|
|
|
@@ -152673,7 +152674,7 @@ var require_buffer_list = /* @__PURE__ */ __commonJSMin(((exports2, module2) =>
|
|
|
152673
152674
|
},
|
|
152674
152675
|
{
|
|
152675
152676
|
key: "join",
|
|
152676
|
-
value: function
|
|
152677
|
+
value: function join3(s) {
|
|
152677
152678
|
if (this.length === 0) return "";
|
|
152678
152679
|
var p = this.head;
|
|
152679
152680
|
var ret2 = "" + p.data;
|
|
@@ -170152,6 +170153,11 @@ async function generateDocument(kind, spec, theme) {
|
|
|
170152
170153
|
}
|
|
170153
170154
|
}
|
|
170154
170155
|
|
|
170156
|
+
// packages/core/dist/document/html-escape.js
|
|
170157
|
+
function escapeHtml(value) {
|
|
170158
|
+
return String(value).replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
170159
|
+
}
|
|
170160
|
+
|
|
170155
170161
|
// packages/core/dist/document/doc-html.js
|
|
170156
170162
|
var FONT_STACK = 'TalosCJK, "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Source Han Sans SC", "WenQuanYi Zen Hei", sans-serif';
|
|
170157
170163
|
|
|
@@ -170180,9 +170186,6 @@ function htmlShell(bodyHtml, title) {
|
|
|
170180
170186
|
const head = `<meta charset="utf-8">` + (title ? `<title>${escapeHtml(title)}</title>` : "") + `<style>${PRINT_STYLE}</style>`;
|
|
170181
170187
|
return `<!doctype html><html lang="zh"><head>${head}</head><body>${bodyHtml}</body></html>`;
|
|
170182
170188
|
}
|
|
170183
|
-
function escapeHtml(s) {
|
|
170184
|
-
return s.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c]);
|
|
170185
|
-
}
|
|
170186
170189
|
function titleFromFilename(filename) {
|
|
170187
170190
|
const base = filename.split(/[\\/]/).pop() ?? filename;
|
|
170188
170191
|
const stem = base.replace(/\.[^.]+$/, "").trim();
|
|
@@ -170468,10 +170471,39 @@ async function renderHtmlViaService(html) {
|
|
|
170468
170471
|
return null;
|
|
170469
170472
|
}
|
|
170470
170473
|
}
|
|
170471
|
-
async function
|
|
170474
|
+
async function faithfulCachePath(cacheDir, input, raw) {
|
|
170475
|
+
if (!cacheDir) return null;
|
|
170476
|
+
await (0, import_promises2.mkdir)(cacheDir, { recursive: true, mode: 448 });
|
|
170477
|
+
const key = (0, import_node_crypto.createHash)("sha256").update("talos-doc-convert-pdf-v1\0").update((0, import_node_path2.extname)(input).toLowerCase()).update("\0").update(raw).digest("hex");
|
|
170478
|
+
return (0, import_node_path2.join)(cacheDir, `${key}.pdf`);
|
|
170479
|
+
}
|
|
170480
|
+
async function readCachedPdf(path) {
|
|
170481
|
+
if (!path) return null;
|
|
170482
|
+
const bytes = await (0, import_promises2.readFile)(path).catch(() => null);
|
|
170483
|
+
return bytes && bytes.subarray(0, 5).toString("latin1") === "%PDF-" ? bytes : null;
|
|
170484
|
+
}
|
|
170485
|
+
async function writeCachedPdf(path, bytes) {
|
|
170486
|
+
if (!path) return;
|
|
170487
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
170488
|
+
try {
|
|
170489
|
+
await (0, import_promises2.writeFile)(tmp, bytes, { mode: 384 });
|
|
170490
|
+
await (0, import_promises2.rename)(tmp, path);
|
|
170491
|
+
} finally {
|
|
170492
|
+
await (0, import_promises2.rm)(tmp, { force: true }).catch(() => {
|
|
170493
|
+
});
|
|
170494
|
+
}
|
|
170495
|
+
}
|
|
170496
|
+
async function renderViaSoffice(input, cachePath) {
|
|
170472
170497
|
if (!resolveSoffice()) return null;
|
|
170498
|
+
const cached = await readCachedPdf(cachePath);
|
|
170499
|
+
if (cached) return { bytes: cached, cached: true };
|
|
170473
170500
|
try {
|
|
170474
|
-
|
|
170501
|
+
const bytes = await convertToPdfViaSoffice(input);
|
|
170502
|
+
await writeCachedPdf(cachePath, bytes).catch((e) => {
|
|
170503
|
+
process.stderr.write(`doc-convert: cache write skipped (${e.message})
|
|
170504
|
+
`);
|
|
170505
|
+
});
|
|
170506
|
+
return { bytes, cached: false };
|
|
170475
170507
|
} catch (e) {
|
|
170476
170508
|
process.stderr.write(`doc-convert: LibreOffice failed (${e.message}); falling back to HTML render
|
|
170477
170509
|
`);
|
|
@@ -170493,8 +170525,13 @@ async function renderViaOfficeService(input, raw) {
|
|
|
170493
170525
|
}
|
|
170494
170526
|
}
|
|
170495
170527
|
async function main() {
|
|
170496
|
-
const
|
|
170497
|
-
|
|
170528
|
+
const args = process.argv.slice(2);
|
|
170529
|
+
const cacheIdx = args.indexOf("--cache-dir");
|
|
170530
|
+
const cacheDir = cacheIdx >= 0 ? args[cacheIdx + 1] : process.env.TALOS_OFFICE_CACHE_DIR;
|
|
170531
|
+
const consumed = /* @__PURE__ */ new Set([cacheIdx, cacheIdx >= 0 ? cacheIdx + 1 : -1]);
|
|
170532
|
+
const [input, out] = args.filter((_4, i) => !consumed.has(i));
|
|
170533
|
+
if (!input || !out) die("usage: doc-convert <in.docx|pptx|xlsx> <out.pdf> [--cache-dir <dir>]", 64);
|
|
170534
|
+
if (cacheIdx >= 0 && !cacheDir) die("--cache-dir requires a directory", 64);
|
|
170498
170535
|
if (!/\.pdf$/i.test(out)) die("output must be a .pdf path", 64);
|
|
170499
170536
|
let raw;
|
|
170500
170537
|
try {
|
|
@@ -170503,10 +170540,11 @@ async function main() {
|
|
|
170503
170540
|
die(`cannot read ${input}: ${e.message}`, 66);
|
|
170504
170541
|
}
|
|
170505
170542
|
const buffer = raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength);
|
|
170506
|
-
const
|
|
170507
|
-
|
|
170508
|
-
|
|
170509
|
-
|
|
170543
|
+
const cachePath = await faithfulCachePath(cacheDir, input, raw).catch((e) => die(`cannot prepare cache: ${e.message}`, 73));
|
|
170544
|
+
const loResult = await renderViaSoffice(input, cachePath);
|
|
170545
|
+
if (loResult) {
|
|
170546
|
+
await (0, import_promises2.writeFile)(out, Buffer.from(loResult.bytes));
|
|
170547
|
+
process.stdout.write(`wrote ${out} [pdf (libreoffice${loResult.cached ? ", cache hit" : ""})]
|
|
170510
170548
|
`);
|
|
170511
170549
|
return;
|
|
170512
170550
|
}
|
|
@@ -154029,6 +154029,11 @@ async function generateDocument(kind, spec, theme) {
|
|
|
154029
154029
|
}
|
|
154030
154030
|
}
|
|
154031
154031
|
|
|
154032
|
+
// packages/core/dist/document/html-escape.js
|
|
154033
|
+
function escapeHtml(value) {
|
|
154034
|
+
return String(value).replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
154035
|
+
}
|
|
154036
|
+
|
|
154032
154037
|
// packages/core/dist/document/doc-html.js
|
|
154033
154038
|
var FONT_STACK = 'TalosCJK, "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Source Han Sans SC", "WenQuanYi Zen Hei", sans-serif';
|
|
154034
154039
|
function stackWith(font) {
|
|
@@ -154064,7 +154069,7 @@ function foldFullwidthAlnum2(s) {
|
|
|
154064
154069
|
return s.replace(/[0-9A-Za-z]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 65248)).replace(/ /g, " ");
|
|
154065
154070
|
}
|
|
154066
154071
|
function norm(s) {
|
|
154067
|
-
return foldFullwidthAlnum2(String(s))
|
|
154072
|
+
return escapeHtml(foldFullwidthAlnum2(String(s)));
|
|
154068
154073
|
}
|
|
154069
154074
|
function paragraphHtml(text) {
|
|
154070
154075
|
return `<p>${norm(text).replace(/\r?\n/g, "<br>")}</p>`;
|
|
@@ -154191,9 +154196,6 @@ function parseTemplate(src) {
|
|
|
154191
154196
|
}
|
|
154192
154197
|
return walk();
|
|
154193
154198
|
}
|
|
154194
|
-
function escapeHtml(s) {
|
|
154195
|
-
return s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
154196
|
-
}
|
|
154197
154199
|
function resolve(path, scope) {
|
|
154198
154200
|
if (path === "." || path === "this")
|
|
154199
154201
|
return scope.ctx;
|