Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
133 changes: 133 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Documentation checks and Pages

on:
push:
branches-ignore: [gh-pages]
pull_request:
workflow_dispatch:
inputs:
deploy:
description: Publish the tested snapshot and preserve historical versions
type: boolean
default: false

permissions:
contents: read

concurrency:
group: docs-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }}

jobs:
docs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: '24.x'
cache: npm
- run: npm ci
- run: npm audit --audit-level=low
- name: Install pinned Hugo
env:
HUGO_VERSION: '0.168.0'
run: |
archive="hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
curl --fail --location --output "$archive" "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/$archive"
curl --fail --location --output checksums.txt "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_checksums.txt"
grep " hugo_${HUGO_VERSION}_linux-amd64.tar.gz$" checksums.txt | sha256sum --check
mkdir -p "$RUNNER_TEMP/hugo"
tar -xzf "$archive" -C "$RUNNER_TEMP/hugo" hugo
echo "$RUNNER_TEMP/hugo" >> "$GITHUB_PATH"
rm "$archive" checksums.txt
- name: Read snapshot version
id: snapshot
run: node --input-type=module -e "import fs from 'node:fs';import {activeVersion} from './scripts/versions.mjs';fs.appendFileSync(process.env.GITHUB_OUTPUT, 'version='+activeVersion.id+'\n')"
- run: npm test
- run: npm run build
- run: npx playwright install --with-deps chromium
- run: npm run test:browser
env:
SCREENSHOT_DIR: test-results
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: browser-screenshots
path: test-results/
retention-days: 7
if-no-files-found: ignore
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: pdfmake-docs-${{ steps.snapshot.outputs.version }}-preview
path: public/
retention-days: 14
if-no-files-found: error

pages:
name: Publish verified documentation
needs: docs
if: github.event_name == 'workflow_dispatch' && inputs.deploy && github.ref == 'refs/heads/master' && github.repository == 'pdfmake/docs'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
# Retain the exact deployed site so future series preserve the latest snapshots.
contents: write
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
concurrency:
group: docs-pages-production
cancel-in-progress: false
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7
with:
node-version: '24.x'
- name: Read snapshot version
id: snapshot
run: node --input-type=module -e "import fs from 'node:fs';import {activeVersion} from './scripts/versions.mjs';fs.appendFileSync(process.env.GITHUB_OUTPUT, 'version='+activeVersion.id+'\n')"
- name: Download the exact artifact that passed checks
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: pdfmake-docs-${{ steps.snapshot.outputs.version }}-preview
path: verified
- name: Preserve existing root and historical documentation
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: gh-pages
path: published
persist-credentials: true
- name: Configure project Pages
id: pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
- name: Assemble the complete Pages site
run: node scripts/assemble-pages.mjs verified published pages-artifact
env:
PAGES_BASE_PATH: ${{ steps.pages.outputs.base_path }}
- uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4
with:
path: pages-artifact
- name: Deploy atomically
id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
- name: Archive the successfully deployed snapshots
working-directory: published
env:
SOURCE_SHA: ${{ github.sha }}
run: |
# A regular fast-forward push rejects concurrent archive modifications.
# Pages must use Actions as its source, so this archive commit does not deploy a second time.
rsync -a --delete --exclude='.git/' ../pages-artifact/ ./
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add --all
if ! git diff --cached --quiet; then
git commit -m "Archive documentation from ${SOURCE_SHA}"
git push origin HEAD:gh-pages
fi
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
public/
/.idea
node_modules/
.hugo_build.lock
resources/
static/playground/vendor/
static/playground/editor.js
test-results/

.generated/
collection/
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Documentation contributor guide

This repository documents pdfmake **0.3.x**. The `0.1` branch owns the older
0.1/0.2 docs. Keep public page paths stable, including the historical spelling
`document-medatadata`; add aliases if introducing new paths.

Author content in `content/` with TOML title, description and weight. Prefer a
complete runnable example before options and edge cases. Explain environment,
minimum version, defaults, units and failure behavior. Use Promise-based output
methods. Resource policies must be synchronous. Distinguish PDF encryption from
server resource-access controls. Preserve security caveats and advanced features.

`npm ci`, `npm run docs:generate`, `npm test`, `npm run build` validate the corpus,
executable examples, MCP protocol and all generated internal links. Install Hugo
0.168.0 for the website. The first build step generates versioned Markdown,
`llms.txt`, `llms-full.txt` and `docs-index.json` from the same pages. Do not edit
these generated files manually. The MCP stdio server in `mcp/server.mjs` reads
that snapshot; it must not execute example code or fetch remote content.

`layouts/` and `static/assets/` own the documentation UI. The historical theme
is retained for reference but is not loaded. Keep the site usable without JS;
JS adds search and copy buttons. Use semantic HTML and local assets. Docs tooling
requires Node >=24.11; this is separate from the library's Node >=20 runtime.

Translations use language-suffixed Markdown files (`.de.md`, `.fr.md`, `.es.md`,
`.pt-br.md`) beside the English original. Preserve code/API identifiers and include
`sourceDigest`, the SHA-256 of the English source with LF line endings, after
reviewing changes. Do not copy untranslated English pages into language URLs or
claim them in hreflang. Missing translations link explicitly to English or the
locale start page. Search/MCP/Markdown exports must retain language separation.

All supported languages must cover the full English page set. Translation checks
compare source digests, fenced code, runnable examples, heading structure, table
rows and localized internal links. Translate explanatory prose fully; do not
replace reference sections with summaries. Keep shared example source/output
unchanged so every language demonstrates the same tested API behavior.

Chapter navigation is curated by task in `data/navigation.json`, not inferred from
the content directory. Keep all existing page URLs reachable. The primary
playground is a rendered documentation route, mounted directly into the shared
shell. Preserve its editor state across SPA navigation and cancel background work
when detached. Use `standalone.html` only for isolated previews and library-only
development. Validate navigation, state retention, Back/Forward, mobile drawer,
themes and language equivalents with the browser suite when changing this shell.

Versions are configured in `versions.json`. Use the npm Hugo wrapper; do not edit
`.generated/` or hardcode another series in templates, exporters or MCP. Never
advertise a future release without a real verified snapshot. Keep playground
runtime pins aligned and version-switch chapter metadata explicit. Test current
and synthetic future corpus paths without publishing fake releases.

Code example variants are generated by `scripts/code-examples.mjs`. Never maintain
independent manually diverging JS/TS copies. Include all variants in portable
Markdown. New document examples must pass the browser TypeScript checker; avoid
`any`, suppression comments or unchecked type assertions to conceal errors. Keep
inline editors isolated, cancel workers on navigation and preserve independent
language drafts. Environment-dependent examples must not pretend to execute Node
or access private files in browser previews.
170 changes: 156 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,171 @@
# pdfmake docs for version 0.3
# pdfmake developer documentation

The source for website https://pdfmake.github.io/docs/
The documentation application for **pdfmake 0.3.x**: task-oriented guides,
searchable references and editable JavaScript/TypeScript examples with PDF previews.
Built with Hugo, progressively enhanced navigation and local browser assets.

For source of version 0.1 or 0.2 go here: https://github.com/pdfmake/docs/tree/0.1
[Read the documentation](https://pdfmake.github.io/docs/0.3/) · [Try the playground](https://pdfmake.github.io/docs/0.3/playground/) · [Library source](https://github.com/bpampuch/pdfmake) · [Authoring guide](AGENTS.md)

### Run from sources
## Run locally

#### Requirements
Prerequisites: **Node.js >=24.11** and [Hugo 0.168.0](https://github.com/gohugoio/hugo/releases/tag/v0.168.0).

* Hugo (https://gohugo.io/)
```sh
npm ci
npm run dev
```

Open <http://127.0.0.1:1313/docs/0.3/>. The playground is part of the same application;
its editor, TypeScript compiler, fonts and PDF preview require no CDN or account.
The site remains readable and navigable without JavaScript. The UI respects the
system color preference and offers persistent light/dark selection.

## Repository map

| Location | Responsibility |
| --- | --- |
| `content/` | Markdown source and complete language editions |
| `data/navigation.json` | Curated chapter groups and ordering |
| `layouts/`, `static/assets/` | Server-rendered shell and navigation enhancements |
| `static/playground/`, `playground/` | Shared editor, worker and PDF preview |
| `scripts/` | Generation, validation, versioning and build tools |
| `tests/` | Corpus, imports, MCP, deployment assembly and browser regression tests |
| `mcp/` | Read-only documentation server |
| `versions.json` | Supported snapshots, source refs and runtime pins |
| `tooling/pdfmake-types/` | Attributed native declaration snapshot for unreleased library work |

#### Clone and start website
## Build and verify

```sh
npm run docs:generate
npm test
npm run build
npx playwright install chromium
npm run test:browser
```
git clone --branch master https://github.com/pdfmake/docs.git
cd docs
hugo server

The build writes `public/` and checks links, fragments, canonical URLs, structured
data and discovery files. Tests cover translations, JavaScript/TypeScript examples,
actual Node PDF generation, search, MCP and multi-version deployment composition.
Browser tests exercise previews, imports, downloads, errors, autosave, undo/redo,
named documents, mobile navigation, themes, history and operation without JavaScript.

For a production-style local preview, run `node scripts/serve.mjs` after building.
CI runs clean installs, dependency audits, the full build and browser tests before
uploading a review artifact. Generated vendor assets and `public/` are ignored.

## Edit documentation

Write Markdown with a TOML title, description and weight. Start with a runnable
example, explain its result, then document defaults and edge cases. Keep API names,
minimum versions, units, resource policies and failure behavior accurate.
Use the 0.3 Promise API and retain existing page URLs.

Code example pairs come from `scripts/code-examples.mjs`; do not independently
maintain JS and TS copies. Run `npm run docs:generate` after source edits and commit
the generated Markdown, search indexes and LLM exports. Executable definitions
must pass the same native TypeScript checker used by the editor.

English, German (`de`), French (`fr`), Spanish (`es`) and Brazilian Portuguese
(`pt-br`) have complete chapter sets. Translations live beside the source, for
example `tables.de.md`. After reviewing an English change, update the translation
and its `sourceDigest` (SHA-256 of the English source with LF line endings).
Tests compare page coverage, digests, headings, code, tables and internal links.
Search, portable Markdown and MCP results remain language-specific.
Playground controls and shared executable example output currently remain English.

## Review a local library change

Build the library first, then select it for documentation tests and previews:

```powershell
$env:PDFMAKE_SOURCE = 'C:\path\to\pdfmake'
node scripts/sync-native-types.mjs $env:PDFMAKE_SOURCE
npm run docs:generate
npm test
npm run build
```

and open in browser:
The selected package version must match `versions.json`. Without the override,
PDF generation uses the pinned published runtime. **The published 0.3.12 runtime
has no bundled declarations or preflight API.** This development branch retains
an explicitly attributed, declaration-only snapshot from the improved library so
docs TypeScript examples are reproducible before its release. Native package
imports are verified against the actual tarball in the library repository.
The preflight API is used by previews when the selected runtime implements it;
there is no shim claiming an old runtime supports new functionality.

Check declaration synchronization with:

```sh
node scripts/sync-native-types.mjs /path/to/pdfmake --check
```
http://localhost:1313/docs/0.3/

Once native declarations are released, update the pinned runtime and snapshot
together. PDF.js, CodeMirror and TypeScript are documentation tooling only.

The library's standalone playground mirrors these authored UI sources:

```sh
node scripts/sync-playground.mjs /path/to/pdfmake
node scripts/sync-playground.mjs /path/to/pdfmake --check
```

#### Deploy webpages
## Markdown and MCP

Generation produces `llms.txt`, `llms-full.txt`, individual Markdown pages and
`docs-index.json` from the same source as the website. Each snapshot and language
has its own exports. Configure an MCP client to launch:

```sh
node /absolute/path/to/docs/mcp/server.mjs
```
hugo --cleanDestinationDir

The stdio server exposes `search_docs`, `get_doc` and versioned Markdown resources.
It does not execute examples, render PDFs or read arbitrary caller-selected paths.
See [the integration guide](content/guides/llm-and-mcp.md).

## Versions and GitHub Pages

`versions.json` defines real supported snapshots and their library pins. The `0.1`
branch owns historical 0.1/0.2 documentation; never overwrite it with a 0.3 build.
To prepare another series, add a verified snapshot and matching runtime/source ref.
Version selectors, canonical URLs, search and exports derive from that registry.
Build isolated snapshots with `DOCS_VERSION`; compose a local collection with:

```sh
npm run build:collection -- collection 0.3=public
```

GitHub Pages remains a suitable host: this is a static, server-rendered website
with client-side enhancements. No application server or separate playground host
is required. The workflow uses GitHub's official configure/upload/deploy actions,
OIDC and a protected `github-pages` environment, with no personal deployment token secret. Only the explicit publication job has
`contents: write`, needed to archive the exact deployed site for subsequent series.

Production publication is **explicit**, from `master` in `pdfmake/docs`: dispatch
**Documentation checks and Pages** with `deploy: true`. It builds and tests first,
then deploys that exact artifact. `assemble-pages.mjs` preserves the existing
`gh-pages` root and every other registered snapshot, verifies metadata and stages
the current series under `0.3/`. GitHub serves the artifact under `/docs/`.
Deployments are serialized and do not cancel each other.

Before enabling publication, a maintainer must select **GitHub Actions** as the
Pages source, protect the `github-pages` environment (branch restriction and
required reviewer), retain the historical `gh-pages` branch as the preservation
source, and retire any competing publisher. This local review changes none of
those settings and performs no deployment.

For rollback, dispatch the last known-good source commit on the allowed branch
after reverting the offending change; the same tests and complete-site assembly
run again. The workflow commits the successfully deployed site to `gh-pages` as its preservation
archive; the root and other series retain their bytes. A normal fast-forward push
rejects concurrent modifications. Treat an archive-step failure as a failed
publication and repair/retry it before publishing another series.
`deployment.json` records the deployed source commit, series and runtime pin.

## Contribute

Follow [AGENTS.md](AGENTS.md), include a minimal example for behavior changes and
run the relevant validation commands above. Keep the site usable without JS and
retain the MIT notices for imported declarations and other third-party assets.
Loading