blob: 71b363ed9ae211bd8cd4ab039e9db3f1e08c4ccd [file]
#!/usr/bin/env node
const fs = require('node:fs');
const path = require('node:path');
const {parseArgs} = require('node:util');
const {availableVersions, normalizeVersion, contentDirectory} = require('../docs-inventory.cjs');
const root = path.resolve(__dirname, '../..');
const help = `Export a local Apache Doris documentation version to PDF.
Usage: yarn docs:pdf --version <version> [options]
--version <version> Required: dev (alias: current), an active or archived version
--locale <locales> en, zh-CN, or en,zh-CN (default: en,zh-CN)
--output <directory> Default: output/pdf/docs/<version>/
--chrome <executable> Installed Chrome/Chromium; auto-detected when omitted
--python <executable> Python with pypdf (default: repo venv, then python3)
--limit <count> Sample export; requires an explicit --output
--allow-missing-images Use linked placeholders for unreachable images
--resume Retain PDFs for other locales from the same commit
--list-versions List versions available in this checkout
--help Show this help
Outputs: PDF files, manifest.json, and SHA256SUMS. Upload is a separate manual step.
`;
function parseOptions(args, siteDir = root) {
const {values} = parseArgs({args, options: {
version: {type: 'string'}, locale: {type: 'string', default: 'en,zh-CN'}, output: {type: 'string'},
chrome: {type: 'string'}, python: {type: 'string'},
'allow-missing-images': {type: 'boolean'}, limit: {type: 'string'}, resume: {type: 'boolean'}, 'list-versions': {type: 'boolean'}, help: {type: 'boolean'},
}});
if (values.help || values['list-versions']) return values;
if (!values.version?.trim()) throw new Error('Specify --version. Use --list-versions to see available versions.');
const version = normalizeVersion(values.version.trim());
if (!availableVersions(siteDir).includes(version)) throw new Error(`Unknown documentation version: ${values.version}. Use --list-versions.`);
const locales = values.locale.split(',').map(locale => locale.trim());
if (new Set(locales).size !== locales.length || locales.some(locale => !['en', 'zh-CN'].includes(locale)))
throw new Error('--locale must be en, zh-CN, or en,zh-CN.');
for (const locale of locales) if (!fs.existsSync(contentDirectory(siteDir, version, locale)))
throw new Error(`Missing ${locale} source for ${version}.`);
const limit = values.limit === undefined ? 0 : Number(values.limit);
if (values.limit !== undefined && (!Number.isSafeInteger(limit) || limit < 1)) throw new Error('--limit must be a positive integer.');
if (limit && !values.output) throw new Error('Sample exports require an explicit --output directory.');
const venvPython = path.join(siteDir, 'tmp/pdfs/.venv', process.platform === 'win32' ? 'Scripts/python.exe' : 'bin/python');
const python = values.python || process.env.DOCS_PDF_PYTHON || (fs.existsSync(venvPython) ? venvPython : 'python3');
return {version, locales, limit, allowMissingImages: values['allow-missing-images'] ?? false, resume: values.resume ?? false, python,
chrome: values.chrome || process.env.DOCS_PDF_CHROME || process.env.PUPPETEER_EXECUTABLE_PATH,
output: values.output ? path.resolve(values.output) : path.join(siteDir, 'output/pdf/docs', version)};
}
async function main() {
const options = parseOptions(process.argv.slice(2));
if (options.help) return process.stdout.write(help);
if (options['list-versions']) return process.stdout.write(availableVersions(root).join('\n') + '\n');
await require('./generate.cjs').generate(options);
}
if (require.main === module) main().catch(error => {console.error(`PDF export failed: ${error.message}`); process.exitCode = 1;});
module.exports = {parseOptions};