Files
SSAUGenerator/pptx/src/scaffold.js
StepanovPlaton bf7816ab7c Rename project to SSAU Generator and restructure content
- Move projects into content/<project>/{docx,pptx} with shared assets/
- Flatten config paths; output = project name in project folder
- Add pptx --init scaffold; remove docx exe build
- Add feature-complete content/example; ignore content/* except example
- Rewrite README and AGENTS.md
2026-10-11 23:25:22 +04:00

116 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
const fs = require("fs");
const path = require("path");
const yaml = require("js-yaml");
const { DEFAULTS, deepMerge } = require("./config");
const { solidPng } = require("./png");
const CONFIG_HEADER = `# Конфигурация генератора SSAU Generator PPTX.
# Все относительные пути считаются от каталога этого файла.
# Любой ключ можно опустить — будет использовано значение по умолчанию.
`;
const SAMPLE = {
"slides/00-title.md": `# Название презентации
## Подзаголовок
`,
"slides/01-content.md": `# Первый слайд
- первый пункт списка;
- второй пункт списка:
- вложенный пункт;
Обычный абзац с **полужирным**, *курсивом* и ==выделением==.
`,
"slides/02-final.md": `# Спасибо за внимание
`,
};
// Цвета задников: [R, G, B].
const BRAND = [27, 135, 201];
const BACKGROUNDS = {
"title-bg.png": BRAND,
"content-bg.png": [255, 255, 255],
"final-bg.png": BRAND,
};
function isGeneratorDir(baseDir) {
const base = path.basename(baseDir).toLowerCase();
return base === "docx" || base === "pptx";
}
/**
* Раскладка проекта: имя проекта = имя папки проекта, общие ресурсы в
* content/<проект>/assets/, результат — content/<проект>/<проект>.pptx.
*/
function projectLayout(baseDir) {
const isSub = isGeneratorDir(baseDir);
const projectDir = isSub ? path.dirname(baseDir) : baseDir;
const projectName = path.basename(projectDir) || "project";
return {
projectDir,
projectName,
assetsRel: isSub ? "../assets" : "assets",
assetsDir: path.join(projectDir, "assets"),
outputRel: isSub ? `../${projectName}.pptx` : `${projectName}.pptx`,
};
}
function defaultConfigYaml(layout) {
const config = deepMerge(DEFAULTS, {
presentation: { output: layout.outputRel },
theme: {
backgrounds: {
title: `${layout.assetsRel}/title-bg.png`,
content: `${layout.assetsRel}/content-bg.png`,
final: `${layout.assetsRel}/final-bg.png`,
},
},
content: { dir: "." },
slides: [
{ type: "title", file: "slides/00-title.md" },
{ type: "content", file: "slides/01-content.md" },
{ type: "final", file: "slides/02-final.md" },
],
});
return (
CONFIG_HEADER +
yaml.dump(config, { noRefs: true, lineWidth: -1, sortKeys: false })
);
}
/**
* Создаёт config.yaml, примеры слайдов и общие ресурсы проекта
* (content/<проект>/assets/), если их ещё нет.
*/
async function ensureScaffold(baseDir) {
const layout = projectLayout(baseDir);
const created = [];
const write = (target, content) => {
if (fs.existsSync(target)) return;
fs.mkdirSync(path.dirname(target), { recursive: true });
if (content && typeof content === "object" && content.binary) {
fs.writeFileSync(target, content.binary);
} else {
fs.writeFileSync(target, content, "utf8");
}
created.push(target);
};
write(path.join(baseDir, "config.yaml"), defaultConfigYaml(layout));
for (const [name, content] of Object.entries(SAMPLE)) {
write(path.join(baseDir, name), content);
}
for (const [name, color] of Object.entries(BACKGROUNDS)) {
write(path.join(layout.assetsDir, name), { binary: solidPng(1920, 1080, color) });
}
return created;
}
module.exports = { projectLayout, defaultConfigYaml, ensureScaffold, SAMPLE };