printmaker
Version:
Generate PDF documents and from JavaScript objects
337 lines (310 loc) • 8.97 kB
text/typescript
import { namedColors } from './colors.js';
/**
* The complete definition of a document to create.
*/
export type DocumentDefinition = {
/**
* A content block that is printed at the top of each page.
* A function can be passed to create page-specific headers.
*/
header?: Block | ((info: PageInfo) => Block);
/**
* A content block that is printed at the bottom of each page.
* A function can be passed to create page-specific footers.
*/
footer?: Block | ((info: PageInfo) => Block);
/**
* The sequence of blocks that contain the document's content.
*/
content: Block[];
/**
* The default style attributes to use in the document.
*/
defaultStyle?: TextAttrs;
/**
* The page margins. Defaults to 50pt on each side.
*/
margin?: Length | BoxLengths;
/**
* The fonts to use in the document. There is no default. Each font that is used in the document
* must be registered. Not needed for documents that contain only graphics.
*/
fonts?: FontsDefinition;
/**
* The images to use in the document. Each image in the document needs to be registered.
* Once registered, an image can be reused without multiplying its footprint.
* Only JPEG images are supported.
*/
images?: ImagesDefinition;
/**
* Metadata to include in the PDF's *document information dictionary*.
*/
info?: InfoAttrs & CustomInfoAttrs;
dev?: {
/**
* Whether to draw a thin colored rectangle around each rendered frame.
*/
guides?: boolean;
};
};
/**
* Standard metadata attributes to include in the PDF's *document information dictionary*.
*/
type InfoAttrs = {
/**
* The document’s title.
*/
title?: string;
/**
* The name of the person who created the document.
*/
author?: string;
/**
* The subject of the document.
*/
subject?: string;
/**
* Keywords associated with the document.
*/
keywords?: string[];
/**
* The date and time the document was created (defaults to current time).
*/
creationDate?: Date;
/**
* The name of the application that created the original content.
*/
creator?: string;
/**
* The name of the application that created the PDF.
*/
producer?: string;
};
/**
* Custom metadata attributes to include in the PDF's *document information dictionary*.
*/
type CustomInfoAttrs = {
[name: string]: string;
};
export type FontsDefinition = { [name: string]: FontDefinition[] };
export type FontDefinition = {
/**
* The font data, as a Uint8Array, ArrayBuffer, or a base64-encoded string.
*
* Supports TrueType (`.ttf`), OpenType (`.otf`), WOFF, WOFF2, TrueType Collection (`.ttc`),
* and Datafork TrueType (`.dfont`) font files (see https://github.com/Hopding/fontkit).
*/
data: string | Uint8Array | ArrayBuffer;
/**
* Whether this is a bold font.
*/
bold?: boolean;
/**
* Whether this is an italic font.
*/
italic?: boolean;
};
export type ImagesDefinition = { [name: string]: ImageDefinition };
export type ImageDefinition = {
/**
* The image data, as a Uint8Array, ArrayBuffer, or a base64-encoded string.
* Only JPEG images are supported.
*/
data: string | Uint8Array | ArrayBuffer;
};
export type Block = Columns | Rows | Image | Paragraph;
export type Columns = {
/**
* Content blocks to arrange horizontally.
*/
columns: Block[];
} & TextAttrs &
TextBlockAttrs;
export type Rows = {
/**
* Blocks to arrange vertically.
*/
rows: Block[];
} & TextAttrs &
TextBlockAttrs;
export type Image = {
/**
* The name of the JPG image to display in this block. The image must have been registered with
* the global `images` attribute.
*
* When any of the attributes `width` and `height` are specified, the image will be scaled
* proportionally to be contained in the given bounds.
* When neither `width` nor `height` is given, the image is not scaled unless it exceeds the
* maximum available width. In this case, it is scaled down to fit onto the page.
*/
image?: string;
/**
* Space to leave between the image and the edges of this paragraph.
*/
padding?: Length | BoxLengths;
} & BlockAttrs;
export type Paragraph = {
/**
* Text to display in this paragraph.
*/
text?: Text;
/**
* Graphic elements to draw in the area covered by the paragraph.
* The coordinate system for graphics shapes starts at the top left corner of the paragraph's
* padding.
*/
graphics?: Shape[];
/**
* Space to leave between the text and the edges of the paragraph.
*/
padding?: Length | BoxLengths;
} & TextAttrs &
TextBlockAttrs;
export type TextBlockAttrs = BlockAttrs & {
/**
* Align texts included in this block.
* Supported values are `left`, `right` and `center`. By default, texts are left-aligned.
*/
textAlign?: Alignment;
};
export type BlockAttrs = {
/**
* Space to surround the block.
* The `top` and `bottom` margins of adjacent blocks are collapsed into a single margin
* whose size is the maximum of the two margins. Column margins don't collapse.
*/
margin?: Length | BoxLengths;
/**
* A fixed width for the block. If left out, the block uses the available width.
*/
width?: Length;
/**
* A fixed height for the block. If left out, the height is defined by the included text.
*/
height?: Length;
/**
* Align texts included in this block.
* Supported values are `left`, `right` and `center`. By default, texts are left-aligned.
*/
textAlign?: Alignment;
/**
* An optional *unique* id for the element. When an `id` is specified, an anchor with this id
* will be included in the PDF document that can be used to refer to this element using the text
* attribute `link`.
*/
id?: string;
};
export type PageInfo = {
/**
* The number of the current page, starting at 1.
*/
readonly pageNumber: number;
/**
* The total number of pages.
*/
readonly pageCount: number;
/**
* The size of the current page in pt.
*/
readonly pageSize: { width: number; height: number };
};
export type Shape = Rect | Line | Polyline;
export type Rect = {
type: 'rect';
x: number;
y: number;
width: number;
height: number;
strokeWidth?: number;
strokeColor?: Color;
fillColor?: Color;
};
export type Line = {
type: 'line';
x1: number;
y1: number;
x2: number;
y2: number;
strokeWidth?: number;
strokeColor?: Color;
};
export type Polyline = {
type: 'polyline';
points: { x: number; y: number }[];
closePath?: boolean;
strokeWidth?: number;
strokeColor?: Color;
fillColor?: Color;
};
/**
* A piece of inline text. A list can be used to apply styles to parts of a paragraph.
*/
export type Text = string | ({ text: Text } & TextAttrs) | Text[];
export type TextAttrs = {
/**
* The name of the font to use.
* If not specified, the first font registered in the document definition that matches the other
* font attributes will be used.
*/
fontFamily?: string;
/**
* The font size in pt.
*/
fontSize?: number;
/**
* The line height as a multiple of the font size. Defaults to `1.2`.
*/
lineHeight?: number;
/**
* Whether to use a bold variant of the selected font.
*/
bold?: boolean;
/**
* Whether to use an italic variant of the selected font.
*/
italic?: boolean;
/**
* The text color.
*/
color?: Color;
/**
* A link target. When this attribute is present, the corresponding text will be rendered as a
* link to the given target. The target can either be a URL or a reference to an anchor in the
* document. An internal reference starts with a hash sign (`#`), followed by the `id` of an
* element in the document.
*/
link?: string;
};
/**
* A definition of space around the edges of a box.
* Undefined edges default to zero.
*/
export type BoxLengths = {
/** Space on the left edge, overrides `x`. */
left?: Length;
/** Space on the right edge, overrides `x`. */
right?: Length;
/** Space on the upper edge, overrides `y`. */
top?: Length;
/** Space on the lower edge, overrides `y`. */
bottom?: Length;
/** Space on the left and right edge. */
x?: Length;
/** Space on the upper and lower edge. */
y?: Length;
};
/**
* A length definition as a number, optionally followed by a unit.
* Supported units are `pt` (point), `in` (inch), `mm` (millimeter), and `cm` (centimeter).
* If the unit is left out, the number is interpreted as point (`pt`).
* One point is defined as `1/72` of an inch (`72pt = 1in`).
*/
export type Length = number | `${number}${LengthUnit}`;
export type LengthUnit = 'pt' | 'in' | 'mm' | 'cm';
export type Color = NamedColor | HTMLColor;
export type NamedColor = keyof typeof namedColors;
/**
* A color specified in the hexadecimal format `#xxxxxx` that is usual in HTML.
*/
export type HTMLColor = `#${string}`;
export type Alignment = 'left' | 'right' | 'center';