|<\/div>/g, '')).join('');
+ return { id, language, translationKey, path: basePath + route, title: meta.title, description: meta.description, version: version.id,
+ sourceDigest: meta.sourceDigest || null, source: relative, url: baseURL + route, uri: `pdfmake://docs/${version.id}/${id}`,
+ markdown: `# ${meta.title}\n\nVersion: pdfmake ${version.label}\nLanguage: ${language}\nSource: ${baseURL + route}\n\n${portableMarkdown}\n` };
+ }));
+}
+
+export function searchPages(pages, query, limit = 5) {
+ const terms = [...new Set(query.toLowerCase().match(/[\p{L}\p{N}_]+/gu) || [])];
+ if (!terms.length) return [];
+ return pages.map(page => {
+ const title = `${page.title} ${page.id}`.toLowerCase();
+ const description = page.description.toLowerCase();
+ const body = page.markdown.toLowerCase();
+ const score = terms.reduce((total, term) => total + (title.includes(term) ? 12 : 0)
+ + (description.includes(term) ? 5 : 0) + (body.includes(term) ? 1 : 0), 0);
+ return { ...page, score };
+ }).filter(page => page.score > 0).sort((a, b) => b.score - a.score || a.id.localeCompare(b.id)).slice(0, limit);
+}
diff --git a/scripts/generate.mjs b/scripts/generate.mjs
new file mode 100644
index 00000000..cb8b780d
--- /dev/null
+++ b/scripts/generate.mjs
@@ -0,0 +1,83 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { root, loadPages, baseURL, languages } from './corpus.mjs';
+import { activeVersion, versionConfig, rebaseLinks, versionTargets } from './versions.mjs';
+import { createCodeExample, codeKey } from './code-examples.mjs';
+import { examples } from '../static/playground/examples.js';
+
+const codeExamples = {};
+async function collectCode(directory) {
+ for (const entry of await fs.readdir(directory, { withFileTypes: true })) {
+ const file = path.join(directory, entry.name);
+ if (entry.isDirectory()) await collectCode(file);
+ else if (entry.name.endsWith('.md')) {
+ const source = (await fs.readFile(file, 'utf8')).replaceAll('\r\n', '\n');
+ for (const match of source.matchAll(/^([ \t]*)```[ \t]*([\w-]*)[ \t]*\n([\s\S]*?)^\1```/gm)) {
+ const code = match[3].split('\n').map(line => line.startsWith(match[1]) ? line.slice(match[1].length) : line).join('\n');
+ if (/^(js|javascript|ts|typescript)$/.test(match[2]) || (!match[2] && /^\s*(?:\/\/|var\b|const\b|let\b|import\b|[{}]|text:\s*\[)/.test(code))) codeExamples[codeKey(code)] = createCodeExample(code, match[2] || 'js');
+ }
+ }
+ }
+}
+await collectCode(path.join(root, 'content'));
+for (const example of examples) codeExamples[codeKey(example.source)] = createCodeExample(example.source);
+const pages = await loadPages({ codeExamples });
+const files = new Map();
+files.set('static/playground/typed-examples.js', 'export const typedExamples = ' + JSON.stringify(Object.fromEntries(examples.map(example => [example.id, codeExamples[codeKey(example.source)].typescript])), null, 2) + ';\n');
+files.set('data/codeExamples.json', JSON.stringify(codeExamples, null, 2) + '\n');
+files.set('data/playground.json', JSON.stringify(examples, null, 2) + '\n');
+files.set('data/docs-all.json', JSON.stringify({ version: activeVersion.id, pages }, null, 2) + '\n');
+for (const language of languages) {
+ const localized = pages.filter(page => page.language === language);
+ const prefix = language === 'en' ? '' : `${language}/`;
+ files.set(`static/${prefix}docs-index.json`, JSON.stringify({ version: activeVersion.id, language, pages: localized }, null, 2) + '\n');
+ files.set(`static/${prefix}llms.txt`, `# pdfmake ${activeVersion.id} documentation · ${language}\n\n`
+ + `> Generate PDFs in Node.js and browsers from document definitions. This corpus targets ${activeVersion.label} only.\n\n`
+ + `Use only examples for ${activeVersion.label}; do not mix APIs from different version series.\n`
+ + 'Use synchronous resource access policies. Never execute untrusted document callbacks.\n\n'
+ + `Translation coverage: ${localized.length} of ${pages.filter(page => page.language === 'en').length} documentation pages.\n\n`
+ + `Full Markdown corpus: ${baseURL}${prefix}llms-full.txt\n\n## Languages\n\n`
+ + languages.map(lang => `- [${lang}](${baseURL}${lang === 'en' ? '' : lang + '/'}llms.txt)`).join('\n') + '\n\n## Pages\n\n'
+ + localized.map(p => `- [${p.title}](${baseURL}markdown/${p.id}.md): ${p.description}`).join('\n') + '\n');
+ files.set(`static/${prefix}llms-full.txt`, localized.map(p => p.markdown).join('\n---\n\n'));
+}
+for (const page of pages) files.set(`static/markdown/${page.id}.md`, page.markdown);
+files.set('data/versionLinks.json', JSON.stringify(Object.fromEntries(pages.map(page => [page.id, versionTargets(page)])), null, 2) + '\n');
+files.set('data/docsVersion.json', JSON.stringify({ ...activeVersion, releases: versionConfig.releases }, null, 2) + '\n');
+files.set('static/version-snapshot.json', JSON.stringify({ version: activeVersion.id, libraryVersion: activeVersion.libraryVersion, baseURL, languages, chapters: pages.filter(page => page.language === 'en').map(page => page.translationKey) }, null, 2) + '\n');
+files.set('static/versions.json', JSON.stringify({ current: versionConfig.current, releases: versionConfig.releases.map(({ id, label, status }) => ({ id, label, status, url: new URL(`/docs/${id}/`, versionConfig.origin).href })) }, null, 2) + '\n');
+files.set('.generated/hugo.json', JSON.stringify({ baseURL, contentDir: '.generated/content', params: { docsVersion: activeVersion.id, docsVersionLabel: activeVersion.label, editURL: `https://github.com/pdfmake/docs/edit/${activeVersion.ref}/content/` } }, null, 2) + '\n');
+async function stageContent(directory) {
+ for (const item of await fs.readdir(directory, { withFileTypes: true })) {
+ const file = path.join(directory, item.name);
+ if (item.isDirectory()) await stageContent(file);
+ else files.set('.generated/content/' + path.relative(path.join(root, 'content'), file).replaceAll('\\', '/'), rebaseLinks(await fs.readFile(file, 'utf8')));
+ }
+}
+await stageContent(path.join(root, 'content'));
+const check = process.argv.includes('--check');
+for (const [name, text] of files) {
+ // Ephemeral Hugo inputs are recreated by build/dev and do not exist in clean CI checkouts.
+ if (check && name.startsWith('.generated/')) continue;
+ const file = path.join(root, name);
+ if (check) {
+ if (await fs.readFile(file, 'utf8').catch(() => '') !== text) throw new Error(`Stale generated file: ${name}. Run npm run docs:generate.`);
+ } else {
+ await fs.mkdir(path.dirname(file), { recursive: true });
+ await fs.writeFile(file, text);
+ }
+}
+// Detect removed pages too: old resources must not survive in the generated corpus.
+async function checkExtra(directory) {
+ for (const entry of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
+ const file = path.join(directory, entry.name);
+ if (entry.isDirectory()) await checkExtra(file);
+ else if (!files.has(path.relative(root, file).replaceAll('\\', '/'))) {
+ if (check) throw new Error(`Orphaned generated resource: ${file}`);
+ await fs.unlink(file);
+ }
+ }
+}
+await checkExtra(path.join(root, 'static/markdown'));
+if (!check) await checkExtra(path.join(root, '.generated/content'));
+console.log(`${check ? 'Checked' : 'Generated'} ${pages.length} versioned documentation pages`);
diff --git a/scripts/hugo.mjs b/scripts/hugo.mjs
new file mode 100644
index 00000000..b3495831
--- /dev/null
+++ b/scripts/hugo.mjs
@@ -0,0 +1,4 @@
+import { spawnSync } from 'node:child_process';
+const result = spawnSync('hugo', ['--config', 'config.toml,.generated/hugo.json', ...process.argv.slice(2)], { stdio: 'inherit' });
+if (result.error) throw result.error;
+process.exitCode = result.status ?? 1;
diff --git a/scripts/prepare-playground.mjs b/scripts/prepare-playground.mjs
new file mode 100644
index 00000000..906254ca
--- /dev/null
+++ b/scripts/prepare-playground.mjs
@@ -0,0 +1,22 @@
+import { prepareTypeScript } from './prepare-typescript.mjs';
+import { activeVersion } from './versions.mjs';
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { createRequire } from 'node:module';
+import { build, transform } from 'esbuild';
+import { root } from './corpus.mjs';
+
+const require = createRequire(import.meta.url);
+const library = process.env.PDFMAKE_SOURCE || path.dirname(require.resolve('pdfmake/package.json'));
+const { version } = JSON.parse(await fs.readFile(path.join(library, 'package.json'), 'utf8'));
+if (version !== activeVersion.libraryVersion) throw new Error(`Playground library ${version} does not match configured ${activeVersion.libraryVersion}`);
+const output = path.join(root, 'static/playground/vendor');
+await fs.mkdir(output, { recursive: true });
+await prepareTypeScript(output, { transform });
+for (const name of ['pdfmake.min.js', 'vfs_fonts.js']) await fs.copyFile(path.join(library, 'build', name), path.join(output, name));
+const pdfjs = path.dirname(require.resolve('pdfjs-dist/package.json'));
+for (const name of ['pdf.mjs', 'pdf.worker.mjs']) await fs.copyFile(path.join(pdfjs, 'build', name), path.join(output, name));
+await fs.copyFile(path.join(pdfjs, 'LICENSE'), path.join(output, 'PDFJS-LICENSE.txt'));
+await fs.writeFile(path.join(output, 'version.json'), JSON.stringify({ version }) + '\n');
+await build({ entryPoints: [path.join(root, 'playground/editor.mjs')], outfile: path.join(root, 'static/playground/editor.js'), bundle: true, minify: true, format: 'esm', target: 'es2020', legalComments: 'eof' });
+console.log(`Prepared playground with pdfmake ${version} from ${library}`);
diff --git a/scripts/prepare-typescript.mjs b/scripts/prepare-typescript.mjs
new file mode 100644
index 00000000..b64aabc8
--- /dev/null
+++ b/scripts/prepare-typescript.mjs
@@ -0,0 +1,50 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
+export async function prepareTypeScript(output, { transform } = {}) {
+ const modules = path.dirname(path.dirname(require.resolve('typescript/package.json')));
+ const source = path.join(modules, 'typescript/lib/typescript.js');
+ if (transform) {
+ const result = await transform(await fs.readFile(source, 'utf8'), { minify: true, legalComments: 'eof', target: 'es2020' });
+ await fs.writeFile(path.join(output, 'typescript.js'), result.code);
+ } else await fs.copyFile(source, path.join(output, 'typescript.js'));
+ const licenses = [];
+ for (const name of ['typescript/LICENSE.txt', 'typescript/ThirdPartyNoticeText.txt', '@types/pdfkit/LICENSE', '@types/node/LICENSE', 'undici-types/LICENSE']) {
+ const text = await fs.readFile(path.join(modules, name), 'utf8').catch(() => '');
+ if (text) licenses.push(name + '\n\n' + text);
+ }
+ const native = await nativeLibrary();
+ licenses.push('pdfmake/types/LICENSE\n\n' + await fs.readFile(path.join(native, 'types/LICENSE'), 'utf8'));
+ await fs.writeFile(path.join(output, 'TYPESCRIPT-LICENSES.txt'), licenses.join('\n\n---\n\n'));
+ await fs.writeFile(path.join(output, 'typescript-types.js'), 'var pdfmakeTypeFiles = ' + JSON.stringify(await collectTypeFiles()) + ';\n');
+}
+export async function collectTypeFiles() {
+ const modules = path.dirname(path.dirname(require.resolve('typescript/package.json')));
+ const files = {};
+ async function collect(directory, base = modules, prefix = '/node_modules/') {
+ for (const item of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
+ const file = path.join(directory, item.name);
+ if (item.isDirectory()) await collect(file, base, prefix);
+ else if (item.name.endsWith('.d.ts') || item.name === 'package.json') files[prefix + path.relative(base, file).replaceAll('\\', '/')] = await fs.readFile(file, 'utf8');
+ }
+ }
+ for (const name of ['typescript/lib', '@types', 'undici-types']) await collect(path.join(modules, name));
+ const native = await nativeLibrary();
+ for (const name of ['types', 'build']) {
+ if (name === 'types') await collect(path.join(native, name), native, '/node_modules/pdfmake/');
+ else for (const file of ['pdfmake.d.ts', 'pdfmake.min.d.ts', 'vfs_fonts.d.ts']) files['/node_modules/pdfmake/build/' + file] = await fs.readFile(path.join(native, name, file), 'utf8');
+ }
+ for (const file of ['package.json', 'interfaces.d.ts']) files['/node_modules/pdfmake/' + file] = await fs.readFile(path.join(native, file), 'utf8');
+ return files;
+}
+
+async function nativeLibrary() {
+ const root = fileURLToPath(new URL('../', import.meta.url));
+ let installed;
+ try { installed = path.dirname(require.resolve('pdfmake/package.json')); } catch { /* The library checkout itself is also supported. */ }
+ const candidates = [process.env.PDFMAKE_SOURCE, root, installed, path.join(root, 'tooling/pdfmake-types')].filter(Boolean);
+ for (const candidate of candidates) if (await fs.stat(path.join(candidate, 'types/interfaces.d.ts')).catch(() => null)) return candidate;
+ throw new Error('Native declarations are missing. Run sync-native-types against the built library.');
+}
diff --git a/scripts/serve.mjs b/scripts/serve.mjs
new file mode 100644
index 00000000..16fa767b
--- /dev/null
+++ b/scripts/serve.mjs
@@ -0,0 +1,32 @@
+import { basePath } from './versions.mjs';
+import http from 'node:http';
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+export async function serve(directory, port = 0, { collection = false } = {}) {
+ const root = path.resolve(directory);
+ const types = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.mjs': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.json': 'application/json; charset=utf-8', '.md': 'text/plain; charset=utf-8', '.txt': 'text/plain; charset=utf-8', '.svg': 'image/svg+xml' };
+ const server = http.createServer(async (req, res) => {
+ if (!['GET', 'HEAD'].includes(req.method)) { res.writeHead(405).end(); return; }
+ try {
+ const url = new URL(req.url, 'http://localhost');
+ const relative = decodeURIComponent(!collection && url.pathname.startsWith(basePath) ? '/' + url.pathname.slice(basePath.length) : url.pathname);
+ let file = path.resolve(root, '.' + relative);
+ if (file !== root && !file.startsWith(root + path.sep)) { res.writeHead(403).end(); return; }
+ if ((await fs.stat(file)).isDirectory()) file = path.join(file, 'index.html');
+ const data = await fs.readFile(file);
+ res.setHeader('Content-Type', types[path.extname(file)] || 'application/octet-stream');
+ res.setHeader('X-Content-Type-Options', 'nosniff');
+ if (path.basename(file) === 'worker.js') res.setHeader('Content-Security-Policy', "default-src 'none'; script-src 'self' 'unsafe-eval'; connect-src 'none'");
+ res.writeHead(200).end(req.method === 'HEAD' ? undefined : data);
+ } catch { res.writeHead(404).end('Not found'); }
+ });
+ await new Promise(resolve => server.listen(port, '127.0.0.1', resolve));
+ return server;
+}
+
+if (process.argv[1] && import.meta.url === (await import('node:url')).pathToFileURL(process.argv[1]).href) {
+ const server = await serve(process.argv[2] || fileURLToPath(new URL('../public/', import.meta.url)), Number(process.env.PORT || 1313), { collection: process.argv.includes('--collection') });
+ console.log(`Documentation: http://127.0.0.1:${server.address().port}${basePath}`);
+}
diff --git a/scripts/sync-native-types.mjs b/scripts/sync-native-types.mjs
new file mode 100644
index 00000000..c5bf3b49
--- /dev/null
+++ b/scripts/sync-native-types.mjs
@@ -0,0 +1,21 @@
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { createHash } from 'node:crypto';
+const library = process.argv[2];
+if (!library) throw new Error('Usage: node scripts/sync-native-types.mjs /path/to/pdfmake [--check]');
+const target = new URL('../tooling/pdfmake-types/', import.meta.url);
+const names = ['package.json', 'interfaces.d.ts', 'types/interfaces.d.ts', 'types/index.d.ts', 'types/browser.d.ts', 'types/LICENSE', 'build/pdfmake.d.ts', 'build/pdfmake.min.d.ts', 'build/vfs_fonts.d.ts'];
+const hashes = {};
+for (const name of names) {
+ let content = await fs.readFile(path.join(library, name), 'utf8');
+ if (name === 'package.json') { const source = JSON.parse(content); content = JSON.stringify({ name: source.name, version: source.version, types: source.types, description: 'Declaration-only snapshot of the local unreleased library branch; not a published runtime.' }, null, 2) + '\n'; }
+ content = content.replaceAll('\r\n', '\n');
+ hashes[name] = createHash('sha256').update(content).digest('hex');
+ const file = new URL(name, target);
+ if (process.argv.includes('--check')) { if ((await fs.readFile(file, 'utf8')).replaceAll('\r\n', '\n') !== content) throw new Error(`Native type snapshot drift: ${name}`); }
+ else { await fs.mkdir(new URL('.', file), { recursive: true }); await fs.writeFile(file, content); }
+}
+const manifest = JSON.stringify({ source: 'pdfmake local improvement branch (unreleased)', files: hashes }, null, 2) + '\n';
+if (process.argv.includes('--check')) { if ((await fs.readFile(new URL('snapshot.json', target), 'utf8')).replaceAll('\r\n', '\n') !== manifest) throw new Error('Type snapshot manifest drift'); }
+else await fs.writeFile(new URL('snapshot.json', target), manifest);
+console.log('Native declaration snapshot matches the library');
diff --git a/scripts/sync-playground.mjs b/scripts/sync-playground.mjs
new file mode 100644
index 00000000..ce4e1d63
--- /dev/null
+++ b/scripts/sync-playground.mjs
@@ -0,0 +1,24 @@
+// Mirror the documentation playground into the library's standalone development tool.
+// Run explicitly when changing the shared UI; --check detects drift without modifying files.
+import fs from 'node:fs/promises';
+import path from 'node:path';
+import { root } from './corpus.mjs';
+
+const library = process.argv[2];
+if (!library) throw new Error('Usage: node scripts/sync-playground.mjs /path/to/pdfmake [--check]');
+const pairs = ['standalone.html', 'standalone.js', 'theme.js', 'app.js', 'examples.js', 'typed-examples.js', 'worker.js', 'typescript-check.js', 'playground.css', 'brand/pdfmake-logo.png', 'brand/pdfmake-icon.png', 'brand/icon-16.png', 'brand/icon-32.png', 'brand/icon-180.png'].map(name => [
+ path.join(root, 'static/playground', name), path.join(library, 'dev-playground/public', name === 'standalone.html' ? 'index.html' : name)
+]);
+pairs.push([path.join(root, 'scripts/prepare-typescript.mjs'), path.join(library, 'scripts/prepare-typescript.mjs')]);
+pairs.push([path.join(root, 'playground/editor.mjs'), path.join(library, 'dev-playground/editor.mjs')]);
+for (const [source, target] of pairs) {
+ const content = await fs.readFile(source);
+ if (process.argv.includes('--check')) {
+ const normalize = value => value.toString('utf8').replaceAll('\r\n', '\n');
+ if (source.endsWith('.png') ? !content.equals(await fs.readFile(target)) : normalize(content) !== normalize(await fs.readFile(target))) throw new Error(`Playground drift: ${target}`);
+ } else {
+ await fs.mkdir(path.dirname(target), { recursive: true });
+ await fs.writeFile(target, content);
+ }
+}
+console.log('Playground source mirror matches');
diff --git a/scripts/versions.mjs b/scripts/versions.mjs
new file mode 100644
index 00000000..41b7362d
--- /dev/null
+++ b/scripts/versions.mjs
@@ -0,0 +1,50 @@
+import fs from 'node:fs/promises';
+
+export function resolveVersion(config, requested = config.current) {
+ if (new URL(config.origin).protocol !== 'https:') throw new Error('Documentation origin must use HTTPS');
+ const ids = new Set();
+ for (const release of config.releases) {
+ if (!/^\d+\.\d+$/.test(release.id) || ids.has(release.id)) throw new Error('Invalid or duplicate documentation version');
+ if (!['current', 'supported', 'legacy', 'preview'].includes(release.status)) throw new Error('Invalid version status');
+ ids.add(release.id);
+ }
+ if (!ids.has(config.current) || !/^\d+\.\d+$/.test(config.sourceVersion)) throw new Error('Invalid current/source version');
+ const release = config.releases.find(item => item.id === requested);
+ if (!release?.managed) throw new Error(`No managed documentation snapshot for version ${requested}`);
+ if (!release.ref || !new RegExp(`^${release.id.replace('.', '\\.')}\\.\\d+(?:-[\\w.-]+)?$`).test(release.libraryVersion)) throw new Error('Library version must match the documentation series');
+ const basePath = `/docs/${release.id}/`;
+ return { ...release, basePath, baseURL: new URL(basePath, config.origin).href, sourceBasePath: `/docs/${config.sourceVersion}/` };
+}
+
+export const versionConfig = JSON.parse(await fs.readFile(new URL('../versions.json', import.meta.url), 'utf8'));
+export const activeVersion = resolveVersion(versionConfig, process.env.DOCS_VERSION || versionConfig.current);
+export const basePath = activeVersion.basePath;
+export const baseURL = activeVersion.baseURL;
+export function versionTargets(page, config = versionConfig) {
+ return config.releases.map(release => {
+ const sameVersion = release.id === page.version;
+ const sameChapter = sameVersion || release.chapters?.includes(page.translationKey);
+ const language = sameVersion || release.languages?.includes(page.language) ? page.language : 'en';
+ const prefix = language === 'en' ? '' : `${language}/`;
+ const chapter = sameChapter && page.translationKey !== 'index' ? `${page.translationKey}/` : '';
+ return { id: release.id, label: release.label, current: sameVersion, sameChapter: !!sameChapter,
+ url: release.managed ? `/docs/${release.id}/${prefix}${chapter}` : new URL(`/docs/${release.id}/${prefix}${chapter}`, config.origin).href };
+ });
+}
+// Authored links remain relative to their source snapshot; code/API examples are never rewritten.
+export function rebaseLinks(text, version = activeVersion) {
+ let closingFence;
+ return text.split('\n').map(line => {
+ if (closingFence) {
+ if (closingFence.test(line)) closingFence = undefined;
+ return line;
+ }
+ const opening = line.match(/^ {0,3}(`{3,}|~{3,})/);
+ if (opening) {
+ const fence = opening[1];
+ closingFence = new RegExp(`^ {0,3}${fence[0]}{${fence.length},}[ \\t\\r]*$`);
+ return line;
+ }
+ return line.replaceAll(version.sourceBasePath, version.basePath);
+ }).join('\n');
+}
diff --git a/static/assets/docs.css b/static/assets/docs.css
new file mode 100644
index 00000000..b7809016
--- /dev/null
+++ b/static/assets/docs.css
@@ -0,0 +1,19 @@
+:root{--header-height:64px;--sidebar-width:270px;--surface:#fff;--ink:#202124;--muted:#606770;--accent:#c9252d;--line:#e5e7eb;--wash:#f7f7f8;--inline-code:#f0f1f3;--notice:#fff7e8;--card:#fff5f5;--badge:#fde8e9;--selection:#f9cbd0;--syntax-keyword:#ae273e;--syntax-string:#286341;--syntax-number:#7440a8;color-scheme:light;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;font-size:16px;line-height:1.7;color:var(--ink);background:var(--surface)}
+@media(prefers-color-scheme:dark){:root:not([data-theme="light"]){--surface:#111b23;--ink:#e3ecef;--muted:#aab5bf;--accent:#ff8c90;--line:#33404b;--wash:#1b252e;--inline-code:#27323d;--notice:#30291b;--card:#2b2029;--badge:#41242b;--selection:#67353e;--syntax-keyword:#ff9cab;--syntax-string:#a5d6a7;--syntax-number:#d5acff;color-scheme:dark}}
+:root[data-theme="dark"]{--surface:#111b23;--ink:#e3ecef;--muted:#aab5bf;--accent:#ff8c90;--line:#33404b;--wash:#1b252e;--inline-code:#27323d;--notice:#30291b;--card:#2b2029;--badge:#41242b;--selection:#67353e;--syntax-keyword:#ff9cab;--syntax-string:#a5d6a7;--syntax-number:#d5acff;color-scheme:dark}
+*{box-sizing:border-box}[hidden]{display:none!important}body{margin:0}a{color:var(--accent);text-decoration:none}article a:hover,footer a:hover{text-decoration:underline;text-underline-offset:3px}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,summary:focus-visible{outline:3px solid var(--accent);outline-offset:3px}button,input,select{font:inherit}button,summary{cursor:pointer}button:disabled{cursor:default;opacity:.5}img{max-width:100%}.sr-only,.skip:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.skip:focus{position:fixed;top:5px;left:10px;background:var(--surface);padding:10px;z-index:100}
+.topbar{position:sticky;top:0;height:var(--header-height);display:flex;align-items:center;gap:26px;padding:0 24px;background:var(--surface);border-bottom:1px solid var(--line);z-index:30}.brand{flex-shrink:0;line-height:0}.brand-logo{display:block;width:142px;height:auto;padding:3px 5px;background:#fff;border-radius:4px}.primary-nav{display:flex;align-self:stretch;gap:24px;font-size:14px;font-weight:650;align-items:stretch}.primary-nav a{display:flex;align-items:center;color:var(--ink);border-bottom:2px solid transparent}.primary-nav a[aria-current]{border-color:var(--accent);color:var(--accent)}.header-links{margin-left:auto;display:flex;gap:16px;align-items:center;font-size:12px;white-space:nowrap}.version{font-weight:700;color:var(--accent);background:var(--badge);padding:2px 7px;border-radius:4px}.theme-control select{background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:5px;padding:4px 6px;font-size:12px}.github-link{color:var(--ink)}:is(.language-menu,.version-menu){position:relative}:is(.language-menu,.version-menu) summary{color:var(--muted);cursor:pointer}:is(.language-menu,.version-menu) ul{list-style:none;position:absolute;right:0;top:100%;min-width:220px;max-width:80vw;margin:10px 0;padding:6px;background:var(--surface);border:1px solid var(--line);border-radius:6px;box-shadow:0 8px 30px #0002}:is(.language-menu,.version-menu) a{display:block;padding:7px 10px;color:var(--ink)}:is(.language-menu,.version-menu) a:hover,:is(.language-menu,.version-menu) a[aria-current]{background:var(--wash);color:var(--accent)}:is(.language-menu,.version-menu) small{display:block;white-space:normal;font-size:10px}.nav-toggle{display:none}
+.search-area{position:relative;max-width:270px;min-width:180px;margin-left:auto;flex:1}.search-area input{width:100%;background:var(--wash);color:var(--ink);border:1px solid transparent;border-radius:7px;padding:8px 32px 8px 12px;font-size:12px;line-height:1.5}.search-area input:focus{border-color:var(--accent)}.search-area>kbd{position:absolute;right:12px;top:7px;color:var(--muted);font-size:12px}.search-popover{position:absolute;top:calc(100% + 12px);right:0;width:380px;max-width:90vw;padding:10px 14px;background:var(--surface);border:1px solid var(--line);border-radius:8px;box-shadow:0 12px 40px #0003;max-height:65vh;overflow:auto}#search-status{font-size:12px;color:var(--muted);margin:3px 0 8px}#search-results{padding:0;margin:0;list-style:none}#search-results a{display:block;border-radius:5px;padding:8px 10px;font-size:14px}#search-results a:hover,#search-results a:focus{background:var(--wash)}
+.shell{display:grid;grid-template-columns:var(--sidebar-width) minmax(0,1fr);max-width:1920px;margin:auto}.sidebar{position:sticky;top:var(--header-height);height:calc(100dvh - var(--header-height));overflow:auto;overscroll-behavior:contain;border-right:1px solid var(--line);padding:22px 14px 20px;font-size:13px;scrollbar-width:thin}.workspace-nav{display:flex;align-items:center;justify-content:space-between;margin:0 0 19px;padding:9px 13px;border:1px solid var(--line);border-radius:6px;font-weight:650;color:var(--ink)}.workspace-nav[aria-current]{color:var(--accent);background:var(--card);border-color:var(--accent)}.workspace-nav span{font-size:18px;color:var(--accent)}.sidebar details{margin:2px 0 12px}.sidebar summary{padding:5px 10px;font-weight:700;color:var(--ink);list-style:none;display:flex;align-items:center;justify-content:space-between}.sidebar summary:after{content:'›';font-size:20px;line-height:1;transform:rotate(0deg);color:var(--muted)}.sidebar details[open]>summary:after{transform:rotate(90deg)}.sidebar summary::-webkit-details-marker{display:none}.sidebar ul{list-style:none;padding:0;margin:4px 0 0}.sidebar li a{display:block;color:var(--muted);padding:6px 13px 6px 22px;line-height:1.55;border-radius:5px}.sidebar a:hover{background:var(--wash)}.sidebar li a[aria-current]{background:var(--card);color:var(--accent);font-weight:650;border-left:2px solid var(--accent);padding-left:20px}.language-tag{font-size:9px;border:1px solid var(--line);border-radius:3px;padding:0 3px;margin-left:3px;color:var(--muted)}.sidebar-bottom{display:flex;flex-wrap:wrap;gap:8px 14px;border-top:1px solid var(--line);padding:16px 10px;margin-top:24px;font-size:11px}.sidebar-bottom a{color:var(--muted)}
+main{min-width:0;padding:24px 36px 40px;scroll-margin-top:calc(var(--header-height) + 24px)}.breadcrumbs{display:flex;align-items:center;gap:10px;font-size:11px;color:var(--muted);margin-bottom:20px}.breadcrumbs>a{color:var(--muted)}.breadcrumbs>span:last-child{background:var(--wash);padding:2px 9px;border-radius:12px;color:var(--accent)}.article-grid{display:grid;grid-template-columns:minmax(0,800px) minmax(140px,190px);gap:44px;justify-content:center}.article-body{min-width:0}h1{font-size:clamp(32px,3vw,44px);line-height:1.2;letter-spacing:-1.1px;margin:0 0 18px;font-weight:750}.lead{font-size:17px;color:var(--muted);line-height:1.75;margin:0 0 22px}.version-note{font-size:11px;border-left:3px solid var(--accent);background:var(--wash);padding:9px 13px;margin:0 0 27px}article{font-size:15px;min-width:0}h2{font-size:27px;line-height:1.3;letter-spacing:-.4px;margin:36px 0 14px}h3{font-size:21px;line-height:1.4;margin:28px 0 12px}h4,h5{font-size:17px;margin:26px 0 12px}h2,h3,h4,h5{scroll-margin-top:calc(var(--header-height) + 20px)}p,ul,ol{margin:13px 0}li{margin:5px 0}article>h2:first-child{margin-top:24px}code{font-family:ui-monospace,Consolas,monospace;font-size:.88em;padding:2px 5px;background:var(--inline-code);border-radius:4px;overflow-wrap:anywhere}pre{background:var(--wash);border:1px solid var(--line);border-radius:7px;padding:18px;overflow:auto;line-height:1.65}pre code{padding:0;background:none;white-space:pre;overflow-wrap:normal}.toc{position:sticky;top:calc(var(--header-height) + 28px);align-self:start;max-height:calc(100dvh - var(--header-height) - 50px);overflow:auto;scrollbar-width:thin;border-left:1px solid var(--line);padding-left:18px;font-size:11px;color:var(--muted);line-height:1.6}.toc strong{display:block;font-size:11px;margin:0 0 10px}.toc ul{list-style:none;margin:0;padding:0 0 0 10px}.toc nav>ul{padding:0}.toc li{margin:6px 0}.toc a{color:var(--muted)}.toc a[aria-current]{color:var(--accent);font-weight:650}.notice,blockquote{border-left:3px solid #d39537;background:var(--notice);margin:20px 0;padding:4px 16px}table{display:block;overflow:auto;border-collapse:collapse;width:100%;font-size:13px;margin:20px 0}th,td{border:1px solid var(--line);padding:10px 13px;text-align:left;vertical-align:top}th{background:var(--wash)}.cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:22px 0}.card,.learning-path a{border:1px solid var(--line);border-radius:7px;padding:20px;display:block;text-decoration:none!important}.card:hover,.learning-path a:hover{border-color:var(--accent);background:var(--card)}.card strong,.learning-path strong{display:block;font-size:17px;margin-bottom:6px;color:var(--ink)}.card span,.learning-path span{display:block;font-size:13px;color:var(--muted)}.learning-path{display:grid;gap:12px;margin:22px 0}.learning-path a{background:var(--card)}.chapter-pagination{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:42px}.chapter-pagination a{border:1px solid var(--line);border-radius:7px;padding:13px 17px;line-height:1.5}.chapter-pagination a:hover{border-color:var(--accent)}.chapter-pagination a[rel=next]{text-align:right}.chapter-pagination small{display:block;color:var(--muted);font-size:11px;margin-bottom:4px}.chapter-pagination strong{font-size:14px}footer{display:flex;flex-wrap:wrap;gap:14px 24px;font-size:11px;color:var(--muted);border-top:1px solid var(--line);padding-top:20px;margin-top:24px}footer a{color:var(--muted)}
+.code-block,.example-source{background:#0d1117;border:1px solid #303d49;border-radius:8px;overflow:hidden;margin:20px 0}.code-meta{display:flex;justify-content:space-between;align-items:center;padding:9px 15px;background:#17212b;color:#b6c8d4;font-size:11px}.code-meta button{font:inherit;font-size:11px;color:#e3ecef;background:#2b3540;border:1px solid #536170;border-radius:4px;padding:3px 9px}.code-block pre,.example-source pre{border:0;border-radius:0;background:#0d1117!important;color:#e6edf3;padding:18px;margin:0;font-size:12px;line-height:1.8}.code-block code,.example-source code{background:none;color:inherit}.code-block .highlight,.example-source .highlight{overflow:auto}.worked-example{border:1px solid var(--line);border-radius:8px;overflow:hidden;margin:24px 0;background:var(--wash)}.example-heading{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:13px 16px;font-size:12px}.example-heading>a{font-size:11px;font-weight:650}.example-source{margin:0;border-radius:0;max-height:380px;overflow:auto}.worked-example figure{margin:0;background:var(--surface)}.worked-example figcaption{font-size:11px;padding:8px 15px;color:var(--muted);border-bottom:1px solid var(--line)}.worked-example iframe{display:block;width:100%;height:525px;border:0}main[aria-busy=true]{opacity:.65}.runtime-picker{display:flex;gap:6px;border-bottom:1px solid var(--line);margin:24px 0 16px}.runtime-picker button{border:0;background:none;color:var(--muted);padding:9px 17px;border-bottom:2px solid transparent;font-size:13px;font-weight:650}.runtime-picker button[aria-selected=true]{color:var(--accent);border-color:var(--accent)}.start-actions{display:flex;flex-wrap:wrap;gap:12px;margin:22px 0}.start-actions a{display:inline-flex;align-items:center;padding:8px 16px;background:var(--accent);color:var(--surface);font-size:13px;font-weight:650;border-radius:5px}.start-actions a+ a{background:var(--wash);color:var(--ink);border:1px solid var(--line)}
+@media(min-width:1600px){main{padding:28px 56px}.article-grid{gap:64px}}
+@media(max-width:1180px){.article-grid{grid-template-columns:minmax(0,1fr)}.toc{display:none}.topbar{gap:16px}.header-links{gap:10px}.github-link{display:none}.search-area{max-width:240px}.primary-nav{gap:16px}}
+@media(max-width:900px){:root{--header-height:112px}.topbar{height:var(--header-height);padding:10px 16px;gap:12px;flex-wrap:wrap;align-content:center}.brand-logo{width:112px}.header-links{gap:10px;margin-left:auto;font-size:10px}.header-links .version{display:none}.theme-control select{font-size:10px;padding:4px}.primary-nav{height:30px;font-size:12px;gap:16px}.search-area{flex-basis:100%;max-width:none;order:6}.search-area input{padding:7px 30px 7px 10px}.search-area>kbd{top:6px}:is(.language-menu,.version-menu) summary{font-size:10px}.shell{display:block}main{padding:22px 22px 32px}.sidebar{position:static;height:auto;max-height:320px;border-right:0;border-bottom:1px solid var(--line)}.js .sidebar{position:fixed;top:var(--header-height);bottom:0;left:0;width:290px;max-height:none;height:calc(100dvh - var(--header-height));z-index:25;background:var(--surface);transform:translateX(-100%);visibility:hidden;border-right:1px solid var(--line)}.js .nav-toggle:not([hidden]){display:block;border:1px solid var(--line);border-radius:4px;padding:4px 7px;color:var(--ink);background:var(--surface);font-size:10px}.nav-open .sidebar{transform:translateX(0);visibility:visible}.nav-open{overflow:hidden}.nav-backdrop:not([hidden]){display:block;position:fixed;inset:var(--header-height) 0 0;background:#0006;border:0;z-index:24}.cards{grid-template-columns:1fr}.chapter-pagination{gap:10px}.chapter-pagination a{padding:11px}h1{font-size:34px}.lead{font-size:16px}.search-popover{left:0;right:auto;width:100%;max-width:none}.breadcrumbs{font-size:10px;flex-wrap:wrap}.article-grid{gap:0}}
+@media(max-width:480px){.topbar{gap:8px}.brand-logo{width:95px}.primary-nav{gap:10px;font-size:11px}.header-links{gap:7px}:is(.language-menu,.version-menu) summary{max-width:62px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.nav-toggle{max-width:50px;overflow:hidden}main{padding-left:18px;padding-right:18px}.chapter-pagination{grid-template-columns:1fr}.chapter-pagination a[rel=next]{text-align:left}}
+@media print{.topbar,.sidebar,.toc,.nav-backdrop,.code-meta button,.chapter-pagination,footer{display:none!important}.shell,.article-grid{display:block}main{padding:0}.worked-example iframe{display:none}pre{white-space:pre-wrap}:root,:root[data-theme],:root:not([data-theme]){color-scheme:light;--surface:#fff;--ink:#202124;--muted:#606770;--accent:#c9252d;--line:#ddd;--wash:#f7f7f8}}
+
+@media(max-width:900px){.primary-nav{order:4}.search-area{order:5;flex-basis:160px;min-width:0}.topbar>.header-links{order:3}}
+/* Editable documentation examples. Both variants remain visible without JavaScript. */
+.interactive-code{min-width:0}.code-languages{display:flex;gap:5px;align-items:center}.code-languages button[aria-pressed=true]{background:var(--accent);color:var(--surface);border-color:var(--accent)}.code-meta{flex-wrap:wrap;gap:8px}.code-meta .edit-code{margin-left:auto}.js .interactive-code:not([data-language=typescript]) [data-code-pane=typescript],.js .interactive-code[data-language=typescript] [data-code-pane=javascript]{display:none}.interactive-code [hidden]{display:none!important}.inline-editor{height:350px;min-height:200px;max-height:750px;resize:vertical;overflow:auto;background:var(--surface);color:var(--ink)}.inline-actions{display:flex;flex-wrap:wrap;align-items:center;gap:7px;padding:10px;background:var(--wash);border-top:1px solid var(--line);font-size:11px}.inline-actions button,.inline-preview-toolbar button,.inline-preview-toolbar a{font:inherit;padding:5px 8px;border:1px solid var(--line);border-radius:4px;background:var(--surface);color:var(--ink)}.inline-actions label{display:flex;align-items:center;gap:4px}.inline-status{font-size:11px;padding:8px 12px;margin:0;color:var(--muted);background:var(--surface)}.interactive-code .inline-error{font-size:11px;white-space:pre-wrap;overflow-wrap:anywhere;margin:0;border-left:3px solid var(--accent);color:var(--ink);background:var(--wash);padding:10px}.inline-preview{background:var(--wash);min-width:0;border-top:1px solid var(--line)}.inline-preview-toolbar{display:flex;align-items:center;justify-content:center;gap:8px;min-height:45px;font-size:11px;border-bottom:1px solid var(--line)}.inline-download:not([href]){opacity:.5;pointer-events:none}.inline-canvas{height:350px;overflow:auto;padding:14px;text-align:center}.inline-canvas canvas{display:block;margin:auto;max-width:none;background:white;box-shadow:0 2px 12px #0003}.inline-text{padding:8px 12px;font-size:11px;color:var(--ink);max-height:120px;overflow:auto}.inline-text p{white-space:pre-wrap}.interactive-code[data-stale=true] .inline-canvas{outline:2px solid var(--line);outline-offset:-2px}.interactive-code .cm-tooltip{background:var(--surface);color:var(--ink)}.interactive-code.is-editing[data-runnable=true]{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.interactive-code.is-editing[data-runnable=true]>.code-meta{grid-column:1/-1}.interactive-code.is-editing[data-runnable=true]>.inline-editor{grid-column:1;grid-row:2}.interactive-code.is-editing[data-runnable=true]>.inline-actions{grid-column:1;grid-row:3}.interactive-code.is-editing[data-runnable=true]>.inline-status{grid-column:1;grid-row:4}.interactive-code.is-editing[data-runnable=true]>.inline-error{grid-column:1;grid-row:5}.interactive-code.is-editing[data-runnable=true]>.inline-preview{grid-column:2;grid-row:2/span 4;border-top:0;border-left:1px solid var(--line)}.interactive-code .cm-content{white-space:pre!important}.interactive-code .cm-editor{height:100%}.worked-example>.interactive-code{margin:0;border:0;border-radius:0}
+@media(max-width:1000px){.interactive-code.is-editing[data-runnable=true]{display:block}.inline-editor{height:300px}.inline-canvas{height:360px}.interactive-code.is-editing[data-runnable=true]>.inline-preview{border-left:0;border-top:1px solid var(--line)}}
diff --git a/static/assets/docs.js b/static/assets/docs.js
new file mode 100644
index 00000000..af6a6e39
--- /dev/null
+++ b/static/assets/docs.js
@@ -0,0 +1,198 @@
+(() => {
+ const script = document.currentScript;
+ const ui = JSON.parse(script.dataset.ui);
+ const input = document.querySelector('#search');
+ const results = document.querySelector('#search-results');
+ const status = document.querySelector('#search-status');
+ document.documentElement.classList.add('js');
+ const menu = document.querySelector('.nav-toggle');
+ const backdrop = document.querySelector('.nav-backdrop');
+ menu.hidden = false;
+ function closeMenu(focus = false) { const wasOpen = document.body.classList.contains('nav-open'); document.body.classList.remove('nav-open'); document.querySelector('main').inert = false; menu.setAttribute('aria-expanded', 'false'); backdrop.hidden = true; if (focus && wasOpen) menu.focus(); }
+ menu.addEventListener('click', () => { const open = menu.getAttribute('aria-expanded') !== 'true'; document.body.classList.toggle('nav-open', open); document.querySelector('main').inert = open; menu.setAttribute('aria-expanded', String(open)); backdrop.hidden = !open; });
+ backdrop.addEventListener('click', () => closeMenu(true));
+ document.addEventListener('keydown', event => { if (event.key === 'Escape') { closeMenu(true); document.querySelector('.search-popover').hidden = true; } if (event.key === '/' && !/INPUT|TEXTAREA|SELECT/.test(document.activeElement.tagName) && !document.activeElement.isContentEditable) { event.preventDefault(); input.focus(); } });
+ let corpus;
+ function getCorpus() {
+ return corpus ??= fetch(script.dataset.index).then(response => { if (!response.ok) throw new Error('Search index unavailable'); return response.json(); }).catch(error => { corpus = undefined; throw error; });
+ }
+ let request = 0;
+ input.addEventListener('focus', () => { if (input.value.trim()) document.querySelector('.search-popover').hidden = false; });
+ input.addEventListener('keydown', event => { if (event.key === 'ArrowDown') { const first = results.querySelector('a'); if (first) { event.preventDefault(); first.focus(); } } });
+ results.addEventListener('keydown', event => {
+ if (!['ArrowDown', 'ArrowUp'].includes(event.key)) return;
+ event.preventDefault();
+ const links = [...results.querySelectorAll('a')], current = links.indexOf(document.activeElement);
+ if (event.key === 'ArrowUp' && current <= 0) input.focus();
+ else links[(current + (event.key === 'ArrowDown' ? 1 : links.length - 1)) % links.length]?.focus();
+ });
+ input.addEventListener('input', async () => {
+ const current = ++request;
+ const query = input.value.trim().toLowerCase();
+ results.replaceChildren();
+ results.hidden = !query;
+ status.textContent = '';
+ document.querySelector('.search-popover').hidden = !query;
+ if (!query) return;
+ try {
+ const { pages } = await getCorpus();
+ if (request !== current) return;
+ const terms = query.match(/[\p{L}\p{N}_]+/gu) || [];
+ const hits = pages.map(page => ({ page, score: terms.reduce((score, term) => score
+ + (`${page.title} ${page.id}`.toLowerCase().includes(term) ? 12 : 0)
+ + (page.description.toLowerCase().includes(term) ? 5 : 0)
+ + (page.markdown.toLowerCase().includes(term) ? 1 : 0), 0) }))
+ .filter(hit => hit.score > 0).sort((a, b) => b.score - a.score || a.page.id.localeCompare(b.page.id)).slice(0, 8);
+ for (const { page } of hits) {
+ const li = document.createElement('li');
+ const link = document.createElement('a');
+ link.href = page.path;
+ link.textContent = page.title;
+ li.append(link);
+ results.append(li);
+ }
+ status.textContent = hits.length ? ui.results.replace('{count}', hits.length) : ui.noResults;
+ } catch {
+ if (request === current) status.textContent = ui.searchFailed;
+ }
+ });
+ let inlineModule;
+ const codeUI = JSON.parse(script.dataset.codeUi);
+ function examples(scope) {
+ inlineModule ??= import(new URL('./inline-examples.js', script.src));
+ inlineModule.then(module => { if (scope === document || scope.isConnected) module.enhanceExamples(scope, codeUI); }).catch(console.error);
+ }
+ let observer;
+ function enhance(scope) {
+ observer?.disconnect();
+ const headings = [...scope.querySelectorAll('article h2[id], article h3[id]')];
+ observer = new IntersectionObserver(entries => {
+ const entry = entries.find(item => item.isIntersecting);
+ if (!entry) return;
+ for (const link of document.querySelectorAll('.toc a')) { if (decodeURIComponent(new URL(link.href).hash.slice(1)) === entry.target.id) link.setAttribute('aria-current', 'location'); else link.removeAttribute('aria-current'); }
+ }, { rootMargin: '-80px 0px -65% 0px' });
+ headings.forEach(heading => observer.observe(heading));
+ const kind = scope.dataset?.pageKind || document.querySelector('main').dataset.pageKind;
+ for (const link of document.querySelectorAll('.primary-nav a')) { if (link.dataset.section === (kind === 'workspace' ? 'playground' : 'docs')) link.setAttribute('aria-current', 'page'); else link.removeAttribute('aria-current'); }
+ for (const picker of scope.querySelectorAll('[data-runtime-picker]')) {
+ const buttons = [...picker.querySelectorAll('button')];
+ const panels = [...scope.querySelectorAll('[data-runtime-panel]')];
+ function choose(name) { buttons.forEach(button => { button.setAttribute('aria-selected', String(button.dataset.runtime === name)); button.tabIndex = button.dataset.runtime === name ? 0 : -1; }); panels.forEach(panel => { panel.hidden = panel.dataset.runtimePanel !== name; }); }
+ picker.addEventListener('click', event => { const button = event.target.closest('[data-runtime]'); if (button) choose(button.dataset.runtime); });
+ picker.addEventListener('keydown', event => { if (!['ArrowLeft', 'ArrowRight'].includes(event.key)) return; event.preventDefault(); const index = buttons.indexOf(document.activeElement); const next = buttons[(index + (event.key === 'ArrowRight' ? 1 : buttons.length - 1)) % buttons.length]; choose(next.dataset.runtime); next.focus(); });
+ choose('node');
+ }
+ examples(scope);
+ for (const button of scope.querySelectorAll('.copy-example')) {
+ if (button.closest('.interactive-code')) continue;
+ const code = button.closest('.code-block, .example-source')?.querySelector('code');
+ if (!code) continue;
+ button.setAttribute('aria-label', ui.copy);
+ button.addEventListener('click', async () => {
+ try { await navigator.clipboard.writeText(code.textContent); button.textContent = ui.copied; }
+ catch { button.textContent = ui.copyFailed; }
+ });
+ }
+ }
+ enhance(document);
+
+ // Full HTML is always served for crawlers and direct links. Enhance only chapter navigation.
+ const cache = new Map();
+ let navigation = 0;
+ function chapter(link) {
+ if (!link || link.hasAttribute('data-version') || link.hasAttribute('data-language') || link.target || link.hasAttribute('download')) return null;
+ const url = new URL(link.href, location.href);
+ const base = new URL(script.dataset.index, location.href).pathname.replace(/docs-index\.json$/, '');
+ if (url.origin !== location.origin || !url.pathname.startsWith(base) || url.pathname.includes('/playground/standalone.html') || /\.[a-z0-9]+$/i.test(url.pathname)) return null;
+ const relative = url.pathname.slice(new URL(script.dataset.index, location.href).pathname.replace(/docs-index\.json$/, '').length);
+ if (script.dataset.language === 'en' && /^(de|fr|es|pt-br)\//.test(relative)) return null;
+ return url;
+ }
+ function getPage(url) {
+ const key = url.pathname;
+ if (!cache.has(key)) {
+ cache.set(key, fetch(key, { headers: { Accept: 'text/html' } }).then(response => {
+ if (!response.ok) throw new Error('Could not load chapter');
+ return response.text();
+ }).catch(error => { cache.delete(key); throw error; }));
+ if (cache.size > 20) cache.delete(cache.keys().next().value);
+ }
+ return cache.get(key);
+ }
+ let workspace;
+ let workspaceController;
+ async function activateWorkspace(main, url) {
+ if (main.dataset.pageKind !== 'workspace') return;
+ if (workspaceController && main === workspace) { workspaceController.resume(url); return; }
+ const { mountPlayground } = await import(script.dataset.playground);
+ if (!main.isConnected) return;
+ const { pages } = await getCorpus().catch(() => ({ pages: [] }));
+ if (!main.isConnected) return;
+ workspace = main;
+ workspaceController = mountPlayground(main, { url: url.href, version: script.dataset.version, docLinks: Object.fromEntries(pages.map(page => [page.translationKey + '/', page.path])) });
+ }
+ activateWorkspace(document.querySelector('main'), new URL(location.href)).catch(error => { document.querySelector('[data-workspace]')?.prepend(Object.assign(document.createElement('p'), { textContent: error.message })); });
+ async function navigate(url, push = true, scroll) {
+ const current = ++navigation;
+ document.querySelector('main').setAttribute('aria-busy', 'true');
+ try {
+ const html = await getPage(url);
+ if (current !== navigation) return;
+ const next = new DOMParser().parseFromString(html, 'text/html');
+ const incoming = next.querySelector('main');
+ const main = incoming?.dataset.pageKind === 'workspace' && workspace ? workspace : incoming;
+ if (!main) throw new Error('Missing chapter content');
+ if (push) {
+ history.replaceState({ docs: true, scroll: [scrollX, scrollY] }, '', location.href);
+ history.pushState({ docs: true, scroll: [0, 0] }, '', url);
+ }
+ (await inlineModule)?.disposeExamples();
+ if (current !== navigation) return;
+ if (document.querySelector('main') === workspace) workspaceController.suspend();
+ document.querySelector('main').replaceWith(main);
+ const sidebar = document.querySelector('.sidebar');
+ const openGroups = new Set([...sidebar.querySelectorAll('details[open]')].map(group => group.dataset.navGroup));
+ const incomingSidebar = next.querySelector('.sidebar');
+ for (const group of incomingSidebar.querySelectorAll('details')) if (openGroups.has(group.dataset.navGroup)) group.open = true;
+ const sidebarScroll = sidebar.scrollTop;
+ sidebar.replaceWith(incomingSidebar);
+ incomingSidebar.scrollTop = sidebarScroll;
+ closeMenu();
+ document.querySelector('.search-popover').hidden = true;
+ document.title = next.title;
+ document.querySelector('.language-menu').replaceWith(next.querySelector('.language-menu'));
+ document.querySelector('.version-menu').replaceWith(next.querySelector('.version-menu'));
+ document.head.querySelectorAll('link[hreflang]').forEach(link => link.remove());
+ for (const link of next.head.querySelectorAll('link[hreflang]')) document.head.append(link);
+ for (const selector of ['meta[name="description"]', 'link[rel="canonical"]', 'link[rel="alternate"][type="text/markdown"]', 'meta[property="og:title"]', 'meta[property="og:description"]', 'meta[property="og:url"]', 'script[type="application/ld+json"]']) {
+ const incoming = next.querySelector(selector), existing = document.head.querySelector(selector);
+ if (incoming && existing) existing.replaceWith(incoming);
+ }
+ for (const link of document.querySelectorAll('.sidebar a')) {
+ if (new URL(link.href).pathname === url.pathname) link.setAttribute('aria-current', 'page'); else link.removeAttribute('aria-current');
+ }
+ enhance(main);
+ await activateWorkspace(main, url);
+ main.removeAttribute('aria-busy');
+ if (scroll) window.scrollTo(...scroll);
+ else if (url.hash) document.getElementById(decodeURIComponent(url.hash.slice(1)))?.scrollIntoView();
+ else window.scrollTo(0, 0);
+ if (push) main.focus({ preventScroll: true });
+ document.dispatchEvent(new CustomEvent('docs:navigated', { detail: { path: url.pathname } }));
+ } catch { if (current === navigation) location.assign(url.href); }
+ }
+ history.replaceState({ docs: true, scroll: [scrollX, scrollY] }, '', location.href);
+ history.scrollRestoration = 'manual';
+ document.addEventListener('click', event => {
+ if (!event.target.closest('.search-area')) document.querySelector('.search-popover').hidden = true;
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
+ const url = chapter(event.target.closest('a[href]'));
+ if (!url || (url.pathname === location.pathname && url.hash)) return;
+ event.preventDefault(); navigate(url);
+ });
+ window.addEventListener('popstate', event => { if (event.state?.docs) navigate(new URL(location.href), false, event.state.scroll); });
+ document.addEventListener('pointerover', event => {
+ const url = chapter(event.target.closest('a[href]'));
+ if (url && url.pathname !== location.pathname) getPage(url).catch(() => {});
+ });
+})();
diff --git a/static/assets/inline-examples.js b/static/assets/inline-examples.js
new file mode 100644
index 00000000..2eec5542
--- /dev/null
+++ b/static/assets/inline-examples.js
@@ -0,0 +1,151 @@
+import { createEditor } from '../playground/editor.js';
+
+const active = new Set();
+const drafts = new Map();
+let pdfModule;
+function pdfjs() {
+ return pdfModule ??= import('../playground/vendor/pdf.mjs').then(module => {
+ module.GlobalWorkerOptions.workerSrc = new URL('../playground/vendor/pdf.worker.mjs', import.meta.url).href;
+ return module;
+ });
+}
+export function disposeExamples() { for (const controller of active) controller.destroy(); active.clear(); }
+
+export function enhanceExamples(scope, ui) {
+ const controllers = [];
+ for (const [index, block] of [...scope.querySelectorAll('.interactive-code')].entries()) {
+ if (block.dataset.enhanced) continue;
+ block.dataset.enhanced = 'true';
+ const $ = selector => block.querySelector(selector);
+ const key = location.pathname + ':' + block.dataset.exampleKey + ':' + index;
+ const original = Object.fromEntries([...block.querySelectorAll('[data-code-pane]')].map(pane => [pane.dataset.codePane, pane.querySelector('code').textContent.trim()]));
+ const saved = drafts.get(key);
+ const versions = { ...original, ...saved?.versions };
+ const histories = { ...saved?.histories };
+ let language = saved?.language || 'javascript', editor, loading = false, revision = 0, timer, worker, timeout;
+ let destroyed = false, pdf, pdfLoad, pdfUrl, pageNumber = 1, pageRevision = 0, task;
+ const runnable = block.dataset.runnable === 'true';
+ function status(text) { $('.inline-status').hidden = false; $('.inline-status').textContent = text; }
+ function save() {
+ if (editor) { versions[language] = editor.getValue(); histories[language] = editor.serialize(); }
+ drafts.delete(key); drafts.set(key, { versions: { ...versions }, histories: { ...histories }, language, edited: !!editor });
+ while (drafts.size > 60) drafts.delete(drafts.keys().next().value);
+ }
+ function stop() { worker?.terminate(); worker = undefined; clearTimeout(timeout); }
+ function error(message) { $('.inline-error').hidden = false; $('.inline-error').textContent = message; status(ui.codeFailed); }
+ function schedule() { clearTimeout(timer); if (!destroyed && runnable && $('[data-code-live]').checked) timer = setTimeout(run, 650); }
+ function changed() {
+ if (loading || !editor) return;
+ revision++; stop(); clearTimeout(timer); save();
+ $('.inline-error').hidden = true;
+ $('.inline-download')?.removeAttribute('href');
+ block.dataset.stale = 'true';
+ status(runnable ? ui.codeWaiting : ui[block.dataset.context === 'node' ? 'codeNodeContext' : 'codeContext']);
+ schedule();
+ }
+ function choose(value) {
+ save(); revision++; stop(); clearTimeout(timer); language = value; block.dataset.language = value;
+ block.querySelectorAll('[data-code-language]').forEach(button => button.setAttribute('aria-pressed', String(button.dataset.codeLanguage === value)));
+ block.querySelectorAll('[data-code-pane]').forEach(pane => { pane.hidden = !!editor || pane.dataset.codePane !== value; });
+ if (editor) {
+ loading = true; editor.setLanguage(value);
+ if (histories[value]) { try { editor.restore(histories[value]); } catch { editor.setValue(versions[value]); } }
+ else editor.resetValue(versions[value]);
+ editor.setLanguage(value);
+ loading = false; changed();
+ }
+ save();
+ }
+ function edit() {
+ if (editor || destroyed) return;
+ $('.inline-editor').hidden = false; $('.inline-actions').hidden = false; $('.edit-code').hidden = true;
+ block.classList.add('is-editing');
+ editor = createEditor($('.inline-editor'), versions[language], changed, run, { language, sourceType: 'module' });
+ if (histories[language]) { loading = true; try { editor.restore(histories[language]); } catch {} loading = false; }
+ choose(language);
+ status(runnable ? ui.codeWaiting : ui[block.dataset.context === 'node' ? 'codeNodeContext' : 'codeContext']);
+ }
+ async function draw(doc, number, current) {
+ const page = await doc.getPage(number);
+ const scale = Math.max(0.2, Math.min(1.25, ($('.inline-canvas').clientWidth - 28) / page.getViewport({ scale: 1 }).width));
+ const viewport = page.getViewport({ scale });
+ const canvas = document.createElement('canvas'); const ratio = Math.min(devicePixelRatio || 1, 2);
+ canvas.width = Math.floor(viewport.width * ratio); canvas.height = Math.floor(viewport.height * ratio);
+ canvas.style.width = viewport.width + 'px'; canvas.style.height = viewport.height + 'px';
+ canvas.setAttribute('role', 'img'); canvas.setAttribute('aria-label', ui.codePdf + ' ' + number);
+ task = page.render({ canvasContext: canvas.getContext('2d'), viewport, transform: [ratio, 0, 0, ratio, 0, 0] });
+ await task.promise;
+ const text = await page.getTextContent();
+ if (!current()) return false;
+ $('.inline-canvas').replaceChildren(canvas); $('.inline-text p').textContent = text.items.map(item => item.str).join(' ');
+ $('.inline-page-count').textContent = `${number} / ${doc.numPages}`;
+ $('[data-code-action="previous"]').disabled = number === 1; $('[data-code-action="next"]').disabled = number === doc.numPages;
+ return true;
+ }
+ async function accept(data, current) {
+ let pending;
+ try {
+ const module = await pdfjs();
+ if (destroyed || current !== revision) return;
+ const blob = new Blob([data.buffer], { type: 'application/pdf' });
+ pending = module.getDocument({ data: new Uint8Array(data.buffer), password: data.password });
+ const doc = await pending.promise;
+ if (destroyed || current !== revision) { await pending.destroy(); return; }
+ $('.inline-preview').hidden = false;
+ if (!await draw(doc, 1, () => !destroyed && current === revision)) { await pending.destroy(); return; }
+ const old = pdfLoad, oldUrl = pdfUrl; pdf = doc; pdfLoad = pending; pageNumber = 1;
+ pdfUrl = URL.createObjectURL(blob);
+ $('.inline-download').href = pdfUrl; $('.inline-error').hidden = true; block.dataset.stale = 'false';
+ status(ui.codeReady); old?.destroy(); if (oldUrl) URL.revokeObjectURL(oldUrl);
+ } catch (failure) { if (!destroyed && current === revision) error(failure.message); if (pending !== pdfLoad) pending?.destroy(); }
+ }
+ function run() {
+ if (!editor || destroyed) return;
+ stop(); clearTimeout(timer); const current = ++revision;
+ const source = editor.getValue();
+ if (source.length > 500000) { error(ui.codeTooLarge); return; }
+ $('.inline-error').hidden = true;
+ const [syntax] = editor.diagnose(); if (syntax) { error(syntax.message); return; }
+ status(ui.codeRendering);
+ const instance = worker = new Worker(new URL('../playground/worker.js', import.meta.url));
+ instance.onmessage = ({ data }) => {
+ if (destroyed || instance !== worker || current !== revision) return;
+ stop();
+ if (data.diagnostics) editor.reportDiagnostics(data.diagnostics);
+ if (data.error) { error(data.error); return; }
+ if (data.checked) { status(ui.codeChecked); return; }
+ accept(data, current);
+ };
+ instance.onerror = event => { if (instance === worker) { stop(); error(event.message || ui.codeFailed); } };
+ timeout = setTimeout(() => { if (current === revision) { stop(); error(ui.codeTimeout); } }, 15000);
+ instance.postMessage({ source, language, checkOnly: !runnable, syntaxOnly: !runnable });
+ }
+ for (const button of block.querySelectorAll('[data-code-language]')) button.addEventListener('click', () => choose(button.dataset.codeLanguage));
+ $('.edit-code').addEventListener('click', () => { edit(); editor.focus(); });
+ $('.copy-example').addEventListener('click', async () => {
+ try { await navigator.clipboard.writeText(editor ? editor.getValue() : versions[language]); $('.copy-example').textContent = ui.copied; }
+ catch { status(ui.copyFailed); }
+ });
+ block.addEventListener('click', async event => {
+ const action = event.target.closest('[data-code-action]')?.dataset.codeAction;
+ if (!action || !editor) return;
+ if (action === 'undo' || action === 'redo') editor[action]();
+ if (action === 'run') run();
+ if (action === 'reset') { editor.setValue(original[language]); editor.focus(); }
+ if ((action === 'previous' || action === 'next') && pdf) {
+ pageNumber = Math.min(pdf.numPages, Math.max(1, pageNumber + (action === 'next' ? 1 : -1)));
+ const current = ++pageRevision; task?.cancel();
+ try { await draw(pdf, pageNumber, () => !destroyed && current === pageRevision); } catch (failure) { if (failure.name !== 'RenderingCancelledException') error(failure.message); }
+ }
+ });
+ $('[data-code-live]')?.addEventListener('change', () => { if ($('[data-code-live]').checked) run(); else clearTimeout(timer); });
+ choose(language);
+ const observer = new IntersectionObserver(entries => { if (entries.some(entry => entry.isIntersecting)) { observer.disconnect(); if (block.closest('.worked-example')) edit(); } }, { rootMargin: '100px' });
+ observer.observe(block);
+ if (saved?.edited) edit();
+ const controller = { destroy() { if (destroyed) return; save(); destroyed = true; revision++; pageRevision++; stop(); clearTimeout(timer); observer.disconnect(); task?.cancel(); editor?.destroy(); pdfLoad?.destroy(); if (pdfUrl) URL.revokeObjectURL(pdfUrl); active.delete(controller); } };
+ active.add(controller); controllers.push(controller);
+ for (const button of block.querySelectorAll('.code-meta button')) button.disabled = false;
+ }
+ return controllers;
+}
diff --git a/static/assets/workspace.css b/static/assets/workspace.css
new file mode 100644
index 00000000..536a6631
--- /dev/null
+++ b/static/assets/workspace.css
@@ -0,0 +1,3 @@
+.workspace-page .article-grid{grid-template-columns:minmax(0,1fr);max-width:none}.workspace-page h1{font-size:30px;margin-bottom:8px}.workspace-page .lead{font-size:14px;margin-bottom:16px}.workspace-page .breadcrumbs{margin-bottom:14px}.workspace-page .article-body{max-width:none}.workspace-page article{font-size:13px}.playground-app{font-size:12px}.workspace-heading{display:flex;justify-content:flex-end;font-size:10px;color:var(--muted);margin-bottom:8px}.playground-app .toolbar{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}.playground-app label{display:inline-flex;align-items:center;gap:7px;font-size:11px}.playground-app button,.playground-app select,.playground-app .import{border:1px solid var(--line);color:var(--ink);background:var(--surface);border-radius:4px;padding:6px 9px;font-size:11px;line-height:1.5}.playground-app .actions{display:flex;flex-wrap:wrap;gap:6px;align-items:center}.playground-app .actions label{white-space:nowrap}.playground-app .primary{background:#c9252d;border-color:#c9252d;color:white;font-weight:650}.playground-app .primary kbd{font-size:9px;margin-left:7px;opacity:.8}.playground-app .import input{position:absolute;width:1px;height:1px;opacity:0}.playground-app .import:focus-within{outline:3px solid var(--accent)}.playground-app .saved-documents{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:14px}.playground-app .saved-documents input{background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:4px;padding:6px;font-size:11px;max-width:160px}.playground-app .saved-documents select{max-width:190px}.playground-app .saved-documents>span{font-size:10px;color:var(--muted)}.playground-app .workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px}.playground-app .panel{border:1px solid var(--line);border-radius:6px;overflow:hidden;min-width:0;background:var(--surface);display:flex;flex-direction:column}.playground-app .panel-head{display:flex;justify-content:space-between;align-items:center;gap:8px;min-height:47px;padding:8px 12px;border-bottom:1px solid var(--line)}.playground-app h2{font-size:12px;letter-spacing:0;margin:0;line-height:1.4}.playground-app .panel-head>span{font-size:10px;color:var(--muted)}.playground-app .panel-head>div{display:flex;gap:10px;align-items:center;font-size:10px}.playground-app #editor{height:510px;min-height:250px}.playground-app #preview,.playground-app #preview-empty{height:510px}.playground-app #preview-empty{display:grid;align-content:center;text-align:center;background:var(--wash);color:var(--muted);font-size:13px}.playground-app #preview{background:var(--wash);overflow:auto}.playground-app .preview-controls{display:flex;justify-content:center;align-items:center;gap:10px;padding:7px;border-bottom:1px solid var(--line);font-size:10px}.playground-app .preview-controls button,.playground-app .preview-controls select{padding:2px 7px;font-size:10px}.playground-app .canvas-scroll{height:416px;overflow:auto;padding:14px;background:var(--wash);text-align:center}.playground-app #pdf-canvas{display:block;margin:auto;background:#fff;box-shadow:0 3px 14px #0003;max-width:none}.playground-app .page-text{font-size:10px;padding:5px 12px;max-height:90px;overflow:auto}.playground-app .page-text p{white-space:pre-wrap;text-align:left}.playground-app .editor-footer,.playground-app .preview-footer{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:6px;padding:7px 10px;border-top:1px solid var(--line);min-height:43px;font-size:10px;color:var(--muted)}.playground-app .editor-footer button{padding:2px 5px;font-size:9px}.playground-app .status-row{display:flex;justify-content:space-between;gap:14px;font-size:10px;color:var(--muted)}.playground-app #status{font-weight:600}.playground-app #status[data-error=true]{color:var(--accent)}.playground-app #error{white-space:pre-wrap;overflow-wrap:anywhere;background:var(--card);border-color:var(--accent);font-size:12px}.playground-app .help{border-top:1px solid var(--line);padding-top:12px;color:var(--muted);font-size:11px}.playground-app .help p{margin:10px 0}.playground-app #preview[data-stale=true]{outline:2px solid #d6ac5f;outline-offset:-2px}.playground-app .cm-tooltip{background:var(--surface);color:var(--ink);border:1px solid var(--line)}.playground-app .cm-panels{background:var(--wash);color:var(--ink)}
+@media(min-width:1600px){.playground-app #editor,.playground-app #preview,.playground-app #preview-empty{height:590px}.playground-app .canvas-scroll{height:496px}}
+@media(max-width:1100px){.playground-app .workspace{grid-template-columns:1fr}.playground-app #editor{height:380px}.playground-app .saved-documents>span{flex-basis:100%}.playground-app .status-row{flex-wrap:wrap;gap:0}.playground-app .status-row>span{margin-bottom:10px}}
diff --git a/static/de/docs-index.json b/static/de/docs-index.json
new file mode 100644
index 00000000..0cae31aa
--- /dev/null
+++ b/static/de/docs-index.json
@@ -0,0 +1,818 @@
+{
+ "version": "0.3",
+ "language": "de",
+ "pages": [
+ {
+ "id": "de/index",
+ "language": "de",
+ "translationKey": "index",
+ "path": "/docs/0.3/de/",
+ "title": "Übersicht",
+ "description": "PDFs mit pdfmake 0.3 erstellen: verständliche Anleitungen, ausführbare Beispiele und Referenz für JavaScript.",
+ "version": "0.3",
+ "sourceDigest": "3be141146a4c948512e50597ef37f878749e249c98a65a0af17c20b1e7cc62b3",
+ "source": "_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/",
+ "uri": "pdfmake://docs/0.3/de/index",
+ "markdown": "# Übersicht\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/\n\nErstelle eine PDF in drei Schritten: Laufzeit einrichten, Inhalt beschreiben und Ausgabe anfordern.\n\n## 1. Laufzeit auswählen\n\n\n\n\nVerwende Node.js 20 oder neuer. Installiere die folgende feste Version, speichere das vollständige Beispiel als `first-pdf.cjs` und starte `node first-pdf.cjs`.\n\n```sh\nnpm install pdfmake@0.3.13\n```\n\n**JavaScript**\n\n```js\nconst pdfmake = require('pdfmake');\n\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const definition = {\n defaultStyle: { font: 'Helvetica' },\n content: [\n { text: 'Hello, pdfmake!', fontSize: 24, bold: true },\n 'Your first PDF, generated in Node.js.'\n ]\n };\n await pdfmake.createPdf(definition).write('document.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\nimport pdfmake from \"pdfmake\";\n\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const definition: TDocumentDefinitions = {\n defaultStyle: { font: 'Helvetica' },\n content: [\n { text: 'Hello, pdfmake!', fontSize: 24, bold: true },\n 'Your first PDF, generated in Node.js.'\n ]\n };\n await pdfmake.createPdf(definition).write('document.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n[Node.js-Schnellstart](/docs/0.3/de/getting-started/server-side/)\n\n\n\n\nIm Browser brauchst du Engine und Schriften in dieser Reihenfolge. Der vollständige Schnellstart enthält einen Download-Button und Fehlerbehandlung.\n\n[Browser-Schnellstart](/docs/0.3/de/getting-started/client-side/)\n\n\n\n## 2. Die Definition verstehen\n\nDie Definition ist ein JavaScript-Objekt, kein HTML. `content` enthält Blöcke in Lesereihenfolge. Dieses Beispiel erzeugt genau die sichtbare PDF. Bearbeite es im Playground und kehre hierher zurück, ohne deinen Arbeitsbereich zu verlieren.\n\n\n\n### Runnable example: 01 · First document\n\n**JavaScript**\n\n```js\n// Define a fresh document in dd. Ctrl/⌘ + Enter to run.\nvar dd = {\n content: [\n { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },\n 'A paragraph, a table, a report. Start here and make it yours.',\n { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\n// Define a fresh document in dd. Ctrl/⌘ + Enter to run.\nvar dd: TDocumentDefinitions = {\n content: [\n { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },\n 'A paragraph, a table, a report. Start here and make it yours.',\n { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }\n ]\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=welcome)\n\n\n\n## 3. Mit dem passenden Baustein weitermachen\n\n- [Deine erste PDF](/docs/0.3/de/learn/first-pdf/)\n- [Das Dokumentmodell](/docs/0.3/de/learn/document-model/)\n- [Stile und Formatierung](/docs/0.3/de/document-definition-object/styling/)\n- [Tabellen](/docs/0.3/de/document-definition-object/tables/)\n- [Schriften und Zeichensätze](/docs/0.3/de/fonts/)\n- [Fehler erkennen und behandeln](/docs/0.3/de/guides/errors/)\n\nVerwende bei jeder Generierung eine neue Definition, weil das Layout das Objekt verändert. Ausgabemethoden liefern Promises: Warte mit `await` und behandle Fehler.\n"
+ },
+ {
+ "id": "de/document-definition-object",
+ "language": "de",
+ "translationKey": "document-definition-object",
+ "path": "/docs/0.3/de/document-definition-object/",
+ "title": "Referenz zur Dokumentdefinition",
+ "description": "Beschreibe PDF-Inhalt, Stile, Seiten und Metadaten mit dem deklarativen Dokumentdefinitionsobjekt von pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "4ba6505e4e79830c1a75f138d92099725eb693602811b878dcbb870190e10ec7",
+ "source": "document-definition-object/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object",
+ "markdown": "# Referenz zur Dokumentdefinition\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/\n\n## Aufbau einer Definition\n\n**JavaScript**\n\n```js\nconst docDefinition = {\n pageSize: 'A4',\n pageOrientation: 'portrait',\n pageMargins: [40, 50, 40, 50],\n defaultStyle: { fontSize: 12 },\n styles: { heading: { fontSize: 20, bold: true } },\n info: { title: 'Example document', author: 'Example author' },\n content: [\n { text: 'Document heading', style: 'heading' },\n 'A plain string becomes a paragraph.',\n { ul: ['First item', 'Second item'] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nconst docDefinition: TDocumentDefinitions = {\n pageSize: 'A4',\n pageOrientation: 'portrait',\n pageMargins: [40, 50, 40, 50],\n defaultStyle: { fontSize: 12 },\n styles: { heading: { fontSize: 20, bold: true } },\n info: { title: 'Example document', author: 'Example author' },\n content: [\n { text: 'Document heading', style: 'heading' },\n 'A plain string becomes a paragraph.',\n { ul: ['First item', 'Second item'] }\n ]\n};\n```\n\nÜbergib die Definition nach der Schriftkonfiguration an die `createPdf`-Methode deiner Laufzeit. Alle numerischen Maße werden in **Punkten** angegeben (72 Punkte pro Zoll). Die Reihenfolge der Seitenränder ist **links, oben, rechts, unten**. Ein `content`-Array bildet einen vertikalen Stapel. Erzeuge für jeden Renderdurchlauf ein neues Objekt; beim Layout werden interne Messwerte und Positionen hinzugefügt.\n\n## Inhaltsknoten\n\n| Knoten | Zweck | Referenz |\n| --- | --- | --- |\n| `{ text: '...' }` | Absatz oder Inline-Textsegmente | [Stile](/docs/0.3/de/document-definition-object/styling/) |\n| `{ stack: [...] }` | Blöcke gruppieren und einen gemeinsamen Stil anwenden | [Stapel](/docs/0.3/de/document-definition-object/stack/) |\n| `{ columns: [...] }` | Inhalte nebeneinander anordnen | [Spalten](/docs/0.3/de/document-definition-object/columns/) |\n| `{ table: { body: [...] } }` | Zeilen, Zellen und wiederholte Kopfzeilen | [Tabellen](/docs/0.3/de/document-definition-object/tables/) |\n| `{ ul: [...] }`, `{ ol: [...] }` | Aufzählungs- und nummerierte Listen | [Listen](/docs/0.3/de/document-definition-object/lists/) |\n| `{ image: 'key' }` | PNG oder JPEG | [Bilder](/docs/0.3/de/document-definition-object/images/) |\n| `{ svg: '
... ' }` | SVG-Vektorgrafik | [SVGs](/docs/0.3/de/document-definition-object/svgs/) |\n| `{ qr: '...' }` | QR-Code | [QR-Code](/docs/0.3/de/document-definition-object/qr/) |\n\n## Dokumentweite Einstellungen\n\n- [Seitengröße, Ausrichtung und Umbrüche](/docs/0.3/de/document-definition-object/page/), [Ränder](/docs/0.3/de/document-definition-object/margins/) und [Abschnitte](/docs/0.3/de/document-definition-object/sections/).\n- [Kopf- und Fußzeilen](/docs/0.3/de/document-definition-object/headers-footers/), [Hintergründe](/docs/0.3/de/document-definition-object/background-layer/) und [Wasserzeichen](/docs/0.3/de/document-definition-object/watermark/).\n- [Metadaten](/docs/0.3/de/document-definition-object/document-medatadata/), [Links](/docs/0.3/de/document-definition-object/links/), [Inhaltsverzeichnis](/docs/0.3/de/document-definition-object/toc/) und [Gliederungen](/docs/0.3/de/document-definition-object/outlines/).\n- [Anhänge](/docs/0.3/de/document-definition-object/attachments/), [Verschlüsselung](/docs/0.3/de/document-definition-object/security/), [PDF/A](/docs/0.3/de/document-definition-object/pdfa/) und [Komprimierung](/docs/0.3/de/document-definition-object/compression/).\n\n## Definition und Rendering-Optionen\n\nInhalt und visuelle Einstellungen gehören in die Definition. `fontLayoutCache` und `bufferPages` gehören in das zweite Argument von `createPdf`. Schriften, Tabellenlayoutregistrierungen und Ressourcenrichtlinien werden über die pdfmake-API festgelegt. Siehe [API-Übersicht](/docs/0.3/de/guides/api-reference/).\n"
+ },
+ {
+ "id": "de/document-definition-object/attachments",
+ "language": "de",
+ "translationKey": "document-definition-object/attachments",
+ "path": "/docs/0.3/de/document-definition-object/attachments/",
+ "title": "Dateianhänge einbetten",
+ "description": "Füge mit pdfmake 0.3 Dateien als PDF-Anmerkungen oder eingebettete Dateianhänge ein.",
+ "version": "0.3",
+ "sourceDigest": "fa2ac7caf1087dd025de26934674d3e7f4d0c75f51fbfb900170400b914fb224",
+ "source": "document-definition-object/attachments.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/attachments/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/attachments",
+ "markdown": "# Dateianhänge einbetten\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/attachments/\n\npdfmake unterstützt sowohl Dateianhänge als Anmerkungen als auch eingebettete Dateien. Eingebettete Dateien werden dem Wörterbuch `files` hinzugefügt und erscheinen in den Anhangbereichen unterstützter PDF-Viewer.\n\nDateianhänge sind Anmerkungen, die auf eine Datei verweisen.\n\nJeder Anhang und jede eingebettete Datei muss mindestens `src` angeben. Es wird dringend empfohlen, über `name` einen Dateinamen anzugeben.\n\nDer `src` eines Anhangs kann als Data-URL angegeben werden (wie beim folgenden Anhang von http://www.clipartbest.com/clipart-dT7zx5rT9); lokale Dateien sind ebenfalls möglich.\n\n**JavaScript**\n\n```js\nvar dd = {\n\tcontent: [\n\t\t'Any attachment or embedded file must provide at least a \"src\", providing a filename through \"name\" is highly recommended.',\n\t\t'The \"src\" of any attachment can be provided in dataURL format (like the following attachment, taken from http://www.clipartbest.com/clipart-dT7zx5rT9), but local files are allowed as well.',\n\t\t{\n\t\t\tattachment: {\n\t\t\t\tsrc: 'data:image/png;base64,iVBOR....',\n\t\t\t\tname: 'testImage.png'\n\t\t\t}\n\t\t},\n\t\t'You can also define an attachment in the \"attachments\" dictionary and reference it by name.',\n\t\t{\n\t\t\tattachment: 'sampleImage'\n\t\t},\n\t\t'And there are three different standard icons for attachments, \"GraphPush\", \"Paperclip\", and \"Push\" (the default value). Set them with the \"icon\" option.',\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'GraphPush'\n\t\t},\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'Paperclip'\n\t\t},\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'Push'\n\t\t},\n\t\t'For better customization, add an image and attach a file to it with linkToFile:',\n\t\t{\n\t\t\timage: 'fonts/sampleImage.jpg',\n\t\t\twidth: 150,\n\t\t\tlinkToFile: 'sampleImage'\n\t\t},\n\t\t\"You can add a description, which will show in your pdf viewer's attachments panel and as a tooltip when hovering over the attachment.\",\n\t\t{\n\t\t\tattachment: {\n\t\t\t\tsrc: 'data:image/png;base64,iVBOR....',\n\t\t\t\tname: 'withDescription.png',\n\t\t\t\tdescription: 'file description'\n\t\t\t}\n\t\t},\n\t\t'You can also define the \"src\" of an attachment or embedded file in the \"attachments\" and \"files\" dictionary via URL address.',\n\t],\n\tattachments: {\n\t\tsampleImage: {\n\t\t\tsrc: 'fonts/sampleImage.jpg',\n\t\t\tname: 'sampleImage.png'\n\t\t}\n\t},\n\tfiles: {\n\t\tREADME: {\n\t\t\tsrc: 'https://raw.githubusercontent.com/bpampuch/pdfmake/master/README.md',\n\t\t\tname: 'pdfmake README.md'\n\t\t}\n\t}\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n\tcontent: [\n\t\t'Any attachment or embedded file must provide at least a \"src\", providing a filename through \"name\" is highly recommended.',\n\t\t'The \"src\" of any attachment can be provided in dataURL format (like the following attachment, taken from http://www.clipartbest.com/clipart-dT7zx5rT9), but local files are allowed as well.',\n\t\t{\n\t\t\tattachment: {\n\t\t\t\tsrc: 'data:image/png;base64,iVBOR....',\n\t\t\t\tname: 'testImage.png'\n\t\t\t}\n\t\t},\n\t\t'You can also define an attachment in the \"attachments\" dictionary and reference it by name.',\n\t\t{\n\t\t\tattachment: 'sampleImage'\n\t\t},\n\t\t'And there are three different standard icons for attachments, \"GraphPush\", \"Paperclip\", and \"Push\" (the default value). Set them with the \"icon\" option.',\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'GraphPush'\n\t\t},\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'Paperclip'\n\t\t},\n\t\t{\n\t\t\tattachment: 'sampleImage',\n\t\t\ticon: 'Push'\n\t\t},\n\t\t'For better customization, add an image and attach a file to it with linkToFile:',\n\t\t{\n\t\t\timage: 'fonts/sampleImage.jpg',\n\t\t\twidth: 150,\n\t\t\tlinkToFile: 'sampleImage'\n\t\t},\n\t\t\"You can add a description, which will show in your pdf viewer's attachments panel and as a tooltip when hovering over the attachment.\",\n\t\t{\n\t\t\tattachment: {\n\t\t\t\tsrc: 'data:image/png;base64,iVBOR....',\n\t\t\t\tname: 'withDescription.png',\n\t\t\t\tdescription: 'file description'\n\t\t\t}\n\t\t},\n\t\t'You can also define the \"src\" of an attachment or embedded file in the \"attachments\" and \"files\" dictionary via URL address.',\n\t],\n\tattachments: {\n\t\tsampleImage: {\n\t\t\tsrc: 'fonts/sampleImage.jpg',\n\t\t\tname: 'sampleImage.png'\n\t\t}\n\t},\n\tfiles: {\n\t\tREADME: {\n\t\t\tsrc: 'https://raw.githubusercontent.com/bpampuch/pdfmake/master/README.md',\n\t\t\tname: 'pdfmake README.md'\n\t\t}\n\t}\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/background-layer",
+ "language": "de",
+ "translationKey": "document-definition-object/background-layer",
+ "path": "/docs/0.3/de/document-definition-object/background-layer/",
+ "title": "Hintergrundebene",
+ "description": "Lege mit Beispielen, Optionen und Anwendungshinweisen die Hintergrundebene in pdfmake 0.3 fest.",
+ "version": "0.3",
+ "sourceDigest": "5c5dac8a66e0c2a715ca9e59b03966f51840300097a5d71e3ae1d62e553f883a",
+ "source": "document-definition-object/background-layer.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/background-layer/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/background-layer",
+ "markdown": "# Hintergrundebene\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/background-layer/\n\nDie Hintergrundebene wird auf jeder Seite eingefügt.\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n background: 'simple text',\n\n content: ['Example document content']\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n background: 'simple text',\n\n content: ['Example document content']\n};\n```\n\nSie kann auch jedes andere Objekt enthalten (Bilder, Tabellen usw.) oder dynamisch erzeugt werden:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n background: function(currentPage, pageSize) {\n return `page ${currentPage} with size ${pageSize.width} x ${pageSize.height}`\n },\n\n content: ['Example document content']\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n background: function(currentPage, pageSize) {\n return `page ${currentPage} with size ${pageSize.width} x ${pageSize.height}`\n },\n\n content: ['Example document content']\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/columns",
+ "language": "de",
+ "translationKey": "document-definition-object/columns",
+ "path": "/docs/0.3/de/document-definition-object/columns/",
+ "title": "Spalten",
+ "description": "Lege mit Beispielen, Optionen und Anwendungshinweisen Spalten in pdfmake 0.3 fest.",
+ "version": "0.3",
+ "sourceDigest": "c5cad4de1cdcd5bc45a17a7f4bc373478b5f7e877859ca80db4facadca0459da",
+ "source": "document-definition-object/columns.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/columns/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/columns",
+ "markdown": "# Spalten\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/columns/\n\nAbsätze werden standardmäßig als vertikaler Stapel von Elementen ausgegeben. Du kannst den verfügbaren Platz jedoch auch in Spalten aufteilen.\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n 'This paragraph fills full width, as there are no columns. Next paragraph however consists of three columns',\n {\n columns: [\n {\n // auto-sized columns have their widths based on their content\n width: 'auto',\n text: 'First column'\n },\n {\n // star-sized columns fill the remaining space\n // if there's more than one star-column, available width is divided equally\n width: '*',\n text: 'Second column'\n },\n {\n // fixed width\n width: 100,\n text: 'Third column'\n },\n {\n // % width\n width: '20%',\n text: 'Fourth column'\n }\n ],\n // optional space between columns\n columnGap: 10\n },\n 'This paragraph goes below all columns and has full width'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n 'This paragraph fills full width, as there are no columns. Next paragraph however consists of three columns',\n {\n columns: [\n {\n // auto-sized columns have their widths based on their content\n width: 'auto',\n text: 'First column'\n },\n {\n // star-sized columns fill the remaining space\n // if there's more than one star-column, available width is divided equally\n width: '*',\n text: 'Second column'\n },\n {\n // fixed width\n width: 100,\n text: 'Third column'\n },\n {\n // % width\n width: '20%',\n text: 'Fourth column'\n }\n ],\n // optional space between columns\n columnGap: 10\n },\n 'This paragraph goes below all columns and has full width'\n ]\n};\n```\n\nDer Inhalt einer Spalte ist nicht auf einfachen Text beschränkt. Er kann jedes gültige pdfmake-Element enthalten. Sieh dir dazu das Beispiel COLUMNS im [Playground](/docs/0.3/de/playground/) an.\n\n## Eigenschaften\n\n* `columnGap: number` legt den Abstand zwischen Spalten fest.\n* `snakingColumns: boolean` aktiviert Spalten im Zeitungsstil. Siehe [diesen Artikel](/docs/0.3/de/document-definition-object/snaking-columns/) _(Mindestversion: 0.3.5)_\n"
+ },
+ {
+ "id": "de/document-definition-object/compression",
+ "language": "de",
+ "translationKey": "document-definition-object/compression",
+ "path": "/docs/0.3/de/document-definition-object/compression/",
+ "title": "Komprimierung",
+ "description": "Steuere die Komprimierung von PDF-Datenströmen mit dem Dokumentfeld compress; standardmäßig ist sie aktiviert.",
+ "version": "0.3",
+ "sourceDigest": "92de3279ae232bb95314ce206d2d5914ca81723e46208aabd408dce25d90db55",
+ "source": "document-definition-object/compression.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/compression/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/compression",
+ "markdown": "# Komprimierung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/compression/\n\n## Standardverhalten\n\nPDF-Datenströme werden standardmäßig komprimiert. So deaktivierst du die Komprimierung zur Überprüfung:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n compress: false,\n content: ['An uncompressed example document.']\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n compress: false,\n content: ['An uncompressed example document.']\n};\n```\n\n`compress` ist ein boolesches Feld der Dokumentdefinition und gehört nicht zum Optionsobjekt von `createPdf`. Wenn du die Komprimierung deaktivierst, wird die Ausgabedatei in der Regel größer. Eingebettete Schriften oder Bilddaten werden dadurch nicht entfernt; auch der für das Layout benötigte Speicher wird nicht reduziert. Hinweise zur Messung findest du unter [Leistung](/docs/0.3/de/guides/performance/).\n"
+ },
+ {
+ "id": "de/document-definition-object/document-medatadata",
+ "language": "de",
+ "translationKey": "document-definition-object/document-medatadata",
+ "path": "/docs/0.3/de/document-definition-object/document-medatadata/",
+ "title": "Dokumentmetadaten",
+ "description": "Lege PDF-Titel, Autor, Thema, Schlüsselwörter und benutzerdefinierte Metadatenfelder fest.",
+ "version": "0.3",
+ "sourceDigest": "7c039db6c37d93f4df69313d60659fa0479cb3f5b47dd4c5ee8b6bd7af11d7ef",
+ "source": "document-definition-object/document-medatadata.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/document-medatadata/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/document-medatadata",
+ "markdown": "# Dokumentmetadaten\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/document-medatadata/\n\nPDF-Dokumente können verschiedene Metadaten enthalten, beispielsweise Titel und Autor. Füge diese Angaben der Dokumentdefinition hinzu:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n info: {\n\ttitle: 'awesome Document',\n\tauthor: 'john doe',\n\tsubject: 'subject of document',\n\tkeywords: 'keywords for document',\n },\n content: 'This is an sample PDF printed with pdfMake'\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n info: {\n\ttitle: 'awesome Document',\n\tauthor: 'john doe',\n\tsubject: 'subject of document',\n\tkeywords: 'keywords for document',\n },\n content: 'This is an sample PDF printed with pdfMake'\n}\n```\n\nStandardfelder:\n\n* `title` – Titel des Dokuments\n* `author` – Name des Autors\n* `subject` – Thema des Dokuments\n* `keywords` – mit dem Dokument verknüpfte Schlüsselwörter\n* `creator` – Ersteller (Standard ist `'pdfmake'`)\n* `producer` – erzeugende Software (Standard ist `'pdfmake'`)\n* `creationDate` – Erstellungsdatum (wird automatisch von pdfmake hinzugefügt)\n* `modDate` – Datum der letzten Änderung\n* `trapped` – Kennzeichen, das angibt, ob das Dokument für den Druck durch Farbkorrekturen (Trapping) vorbereitet wurde\n\nBenutzerdefinierte Felder:\n\nDu kannst benutzerdefinierte Felder hinzufügen. Der Feldschlüssel darf keine Leerzeichen enthalten.\n\n## Dokumentsprache\n\nÜber die Eigenschaft `language` kannst du eine Sprache für das PDF-Dokument festlegen.\n\nBeispiel:\n**JavaScript**\n\n```js\nvar docDefinition = {\n language: 'cs-CZ',\n content: 'Jednoduchý PDF dokument vytvoření pomocí pdfmake'\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n language: 'cs-CZ',\n content: 'Jednoduchý PDF dokument vytvoření pomocí pdfmake'\n}\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/headers-footers",
+ "language": "de",
+ "translationKey": "document-definition-object/headers-footers",
+ "path": "/docs/0.3/de/document-definition-object/headers-footers/",
+ "title": "Kopf- und Fußzeilen",
+ "description": "Füge statische oder dynamische Seitenkopf- und Fußzeilen mit Seitenzahlen und Gesamtseitenzahl hinzu und reserviere Platz in den Seitenrändern.",
+ "version": "0.3",
+ "sourceDigest": "a47e47aa446dfbb4a3b97ade1254c9b6edbe8abfc9b34ac2cd7d2cfaac111b14",
+ "source": "document-definition-object/headers-footers.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/headers-footers/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/headers-footers",
+ "markdown": "# Kopf- und Fußzeilen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/headers-footers/\n\n## Statische Kopfzeile hinzufügen\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n pageMargins: [40, 65, 40, 55],\n header: { text: 'Example report', margin: [40, 20, 40, 0] },\n footer: { text: 'Example Studio', alignment: 'center', fontSize: 9 },\n content: ['Document content']\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n pageMargins: [40, 65, 40, 55],\n header: { text: 'Example report', margin: [40, 20, 40, 0] },\n footer: { text: 'Example Studio', alignment: 'center', fontSize: 9 },\n content: ['Document content']\n};\n```\n\nKopf- und Fußzeilen werden auf den Seiten wiederholt. Reserviere in den oberen und unteren Rändern genügend Platz für ihren Inhalt; die Ränder des Hauptinhalts werden nicht automatisch vergrößert. Zurückgegebener Inhalt verwendet normale pdfmake-Knoten.\n\n## Seitenzahlen hinzufügen\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n pageMargins: [40, 65, 40, 55],\n header: function (currentPage, pageCount, pageSize) {\n return {\n text: 'Report · ' + pageSize.width + ' pt wide',\n alignment: currentPage % 2 ? 'left' : 'right',\n margin: [40, 20, 40, 0],\n fontSize: 9\n };\n },\n footer: function (currentPage, pageCount) {\n return { text: currentPage + ' of ' + pageCount, alignment: 'center', fontSize: 9 };\n },\n content: ['First page', { text: 'Second page', pageBreak: 'before' }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n pageMargins: [40, 65, 40, 55],\n header: function (currentPage, pageCount, pageSize) {\n return {\n text: 'Report · ' + pageSize.width + ' pt wide',\n alignment: currentPage % 2 ? 'left' : 'right',\n margin: [40, 20, 40, 0],\n fontSize: 9\n };\n },\n footer: function (currentPage, pageCount) {\n return { text: currentPage + ' of ' + pageCount, alignment: 'center', fontSize: 9 };\n },\n content: ['First page', { text: 'Second page', pageBreak: 'before' }]\n};\n```\n\nCallbacks erhalten die aktuelle Seitennummer (beginnend bei 1), die Gesamtseitenzahl und die Seitengröße. Gib bei jedem Aufruf einen neuen Knoten zurück. Sorge für deterministische Callbacks und vermeide Änderungen an gemeinsam genutzten Anwendungsdaten.\n"
+ },
+ {
+ "id": "de/document-definition-object/images",
+ "language": "de",
+ "translationKey": "document-definition-object/images",
+ "path": "/docs/0.3/de/document-definition-object/images/",
+ "title": "Bilder",
+ "description": "Bette PNG- und JPEG-Bilder über Data-URLs, benannte Ressourcen, Dateien oder freigegebene externe URLs ein.",
+ "version": "0.3",
+ "sourceDigest": "e0419b93231e1257dc4fafa17f5b9f74c214b95807240b77511d32bfe7c0da6d",
+ "source": "document-definition-object/images.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/images/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/images",
+ "markdown": "# Bilder\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/images/\n\n## Eingebettete PNG- oder JPEG-Daten wiederverwenden\n\nEin Bildknoten hat die Form `{ image: 'key' }`; der Schlüssel verweist auf einen Eintrag im Wörterbuch `images`. Verwende denselben Schlüssel, wenn ein Bild mehrfach vorkommt. Unterstützt werden PNG und JPEG. Für SVG-Inhalte verwende einen [SVG-Knoten](/docs/0.3/de/document-definition-object/svgs/).\n\n\n\n### Runnable example: 09 · Embedded images\n\n**JavaScript**\n\n```js\nvar dd = {\n images: { pixel: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAF0lEQVR4nGPgqMgmCTGMahjVkD1sNQAAjRnrAVbW+rcAAAAASUVORK5CYII=' },\n content: [\n { text: 'One resource, several uses', fontSize: 24, bold: true, margin: [0, 0, 0, 18] },\n 'Use the images dictionary to reuse embedded PNG or JPEG data.',\n { image: 'pixel', width: 30, margin: [0, 15, 0, 15] },\n { image: 'pixel', fit: [60, 60] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n images: { pixel: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAF0lEQVR4nGPgqMgmCTGMahjVkD1sNQAAjRnrAVbW+rcAAAAASUVORK5CYII=' },\n content: [\n { text: 'One resource, several uses', fontSize: 24, bold: true, margin: [0, 0, 0, 18] },\n 'Use the images dictionary to reuse embedded PNG or JPEG data.',\n { image: 'pixel', width: 30, margin: [0, 15, 0, 15] },\n { image: 'pixel', fit: [60, 60] }\n ]\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=images)\n\n\n\n## Skalierung festlegen\n\n| Felder des Bildknotens | Ergebnis |\n| --- | --- |\n| Keine Angabe von width, height oder fit | Natürliche Abmessungen des Bildes verwenden |\n| `width: 150` | Proportional auf diese Breite skalieren |\n| `height: 100` | Proportional auf diese Höhe skalieren; seit 0.3.2 |\n| `width: 150, height: 100` | Diese Abmessungen erzwingen; das Bild kann dadurch gestreckt werden |\n| `fit: [150, 100]` | In ein Rechteck einpassen und Seitenverhältnis beibehalten |\n| `cover: { width: 150, height: 100, align: 'right', valign: 'bottom' }` | Rechteck mit Bild füllen, zuschneiden und ausrichten |\n\nDie angezeigten Abmessungen verkleinern nicht die ursprünglichen Bilddaten. Skaliere übergroße Quelldateien vor dem Einbetten, wenn Ausgabegröße und Speicherverbrauch wichtig sind.\n\n## Quelle für deine Laufzeit auswählen\n\n| Quelle | Einrichtung |\n| --- | --- |\n| Data-URL | Vollständige PNG-/JPEG-Base64-Data-URL in `images` oder direkt im Knoten angeben |\n| Lokale Datei | Nur Node.js oder eine Datei, die bereits im Browser-VFS liegt |\n| HTTP(S)-URL | Benannten Eintrag in `images` verwenden und über die Ressourcenrichtlinie freigeben |\n| URL mit Headern | `{ url, headers }` im benannten Eintrag unter `images` verwenden |\n\n**JavaScript**\n\n```js\nvar dd = {\n images: {\n logo: '/application-owned/assets/logo.png',\n remote: {\n url: 'https://assets.example.com/photo.jpg',\n headers: { 'X-Example-Header': 'value' }\n }\n },\n content: [\n { image: 'logo', width: 120 },\n { image: 'remote', fit: [200, 150] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n images: {\n logo: '/application-owned/assets/logo.png',\n remote: {\n url: 'https://assets.example.com/photo.jpg',\n headers: { 'X-Example-Header': 'value' }\n }\n },\n content: [\n { image: 'logo', width: 120 },\n { image: 'remote', fit: [200, 150] }\n ]\n};\n```\n\nDieses Snippet zeigt die Formen der Quellen, ist aber kein eigenständiges Beispiel zum Herunterladen. Stelle eine vorhandene, von deiner Anwendung verwaltete Datei und eine gültige, freigegebene URL bereit. Im Browser muss die lokale Datei im VFS vorhanden sein; Browser-URLs benötigen außerdem CORS-Unterstützung. Füge keine privaten Zugangsdaten in clientseitige Definitionen ein. Das oben gezeigte eingebettete Beispiel benötigt keine Netzwerkressource.\n\n## Fehlende Bilder untersuchen\n\nEin leerer oder ungültiger Bildwert führt zu einem Fehler. Prüfe den Wörterbuchschlüssel, das vollständige Data-URL-Präfix und die Datenbytes, das Vorhandensein der Datei, die URL-Antwort und die Zugriffsrichtlinie. `setUrlAccessPolicy` umgeht CORS nicht. Eine lokale Dateirichtlinie muss den tatsächlich aufgelösten Dateipfad erlauben. Siehe [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/) und [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/).\n"
+ },
+ {
+ "id": "de/document-definition-object/links",
+ "language": "de",
+ "translationKey": "document-definition-object/links",
+ "path": "/docs/0.3/de/document-definition-object/links/",
+ "title": "Links",
+ "description": "Lege mit Beispielen, Optionen und Anwendungshinweisen Links in pdfmake 0.3 fest.",
+ "version": "0.3",
+ "sourceDigest": "83e3e95f41aa0ba93449638032a7b8be6d0b6aafa82d1d8384d5364990825ad3",
+ "source": "document-definition-object/links.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/links/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/links",
+ "markdown": "# Links\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/links/\n\nFür externe oder interne Links verwendest du die folgende Syntax:\n**JavaScript**\n\n```js\nvar dd = { content: [\n{ text: 'google', link: 'http://google.com' },\n{ text: 'Go to page 2', linkToPage: 2 },\n{ text: 'Go to Header', linkToDestination: 'header' },\n{ text: 'Header content', id: 'header' },\n] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [\n{ text: 'google', link: 'http://google.com' },\n{ text: 'Go to page 2', linkToPage: 2 },\n{ text: 'Go to Header', linkToDestination: 'header' },\n{ text: 'Header content', id: 'header' },\n] };\n```\nOder du verlinkst eine lokale Datei auf dem Computer:\n**JavaScript**\n\n```js\nvar dd = {\n\tcontent: [\n\t\t{\n\t\t text: 'link',\n\t\t link: 'file:///c:/testFile.txt'\n\t\t}\n\t]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n\tcontent: [\n\t\t{\n\t\t text: 'link',\n\t\t link: 'file:///c:/testFile.txt'\n\t\t}\n\t]\n};\n```\n\n## Eigenschaften\n\n- `link` (`string`) – URL zu einer externen Website\n- `linkToPage` (`number`) – Link zu einer Seitennummer\n- `linkToDestination` (`string`) – Link zu einem Dokumentziel\n"
+ },
+ {
+ "id": "de/document-definition-object/lists",
+ "language": "de",
+ "translationKey": "document-definition-object/lists",
+ "path": "/docs/0.3/de/document-definition-object/lists/",
+ "title": "Listen",
+ "description": "Erstelle nummerierte und Aufzählungslisten in pdfmake 0.3 und passe Farben und Aufzählungszeichen an.",
+ "version": "0.3",
+ "sourceDigest": "5a9a9e5b03459677b99b2dbeeb26d15d6298dfb3e0c88a8c5e2b43ed48383e8f",
+ "source": "document-definition-object/lists.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/lists/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/lists",
+ "markdown": "# Listen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/lists/\n\npdfmake unterstützt sowohl nummerierte Listen als auch Aufzählungslisten:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n 'Bulleted list example:',\n {\n // to treat a paragraph as a bulleted list, set an array of items under the ul key\n ul: [\n 'Item 1',\n 'Item 2',\n 'Item 3',\n { text: 'Item 4', bold: true },\n ]\n },\n\n 'Numbered list example:',\n {\n // for numbered lists set the ol key\n ol: [\n 'Item 1',\n 'Item 2',\n 'Item 3'\n ]\n },\n\n 'Colored unordered list:',\n {\n color: 'blue',\n ul: [\n 'item 1',\n 'item 2',\n 'item 3'\n ]\n },\n\n 'Colored unordered list with own marker color:',\n {\n color: 'blue',\n markerColor: 'red',\n ul: [\n 'item 1',\n 'item 2',\n { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2\n ]\n },\n\n 'Colored ordered list',\n {\n color: 'blue',\n ol: [\n 'item 1',\n 'item 2',\n 'item 3'\n ]\n },\n 'Colored ordered list with own marker color:',\n {\n color: 'blue',\n markerColor: 'red',\n ol: [\n 'item 1',\n 'item 2',\n { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2\n ]\n },\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n 'Bulleted list example:',\n {\n // to treat a paragraph as a bulleted list, set an array of items under the ul key\n ul: [\n 'Item 1',\n 'Item 2',\n 'Item 3',\n { text: 'Item 4', bold: true },\n ]\n },\n\n 'Numbered list example:',\n {\n // for numbered lists set the ol key\n ol: [\n 'Item 1',\n 'Item 2',\n 'Item 3'\n ]\n },\n\n 'Colored unordered list:',\n {\n color: 'blue',\n ul: [\n 'item 1',\n 'item 2',\n 'item 3'\n ]\n },\n\n 'Colored unordered list with own marker color:',\n {\n color: 'blue',\n markerColor: 'red',\n ul: [\n 'item 1',\n 'item 2',\n { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2\n ]\n },\n\n 'Colored ordered list',\n {\n color: 'blue',\n ol: [\n 'item 1',\n 'item 2',\n 'item 3'\n ]\n },\n 'Colored ordered list with own marker color:',\n {\n color: 'blue',\n markerColor: 'red',\n ol: [\n 'item 1',\n 'item 2',\n { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2\n ]\n },\n ]\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/margins",
+ "language": "de",
+ "translationKey": "document-definition-object/margins",
+ "path": "/docs/0.3/de/document-definition-object/margins/",
+ "title": "Abstände",
+ "description": "Lege mit Beispielen, Optionen und Anwendungshinweisen Abstände in pdfmake 0.3 fest.",
+ "version": "0.3",
+ "sourceDigest": "f331bdfb9263dd2a8867f8ed754a7e6eedb9072c8a27a47f57313fb56c0159cb",
+ "source": "document-definition-object/margins.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/margins/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/margins",
+ "markdown": "# Abstände\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/margins/\n\nJedes Element in pdfMake kann einen Abstand haben:\n\n**JavaScript**\n\n```js\nvar dd = { content: [\n// margin: [left, top, right, bottom]\n{ text: 'sample', margin: [ 5, 2, 10, 20 ] },\n\n// margin: [horizontal, vertical]\n{ text: 'another text', margin: [5, 2] },\n\n// margin: equalLeftTopRightBottom\n{ text: 'last one', margin: 5 },\n\n// single-side margins\n{ text: 'sample', marginLeft: 5, marginTop: 2, marginRight: 10, marginBottom: 2 },\n] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [\n// margin: [left, top, right, bottom]\n{ text: 'sample', margin: [ 5, 2, 10, 20 ] },\n\n// margin: [horizontal, vertical]\n{ text: 'another text', margin: [5, 2] },\n\n// margin: equalLeftTopRightBottom\n{ text: 'last one', margin: 5 },\n\n// single-side margins\n{ text: 'sample', marginLeft: 5, marginTop: 2, marginRight: 10, marginBottom: 2 },\n] };\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/outlines",
+ "language": "de",
+ "translationKey": "document-definition-object/outlines",
+ "path": "/docs/0.3/de/document-definition-object/outlines/",
+ "title": "Gliederungen und Lesezeichen",
+ "description": "Erstelle hierarchische PDF-Lesezeichen mit pdfmake 0.3 und steuere ihre Beschriftung, Elternknoten und den geöffneten Zustand.",
+ "version": "0.3",
+ "sourceDigest": "c3e4279bfaad7589de23fa588bc515727f35f2255fa8effd7da1ce56b06a7cb2",
+ "source": "document-definition-object/outlines.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/outlines/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/outlines",
+ "markdown": "# Gliederungen und Lesezeichen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/outlines/\n\n> **Note:** Mindestversion: **0.3.5**\n\n\nPDF-Gliederungen (auch Lesezeichen genannt) sind eine hierarchische Navigationsstruktur im PDF-Dokument. Damit können Benutzer direkt zu bestimmten Seiten springen. Sie funktionieren wie ein interaktives Inhaltsverzeichnis und werden normalerweise im Navigationsbereich des PDF-Viewers angezeigt.\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n {\n text: 'First header in bookmarks',\n outline: true,\n },\n {\n text: 'Second header with custom bookmark',\n outline: true,\n outlineText: 'Custom bookmark text',\n },\n {\n text: 'Structured bookmarks',\n id: 'structured-bookmarks',\n outline: true,\n outlineExpanded: true\n },\n {\n text: 'First subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks'\n },\n {\n text: 'Second subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks'\n },\n {\n text: 'Third subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks',\n id: 'third-subheader'\n }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n {\n text: 'First header in bookmarks',\n outline: true,\n },\n {\n text: 'Second header with custom bookmark',\n outline: true,\n outlineText: 'Custom bookmark text',\n },\n {\n text: 'Structured bookmarks',\n id: 'structured-bookmarks',\n outline: true,\n outlineExpanded: true\n },\n {\n text: 'First subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks'\n },\n {\n text: 'Second subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks'\n },\n {\n text: 'Third subheader',\n outline: true,\n outlineParentId: 'structured-bookmarks',\n id: 'third-subheader'\n }\n ]\n};\n```\n\n## Eigenschaften\n\n- `outline: boolean` – auf `true` setzen, um den Knoten in die Lesezeichen aufzunehmen\n- `outlineText: string` (optional) – benutzerdefinierter Lesezeichentext; andernfalls wird der Text des Knotens verwendet\n- `outlineExpanded: boolean` (optional) – auf `true` setzen, damit das Lesezeichen geöffnet angezeigt wird\n- `outlineParentId: string` (optional) – `id` des übergeordneten Lesezeichens\n"
+ },
+ {
+ "id": "de/document-definition-object/page",
+ "language": "de",
+ "translationKey": "document-definition-object/page",
+ "path": "/docs/0.3/de/document-definition-object/page/",
+ "title": "Seitengröße, Ausrichtung und Ränder",
+ "description": "Lege Seitengröße, Ausrichtung und Ränder fest und steuere automatische oder explizite Seitenumbrüche.",
+ "version": "0.3",
+ "sourceDigest": "433a428f2dbdb4d2db7e93f3a845e24637a4e34c5631c1d97f53c9f666b00de9",
+ "source": "document-definition-object/page.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/page/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/page",
+ "markdown": "# Seitengröße, Ausrichtung und Ränder\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/page/\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n // a string or { width: number, height: number }\n pageSize: 'A5',\n\n // by default we use portrait, you can change it to landscape if you wish\n pageOrientation: 'landscape',\n\n // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins\n pageMargins: [ 40, 60, 40, 60 ],\n content: ['Page size, orientation and margins.']\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n // a string or { width: number, height: number }\n pageSize: 'A5',\n\n // by default we use portrait, you can change it to landscape if you wish\n pageOrientation: 'landscape',\n\n // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins\n pageMargins: [ 40, 60, 40, 60 ],\n content: ['Page size, orientation and margins.']\n};\n```\n\nWenn du `pageSize` als Zeichenfolge festlegst, kannst du einen der folgenden Werte verwenden:\n\n* `'4A0'`, `'2A0'`, `'A0'`, `'A1'`, `'A2'`, `'A3'`, `'A4'`, `'A5'`, `'A6'`, `'A7'`, `'A8'`, `'A9'`, `'A10'`,\n* `'B0'`, `'B1'`, `'B2'`, `'B3'`, `'B4'`, `'B5'`, `'B6'`, `'B7'`, `'B8'`, `'B9'`, `'B10'`,\n* `'C0'`, `'C1'`, `'C2'`, `'C3'`, `'C4'`, `'C5'`, `'C6'`, `'C7'`, `'C8'`, `'C9'`, `'C10'`,\n* `'RA0'`, `'RA1'`, `'RA2'`, `'RA3'`, `'RA4'`,\n* `'SRA0'`, `'SRA1'`, `'SRA2'`, `'SRA3'`, `'SRA4'`,\n* `'EXECUTIVE'`, `'FOLIO'`, `'LEGAL'`, `'LETTER'`, `'TABLOID'`\n\nUm die Seitenausrichtung innerhalb eines Dokuments zu ändern, füge einen Seitenumbruch mit der neuen Ausrichtung ein.\n\n**JavaScript**\n\n```js\nvar dd = {\n pageOrientation: 'portrait',\n content: [\n {text: 'Text on Portrait'},\n {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'},\n {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'},\n {text: 'Text on Portrait 2'},\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n pageOrientation: 'portrait',\n content: [\n {text: 'Text on Portrait'},\n {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'},\n {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'},\n {text: 'Text on Portrait 2'},\n ]\n};\n```\n\nAutomatische Seitenhöhe:\n\n**JavaScript**\n\n```js\nvar dd = {\n pageSize: {\n width: 595.28,\n height: 'auto'\n },\n content: [\n // ...\n ]\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n pageSize: {\n width: 595.28,\n height: 'auto'\n },\n content: [\n // ...\n ]\n}\n```\n\n## Seitenumbrüche dynamisch steuern, zum Beispiel um verwaiste Unterelemente zu vermeiden\n\nDu kannst eine Funktion `pageBreakBefore` angeben, die entscheidet, ob vor einem Knoten ein Seitenumbruch eingefügt werden soll. Für die Regel „keine verwaiste Unterüberschrift“ kannst du folgende Definition verwenden:\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [\n {text: '1 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n {text: '2 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n {text: '3 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n ],\n pageBreakBefore: function(currentNode, nodeContainer) {\n // nodeContainer.getFollowingNodesOnPage();\n // nodeContainer.getNodesOnNextPage();\n // nodeContainer.getPreviousNodesOnPage();\n\n return currentNode.headlineLevel === 1 && nodeContainer.getFollowingNodesOnPage().length === 0;\n }\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [\n {text: '1 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n {text: '2 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n {text: '3 Headline', headlineLevel: 1},\n 'Some long text of variable length ...',\n ],\n pageBreakBefore: function(currentNode, nodeContainer) {\n // nodeContainer.getFollowingNodesOnPage();\n // nodeContainer.getNodesOnNextPage();\n // nodeContainer.getPreviousNodesOnPage();\n\n return currentNode.headlineLevel === 1 && nodeContainer.getFollowingNodesOnPage().length === 0;\n }\n}\n```\n\nWenn `pageBreakBefore` `true` zurückgibt, wird vor dem `currentNode` ein Seitenumbruch eingefügt. Dem aktuellen Knoten sind folgende Informationen zugeordnet:\n\n**JavaScript**\n\n```js\nconst currentNode = {\n id: '
',\n headlineLevel: '',\n text: '',\n ul: '',\n ol: '',\n table: '',\n image: '',\n qr: '',\n canvas: '',\n columns: '',\n style: '',\n pageOrientation: '',\n pageNumbers: [2, 3], // The pages this element is visible on (e.g. multi-line text could be on more than one page)\n pages: 6, // the total number of pages of this document\n stack: false, // if this is an element which encapsulates multiple sub-objects\n startPosition: {\n pageNumber: 2, // the page this node starts on\n pageOrientation: 'landscape', // the orientation of this page\n left: 60, // the left position\n right: 60, // the right position\n verticalRatio: 0.2, // the ratio of space used vertically in this document (excluding margins)\n horizontalRatio: 0.0 // the ratio of space used horizontally in this document (excluding margins)\n }\n};\n```\n\n**TypeScript**\n\n```ts\nconst currentNode = {\n id: '',\n headlineLevel: '',\n text: '',\n ul: '',\n ol: '',\n table: '',\n image: '',\n qr: '',\n canvas: '',\n columns: '',\n style: '',\n pageOrientation: '',\n pageNumbers: [2, 3], // The pages this element is visible on (e.g. multi-line text could be on more than one page)\n pages: 6, // the total number of pages of this document\n stack: false, // if this is an element which encapsulates multiple sub-objects\n startPosition: {\n pageNumber: 2, // the page this node starts on\n pageOrientation: 'landscape', // the orientation of this page\n left: 60, // the left position\n right: 60, // the right position\n verticalRatio: 0.2, // the ratio of space used vertically in this document (excluding margins)\n horizontalRatio: 0.0 // the ratio of space used horizontally in this document (excluding margins)\n }\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/patterns",
+ "language": "de",
+ "translationKey": "document-definition-object/patterns",
+ "path": "/docs/0.3/de/document-definition-object/patterns/",
+ "title": "Muster",
+ "description": "Definiere und verwende Kachelmuster für Text, Vektoren und Tabellenzellen in pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "85d5a2f40ac8d6ba0cd8c74c4dd5d7261674b55739b2309aa929c3410047b331",
+ "source": "document-definition-object/patterns.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/patterns/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/patterns",
+ "markdown": "# Muster\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/patterns/\n\nMuster lassen sich als Wörterbuch vordefinierter Muster in der Dokumentdefinition angeben.\n\nUnterstützt werden nur Kachelmuster.\n\n## Musterdefinition\n\nJedes Muster wird mit folgenden Eigenschaften definiert:\n\n- `boundingBox` – Begrenzungsrahmen zum Beschneiden der Musterzelle\n- `xStep` – horizontaler Abstand zwischen Zellen\n- `yStep` – vertikaler Abstand zwischen Zellen\n- `pattern` – PDF-Datenstrom mit den Operationen zum Zeichnen der Grafiken und des Textes in der Zelle\n\nWeitere Informationen zu den Eigenschaften und Mustern im Allgemeinen findest du in der [PDF-Referenz](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf), insbesondere in Abschnitt 4.6 und 4.6.2 zu Kachelmustern.\n\n## Beispiel einer Musterdefinition\n\nEin einfaches Muster mit Streifen im 45°-Winkel:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\"...\"],\n patterns: {\n stripe45d: {\n boundingBox: [1, 1, 4, 4],\n xStep: 3,\n yStep: 3,\n pattern: \"1 w 0 1 m 4 5 l s 2 0 m 5 3 l s\",\n },\n },\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\"...\"],\n patterns: {\n stripe45d: {\n boundingBox: [1, 1, 4, 4],\n xStep: 3,\n yStep: 3,\n pattern: \"1 w 0 1 m 4 5 l s 2 0 m 5 3 l s\",\n },\n },\n};\n```\n\nDie Ausgabe ist im Vektorbeispiel zu sehen.\n\n## Verwendung in Vektoren, Tabellen und Text\n\nDie folgenden Eigenschaften stehen zur Verfügung.\n\nFür Text:\n\n- `background` – als Texthintergrund setzen (siehe Beispiel `styling_properties`)\n\nFür Vektoren:\n\n- `color` – als Füllung eines Vektors setzen (siehe das Rechteck im Vektorbeispiel)\n\nFür Tabellenzellen:\n\n- `fillColor` – Füllfarbe der Zelle (Hintergrund)\n- `overlayPattern` – Muster über den Zellinhalt legen\n- `overlayOpacity` – Deckkraft der Überlagerung\n\nJede dieser Eigenschaften wird als Tupel `[string, string]` angegeben. Das erste Element ist der Schlüssel im Musterwörterbuch, das zweite die Farbe, mit der das Muster gezeichnet wird.\n\n## Beispiele\n\nText:\n\n**JavaScript**\n\n```js\nvar dd = { content: [\n{ text: 'Insert lorem. And ipsum', background: ['stripe45d', 'gray'] }\n] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [\n{ text: 'Insert lorem. And ipsum', background: ['stripe45d', 'gray'] }\n] };\n```\n\nVektor:\n\n**JavaScript**\n\n```js\nvar dd = { content: [{ canvas: [\n{\n type: 'rect',\n x: 10, y: 250, w: 50, h: 30,\n color: ['stripe45d', 'blue'],\n}\n] }] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [{ canvas: [\n{\n type: 'rect',\n x: 10, y: 250, w: 50, h: 30,\n color: ['stripe45d', 'blue'],\n}\n] }] };\n```\n\nTabelle (wie in Tabellenzellen verwendet):\n\n**JavaScript**\n\n```js\nvar dd = { content: [\n{\n text: 'Sample value',\n fillOpacity: 0.85,\n fillColor: ['stripe45d', 'blue']\n}\n] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [\n{\n text: 'Sample value',\n fillOpacity: 0.85,\n fillColor: ['stripe45d', 'blue']\n}\n] };\n```\n\n**JavaScript**\n\n```js\nvar dd = { content: [\n{\n text: 'Sample value',\n fillOpacity: 0.15,\n fillColor: 'blue',\n overlayPattern: ['stripe45d', 'gray'],\n overlayOpacity: 0.15\n}\n] };\n```\n\n**TypeScript**\n\n```ts\nimport type { ContentText } from \"pdfmake/interfaces\";\n\n// Cell properties are included in the bundled pdfmake declarations.\nconst cell = {\n text: 'Sample value',\n fillOpacity: 0.15,\n fillColor: 'blue',\n overlayPattern: ['stripe45d', 'gray'],\n overlayOpacity: 0.15\n} satisfies ContentText;\n\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/pdfa",
+ "language": "de",
+ "translationKey": "document-definition-object/pdfa",
+ "path": "/docs/0.3/de/document-definition-object/pdfa/",
+ "title": "PDF/A",
+ "description": "Lege mit Beispielen, Optionen und Anwendungshinweisen PDF/A in pdfmake 0.3 fest.",
+ "version": "0.3",
+ "sourceDigest": "3a4aac84f9ac2fad0a48e377a819ab231184afd5b8138332817198c5125b12c5",
+ "source": "document-definition-object/pdfa.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/pdfa/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/pdfa",
+ "markdown": "# PDF/A\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/pdfa/\n\nPDF/A ist ein spezielles Format zur Archivierung und langfristigen Aufbewahrung elektronischer Dokumente.\n\nErforderlich ist PDF-Version 1.4 oder höher.\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n version: '1.5',\n subset: 'PDF/A-3a',\n tagged: true,\n displayTitle: true,\n info: {\n title: 'Awesome PDF document from pdfmake'\n },\n content: [\n 'PDF/A document for archive'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n version: '1.5',\n subset: 'PDF/A-3a',\n tagged: true,\n displayTitle: true,\n info: {\n title: 'Awesome PDF document from pdfmake'\n },\n content: [\n 'PDF/A document for archive'\n ]\n};\n```\n\nUnterstützte PDF-Versionen (Eigenschaft `version`):\n- `1.3` – PDF-Version 1.3 (Standard), **für PDF/A nicht unterstützt**\n- `1.4` – PDF-Version 1.4\n- `1.5` – PDF-Version 1.5\n- `1.6` – PDF-Version 1.6\n- `1.7` – PDF-Version 1.7\n- `1.7ext3` – PDF-Version 1.7 ExtensionLevel 3\n\nKonformitätsstufe des Dokuments (Eigenschaft `subset`):\n- `PDF/A-1` (Kurzform für PDF/A-1b)\n- `PDF/A-1a`\n- `PDF/A-1b`\n- `PDF/A-2` (Kurzform für PDF/A-2b)\n- `PDF/A-2a`\n- `PDF/A-2b`\n- `PDF/A-3` (Kurzform für PDF/A-3b)\n- `PDF/A-3a`\n- `PDF/A-3b`\n- `PDF/UA`\n\nDokument als getaggtes PDF kennzeichnen (Eigenschaft `tagged`):\n- `true` – aktivieren\n- `false` – deaktivieren\n\nDokumenttitel in der Titelleiste des Fensters anzeigen (Eigenschaft `displayTitle`):\n- `true` – aktivieren\n- `false` – deaktivieren\n"
+ },
+ {
+ "id": "de/document-definition-object/qr",
+ "language": "de",
+ "translationKey": "document-definition-object/qr",
+ "path": "/docs/0.3/de/document-definition-object/qr/",
+ "title": "QR-Code",
+ "description": "Erzeuge QR-Codes in pdfmake 0.3 und passe Farbe, Größe, Version, Fehlerkorrektur, Kodierung und Maskenmuster an.",
+ "version": "0.3",
+ "sourceDigest": "1faae2f9f0ec8989f3aac23e9c10b8b8c91998d2830d52b4558b2ff3f8beafe9",
+ "source": "document-definition-object/qr.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/qr/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/qr",
+ "markdown": "# QR-Code\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/qr/\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n // basic usage\n { qr: 'text in QR' },\n\n // colored QR\n { qr: 'text in QR', foreground: 'red', background: 'yellow' },\n\n // resized QR\n { qr: 'text in QR', fit: 500 },\n ]\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n // basic usage\n { qr: 'text in QR' },\n\n // colored QR\n { qr: 'text in QR', foreground: 'red', background: 'yellow' },\n\n // resized QR\n { qr: 'text in QR', fit: 500 },\n ]\n}\n```\n\nEigenschaften:\n\n* `qr`: `string` – Text im QR-Code\n* `foreground`: `string` (optional, Standard schwarz) – Vordergrundfarbe\n* `background`: `string` (optional, Standard weiß) – Hintergrundfarbe\n* `fit`: `integer` (optional) – Größe des ausgegebenen QR-Bildes anpassen\n* `version`: `integer` (optional) – QR-Version von 1 bis 40 (Details siehe [wikipedia.org](https://en.wikipedia.org/wiki/QR_code#Storage))\n* `eccLevel`: `string` (optional, Standard L) – Fehlerkorrekturstufe (Details siehe [wikipedia.org](https://en.wikipedia.org/wiki/QR_code#Error_correction)); mögliche Werte:\n * _L_ – Stufe L (niedrig), ungefähr 7 % der Codewörter können wiederhergestellt werden\n * _M_ – Stufe M (mittel), ungefähr 15 % der Codewörter können wiederhergestellt werden\n * _Q_ – Stufe Q (Quartil), ungefähr 25 % der Codewörter können wiederhergestellt werden\n * _H_ – Stufe H (hoch), ungefähr 30 % der Codewörter können wiederhergestellt werden\n* `mode`: `string` (optional) – Kodierungsmodus; mögliche Werte: _numeric_, _alphanumeric_, _octet_ (Details siehe [wikipedia.org](https://en.wikipedia.org/wiki/QR_code#Storage))\n* `mask`: `integer` (optional) – Maskenmuster von 0 bis 7 (Details siehe [wikipedia.org](https://en.wikipedia.org/wiki/QR_code#Encoding))\n"
+ },
+ {
+ "id": "de/document-definition-object/sections",
+ "language": "de",
+ "translationKey": "document-definition-object/sections",
+ "path": "/docs/0.3/de/document-definition-object/sections/",
+ "title": "Dokumentabschnitte",
+ "description": "Lege für einzelne Dokumentabschnitte in pdfmake 0.3 Seiteneinstellungen, Kopf- und Fußzeilen, Wasserzeichen sowie Hintergründe fest.",
+ "version": "0.3",
+ "sourceDigest": "6dc77fa5678a9e679efdf6b4bff537f029525cefa55e1030486444fce88c0ea8",
+ "source": "document-definition-object/sections.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/sections/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/sections",
+ "markdown": "# Dokumentabschnitte\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/sections/\n\nMit Dokumentabschnitten kannst du ein Dokument in mehrere Teile mit jeweils eigenen Seiteneinstellungen aufteilen.\n\nJeder Abschnitt kann Folgendes festlegen:\n- eigene Seitengröße und Ausrichtung\n- eigene Seitenränder\n- eigene Kopf- und Fußzeile\n- eigenes Wasserzeichen\n- eigenen Hintergrund\n\nEine Definition mit allen Eigenschaften:\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n {\n header: function (currentPage, pageCount) {\n return currentPage.toString() + ' of ' + pageCount;\n },\n footer: function (currentPage, pageCount) {\n return currentPage.toString() + ' of ' + pageCount;\n },\n background: function () {\n return {text: 'background', alignment: 'right'};\n },\n watermark: 'watermark',\n pageSize: 'A4',\n pageOrientation: 'landscape',\n pageMargins: 5,\n section: [\n 'Text in section.'\n ]\n }\n ]\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n {\n header: function (currentPage, pageCount) {\n return currentPage.toString() + ' of ' + pageCount;\n },\n footer: function (currentPage, pageCount) {\n return currentPage.toString() + ' of ' + pageCount;\n },\n background: function () {\n return {text: 'background', alignment: 'right'};\n },\n watermark: 'watermark',\n pageSize: 'A4',\n pageOrientation: 'landscape',\n pageMargins: 5,\n section: [\n 'Text in section.'\n ]\n }\n ]\n}\n```\n\nIm nächsten Abschnitt können Eigenschaften vom vorherigen Abschnitt übernommen werden:\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n {\n header: 'inherit',\n footer: 'inherit',\n background: 'inherit',\n watermark: 'inherit',\n pageSize: 'inherit',\n pageOrientation: 'inherit',\n pageMargins: 'inherit',\n section: [\n 'Text in section.'\n ]\n }\n ]\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n {\n header: 'inherit',\n footer: 'inherit',\n background: 'inherit',\n watermark: 'inherit',\n pageSize: 'inherit',\n pageOrientation: 'inherit',\n pageMargins: 'inherit',\n section: [\n 'Text in section.'\n ]\n }\n ]\n}\n```\n\nEin vollständiges Beispiel findest du unter [examples/section.js](https://github.com/bpampuch/pdfmake/blob/master/examples/sections.js).\n"
+ },
+ {
+ "id": "de/document-definition-object/security",
+ "language": "de",
+ "translationKey": "document-definition-object/security",
+ "path": "/docs/0.3/de/document-definition-object/security/",
+ "title": "Verschlüsselung und Zugriffsrechte",
+ "description": "Lege PDF-Passwörter, Verschlüsselungsversionen und Dokumentberechtigungen fest; diese sind von Ressourcen-Zugriffsrichtlinien getrennt.",
+ "version": "0.3",
+ "sourceDigest": "6736e08d8db59cae0ce17becb97f86de18201817a5135ee1385a2a15cc1608f5",
+ "source": "document-definition-object/security.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/security/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/security",
+ "markdown": "# Verschlüsselung und Zugriffsrechte\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/security/\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n userPassword: '123',\n ownerPassword: '123456',\n permissions: {\n printing: 'highResolution', //'lowResolution'\n modifying: false,\n copying: false,\n annotating: true,\n fillingForms: true,\n contentAccessibility: true,\n documentAssembly: true\n },\n content: [\n '...'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n userPassword: '123',\n ownerPassword: '123456',\n permissions: {\n printing: 'highResolution', //'lowResolution'\n modifying: false,\n copying: false,\n annotating: true,\n fillingForms: true,\n contentAccessibility: true,\n documentAssembly: true\n },\n content: [\n '...'\n ]\n};\n```\n\nPDF-Dokumente können verschlüsselt und beim Öffnen durch ein Passwort geschützt werden. Außerdem können Berechtigungen für die Aktionen festgelegt werden, die Benutzer mit dem PDF ausführen dürfen.\n\nUm die Verschlüsselung zu aktivieren, setze das Benutzerpasswort (Zeichenfolge) in `userPassword`. Wenn ein Benutzerpasswort angegeben ist, wird die PDF-Datei verschlüsselt und Benutzer werden beim Öffnen aufgefordert, das Passwort zum Entschlüsseln einzugeben.\n\nUm Zugriffsrechte für die PDF-Datei festzulegen, musst du ein Eigentümerpasswort (Zeichenfolge) in `ownerPassword` und ein Objekt `permissions` mit Berechtigungen angeben. Standardmäßig sind alle Vorgänge gesperrt. Du musst die gewünschten Vorgänge ausdrücklich erlauben.\n\nFolgende Einstellungen sind im Objekt `permissions` möglich:\n\n- `printing` – ob Drucken erlaubt ist. Mit `\"lowResolution\"` wird Drucken in niedriger Auflösung erlaubt, mit `\"highResolution\"` Drucken in hoher Auflösung.\n- `modifying` – ob Änderungen erlaubt sind. Setze den Wert auf `true`, um Änderungen am Dokumentinhalt zu erlauben.\n- `copying` – ob Text oder Grafiken kopiert werden dürfen. Setze den Wert auf `true`, um das Kopieren zu erlauben.\n- `annotating` – ob Anmerkungen und das Ausfüllen von Formularen erlaubt sind. Setze den Wert auf `true`, um beides zuzulassen.\n- `fillingForms` – ob Formulare ausgefüllt und signiert werden dürfen. Setze den Wert auf `true`, um das Ausfüllen und Signieren von Formularfeldern zu erlauben.\n- `contentAccessibility` – ob Text für Barrierefreiheit kopiert werden darf. Setze den Wert auf `true`, um dieses Kopieren zu erlauben.\n- `documentAssembly` – ob das Dokument zusammengestellt werden darf. Setze den Wert auf `true`, um das Zusammenstellen zu erlauben.\n\nDu kannst das Benutzerpasswort, das Eigentümerpasswort oder beide angeben. Das Verhalten hängt von den angegebenen Passwörtern ab:\n\n- Wenn nur ein Benutzerpasswort angegeben ist, können Benutzer mit diesem Passwort die Datei entschlüsseln und haben vollen Zugriff auf das Dokument.\n- Wenn nur ein Eigentümerpasswort angegeben ist, können Benutzer das Dokument ohne Passwort entschlüsseln und öffnen, haben aber nur Zugriff auf ausdrücklich erlaubte Vorgänge. Benutzer mit Eigentümerpasswort haben vollen Zugriff auf das Dokument.\n- Wenn beide Passwörter angegeben sind, können Benutzer mit dem Benutzerpasswort die Datei entschlüsseln, haben aber entsprechend den Berechtigungseinstellungen nur eingeschränkten Zugriff. Benutzer mit Eigentümerpasswort haben vollen Zugriff auf das Dokument.\n\nBeachte, dass die PDF-Datei selbst Zugriffsrechte nicht durchsetzen kann. Sobald die Datei entschlüsselt ist, haben PDF-Viewer Zugriff auf den gesamten Dateiinhalt. Es liegt an den Viewer-Anwendungen, die Berechtigungseinstellungen zu beachten.\n\nUm das Verschlüsselungsverfahren auszuwählen, musst du über `version` die PDF-Version angeben. Es wird das bestmögliche Verschlüsselungsverfahren für diese PDF-Version verwendet.\n\n\n> **Note:** Die PDF-Version wird nur für das Verschlüsselungsverfahren verwendet; alle anderen PDF-Elemente haben Version 1.3.\n\n\nVerfügbare Versionen:\n\n- `1.3` – PDF-Version 1.3 (Standard), 40-Bit-RC4\n- `1.4` – PDF-Version 1.4, 128-Bit-RC4\n- `1.5` – PDF-Version 1.5, 128-Bit-RC4\n- `1.6` – PDF-Version 1.6, 128-Bit-AES\n- `1.7` – PDF-Version 1.7, 128-Bit-AES\n- `1.7ext3` – PDF-Version 1.7 ExtensionLevel 3, 256-Bit-AES\n\nBei PDF-Version 1.7 ExtensionLevel 3 wird das Passwort auf 127 Bytes seiner UTF-8-Darstellung gekürzt. In älteren Versionen wird es auf 32 Bytes gekürzt; erlaubt sind dort nur Latin-1-Zeichen.\n"
+ },
+ {
+ "id": "de/document-definition-object/snaking-columns",
+ "language": "de",
+ "translationKey": "document-definition-object/snaking-columns",
+ "path": "/docs/0.3/de/document-definition-object/snaking-columns/",
+ "title": "Schlangenförmige Spalten",
+ "description": "Ordne Inhalte im Zeitungsstil fortlaufend über mehrere Spalten an und beachte die Einschränkungen der Verschachtelung.",
+ "version": "0.3",
+ "sourceDigest": "d3e6aecd99823a11767f72c7ac5e205d78dcb0fcc84bdd4fe9694a3ab50ff869",
+ "source": "document-definition-object/snaking-columns.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/snaking-columns/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/snaking-columns",
+ "markdown": "# Schlangenförmige Spalten\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/snaking-columns/\n\n> **Note:** Mindestversion: **0.3.5**\n\n\nSchlangenförmige Spalten (Spalten im Zeitungsstil) sind ein Layoutmodus, bei dem der Inhalt zunächst vertikal durch die erste Spalte und anschließend am oberen Rand der nächsten Spalte weiterfließt. Der Inhalt bewegt sich bei Bedarf abwechselnd durch die Spalten. Anders als bei Spalten, die für jede neue Zeile wieder oben beginnen, läuft die Reihenfolge fortlaufend durch alle verfügbaren Spalten.\n\nWenn `snakingColumns: true` aktiviert ist, sollte nur die **erste Spalte** Inhalt enthalten. Die folgenden Spalten dienen als leere Platzhalter für den überlaufenden Inhalt.\n\n**JavaScript**\n\n```js\nvar myLongContent = 'A paragraph flowing through snaking columns. '.repeat(120);\nvar docDefinition = {\n content: [\n {\n columns: [\n {text: myLongContent, width: '*'}, // Content goes here\n {text: '', width: '*'}, // Empty overflow target\n {text: '', width: '*'} // Empty overflow target\n ],\n snakingColumns: true\n }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar myLongContent = 'A paragraph flowing through snaking columns. '.repeat(120);\nvar docDefinition: TDocumentDefinitions = {\n content: [\n {\n columns: [\n {text: myLongContent, width: '*'}, // Content goes here\n {text: '', width: '*'}, // Empty overflow target\n {text: '', width: '*'} // Empty overflow target\n ],\n snakingColumns: true\n }\n ]\n};\n```\n\nEine schlangenförmige Spalte direkt in eine weitere schlangenförmige Spalte einzubetten (rekursives Schlangenlayout) wird nicht unterstützt.\n\n**Empfehlungen:**\n- Vermeide tiefe Verschachtelungen schlangenförmiger Spalten.\n- Normale Spalten (ohne Schlangenlayout) können sicher in schlangenförmige Spalten verschachtelt werden.\n- Schlangenförmige Spalten können sicher in normalen Spalten verschachtelt werden.\n"
+ },
+ {
+ "id": "de/document-definition-object/stack",
+ "language": "de",
+ "translationKey": "document-definition-object/stack",
+ "path": "/docs/0.3/de/document-definition-object/stack/",
+ "title": "Absatzstapel",
+ "description": "Ordne Absätze mit der Stack-Struktur in pdfmake 0.3 untereinander an und formatiere verschachtelte Inhalte.",
+ "version": "0.3",
+ "sourceDigest": "04c569677571b5807400b3610efeeabd2981f70fae31c778b9a5337c0abe6c26",
+ "source": "document-definition-object/stack.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/stack/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/stack",
+ "markdown": "# Absatzstapel\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/stack/\n\nAn den Beispielen hast du wahrscheinlich schon erkannt: Wenn du `content` auf ein Array setzt, wird das Dokument als Stapel von Absätzen dargestellt.\n\nDiese Struktur kannst du häufig in einem verschachtelten Element wiederverwenden, wie im folgenden Beispiel:\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n 'paragraph 1',\n 'paragraph 2',\n {\n columns: [\n 'first column is a simple text',\n [\n // second column consists of paragraphs\n 'paragraph A',\n 'paragraph B',\n 'these paragraphs will be rendered one below another inside the column'\n ]\n ]\n }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n 'paragraph 1',\n 'paragraph 2',\n {\n columns: [\n 'first column is a simple text',\n [\n // second column consists of paragraphs\n 'paragraph A',\n 'paragraph B',\n 'these paragraphs will be rendered one below another inside the column'\n ]\n ]\n }\n ]\n};\n```\n\nEin Array hat den Nachteil, dass du ihm keine Formatierungseigenschaften hinzufügen kannst (zum Beispiel, um `fontSize` zu ändern).\n\nDie gute Nachricht: In pdfMake ist ein Array nur eine Kurzform für `{ stack: [] }`. Wenn du den ganzen Stapel anders formatieren möchtest, kannst du die ausführliche Definition verwenden:\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n 'paragraph 1',\n 'paragraph 2',\n {\n columns: [\n 'first column is a simple text',\n {\n stack: [\n // second column consists of paragraphs\n 'paragraph A',\n 'paragraph B',\n 'these paragraphs will be rendered one below another inside the column'\n ],\n fontSize: 15\n }\n ]\n }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n 'paragraph 1',\n 'paragraph 2',\n {\n columns: [\n 'first column is a simple text',\n {\n stack: [\n // second column consists of paragraphs\n 'paragraph A',\n 'paragraph B',\n 'these paragraphs will be rendered one below another inside the column'\n ],\n fontSize: 15\n }\n ]\n }\n ]\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/styling",
+ "language": "de",
+ "translationKey": "document-definition-object/styling",
+ "path": "/docs/0.3/de/document-definition-object/styling/",
+ "title": "Stile und Formatierung",
+ "description": "Formatiere Text mit benannten Stilen, Schriftvarianten, Ausrichtung, Farben und Vererbung in pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "9369a9e17f5173482ecd79123f5aee3a2489a7678b916cec9f9003263fe860ae",
+ "source": "document-definition-object/styling.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/styling/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/styling",
+ "markdown": "# Stile und Formatierung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/styling/\n\n## Blöcke oder Inline-Text formatieren\n\nEine Zeichenfolge ist ein einfacher Absatz. Verwende einen Textknoten, um Eigenschaften hinzuzufügen. Mit einem `text`-Array kannst du Textsegmente **innerhalb desselben Absatzes** unterschiedlich formatieren; ein `content`-Array oder ein Stapel erzeugt getrennte Blöcke.\n\n\n\n### Runnable example: 04 · Text & named styles\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [\n { text: 'Style with intent', style: 'heading' },\n { text: ['One paragraph with ', { text: 'bold', bold: true }, ' and ', { text: 'italic', italics: true }, ' inline text.'] },\n { text: 'A reusable note style.', style: 'note' },\n { ul: ['Readable defaults', 'Small style dictionaries', 'Consistent spacing'], margin: [0, 12, 0, 0] }\n ],\n defaultStyle: { fontSize: 12, lineHeight: 1.3 },\n styles: {\n heading: { fontSize: 26, bold: true, color: '#08786b', margin: [0, 0, 0, 18] },\n note: { fontSize: 10, color: '#536771', margin: [0, 12, 0, 0] }\n }\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [\n { text: 'Style with intent', style: 'heading' },\n { text: ['One paragraph with ', { text: 'bold', bold: true }, ' and ', { text: 'italic', italics: true }, ' inline text.'] },\n { text: 'A reusable note style.', style: 'note' },\n { ul: ['Readable defaults', 'Small style dictionaries', 'Consistent spacing'], margin: [0, 12, 0, 0] }\n ],\n defaultStyle: { fontSize: 12, lineHeight: 1.3 },\n styles: {\n heading: { fontSize: 26, bold: true, color: '#08786b', margin: [0, 0, 0, 18] },\n note: { fontSize: 10, color: '#536771', margin: [0, 12, 0, 0] }\n }\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=styles)\n\n\n\n## Benannte Stile wiederverwenden\n\n**JavaScript**\n\n```js\nvar dd = {\n defaultStyle: { fontSize: 11, lineHeight: 1.2 },\n styles: {\n heading: { fontSize: 24, bold: true },\n muted: { color: '#536771' },\n subheading: { extends: 'heading', fontSize: 16 }\n },\n content: [\n { text: 'A heading', style: 'heading' },\n { text: 'A muted heading', style: ['heading', 'muted'] },\n { text: 'An explicit override', style: 'heading', fontSize: 18 },\n { text: 'A subheading', style: 'subheading' }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n defaultStyle: { fontSize: 11, lineHeight: 1.2 },\n styles: {\n heading: { fontSize: 24, bold: true },\n muted: { color: '#536771' },\n subheading: { extends: 'heading', fontSize: 16 }\n },\n content: [\n { text: 'A heading', style: 'heading' },\n { text: 'A muted heading', style: ['heading', 'muted'] },\n { text: 'An explicit override', style: 'heading', fontSize: 18 },\n { text: 'A subheading', style: 'subheading' }\n ]\n};\n```\n\n`style` verweist auf Einträge in `styles`. Wenn mehrere Stile in einem Array dieselbe Eigenschaft definieren, hat der spätere Stil Vorrang. Explizite Eigenschaften des Knotens haben Vorrang vor seinen benannten Stilen. `defaultStyle` stellt dokumentweite Standardwerte bereit. Stile von Containern können an ihre Kindelemente vererbt werden; explizite Eigenschaften des Kindelements überschreiben sie.\n\nBenannte Stile unterstützen `extends` seit **0.3.3**. Die Eigenschaft akzeptiert einen übergeordneten Namen oder ein Array mit Namen. Die eigenen Eigenschaften eines Stils haben Vorrang vor den übergeordneten; wenn mehrere übergeordnete Stile dieselbe Eigenschaft festlegen, hat der spätere Vorrang. Halte die Vererbung kurz und frei von Zyklen, damit das Ergebnis übersichtlich bleibt.\n\n## Häufige Texteigenschaften\n\n| Eigenschaft | Typ / Werte | Bedeutung |\n| --- | --- | --- |\n| `font` | Registrierter Familienname | Muss mit deiner Schriftzuordnung übereinstimmen |\n| `fontSize` | Zahl, Punkte | Textgröße |\n| `bold`, `italics` | Boolean, Standard `false` | Wählt die entsprechende Schriftvariante aus |\n| `alignment` | `'left'`, `'center'`, `'right'`, `'justify'` | Absatzausrichtung |\n| `lineHeight` | Zahl, Standard 1 | Zeilenhöhenmultiplikator |\n| `color`, `background` | Farbname oder Hex-Zeichenfolge | Textfarbe und Texthintergrund |\n| `characterSpacing` | Zahl, Punkte | Zusätzlicher Abstand zwischen Zeichen |\n| `wordBreak` | `'normal'` (Standard), `'break-all'` | Verhalten beim Zeilenumbruch |\n| `fontFeatures` | Array mit Zeichenfolgen | Schriftartspezifische typografische Merkmale |\n| `style` | Zeichenfolge oder Array mit Zeichenfolgen | Anzuwendende benannte Stile |\n| `markerColor` | Farbe | Farbe des Aufzählungszeichens |\n\nUnterstützt werden benannte Farben und Hexwerte wie `'#08786b'`. Schriftmerkmale hängen von der ausgewählten Schriftart ab. Für `bold` oder `italics` muss die jeweilige Variante registriert sein; das Setzen einer Eigenschaft ersetzt keine fehlende Schriftdatei.\n\n## Auszeichnungen\n\n| Eigenschaft | Typ / Werte |\n| --- | --- |\n| `decoration` | `'underline'`, `'lineThrough'`, `'overline'` oder ein Array |\n| `decorationStyle` | `'solid'`, `'dashed'`, `'dotted'`, `'double'`, `'wavy'` |\n| `decorationColor` | Farbe |\n| `decorationThickness` | Numerische Breite; seit 0.3.3 |\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [{ text: 'A marked passage', decoration: 'underline', decorationStyle: 'wavy', decorationColor: '#08786b' }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [{ text: 'A marked passage', decoration: 'underline', decorationStyle: 'wavy', decorationColor: '#08786b' }]\n};\n```\n\n## Stile sind kein CSS\n\nVerwende die dokumentierten Feldnamen von pdfmake. Es gibt weder CSS-Kaskade noch DOM-Selektor oder Browser-Boxmodell. Ränder werden in Punkten angegeben und folgen der Reihenfolge `[links, oben, rechts, unten]`. Um mehrere Blöcke gemeinsam zu formatieren, verwende einen [Stapel](/docs/0.3/de/document-definition-object/stack/). Informationen zur Registrierung von Schriftvarianten und Zeichenabdeckung findest du unter [Schriften](/docs/0.3/de/fonts/).\n"
+ },
+ {
+ "id": "de/document-definition-object/svgs",
+ "language": "de",
+ "translationKey": "document-definition-object/svgs",
+ "path": "/docs/0.3/de/document-definition-object/svgs/",
+ "title": "SVGs",
+ "description": "Binde SVG-Inhalte in pdfmake 0.3 als Text oder SVGElement ein und skaliere sie proportional oder passend in ein Rechteck.",
+ "version": "0.3",
+ "sourceDigest": "1370a9ae1ce49896f1ce3301d0947639f4e5fd7225b9babd15b140e19eed060a",
+ "source": "document-definition-object/svgs.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/svgs/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/svgs",
+ "markdown": "# SVGs\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/svgs/\n\nSVGs ähneln [Bildern](/docs/0.3/de/document-definition-object/images/), derzeit können sie jedoch weder über eine Datei eingebunden noch aus einem Wörterbuch wiederverwendet werden.\n\n\n> **Note:** Der SVG-Knoten erwartet einen gültigen SVG-Wert. Ist der Wert ungültig oder leer, wird ein Fehler ausgelöst.\n\n\nFür die Umwandlung von SVG in ein PDF-Dokument wird die Bibliothek [SVG-to-PDFKit](https://github.com/alafr/SVG-to-PDFKit) verwendet.\n\nDer Wert des Knotens `svg` kann eine Zeichenfolge oder ein `SVGElement`-Objekt sein (letzteres ist nur im Browser verfügbar).\n\n\n> **Note:** `SVGElement`-Objekte werden ab Version **0.3.1** unterstützt.\n\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n {\n // If no width/height/fit is used, then dimensions from the svg element is used.\n svg: '... '\n },\n {\n // if you specify width, svg will scale proportionally\n svg: '... ',\n width: 150\n },\n {\n // if you specify height, svg will scale proportionally\n // Minimal pdfmake version: 0.3.2\n svg: '... ',\n height: 100\n },\n {\n // if you specify both width and height - svg will be stretched\n svg: '... ',\n width: 600,\n height: 400\n },\n {\n // you can also fit the svg inside a rectangle\n svg: '... ',\n fit: [150, 100]\n },\n {\n // if no width/height is specified in SVG element, you must set width and height for node\n svg: '... ',\n width: 300,\n height: 200\n },\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n {\n // If no width/height/fit is used, then dimensions from the svg element is used.\n svg: '... '\n },\n {\n // if you specify width, svg will scale proportionally\n svg: '... ',\n width: 150\n },\n {\n // if you specify height, svg will scale proportionally\n // Minimal pdfmake version: 0.3.2\n svg: '... ',\n height: 100\n },\n {\n // if you specify both width and height - svg will be stretched\n svg: '... ',\n width: 600,\n height: 400\n },\n {\n // you can also fit the svg inside a rectangle\n svg: '... ',\n fit: [150, 100]\n },\n {\n // if no width/height is specified in SVG element, you must set width and height for node\n svg: '... ',\n width: 300,\n height: 200\n },\n ]\n};\n```\n"
+ },
+ {
+ "id": "de/document-definition-object/tables",
+ "language": "de",
+ "translationKey": "document-definition-object/tables",
+ "path": "/docs/0.3/de/document-definition-object/tables/",
+ "title": "Tabellen",
+ "description": "Erstelle Tabellen mit einheitlichen Zeilen, wiederholten Kopfzeilen, benutzerdefinierten Rahmen, Breiten und verbundenen Zellen.",
+ "version": "0.3",
+ "sourceDigest": "c80db33fd2025ca3fdc93880f47e52e7b8169c0b5a2901a4156cd2d208073487",
+ "source": "document-definition-object/tables.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/tables/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/tables",
+ "markdown": "# Tabellen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/tables/\n\n## Mit Zeilen und wiederholter Kopfzeile beginnen\n\nVerwende eine Tabelle, wenn Zellen verschiedener Zeilen ausgerichtet werden sollen. `body` ist ein Array mit Zeilen-Arrays. Jede Zeile muss dieselbe Anzahl von Zellen enthalten; Zellen können Text oder andere pdfmake-Knoten enthalten. `headerRows: 1` wiederholt die erste Zeile, wenn die Tabelle auf einer neuen Seite fortgesetzt wird.\n\n\n\n### Runnable example: 03 · Tables & repeating headers\n\n**JavaScript**\n\n```js\nvar rows = Array.from({ length: 65 }, (_, i) => [\n 'Item ' + (i + 1), 'A row that can continue across pages', String(i + 1)\n]);\nvar dd = {\n content: [\n { text: 'A longer table', fontSize: 24, bold: true, margin: [0, 0, 0, 16] },\n { layout: 'lightHorizontalLines', table: {\n headerRows: 1, widths: [70, '*', 40],\n body: [[{ text: 'Item', bold: true }, { text: 'Description', bold: true }, { text: 'Qty', bold: true }], ...rows]\n } }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar rows = Array.from({ length: 65 }, (_, i) => [\n 'Item ' + (i + 1), 'A row that can continue across pages', String(i + 1)\n]);\nvar dd: TDocumentDefinitions = {\n content: [\n { text: 'A longer table', fontSize: 24, bold: true, margin: [0, 0, 0, 16] },\n { layout: 'lightHorizontalLines', table: {\n headerRows: 1, widths: [70, '*', 40],\n body: [[{ text: 'Item', bold: true }, { text: 'Description', bold: true }, { text: 'Qty', bold: true }], ...rows]\n } }\n ]\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=tables)\n\n\n\n## Breiten auswählen\n\n| Breite | Bedeutung | Geeignet, wenn |\n| --- | --- | --- |\n| Eine Zahl, zum Beispiel `80` | Feste Punkte | Codes, Mengen oder eine Spalte mit vorhersehbaren Beschriftungen |\n| `'*'` | Verbleibende Breite teilen | Eine Beschreibung den verfügbaren Platz ausfüllen soll |\n| `'auto'` | Inhalt messen | Kurze Beschriftungen nur die benötigte Breite belegen sollen |\n| Prozentangabe als Zeichenfolge | Prozentuale Breite | Ein proportionales Layout erforderlich ist; gemischte Breiten sorgfältig prüfen |\n\nRahmen, Innenabstände, Seitenränder und andere Spalten belegen ebenfalls Platz. Beginne mit festen Breiten und Sternbreiten und verwende `auto`, wenn eine inhaltsabhängige Größe beabsichtigt ist. Vermeide große feste Breiten, die den Inhaltsbereich überschreiten.\n\n## Tabellen- und Zellfelder\n\n| Feld | Ebene | Typ / Zweck |\n| --- | --- | --- |\n| `body` | `table` | Nichtleere Zeilen-Arrays |\n| `widths` | `table` | Breitenangaben, eine pro Spalte |\n| `headerRows` | `table` | Anzahl der ersten Zeilen, die als Kopfzeile wiederholt werden |\n| `dontBreakRows` | `table` | Verhindert, dass eine einzelne Zeile auf mehrere Seiten aufgeteilt wird |\n| `keepWithHeaderRows` | `table` | Anzahl der folgenden Zeilen, die zusammen mit der Kopfzeile gehalten werden |\n| `layout` | Knoten neben `table` | Name eines integrierten Layouts, registrierter eigener Name oder Layoutobjekt |\n| `tableAlignment` | Knoten neben `table` | Horizontale Ausrichtung der gesamten Tabelle: `left`, `center`, `right`; seit 0.3.13 |\n| `colSpan`, `rowSpan` | Zelle | Positive Anzahl der überspannten Spalten/Zeilen; Platzhalter sind weiterhin erforderlich |\n| `verticalAlignment` | Zelle | `'top'` (Standard), `'middle'` oder `'bottom'` |\n| `border` | Zelle | Vier boolesche Werte: links, oben, rechts, unten |\n| `borderColor` | Zelle | Vier Farben in derselben Reihenfolge |\n| `fillColor` | Zelle | Hintergrundfarbe oder unterstütztes Mustertupel |\n| `fillOpacity` | Zelle | Numerische Deckkraft des Hintergrunds |\n| `overlayPattern`, `overlayOpacity` | Zelle | Mustertupel und numerische Deckkraft, die über den Inhalt gelegt werden |\n\nEine Zeile zusammenzuhalten sorgt nicht dafür, dass eine übergroße Zeile auf eine Seite passt. Prüfe lange Beschreibungen und verschachtelten Inhalt mit deiner tatsächlichen Seitengröße und deinen Schriften.\n\n## Die gesamte Tabelle ausrichten\n\n**Seit 0.3.13.** Setze `tableAlignment` am Knoten neben `table`. Unterstützt werden `left` (Standard), `center` und `right`. Damit wird die gesamte Tabelle innerhalb der verfügbaren Breite positioniert; `alignment` steuert unabhängig davon den Text in den Zellen.\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [{\n tableAlignment: 'center',\n alignment: 'left',\n table: {\n widths: ['auto', 'auto'],\n body: [['Item', 'Quantity'], ['Example', '2']]\n }\n }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [{\n tableAlignment: 'center',\n alignment: 'left',\n table: {\n widths: ['auto', 'auto'],\n body: [['Item', 'Quantity'], ['Example', '2']]\n }\n }]\n};\n```\n\nDas Beispiel zentriert die Tabelle und lässt den Text linksbündig. Mit `tableAlignment: 'right'` wird die Tabelle rechts ausgerichtet. Die Ausrichtung ist sichtbar, wenn die Tabelle schmaler als ihre verfügbare Breite ist, beispielsweise mit `auto` oder festen Spaltenbreiten. Tabellen, die diese Breite ausfüllen oder überschreiten, bleiben links. Seitenränder sowie die umgebende Spalte oder Tabellenzelle bestimmen die verfügbare Breite.\n\n## Zellen verbinden, ohne die Zeilenlänge zu ändern\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [{\n table: {\n widths: ['*', '*', '*'],\n body: [\n [{ text: 'A heading across three columns', colSpan: 3, bold: true }, {}, {}],\n [{ text: 'Two rows', rowSpan: 2 }, 'A', 'B'],\n [{}, 'C', 'D']\n ]\n }\n }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [{\n table: {\n widths: ['*', '*', '*'],\n body: [\n [{ text: 'A heading across three columns', colSpan: 3, bold: true }, {}, {}],\n [{ text: 'Two rows', rowSpan: 2 }, 'A', 'B'],\n [{}, 'C', 'D']\n ]\n }\n }]\n};\n```\n\nDie leeren Objekte belegen die von einer Zelle überspannten Plätze. Ohne sie ist eine Zeile nicht einheitlich. Verwende `undefined` nicht als Platzhalter. Das [Playground-Beispiel zu Zellüberspannungen](/docs/0.3/de/playground/?example=spans) zeigt diese Definition.\n\n## Integriertes Layout verwenden\n\nDie Layouts `noBorders`, `headerLineOnly` und `lightHorizontalLines` stehen unter ihrem Namen zur Verfügung. Setze `layout` neben `table`, nicht innerhalb davon:\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [{\n layout: 'lightHorizontalLines',\n table: { headerRows: 1, widths: ['*', 'auto'], body: [['Item', 'Qty'], ['Notebook', 3]] }\n }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [{\n layout: 'lightHorizontalLines',\n table: { headerRows: 1, widths: ['*', 'auto'], body: [['Item', 'Qty'], ['Notebook', 3]] }\n }]\n};\n```\n\n## Eigenes Layout registrieren\n\nRegistriere Layouts, bevor du das Dokument erstellst. Verwende in Node.js dein konfiguriertes `pdfmake`-Singleton und im Browser `pdfMake`.\n\n**JavaScript**\n\n```js\npdfMake.addTableLayouts({\n compact: {\n hLineWidth: function (index, node) {\n return index === node.table.headerRows ? 1 : 0;\n },\n vLineWidth: function () { return 0; },\n hLineColor: function () { return '#b7cfc4'; },\n paddingLeft: function () { return 6; },\n paddingRight: function () { return 6; }\n }\n});\n\nvar dd = {\n content: [{ layout: 'compact', table: { headerRows: 1, body: [['Item', 'Qty'], ['Notebook', 3]] } }]\n};\n```\n\n**TypeScript**\n\n```ts\nimport pdfMake from \"pdfmake/build/pdfmake.js\";\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\npdfMake.addTableLayouts({\n compact: {\n hLineWidth: function (index, node) {\n return index === node.table.headerRows ? 1 : 0;\n },\n vLineWidth: function () { return 0; },\n hLineColor: function () { return '#b7cfc4'; },\n paddingLeft: function () { return 6; },\n paddingRight: function () { return 6; }\n }\n});\n\nvar dd: TDocumentDefinitions = {\n content: [{ layout: 'compact', table: { headerRows: 1, body: [['Item', 'Qty'], ['Notebook', 3]] } }]\n};\n```\n\nDas Snippet setzt voraus, dass Browser-Engine und Schriften geladen sind. Eine Layoutvariable zu definieren, registriert sie noch nicht. Verwende möglichst deterministische Callbacks und ändere gemeinsam genutzte Konfiguration nicht während paralleler Node.js-Aufträge.\n\n## Fehlerhafte Tabellen diagnostizieren\n\nPrüfe `body`, bevor du Rahmen oder Breiten änderst: Es muss Zeilen-Arrays mit einheitlicher Länge enthalten. Prüfe anschließend die Platzhalter für überspannte Zellen. Im lokalen Verbesserungszweig nennen Diagnosen den fehlerhaften Definitionspfad und die erwartete Zellanzahl. Siehe [Fehler und Diagnose](/docs/0.3/de/guides/errors/).\n"
+ },
+ {
+ "id": "de/document-definition-object/toc",
+ "language": "de",
+ "translationKey": "document-definition-object/toc",
+ "path": "/docs/0.3/de/document-definition-object/toc/",
+ "title": "Inhaltsverzeichnis",
+ "description": "Erzeuge ein oder mehrere Inhaltsverzeichnisse aus markierten Elementen, mit Sortierung, Stilen und optionalen PDF-Lesezeichen.",
+ "version": "0.3",
+ "sourceDigest": "54b38f6844726a1c78499e217c2cf64d2cebd568ef974973ac6c9a7ee39cac11",
+ "source": "document-definition-object/toc.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/toc/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/toc",
+ "markdown": "# Inhaltsverzeichnis\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/toc/\n\n## Überschriften zur Aufnahme markieren\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n { toc: { title: { text: 'Contents', fontSize: 20, bold: true }, numberStyle: { bold: true } } },\n { text: 'Introduction', tocItem: true, fontSize: 18, margin: [0, 20, 0, 10] },\n 'Document body',\n { text: 'Details', tocItem: true, pageBreak: 'before', fontSize: 18 }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n { toc: { title: { text: 'Contents', fontSize: 20, bold: true }, numberStyle: { bold: true } } },\n { text: 'Introduction', tocItem: true, fontSize: 18, margin: [0, 20, 0, 10] },\n 'Document body',\n { text: 'Details', tocItem: true, pageBreak: 'before', fontSize: 18 }\n ]\n};\n```\n\nDer `toc`-Knoten fügt das erzeugte Verzeichnis ein; `tocItem` markiert Textknoten, die darin aufgeführt werden sollen. Die Seitenzahlen werden während des Layouts berechnet.\n\n## Mehrere Inhaltsverzeichnisse\n\nJedes Inhaltsverzeichnis ist ein eigener Inhaltsknoten. Mit IDs legst du fest, in welchen Listen die einzelnen Einträge erscheinen:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: [\n { toc: { id: 'main', title: 'All sections' } },\n { toc: { id: 'details', title: 'Detailed sections' } },\n { text: 'Overview', tocItem: 'main' },\n { text: 'Technical details', tocItem: ['main', 'details'], pageBreak: 'before' }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: [\n { toc: { id: 'main', title: 'All sections' } },\n { toc: { id: 'details', title: 'Detailed sections' } },\n { text: 'Overview', tocItem: 'main' },\n { text: 'Technical details', tocItem: ['main', 'details'], pageBreak: 'before' }\n ]\n};\n```\n\nFüge nicht zwei `toc`-Schlüssel in dasselbe Objekt ein; JavaScript behält nur den letzten Wert.\n\n## Optionen des Inhaltsverzeichnisses\n\n| Feld | Typ | Bedeutung |\n| --- | --- | --- |\n| `id` | string | Kennung für ein benanntes Inhaltsverzeichnis |\n| `title` | string oder Textknoten | Optionaler Titel |\n| `textStyle`, `numberStyle` | Stilobjekt | Formatierung des Eintragstextes und der Seitenzahl |\n| `textMargin` | Abstand | Abstand des Eintrags |\n| `hideEmpty` | boolean | Leeres Inhaltsverzeichnis ausblenden; Standard `false`, seit 0.3.3 |\n| `sortBy` | `'page'` oder `'title'` | Sortierreihenfolge; Standard `page`, seit 0.3.3 |\n| `sortLocale` | string | Gebietsschema für die Sortierung; standardmäßig das Laufzeitgebietsschema, seit 0.3.3 |\n| `outlines` | boolean | Einträge in PDF-Lesezeichen aufnehmen; seit 0.3.5 |\n\nBei einem markierten Textknoten akzeptiert `tocItem` den Wert `true`, eine ToC-ID oder ein Array mit IDs. Mit `textStyle`, `numberStyle` und `textMargin` des Textknotens kannst du den Eintrag formatieren. Steuere Lesezeichen über [Gliederungen](/docs/0.3/de/document-definition-object/outlines/).\n"
+ },
+ {
+ "id": "de/document-definition-object/watermark",
+ "language": "de",
+ "translationKey": "document-definition-object/watermark",
+ "path": "/docs/0.3/de/document-definition-object/watermark/",
+ "title": "Wasserzeichen",
+ "description": "Lege Wasserzeichen in pdfmake 0.3 mit Beispielen, Optionen und Anwendungshinweisen fest.",
+ "version": "0.3",
+ "sourceDigest": "6282ba69e28519af356033aef8c20701350b760f1926f0c1d592767e5cde5c02",
+ "source": "document-definition-object/watermark.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/document-definition-object/watermark/",
+ "uri": "pdfmake://docs/0.3/de/document-definition-object/watermark",
+ "markdown": "# Wasserzeichen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/document-definition-object/watermark/\n\n## Eigenschaften\n\n* `text` – Text des Wasserzeichens\n* `color` – Textfarbe\n* `opacity` – Deckkraft des Textes\n* `bold` – fette Textformatierung\n* `italics` – kursive Textformatierung\n* `fontSize` – eigene Schriftgröße des Textes (die ideale Größe wird automatisch berechnet)\n* `angle` – Drehwinkel des Textes\n\n## Beispiele\n\nEin einfaches Beispiel für die Verwendung:\n**JavaScript**\n\n```js\nvar docDefinition = {\n watermark: 'test watermark',\n content: [\n '...'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n watermark: 'test watermark',\n content: [\n '...'\n ]\n};\n```\n\nBeispiel mit Schriftformatierung:\n**JavaScript**\n\n```js\nvar docDefinition = {\n watermark: { text: 'test watermark', color: 'blue', opacity: 0.3, bold: true, italics: false },\n content: [\n '...'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n watermark: { text: 'test watermark', color: 'blue', opacity: 0.3, bold: true, italics: false },\n content: [\n '...'\n ]\n};\n```\n\nBeispiel mit eigener Schriftgröße:\n**JavaScript**\n\n```js\nvar docDefinition = {\n watermark: { text: 'test watermark', fontSize: 20 },\n content: [\n '...'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n watermark: { text: 'test watermark', fontSize: 20 },\n content: [\n '...'\n ]\n};\n```\n\nBeispiel für den Drehwinkel des Wasserzeichens:\n**JavaScript**\n\n```js\nvar docDefinition = {\n watermark: { text: 'test watermark', angle: 70 },\n content: [\n '...'\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n watermark: { text: 'test watermark', angle: 70 },\n content: [\n '...'\n ]\n};\n```\n"
+ },
+ {
+ "id": "de/fonts",
+ "language": "de",
+ "translationKey": "fonts",
+ "path": "/docs/0.3/de/fonts/",
+ "title": "Schriften und Zeichensatzabdeckung",
+ "description": "Registriere Schriftfamilien und Varianten in Node.js oder im Browser und wähle Schriften, die die Sprachen deines Dokuments abdecken.",
+ "version": "0.3",
+ "sourceDigest": "62a4549bbe46519fb6f576d6cab99d9ed5fc071bddcfb1b77fa75f75df6e785b",
+ "source": "fonts/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/",
+ "uri": "pdfmake://docs/0.3/de/fonts",
+ "markdown": "# Schriften und Zeichensatzabdeckung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/\n\n## Schriftstrategie auswählen\n\n| Laufzeit | Schriftquelle | Einrichtung |\n| --- | --- | --- |\n| Node.js | Echte Schriftdateien | `addFonts` mit absoluten Pfaden |\n| Node.js | PDF-Standardschriften | `require('pdfmake/standard-fonts/Helvetica')` |\n| Browser | Gebündeltes Roboto-VFS | `build/vfs_fonts.js` laden |\n| Browser | Benutzerdefiniertes VFS oder URLs | [Eigene Browser-Schriften](/docs/0.3/de/fonts/custom-fonts-client-side/) |\n\nDie Standardschriftfamilie ist `Roboto`. In Node.js werden die Dateien nicht automatisch registriert. Jede Familie sollte `normal`, `bold`, `italics` und `bolditalics` passenden Schriftdaten zuordnen. Ein Stil, der eine nicht registrierte Variante auswählt, kann fehlschlagen, obwohl normaler Text funktioniert.\n\n## Lokale Schriften in Node.js registrieren\n\nDieses Beispiel setzt voraus, dass sich lizenzierte Schriftdateien in einem Verzeichnis `fonts` neben deinem CommonJS-Skript befinden:\n\n**JavaScript**\n\n```js\nconst path = require('node:path');\nconst pdfmake = require('pdfmake');\nconst fonts = {\n Roboto: {\n normal: path.join(__dirname, 'fonts/Roboto-Regular.ttf'),\n bold: path.join(__dirname, 'fonts/Roboto-Medium.ttf'),\n italics: path.join(__dirname, 'fonts/Roboto-Italic.ttf'),\n bolditalics: path.join(__dirname, 'fonts/Roboto-MediumItalic.ttf')\n }\n};\nconst allowed = new Set(Object.values(fonts.Roboto));\npdfmake.addFonts(fonts);\npdfmake.setLocalAccessPolicy(file => allowed.has(path.resolve(file)));\npdfmake.setUrlAccessPolicy(() => false);\n```\n\n**TypeScript**\n\n```ts\nconst path = require('node:path');\nimport pdfmake from \"pdfmake\";\nconst fonts = {\n Roboto: {\n normal: path.join(__dirname, 'fonts/Roboto-Regular.ttf'),\n bold: path.join(__dirname, 'fonts/Roboto-Medium.ttf'),\n italics: path.join(__dirname, 'fonts/Roboto-Italic.ttf'),\n bolditalics: path.join(__dirname, 'fonts/Roboto-MediumItalic.ttf')\n }\n};\nconst allowed = new Set(Object.values(fonts.Roboto));\npdfmake.addFonts(fonts);\npdfmake.setLocalAccessPolicy(file => allowed.has(path.resolve(file)));\npdfmake.setUrlAccessPolicy(() => false);\n```\n\nDie Zulassungsliste eignet sich für unveränderliche Dateien, die deiner Anwendung gehören. Wenn Pfade von nicht vertrauenswürdigen Benutzern kommen, musst du auch symbolische Links und Dateisystemberechtigungen berücksichtigen. Ein Zeichenfolgenpräfix wie `fonts/` ist keine sichere Zugriffsschranke.\n\n## Text auf Glyphenabdeckung abstimmen\n\nStandardschriften haben begrenzte Kodierungen und decken nicht beliebige Unicode-Zeichen ab. Wähle eingebettete Schriften mit den benötigten Glyphen deiner tatsächlichen Sprachen. Eine Unicode-Zeichenfolge allein garantiert nicht, dass die ausgewählte Schrift sie darstellen kann. Prüfe repräsentative Zeichen und alle fetten und kursiven Varianten in erzeugten PDFs.\n\npdfmake bettet Schriften über PDFKit ein. Binde im Browser nur benötigte Schriftfamilien ein; VFS-Daten erhöhen Download- und Verarbeitungskosten. Beachte die Lizenz zur Weitergabe und Einbettung jeder Schrift.\n\n## Verwandte Anleitungen\n\n[14 Standardschriften](/docs/0.3/de/fonts/standard-14-fonts/) · [Browser-VFS](/docs/0.3/de/fonts/custom-fonts-client-side/vfs/) · [Schrift-URLs](/docs/0.3/de/fonts/custom-fonts-client-side/url/) · [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/)\n"
+ },
+ {
+ "id": "de/fonts/custom-fonts-client-side",
+ "language": "de",
+ "translationKey": "fonts/custom-fonts-client-side",
+ "path": "/docs/0.3/de/fonts/custom-fonts-client-side/",
+ "title": "Eigene Schriften im Browser",
+ "description": "Verwende eigene Schriften in pdfmake 0.3 in Browseranwendungen.",
+ "version": "0.3",
+ "sourceDigest": "ac4405571a6117ebb522a964e5a17a54067292ff7e11fe6f1321aedbbec503a3",
+ "source": "fonts/custom-fonts-client-side/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/",
+ "uri": "pdfmake://docs/0.3/de/fonts/custom-fonts-client-side",
+ "markdown": "# Eigene Schriften im Browser\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/\n\npdfmake verwendet standardmäßig die Schrift Roboto. Diese Anleitung erklärt, wie du in Browser-Code eigene Schriften mit pdfmake verwendest.\n\n## Es gibt zwei Möglichkeiten:\n* [Verwende ein virtuelles Dateisystem](/docs/0.3/de/fonts/custom-fonts-client-side/vfs/).\n* [Verwende eine Schriftdatei über eine URL (https://- oder http://-Protokoll)](/docs/0.3/de/fonts/custom-fonts-client-side/url/).\n"
+ },
+ {
+ "id": "de/fonts/custom-fonts-client-side/url",
+ "language": "de",
+ "translationKey": "fonts/custom-fonts-client-side/url",
+ "path": "/docs/0.3/de/fonts/custom-fonts-client-side/url/",
+ "title": "Über das URL-Protokoll",
+ "description": "Binde Schriftdateien über URL-Adressen in pdfmake ein und registriere sie für die Verwendung in der Browseranwendung.",
+ "version": "0.3",
+ "sourceDigest": "7a21062929c7b5e61fa55fb47082995e80a6dab97f654ad3fa35ab0370e6ceef",
+ "source": "fonts/custom-fonts-client-side/url/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/url/",
+ "uri": "pdfmake://docs/0.3/de/fonts/custom-fonts-client-side/url",
+ "markdown": "# Über das URL-Protokoll\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/url/\n\nUm eigene Schriften zu verwenden, sind zwei Schritte erforderlich:\n\n1. Weise `pdfMake.addFonts(...)` in JavaScript deine über eine URL erreichbaren Schriftdateien zu.\n2. Gib die Schrift in der Dokumentdefinition an.\n\n## 1. Weise `pdfMake.addFonts(...)` in JavaScript die Schriftdateien zu\n\nSchriftdateien müssen über eine URL (mit `https://`- oder `http://`-Protokoll) erreichbar sein. Rufe in deinem Code vor `pdfMake.createPdf(docDefinition)` `pdfMake.addFonts(...)` auf, wie im folgenden Beispiel:\n\n**JavaScript**\n\n```js\nvar fonts = {\n yourFontName: {\n normal: 'https://example.com/fonts/fontFile.ttf',\n bold: 'https://example.com/fonts/fontFile2.ttf',\n italics: 'https://example.com/fonts/fontFile3.ttf',\n bolditalics: 'https://example.com/fonts/fontFile4.ttf'\n },\n anotherFontName: {\n\n },\n\n // download default Roboto font from unpkg.com\n Roboto: {\n normal: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Regular.ttf',\n bold: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Medium.ttf',\n italics: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Italic.ttf',\n bolditalics: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-MediumItalic.ttf'\n },\n\n // example of usage fonts in collection\n PingFangSC: {\n normal: ['https://example.com/fonts/pingfang.ttc', 'PingFangSC-Regular'],\n bold: ['https://example.com/fonts/pingfang.ttc', 'PingFangSC-Semibold'],\n }\n};\n\npdfMake.addFonts(fonts);\n```\n\n**TypeScript**\n\n```ts\nvar fonts = {\n yourFontName: {\n normal: 'https://example.com/fonts/fontFile.ttf',\n bold: 'https://example.com/fonts/fontFile2.ttf',\n italics: 'https://example.com/fonts/fontFile3.ttf',\n bolditalics: 'https://example.com/fonts/fontFile4.ttf'\n },\n anotherFontName: {\n\n },\n\n // download default Roboto font from unpkg.com\n Roboto: {\n normal: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Regular.ttf',\n bold: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Medium.ttf',\n italics: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-Italic.ttf',\n bolditalics: 'https://unpkg.com/pdfmake@0.3.13/build/fonts/Roboto/Roboto-MediumItalic.ttf'\n },\n\n // example of usage fonts in collection\n PingFangSC: {\n normal: ['https://example.com/fonts/pingfang.ttc', 'PingFangSC-Regular'],\n bold: ['https://example.com/fonts/pingfang.ttc', 'PingFangSC-Semibold'],\n }\n};\n\npdfMake.addFonts(fonts);\n```\n\n## 2. Gib die Schrift in deiner Dokumentdefinition an\n\npdfMake verwendet standardmäßig `Roboto`. Damit deine eigene Schrift verwendet wird, musst du sie in der Dokumentdefinition angeben.\n\nAm einfachsten legst du sie global in **`defaultStyle`** fest:\n\n**JavaScript**\n\n```js\nvar docDefinition = {\n content: ['Example document content'],\n defaultStyle: {\n font: 'yourFontName'\n }\n}\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar docDefinition: TDocumentDefinitions = {\n content: ['Example document content'],\n defaultStyle: {\n font: 'yourFontName'\n }\n}\n```\n"
+ },
+ {
+ "id": "de/fonts/custom-fonts-client-side/vfs",
+ "language": "de",
+ "translationKey": "fonts/custom-fonts-client-side/vfs",
+ "path": "/docs/0.3/de/fonts/custom-fonts-client-side/vfs/",
+ "title": "Eigene Schriften mit VFS",
+ "description": "Erstelle ein virtuelles Schriftdateisystem außerhalb von node_modules, registriere Schriftvarianten und verwende eine eigene Familie in Browser-PDFs.",
+ "version": "0.3",
+ "sourceDigest": "bea37c79f0184516d0fe4a72f5f5c7b3dfb11fa1b76e3eb1d2b51e41c2128cb2",
+ "source": "fonts/custom-fonts-client-side/vfs/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/vfs/",
+ "uri": "pdfmake://docs/0.3/de/fonts/custom-fonts-client-side/vfs",
+ "markdown": "# Eigene Schriften mit VFS\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/custom-fonts-client-side/vfs/\n\n## Schriftcontainer erstellen\n\nVerwende lizenzierte Schriftdateien, die die benötigten Sprachen abdecken. Lege sie im Verzeichnis `fonts/` deiner Anwendung ab und erzeuge vom Projektstamm aus eine VFS-Datei:\n\n```sh\nnode node_modules/pdfmake/build-vfs.js ./fonts ./vfs_fonts.js\n```\n\nAlle Dateien im angegebenen Verzeichnis werden als Base64-Einträge eingebettet. Lege erzeugte Anwendungsressourcen außerhalb von `node_modules` ab, damit eine Installation deine eigenen Schriften nicht überschreibt. Erzeuge die VFS-Datei neu, sobald sich die Schriftdateien ändern. Für normale [Schriftpfade in Node.js](/docs/0.3/de/fonts/) ist keine Browser-VFS erforderlich.\n\n## Laden und registrieren\n\nLade die Engine vor dem erzeugten VFS-Skript. Wenn `pdfMake` bereits verfügbar ist, registriert das erzeugte Skript seine Dateien. In einem Bundler importierst du das VFS-Objekt und rufst `addVirtualFileSystem` explizit auf:\n\n**JavaScript**\n\n```js\nimport pdfMake from 'pdfmake/build/pdfmake';\nimport customVfs from './vfs_fonts';\n\npdfMake.addVirtualFileSystem(customVfs);\npdfMake.addFonts({\n MyFont: {\n normal: 'MyFont-Regular.ttf',\n bold: 'MyFont-Bold.ttf',\n italics: 'MyFont-Italic.ttf',\n bolditalics: 'MyFont-BoldItalic.ttf'\n }\n});\n\nawait pdfMake.createPdf({\n defaultStyle: { font: 'MyFont' },\n content: ['A document using my font.']\n}).download('document.pdf');\n```\n\n**TypeScript**\n\n```ts\nimport pdfMake from 'pdfmake/build/pdfmake';\nimport customVfs from './vfs_fonts';\n\npdfMake.addVirtualFileSystem(customVfs);\npdfMake.addFonts({\n MyFont: {\n normal: 'MyFont-Regular.ttf',\n bold: 'MyFont-Bold.ttf',\n italics: 'MyFont-Italic.ttf',\n bolditalics: 'MyFont-BoldItalic.ttf'\n }\n});\n\nawait pdfMake.createPdf({\n defaultStyle: { font: 'MyFont' },\n content: ['A document using my font.']\n}).download('document.pdf');\n```\n\nErsetze die Namen durch die exakten Schlüssel in deiner erzeugten VFS-Datei. Schriftfamiliennamen wie `MyFont` verwendest du in Stilen; Dateischlüssel verweisen auf eingebettete Dateien. Definiere jede verwendete Variante. Du kannst mehrere Varianten derselben Datei zuordnen, wenn das beabsichtigt ist; dadurch entsteht aber keine echte fette oder kursive Schrift.\n\n## Schriftsammlungen\n\nFür unterstützte TrueType-Sammlungen kann ein Deskriptor als `[filename, faceName]` angegeben werden:\n\n**JavaScript**\n\n```js\npdfMake.addFonts({\n PingFangSC: {\n normal: ['pingfang.ttc', 'PingFangSC-Regular'],\n bold: ['pingfang.ttc', 'PingFangSC-Semibold']\n }\n});\n```\n\n**TypeScript**\n\n```ts\npdfMake.addFonts({\n PingFangSC: {\n normal: ['pingfang.ttc', 'PingFangSC-Regular'],\n bold: ['pingfang.ttc', 'PingFangSC-Semibold']\n }\n});\n```\n\nBette die Sammlung ein und verwende gültige Namen für die Schriftschnitte. Dieses Beispiel registriert nur normale und fette Schrift; ergänze kursive Varianten, bevor du sie verwendest.\n\n## Häufige Fehler\n\nWenn eine Datei nicht gefunden wird, vergleiche den Dateinamen im Deskriptor mit den Schlüsseln der erzeugten VFS-Datei. Wenn eine Schrift nicht definiert ist, vergleiche `defaultStyle.font` mit der Schriftfamilienzuordnung. Wenn Zeichen fehlen, prüfe die Glyphenabdeckung der Schrift. Wenn das Browser-Bundle zu groß ist, entferne nicht verwendete Familien und Dateien aus dem Eingabeverzeichnis der VFS.\n"
+ },
+ {
+ "id": "de/fonts/icons",
+ "language": "de",
+ "translationKey": "fonts/icons",
+ "path": "/docs/0.3/de/fonts/icons/",
+ "title": "Symbole",
+ "description": "Verwende Icon-Schriften in pdfmake 0.3 mit einer registrierten Schriftfamilie und einem eigenen Stil.",
+ "version": "0.3",
+ "sourceDigest": "389a424f61b90f95836afb77e66802f06435c1b671de3c8b4054b385699698b1",
+ "source": "fonts/icons.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/icons/",
+ "uri": "pdfmake://docs/0.3/de/fonts/icons",
+ "markdown": "# Symbole\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/icons/\n\n- Erstelle eine Schriftdatei bei http://fontello.com/ oder einem ähnlichen Dienst und lade sie herunter.\n\n- Erzeuge aus der Schriftdatei (zum Beispiel `.ttf`) eine `vfs_fonts.js`-Datei (siehe [eigene Schriften verwenden](/docs/0.3/de/fonts/custom-fonts-client-side/vfs/)).\n\n- Registriere die Schrift in JavaScript (es kann ausreichen, nur `normal` zu definieren):\n**JavaScript**\n\n```js\npdfMake.fonts = {\n Fontello: {\n normal: 'fontello.ttf',\n bold: 'fontello.ttf',\n italics: 'fontello.ttf',\n bolditalics: 'fontello.ttf'\n }\n}\n```\n\n**TypeScript**\n\n```ts\npdfMake.fonts = {\n Fontello: {\n normal: 'fontello.ttf',\n bold: 'fontello.ttf',\n italics: 'fontello.ttf',\n bolditalics: 'fontello.ttf'\n }\n}\n```\n\n- Lege einen Stil für Symbole an:\n` icon: {\n font: 'Fontello'\n }`\n- Erstelle einen Textabsatz:\n`\n { text: '', style: 'icon' }, //icon wifi`\n- Verwende als Text das Zeichen aus den Kommentaren in `fontello-codes.css`, nicht den Escape-Wert.\n\n---\n\nWenn du ein Symbol innerhalb eines Textes brauchst, musst du Textobjekte verschachteln:\n\n**JavaScript**\n\n```js\nvar dd = { content: [{\ntext: [\n { text: '', style: 'icon' }, //icon gift\n \" my present\"\n ]\n}] };\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: [{\ntext: [\n { text: '', style: 'icon' }, //icon gift\n \" my present\"\n ]\n}] };\n```\nDies gibt Folgendes aus: „[gift icon] my present“.\n"
+ },
+ {
+ "id": "de/fonts/standard-14-fonts",
+ "language": "de",
+ "translationKey": "fonts/standard-14-fonts",
+ "path": "/docs/0.3/de/fonts/standard-14-fonts/",
+ "title": "Die 14 Standardschriften",
+ "description": "Verwende Standardschriftfamilien von PDF in Node.js und Browser-Bundles; beachte die begrenzte Zeichenkodierung.",
+ "version": "0.3",
+ "sourceDigest": "201689392ed36c1d4a7a653265576461a8802566860caae2b86967ad9d9e0367",
+ "source": "fonts/standard-14-fonts.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/fonts/standard-14-fonts/",
+ "uri": "pdfmake://docs/0.3/de/fonts/standard-14-fonts",
+ "markdown": "# Die 14 Standardschriften\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/fonts/standard-14-fonts/\n\nPDF enthält [14 Standardschriften](http://www.enfocus.com/manuals/ReferenceGuide/PS/18/enUS/en-us/common/pse/concept/c_aa1044513.html).\n\n**Zeichenabdeckung:** Standardschriften verwenden begrenzte Kodierungen und unterstützen nicht beliebige Unicode-Zeichen. Verwende für mehrsprachige Dokumente eingebettete Schriften und prüfe die benötigten Glyphen.\n\n## Verwendung von pdfmake auf dem Server\n\n**Anwendungsbeispiel:**\n**JavaScript**\n\n```js\nvar fonts = {\n Courier: {\n normal: 'Courier',\n bold: 'Courier-Bold',\n italics: 'Courier-Oblique',\n bolditalics: 'Courier-BoldOblique'\n },\n Helvetica: {\n normal: 'Helvetica',\n bold: 'Helvetica-Bold',\n italics: 'Helvetica-Oblique',\n bolditalics: 'Helvetica-BoldOblique'\n },\n Times: {\n normal: 'Times-Roman',\n bold: 'Times-Bold',\n italics: 'Times-Italic',\n bolditalics: 'Times-BoldItalic'\n },\n Symbol: {\n normal: 'Symbol'\n },\n ZapfDingbats: {\n normal: 'ZapfDingbats'\n }\n};\n\nvar pdfmake = require('pdfmake');\npdfmake.addFonts(fonts);\n\nvar docDefinition = {\n content: ['First paragraph', 'Another paragraph'],\n defaultStyle: {\n font: 'Helvetica'\n }\n};\n\nvar pdf = pdfmake.createPdf(docDefinition);\npdf.write('test.pdf').then(() => {\n // success event\n}, err => {\n console.error(err);\n});\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar fonts = {\n Courier: {\n normal: 'Courier',\n bold: 'Courier-Bold',\n italics: 'Courier-Oblique',\n bolditalics: 'Courier-BoldOblique'\n },\n Helvetica: {\n normal: 'Helvetica',\n bold: 'Helvetica-Bold',\n italics: 'Helvetica-Oblique',\n bolditalics: 'Helvetica-BoldOblique'\n },\n Times: {\n normal: 'Times-Roman',\n bold: 'Times-Bold',\n italics: 'Times-Italic',\n bolditalics: 'Times-BoldItalic'\n },\n Symbol: {\n normal: 'Symbol'\n },\n ZapfDingbats: {\n normal: 'ZapfDingbats'\n }\n};\n\nvar pdfmake = require('pdfmake');\npdfmake.addFonts(fonts);\n\nvar docDefinition: TDocumentDefinitions = {\n content: ['First paragraph', 'Another paragraph'],\n defaultStyle: {\n font: 'Helvetica'\n }\n};\n\nvar pdf = pdfmake.createPdf(docDefinition);\npdf.write('test.pdf').then(() => {\n // success event\n}, err => {\n console.error(err);\n});\n```\n\n## Verwendung von pdfmake im Browser\n\nBundles mit Standardschriften sind im Verzeichnis `build/standard-fonts/` des pdfmake-Pakets verfügbar. Binde das Bundle jeder benötigten Schriftfamilie **nach** `pdfmake.min.js` ein. Jedes Bundle registriert seine Schriften automatisch bei `pdfMake`.\n\nBeispiel für Helvetica:\n\n```html\n\n\n\n```\n\nVerfügbare Bundles: `Courier.js`, `Helvetica.js`, `Times.js`, `Symbol.js` und `ZapfDingbats.js`. Setze `defaultStyle.font` auf eine registrierte Schriftfamilie, wie oben gezeigt.\n"
+ },
+ {
+ "id": "de/getting-started",
+ "language": "de",
+ "translationKey": "getting-started",
+ "path": "/docs/0.3/de/getting-started/",
+ "title": "Einrichtung",
+ "description": "Installiere pdfmake 0.3 für Node.js oder den Browser und wähle die passende Promise-basierte Ausgabe.",
+ "version": "0.3",
+ "sourceDigest": "99fb4e43045381e3fb65fdf81576ac12ed30e6cf3ca5e79f4130207b775a67d0",
+ "source": "getting-started/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/",
+ "uri": "pdfmake://docs/0.3/de/getting-started",
+ "markdown": "# Einrichtung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/\n\n## Die Laufzeit entscheidet\n\n- [Node.js](/docs/0.3/de/getting-started/server-side/): PDF-Dateien schreiben oder Bytes an eine API-Antwort übergeben.\n- [Browser](/docs/0.3/de/getting-started/client-side/): Vorschau öffnen oder eine PDF herunterladen.\n\nBeide Laufzeiten verwenden dieselbe [Dokumentdefinition](/docs/0.3/de/document-definition-object/), benötigen aber unterschiedliche Imports und Schriftregistrierung. Vermische die Einrichtung nicht mit älteren `PdfPrinter`-Beispielen. Die Ausgabe in 0.3 ist Promise-basiert: Fehler mit `await` und `try/catch` behandeln.\n\n[Die erste PDF](/docs/0.3/de/learn/first-pdf/) zeigt den gesamten Ablauf.\n\n## Vor dem Start\n\nVerwende die Dokumentation passend zur installierten Version (`npm ls pdfmake`). Beginne mit einem minimalen Beispiel, bevor du eigene Schriften, entfernte Bilder oder Tabellenlayouts hinzufügst. Wenn du eine Anwendung mit Version 0.1/0.2 betreibst, folge der [Migrationsanleitung](/docs/0.3/de/migration-from-0.1/).\n\n## JavaScript und TypeScript\n\nDieser Entwicklungszweig liefert eigene TypeScript-Deklarationen mit der Library aus und trennt Node- und Browser-APIs. Installiere für den lokal gepackten Zweig TypeScript ohne `@types/pdfmake`. Das veröffentlichte npm-Paket 0.3.13 benötigt weiterhin passende Community-Typen; die hier beschriebenen nativen Deklarationen und die Vorabvalidierung sind noch unveröffentlicht. Geprüft wird mit TypeScript 5.9.3.\n\n```sh\nnpm install pdfmake@0.3.13\nnpm install --save-dev typescript@~5.9.3\n```\n\nNode.js: Speichere dies als `document.mts`. Mit `NodeNext` bildet der Compiler die tatsächlichen Node-Imports ab. Eine CommonJS-Datei mit `.cts` kann stattdessen mit `import pdfmake = require(\"pdfmake\")` beginnen. Verlasse dich nicht auf benannte Laufzeit-Imports.\n\n```json\n{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"NodeNext\",\n \"moduleResolution\": \"NodeNext\",\n \"strict\": true,\n \"esModuleInterop\": true\n }\n}\n```\n\n**JavaScript**\n\n```js\nimport pdfmake from 'pdfmake';\nimport { strict as assert } from 'node:assert';\npdfmake.addFonts({ Helvetica: { normal: 'Helvetica', bold: 'Helvetica-Bold', italics: 'Helvetica-Oblique', bolditalics: 'Helvetica-BoldOblique' } });\npdfmake.setUrlAccessPolicy(() => false);\npdfmake.setLocalAccessPolicy(name => name.startsWith('Helvetica'));\nconst definition = { content: [{ table: { body: [['ESM', 'TypeScript'], ['Promise', 'Output']] } }], defaultStyle: { font: 'Helvetica' } };\nconst buffer = await pdfmake.createPdf(definition).getBuffer();\nassert.equal(buffer.subarray(0, 5).toString(), '%PDF-');\n```\n\n**TypeScript**\n\n```ts\nimport pdfmake from 'pdfmake';\nimport type { TDocumentDefinitions } from 'pdfmake/interfaces.js';\nimport { strict as assert } from 'node:assert';\n\npdfmake.addFonts({ Helvetica: { normal: 'Helvetica', bold: 'Helvetica-Bold', italics: 'Helvetica-Oblique', bolditalics: 'Helvetica-BoldOblique' } });\npdfmake.setUrlAccessPolicy(() => false);\npdfmake.setLocalAccessPolicy(name => name.startsWith('Helvetica'));\nconst definition: TDocumentDefinitions = { content: [{ table: { body: [['ESM', 'TypeScript'], ['Promise', 'Output']] } }], defaultStyle: { font: 'Helvetica' } };\nconst buffer: Buffer = await pdfmake.createPdf(definition).getBuffer();\nassert.equal(buffer.subarray(0, 5).toString(), '%PDF-');\n```\n\nBrowser-Bundler: Importiere den fertigen Browser-Einstieg und registriere das VFS direkt. Verwende `module: \"ESNext\"` und `moduleResolution: \"Bundler\"` im Bundler-Projekt; diese Optionen benötigen einen Bundler und sind nicht zum direkten Ausführen der Ausgabe in Node gedacht.\n\n**JavaScript**\n\n```js\nimport pdfmake from 'pdfmake/build/pdfmake.js';\nimport vfs from 'pdfmake/build/vfs_fonts.js';\npdfmake.addVirtualFileSystem(vfs);\nconst definition = { content: [{ text: 'TypeScript browser bundler', bold: true }] };\nexport async function render() {\n return pdfmake.createPdf(definition).getBlob();\n}\n```\n\n**TypeScript**\n\n```ts\nimport pdfmake from 'pdfmake/build/pdfmake.js';\nimport vfs from 'pdfmake/build/vfs_fonts.js';\nimport type { TDocumentDefinitions } from 'pdfmake/interfaces';\n\npdfmake.addVirtualFileSystem(vfs);\nconst definition = { content: [{ text: 'TypeScript browser bundler', bold: true }] } satisfies TDocumentDefinitions;\nexport async function render(): Promise {\n return pdfmake.createPdf(definition).getBlob();\n}\n```\n\nTypen bieten Vervollständigung und Prüfungen beim Kompilieren. Sie validieren kein externes JSON und garantieren kein erfolgreiches Layout. Die eigenen Deklarationen unterscheiden Node-`write` von Browser-`getBlob`, `download`, `open` und `print`. Verwende für Bundler explizite Browser-Imports. Playground und eingebettete Beispiele prüfen TypeScript lokal vor dem Rendern. Siehe [Dokumentvalidierung](/docs/0.3/de/guides/errors/) für Laufzeitprüfungen.\n"
+ },
+ {
+ "id": "de/getting-started/client-side",
+ "language": "de",
+ "translationKey": "getting-started/client-side",
+ "path": "/docs/0.3/de/getting-started/client-side/",
+ "title": "Browser-Schnellstart",
+ "description": "Lade pdfmake 0.3 und das Schrift-Bundle und lade dann ein PDF als Reaktion auf eine Benutzeraktion herunter.",
+ "version": "0.3",
+ "sourceDigest": "7427dae21c26c2f61d3836ce87ed99ce36fd9d5558ac2b6d0e6b7a7570fd7a83",
+ "source": "getting-started/client-side/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/client-side",
+ "markdown": "# Browser-Schnellstart\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/\n\n## Browserressourcen installieren und kopieren\n\n```sh\nnpm install pdfmake@0.3.13\n```\n\nKopiere `node_modules/pdfmake/build/pdfmake.min.js` und `node_modules/pdfmake/build/vfs_fonts.js` neben diese HTML-Datei. Stelle das Verzeichnis über deinen lokalen Entwicklungsserver bereit.\n\n## PDF erzeugen\n\n```html\n\n\nMy first PDF \n\n Download PDF \n
\n \n \n \n\n\n```\n\nLade die Engine **vor** ihrem Schrift-Bundle. `vfs_fonts.js` stellt die standardmäßigen Roboto-Schriftdateien bereit. Für dieses Beispiel benötigst du keine serverseitige Rendering-API. Wenn das Promise von `download()` erfüllt wird, wurde der Download gestartet; es bestätigt nicht, dass der Benutzer die Datei gespeichert hat.\n\n## Einen Bundler verwenden\n\n**JavaScript**\n\n```js\nimport pdfMake from 'pdfmake/build/pdfmake';\nimport pdfFonts from 'pdfmake/build/vfs_fonts';\n\npdfMake.addVirtualFileSystem(pdfFonts);\nawait pdfMake.createPdf({ content: ['Bundled application'] }).download('document.pdf');\n```\n\n**TypeScript**\n\n```ts\nimport pdfMake from 'pdfmake/build/pdfmake';\nimport pdfFonts from 'pdfmake/build/vfs_fonts';\n\npdfMake.addVirtualFileSystem(pdfFonts);\nawait pdfMake.createPdf({ content: ['Bundled application'] }).download('document.pdf');\n```\n\nDieser Code wird innerhalb des Moduls oder eines asynchronen Event-Handlers deiner Anwendung ausgeführt. Wenn du ein SSR-Framework nutzt, darf der Import nicht in serverseitig ausgeführten Code geraten. Verwende in TypeScript Typdefinitionen, die zu deiner installierten pdfmake-Version passen; Typen machen eine ältere Laufzeit nicht mit der 0.3-API kompatibel.\n\n## Öffnen und drucken\n\nRufe `open()` oder `print()` während einer Benutzeraktion auf, um Popup-Blocker zu vermeiden. Wenn du zuerst Daten abrufst, öffne synchron ein Fenster und übergib es anschließend an die Ausgabemethode. Siehe [Browsermethoden](/docs/0.3/de/getting-started/client-side/methods/).\n\n## Nächste Schritte\n\n[Eigene Schriften](/docs/0.3/de/fonts/custom-fonts-client-side/) · [Browsermethoden](/docs/0.3/de/getting-started/client-side/methods/) · [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/)\n"
+ },
+ {
+ "id": "de/getting-started/client-side/examples",
+ "language": "de",
+ "translationKey": "getting-started/client-side/examples",
+ "path": "/docs/0.3/de/getting-started/client-side/examples/",
+ "title": "Beispiele",
+ "description": "Sieh dir Beispiele für die Verwendung von pdfmake 0.3 an.",
+ "version": "0.3",
+ "sourceDigest": "564c62eedf95371a7703dae15a84350aa49933c3eb606a9e4ed6cdb4541f38d7",
+ "source": "getting-started/client-side/examples.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/examples/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/client-side/examples",
+ "markdown": "# Beispiele\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/examples/\n\nSieh dir den [Playground](/docs/0.3/de/playground/) und die [Beispiele](https://github.com/bpampuch/pdfmake/tree/master/examples) an.\n"
+ },
+ {
+ "id": "de/getting-started/client-side/methods",
+ "language": "de",
+ "translationKey": "getting-started/client-side/methods",
+ "path": "/docs/0.3/de/getting-started/client-side/methods/",
+ "title": "Ausgabemethoden im Browser",
+ "description": "Lade PDFs herunter, öffne, drucke oder erhalte PDF-Bytes und Blobs mit Promise-basierten Browsermethoden in pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "9223df7c21e72e445796980b101e0e55c3724007a9f7b3f7e0888260b13476f1",
+ "source": "getting-started/client-side/methods.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/methods/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/client-side/methods",
+ "markdown": "# Ausgabemethoden im Browser\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/methods/\n\n## Dokument erstellen\n\nNachdem du [Engine und Schriften geladen hast](/docs/0.3/de/getting-started/client-side/):\n\n**JavaScript**\n\n```js\nconst output = pdfMake.createPdf(docDefinition, options);\n```\n\n**TypeScript**\n\n```ts\nconst output = pdfMake.createPdf(docDefinition, options);\n```\n\nDas optionale zweite Argument enthält [Rendering-Optionen](/docs/0.3/de/options/). `createPdf` gibt sofort einen Ausgabe-Wrapper zurück. Ausgabemethoden liefern Promises; behandle deren Ablehnungen.\n\n## Ausgabe auswählen\n\n| Methode | Ergebnis | Verhalten |\n| --- | --- | --- |\n| `download(filename?)` | `undefined` | Startet einen Download; Standarddateiname ist `file.pdf` |\n| `open(window?)` | `undefined` | Öffnet das erzeugte PDF in einem neuen oder angegebenen Fenster |\n| `print(window?)` | `undefined` | Öffnet ein PDF mit Druckaktion; das Verhalten hängt vom Viewer ab |\n| `getBlob()` | `Blob` | Binärdaten mit MIME-Typ `application/pdf` |\n| `getBuffer()` | Buffer-kompatible Bytes | Rohe PDF-Bytes |\n| `getBase64()` | `string` | Base64-kodiertes PDF |\n| `getDataUrl()` | `string` | Base64-Data-URL |\n| `getStream()` | PDFKit-Stream | Ausgabe auf niedriger Ebene; verwende normalerweise Blob oder Bytes |\n\n**JavaScript**\n\n```js\ntry {\n await pdfMake.createPdf(docDefinition).download('report.pdf');\n} catch (error) {\n console.error('PDF generation failed', error);\n}\n```\n\n**TypeScript**\n\n```ts\ntry {\n await pdfMake.createPdf(docDefinition).download('report.pdf');\n} catch (error) {\n console.error('PDF generation failed', error);\n}\n```\n\nEin erfülltes Download-Promise bestätigt nicht, dass der Benutzer die Datei gespeichert hat. Drucken hängt vom Browser und PDF-Viewer ab; verlasse dich nicht auf stilles Drucken.\n\n## Nach asynchroner Arbeit öffnen\n\nÖffne das Fenster direkt im Click-Handler des Benutzers, bevor du auf Daten wartest. Andernfalls können Popup-Blocker das Öffnen verhindern.\n\n**JavaScript**\n\n```js\nasync function openReport() {\n const win = window.open('', '_blank');\n if (!win) throw new Error('Allow popups to open the PDF');\n try {\n const response = await fetch('/report-data');\n if (!response.ok) throw new Error('Could not load report data');\n const data = await response.json();\n const definition = { content: [String(data.title)] };\n await pdfMake.createPdf(definition).open(win);\n } catch (error) {\n win.close();\n throw error;\n }\n}\n```\n\n**TypeScript**\n\n```ts\nasync function openReport() {\n const win = window.open('', '_blank');\n if (!win) throw new Error('Allow popups to open the PDF');\n try {\n const response = await fetch('/report-data');\n if (!response.ok) throw new Error('Could not load report data');\n const data = await response.json();\n const definition = { content: [String(data.title)] };\n await pdfMake.createPdf(definition).open(win);\n } catch (error) {\n win.close();\n throw error;\n }\n}\n```\n\nRufe `openReport` im Click-Handler deiner Anwendung auf und behandle das abgelehnte Promise. Ersetze zum Drucken `.open(win)` durch `.print(win)`. Mit `window` navigierst du im aktuellen Tab. Lege den PDF-Titel über die [Dokumentmetadaten](/docs/0.3/de/document-definition-object/document-medatadata/) fest; Dateinamen und Titel im Viewer hängen vom Browser ab.\n\n## Blob-URLs verwalten\n\n**JavaScript**\n\n```js\nconst blob = await pdfMake.createPdf(docDefinition).getBlob();\nconst url = URL.createObjectURL(blob);\ndocument.querySelector('#preview').src = url;\n// Revoke url when replacing the preview or removing it, after it is no longer needed.\n```\n\n**TypeScript**\n\n```ts\nconst blob = await pdfMake.createPdf(docDefinition).getBlob();\nconst url = URL.createObjectURL(blob);\ndocument.querySelector('#preview').src = url;\n// Revoke url when replacing the preview or removing it, after it is no longer needed.\n```\n\nLass die URL bestehen, solange der Viewer sie verwendet. Rufe beim Aufräumen `URL.revokeObjectURL(url)` auf. Verwende für jeden Renderdurchlauf einen neuen Ausgabe-Wrapper. Kombiniere die manuelle Verarbeitung eines Streams nicht mit Buffer- oder Blob-Hilfsmethoden auf demselben Ausgabe-Wrapper.\n\n## URL-Zugriffsrichtlinie\n\nSeit **0.3.6** akzeptiert `setUrlAccessPolicy(callback)` einen synchronen booleschen Callback. Diese Funktion ist keine vollständige Netzwerksandbox; Weiterleitungen im Browser können stattfinden, bevor die endgültige URL geprüft wird. Siehe [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/).\n"
+ },
+ {
+ "id": "de/getting-started/client-side/supported-browsers",
+ "language": "de",
+ "translationKey": "getting-started/client-side/supported-browsers",
+ "path": "/docs/0.3/de/getting-started/client-side/supported-browsers/",
+ "title": "Unterstützte Browser",
+ "description": "Prüfe die Browserkompatibilität sowie Einschränkungen der Hilfsfunktionen zum Öffnen, Drucken und Herunterladen.",
+ "version": "0.3",
+ "sourceDigest": "3ea8d830019ccfb8321db6f8c7fe9d40ba017ac0b435e042cefefa32be20db66",
+ "source": "getting-started/client-side/supported-browsers.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/supported-browsers/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/client-side/supported-browsers",
+ "markdown": "# Unterstützte Browser\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/client-side/supported-browsers/\n\n* Edge\n* Firefox\n* Chrome\n* Chrome (Android)\n* Opera\n* Safari (iOS)\n* Safari (iOS) iPhone\n\n\n> **Note:** Die Methoden **`open()`** und **`print()`** werden nur in folgenden Browsern unterstützt:\n\n* Firefox\n* Chrome\n* Opera\n\n\n\n> **Note:** Browser-Erweiterungen können die Funktion von pdfmake beeinflussen (insbesondere `open()` und `print()`). Wenn pdfmake nicht funktioniert, deaktiviere testweise die Erweiterungen.\n\n\n\n> **Note:** AdBlock\n\n\nDie vollständige Beschreibung findest du im [Issue](https://github.com/bpampuch/pdfmake/issues/800).\n"
+ },
+ {
+ "id": "de/getting-started/examples-from-comunity",
+ "language": "de",
+ "translationKey": "getting-started/examples-from-comunity",
+ "path": "/docs/0.3/de/getting-started/examples-from-comunity/",
+ "title": "Beispiele aus der Community",
+ "description": "Entdecke Beispiele aus der Community für pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "e2c8721f10e846c4674b764d9275542cc75f8c76e79e0ec6f97f2fae8194e6e5",
+ "source": "getting-started/examples-from-comunity/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/examples-from-comunity/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/examples-from-comunity",
+ "markdown": "# Beispiele aus der Community\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/examples-from-comunity/\n\n- [Vue.js-Beispiel](https://github.com/bpampuch/pdfmake/issues/2498)\n- [React-Native-Beispiel](https://github.com/ieschalier/rn-pdfmake)\n"
+ },
+ {
+ "id": "de/getting-started/server-side",
+ "language": "de",
+ "translationKey": "getting-started/server-side",
+ "path": "/docs/0.3/de/getting-started/server-side/",
+ "title": "Node.js-Schnellstart",
+ "description": "Erzeuge mit Node.js, pdfmake 0.3, Standardschriften und Promise-basierter Ausgabe eine vollständige PDF-Datei.",
+ "version": "0.3",
+ "sourceDigest": "a943d71f035716932810834880e3bf5c02cde041ecc0cf438373b27e0c62157d",
+ "source": "getting-started/server-side/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/server-side",
+ "markdown": "# Node.js-Schnellstart\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/\n\n## Installieren\n\nVerwende **Node.js 20 oder neuer**. Erstelle eine Anwendung und installiere pdfmake:\n\n```sh\nnpm init -y\nnpm install pdfmake@0.3.13\n```\n\nDie genaue Version macht das Beispiel reproduzierbar. Prüfe die Versionshinweise und teste, bevor du ein neueres Patch-Release auswählst.\n\n## Erste PDF-Datei schreiben\n\nSpeichere das vollständige Beispiel als `first-pdf.cjs` und führe `node first-pdf.cjs` aus.\n\n**JavaScript**\n\n```js\n// docs-test: node-quickstart\nconst pdfmake = require('pdfmake');\n\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const definition = {\n defaultStyle: { font: 'Helvetica' },\n content: [\n { text: 'Hello, pdfmake!', fontSize: 24, bold: true },\n 'Your first PDF, generated in Node.js.'\n ]\n };\n await pdfmake.createPdf(definition).write('document.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n// docs-test: node-quickstart\nimport pdfmake from \"pdfmake\";\n\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const definition: TDocumentDefinitions = {\n defaultStyle: { font: 'Helvetica' },\n content: [\n { text: 'Hello, pdfmake!', fontSize: 24, bold: true },\n 'Your first PDF, generated in Node.js.'\n ]\n };\n await pdfmake.createPdf(definition).write('document.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n`write()` wird erfüllt, wenn die Ausgabedatei geschlossen ist. Behandle abgelehnte Promises, damit eine fehlgeschlagene Generierung nicht unbemerkt zu einer erfolgreichen API-Antwort führt.\n\nHelvetica benötigt keine lokalen Schriftdateien. Daher sperrt das Beispiel externe URLs und erlaubt über die lokale Richtlinie nur Standard-Schriftkennungen. Die aktuelle Implementierung prüft diese Kennungen, obwohl sie keine Dateipfade sind. Standardschriften haben eine begrenzte Zeichenabdeckung. Für mehrsprachige Dokumente [registriere geeignete Schriftdateien](/docs/0.3/de/fonts/) und erlaube ihre aufgelösten Pfade ausdrücklich.\n\n## PDF-Bytes über eine API zurückgeben\n\n**JavaScript**\n\n```js\nconst buffer = await pdfmake.createPdf({\n defaultStyle: { font: 'Helvetica' },\n content: ['API document']\n}).getBuffer();\n\n// Adapt these lines to your HTTP framework:\nresponse.setHeader('Content-Type', 'application/pdf');\nresponse.setHeader('Content-Disposition', 'attachment; filename=\"document.pdf\"');\nresponse.end(buffer);\n```\n\n**TypeScript**\n\n```ts\nconst buffer = await pdfmake.createPdf({\n defaultStyle: { font: 'Helvetica' },\n content: ['API document']\n}).getBuffer();\n\n// Adapt these lines to your HTTP framework:\nresponse.setHeader('Content-Type', 'application/pdf');\nresponse.setHeader('Content-Disposition', 'attachment; filename=\"document.pdf\"');\nresponse.end(buffer);\n```\n\nDieses Snippet setzt voraus, dass `pdfmake` wie oben konfiguriert und `response` das Response-Objekt deines Frameworks ist. Prüfe Anfragedaten, bevor du eine Definition erstellst. Erzeuge für jede Anfrage eine neue Definition; das Layout verändert sie.\n\n## ESM-Anwendungen\n\nDas Node.js-Paket exportiert ein konfiguriertes Singleton. Verwende in einer ESM-Anwendung `import pdfmake from 'pdfmake'`; erstelle keine Instanz mit `new PdfPrinter(...)` wie in älteren Beispielen. Registriere Schriften und Richtlinien einmal beim Anwendungsstart. Ändere die Singleton-Konfiguration nicht für parallele Anfragen.\n\n## Nächste Schritte\n\n[Ausgabemethoden](/docs/0.3/de/getting-started/server-side/methods/) · [Ressourcenzugriff](/docs/0.3/de/guides/resource-security/) · [Rezept: Rechnung](/docs/0.3/de/guides/invoice/)\n"
+ },
+ {
+ "id": "de/getting-started/server-side/examples",
+ "language": "de",
+ "translationKey": "getting-started/server-side/examples",
+ "path": "/docs/0.3/de/getting-started/server-side/examples/",
+ "title": "Beispiele",
+ "description": "Sieh dir Beispiele für die Verwendung von pdfmake 0.3 an.",
+ "version": "0.3",
+ "sourceDigest": "948d95fa838012c81b3343e5bcfafa089a1340bd04b510cdff7f3b4e5a44a8bb",
+ "source": "getting-started/server-side/examples.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/examples/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/server-side/examples",
+ "markdown": "# Beispiele\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/examples/\n\nSiehe die [Beispiele](https://github.com/bpampuch/pdfmake/tree/master/examples) und das [Skript des Dev-Playground-Servers](https://github.com/bpampuch/pdfmake/blob/master/dev-playground/server.js).\n"
+ },
+ {
+ "id": "de/getting-started/server-side/methods",
+ "language": "de",
+ "translationKey": "getting-started/server-side/methods",
+ "path": "/docs/0.3/de/getting-started/server-side/methods/",
+ "title": "Ausgabemethoden in Node.js",
+ "description": "Referenz für createPdf, Buffer, Base64, Datei- und Streamausgabe sowie Ressourcenrichtlinien in pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "f0daec88513f195e653aeface6a0c5a92da517ba092a13919c74940aa3169a09",
+ "source": "getting-started/server-side/methods.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/methods/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/server-side/methods",
+ "markdown": "# Ausgabemethoden in Node.js\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/methods/\n\n## Dokument erstellen\n\n**JavaScript**\n\n```js\nconst output = pdfmake.createPdf(docDefinition, options);\n```\n\n**TypeScript**\n\n```ts\nconst output = pdfmake.createPdf(docDefinition, options);\n```\n\n`docDefinition` ist eine [Dokumentdefinition](/docs/0.3/de/document-definition-object/). `options` ist ein optionales [Optionsobjekt](/docs/0.3/de/options/). `createPdf` gibt sofort einen Ausgabe-Wrapper zurück; Fehler bei der Generierung lehnen das Promise der Ausgabemethode ab. Ungültige Argumenttypen können synchron einen Fehler auslösen.\n\n## Ausgabemethoden\n\n| Methode | Ergebnis | Verwendung |\n| --- | --- | --- |\n| `write(filename)` | `undefined` | Datei schreiben und auf das Schließen warten |\n| `getBuffer()` | `Buffer` | PDF-Bytes für eine API zurückgeben |\n| `getBase64()` | `string` | Bytes als Base64 kodieren |\n| `getDataUrl()` | `string` | Base64 das Präfix `data:application/pdf;base64,` voranstellen |\n| `getStream()` | PDFKit-Dokumentstream | Stream direkt verwalten |\n\n**JavaScript**\n\n```js\ntry {\n const output = pdfmake.createPdf(docDefinition);\n const bytes = await output.getBuffer();\n // Send or store bytes here.\n} catch (error) {\n // Report generation failure to your caller.\n}\n```\n\n**TypeScript**\n\n```ts\ntry {\n const output = pdfmake.createPdf(docDefinition);\n const bytes = await output.getBuffer();\n // Send or store bytes here.\n} catch (error) {\n // Report generation failure to your caller.\n}\n```\n\n`getBuffer()` speichert sein Promise zwischen; `getBase64()` und `getDataUrl()` verwenden dieselben Bytes wieder. Erzeuge für einen unabhängigen Renderdurchlauf einen neuen Ausgabe-Wrapper. Kombiniere die manuelle Streamverarbeitung nicht mit Buffer- oder Dateihilfsmethoden auf demselben Wrapper.\n\n## Stream verarbeiten\n\n**JavaScript**\n\n```js\nconst stream = await pdfmake.createPdf(docDefinition).getStream();\nstream.on('error', error => { /* Handle generation errors. */ });\ndestination.on('error', error => { /* Handle destination errors. */ });\nstream.pipe(destination);\nstream.end();\n```\n\n**TypeScript**\n\n```ts\nconst stream = await pdfmake.createPdf(docDefinition).getStream();\nstream.on('error', error => { /* Handle generation errors. */ });\ndestination.on('error', error => { /* Handle destination errors. */ });\nstream.pipe(destination);\nstream.end();\n```\n\n`destination` muss ein von deiner Anwendung verwalteter beschreibbarer Stream sein. Registriere Ereignis-Listener, bevor du `end()` aufrufst. Für eine einfache Datei ist `write()` vorzuziehen. Streaming macht das Dokumentlayout nicht inkrementell: pdfmake legt das Dokumentlayout fertig, bevor der Stream zurückgegeben wird.\n\n## URL-Zugriffsrichtlinie\n\nVerfügbar seit **0.3.6**. Konfiguriere sie vor dem Erstellen von Dokumenten:\n\n**JavaScript**\n\n```js\npdfmake.setUrlAccessPolicy(url => {\n const parsed = new URL(url);\n return parsed.protocol === 'https:' && parsed.hostname === 'assets.example.com';\n});\n```\n\n**TypeScript**\n\n```ts\npdfmake.setUrlAccessPolicy(url => {\n const parsed = new URL(url);\n return parsed.protocol === 'https:' && parsed.hostname === 'assets.example.com';\n});\n```\n\nDer Callback muss synchron den booleschen Wert `true` zurückgeben, damit eine URL erlaubt wird. Eine `async`-Funktion gibt ein Promise zurück und wird in der aktuellen Implementierung abgelehnt. Eine Zulassungsliste ist nur eine Schutzmaßnahme gegen SSRF; setze Netzwerkregeln ein oder verwende geprüfte Bytes, wenn du nicht vertrauenswürdige Eingaben verarbeitest. Siehe [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/).\n\n## Zugriff auf lokale Dateien\n\nVerfügbar seit **0.3.8**. Wenn alle Ressourcen eingebettet sind, kannst du lokale Dateien sperren:\n\n**JavaScript**\n\n```js\npdfmake.setLocalAccessPolicy(() => false);\n```\n\n**TypeScript**\n\n```ts\npdfmake.setLocalAccessPolicy(() => false);\n```\n\nErlaube für lokale Schriften oder Bilder exakt aufgelöste Pfade statt eines Zeichenfolgenpräfixes. Siehe die [vollständige Einrichtung lokaler Schriften](/docs/0.3/de/fonts/). `undefined` löscht eine konfigurierte Richtlinie; eine nicht gesetzte Richtlinie sperrt nicht automatisch alle Zugriffe.\n"
+ },
+ {
+ "id": "de/getting-started/server-side/supported-nodejs-versions",
+ "language": "de",
+ "translationKey": "getting-started/server-side/supported-nodejs-versions",
+ "path": "/docs/0.3/de/getting-started/server-side/supported-nodejs-versions/",
+ "title": "Unterstützte Node.js-Versionen",
+ "description": "Prüfe die Laufzeitanforderung des Pakets und die CI-Laufzeitmatrix für pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "16cebaa83ef298cf564edac58e4bb046a96e29d8d0b06c7d858ef19db881d2b7",
+ "source": "getting-started/server-side/supported-nodejs-versions.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/supported-nodejs-versions/",
+ "uri": "pdfmake://docs/0.3/de/getting-started/server-side/supported-nodejs-versions",
+ "markdown": "# Unterstützte Node.js-Versionen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/getting-started/server-side/supported-nodejs-versions/\n\n## Laufzeitanforderung\n\nDas Paket 0.3.13 gibt in `package.json` **Node.js >=20** als Mindestversion an. Die vorgeschlagene CI-Matrix umfasst Node.js 20, 22 und 24 unter Linux, Windows und macOS. Diese Kompatibilitätstests sind unabhängig vom Sicherheits-Support der Node.js-Versionen.\n\nVerwende in der Produktion eine Node.js-Version, die noch gewartet wird. Sieh im [offiziellen Veröffentlichungsplan von Node.js](https://github.com/nodejs/Release#release-schedule) nach, bevor du eine Laufzeit auswählst. Teste deine Schriften, Ressourcen und Dokumentlast mit genau der Version, die du bereitstellst.\n"
+ },
+ {
+ "id": "de/guides",
+ "language": "de",
+ "translationKey": "guides",
+ "path": "/docs/0.3/de/guides/",
+ "title": "Anleitungen und Rezepte",
+ "description": "Praktische Rezepte für pdfmake 0.3 zu APIs, Rechnungen, Sicherheit, Leistung, Migration und KI-gestützter Entwicklung.",
+ "version": "0.3",
+ "sourceDigest": "cb74b315d38242522e55688bb21f3467ea69795d4ed5f0279aa709979a5549cf",
+ "source": "guides/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/",
+ "uri": "pdfmake://docs/0.3/de/guides",
+ "markdown": "# Anleitungen und Rezepte\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/\n\n## Dokumente erstellen und betreiben\n\n- [Playground-Anleitung](/docs/0.3/de/guides/playground/): Beispiele bearbeiten, Seiten prüfen und Quelldateien lokal behalten.\n- [Rezept: Rechnung](/docs/0.3/de/guides/invoice/): ein vollständiges ausführbares Dokument mit Tabelle, Summen und Seitenzahlen.\n- [API-Übersicht](/docs/0.3/de/guides/api-reference/): wo Konfiguration, Definitionen und Ausgabemethoden hingehören.\n- [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/): URLs, Dateien und nicht vertrauenswürdige Eingaben sicher verarbeiten.\n- [Leistung](/docs/0.3/de/guides/performance/): Layout, Ausgabe, Speicher und Parallelität getrennt messen.\n- [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/): Probleme mit Schriften, Imports, Tabellen und Ausgaben diagnostizieren.\n- [LLM- und MCP-Integration](/docs/0.3/de/guides/llm-and-mcp/): versionierte Dokumentation online und offline mit KI-Werkzeugen verwenden.\n- [Mitwirken](/docs/0.3/de/guides/contributing/): Quellcode finden und Regressionen testen.\n"
+ },
+ {
+ "id": "de/guides/api-reference",
+ "language": "de",
+ "translationKey": "guides/api-reference",
+ "path": "/docs/0.3/de/guides/api-reference/",
+ "title": "API-Übersicht",
+ "description": "Finde Konfigurationsmethoden, Rendering-Optionen und Ausgabemethoden der Node.js- und Browser-APIs von pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "f1491a6775394bd4e30fc8da29d4972607400a030e766c3e7acd329137b35166",
+ "source": "guides/api-reference.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/api-reference/",
+ "uri": "pdfmake://docs/0.3/de/guides/api-reference",
+ "markdown": "# API-Übersicht\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/api-reference/\n\n## Einmal konfigurieren, oft rendern\n\nBeide Einstiegspunkte stellen ein Singleton bereit. Konfiguriere Schriften, Richtlinien und Layouts beim Start der Anwendung. Ändere keine gemeinsam genutzte Konfiguration, während parallele Anfragen rendern.\n\n| Methode | Laufzeit | Verhalten |\n| --- | --- | --- |\n| `addFonts(fonts)` | Beide | Schriftfamilien zusammenführen; eine angegebene Familie ersetzt die bisherige Zuordnung |\n| `setFonts(fonts)` | Beide | Gesamte Schriftzuordnung ersetzen |\n| `clearFonts()` | Beide | Registrierte Schriften entfernen |\n| `addTableLayouts(layouts)` | Beide | Benannte Layoutfunktionen zusammenführen |\n| `setTableLayouts(layouts)` | Beide | Benannte Layoutfunktionen ersetzen |\n| `clearTableLayouts()` | Beide | Benutzerdefinierte Layouts entfernen |\n| `setProgressCallback(callback)` | Beide | Rendering-Fortschritt empfangen; kein Profiler für das Seitenlayout |\n| `setUrlAccessPolicy(callback)` | Beide, seit 0.3.6 | Ressourcen-URLs nur zulassen, wenn der Callback synchron `true` zurückgibt |\n| `setLocalAccessPolicy(callback)` | Node.js, seit 0.3.8 | Lokale Ressourcen nur zulassen, wenn der Callback synchron `true` zurückgibt |\n| `addVirtualFileSystem(vfs)` | Browser | Base64-Schrift- und Ressourcendaten zum virtuellen Dateisystem hinzufügen |\n| `addFontContainer(container)` | Browser | Einen gebündelten Schriftcontainer registrieren |\n\n## Rendern\n\n`createPdf(docDefinition, options?)` akzeptiert Objekte und gibt einen Ausgabe-Wrapper zurück. Verwende [Dokumentfelder](/docs/0.3/de/document-definition-object/) im ersten Argument und [Rendering-Optionen](/docs/0.3/de/options/) im zweiten.\n\n| Ausgabe | Node.js | Browser |\n| --- | --- | --- |\n| `getBuffer()`, `getBase64()`, `getDataUrl()`, `getStream()` | Ja | Ja |\n| `write(filename)` | Ja | Nein |\n| `download(filename?)`, `open(window?)`, `print(window?)`, `getBlob()` | Nein | Ja |\n\nAlle Ausgabemethoden geben Promises zurück. Behandle abgelehnte Promises immer. Der `createPdf`-Wrapper selbst ist kein Promise. Details zum Lebenszyklus findest du unter [Node.js-Methoden](/docs/0.3/de/getting-started/server-side/methods/) und [Browsermethoden](/docs/0.3/de/getting-started/client-side/methods/).\n"
+ },
+ {
+ "id": "de/guides/contributing",
+ "language": "de",
+ "translationKey": "guides/contributing",
+ "path": "/docs/0.3/de/guides/contributing/",
+ "title": "Mitwirken und Quellcodearchitektur",
+ "description": "Lerne die Rendering-Pipeline von pdfmake kennen, ergänze gezielte Regressionstests und prüfe Beiträge zur Bibliothek oder Dokumentation lokal.",
+ "version": "0.3",
+ "sourceDigest": "ca6cb5430de16efbb426ec56f526fac9bd29bebd50ca1a5c9f971b896f29363b",
+ "source": "guides/contributing.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/contributing/",
+ "uri": "pdfmake://docs/0.3/de/guides/contributing",
+ "markdown": "# Mitwirken und Quellcodearchitektur\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/contributing/\n\n## Quellcodeübersicht\n\nDie Bibliothek und diese Website liegen in getrennten Repositories:\n\n- [bpampuch/pdfmake](https://github.com/bpampuch/pdfmake): Engine, Bundles, Tests und Beispiele.\n- [pdfmake/docs](https://github.com/pdfmake/docs): diese versionierte Entwicklerwebsite und die Dokumentationswerkzeuge.\n\nDer Node.js-Einstieg der Bibliothek ist `src/index.js`; gemeinsame Konfiguration liegt in `src/base.js`. Die Browserintegration befindet sich unter `src/browser-extensions/`. `Printer` bereitet Ressourcen vor und erzeugt die PDFKit-Ausgabe. `DocPreprocessor` normalisiert Knoten, `DocMeasure` und `TextInlines` messen sie, `LayoutBuilder` und `TableProcessor` teilen sie auf Seiten auf, und `Renderer` schreibt PDFKit-Zeichenanweisungen.\n\n## Änderungen an der Engine prüfen\n\n```sh\nnpm ci\nnpm test\nnpm run build:examples\nnpm run test:package\n```\n\n`npm test` erstellt generierte Node.js- und Browserartefakte und führt dann Mocha und ESLint aus. Unit-Tests importieren kompiliertes `js/`; erstelle diese Dateien nach Änderungen in `src/` erneut. Bearbeite `js/` oder `build/` nicht direkt. Der neue Paket-Rauchtest installiert das tatsächliche Tarball in einem temporären Consumer mit Produktionsabhängigkeiten und prüft anschließend die Node.js-Ausgabe und beide Browser-Bundles. Er ersetzt Tests in echten Browsern nicht.\n\nBewahre bei Optimierungen Text, Schriftmetriken, Stilvererbung und Seiteneinteilung. Ergänze einen Regressionstest für einen Randfall und vergleiche, wenn möglich, mit dem bisherigen Verhalten. Halte Leistungsbenchmarks getrennt von Korrektheitstests.\n\n## Dokumentationsänderungen prüfen\n\nVerwende Node.js >=24.11 und Hugo **0.168.0**. Führe im Repository Folgendes aus:\n\n```sh\nnpm ci\nnpm run docs:generate\nnpm test\nnpm run build\nnpm run dev\n```\n\nÖffne die von Hugo ausgegebene Adresse. Die Generierung erstellt den Website-Suchindex, Markdown-Exporte und den MCP-Korpus aus `content/`. Tests prüfen Metadaten, Beispiele und MCP-Verhalten. Der Build prüft generierte interne Links und Fragmentziele. Übernimm die neu generierten Ausgaben zusammen mit den Quelldateien, damit Clients den Korpus ohne Hugo-Installation verwenden können.\n\n## Releases\n\nDie Bibliothek behält den GitHub-Release-Trigger des Upstream-Projekts bei. Der vorgeschlagene Workflow prüft, ob Tag und Version übereinstimmen, erstellt und testet das Paket, generiert Beispiele, prüft ein gepacktes Consumer-Projekt und veröffentlicht anschließend genau dieses Tarball mit Herkunftsnachweis. Lokale Tests veröffentlichen nichts in der Registry.\n\nDer Dokumentationsworkflow erstellt und lädt bei Pushes und Pull Requests ein Prüf-Artefakt hoch; er überschreibt nicht die versionierte Produktionswebsite. Die bestehende Bereitstellung für mehrere Versionen muss mit den Maintainer:innen abgestimmt werden, bevor die Deployment-Konfiguration geändert wird.\n"
+ },
+ {
+ "id": "de/guides/errors",
+ "language": "de",
+ "translationKey": "guides/errors",
+ "path": "/docs/0.3/de/guides/errors/",
+ "title": "Fehler und Diagnose",
+ "description": "Finde JavaScript-Syntaxfehler, ungültige Dokumentknoten, Ressourcenfehler und unterbrochene Ausgaben anhand aussagekräftiger Diagnosen.",
+ "version": "0.3",
+ "sourceDigest": "ff68daa138b7259216d53546c431739a03360e22b4e9749840a4eba20c38c633",
+ "source": "guides/errors.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/errors/",
+ "uri": "pdfmake://docs/0.3/de/guides/errors",
+ "markdown": "# Fehler und Diagnose\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/errors/\n\n## Zuerst die fehlerhafte Phase bestimmen\n\nEine ungültige Definition sollte einen Fehler auslösen und Inhalte nicht stillschweigend auslassen. Entscheidend ist, an welcher Stelle der Fehler auftritt und wie er an deine Anwendung weitergegeben wird.\n\n| Phase | Typischer Fehler | Wo beheben? |\n| --- | --- | --- |\n| JavaScript-Parsing | Fehlendes Komma, Anführungszeichen oder schließende Klammer | Quellcode-Editor; die Bibliothek wurde noch nicht aufgerufen |\n| Ausführung der Definition | `ReferenceError` oder fehlschlagender Callback | Anwendungscode, der die Definition erstellt |\n| Dokumentstruktur | Falscher Knotentyp, ungültige Tabellenzeilen oder Liste | Angegebener Pfad in der Definition |\n| Ressourcenladen | Fehlende Schrift, abgelehnte URL, nicht lesbares Bild | Schrift-/Ressourcenregistrierung und Zugriffsrichtlinien |\n| Layout/Rendering | Zu großer Inhalt, ungültige Abmessungen oder Callback-Fehler | Kleinste Definition, die den Fehler reproduziert |\n| Ausgabe | Geschlossener Stream, Schreibrechte oder Fehler des Ziels | Fehlerbehandlung für Buffer, Stream oder Datei |\n\n## Immer auf die Ausgabe warten\n\n**JavaScript**\n\n```js\nasync function generateReport(pdfmake, definition) {\n try {\n return await pdfmake.createPdf(definition).getBuffer();\n } catch (error) {\n console.error('PDF generation failed', {\n message: error.message,\n code: error.code,\n phase: error.phase,\n path: error.path\n });\n throw error;\n }\n}\n```\n\n**TypeScript**\n\n```ts\nasync function generateReport(pdfmake, definition) {\n try {\n return await pdfmake.createPdf(definition).getBuffer();\n } catch (error) {\n console.error('PDF generation failed', {\n message: error.message,\n code: error.code,\n phase: error.phase,\n path: error.path\n });\n throw error;\n }\n}\n```\n\nGib einen Fehler an den API-Aufrufer zurück oder zeige `error.message` in der Benutzeroberfläche an. Gib keine leere PDF zurück und melde keinen Erfolg, nachdem die Ablehnung verschluckt wurde. Vermeide es, Dokumentinhalte oder geheime Zugangsdaten für Ressourcen zu protokollieren.\n\nAb 0.3.13 lehnt `getStream()` den Zugriff ab, wenn der Stream bereits verbraucht wurde. Buffer-basierte Methoden verwenden ihre zwischengespeicherten Bytes erneut; Node-`write()` unterstützt auch Ausgaben, die bereits mit `getBuffer()`, `getBase64()` oder `getDataUrl()` gelesen wurden. Erzeuge für einen neuen Rohdatenstream eine neue Ausgabeinstanz.\n\n## Dokumentpfad lesen\n\nDer lokale Verbesserungszweig der Bibliothek ergänzt `PDFMAKE_INVALID_DOCUMENT`-Diagnosen mit `phase: 'preprocess'` und einer Eigenschaft `path`. Ein Beispiel:\n\n```text\nUnrecognized document structure: ...\nDocument path: content[0].columns[0].ul[1]\n```\n\nDer Pfad verweist auf den zweiten Listeneintrag in der ersten Spalte des ersten Hauptinhaltsknotens. Prüfe auf Tippfehler wie `{ txt: 'Hello' }` statt `{ text: 'Hello' }`. Bei fehlerhaften Tabellenzeilen werden die Zeile und die erwartete Anzahl an Zellen angegeben. Leere Tabellen melden, dass `table.body` nichtleere Zeilen-Arrays enthalten muss. Behalte `{}`-Platzhalter für überspannte Zellen bei. Vorhandener Fehlertext bleibt bestehen; verwende nach Möglichkeit die Diagnosefelder statt Zeichenfolgen aus der Meldung zu parsen.\n\nDiese strukturierten Diagnosen sind **neu im lokalen Verbesserungszweig**; das veröffentlichte Paket 0.3.13 enthält sie noch nicht. Allgemeine Fehler liefern weiterhin eine Meldung. Der Zweig lehnt außerdem vorzeitig geschlossene Buffer-Streams ab, statt deren Promise unerfüllt zu lassen.\n\n## Syntaxfehler im Playground\n\nDer Editor parst die Definition, bevor er sie ausführt, markiert die fehlerhafte Stelle und zeigt Zeile und Spalte an. **Im Editor zum Fehler springen** fokussiert die Stelle. Undo/Redo und das Fehlerfeld ermöglichen Korrekturen, ohne deine Arbeit zu verlieren. Bei Live-Vorschau bleibt die letzte erfolgreiche PDF während der Bearbeitung und nach Fehlern sichtbar; der Download ist deaktiviert, wenn die Vorschau nicht mehr zum aktuellen Quelltext passt.\n\n## Schwierige Fehler eingrenzen\n\nVerwende dieselben Schriften und dieselbe Laufzeit. Ersetze den Inhalt durch einen einzelnen Absatz und füge die Blöcke schrittweise wieder hinzu, bis das Problem erneut auftritt. Prüfe bei Tabellen zuerst Zeilenlängen und Zellüberspannungen, bevor du Breiten anpasst. Verwende bei Ressourcenfehlern zunächst eine bekannte lokale Schrift und ein eingebettetes Bild. Weitere Symptome findest du unter [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/).\n\n## Die vollständige Definition vor dem Rendern prüfen\n\nDie lokale, unveröffentlichte API `validateDocument(input, options)` prüft alle deklarierten Dokumenteigenschaften und sammelt mehrere Fehler mit Pfaden. Zusätzlich prüft sie Tabellen, Spans, Referenzen, Zahlenbereiche und Zyklen. Sie verändert keine Eingabe, führt keine Callbacks aus und greift auf keine Ressourcen zu. Unbekannte Eigenschaften sind standardmäßig Warnungen; mit `strict: true` werden sie zu Fehlern.\n\n**JavaScript**\n\n```js\nconst input = { content: [{ text: 'Report', fontSize: 'large' }] };\nconst report = pdfMake.validateDocument(input, { strict: true });\nfor (const issue of report.errors) {\n console.error(issue.path, issue.code, issue.message);\n}\n```\n\n**TypeScript**\n\n```ts\nconst input = { content: [{ text: 'Report', fontSize: 'large' }] };\nconst report = pdfMake.validateDocument(input, { strict: true });\nfor (const issue of report.errors) {\n console.error(issue.path, issue.code, issue.message);\n}\n```\n\nDas Ergebnis enthält `valid`, `errors`, `warnings`, `deferred` und `truncated`. Jeder Befund enthält `path`, `code`, `severity` und `message`. Standardgrenzen: 100 Befunde, 100 Verschachtelungsebenen und 50.000 untersuchte Werte. Ein ausgeschöpftes Limit meldet niemals Erfolg. Callback-Ergebnisse, Ressourcenverfügbarkeit und -dekodierung sowie das endgültige Layout werden weiterhin beim Rendern geprüft. JavaScript muss bereits syntaktisch gültig sein, bevor diese Objekt-API aufgerufen werden kann.\n\nÜbergebe `{ validation: true }` als zweites Argument an `createPdf`, um ungültige Definitionen vor dem Laden von Ressourcen abzulehnen. Ein ungültiges Dokument wirft einen `DocumentValidationError` mit `code: \"PDFMAKE_VALIDATION_ERROR\"`, `phase: \"validation\"` und einem `diagnostics`-Array. Bestehende Aufrufe bleiben kompatibel; die automatische Vorabprüfung ist optional. Der lokale Playground führt sie mit der verbesserten Library automatisch aus.\n"
+ },
+ {
+ "id": "de/guides/invoice",
+ "language": "de",
+ "translationKey": "guides/invoice",
+ "path": "/docs/0.3/de/guides/invoice/",
+ "title": "Rezept: Rechnung",
+ "description": "Erzeuge eine vollständige Rechnungs-PDF mit wiederverwendbaren Stilen, wiederholter Tabellenkopfzeile, Summen und Seitenzahlen.",
+ "version": "0.3",
+ "sourceDigest": "b5cda8b991f77dbe11893d23edc93a699f221ce0a046d02d8964c10f0290b842",
+ "source": "guides/invoice.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/invoice/",
+ "uri": "pdfmake://docs/0.3/de/guides/invoice",
+ "markdown": "# Rezept: Rechnung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/invoice/\n\n## Beispiel ausführen\n\nInstalliere `pdfmake@0.3.13`, speichere den folgenden Inhalt als `invoice.cjs` und führe `node invoice.cjs` aus. Das Beispiel verwendet die Standardschrift Helvetica mit ASCII-Inhalt, um externe Ressourcen zu vermeiden. Für eine größere Sprachenabdeckung solltest du eingebettete Schriften verwenden.\n\n**JavaScript**\n\n```js\n// docs-test: invoice\nconst pdfmake = require('pdfmake');\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const items = [\n { description: 'Design services', quantity: 2, unitPriceCents: 12500 },\n { description: 'Document review', quantity: 1, unitPriceCents: 7500 }\n ];\n const money = cents => (cents / 100).toFixed(2) + ' EUR';\n const total = items.reduce((sum, item) => sum + item.quantity * item.unitPriceCents, 0);\n const definition = {\n defaultStyle: { font: 'Helvetica', fontSize: 10 },\n pageMargins: [40, 50, 40, 50],\n info: { title: 'Invoice INV-001', author: 'Example Studio' },\n footer: (page, pages) => ({ text: `Page ${page} of ${pages}`, alignment: 'center', fontSize: 9 }),\n content: [\n { text: 'INVOICE', style: 'title' },\n { columns: ['Example Studio', { text: 'INV-001', alignment: 'right' }], margin: [0, 0, 0, 20] },\n { layout: 'lightHorizontalLines', table: {\n headerRows: 1,\n widths: ['*', 'auto', 'auto', 'auto'],\n body: [\n ['Description', 'Qty', 'Unit price', 'Amount'].map(text => ({ text, bold: true })),\n ...items.map(item => [item.description, item.quantity, money(item.unitPriceCents),\n { text: money(item.quantity * item.unitPriceCents), alignment: 'right' }])\n ]\n } },\n { text: 'Total: ' + money(total), alignment: 'right', bold: true, margin: [0, 16, 0, 0] }\n ],\n styles: { title: { fontSize: 28, bold: true, margin: [0, 0, 0, 16] } }\n };\n await pdfmake.createPdf(definition).write('invoice.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n// docs-test: invoice\nimport pdfmake from \"pdfmake\";\nconst fonts = require('pdfmake/standard-fonts/Helvetica');\npdfmake.addFonts(fonts);\npdfmake.setUrlAccessPolicy(() => false);\nconst standardNames = new Set(Object.values(fonts.Helvetica));\npdfmake.setLocalAccessPolicy(name => standardNames.has(name));\n\nasync function main() {\n const items = [\n { description: 'Design services', quantity: 2, unitPriceCents: 12500 },\n { description: 'Document review', quantity: 1, unitPriceCents: 7500 }\n ];\n const money = (cents: number) => (cents / 100).toFixed(2) + ' EUR';\n const total = items.reduce((sum, item) => sum + item.quantity * item.unitPriceCents, 0);\n const definition: TDocumentDefinitions = {\n defaultStyle: { font: 'Helvetica', fontSize: 10 },\n pageMargins: [40, 50, 40, 50],\n info: { title: 'Invoice INV-001', author: 'Example Studio' },\n footer: (page, pages) => ({ text: `Page ${page} of ${pages}`, alignment: 'center', fontSize: 9 }),\n content: [\n { text: 'INVOICE', style: 'title' },\n { columns: ['Example Studio', { text: 'INV-001', alignment: 'right' }], margin: [0, 0, 0, 20] },\n { layout: 'lightHorizontalLines', table: {\n headerRows: 1,\n widths: ['*', 'auto', 'auto', 'auto'],\n body: [\n ['Description', 'Qty', 'Unit price', 'Amount'].map(text => ({ text, bold: true })),\n ...items.map(item => [item.description, item.quantity, money(item.unitPriceCents),\n { text: money(item.quantity * item.unitPriceCents), alignment: 'right' }])\n ]\n } },\n { text: 'Total: ' + money(total), alignment: 'right', bold: true, margin: [0, 16, 0, 0] }\n ],\n styles: { title: { fontSize: 28, bold: true, margin: [0, 0, 0, 16] } }\n };\n await pdfmake.createPdf(definition).write('invoice.pdf');\n}\n\nmain().catch(error => { console.error(error); process.exitCode = 1; });\n```\n\n## An deine Anwendung anpassen\n\nDies ist ein Layoutbeispiel und keine Steuer- oder Buchhaltungslösung. Prüfe Mengen und Preise, bevor du die Definition erzeugst. In diesem Beispiel werden Beträge als ganzzahlige Cent-Werte gespeichert, um Dezimalfehler durch wiederholte Addition zu vermeiden; wende deine fachlichen Rundungsregeln separat an. Ersetze für eine HTTP-Antwort `write()` durch `getBuffer()`, wie in der [Node.js-Schnellstartanleitung](/docs/0.3/de/getting-started/server-side/) gezeigt.\n\n`headerRows: 1` wiederholt die Tabellenkopfzeile, wenn die Zeilen auf einer neuen Seite fortgesetzt werden. Jede Zeile muss dieselbe Länge wie `widths` haben. Erzeuge für jede Rechnung eine neue Definition.\n"
+ },
+ {
+ "id": "de/guides/llm-and-mcp",
+ "language": "de",
+ "translationKey": "guides/llm-and-mcp",
+ "path": "/docs/0.3/de/guides/llm-and-mcp/",
+ "title": "LLM- und MCP-Integration",
+ "description": "Verwende versionierte Markdown-Ressourcen, llms.txt und einen lokalen MCP-Dokumentationsserver mit reinem Lesezugriff für pdfmake 0.3.",
+ "version": "0.3",
+ "sourceDigest": "f369b718c3c46a1865fd7a38d3ccd5b001b457935d5a0a4bd9fccb22d194bbd3",
+ "source": "guides/llm-and-mcp.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/llm-and-mcp/",
+ "uri": "pdfmake://docs/0.3/de/guides/llm-and-mcp",
+ "markdown": "# LLM- und MCP-Integration\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/llm-and-mcp/\n\n## Dokumentation ohne MCP verwenden\n\nJede Seite ist als generiertes Markdown verfügbar. Dieselbe Quelle erzeugt:\n\n- [llms.txt](/docs/0.3/de/llms.txt): Seitenverzeichnis mit Beschreibungen und Markdown-Links.\n- [llms-full.txt](/docs/0.3/de/llms-full.txt): den vollständigen, versionierten Markdown-Korpus.\n- [docs-index.json](/docs/0.3/de/docs-index.json): Seiten-IDs, Titel, Beschreibungen, Quell-URLs und vollständiges Markdown.\n\nDiese Dateien erleichtern das Auffinden von Inhalten, garantieren aber keine Suchmaschinenindexierung oder Aufnahme in Modellindizes. Nenne im Prompt die installierte Bibliotheksversion. Bitte das Modell, die verwendete Dokumentationsseite anzugeben und Promise-basierte Ausgabemethoden zu verwenden. Die `AGENTS.md`-Datei der Bibliothek beschreibt den Quellprozess und Testbefehle für Coding-Agenten.\n\n## Lokalen MCP-Server starten\n\nKlone das Dokumentationsrepository, installiere die Abhängigkeiten, erzeuge den Korpus und starte den Server:\n\n```sh\ngit clone https://github.com/pdfmake/docs.git\ncd docs\nnpm ci\nnpm run docs:generate\nnode mcp/server.mjs\n```\n\nBis zur Annahme durch das Upstream-Projekt gehört dieser Server zum lokalen Verbesserungszweig. Starte ihn über die stdio-Konfiguration deines MCP-Clients und verwende absolute Pfade:\n\n```json\n{\n \"mcpServers\": {\n \"pdfmake-docs\": {\n \"command\": \"node\",\n \"args\": [\"/absolute/path/to/docs/mcp/server.mjs\"]\n }\n }\n}\n```\n\nErsetze den Beispielpfad durch den Pfad deines Klons. In Windows-JSON-Pfaden musst du `/` oder escaped `\\\\` verwenden. Die Speicherorte der Clientkonfiguration unterscheiden sich. Der Server schreibt Protokollnachrichten nach stdout und Fehler nach stderr. Nach der Installation der Abhängigkeiten benötigt er weder einen API-Schlüssel noch ein Modellkonto oder eine Netzwerkverbindung.\n\n## Werkzeuge und Ressourcen\n\n| Funktion | Eingabe | Ergebnis |\n| --- | --- | --- |\n| `search_docs` | `query`, optional `limit` (1–10), optional `language` | Rangsortierte Seiten mit exakten IDs, Sprache, Version, Quell-URLs und Auszügen |\n| `get_doc` | Exakte `id` aus der Suche | Vollständige Markdown-Seite |\n| MCP-Ressourcen | `pdfmake://docs/0.3/de/` | Dieselbe versionierte Markdown-Seite |\n\nDer Server kann nur den mitgelieferten Dokumentationskorpus lesen. Er kann keine PDFs rendern, keinen Code auswerten, keine vom Aufrufer ausgewählten Dateisystempfade lesen und keine entfernten URLs aufrufen. Erzeuge den Korpus nach Dokumentationsänderungen erneut und starte den Server neu.\n\n`language` akzeptiert `en` (Standard), `de`, `fr`, `es` und `pt-br`. Jede unterstützte Sprache enthält dieselbe vollständige Menge an Dokumentationsseiten. Bei der Suche werden Sprachen nicht unbemerkt vermischt. Eine übersetzte ID wie `de/learn/first-pdf` kann mit `get_doc` oder über die Ressource `pdfmake://docs/0.3/de/learn/first-pdf` abgerufen werden. Jede Sprache hat eigene Discovery-Dateien, zum Beispiel `/docs/0.3/de/llms.txt` und `/docs/0.3/de/llms-full.txt`.\n\n## Promptvorschlag\n\n> Ich verwende pdfmake 0.3.x in Node.js. Suche in der passenden Dokumentation, bevor du Code erzeugst. Verwende die Node-Singleton-API, registriere Schriften, konfiguriere synchrone Ressourcenrichtlinien, warte Ausgabemethoden mit await ab und nenne die verwendeten Seiten-IDs. Erstelle für jede Anfrage eine neue Dokumentdefinition.\n"
+ },
+ {
+ "id": "de/guides/performance",
+ "language": "de",
+ "translationKey": "guides/performance",
+ "path": "/docs/0.3/de/guides/performance/",
+ "title": "Leistung und Speicher",
+ "description": "Miss Layout- und Ausgabekosten von pdfmake, reduziere wiederholte Ressourcen und steuere die Parallelität, ohne das Dokumentverhalten zu ändern.",
+ "version": "0.3",
+ "sourceDigest": "9aada83a6a91e02de05a173270245ef69b2e909bde55078052abdcaddacc0bf2",
+ "source": "guides/performance.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/performance/",
+ "uri": "pdfmake://docs/0.3/de/guides/performance",
+ "markdown": "# Leistung und Speicher\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/performance/\n\n## Arbeitslast messen\n\nVergleiche repräsentative Dokumente mit derselben Node.js-Version, denselben Schriften und Eingabedaten. Erfasse Median und hohe Latenzwerte, Spitzenspeicherverbrauch, Seitenzahl und Ausgabegröße. Miss den Kaltstart und das Laden der Schriften getrennt von wiederholten Renderdurchläufen. Vergleiche Dokumente mit vielen Tabellen, langem Text und vielen Bildern separat.\n\n**JavaScript**\n\n```js\nconst start = performance.now();\nconst bytes = await pdfmake.createPdf(makeFreshDefinition()).getBuffer();\nconsole.log({ milliseconds: performance.now() - start, bytes: bytes.length });\n```\n\n**TypeScript**\n\n```ts\nconst start = performance.now();\nconst bytes = await pdfmake.createPdf(makeFreshDefinition()).getBuffer();\nconsole.log({ milliseconds: performance.now() - start, bytes: bytes.length });\n```\n\n`makeFreshDefinition()` ist eine eigene Factory-Funktion. Verwende keine Dokumentdefinition wieder, die das Layout bereits verändert hat. Prüfe neben der Geschwindigkeit auch den Text, die Seitenzahlen und repräsentative gerenderte Seiten.\n\n## Vermeidbare Arbeit reduzieren\n\n- Lege wiederholte Bilder im Wörterbuch `images` ab und verweise über ihren Schlüssel darauf. Skaliere große Quelldateien vor dem Einbetten; die Anzeigemaße verkleinern nicht die ursprünglichen Bilddaten.\n- Verwende feste Breiten, wenn dein Layout es zulässt. Inhaltsabhängige `auto`-Breiten erfordern Textmessungen; miss die Leistung, bevor du Tabellen neu gestaltest.\n- Registriere Schriften einmal. Liefere in Browseranwendungen nur die benötigten Schriftfamilien und Varianten aus.\n- Lass `fontLayoutCache` aktiviert, sofern kein gemessenes Kompatibilitätsproblem das Deaktivieren erfordert. Siehe [Rendering-Optionen](/docs/0.3/de/options/).\n- Vermeide Base64, wenn deine API binäre PDF-Bytes zurückgeben kann. Base64 stellt je drei Bytes mit vier Zeichen dar und legt außerdem eine Zeichenfolge im Speicher an.\n- Verwende `write()` oder verarbeite Streams direkt, um den zusätzlichen zusammengefügten Buffer von `getBuffer()` zu vermeiden, wenn du nur eine Datei oder einen Stream benötigst. Das Layout wird trotzdem vor der Ausgabe berechnet.\n\n## Parallelität steuern\n\nMehr gleichzeitige PDF-Aufträge können den Speicherverbrauch und die Verzögerungen der Event-Loop erhöhen. Begrenze die Zahl paralleler Renderdurchläufe und teste die Auslastung, statt nur eine Anfrage zu messen. Verwende Worker-Threads oder separate Prozesse, wenn blockierende Arbeit die Reaktionsfähigkeit der API beeinträchtigt. Ändere veränderliche Singleton-Konfiguration nicht pro Anfrage.\n\n## Benchmark für die Bibliotheksentwicklung\n\nDer Verbesserungszweig der Bibliothek enthält `npm run benchmark:text`, ausführbar nach `npm run build:node`. Der Benchmark vergleicht das Abflachen von Text-Arrays mit dem vorherigen Algorithmus anhand deterministischer gemischter Eingaben und prüft, ob die Ergebnisse übereinstimmen. Die optimierte Schleife vermeidet wiederholtes Kopieren von Präfixen. Der gemessene Geschwindigkeitsgewinn betrifft nur diese Hilfsfunktion; er sagt nichts über die Gesamtdauer der PDF-Erzeugung aus.\n\nZeitgrenzwerte sind bewusst nicht Teil von CI, da gemeinsam genutzte Runner unzuverlässige Messwerte liefern. Verwende Korrektheitstests als Freigabekriterium und halte Benchmark-Ergebnisse mit den Umgebungsdetails zur Prüfung fest.\n"
+ },
+ {
+ "id": "de/guides/playground",
+ "language": "de",
+ "translationKey": "guides/playground",
+ "path": "/docs/0.3/de/guides/playground/",
+ "title": "Playground-Anleitung",
+ "description": "Erkunde pdfmake-Beispiele mit Code-Editor, direkter PDF-Vorschau, Seitennavigation, lokalen Imports und herunterladbarem Quellcode.",
+ "version": "0.3",
+ "sourceDigest": "396ad48200f73ea3dadbbbcc3eaaf41d819c39e44ee4dd12c2546b4608adf171",
+ "source": "guides/playground.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/playground/",
+ "uri": "pdfmake://docs/0.3/de/guides/playground",
+ "markdown": "# Playground-Anleitung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/playground/\n\n## Durch Bearbeiten lernen\n\nÖffne den [Playground](/docs/0.3/de/playground/), wähle ein Beispiel und bearbeite die Definition im linken Bereich. Rechts siehst du eine echte, mit PDF.js gerenderte PDF. Wenn **Live-Vorschau** aktiviert ist, wird die PDF nach jeder Bearbeitung automatisch aktualisiert. Wähle **Ausführen** oder drücke **Strg/Command + Enter**, um sie sofort zu aktualisieren.\n\nDer CodeMirror-6-Editor bietet Syntaxhervorhebung, Zeilennummern, Klammerzuordnung, Einrückung, Undo/Redo-Schaltflächen, einen persistenten Rückgängig-Verlauf und Syntaxdiagnosen mit Zeile und Spalte. Mit **Zum Fehler springen** wird die fehlerhafte Quelltextstelle fokussiert. Der Editor bietet außerdem Vervollständigungen. Drücke **Strg + Leertaste**, um sie aufzurufen. Vorgeschlagene Feldnamen sind Hinweise; gültigen Kontext, Typ und Werte beschreibt die Dokumentreferenz.\n\n## Beispiele\n\n| Beispiel | Erkunden |\n| --- | --- |\n| [Erstes Dokument](/docs/0.3/de/playground/?example=welcome) | Text, Abstände und Schriftstile |\n| [Rechnung](/docs/0.3/de/playground/?example=invoice) | Tabelle, Summen und Fußzeile mit Seitenzahlen |\n| [Tabellen](/docs/0.3/de/playground/?example=tables) | Wiederholte Kopfzeilen auf mehreren Seiten |\n| [Textstile](/docs/0.3/de/playground/?example=styles) | Benannte Stile und Inline-Überschreibungen |\n| [Spalten](/docs/0.3/de/playground/?example=columns) | Nebeneinander angeordnete Blöcke und Stapel |\n| [Zellüberspannungen](/docs/0.3/de/playground/?example=spans) | Zeilen- und Spaltenüberspannungen mit Platzhaltern |\n| [Seiten](/docs/0.3/de/playground/?example=pages) | Seitenumbrüche, Kopf- und Fußzeilen |\n| [Vektoren](/docs/0.3/de/playground/?example=vectors) | Eingebettete SVGs und QR-Codes |\n| [Bilder](/docs/0.3/de/playground/?example=images) | Eingebettete PNG-Daten unter einem Namen wiederverwenden |\n| [Listen](/docs/0.3/de/playground/?example=lists) | Nummerierte Listen, Aufzählungen und Links |\n\nEin `example`-URL-Parameter wählt ein bekanntes Beispiel aus; er akzeptiert kein JavaScript. Die Live-Vorschau aktualisiert auch wiederhergestellte Arbeitsbereiche, gespeicherte Dokumente und importierte Dateien. Schalte **Live-Vorschau** aus, bevor du Code importierst, den du zunächst prüfen möchtest.\n\n## Vorschau und Ausgabe\n\nVerwende die Pfeilschaltflächen, um die Seite zu wechseln, und das Zoommenü, um die Skalierung anzupassen. **Seitentext** zeigt den aus der aktuellen PDF-Seite extrahierten Text zur Prüfung und für unterstützende Technologien an. **PDF öffnen** öffnet die erzeugte Datei separat; **PDF herunterladen** speichert dieselben PDF-Bytes. Die Fußzeile zeigt Erstellungszeit und Ausgabegröße. Die Erstellungszeit umfasst nicht das Rendern der Vorschau mit PDF.js.\n\nDie Live-Vorschau wartet nach der letzten Änderung 650 ms und rendert anschließend in einem neuen Worker. Die vorherige PDF bleibt sichtbar, bis die nächste Seite außerhalb des Bildschirms fertig gerendert ist; danach wird die Canvas in einem Schritt ausgetauscht. Die ausgewählte PDF-Seite und Zoomstufe bleiben nach Möglichkeit erhalten. Downloads sind deaktiviert, wenn die sichtbare PDF nicht dem aktuellen Code entspricht. Bei Fehlern bleibt die letzte erfolgreiche Vorschau erhalten, statt durch ein leeres Feld ersetzt zu werden.\n\n## Arbeit behalten\n\n**Code exportieren** lädt die aktuelle Definition als JavaScript herunter. **.js importieren** liest eine lokale Datei ein. Dateien sind auf 500 KB begrenzt. Deaktiviere **Live-Vorschau**, bevor du Code importierst, den du vor dem Ausführen prüfen möchtest. Vor dem Zurücksetzen oder Wechseln des Beispiels wirst du gefragt, bevor Änderungen überschrieben werden.\n\n**Der aktuelle Arbeitsbereich wird lokal automatisch gespeichert** – einschließlich Definition, Editor-Auswahl, Undo-Verlauf, Beispiel, Seite und Zoomstufe. Beim Neuladen werden Editor, Undo-/Redo-Verlauf und die Einstellung der Live-Vorschau wiederhergestellt. Wenn die Live-Vorschau aktiviert ist, wird die wiederhergestellte PDF automatisch gerendert; Änderungen aktualisieren sie anschließend ohne **Ausführen**. Ist sie deaktiviert, bleibt das Rendering auch nach dem Neuladen manuell.\n\nGib dem Dokument einen Namen und wähle **Dokument speichern**, um eine separate lokale Kopie anzulegen. Ein neuer Name erzeugt ein weiteres gespeichertes Dokument; unter dem aktuell ausgewählten Namen wird die Datei aktualisiert. Über das Menü gespeicherter Dokumente stellst du ein Dokument und seinen Verlauf wieder her. **Löschen** entfernt diese benannte Kopie, behält aber den aktuellen Editorinhalt bei. Bis zu 30 benannte Dokumente können gespeichert werden. Es gelten die Speichergrenzen des Browsers.\n\n**Entwurf lokal speichern** bleibt ein separates Schnellsnapshot mit **Wiederherstellen**- und **Löschen**-Steuerung. **Automatisches Speichern des Arbeitsbereichs löschen** entfernt die aktuelle automatische Speicherung und pausiert sie, bis du wieder Text eingibst. Benannte Dokumente und Schnellentwürfe sind getrennt. Wenn der Browser-Speicher deaktiviert oder voll ist, funktioniert der Editor weiterhin und der Codeexport bleibt verfügbar. Diese Anwendung lädt weder Quellcode noch PDFs hoch.\n\n## Grenzen des Renderings\n\nJeder Renderdurchlauf startet einen neuen Browser-Worker. **Abbrechen** beendet ihn auch bei einer blockierten JavaScript-Schleife. Ein Zeitlimit von zehn Sekunden beendet unerwartet aufwendige Aufgaben. Vereinfache große Dokumente oder teste sie in einer kontrollierten Anwendung, wenn sie das Limit des Playgrounds überschreiten. Die PDF-API sperrt hier entfernte URL-Ressourcen; verwende eingebettete Bilder und die bereitgestellten Roboto-Schriften.\n\nBenutzerdefiniertes JavaScript ist vertrauenswürdiger Benutzer-Code, keine Sicherheitssandbox. Führe keinen Code aus unbekannter Quelle aus. Ein Worker schützt die Benutzeroberfläche vor Blockaden, isoliert aber keinen bösartigen Code. Hinweise für Produktions-APIs findest du unter [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/).\n\n## Eigenständiges Entwicklungswerkzeug starten\n\nFühre in einem erstellten Checkout der pdfmake-Bibliothek `npm run playground` aus. Damit wird dieselbe Benutzeroberfläche mit der Engine dieses Checkouts unter `http://127.0.0.1:1234/playground/` bereitgestellt. Für die separaten Werkzeuge ist Node.js >=22.13 erforderlich. Die Laufzeitanforderung der veröffentlichten Bibliothek bleibt Node.js >=20. Die Dokumentationswebsite kann mit `PDFMAKE_SOURCE` ebenfalls eine lokale Engine verwenden; siehe die README des Dokumentationsrepositorys.\n"
+ },
+ {
+ "id": "de/guides/resource-security",
+ "language": "de",
+ "translationKey": "guides/resource-security",
+ "path": "/docs/0.3/de/guides/resource-security/",
+ "title": "Ressourcensicherheit",
+ "description": "Schütze in Serveranwendungen mit pdfmake den Zugriff auf externe URLs, lokale Dateien und nicht vertrauenswürdige Dokumenteingaben.",
+ "version": "0.3",
+ "sourceDigest": "6c29d58fcc33de62c3b85279453f4530abfd1801030ad057800f73e261b61a26",
+ "source": "guides/resource-security.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/resource-security/",
+ "uri": "pdfmake://docs/0.3/de/guides/resource-security",
+ "markdown": "# Ressourcensicherheit\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/resource-security/\n\n## Behandle Definitionen wie Anwendungscode\n\nEine Definition kann Callback-Funktionen für Kopf- und Fußzeilen, Tabellenlayouts und Seitenumbrüche enthalten. Werte niemals JavaScript aus, das ein nicht vertrauenswürdiger Aufrufer übermittelt. Nimm geprüfte Anwendungsdaten entgegen und erstelle die Definitionen selbst. Begrenze vor dem Rendern Eingabegröße, Verschachtelung, Tabellenabmessungen und Bildgröße.\n\n## Nicht benötigte Ressourcen sperren\n\nWenn alle Ressourcen als In-Memory-Daten bereitgestellt werden, sperre Ressourcenpfade in Form von Zeichenfolgen:\n\n**JavaScript**\n\n```js\npdfmake.setUrlAccessPolicy(() => false);\npdfmake.setLocalAccessPolicy(() => false);\n```\n\n**TypeScript**\n\n```ts\npdfmake.setUrlAccessPolicy(() => false);\npdfmake.setLocalAccessPolicy(() => false);\n```\n\nDie aktuelle Implementierung leitet auch Standard-Schriftkennungen (zum Beispiel `Helvetica-Bold`) durch die lokale Richtlinie. Wenn du Standardschriften verwendest, erlaube die genau registrierten Kennungen; die [Node.js-Schnellstartanleitung](/docs/0.3/de/getting-started/server-side/) zeigt diese Einrichtung.\n\nURL-Richtlinien erfordern **0.3.6+**, lokale Richtlinien **0.3.8+**. Konfiguriere sie, bevor du Aufträge entgegennimmst. Eine nicht gesetzte Richtlinie erlaubt das Laden von Ressourcen; sie bedeutet nicht, dass alle Zugriffe gesperrt sind.\n\n## Synchrone Richtlinien verwenden\n\nDie Implementierung prüft, ob `callback(value) === true` gilt. Verwende in diesen Richtlinien keine `async`-Callbacks, DNS-Abfragen oder Promises. Lade freigegebene Ressourcen in deiner Anwendung vorab, wenn die Prüfung asynchron erfolgen muss, und übergib anschließend eingebettete Daten oder eine anwendungseigene Datei.\n\n**JavaScript**\n\n```js\npdfmake.setUrlAccessPolicy(value => {\n const url = new URL(value);\n return url.protocol === 'https:' && url.hostname === 'assets.example.com' && !url.username && !url.password;\n});\n```\n\n**TypeScript**\n\n```ts\npdfmake.setUrlAccessPolicy(value => {\n const url = new URL(value);\n return url.protocol === 'https:' && url.hostname === 'assets.example.com' && !url.username && !url.password;\n});\n```\n\nDieses Beispiel mit Hostnamen bietet keinen vollständigen Schutz vor SSRF. DNS-Änderungen, Weiterleitungen, interne Adressbereiche und Netzwerkrechte der Bereitstellung sind ebenfalls relevant. Begrenze ausgehende Netzwerkzugriffe. In Node.js prüft der Resolver manuelle Weiterleitungsschritte. Browser können Weiterleitungen folgen, bevor die endgültige URL geprüft wird; Browserrichtlinien können nicht jeden Netzwerkschritt kontrollieren.\n\n## Lokale Dateien\n\nErlaube genau aufgelöste, von deiner Anwendung verwaltete Pfade. Eine funktionierende Zulassungsliste zeigt die [Schriftkonfiguration](/docs/0.3/de/fonts/). Vermeide `startsWith('fonts/')`, da damit weder Pfadmanipulation noch Dateisystem-Aliase verhindert werden. Schütze freigegebene Dateien vor Austausch und berücksichtige symbolische Links. Lass Aufrufer keine beliebigen Serverpfade auswählen.\n\n## Auftragsumfang begrenzen\n\nLayout- und Schriftenverarbeitung können CPU und Speicher verbrauchen, bevor ein Ausgabestream verfügbar ist. Verwende begrenzte Warteschlangen und isolierte Worker, wenn du große oder nicht vertrauenswürdige Dokumente verarbeitest. Ein Promise-Timeout unterbricht das synchrone Layout nicht. Wenn du eine harte Abbruchmöglichkeit brauchst, setze Prozesslimits.\n\n## PDF-Verschlüsselung ist davon getrennt\n\n[Passwörter und PDF-Berechtigungen](/docs/0.3/de/document-definition-object/security/) betreffen das erzeugte Dokument. Sie sichern nicht das Netzwerk, Dateisystem oder die Callback-Ausführung deines Servers.\n"
+ },
+ {
+ "id": "de/guides/troubleshooting",
+ "language": "de",
+ "translationKey": "guides/troubleshooting",
+ "path": "/docs/0.3/de/guides/troubleshooting/",
+ "title": "Fehlerbehebung",
+ "description": "Untersuche häufige Fehler in pdfmake 0.3 mit Imports, Schriften, Tabellen, Promises, Browserfenstern und Ressourcen-Zugriffsrechten.",
+ "version": "0.3",
+ "sourceDigest": "5159bc06095c71b8ab0b613c4df51b538e163232b5543aa4bb809f90b91021bb",
+ "source": "guides/troubleshooting.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/guides/troubleshooting/",
+ "uri": "pdfmake://docs/0.3/de/guides/troubleshooting",
+ "markdown": "# Fehlerbehebung\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/guides/troubleshooting/\n\n## Zuerst Version und Laufzeit prüfen\n\nFühre `npm ls pdfmake` aus und vergleiche deinen Import mit der passenden Schnellstartanleitung. Ein Browser-Bundle und der Node.js-Einstieg bieten unterschiedliche Ausgabemethoden. Beispiele für Version 0.1/0.2 mit `new PdfPrinter(...)` oder Callbacks beschreiben nicht die API von 0.3.\n\n| Symptom | Prüfen | Lösung |\n| --- | --- | --- |\n| Schriftfamilie oder Variante ist nicht definiert | Familienname, Zuordnung für fett/kursiv, Standardschrift | Alle verwendeten Varianten registrieren und die Familie in `defaultStyle` auswählen |\n| Datei nicht gefunden oder Zugriff verweigert | Tatsächlich aufgelöster Pfad der Schrift/des Bildes und Richtlinie | Vorhandene anwendungseigene Pfade und eine passende synchrone Richtlinie verwenden |\n| Glyphen fehlen oder werden falsch dargestellt | Glyphenabdeckung der ausgewählten Schrift | Schrift mit den benötigten Sprachzeichen einbetten; auch fett und kursiv prüfen |\n| Tabelle leer oder fehlerhaft | `body`, Zeilenlängen und Zellenüberspannung | Nichtleere, einheitliche Zeilen und Platzhalter für überspannte Zellen bereitstellen |\n| `download` ist in Node.js keine Funktion | Importierte Laufzeit | In Node.js `write` oder `getBuffer` verwenden |\n| Browser öffnet kein Fenster | Benutzeraktion und Popup-Blocker | Ein Fenster direkt beim Klick öffnen, bevor asynchron Daten geladen werden |\n| URL trotz Zulassungs-Callback abgelehnt | Rückgabetyp des Callbacks | Synchron den booleschen Wert `true` zurückgeben; `async` entfernen |\n| HTTP-Bildanfrage schlägt fehl | URL, Richtlinie, CORS, Status und Weiterleitungen | Zugriff in der Ziel-Laufzeit prüfen; Browser setzen CORS durch |\n| Datei unvollständig oder fehlt | Abgelehntes Promise und Schreibstreamfehler | Auf `write()` warten und Ablehnung behandeln, bevor der Erfolg gemeldet wird |\n| Ausgabe ändert sich nach einem Upgrade | Version, Schriften, Eingaben und Standardwerte | Mit festgelegter Version reproduzieren und extrahierten Text, Seitenzahlen und gerenderte Seiten vergleichen |\n\n## Definition vereinfachen\n\nBeginne mit einem einfachen Absatz und bekannten funktionierenden Schriften. Ergänze Stile, Tabellenzeilen und Ressourcen einzeln. Erzeuge für jeden Versuch eine neue Definition. Trenne Anfrage- und Ressourcenfehler von Layoutfehlern.\n\n## Einen hilfreichen Fehlerbericht erstellen\n\nGib die genauen pdfmake- und Node.js-/Browser-Versionen, das Betriebssystem, eine minimale ausführbare Definition, die Schrifteinrichtung, erwartetes und tatsächliches Verhalten sowie den vollständigen relevanten Stack-Trace an. Entferne private Inhalte und Geheimnisse. Bei Seitenumbruchfehlern nenne die kleinste Eingabe, mit der sich das Problem noch reproduzieren lässt.\n"
+ },
+ {
+ "id": "de/learn",
+ "language": "de",
+ "translationKey": "learn",
+ "path": "/docs/0.3/de/learn/",
+ "title": "Hier anfangen",
+ "description": "Ein kurzer Lernpfad von der Laufzeitwahl bis zum Erstellen, Formatieren und zur Fehlerbehebung deiner ersten PDF.",
+ "version": "0.3",
+ "sourceDigest": "a8635fe5b8817a5c2f610b634abb0689d9672e42eef5a1b0bc6d01f52ba73dbe",
+ "source": "learn/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/learn/",
+ "uri": "pdfmake://docs/0.3/de/learn",
+ "markdown": "# Hier anfangen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/learn/\n\n## Mit einem funktionierenden Dokument beginnen\n\nDu musst nicht erst die gesamte Dokumentreferenz kennen. Folge diesen drei Schritten:\n\n\n\n- [1. Deine erste PDF erstellen](/docs/0.3/de/learn/first-pdf/): Verstehe die Definition, lade Schriften und führe ein vollständiges Beispiel aus.\n\n\n- [2. Das Dokumentmodell kennenlernen](/docs/0.3/de/learn/document-model/): Erfahre, wann Absätze, Inline-Text, Stapel, Spalten oder Tabellen sinnvoll sind.\n\n\n- [3. Fehler lesen und gezielt beheben](/docs/0.3/de/guides/errors/): Unterscheide zwischen JavaScript-Syntax, Dokumentstruktur, Ressourcen und Ausgabe.\n\n\n\n## Welche Laufzeit brauche ich?\n\n| Auswahl | Wann | Ausgabe |\n| --- | --- | --- |\n| [Node.js](/docs/0.3/de/getting-started/server-side/) | Deine API oder ein Hintergrundauftrag erstellt die Datei | `write()` für Dateien; `getBuffer()` für HTTP-Antworten |\n| [Browser](/docs/0.3/de/getting-started/client-side/) | Benutzer erstellen das Dokument auf ihrem Gerät | `download()`, `open()`, `print()` oder `getBlob()` |\n\nDie Dokumentdefinition wird gemeinsam verwendet. Das Laden der Schriften und die Ausgabemethoden hängen von der Laufzeit ab. Diese Seiten beziehen sich auf **0.3.x**; ältere Beispiele mit `new PdfPrinter(...)` und Callback-Ausgabe gehören zu [0.1/0.2](/docs/0.3/de/migration-from-0.1/).\n\n## Durch sichtbare Ergebnisse lernen\n\nDie Beispiele dieses Lernpfads zeigen den exakten JavaScript-Code neben einer tatsächlich erzeugten PDF. Öffne sie im Playground und bearbeite sie. Der vollständige Quellcode ist außerdem im [Markdown-Korpus](/docs/0.3/de/llms-full.txt) enthalten, auch der Code, der sonst von interaktiven Beispielkomponenten erzeugt wird.\n"
+ },
+ {
+ "id": "de/learn/document-model",
+ "language": "de",
+ "translationKey": "learn/document-model",
+ "path": "/docs/0.3/de/learn/document-model/",
+ "title": "Das Dokumentmodell",
+ "description": "Wähle zwischen Absätzen, Inline-Text, Stapeln, Spalten und Tabellen und erfahre, auf welcher Ebene die Konfiguration hingehört.",
+ "version": "0.3",
+ "sourceDigest": "7e8645b7aacec49012239058169490a59be9441a27c94823fc6aa528cef81064",
+ "source": "learn/document-model.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/learn/document-model/",
+ "uri": "pdfmake://docs/0.3/de/learn/document-model",
+ "markdown": "# Das Dokumentmodell\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/learn/document-model/\n\n## Mit dem Inhalt beginnen\n\n`content` beschreibt den Hauptinhalt des PDFs. Eine einfache Zeichenfolge ist ein Absatz. Ein `content`-Array ist eine vertikale Folge von Blöcken. Ein Objekt beschreibt einen Knoten mit zusätzlichen Eigenschaften. pdfmake berechnet die Positionen; normalerweise musst du keine Koordinaten angeben.\n\n**JavaScript**\n\n```js\nconst dd = {\n content: [\n 'One paragraph.',\n { text: 'Another paragraph.', bold: true },\n { text: ['One paragraph with ', { text: 'an emphasized part', italics: true }] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nconst dd: TDocumentDefinitions = {\n content: [\n 'One paragraph.',\n { text: 'Another paragraph.', bold: true },\n { text: ['One paragraph with ', { text: 'an emphasized part', italics: true }] }\n ]\n};\n```\n\nDas verschachtelte `text`-Array erzeugt **Inline-Segmente im selben Absatz**. Ein `content`-Array oder `stack` erzeugt **getrennte Blöcke**. Dieser Unterschied erklärt viele unerwartete Zeilenumbrüche bei den ersten Dokumentdefinitionen.\n\n## Container auswählen\n\n| Bedarf | Knoten | Häufiger Fehler |\n| --- | --- | --- |\n| Mehrere Absätze mit gemeinsamem Stil | `{ stack: [...] }` | Stil-Eigenschaften direkt einem Array zuweisen wollen |\n| Unabhängige Blöcke nebeneinander | `{ columns: [...] }` | Annehmen, dass Zeilen wie in einer Tabelle ausgerichtet werden |\n| Ausgerichtete Zeilen und Zellen | `{ table: { body: [...] } }` | Platzhalterzellen nach `colSpan` oder `rowSpan` auslassen |\n| Aufzählungs- oder nummerierte Elemente | `{ ul: [...] }` oder `{ ol: [...] }` | Eine Zeichenfolge einsetzen, obwohl ein Array mit Elementen erwartet wird |\n| Unterschiedliche Stile innerhalb einer Zeile | `{ text: [...] }` | Einen Stapel verwenden, der getrennte Blöcke erzeugt |\n\n\n\n### Runnable example: 05 · Columns & stacks\n\n**JavaScript**\n\n```js\nvar dd = {\n content: [\n { text: 'Two perspectives', fontSize: 26, bold: true, margin: [0, 0, 0, 20] },\n { columnGap: 24, columns: [\n { width: '*', stack: [{ text: 'The essentials', bold: true }, 'This column takes an equal share of the available width.', { ul: ['Text', 'Lists', 'Nested blocks'] }] },\n { width: '*', stack: [{ text: 'The details', bold: true }, 'Use fixed widths, auto widths or star widths to describe your layout.'] }\n ] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = {\n content: [\n { text: 'Two perspectives', fontSize: 26, bold: true, margin: [0, 0, 0, 20] },\n { columnGap: 24, columns: [\n { width: '*', stack: [{ text: 'The essentials', bold: true }, 'This column takes an equal share of the available width.', { ul: ['Text', 'Lists', 'Nested blocks'] }] },\n { width: '*', stack: [{ text: 'The details', bold: true }, 'Use fixed widths, auto widths or star widths to describe your layout.'] }\n ] }\n ]\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=columns)\n\n\n\n## Einstellungen auf der passenden Ebene festlegen\n\n| Ebene | Beispiele | Zweck |\n| --- | --- | --- |\n| Anwendungskonfiguration | `addFonts`, `addTableLayouts`, Ressourcenrichtlinien | Wiederverwendbare Ressourcen vor dem Start von Aufträgen registrieren |\n| Dokumentdefinition | `content`, `styles`, `defaultStyle`, `pageMargins`, `footer` | Ein PDF beschreiben |\n| Einzelner Knoten | `text`, `fontSize`, `bold`, `margin`, `pageBreak` | Ein Inhaltselement beschreiben |\n| Zweites Argument von `createPdf` | `fontLayoutCache`, `bufferPages` | Engine-Optionen anpassen |\n\nRegistriere gemeinsam genutzte Schriften und Richtlinien einmal in einem Node.js-Dienst. Erzeuge für jeden Auftrag eine neue Definition: Das Layout fügt Knoten Messwerte und Positionen hinzu und verändert sie damit. Ändere die Konfiguration des gemeinsam genutzten pdfmake-Singletons nicht während paralleler Anfragen.\n\n## Einheiten und Breiten verstehen\n\nMaße werden in Punkten angegeben. Ein Rand mit vier Werten hat die Reihenfolge `[links, oben, rechts, unten]`. Eine numerische Breite ist eine feste Breite in Punkten; `'auto'` richtet sich nach dem Inhalt und `'*'` teilt den verbleibenden Platz mit anderen Sternspalten. Verwende zunächst feste Breiten oder Sternbreiten und ergänze inhaltsabhängige Breiten nur dann, wenn sie ein konkretes Layoutproblem lösen.\n\n## In der Referenz weiterlesen\n\n[Stile](/docs/0.3/de/document-definition-object/styling/) · [Tabellen](/docs/0.3/de/document-definition-object/tables/) · [Bilder](/docs/0.3/de/document-definition-object/images/) · [Seitenlayout](/docs/0.3/de/document-definition-object/page/)\n"
+ },
+ {
+ "id": "de/learn/first-pdf",
+ "language": "de",
+ "translationKey": "learn/first-pdf",
+ "path": "/docs/0.3/de/learn/first-pdf/",
+ "title": "Deine erste PDF",
+ "description": "Erstelle in fünf kleinen Schritten ein funktionierendes pdfmake-0.3-Dokument mit Quellcode und tatsächlich gerenderter PDF.",
+ "version": "0.3",
+ "sourceDigest": "cc22460fa895f9043a3b91fedd495c215fe7096cedc48fdf33cf5800f1a7ea7c",
+ "source": "learn/first-pdf.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/learn/first-pdf/",
+ "uri": "pdfmake://docs/0.3/de/learn/first-pdf",
+ "markdown": "# Deine erste PDF\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/learn/first-pdf/\n\n## 1. Die zwei Zutaten verstehen\n\npdfmake benötigt eine **Engine mit Schriften** und eine **Dokumentdefinition**. Die Definition ist ein JavaScript-Objekt, das den zu druckenden Inhalt beschreibt. Sie ist kein HTML und erzeugt erst dann etwas, wenn du sie an `createPdf` übergibst und eine Ausgabe anforderst.\n\nProbiere zunächst das folgende Beispiel im Browser aus. Engine und Roboto-Schrift sind bereits eingerichtet. Richte anschließend in Schritt 3 deine Laufzeit ein.\n\n## 2. Eine vollständige Definition ansehen\n\nDas folgende Ergebnis wird exakt mit diesem Code erzeugt. Drei Einträge in `content` ergeben drei Blöcke untereinander. Text wird automatisch umgebrochen; Ränder und Schriftgrößen werden in PDF-Punkten gemessen (72 Punkte = 1 Zoll).\n\n\n\n### Runnable example: 01 · First document\n\n**JavaScript**\n\n```js\n// Define a fresh document in dd. Ctrl/⌘ + Enter to run.\nvar dd = {\n content: [\n { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },\n 'A paragraph, a table, a report. Start here and make it yours.',\n { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }\n ]\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\n// Define a fresh document in dd. Ctrl/⌘ + Enter to run.\nvar dd: TDocumentDefinitions = {\n content: [\n { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },\n 'A paragraph, a table, a report. Start here and make it yours.',\n { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }\n ]\n};\n```\n\n[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=welcome)\n\n\n\nÄndere im Playground die Überschrift oder Schriftgröße. Bei aktivierter **Live-Vorschau** erscheint die neue PDF, wenn du mit dem Tippen pausierst. Änderungen lassen sich rückgängig machen; du kannst benannte Dokumente im Browser speichern oder eine JavaScript-Datei exportieren.\n\n## 3. Deine Anwendung einrichten\n\nWähle **eine** Einrichtung. Kombiniere den Node.js-Einstieg nicht mit Browser-Ausgabemethoden.\n\n| Laufzeit | Einrichtung | Warum Schriften wichtig sind |\n| --- | --- | --- |\n| Node.js-API | [Vollständiger Node.js-Schnellstart](/docs/0.3/de/getting-started/server-side/) | Registriere echte Schriftdateien oder eine Standardschriftfamilie vor dem Rendern |\n| Browseranwendung | [Vollständiger Browser-Schnellstart](/docs/0.3/de/getting-started/client-side/) | Lade `pdfmake.min.js` und anschließend ein Schrift-VFS oder registriere es im Bundler |\n\nDas Beispiel verwendet `Roboto`, die Standardschrift im Browser. Wenn du die Definition mit der Helvetica-Einrichtung aus dem Node.js-Schnellstart verwendest, ergänze `defaultStyle: { font: 'Helvetica' }` oder registriere Roboto-Dateien. Unicode-Text benötigt außerdem eine Schrift, die die verwendeten Zeichen enthält; eine gültige Zeichenfolge liefert keine fehlenden Glyphen mit.\n\n## 4. Ausgabe anfordern und Fehler behandeln\n\nIn einer eingerichteten Browseranwendung:\n\n**JavaScript**\n\n```js\ntry {\n await pdfMake.createPdf(dd).download('first-document.pdf');\n} catch (error) {\n document.querySelector('#status').textContent = error.message;\n}\n```\n\n**TypeScript**\n\n```ts\ntry {\n await pdfMake.createPdf(dd).download('first-document.pdf');\n} catch (error) {\n document.querySelector('#status').textContent = error.message;\n}\n```\n\nHier ist `dd` die oben gezeigte Definition und `#status` ein Element deiner Anwendung. Verwende in Node.js stattdessen `await pdfmake.createPdf(dd).write('first-document.pdf')`. `createPdf` gibt einen Ausgabe-Wrapper zurück; die Ausgabemethode liefert das Promise, auf das du warten musst. Ohne `await` oder `.catch(...)` erreicht ein Generierungsfehler möglicherweise nie deine Benutzeroberfläche.\n\n## 5. Jeweils ein Konzept ergänzen\n\nBehalte das erste funktionierende Dokument. Ergänze anschließend [benannte Stile](/docs/0.3/de/document-definition-object/styling/) und danach [Tabellen](/docs/0.3/de/document-definition-object/tables/), wenn du Zeilen brauchst. Verwende das [Dokumentmodell](/docs/0.3/de/learn/document-model/), um den passenden Knotentyp auszuwählen. Wenn ein Fehler auftritt, [ordne ihn zunächst einer Fehlerklasse zu](/docs/0.3/de/guides/errors/), bevor du gleichzeitig Schriften, Layout und Ressourcen änderst.\n"
+ },
+ {
+ "id": "de/migration-from-0.1",
+ "language": "de",
+ "translationKey": "migration-from-0.1",
+ "path": "/docs/0.3/de/migration-from-0.1/",
+ "title": "Migration von 0.1/0.2",
+ "description": "Migriere ältere pdfmake-Integrationen zur Singleton-API von 0.3, Promise-Ausgabemethoden, Schriftregistrierung und Seitenumbruch-Callbacks.",
+ "version": "0.3",
+ "sourceDigest": "693d722f104238aae8b671cfceb90abdfddb531f13ae71ca10f39c9f018bb4bf",
+ "source": "migration-from-0.1/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/migration-from-0.1/",
+ "uri": "pdfmake://docs/0.3/de/migration-from-0.1",
+ "markdown": "# Migration von 0.1/0.2\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/migration-from-0.1/\n\n## Geplant aktualisieren\n\nFixiere die Version, die du prüfst. Bewahre repräsentative bestehende PDFs und die Eingaben und Schriften auf, mit denen sie erzeugt wurden. Vergleiche vor dem Upgrade in der Produktion den extrahierten Text, die Seitenzahl und gerenderte Seiten. Bytegenau identische Ausgaben sind oft ungeeignet, weil sich PDF-Metadaten und Kennungen unterscheiden können.\n\n## Node-Konstruktor-API ersetzen\n\nÄltere Node.js-Beispiele erstellen `PdfPrinter` und rufen `createPdfKitDocument` auf. Verwende in 0.3 das Singleton:\n\n**JavaScript**\n\n```js\nconst pdfmake = require('pdfmake');\npdfmake.addFonts(fonts);\nawait pdfmake.createPdf(docDefinition).write('document.pdf');\n```\n\n**TypeScript**\n\n```ts\nimport pdfmake from \"pdfmake\";\npdfmake.addFonts(fonts);\nawait pdfmake.createPdf(docDefinition).write('document.pdf');\n```\n\n`fonts` muss eine gültige Zuordnung von Schriftfamilien sein, wie in der [Node.js-Schnellstartanleitung](/docs/0.3/de/getting-started/server-side/) und im [Schriftenleitfaden](/docs/0.3/de/fonts/) gezeigt. Konfiguriere Richtlinien und Layouts beim Start und vermeide Änderungen am gemeinsam genutzten Singleton pro Anfrage.\n\n## Auf Ausgabemethoden warten\n\nErsetze callbackbasierte Browserausgabe durch Promises:\n\n**JavaScript**\n\n```js\nconst data = await pdfMake.createPdf(docDefinition).getBase64();\n```\n\n**TypeScript**\n\n```ts\nconst data = await pdfMake.createPdf(docDefinition).getBase64();\n```\n\nBehandle Ablehnungen der Ausgabemethoden. Verwende die [Node.js-Methoden](/docs/0.3/de/getting-started/server-side/methods/) oder [Browsermethoden](/docs/0.3/de/getting-started/client-side/methods/) für die jeweilige Zielumgebung.\n\n## Browser-Schriftdateien neu erzeugen\n\nErzeuge benutzerdefinierte VFS-Dateien neu und passe die Registrierung auf `addVirtualFileSystem` an. Nimm nicht an, dass das Format einer älteren generierten Schriftdatei mit dem aktuellen Bundle übereinstimmt. Siehe [VFS-Schriften](/docs/0.3/de/fonts/custom-fonts-client-side/vfs/).\n\n## `pageBreakBefore` aktualisieren\n\nVersion 0.1/0.2 übergab separate Knoten-Arrays. Version 0.3 übergibt einen Knotenkontainer:\n\n**JavaScript**\n\n```js\nvar dd = { content: ['Example document'],\npageBreakBefore: function (currentNode, nodeContainer) {\n return currentNode.headlineLevel === 1 &&\n nodeContainer.getFollowingNodesOnPage().length === 0;\n}\n};\n```\n\n**TypeScript**\n\n```ts\nimport type { TDocumentDefinitions } from \"pdfmake/interfaces\";\n\nvar dd: TDocumentDefinitions = { content: ['Example document'],\npageBreakBefore: function (currentNode, nodeContainer) {\n return currentNode.headlineLevel === 1 &&\n nodeContainer.getFollowingNodesOnPage().length === 0;\n}\n};\n```\n\nDer Kontainer bietet außerdem `getNodesOnNextPage()` und `getPreviousNodesOnPage()`. Dieses Snippet ist eine Eigenschaft innerhalb einer Definition, kein eigenständiges JavaScript. Siehe [Seitenumbrüche](/docs/0.3/de/document-definition-object/page/).\n\n## Ressourcenzugriff konfigurieren\n\nKonfiguriere für **0.3.6+** eine synchrone URL-Zugriffsrichtlinie und für **0.3.8+** eine Richtlinie für lokale Dateien. Prüfe sowohl erlaubte als auch abgelehnte Ressourcen. Siehe [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/).\n"
+ },
+ {
+ "id": "de/options",
+ "language": "de",
+ "translationKey": "options",
+ "path": "/docs/0.3/de/options/",
+ "title": "Rendering-Optionen",
+ "description": "Steuere den Font-Layout-Cache und die Seitenausgabe von PDFKit über das zweite Argument von createPdf.",
+ "version": "0.3",
+ "sourceDigest": "fa3eacf7dfb3dc985a1eb6cf541fdccb9dae9648d423d3d758d78b70eabb4882",
+ "source": "options/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/options/",
+ "uri": "pdfmake://docs/0.3/de/options",
+ "markdown": "# Rendering-Optionen\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/options/\n\n## Optionen an `createPdf` übergeben\n\n**JavaScript**\n\n```js\nconst output = pdfmake.createPdf(docDefinition, {\n fontLayoutCache: true,\n bufferPages: false\n});\n```\n\n**TypeScript**\n\n```ts\nconst output = pdfmake.createPdf(docDefinition, {\n fontLayoutCache: true,\n bufferPages: false\n});\n```\n\nDas Optionsobjekt ist getrennt von der [Dokumentdefinition](/docs/0.3/de/document-definition-object/).\n\n| Option | Typ | Standard | Bedeutung |\n| --- | --- | --- | --- |\n| `fontLayoutCache` | boolean | `true` | Font-Layout-Cache von PDFKit aktivieren |\n| `bufferPages` | boolean | `false` | PDFKit-Seiten puffern, statt sie sofort auszugeben |\n\nBehalte die Standardwerte bei, sofern dein Anwendungsfall keine Änderung erfordert. Das Puffern von Seiten kann den Speicherverbrauch erhöhen. Es macht das Layout von pdfmake nicht verzögert oder inkrementell. Siehe [Leistung](/docs/0.3/de/guides/performance/) und die [Dokumentation zur Seitenausgabe von PDFKit](https://pdfkit.org/docs/getting_started.html).\n\nSchriften, benannte Tabellenlayouts und Ressourcenrichtlinien werden über die [öffentliche API](/docs/0.3/de/guides/api-reference/) konfiguriert. Papierformat, Ränder und Inhalt gehören in die Definition.\n"
+ },
+ {
+ "id": "de/playground",
+ "language": "de",
+ "translationKey": "playground",
+ "path": "/docs/0.3/de/playground/",
+ "title": "Playground",
+ "description": "Bearbeite deine Dokumentdefinition und sieh dir das Ergebnis an. Dein Arbeitsbereich bleibt beim Navigieren erhalten.",
+ "version": "0.3",
+ "sourceDigest": "ed2dd49083b941d64363a1d15bce73210d644f055b742e90c21f85226e5ee75f",
+ "source": "playground/_index.de.md",
+ "url": "https://pdfmake.github.io/docs/0.3/de/playground/",
+ "uri": "pdfmake://docs/0.3/de/playground",
+ "markdown": "# Playground\n\nVersion: pdfmake 0.3.x\nLanguage: de\nSource: https://pdfmake.github.io/docs/0.3/de/playground/\n\nProbiere das Beispiel aus und lies anschließend weiter.\n"
+ }
+ ]
+}
diff --git a/static/de/llms-full.txt b/static/de/llms-full.txt
new file mode 100644
index 00000000..ac29afd0
--- /dev/null
+++ b/static/de/llms-full.txt
@@ -0,0 +1,4959 @@
+# Übersicht
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/
+
+Erstelle eine PDF in drei Schritten: Laufzeit einrichten, Inhalt beschreiben und Ausgabe anfordern.
+
+## 1. Laufzeit auswählen
+
+
+
+
+Verwende Node.js 20 oder neuer. Installiere die folgende feste Version, speichere das vollständige Beispiel als `first-pdf.cjs` und starte `node first-pdf.cjs`.
+
+```sh
+npm install pdfmake@0.3.13
+```
+
+**JavaScript**
+
+```js
+const pdfmake = require('pdfmake');
+
+const fonts = require('pdfmake/standard-fonts/Helvetica');
+pdfmake.addFonts(fonts);
+pdfmake.setUrlAccessPolicy(() => false);
+const standardNames = new Set(Object.values(fonts.Helvetica));
+pdfmake.setLocalAccessPolicy(name => standardNames.has(name));
+
+async function main() {
+ const definition = {
+ defaultStyle: { font: 'Helvetica' },
+ content: [
+ { text: 'Hello, pdfmake!', fontSize: 24, bold: true },
+ 'Your first PDF, generated in Node.js.'
+ ]
+ };
+ await pdfmake.createPdf(definition).write('document.pdf');
+}
+
+main().catch(error => { console.error(error); process.exitCode = 1; });
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+import pdfmake from "pdfmake";
+
+const fonts = require('pdfmake/standard-fonts/Helvetica');
+pdfmake.addFonts(fonts);
+pdfmake.setUrlAccessPolicy(() => false);
+const standardNames = new Set(Object.values(fonts.Helvetica));
+pdfmake.setLocalAccessPolicy(name => standardNames.has(name));
+
+async function main() {
+ const definition: TDocumentDefinitions = {
+ defaultStyle: { font: 'Helvetica' },
+ content: [
+ { text: 'Hello, pdfmake!', fontSize: 24, bold: true },
+ 'Your first PDF, generated in Node.js.'
+ ]
+ };
+ await pdfmake.createPdf(definition).write('document.pdf');
+}
+
+main().catch(error => { console.error(error); process.exitCode = 1; });
+```
+
+[Node.js-Schnellstart](/docs/0.3/de/getting-started/server-side/)
+
+
+
+
+Im Browser brauchst du Engine und Schriften in dieser Reihenfolge. Der vollständige Schnellstart enthält einen Download-Button und Fehlerbehandlung.
+
+[Browser-Schnellstart](/docs/0.3/de/getting-started/client-side/)
+
+
+
+## 2. Die Definition verstehen
+
+Die Definition ist ein JavaScript-Objekt, kein HTML. `content` enthält Blöcke in Lesereihenfolge. Dieses Beispiel erzeugt genau die sichtbare PDF. Bearbeite es im Playground und kehre hierher zurück, ohne deinen Arbeitsbereich zu verlieren.
+
+
+
+### Runnable example: 01 · First document
+
+**JavaScript**
+
+```js
+// Define a fresh document in dd. Ctrl/⌘ + Enter to run.
+var dd = {
+ content: [
+ { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },
+ 'A paragraph, a table, a report. Start here and make it yours.',
+ { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+// Define a fresh document in dd. Ctrl/⌘ + Enter to run.
+var dd: TDocumentDefinitions = {
+ content: [
+ { text: 'Make something clear.', fontSize: 30, bold: true, color: '#08786b', margin: [0, 0, 0, 16] },
+ 'A paragraph, a table, a report. Start here and make it yours.',
+ { text: 'Built with pdfmake', italics: true, color: '#667d73', margin: [0, 20, 0, 0] }
+ ]
+};
+```
+
+[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=welcome)
+
+
+
+## 3. Mit dem passenden Baustein weitermachen
+
+- [Deine erste PDF](/docs/0.3/de/learn/first-pdf/)
+- [Das Dokumentmodell](/docs/0.3/de/learn/document-model/)
+- [Stile und Formatierung](/docs/0.3/de/document-definition-object/styling/)
+- [Tabellen](/docs/0.3/de/document-definition-object/tables/)
+- [Schriften und Zeichensätze](/docs/0.3/de/fonts/)
+- [Fehler erkennen und behandeln](/docs/0.3/de/guides/errors/)
+
+Verwende bei jeder Generierung eine neue Definition, weil das Layout das Objekt verändert. Ausgabemethoden liefern Promises: Warte mit `await` und behandle Fehler.
+
+---
+
+# Referenz zur Dokumentdefinition
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/
+
+## Aufbau einer Definition
+
+**JavaScript**
+
+```js
+const docDefinition = {
+ pageSize: 'A4',
+ pageOrientation: 'portrait',
+ pageMargins: [40, 50, 40, 50],
+ defaultStyle: { fontSize: 12 },
+ styles: { heading: { fontSize: 20, bold: true } },
+ info: { title: 'Example document', author: 'Example author' },
+ content: [
+ { text: 'Document heading', style: 'heading' },
+ 'A plain string becomes a paragraph.',
+ { ul: ['First item', 'Second item'] }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+const docDefinition: TDocumentDefinitions = {
+ pageSize: 'A4',
+ pageOrientation: 'portrait',
+ pageMargins: [40, 50, 40, 50],
+ defaultStyle: { fontSize: 12 },
+ styles: { heading: { fontSize: 20, bold: true } },
+ info: { title: 'Example document', author: 'Example author' },
+ content: [
+ { text: 'Document heading', style: 'heading' },
+ 'A plain string becomes a paragraph.',
+ { ul: ['First item', 'Second item'] }
+ ]
+};
+```
+
+Übergib die Definition nach der Schriftkonfiguration an die `createPdf`-Methode deiner Laufzeit. Alle numerischen Maße werden in **Punkten** angegeben (72 Punkte pro Zoll). Die Reihenfolge der Seitenränder ist **links, oben, rechts, unten**. Ein `content`-Array bildet einen vertikalen Stapel. Erzeuge für jeden Renderdurchlauf ein neues Objekt; beim Layout werden interne Messwerte und Positionen hinzugefügt.
+
+## Inhaltsknoten
+
+| Knoten | Zweck | Referenz |
+| --- | --- | --- |
+| `{ text: '...' }` | Absatz oder Inline-Textsegmente | [Stile](/docs/0.3/de/document-definition-object/styling/) |
+| `{ stack: [...] }` | Blöcke gruppieren und einen gemeinsamen Stil anwenden | [Stapel](/docs/0.3/de/document-definition-object/stack/) |
+| `{ columns: [...] }` | Inhalte nebeneinander anordnen | [Spalten](/docs/0.3/de/document-definition-object/columns/) |
+| `{ table: { body: [...] } }` | Zeilen, Zellen und wiederholte Kopfzeilen | [Tabellen](/docs/0.3/de/document-definition-object/tables/) |
+| `{ ul: [...] }`, `{ ol: [...] }` | Aufzählungs- und nummerierte Listen | [Listen](/docs/0.3/de/document-definition-object/lists/) |
+| `{ image: 'key' }` | PNG oder JPEG | [Bilder](/docs/0.3/de/document-definition-object/images/) |
+| `{ svg: '... ' }` | SVG-Vektorgrafik | [SVGs](/docs/0.3/de/document-definition-object/svgs/) |
+| `{ qr: '...' }` | QR-Code | [QR-Code](/docs/0.3/de/document-definition-object/qr/) |
+
+## Dokumentweite Einstellungen
+
+- [Seitengröße, Ausrichtung und Umbrüche](/docs/0.3/de/document-definition-object/page/), [Ränder](/docs/0.3/de/document-definition-object/margins/) und [Abschnitte](/docs/0.3/de/document-definition-object/sections/).
+- [Kopf- und Fußzeilen](/docs/0.3/de/document-definition-object/headers-footers/), [Hintergründe](/docs/0.3/de/document-definition-object/background-layer/) und [Wasserzeichen](/docs/0.3/de/document-definition-object/watermark/).
+- [Metadaten](/docs/0.3/de/document-definition-object/document-medatadata/), [Links](/docs/0.3/de/document-definition-object/links/), [Inhaltsverzeichnis](/docs/0.3/de/document-definition-object/toc/) und [Gliederungen](/docs/0.3/de/document-definition-object/outlines/).
+- [Anhänge](/docs/0.3/de/document-definition-object/attachments/), [Verschlüsselung](/docs/0.3/de/document-definition-object/security/), [PDF/A](/docs/0.3/de/document-definition-object/pdfa/) und [Komprimierung](/docs/0.3/de/document-definition-object/compression/).
+
+## Definition und Rendering-Optionen
+
+Inhalt und visuelle Einstellungen gehören in die Definition. `fontLayoutCache` und `bufferPages` gehören in das zweite Argument von `createPdf`. Schriften, Tabellenlayoutregistrierungen und Ressourcenrichtlinien werden über die pdfmake-API festgelegt. Siehe [API-Übersicht](/docs/0.3/de/guides/api-reference/).
+
+---
+
+# Dateianhänge einbetten
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/attachments/
+
+pdfmake unterstützt sowohl Dateianhänge als Anmerkungen als auch eingebettete Dateien. Eingebettete Dateien werden dem Wörterbuch `files` hinzugefügt und erscheinen in den Anhangbereichen unterstützter PDF-Viewer.
+
+Dateianhänge sind Anmerkungen, die auf eine Datei verweisen.
+
+Jeder Anhang und jede eingebettete Datei muss mindestens `src` angeben. Es wird dringend empfohlen, über `name` einen Dateinamen anzugeben.
+
+Der `src` eines Anhangs kann als Data-URL angegeben werden (wie beim folgenden Anhang von http://www.clipartbest.com/clipart-dT7zx5rT9); lokale Dateien sind ebenfalls möglich.
+
+**JavaScript**
+
+```js
+var dd = {
+ content: [
+ 'Any attachment or embedded file must provide at least a "src", providing a filename through "name" is highly recommended.',
+ 'The "src" of any attachment can be provided in dataURL format (like the following attachment, taken from http://www.clipartbest.com/clipart-dT7zx5rT9), but local files are allowed as well.',
+ {
+ attachment: {
+ src: 'data:image/png;base64,iVBOR....',
+ name: 'testImage.png'
+ }
+ },
+ 'You can also define an attachment in the "attachments" dictionary and reference it by name.',
+ {
+ attachment: 'sampleImage'
+ },
+ 'And there are three different standard icons for attachments, "GraphPush", "Paperclip", and "Push" (the default value). Set them with the "icon" option.',
+ {
+ attachment: 'sampleImage',
+ icon: 'GraphPush'
+ },
+ {
+ attachment: 'sampleImage',
+ icon: 'Paperclip'
+ },
+ {
+ attachment: 'sampleImage',
+ icon: 'Push'
+ },
+ 'For better customization, add an image and attach a file to it with linkToFile:',
+ {
+ image: 'fonts/sampleImage.jpg',
+ width: 150,
+ linkToFile: 'sampleImage'
+ },
+ "You can add a description, which will show in your pdf viewer's attachments panel and as a tooltip when hovering over the attachment.",
+ {
+ attachment: {
+ src: 'data:image/png;base64,iVBOR....',
+ name: 'withDescription.png',
+ description: 'file description'
+ }
+ },
+ 'You can also define the "src" of an attachment or embedded file in the "attachments" and "files" dictionary via URL address.',
+ ],
+ attachments: {
+ sampleImage: {
+ src: 'fonts/sampleImage.jpg',
+ name: 'sampleImage.png'
+ }
+ },
+ files: {
+ README: {
+ src: 'https://raw.githubusercontent.com/bpampuch/pdfmake/master/README.md',
+ name: 'pdfmake README.md'
+ }
+ }
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ content: [
+ 'Any attachment or embedded file must provide at least a "src", providing a filename through "name" is highly recommended.',
+ 'The "src" of any attachment can be provided in dataURL format (like the following attachment, taken from http://www.clipartbest.com/clipart-dT7zx5rT9), but local files are allowed as well.',
+ {
+ attachment: {
+ src: 'data:image/png;base64,iVBOR....',
+ name: 'testImage.png'
+ }
+ },
+ 'You can also define an attachment in the "attachments" dictionary and reference it by name.',
+ {
+ attachment: 'sampleImage'
+ },
+ 'And there are three different standard icons for attachments, "GraphPush", "Paperclip", and "Push" (the default value). Set them with the "icon" option.',
+ {
+ attachment: 'sampleImage',
+ icon: 'GraphPush'
+ },
+ {
+ attachment: 'sampleImage',
+ icon: 'Paperclip'
+ },
+ {
+ attachment: 'sampleImage',
+ icon: 'Push'
+ },
+ 'For better customization, add an image and attach a file to it with linkToFile:',
+ {
+ image: 'fonts/sampleImage.jpg',
+ width: 150,
+ linkToFile: 'sampleImage'
+ },
+ "You can add a description, which will show in your pdf viewer's attachments panel and as a tooltip when hovering over the attachment.",
+ {
+ attachment: {
+ src: 'data:image/png;base64,iVBOR....',
+ name: 'withDescription.png',
+ description: 'file description'
+ }
+ },
+ 'You can also define the "src" of an attachment or embedded file in the "attachments" and "files" dictionary via URL address.',
+ ],
+ attachments: {
+ sampleImage: {
+ src: 'fonts/sampleImage.jpg',
+ name: 'sampleImage.png'
+ }
+ },
+ files: {
+ README: {
+ src: 'https://raw.githubusercontent.com/bpampuch/pdfmake/master/README.md',
+ name: 'pdfmake README.md'
+ }
+ }
+};
+```
+
+---
+
+# Hintergrundebene
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/background-layer/
+
+Die Hintergrundebene wird auf jeder Seite eingefügt.
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ background: 'simple text',
+
+ content: ['Example document content']
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ background: 'simple text',
+
+ content: ['Example document content']
+};
+```
+
+Sie kann auch jedes andere Objekt enthalten (Bilder, Tabellen usw.) oder dynamisch erzeugt werden:
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ background: function(currentPage, pageSize) {
+ return `page ${currentPage} with size ${pageSize.width} x ${pageSize.height}`
+ },
+
+ content: ['Example document content']
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ background: function(currentPage, pageSize) {
+ return `page ${currentPage} with size ${pageSize.width} x ${pageSize.height}`
+ },
+
+ content: ['Example document content']
+};
+```
+
+---
+
+# Spalten
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/columns/
+
+Absätze werden standardmäßig als vertikaler Stapel von Elementen ausgegeben. Du kannst den verfügbaren Platz jedoch auch in Spalten aufteilen.
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ content: [
+ 'This paragraph fills full width, as there are no columns. Next paragraph however consists of three columns',
+ {
+ columns: [
+ {
+ // auto-sized columns have their widths based on their content
+ width: 'auto',
+ text: 'First column'
+ },
+ {
+ // star-sized columns fill the remaining space
+ // if there's more than one star-column, available width is divided equally
+ width: '*',
+ text: 'Second column'
+ },
+ {
+ // fixed width
+ width: 100,
+ text: 'Third column'
+ },
+ {
+ // % width
+ width: '20%',
+ text: 'Fourth column'
+ }
+ ],
+ // optional space between columns
+ columnGap: 10
+ },
+ 'This paragraph goes below all columns and has full width'
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ content: [
+ 'This paragraph fills full width, as there are no columns. Next paragraph however consists of three columns',
+ {
+ columns: [
+ {
+ // auto-sized columns have their widths based on their content
+ width: 'auto',
+ text: 'First column'
+ },
+ {
+ // star-sized columns fill the remaining space
+ // if there's more than one star-column, available width is divided equally
+ width: '*',
+ text: 'Second column'
+ },
+ {
+ // fixed width
+ width: 100,
+ text: 'Third column'
+ },
+ {
+ // % width
+ width: '20%',
+ text: 'Fourth column'
+ }
+ ],
+ // optional space between columns
+ columnGap: 10
+ },
+ 'This paragraph goes below all columns and has full width'
+ ]
+};
+```
+
+Der Inhalt einer Spalte ist nicht auf einfachen Text beschränkt. Er kann jedes gültige pdfmake-Element enthalten. Sieh dir dazu das Beispiel COLUMNS im [Playground](/docs/0.3/de/playground/) an.
+
+## Eigenschaften
+
+* `columnGap: number` legt den Abstand zwischen Spalten fest.
+* `snakingColumns: boolean` aktiviert Spalten im Zeitungsstil. Siehe [diesen Artikel](/docs/0.3/de/document-definition-object/snaking-columns/) _(Mindestversion: 0.3.5)_
+
+---
+
+# Komprimierung
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/compression/
+
+## Standardverhalten
+
+PDF-Datenströme werden standardmäßig komprimiert. So deaktivierst du die Komprimierung zur Überprüfung:
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ compress: false,
+ content: ['An uncompressed example document.']
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ compress: false,
+ content: ['An uncompressed example document.']
+};
+```
+
+`compress` ist ein boolesches Feld der Dokumentdefinition und gehört nicht zum Optionsobjekt von `createPdf`. Wenn du die Komprimierung deaktivierst, wird die Ausgabedatei in der Regel größer. Eingebettete Schriften oder Bilddaten werden dadurch nicht entfernt; auch der für das Layout benötigte Speicher wird nicht reduziert. Hinweise zur Messung findest du unter [Leistung](/docs/0.3/de/guides/performance/).
+
+---
+
+# Dokumentmetadaten
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/document-medatadata/
+
+PDF-Dokumente können verschiedene Metadaten enthalten, beispielsweise Titel und Autor. Füge diese Angaben der Dokumentdefinition hinzu:
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ info: {
+ title: 'awesome Document',
+ author: 'john doe',
+ subject: 'subject of document',
+ keywords: 'keywords for document',
+ },
+ content: 'This is an sample PDF printed with pdfMake'
+}
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ info: {
+ title: 'awesome Document',
+ author: 'john doe',
+ subject: 'subject of document',
+ keywords: 'keywords for document',
+ },
+ content: 'This is an sample PDF printed with pdfMake'
+}
+```
+
+Standardfelder:
+
+* `title` – Titel des Dokuments
+* `author` – Name des Autors
+* `subject` – Thema des Dokuments
+* `keywords` – mit dem Dokument verknüpfte Schlüsselwörter
+* `creator` – Ersteller (Standard ist `'pdfmake'`)
+* `producer` – erzeugende Software (Standard ist `'pdfmake'`)
+* `creationDate` – Erstellungsdatum (wird automatisch von pdfmake hinzugefügt)
+* `modDate` – Datum der letzten Änderung
+* `trapped` – Kennzeichen, das angibt, ob das Dokument für den Druck durch Farbkorrekturen (Trapping) vorbereitet wurde
+
+Benutzerdefinierte Felder:
+
+Du kannst benutzerdefinierte Felder hinzufügen. Der Feldschlüssel darf keine Leerzeichen enthalten.
+
+## Dokumentsprache
+
+Über die Eigenschaft `language` kannst du eine Sprache für das PDF-Dokument festlegen.
+
+Beispiel:
+**JavaScript**
+
+```js
+var docDefinition = {
+ language: 'cs-CZ',
+ content: 'Jednoduchý PDF dokument vytvoření pomocí pdfmake'
+}
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ language: 'cs-CZ',
+ content: 'Jednoduchý PDF dokument vytvoření pomocí pdfmake'
+}
+```
+
+---
+
+# Kopf- und Fußzeilen
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/headers-footers/
+
+## Statische Kopfzeile hinzufügen
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ pageMargins: [40, 65, 40, 55],
+ header: { text: 'Example report', margin: [40, 20, 40, 0] },
+ footer: { text: 'Example Studio', alignment: 'center', fontSize: 9 },
+ content: ['Document content']
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ pageMargins: [40, 65, 40, 55],
+ header: { text: 'Example report', margin: [40, 20, 40, 0] },
+ footer: { text: 'Example Studio', alignment: 'center', fontSize: 9 },
+ content: ['Document content']
+};
+```
+
+Kopf- und Fußzeilen werden auf den Seiten wiederholt. Reserviere in den oberen und unteren Rändern genügend Platz für ihren Inhalt; die Ränder des Hauptinhalts werden nicht automatisch vergrößert. Zurückgegebener Inhalt verwendet normale pdfmake-Knoten.
+
+## Seitenzahlen hinzufügen
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ pageMargins: [40, 65, 40, 55],
+ header: function (currentPage, pageCount, pageSize) {
+ return {
+ text: 'Report · ' + pageSize.width + ' pt wide',
+ alignment: currentPage % 2 ? 'left' : 'right',
+ margin: [40, 20, 40, 0],
+ fontSize: 9
+ };
+ },
+ footer: function (currentPage, pageCount) {
+ return { text: currentPage + ' of ' + pageCount, alignment: 'center', fontSize: 9 };
+ },
+ content: ['First page', { text: 'Second page', pageBreak: 'before' }]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ pageMargins: [40, 65, 40, 55],
+ header: function (currentPage, pageCount, pageSize) {
+ return {
+ text: 'Report · ' + pageSize.width + ' pt wide',
+ alignment: currentPage % 2 ? 'left' : 'right',
+ margin: [40, 20, 40, 0],
+ fontSize: 9
+ };
+ },
+ footer: function (currentPage, pageCount) {
+ return { text: currentPage + ' of ' + pageCount, alignment: 'center', fontSize: 9 };
+ },
+ content: ['First page', { text: 'Second page', pageBreak: 'before' }]
+};
+```
+
+Callbacks erhalten die aktuelle Seitennummer (beginnend bei 1), die Gesamtseitenzahl und die Seitengröße. Gib bei jedem Aufruf einen neuen Knoten zurück. Sorge für deterministische Callbacks und vermeide Änderungen an gemeinsam genutzten Anwendungsdaten.
+
+---
+
+# Bilder
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/images/
+
+## Eingebettete PNG- oder JPEG-Daten wiederverwenden
+
+Ein Bildknoten hat die Form `{ image: 'key' }`; der Schlüssel verweist auf einen Eintrag im Wörterbuch `images`. Verwende denselben Schlüssel, wenn ein Bild mehrfach vorkommt. Unterstützt werden PNG und JPEG. Für SVG-Inhalte verwende einen [SVG-Knoten](/docs/0.3/de/document-definition-object/svgs/).
+
+
+
+### Runnable example: 09 · Embedded images
+
+**JavaScript**
+
+```js
+var dd = {
+ images: { pixel: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAF0lEQVR4nGPgqMgmCTGMahjVkD1sNQAAjRnrAVbW+rcAAAAASUVORK5CYII=' },
+ content: [
+ { text: 'One resource, several uses', fontSize: 24, bold: true, margin: [0, 0, 0, 18] },
+ 'Use the images dictionary to reuse embedded PNG or JPEG data.',
+ { image: 'pixel', width: 30, margin: [0, 15, 0, 15] },
+ { image: 'pixel', fit: [60, 60] }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ images: { pixel: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAF0lEQVR4nGPgqMgmCTGMahjVkD1sNQAAjRnrAVbW+rcAAAAASUVORK5CYII=' },
+ content: [
+ { text: 'One resource, several uses', fontSize: 24, bold: true, margin: [0, 0, 0, 18] },
+ 'Use the images dictionary to reuse embedded PNG or JPEG data.',
+ { image: 'pixel', width: 30, margin: [0, 15, 0, 15] },
+ { image: 'pixel', fit: [60, 60] }
+ ]
+};
+```
+
+[See the rendered PDF and edit this example](https://pdfmake.github.io/docs/0.3/de/playground/?example=images)
+
+
+
+## Skalierung festlegen
+
+| Felder des Bildknotens | Ergebnis |
+| --- | --- |
+| Keine Angabe von width, height oder fit | Natürliche Abmessungen des Bildes verwenden |
+| `width: 150` | Proportional auf diese Breite skalieren |
+| `height: 100` | Proportional auf diese Höhe skalieren; seit 0.3.2 |
+| `width: 150, height: 100` | Diese Abmessungen erzwingen; das Bild kann dadurch gestreckt werden |
+| `fit: [150, 100]` | In ein Rechteck einpassen und Seitenverhältnis beibehalten |
+| `cover: { width: 150, height: 100, align: 'right', valign: 'bottom' }` | Rechteck mit Bild füllen, zuschneiden und ausrichten |
+
+Die angezeigten Abmessungen verkleinern nicht die ursprünglichen Bilddaten. Skaliere übergroße Quelldateien vor dem Einbetten, wenn Ausgabegröße und Speicherverbrauch wichtig sind.
+
+## Quelle für deine Laufzeit auswählen
+
+| Quelle | Einrichtung |
+| --- | --- |
+| Data-URL | Vollständige PNG-/JPEG-Base64-Data-URL in `images` oder direkt im Knoten angeben |
+| Lokale Datei | Nur Node.js oder eine Datei, die bereits im Browser-VFS liegt |
+| HTTP(S)-URL | Benannten Eintrag in `images` verwenden und über die Ressourcenrichtlinie freigeben |
+| URL mit Headern | `{ url, headers }` im benannten Eintrag unter `images` verwenden |
+
+**JavaScript**
+
+```js
+var dd = {
+ images: {
+ logo: '/application-owned/assets/logo.png',
+ remote: {
+ url: 'https://assets.example.com/photo.jpg',
+ headers: { 'X-Example-Header': 'value' }
+ }
+ },
+ content: [
+ { image: 'logo', width: 120 },
+ { image: 'remote', fit: [200, 150] }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ images: {
+ logo: '/application-owned/assets/logo.png',
+ remote: {
+ url: 'https://assets.example.com/photo.jpg',
+ headers: { 'X-Example-Header': 'value' }
+ }
+ },
+ content: [
+ { image: 'logo', width: 120 },
+ { image: 'remote', fit: [200, 150] }
+ ]
+};
+```
+
+Dieses Snippet zeigt die Formen der Quellen, ist aber kein eigenständiges Beispiel zum Herunterladen. Stelle eine vorhandene, von deiner Anwendung verwaltete Datei und eine gültige, freigegebene URL bereit. Im Browser muss die lokale Datei im VFS vorhanden sein; Browser-URLs benötigen außerdem CORS-Unterstützung. Füge keine privaten Zugangsdaten in clientseitige Definitionen ein. Das oben gezeigte eingebettete Beispiel benötigt keine Netzwerkressource.
+
+## Fehlende Bilder untersuchen
+
+Ein leerer oder ungültiger Bildwert führt zu einem Fehler. Prüfe den Wörterbuchschlüssel, das vollständige Data-URL-Präfix und die Datenbytes, das Vorhandensein der Datei, die URL-Antwort und die Zugriffsrichtlinie. `setUrlAccessPolicy` umgeht CORS nicht. Eine lokale Dateirichtlinie muss den tatsächlich aufgelösten Dateipfad erlauben. Siehe [Ressourcensicherheit](/docs/0.3/de/guides/resource-security/) und [Fehlerbehebung](/docs/0.3/de/guides/troubleshooting/).
+
+---
+
+# Links
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/links/
+
+Für externe oder interne Links verwendest du die folgende Syntax:
+**JavaScript**
+
+```js
+var dd = { content: [
+{ text: 'google', link: 'http://google.com' },
+{ text: 'Go to page 2', linkToPage: 2 },
+{ text: 'Go to Header', linkToDestination: 'header' },
+{ text: 'Header content', id: 'header' },
+] };
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = { content: [
+{ text: 'google', link: 'http://google.com' },
+{ text: 'Go to page 2', linkToPage: 2 },
+{ text: 'Go to Header', linkToDestination: 'header' },
+{ text: 'Header content', id: 'header' },
+] };
+```
+Oder du verlinkst eine lokale Datei auf dem Computer:
+**JavaScript**
+
+```js
+var dd = {
+ content: [
+ {
+ text: 'link',
+ link: 'file:///c:/testFile.txt'
+ }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ content: [
+ {
+ text: 'link',
+ link: 'file:///c:/testFile.txt'
+ }
+ ]
+};
+```
+
+## Eigenschaften
+
+- `link` (`string`) – URL zu einer externen Website
+- `linkToPage` (`number`) – Link zu einer Seitennummer
+- `linkToDestination` (`string`) – Link zu einem Dokumentziel
+
+---
+
+# Listen
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/lists/
+
+pdfmake unterstützt sowohl nummerierte Listen als auch Aufzählungslisten:
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ content: [
+ 'Bulleted list example:',
+ {
+ // to treat a paragraph as a bulleted list, set an array of items under the ul key
+ ul: [
+ 'Item 1',
+ 'Item 2',
+ 'Item 3',
+ { text: 'Item 4', bold: true },
+ ]
+ },
+
+ 'Numbered list example:',
+ {
+ // for numbered lists set the ol key
+ ol: [
+ 'Item 1',
+ 'Item 2',
+ 'Item 3'
+ ]
+ },
+
+ 'Colored unordered list:',
+ {
+ color: 'blue',
+ ul: [
+ 'item 1',
+ 'item 2',
+ 'item 3'
+ ]
+ },
+
+ 'Colored unordered list with own marker color:',
+ {
+ color: 'blue',
+ markerColor: 'red',
+ ul: [
+ 'item 1',
+ 'item 2',
+ { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2
+ ]
+ },
+
+ 'Colored ordered list',
+ {
+ color: 'blue',
+ ol: [
+ 'item 1',
+ 'item 2',
+ 'item 3'
+ ]
+ },
+ 'Colored ordered list with own marker color:',
+ {
+ color: 'blue',
+ markerColor: 'red',
+ ol: [
+ 'item 1',
+ 'item 2',
+ { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2
+ ]
+ },
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ content: [
+ 'Bulleted list example:',
+ {
+ // to treat a paragraph as a bulleted list, set an array of items under the ul key
+ ul: [
+ 'Item 1',
+ 'Item 2',
+ 'Item 3',
+ { text: 'Item 4', bold: true },
+ ]
+ },
+
+ 'Numbered list example:',
+ {
+ // for numbered lists set the ol key
+ ol: [
+ 'Item 1',
+ 'Item 2',
+ 'Item 3'
+ ]
+ },
+
+ 'Colored unordered list:',
+ {
+ color: 'blue',
+ ul: [
+ 'item 1',
+ 'item 2',
+ 'item 3'
+ ]
+ },
+
+ 'Colored unordered list with own marker color:',
+ {
+ color: 'blue',
+ markerColor: 'red',
+ ul: [
+ 'item 1',
+ 'item 2',
+ { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2
+ ]
+ },
+
+ 'Colored ordered list',
+ {
+ color: 'blue',
+ ol: [
+ 'item 1',
+ 'item 2',
+ 'item 3'
+ ]
+ },
+ 'Colored ordered list with own marker color:',
+ {
+ color: 'blue',
+ markerColor: 'red',
+ ol: [
+ 'item 1',
+ 'item 2',
+ { text: 'item 3 with custom marker color', markerColor: 'lime' } // Minimal pdfmake version: 0.3.2
+ ]
+ },
+ ]
+};
+```
+
+---
+
+# Abstände
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/margins/
+
+Jedes Element in pdfMake kann einen Abstand haben:
+
+**JavaScript**
+
+```js
+var dd = { content: [
+// margin: [left, top, right, bottom]
+{ text: 'sample', margin: [ 5, 2, 10, 20 ] },
+
+// margin: [horizontal, vertical]
+{ text: 'another text', margin: [5, 2] },
+
+// margin: equalLeftTopRightBottom
+{ text: 'last one', margin: 5 },
+
+// single-side margins
+{ text: 'sample', marginLeft: 5, marginTop: 2, marginRight: 10, marginBottom: 2 },
+] };
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = { content: [
+// margin: [left, top, right, bottom]
+{ text: 'sample', margin: [ 5, 2, 10, 20 ] },
+
+// margin: [horizontal, vertical]
+{ text: 'another text', margin: [5, 2] },
+
+// margin: equalLeftTopRightBottom
+{ text: 'last one', margin: 5 },
+
+// single-side margins
+{ text: 'sample', marginLeft: 5, marginTop: 2, marginRight: 10, marginBottom: 2 },
+] };
+```
+
+---
+
+# Gliederungen und Lesezeichen
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/outlines/
+
+> **Note:** Mindestversion: **0.3.5**
+
+
+PDF-Gliederungen (auch Lesezeichen genannt) sind eine hierarchische Navigationsstruktur im PDF-Dokument. Damit können Benutzer direkt zu bestimmten Seiten springen. Sie funktionieren wie ein interaktives Inhaltsverzeichnis und werden normalerweise im Navigationsbereich des PDF-Viewers angezeigt.
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ content: [
+ {
+ text: 'First header in bookmarks',
+ outline: true,
+ },
+ {
+ text: 'Second header with custom bookmark',
+ outline: true,
+ outlineText: 'Custom bookmark text',
+ },
+ {
+ text: 'Structured bookmarks',
+ id: 'structured-bookmarks',
+ outline: true,
+ outlineExpanded: true
+ },
+ {
+ text: 'First subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks'
+ },
+ {
+ text: 'Second subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks'
+ },
+ {
+ text: 'Third subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks',
+ id: 'third-subheader'
+ }
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ content: [
+ {
+ text: 'First header in bookmarks',
+ outline: true,
+ },
+ {
+ text: 'Second header with custom bookmark',
+ outline: true,
+ outlineText: 'Custom bookmark text',
+ },
+ {
+ text: 'Structured bookmarks',
+ id: 'structured-bookmarks',
+ outline: true,
+ outlineExpanded: true
+ },
+ {
+ text: 'First subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks'
+ },
+ {
+ text: 'Second subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks'
+ },
+ {
+ text: 'Third subheader',
+ outline: true,
+ outlineParentId: 'structured-bookmarks',
+ id: 'third-subheader'
+ }
+ ]
+};
+```
+
+## Eigenschaften
+
+- `outline: boolean` – auf `true` setzen, um den Knoten in die Lesezeichen aufzunehmen
+- `outlineText: string` (optional) – benutzerdefinierter Lesezeichentext; andernfalls wird der Text des Knotens verwendet
+- `outlineExpanded: boolean` (optional) – auf `true` setzen, damit das Lesezeichen geöffnet angezeigt wird
+- `outlineParentId: string` (optional) – `id` des übergeordneten Lesezeichens
+
+---
+
+# Seitengröße, Ausrichtung und Ränder
+
+Version: pdfmake 0.3.x
+Language: de
+Source: https://pdfmake.github.io/docs/0.3/de/document-definition-object/page/
+
+**JavaScript**
+
+```js
+var docDefinition = {
+ // a string or { width: number, height: number }
+ pageSize: 'A5',
+
+ // by default we use portrait, you can change it to landscape if you wish
+ pageOrientation: 'landscape',
+
+ // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins
+ pageMargins: [ 40, 60, 40, 60 ],
+ content: ['Page size, orientation and margins.']
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var docDefinition: TDocumentDefinitions = {
+ // a string or { width: number, height: number }
+ pageSize: 'A5',
+
+ // by default we use portrait, you can change it to landscape if you wish
+ pageOrientation: 'landscape',
+
+ // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins
+ pageMargins: [ 40, 60, 40, 60 ],
+ content: ['Page size, orientation and margins.']
+};
+```
+
+Wenn du `pageSize` als Zeichenfolge festlegst, kannst du einen der folgenden Werte verwenden:
+
+* `'4A0'`, `'2A0'`, `'A0'`, `'A1'`, `'A2'`, `'A3'`, `'A4'`, `'A5'`, `'A6'`, `'A7'`, `'A8'`, `'A9'`, `'A10'`,
+* `'B0'`, `'B1'`, `'B2'`, `'B3'`, `'B4'`, `'B5'`, `'B6'`, `'B7'`, `'B8'`, `'B9'`, `'B10'`,
+* `'C0'`, `'C1'`, `'C2'`, `'C3'`, `'C4'`, `'C5'`, `'C6'`, `'C7'`, `'C8'`, `'C9'`, `'C10'`,
+* `'RA0'`, `'RA1'`, `'RA2'`, `'RA3'`, `'RA4'`,
+* `'SRA0'`, `'SRA1'`, `'SRA2'`, `'SRA3'`, `'SRA4'`,
+* `'EXECUTIVE'`, `'FOLIO'`, `'LEGAL'`, `'LETTER'`, `'TABLOID'`
+
+Um die Seitenausrichtung innerhalb eines Dokuments zu ändern, füge einen Seitenumbruch mit der neuen Ausrichtung ein.
+
+**JavaScript**
+
+```js
+var dd = {
+ pageOrientation: 'portrait',
+ content: [
+ {text: 'Text on Portrait'},
+ {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'},
+ {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'},
+ {text: 'Text on Portrait 2'},
+ ]
+};
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ pageOrientation: 'portrait',
+ content: [
+ {text: 'Text on Portrait'},
+ {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'},
+ {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'},
+ {text: 'Text on Portrait 2'},
+ ]
+};
+```
+
+Automatische Seitenhöhe:
+
+**JavaScript**
+
+```js
+var dd = {
+ pageSize: {
+ width: 595.28,
+ height: 'auto'
+ },
+ content: [
+ // ...
+ ]
+}
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ pageSize: {
+ width: 595.28,
+ height: 'auto'
+ },
+ content: [
+ // ...
+ ]
+}
+```
+
+## Seitenumbrüche dynamisch steuern, zum Beispiel um verwaiste Unterelemente zu vermeiden
+
+Du kannst eine Funktion `pageBreakBefore` angeben, die entscheidet, ob vor einem Knoten ein Seitenumbruch eingefügt werden soll. Für die Regel „keine verwaiste Unterüberschrift“ kannst du folgende Definition verwenden:
+
+**JavaScript**
+
+```js
+var dd = {
+ content: [
+ {text: '1 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ {text: '2 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ {text: '3 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ ],
+ pageBreakBefore: function(currentNode, nodeContainer) {
+ // nodeContainer.getFollowingNodesOnPage();
+ // nodeContainer.getNodesOnNextPage();
+ // nodeContainer.getPreviousNodesOnPage();
+
+ return currentNode.headlineLevel === 1 && nodeContainer.getFollowingNodesOnPage().length === 0;
+ }
+}
+```
+
+**TypeScript**
+
+```ts
+import type { TDocumentDefinitions } from "pdfmake/interfaces";
+
+var dd: TDocumentDefinitions = {
+ content: [
+ {text: '1 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ {text: '2 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ {text: '3 Headline', headlineLevel: 1},
+ 'Some long text of variable length ...',
+ ],
+ pageBreakBefore: function(currentNode, nodeContainer) {
+ // nodeContainer.getFollowingNodesOnPage();
+ // nodeContainer.getNodesOnNextPage();
+ // nodeContainer.getPreviousNodesOnPage();
+
+ return currentNode.headlineLevel === 1 && nodeContainer.getFollowingNodesOnPage().length === 0;
+ }
+}
+```
+
+Wenn `pageBreakBefore` `true` zurückgibt, wird vor dem `currentNode` ein Seitenumbruch eingefügt. Dem aktuellen Knoten sind folgende Informationen zugeordnet:
+
+**JavaScript**
+
+```js
+const currentNode = {
+ id: '',
+ headlineLevel: '',
+ text: '