kardec

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: MIT Imports: 15 Imported by: 0

README

Kardec

Document-style PDFs in pure Go. Embedded fonts, no Docker, no system dependencies.

Go Reference CI Go Report Card Latest release Go version

package main

import (
    "log"

    "github.com/arthurhrc/kardec"
    _ "github.com/arthurhrc/kardec/render"
)

func main() {
    doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
        Heading(1, kardec.Text("Monthly Report")).
        Paragraph(
            kardec.Text("Sales grew "),
            kardec.Bold("12%"),
            kardec.Text(" this quarter."),
        )
    if err := doc.Render("report.pdf"); err != nil {
        log.Fatal(err)
    }
}

Install

go get github.com/arthurhrc/kardec

Go 1.22+. The blank import _ "github.com/arthurhrc/kardec/render" wires Document.Render via init(). Without it, calls to Render return ErrRendererUnregistered.

Why Kardec

Allan Kardec (1804-1869) was a French educator who took a body of scattered oral traditions and codified them into a structured written doctrine. The library does the equivalent for documents: a program assembles a flowing structure through a fluent Go API, and Kardec freezes it into a portable PDF that opens identically on every reader. The name is a nod to the act of codification.

What that buys you in practice:

  • Flowing prose, headings, footnotes, tables, math, lists. Not a grid.
  • Single static binary. Liberation Sans / Serif, Carlito and JetBrains Mono ship inside (~7 MB, OFL).
  • Byte-reproducible output: same input plus a fixed clock, identical PDFs.

Comparison

Tool Pure Go Container needed Document-flow Markdown ingest Templating
Kardec yes no yes yes yes
Maroto yes no grid only no no
gofpdf / fpdf yes no low-level only no no
Gotenberg no (Docker) yes yes (via LibreOffice) yes no

Kardec covers the seam: pure Go like Maroto, document-shaped like Gotenberg.

Examples

# Core document features
go run ./examples/hello              # smallest end-to-end PDF
go run ./examples/report             # multi-section, header/footer, table with shading
go run ./examples/markdown           # CommonMark + GFM tables
go run ./examples/invoice            # text/template + Markdown -> one PDF per record
go run ./examples/image              # PNG embedded into the PDF
go run ./examples/math               # LaTeX math subset (\frac, \sqrt, \sum, \int, greek)

# Recent features (v0.19+)
go run ./examples/svg                # SVG embed as vector Form XObject
go run ./examples/encryption         # AES-128 with read-only permissions
go run ./examples/watermark          # diagonal "DRAFT" overlay with alpha
go run ./examples/tagged             # PDF/UA tagged structure (H1/H2/P/Figure)
go run ./examples/inlinemath         # math expression inside a paragraph
go run ./examples/qrcode             # QR codes at L/M/Q/H error tiers
go run ./examples/bookstyle          # background letterhead + verso/recto headers
go run ./examples/templates_invoice  # one-line invoice from kardec/templates
go run ./examples/chart              # bar / line / pie charts via kardec/chart
go run ./examples/signature          # PKCS#7 detached signature via kardec/sign

Features

Document structure

  • Headings, paragraphs, lists, tables (borders + shading + colspan), images (JPEG / PNG / SVG), page breaks, spacers, horizontal rules
  • KeepTogether(blocks...) binds groups to a single page
  • Two-column section layout via PageSetup.Columns
  • Multi-section page setups (mix portrait, landscape, custom margins)
  • Section background image; first-page / even-page header & footer variants

Inline content

  • Run decorations: Bold, Italic, Underline, Strikethrough, colored, sized
  • Hyperlinks, named anchors, automatic PDF outline (sidebar bookmarks)
  • LaTeX math subset (\frac, \sqrt, \sum, \int, greek) — Document.Math (display) and InlineMath (Run-level)
  • CommonMark + GFM ingest with Markdown image embed

Cross-references and references

  • Auto figure / table numbering with Label(name) + doc.Ref(label) / doc.RefPage(label)
  • Numeric citations: doc.Cite(key) + doc.Bibliography(entries...)
  • Auto table of contents (clickable, resolved in a post-pass)
  • Footnotes with auto-numbering or custom markers
  • Leader(left, right) dotted rows; SignatureBlock(name, role) for contracts
  • Clause(level, runs...) hierarchical numbering for legal documents

Styling and layout

  • Style system with inheritance and per-block overrides
  • Section headers and footers with {{page}} / {{totalPages}} / {{section}} / {{date}} tokens
  • Decimal-point column alignment for currency / measurement tables
  • Image.Caption(...) auto-prefixed with the figure marker, kept-together with its image
  • Knuth-Liang hyphenation with bundled pattern sets: en, pt-BR, es, fr
  • Optional Knuth-Plass optimum-fit line breaker

Output

  • Byte-reproducible output via Document.SetCreationDate(t) (unsigned rendering)
  • Optional TTF font subsetting (~70 % size reduction)
  • PDF/A-2b conformance markers; OutputIntent + ICC profile when supplied
  • PDF/UA-1 strict tagging: per-block H1–H6 / P / Figure roles, Table > TR > TD/TH hierarchy, Sect groupings around H1 boundaries
  • AES-128 encryption + permissions (Standard Security Handler V=4 / R=4); strings + streams both encrypted (/StrF /StdCF)
  • Per-page diagonal watermark with alpha blending
  • QR codes via Document.QRCode (vector Form XObject)
  • Unicode text via Type 0 / Identity-H font embedding — Δ, Σ, Cyrillic, CJK render correctly

Companion subpackages

  • kardec/render — registers the renderer (blank-imported once at app entry)
  • kardec/httpxWriteResponse(w, doc, filename) for net/http handlers
  • kardec/templates — ready-made Invoice / Certificate / Report scaffolds
  • kardec/chart — pure-Go bar / line / pie chart renderer (SVG out)
  • kardec/sign — PKCS#7 detached signatures (Adobe-compatible, ICP-Brasil-ready)

CLI

  • cmd/kardec ships a kardec binary for rendering Markdown + Go templates without writing Go.

What's NOT in Kardec

Honest non-goals — if you need these, reach for another tool or contribute the support:

  • Interactive form fields (AcroForm beyond signatures). Use a dedicated signing flow.
  • Multi-script text shaping for Arabic, Hebrew (RTL), Devanagari, Thai, Burmese. Kardec handles every Unicode codepoint the source TTF covers but does not run a shaping engine; ligatures, complex marks, and bidi reordering are out of scope. CJK / Cyrillic / Greek + Latin scripts render correctly.
  • PDF/X (print-industry colour management). PDF/A-2b is the closest cousin and ships.
  • Browser-style HTML/CSS rendering. Use Gotenberg + LibreOffice when input is HTML.
  • Live editing / WYSIWYG. Kardec is one-pass programmatic generation, not a layout tool.

Status

v1.0 — API frozen. Every public type, function, and method exposed at v1.0 stays signature-compatible through the v1.x line. Breaking changes need a v2.0 major bump. Internal packages (internal/...) remain unstable; callers reaching into them get whatever they deserve.

Range What it brought
0.1–0.5 Core document model, multi-face fonts, tables, images, Markdown ingest, math subset, byte-reproducible output, font subsetting
0.6–0.11 Cross-references, KeepTogether, footnotes, TOC, hyphenation, two-column layout, metadata setters, OutputIntent
0.12–0.14 CI quality gates, reproducibility check, ToUnicode CMaps, clickable TOC
0.15–0.21 OTF/CFF math glyphs, AES-128 encryption, PDF/UA-1 lite tagging, Knuth-Plass breaker, SVG embed, watermark, inline math
0.22 API cleanup pass; Identity-H Unicode body text; per-block PDF/UA roles; encrypted strings
0.23 Hyphenation pt/es/fr; background image; first-page + even-page header / footer; QR codes; table cell roles; kardec/templates
0.24 PDF/UA strict: Table > TR > TD/TH nesting + Sect groupings
0.25 kardec/chart — pure-Go bar / line / pie
0.26 kardec/sign — PKCS#7 detached signatures
1.0 (current) API frozen. No code change from v0.26 — the surface is committed-stable.

Full release notes in CHANGELOG.md. Design spec in docs/RFC-001-dsl.md. Migration guide in MIGRATING.md.

Contributing

PRs welcome. Each feature lands on its own branch with granular commits and a PR before merging to main. Run go vet ./... && go test ./... before pushing.

License

MIT. See LICENSE for the source license and NOTICE.md for bundled-font and dependency attributions.

Documentation

Overview

Package kardec produces document-like PDFs through a fluent, style-driven DSL.

Kardec targets the gap between report-grid PDF generators (such as Maroto) and container-based DOCX-to-PDF converters (such as Gotenberg). It runs pure Go, ships embedded fonts, and does not require LibreOffice, a system font directory, or a container at runtime.

Quick start

import (
    "github.com/arthurhrc/kardec"
    _ "github.com/arthurhrc/kardec/render"
)

doc := kardec.New(kardec.PageA4, kardec.MarginsNormal)
doc.Heading(1, kardec.Text("Monthly Report"))
doc.Paragraph(kardec.Text("Sales grew "), kardec.Bold("12%"), kardec.Text(" this quarter."))
if err := doc.Render("report.pdf"); err != nil {
    log.Fatal(err)
}

Styles

Every block resolves its visual attributes through the named style table the document carries. BuiltinStyles seeds the table with Default, H1..H6, Caption, Quote, Code, TableHeader, TableCell, Header, Footer, ListItem and Link; users add or override entries via Document.DefineStyle. Styles inherit from a parent (Style.ParentStyle), and per-block overrides via Paragraph(...).WithStyle(...) layer on top during resolution. See Document.ResolveStyle and Document.ResolveBlockStyle for the full chain.

Concurrency

A *Document is not safe for concurrent use by multiple goroutines, in line with bytes.Buffer and strings.Builder. Different *Document values may be used concurrently.

See docs/RFC-001-dsl.md in the repository for the full design specification.

Example

Example shows the canonical "Hello report" pattern: build a Document fluently, then call Render to write a PDF. The Document method API stays compile-checked here; the runnable byte-stream variant lives in the render package's example_test so this file does not need to import render and break the package's "renderer-unregistered" sentinel test.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Heading(1, kardec.Text("Monthly Report")).
		Paragraph(
			kardec.Text("Sales grew "),
			kardec.Bold("12%"),
			kardec.Text(" this quarter."),
		)
	_ = doc.Render
}

Index

Examples

Constants

View Source
const (
	// RefAnchorPrefix is the leading string of the anchor name that
	// LabeledFigure / LabeledTable emit before each labeled block.
	// Internal — exposed so test code can assert on it without
	// importing layout-internal helpers.
	RefAnchorPrefix = "kardec-ref-"

	// RefPagePlaceholder is the placeholder text RefPage emits.
	// Layout's post-pass searches for it and replaces each occurrence
	// with the page number on which the matching anchor landed.
	RefPagePlaceholder = "{{refpage:"
)
View Source
const (
	StyleDefault     = "Default"
	StyleH1          = "H1"
	StyleH2          = "H2"
	StyleH3          = "H3"
	StyleH4          = "H4"
	StyleH5          = "H5"
	StyleH6          = "H6"
	StyleCaption     = "Caption"
	StyleQuote       = "Quote"
	StyleCode        = "Code"
	StyleTableHeader = "TableHeader"
	StyleTableCell   = "TableCell"
	StyleFooter      = "Footer"
	StyleHeader      = "Header"
	StyleListItem    = "ListItem"
	StyleLink        = "Link"
)

Built-in named style identifiers. Strings (not typed constants) are kept because users define their own styles by arbitrary names and the same lookup path serves both built-in and custom styles.

View Source
const (
	FontLiberationSans  = "Liberation Sans"
	FontLiberationSerif = "Liberation Serif"
	FontJetBrainsMono   = "JetBrains Mono"
)

FontLiberationSans is the family name of the bundled default sans face. Mirrors the typography track; declaring it here lets style consumers refer to it without importing the future font registry package.

View Source
const BibAnchorPrefix = "kardec-bib-"

BibAnchorPrefix is the leading string of the anchor names emitted before each Bibliography entry. Exposed so callers building manual cross-links know the convention.

Variables

View Source
var (
	ColorBlack = Color{0, 0, 0}
	ColorWhite = Color{255, 255, 255}
	ColorGray  = Color{128, 128, 128}
)

Common named colors. Kept deliberately small; users compose more through HexColor or RGB.

View Source
var (
	PageA3     = PageSize{Name: "A3", Width: Mm(297), Height: Mm(420)}
	PageA4     = PageSize{Name: "A4", Width: Mm(210), Height: Mm(297)}
	PageA5     = PageSize{Name: "A5", Width: Mm(148), Height: Mm(210)}
	PageLetter = PageSize{Name: "Letter", Width: In(8.5), Height: In(11)}
	PageLegal  = PageSize{Name: "Legal", Width: In(8.5), Height: In(14)}
)

Standard page presets. Dimensions follow ISO 216 for A* and ANSI for the US sizes, both expressed exactly in millimeters.

View Source
var (
	MarginsNarrow = Symmetric(Cm(1.27))
	MarginsNormal = Symmetric(Cm(2.54))
	MarginsWide   = Symmetric(Cm(5.08))
)
View Source
var DefaultStyle = Style{
	Family:      FontLiberationSans,
	Size:        Pt(11),
	Weight:      WeightRegular,
	Italic:      false,
	Color:       ColorBlack,
	SpaceBefore: Pt(0),
	SpaceAfter:  Pt(6),
	LineHeight:  1.15,
	Alignment:   AlignLeft,
}

DefaultStyle is the root of the inheritance tree. Every other built-in style — and every user-defined style without an explicit ParentStyle — resolves through it. Picked to match the Word "Normal" body-text feel.

View Source
var ErrRendererUnregistered = errors.New("kardec: no render implementation registered (import github.com/arthurhrc/kardec/render)")

ErrRendererUnregistered is returned by Render / RenderTo / Bytes when no rendering implementation has been wired in. Importing the public render package — github.com/arthurhrc/kardec/render — installs the default implementation via init(), so this error typically signals a missing blank import:

import _ "github.com/arthurhrc/kardec/render"

Functions

func BibAnchorName added in v0.8.0

func BibAnchorName(num int) string

BibAnchorName returns the anchor name Bibliography emits for the given 1-based citation number.

func BuiltinStyles

func BuiltinStyles() map[string]Style

BuiltinStyles returns a fresh map containing every built-in named style. The returned map is owned by the caller; mutating it does not affect future calls. Document.New copies these into the document's style table during construction.

func HeadingStyleName

func HeadingStyleName(level int) string

HeadingStyleName returns the built-in named style that corresponds to a heading level (1..6). Levels outside the range are clamped, matching the Document.Heading constructor.

func RefAnchorName added in v0.7.0

func RefAnchorName(label string) string

RefAnchorName returns the anchor name LabeledFigure / LabeledTable emit for the given label. Exposed so tests and integrations can build clickable cross-references by hand if needed.

func SetRenderImpl deprecated

func SetRenderImpl(f func(*Document, io.Writer) error)

SetRenderImpl wires a render implementation. The render package calls it from init(); user code should not invoke it directly. Calling SetRenderImpl with a nil function clears the registration.

Deprecated: this is an internal seam exposed only because Go has no friend-package mechanism for the renderer-injection pattern. User code must never call it; the render package's init() is the only legitimate consumer. The function may move behind an internal helper at v1.0 without further notice.

Types

type Alignment

type Alignment uint8

Alignment controls the horizontal arrangement of inline content within a paragraph or table cell.

const (
	AlignLeft Alignment = iota
	AlignCenter
	AlignRight
	AlignJustify
	// AlignDecimal aligns content on the decimal point. Only
	// meaningful inside table cells driven by AlignDecimalCol; using
	// it on a Paragraph degrades to AlignRight at layout time. Cells
	// without a "." pivot in their text fall back to right alignment
	// so an integer mixed in with decimals still rests at the same
	// vertical baseline as the dotted neighbours.
	AlignDecimal
)

type Anchor added in v0.4.0

type Anchor struct {
	// contains filtered or unexported fields
}

Anchor is a named position inside the document. It occupies no vertical space on its own; the layout engine simply records the page and Y coordinate at which it was inserted, and the PDF writer turns the result into a named destination linkable from anywhere else in the document via a "#<name>" URL.

Pair Anchor with Link("text", "#name") to build clickable cross- references — the canonical use case is a TOC at the top of the document linking to each section heading.

func (Anchor) Name added in v0.4.0

func (a Anchor) Name() string

Name returns the anchor's identifier. Read-only access for layout and renderer integrations.

type BibEntry added in v0.8.0

type BibEntry struct {
	Key     string // unique citation key (e.g., "Knuth1984")
	Author  string // "Knuth, D."
	Title   string // "Literate Programming"
	Year    int    // 1984
	Journal string // "The Computer Journal"
	Volume  string // "27"
	Pages   string // "97-111"
	URL     string // "https://..."
}

BibEntry is the user-supplied bibliography record. Fields are kept shallow and string-typed on purpose: composing the emitted line is the job of the renderer, not the BibEntry. Callers needing fine formatting control can override Bibliography's emit step by passing a pre-built block sequence instead — a v0.9 extension.

type Block

type Block interface {
	// contains filtered or unexported methods
}

Block is the unit of vertical flow inside a section. Implementations carry their own content (runs, rows, image ref) and are positioned by the layout engine in document order.

The interface is intentionally minimal at the public surface; concrete methods needed by the layout engine live on the unexported types.

func SignatureBlock added in v0.8.0

func SignatureBlock(name, role string) Block

SignatureBlock returns a KeepTogether containing a horizontal rule (the signature line itself), a centered name paragraph, and an optional centered role paragraph styled smaller. The returned value is a Block; pass it to doc.KeepTogether or use the Document.Signature builder for fluent appending.

Example

ExampleSignatureBlock produces a contract-style signature line: horizontal rule, centered name, optional italic role.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Paragraph(kardec.Text("Signed and acknowledged below.")).
		Signature("Jane Doe", "Lead Engineer")
	_ = doc
}

type Cell added in v0.2.0

type Cell struct {
	Runs []Run
	// Span is the number of columns this cell occupies. 0 and 1 are
	// equivalent (single column); values larger than the remaining
	// columns are clamped at layout time. Cells consumed by a
	// preceding span are simply absent from the row's slice — the
	// layout engine advances the column index by Span as it walks
	// the row.
	Span int
}

Cell carries the inline runs that fill a single (row, column) intersection. Plain string cells become a single text Run; richer content can be supplied via the Cells helper.

func NewCell added in v0.10.0

func NewCell(runs ...Run) Cell

NewCell builds a Cell from the supplied runs — the rich-content counterpart to the plain string accepted by Row.

func SpanCell added in v0.8.0

func SpanCell(span int, runs ...Run) Cell

SpanCell builds a Cell that occupies span columns. The most common use case is a merged header that labels a group of underlying columns ("Q1 vs Q2" spanning two single-month columns).

span values <= 1 collapse to a normal one-column cell. The next span-1 cells in the row's slice should be omitted: layout absorbs the column budget into this Cell's width and advances the column pointer by span.

type Color

type Color struct {
	R, G, B uint8
}

Color is an sRGB color with three 8-bit channels. Alpha is not part of the PDF 1.7 base color model used by Kardec; transparency lives in graphics state rather than per-color.

func HexColor

func HexColor(hex string) Color

HexColor parses a CSS-style hex string ("#2E74B5", "2E74B5", "#fff") into a Color. Invalid input is reported by the document via Document.Err once the color is consumed by a style or content operation.

func RGB

func RGB(r, g, b uint8) Color

RGB constructs a Color from raw 8-bit channels.

func (Color) Hex

func (c Color) Hex() string

Hex returns the canonical six-digit hex representation, prefixed with "#".

type Column added in v0.2.0

type Column struct {
	Header    string
	Width     float64
	Alignment Alignment
}

Column describes a single table column: its visible header, target width and horizontal alignment for the contained cells.

Width carries a dual meaning by convention: values in (0, 1] are interpreted as fractions of the available content width; values strictly greater than 1 are treated as fixed point sizes. Negative or zero widths are normalised by the layout engine into equal shares of the remaining space.

func Col added in v0.2.0

func Col(header string, opts ...ColumnOption) Column

Col returns a Column with the supplied header and any number of options applied. Without options, a Column inherits Width=0 (which the layout engine resolves to "an equal share of the remainder") and Alignment=AlignLeft.

type ColumnOption added in v0.2.0

type ColumnOption func(*Column)

ColumnOption customises a Column when constructed through the Col helper. The functional-option pattern keeps the constructor surface stable while leaving room for future per-column knobs.

func Width added in v0.2.0

func Width(v float64) ColumnOption

Width sets the column's target width. See the Column doc for the fraction-vs-fixed convention.

func WithAlignment added in v0.10.0

func WithAlignment(a Alignment) ColumnOption

WithAlignment is the canonical ColumnOption that sets a column's cell alignment. Replaces the four AlignXxxCol helpers — one option function with the Alignment enum is more idiomatic Go and avoids polluting the package namespace with one function per alignment value:

kardec.Col("Revenue", kardec.WithAlignment(kardec.AlignDecimal))
kardec.Col("Region",  kardec.WithAlignment(kardec.AlignRight))

AlignDecimal is the alignment that, when paired with a numeric column, aligns each cell on the decimal point: the integer part right-aligns against a pivot at 60% of the column width and the fractional part flows from the pivot. Cells without a "." fall back to right alignment so an integer row sits at the same pivot as its dotted neighbours.

type Document

type Document struct {
	// contains filtered or unexported fields
}

Document is the central builder a caller composes content onto. It holds one or more sections (a section owns a PageSetup, an optional header / footer, and a list of blocks).

A *Document is not safe for concurrent use; see the package overview.

func New

func New(size PageSize, margins Margins) *Document

New creates an empty Document with a single Section configured from the supplied page size and margins. Default orientation is Portrait.

Example

ExampleNew builds a minimal one-paragraph document.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Paragraph(kardec.Text("Hello, world."))
	_ = doc // hand off to render.Bytes / render.ToFile in real code
}

func NewWithSetup added in v0.8.0

func NewWithSetup(setup PageSetup) *Document

NewWithSetup is the explicit-PageSetup form of New. Pass a fully populated PageSetup to set the orientation, column count or inter-column gap from the start; everything else is identical to New, including the bundled-font registration.

Example

ExampleNewWithSetup configures a two-column section from the first page using a fully-populated PageSetup.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.NewWithSetup(kardec.PageSetup{
		Size:    kardec.PageA4,
		Margins: kardec.MarginsNormal,
		Columns: 2,
	}).Heading(1, kardec.Text("Reference Card"))
	_ = doc
}

func (*Document) AddHeading

func (d *Document) AddHeading(level int, runs ...Run) *HeadingBuilder

AddHeading starts a fluent Heading builder. Levels outside 1..6 are clamped, mirroring Heading.

func (*Document) Anchor added in v0.4.0

func (d *Document) Anchor(name string) *Document

Anchor appends a named destination at the current flow position. The name is matched against the "#<name>" target of internal Link runs — see Link / SetLink — and is also exposed in the PDF's named destinations table so external tools can jump directly via URL fragments.

Names should be ASCII identifiers without spaces; the writer does not escape them. An empty name is a no-op so callers can guard programmatic anchor generation without special-casing.

func (*Document) AppendMarkdown added in v0.2.0

func (d *Document) AppendMarkdown(src string) *Document

AppendMarkdown parses src as Markdown (CommonMark plus the GFM table extension) and appends the resulting blocks to the current section. Headings, paragraphs, emphasis, strong emphasis, inline code, code blocks, lists, blockquotes and tables are translated; horizontal rules become page breaks.

Current scope:

  • Lists are flattened to plain paragraphs prefixed with "• " or "1. " until a real List block lands.
  • Images and link URLs are rendered as inline text only — image embedding ships with the dedicated Image block.
  • Code blocks become paragraphs styled through StyleCode.
  • GFM tables become real Table blocks with column alignment honoured; the first row repeats on continuation pages.

Errors during parsing are captured in the document's deferred-error chain and surfaced by Err / Render.

Example

ExampleDocument_AppendMarkdown ingests CommonMark + GFM into a Document. Useful for content that arrives as Markdown from a CMS or authored by hand.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		AppendMarkdown(`# Title

Plain paragraph with *emphasis* and **strong**.

| col | val |
|---|---|
| a | 1 |
| b | 2 |
`)
	_ = doc
}

func (*Document) Author added in v0.11.0

func (d *Document) Author() string

Author returns the document author configured via SetAuthor.

func (*Document) Bibliography added in v0.8.0

func (d *Document) Bibliography(entries ...BibEntry) *Document

Bibliography appends a "References" heading followed by one paragraph per entry. Entries are emitted in citation order — the sequence in which Cite first referenced their keys — with any uncited entries appended at the end.

Each entry's anchor matches BibAnchorName(N) so the [N] link Cite returned earlier resolves correctly. The emitter always allocates numbers up to len(entries) so even uncited entries get an anchor the user can link to manually.

Format: "[N] Author. Title. Journal, Volume(Pages), Year. URL." — Vancouver-ish, easy to scan, no italic/bold for portability. Callers wanting custom formatting can pre-build blocks themselves and use Cite directly with manual anchors.

func (*Document) Bytes

func (d *Document) Bytes() ([]byte, error)

Bytes returns the rendered PDF as a byte slice. Convenient for tests and for HTTP handlers that buffer responses; for large documents callers should prefer RenderTo + io.Pipe.

func (*Document) Cite added in v0.8.0

func (d *Document) Cite(key string) Run

Cite returns a Run carrying the canonical "[N]" reference for key, where N is assigned on the first call to Cite for that key and reused on subsequent calls. The Run carries a hyperlink to the matching bibliography entry; resolution waits for Bibliography to emit the anchor at build time.

Citing an unknown key still allocates a number — the bibliography builder is allowed to come after the citations in source order. Callers can audit unresolved keys by comparing Document.CitedKeys (introduced as needed) against the entries they pass to Bibliography.

Example

ExampleDocument_Cite shows numeric citations with a Bibliography. Numbers assign on first reference and reuse on repeats; the generated [N] runs are clickable hyperlinks to the matching entry.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal)
	knuth := doc.Cite("Knuth1984")
	doc.Paragraph(
		kardec.Text("Following "),
		knuth,
		kardec.Text(", we adopt the literate model."),
	).Bibliography(
		kardec.BibEntry{
			Key:    "Knuth1984",
			Author: "Knuth, D.",
			Title:  "Literate Programming",
			Year:   1984,
		},
	)
	_ = doc
}

func (*Document) CitedKeys added in v0.8.0

func (d *Document) CitedKeys() []string

CitedKeys returns the citation keys in the order they were first referenced via Cite. Useful for cross-checking against the entries supplied to Bibliography.

func (*Document) Clause added in v0.8.0

func (d *Document) Clause(level int, runs ...Run) *Document

Clause appends a hierarchically numbered paragraph at the given level. Level 1 produces top-level numbers (1, 2, 3, ...), level 2 produces children (1.1, 1.2, 2.1, ...), and so on. The numbering follows the standard "deeper levels reset when a shallower level advances" rule — calling Clause(2) twice then Clause(1) produces 1.1 / 1.2 / 2.

Levels below 1 are clamped to 1. Skipping a level (calling Clause(3) before any Clause(2) ran) is allowed and treated as if zeroed intermediate counters were initialised on demand, mirroring most legal-document numbering tools.

The numbered text is emitted as a Paragraph with the supplied runs prepended by "N.N.N " (no period after the deepest number for level 1, period for sub-levels — matches Word's "1." / "1.1" style).

Example

ExampleDocument_Clause uses the hierarchical clause numbering helper. Clause(1) advances the top-level counter; Clause(2) opens a sub-level (1.1, 1.2, ...). Calling Clause(1) again resets the deeper counters.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Clause(1, kardec.Text("Definitions")).
		Clause(2, kardec.Text("Confidential Information")).
		Clause(2, kardec.Text("Term")).
		Clause(1, kardec.Text("Obligations"))
	_ = doc
	// The rendered output reads:
	//   1. Definitions
	//   1.1 Confidential Information
	//   1.2 Term
	//   2. Obligations
}

func (*Document) ClauseAt added in v0.8.0

func (d *Document) ClauseAt(number string, runs ...Run) *Document

ClauseAt appends a paragraph numbered with an explicit dotted label, bypassing the auto-counter. Useful for legal documents that reference a fixed clause numbering scheme not aligned with the build order.

func (*Document) CreationDate added in v0.3.0

func (d *Document) CreationDate() (time.Time, bool)

CreationDate returns the timestamp configured via SetCreationDate plus a boolean indicating whether one was set. Render reads this to decide between the fixed stamp and time.Now.

func (*Document) CurrentSection added in v0.4.0

func (d *Document) CurrentSection() *Section

CurrentSection returns the section receiving subsequent block calls. Read-only; useful for tests and integrations that need to inspect Setup or attached Header / Footer values without going through Sections().

func (*Document) DefineStyle

func (d *Document) DefineStyle(name string, s Style) *Document

DefineStyle adds or overrides a named style on the document. Subsequent blocks that resolve through name will see the new definition; existing blocks already laid out are unaffected (layout consumes resolved values at render time). Returns d for fluent chaining.

func (*Document) DisableFontSubsetting added in v0.10.0

func (d *Document) DisableFontSubsetting() *Document

DisableFontSubsetting clears the subset flag set by EnableFontSubsetting, restoring the full-font embed path.

func (*Document) DisablePDFA added in v0.10.0

func (d *Document) DisablePDFA() *Document

DisablePDFA clears the PDF/A flag set by EnablePDFA. Useful when a conditional template flips the conformance choice between renders.

func (*Document) DisableTagging added in v0.17.0

func (d *Document) DisableTagging() *Document

DisableTagging removes any prior SetTagged opt-in. Convenience for the rare callers that build documents through a templating layer that conditionally tags.

func (*Document) EnableFontSubsetting added in v0.10.0

func (d *Document) EnableFontSubsetting() *Document

EnableFontSubsetting opts the document into glyf-table subsetting: every glyph not referenced by a PlacedItem is wiped from the embedded TTF before the FontFile2 stream is FlateDecode-compressed. Real documents drop ~70% of their PDF size with this on.

func (*Document) EnablePDFA added in v0.10.0

func (d *Document) EnablePDFA() *Document

PDFA opts the document into PDF/A-2b conformance markers (XMP metadata + /ID + /Metadata catalog entry). Default off; calling with no arguments turns it on for fluent chaining.

"Lite" caveat: without an OutputIntent referencing an embedded sRGB ICC profile (a v0.6 feature) the document is not strictly PDF/A-2b — the markers are present but veraPDF flags the missing OutputIntent. Most consumer readers (Acrobat, Foxit, Chrome) honor the marker regardless. EnablePDFA opts the document into PDF/A-2b conformance markers. Replaces the variadic-bool PDFA(on ...bool) form for an idiomatic Go API. Pair with DisablePDFA when conditional code paths need to turn the flag back off.

func (*Document) Encryption added in v0.16.0

func (d *Document) Encryption() (EncryptionOptions, bool)

Encryption returns the configured EncryptionOptions plus a boolean indicating whether SetEncryption was called. Read-only; the render bridge consults this to populate pdf.Document.

func (*Document) Err

func (d *Document) Err() error

Err returns the first error captured during builder usage, or nil. Render returns the same error before attempting any I/O, so most callers can wait until Render to handle failures.

func (*Document) EvenPageFooter added in v0.23.0

func (d *Document) EvenPageFooter(runs ...Run) *Document

EvenPageFooter mirrors EvenPageHeader for the bottom of even- numbered pages.

func (*Document) EvenPageHeader added in v0.23.0

func (d *Document) EvenPageHeader(runs ...Run) *Document

EvenPageHeader sets a separate header that prints on even-numbered pages (2, 4, 6, …), overriding Header on those pages. Pair with Header for the odd pages to produce the book / two-sided layout where the title runs across the verso/recto pair.

func (*Document) FirstPageFooter added in v0.23.0

func (d *Document) FirstPageFooter(runs ...Run) *Document

FirstPageFooter mirrors FirstPageHeader for the bottom of the first page in the current section.

func (*Document) FirstPageHeader added in v0.23.0

func (d *Document) FirstPageHeader(runs ...Run) *Document

FirstPageHeader sets a separate header that prints only on the first page of the section, overriding Header for that page. Common pattern: a cover-page section that suppresses the running header, or a chapter opening with a different decorative band.

Pass an empty call (no runs) to clear a previously-set first-page header.

func (*Document) FontRegistry deprecated

func (d *Document) FontRegistry() *typography.Registry

FontRegistry exposes the underlying typography registry.

Deprecated: this leaks the internal *typography.Registry type through the public surface. Use RegisteredFamilies() for introspection. Removed at v1.0 once the renderer-injection seam migrates to an internal helper.

func (*Document) FontSubsetEnabled added in v0.5.0

func (d *Document) FontSubsetEnabled() bool

FontSubsetEnabled reports whether the next render will subset embedded fonts.

func (*Document) Footer added in v0.3.0

func (d *Document) Footer(runs ...Run) *Document

Footer mirrors Header for the bottom of every page in the current section. Same token substitutions apply.

func (*Document) Footnote added in v0.10.0

func (d *Document) Footnote(body string) Run

Footnote builds a Run that renders an auto-numbered superscript marker inline, while registering the supplied body runs for emission at the foot of the same page. Numbering increments per call and is shared with FootnoteWith / Footnote-as-method.

Use it inline in a Paragraph:

doc.Paragraph(
    kardec.Text("Sales grew "),
    doc.Footnote("see appendix B for the breakdown."),
    kardec.Text(" this quarter."),
)

func (*Document) FootnoteWith added in v0.10.0

func (d *Document) FootnoteWith(marker string, body ...Run) Run

FootnoteWith is the rich-content variant of Footnote: a caller- supplied marker (e.g. "*", "†") plus inline runs. An empty marker falls back to the auto-numbered decimal form.

func (*Document) Footnotes added in v0.4.0

func (d *Document) Footnotes() []FootnoteRef

Footnotes returns every footnote registered on the document in declaration order. The slice is the document's own backing store; callers must not mutate it.

func (*Document) Header added in v0.3.0

func (d *Document) Header(runs ...Run) *Document

Header attaches inline content reprinted at the top of every page in the current section. Pass an empty call (no runs) to clear a header previously set on the section.

The runs may carry these substitution tokens — replaced at render time with the appropriate values:

{{page}}        the 1-based page number
{{totalPages}}  the document's total page count
{{section}}     the 1-based section number (1 in single-section docs)
{{date}}        the render date in YYYY-MM-DD form

Example:

doc.Header(kardec.Text("Page {{page}} of {{totalPages}}"))

func (*Document) Heading

func (d *Document) Heading(level int, runs ...Run) *Document

Heading appends a heading block at the requested level. Levels outside 1..6 are clamped to the nearest valid value.

Example

ExampleDocument_Heading shows the level argument and text-only shortcut. Levels outside 1..6 are clamped.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Heading(1, kardec.Text("Top")).
		Heading(2, kardec.Text("Section")).
		Paragraph(kardec.Text("Body."))
	_ = doc
}

func (*Document) HorizontalRule added in v0.7.0

func (d *Document) HorizontalRule(rule ...HorizontalRule) *Document

HorizontalRule appends a horizontal divider line spanning the content width. Calling without arguments produces the default (0.5pt gray line, 6pt padding above and below); pass a populated HorizontalRule to override thickness, color, or padding.

func (*Document) ICCProfile added in v0.11.0

func (d *Document) ICCProfile() ([]byte, int)

ICCProfile returns the bytes set via SetICCProfile (or nil) plus the component count. Read-only access for the render bridge.

func (*Document) Image added in v0.2.0

func (d *Document) Image(data []byte) *ImageBuilder

Image starts an ImageBuilder from an in-memory image payload. The format is auto-detected from the leading bytes; callers needing explicit control can use AddImage with a fully-built Image value.

func (*Document) ImageFile added in v0.2.0

func (d *Document) ImageFile(path string) *ImageBuilder

ImageFile is a convenience that reads path and forwards to Image. Errors from the read are captured in the builder and surface from Build through the document's deferred-error chain.

func (*Document) KeepTogether added in v0.7.0

func (d *Document) KeepTogether(blocks ...Block) *Document

KeepTogether appends a group of inner blocks bound to the same page. The engine guarantees the supplied blocks land on the same page, or flushes once and starts the group on a fresh page when the current remaining space cannot hold them. Groups taller than a full page overflow naturally onto further pages — KeepTogether does not loop trying to find a page tall enough for an oversized group.

Example

ExampleDocument_KeepTogether binds a heading to the paragraph that follows so the two never split across pages. Use NewParagraph / NewHeading to build inner blocks outside the Document chain.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		KeepTogether(
			kardec.NewHeading(2, kardec.Text("Section")),
			kardec.NewParagraph(kardec.Text("Body that must accompany the heading.")),
		)
	_ = doc
}

func (*Document) Keywords added in v0.11.0

func (d *Document) Keywords() string

Keywords returns the keyword string configured via SetKeywords.

func (*Document) Leader added in v0.8.0

func (d *Document) Leader(left, right []Run) *Document

Leader appends a left-and-right block with a dotted fill between the two sides. Convenience wrapper over NewLeader for fluent chaining: doc.Leader([]Run{Text("Skill")}, []Run{Text("80%")}).

Example

ExampleDocument_Leader emits a one-line "left ........ right" row with a dotted fill between the two sides. Reused for CV skill bars, contract signatories, and financial line items.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Leader(
			[]kardec.Run{kardec.Text("Senior Engineer")},
			[]kardec.Run{kardec.Bold("Acme Corp")},
		)
	_ = doc
}

func (*Document) LineBreakAlgorithm added in v0.18.0

func (d *Document) LineBreakAlgorithm() LineBreakAlgorithm

LineBreakAlgorithm reports the currently configured strategy. Read by the layout engine to dispatch breakLines calls.

func (*Document) List added in v0.3.0

func (d *Document) List() *ListBuilder

List starts an unordered ListBuilder anchored to the document. The built block lands on Build.

func (*Document) MarkdownBaseDir added in v0.4.0

func (d *Document) MarkdownBaseDir() string

MarkdownBaseDir returns the configured directory or "" when none.

func (*Document) Math added in v0.3.0

func (d *Document) Math(src string) *Document

Math appends a display-style math block parsed from src. The source is the LaTeX subset documented in internal/math: greek letters, fractions, square roots, sub/superscripts, sums and integrals.

Parsing errors do not fail this call — they propagate through the document's deferred-error chain when Render is invoked, mirroring AppendMarkdown.

func (*Document) MathFont added in v0.3.0

func (d *Document) MathFont() typography.MathFont

MathFont returns the document's math-quality font face. The first call lazily loads Latin Modern Math (the GUST-OFL face bundled via `github.com/go-fonts/latin-modern/lmmath`); subsequent calls return the cached value so the layout engine can call GlyphFor / Measure / AscentDescent for every math atom without reparsing the font.

If the load fails (e.g. the upstream module ships an empty byte slice or canvas refuses the OTF), the error is folded into the document's deferred-error chain — exposed via Err and surfaced by Render — and MathFont returns nil. This mirrors the rest of the builder API where failures accumulate without panicking.

MathFont is the entry point downstream tracks (math parser, math layout) are expected to use to obtain the face attached to a Document; they should not call typography.LatinModernMath directly because that would skip the per-document caching.

func (*Document) MeasureText

func (d *Document) MeasureText(text string, family string, size Length, weight Weight, italic bool) (Length, bool)

MeasureText returns the rendered advance width of text in the requested face. The boolean is false when the family is not registered (or when no fallback face matches), letting callers distinguish a missing font from a zero-width string.

This entry point is provided for the layout track; user code rarely calls it directly.

func (*Document) NewSection added in v0.4.0

func (d *Document) NewSection(setup PageSetup) *Document

NewSection starts a new section configured from the supplied PageSetup. Subsequent block / header / footer calls land in the new section; the previous section's blocks are frozen as-is.

Use SetupOf for the common (size + margins, portrait) path:

doc.NewSection(kardec.SetupOf(kardec.PageLetter, kardec.MarginsNarrow))

or build a PageSetup directly when orientation, columns or column gap differ from the defaults:

doc.NewSection(kardec.PageSetup{
    Size:        kardec.PageA4,
    Orientation: kardec.Landscape,
    Margins:     kardec.MarginsNormal,
})

The previous (size, margins) signature was folded into this one during the v0.10 sweep so the document carries a single section constructor — old callers should migrate via SetupOf.

func (*Document) OrderedList added in v0.3.0

func (d *Document) OrderedList() *ListBuilder

OrderedList starts an ordered ListBuilder. Same shape as List with a different marker; useful when callers need a numbered list without having to tap a setter after construction.

func (*Document) PDFAEnabled added in v0.5.0

func (d *Document) PDFAEnabled() bool

PDFAEnabled reports whether PDF/A markers will be emitted.

func (*Document) PageBreak

func (d *Document) PageBreak() *Document

PageBreak appends a forced page break.

func (*Document) Paragraph

func (d *Document) Paragraph(runs ...Run) *ParagraphRef

Paragraph appends a body paragraph composed of inline runs and returns a *ParagraphRef the caller can use to layer style overrides on top of the just-appended block. The ref embeds *Document so unrelated chained methods (Heading, Image, etc.) keep working unchanged:

doc.Paragraph(kardec.Text("body"))
doc.Paragraph(kardec.Text("body")).WithStyle(myStyle).LineHeight(1.4)
doc.Paragraph(kardec.Text("a")).Heading(2, kardec.Text("next"))

The latter two forms used to require AddParagraph + Done; both are now redundant on *ParagraphRef.

Example

ExampleDocument_Paragraph layers a style override onto the just- appended paragraph using the unified ParagraphRef builder.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Paragraph(kardec.Text("Body text.")).
		WithStyle(kardec.Style{Color: kardec.HexColor("#444")}).
		LineHeight(1.5)
	_ = doc
}

func (*Document) QRCode added in v0.23.0

func (d *Document) QRCode(data string, errorLevel QRErrorLevel, size Length) *ImageBuilder

QRCode renders a QR code carrying data at the given size (a square in points) and appends it as an Image block to the current section. The block participates in the normal flow: it sits between its surrounding blocks, honours alignment via the returned ImageBuilder, and respects column / page constraints.

QR codes flow through the SVG → Form XObject path so the result stays sharp at any rendered size — important when the same document is read on screen at 100% and printed at 600 DPI.

errorLevel selects the QR error-correction tier. Higher levels produce denser codes that survive more damage (smudges, fold lines, partial coverage), at the cost of larger pixel grids. Pass kardec.QRMedium for the typical "fits a phone-camera scan reliably on print" tradeoff.

doc.QRCode("https://example.com/checkout/abc123",
    kardec.QRMedium, kardec.Pt(80)).Center().Build()

Empty data or invalid input collapses into the document's deferred error; Render surfaces it.

func (*Document) Ref added in v0.7.0

func (d *Document) Ref(label string) Run

Ref returns a Run resolving to the canonical visible reference for label — "Figure 3" or "Table 2" — with an internal hyperlink to the auto-anchor LabeledFigure / LabeledTable emitted before the matching block. Pair with RefPage when the prose also wants the destination page number.

Unknown labels resolve to "[?ref:<label>]" so missing references stand out in the rendered output. The Document does not promote missing references to a deferred error: a forward reference whose target lands later in the build is allowed by the auto-numbering model, so the lookup may legitimately fail at the moment Ref is called. Once the document is fully built, callers wanting a strict audit can iterate Document.MissingRefs (introduced when needed).

Example

ExampleDocument_Ref resolves a label set via ImageBuilder.Label (or TableBuilder.Label) into the canonical "Figure N" / "Table N" reference, plus a hyperlink to the matching anchor.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal)
	// Imagine an Image was added with .Label("growth-2024") above.
	// doc.Ref returns a Run with text "Figure N" + an internal
	// hyperlink to the auto-anchor placed before that block.
	ref := doc.Ref("growth-2024")
	doc.Paragraph(
		kardec.Text("As shown in "),
		ref,
		kardec.Text(", growth was strong."),
	)
}

func (*Document) RefPage added in v0.7.0

func (d *Document) RefPage(label string) Run

RefPage returns a Run carrying a page-number placeholder for label. The post-layout pass substitutes the placeholder with the page on which the anchor named "kardec-ref-<label>" landed. Compose with Ref when the prose wants both the canonical reference and the page:

doc.Paragraph(
    kardec.Text("See "),
    doc.Ref("growth-2024"),
    kardec.Text(" on page "),
    doc.RefPage("growth-2024"),
    kardec.Text("."),
)

Unknown labels resolve to a literal "?" placeholder.

func (*Document) RegisterFont

func (d *Document) RegisterFont(family string, weight Weight, italic bool, ttfBytes []byte) *Document

RegisterFont parses ttfBytes and registers the resulting face under the given (family, weight, italic) tuple in the Document's font registry. The first registered face becomes the default unless overridden later.

The weight argument uses the public Weight type whose values map 1:1 onto the internal typography.Weight (Regular through Black). Errors are captured in the Document's deferred error chain and surfaced by Err.

func (*Document) RegisteredFamilies added in v0.10.0

func (d *Document) RegisteredFamilies() []string

RegisteredFamilies returns the names of every font family the document's registry currently knows about, in registration order. Useful for tests and integrations that need to verify a font arrived without exposing the internal *typography.Registry.

func (*Document) Render

func (d *Document) Render(path string) error

Render produces a PDF and writes it to the named file. The file is created (or truncated) with default permissions and closed before Render returns; callers don't manage the handle.

func (*Document) RenderTo

func (d *Document) RenderTo(w io.Writer) error

RenderTo produces a PDF and writes it to the supplied io.Writer.

func (*Document) ResolveBlockStyle

func (d *Document) ResolveBlockStyle(b Block) Style

ResolveBlockStyle returns the effective Style for a Block, applying the priority chain documented in RFC-001 §6:

  1. Block-level WithStyle override (Paragraph.style / Heading.style)
  2. Block-level WithNamedStyle (Paragraph.styleName / Heading.styleName)
  3. The block kind's default named style (H1..H6 for Heading by level, Default for Paragraph)
  4. ParentStyle chain of whichever named style was selected
  5. DefaultStyle as the absolute floor

Run-level inline overrides apply during typography (per-glyph) and are therefore out of scope here.

func (*Document) ResolveStyle

func (d *Document) ResolveStyle(name string) Style

ResolveStyle returns the fully merged Style identified by name. The walk order is: the named style → its ParentStyle (recursively) → DefaultStyle at the root. Unknown names resolve through DefaultStyle alone, and a cycle in the ParentStyle chain is captured via Document.fail.

Resolution is read-only with respect to the style table; callers may invoke ResolveStyle freely without invalidating builder state.

func (*Document) Sections

func (d *Document) Sections() []*Section

Sections returns the ordered sections that compose the document. The returned slice is the document's own backing storage; callers must not mutate it.

func (*Document) SetAuthor added in v0.11.0

func (d *Document) SetAuthor(author string) *Document

SetAuthor sets the document author written to /Info /Author and dc:creator in the PDF/A XMP metadata.

func (*Document) SetBackgroundImage added in v0.23.0

func (d *Document) SetBackgroundImage(data []byte) *Document

SetBackgroundImage attaches an image that renders behind every page's content in the current section. data is the raw image bytes; format auto-detects via the same mechanism Document.Image uses (PNG / JPEG / SVG). The image is scaled to cover the full page (MediaBox) — useful for letterhead paper, decorative borders, or page-wide watermarks that exceed what the SetWatermark text stamp can express.

Pass nil data to clear a previously set background.

func (*Document) SetCreationDate added in v0.3.0

func (d *Document) SetCreationDate(t time.Time) *Document

SetCreationDate fixes the timestamp the renderer writes to the PDF's /Info /CreationDate entry. Two renders of the same Document using the same fixed timestamp produce byte-identical output — useful for reproducible builds, content-addressed caching, and hash-based diffing in CI.

Without an explicit value the renderer falls back to time.Now at emission time, which preserves the conventional behaviour but breaks byte-equality between runs.

SetCreationDate returns the document for fluent chaining.

func (*Document) SetEncryption added in v0.16.0

func (d *Document) SetEncryption(opts EncryptionOptions) *Document

SetEncryption opts the document into the PDF Standard Security Handler. The renderer wraps every stream payload (content streams, font data, image data, ToUnicode CMaps) in AES-128-CBC with a per-object key derived from the supplied passwords + permissions + document /ID.

Strings (Title, Author, Subject, Keywords, link /URI) are encrypted alongside streams (post-v0.22). The /Encrypt dict declares /StmF /StdCF /StrF /StdCF so AESV2 covers both.

Calling SetEncryption with the zero EncryptionOptions disables any prior encryption.

func (*Document) SetICCProfile added in v0.11.0

func (d *Document) SetICCProfile(profile []byte, components int) *Document

SetICCProfile attaches an ICC color profile that the writer references from the PDF /OutputIntents catalog entry when PDFA is enabled. components is the number of color components in the profile (3 for sRGB / RGB-class profiles, 4 for CMYK). Without an ICC profile, EnablePDFA emits the conformance markers but no OutputIntent — strict PDF/A-2b validators (veraPDF) flag that as non-conformant; consumer readers (Acrobat, Foxit, Chrome) accept the lite output regardless.

Pass nil + 0 to clear an earlier profile.

Profiles can be obtained from:

  • color.org (sRGB IEC 61966-2.1)
  • W3C TR/css-color-4 reference profiles
  • your operating system's color management store

Kardec does not bundle a default profile to keep the import footprint small and to avoid licensing complexity around redistributable color profiles.

func (*Document) SetKeywords added in v0.11.0

func (d *Document) SetKeywords(keywords string) *Document

SetKeywords sets a comma- or semicolon-separated list of search keywords written to /Info /Keywords and pdf:Keywords in the PDF/A XMP metadata. The exact format is not constrained by the PDF spec; "comma-separated, lowercase" is the de-facto convention.

func (*Document) SetLineBreakAlgorithm added in v0.18.0

func (d *Document) SetLineBreakAlgorithm(a LineBreakAlgorithm) *Document

SetLineBreakAlgorithm picks the paragraph line-breaking strategy the renderer uses for this document. Calling with the default LineBreakFirstFit is equivalent to never calling — the legacy greedy breaker stays in effect.

func (*Document) SetMarkdownBaseDir added in v0.4.0

func (d *Document) SetMarkdownBaseDir(dir string) *Document

SetMarkdownBaseDir configures the directory inline `![alt](path)` links resolve against during AppendMarkdown. When unset, the bridge keeps its conservative default of warning + dropping the image — the document never reaches the filesystem on its own.

func (*Document) SetSubject added in v0.11.0

func (d *Document) SetSubject(subject string) *Document

SetSubject sets the document subject (a short one-line description of the topic) written to /Info /Subject and dc:description in the PDF/A XMP metadata.

func (*Document) SetTagged added in v0.17.0

func (d *Document) SetTagged(lang string) *Document

SetTagged opts the document into PDF/UA-1 lite tagging.

When enabled, the renderer:

  • declares /MarkInfo << /Marked true >> on the catalog
  • emits a /StructTreeRoot with one /P StructElem per page
  • wraps each page's content stream in a marked-content sequence (BDC/EMC) bound to the matching StructElem via MCID
  • sets /Tabs /S on every page so assistive tech walks annotations in structure order
  • writes /Lang lang on the catalog when lang is non-empty

lang is a BCP-47 language code (e.g. "en", "pt-BR"). Strict PDF/UA-1 conformance requires the language to be declared; pass "" only when language is genuinely unknown.

v0.17.0 ships the scaffolding: every page maps to one /P element. Heading classification, figure alt text, list and table semantics land in v0.17.x as the per-block mapping is wired through the layout engine.

Calling SetTagged("") with the document already untagged is a no-op; calling it on a previously tagged document with lang == "" disables tagging entirely.

func (*Document) SetTitle added in v0.11.0

func (d *Document) SetTitle(title string) *Document

SetTitle sets the document title written to /Info /Title and to dc:title in the PDF/A XMP metadata. The title is what most PDF readers display in their window chrome and tab labels.

func (*Document) SetWatermark added in v0.20.0

func (d *Document) SetWatermark(text string, opts ...WatermarkOptions) *Document

SetWatermark stamps text diagonally across every page in the document. The renderer paints the stamp after primary content so it sits on top of body text and images; opacity blending keeps the underlying content readable.

Calling with an empty text disables any prior watermark.

Defaults applied when the corresponding WatermarkOptions field is zero:

Color    → mid-gray (#888888) so stamp reads as auxiliary
Opacity  → 0.30
AngleDeg → 45 (canonical diagonal)
FontSize → 60 pt

func (*Document) Signature added in v0.8.0

func (d *Document) Signature(name, role string) *Document

Signature is the fluent builder shortcut for SignatureBlock. Pass an empty role to omit the second line.

func (*Document) Spacer

func (d *Document) Spacer(h Length) *Document

Spacer appends vertical whitespace of the given height.

func (*Document) Subject added in v0.11.0

func (d *Document) Subject() string

Subject returns the document subject configured via SetSubject.

func (*Document) Table added in v0.2.0

func (d *Document) Table() *TableBuilder

Table starts a new TableBuilder anchored to the document. The Table block is not committed until Build is called.

Example

ExampleDocument_Table builds a small bordered table with a header row that is reprinted on every continuation page.

package main

import (
	"github.com/arthurhrc/kardec"
)

func main() {
	doc := kardec.New(kardec.PageA4, kardec.MarginsNormal).
		Table().
		Columns(kardec.Col("Region"), kardec.Col("Revenue", kardec.WithAlignment(kardec.AlignDecimal))).
		Borders(kardec.TableBordersAll).
		RepeatHeader().
		Row("Region", "Revenue").
		Row("NA", "1,234.56").
		Row("EMEA", "78.9").
		Build()
	_ = doc
}

func (*Document) TableOfContents added in v0.4.0

func (d *Document) TableOfContents(maxLevel int) *Document

TableOfContents appends an automatic table-of-contents block. The maxLevel argument caps which heading depths land in the TOC: 1 indexes only H1, 2 indexes H1 and H2, and so on. Pass 0 to include every heading regardless of depth.

The block reserves space proportional to the heading count at layout time; page numbers are patched in a post-pass once the final pagination is known.

func (*Document) Tagged added in v0.17.0

func (d *Document) Tagged() (lang string, ok bool)

Tagged reports whether SetTagged was called and returns the configured language code. The render bridge consults this to populate pdf.Document.Tagged / pdf.Document.Lang.

func (*Document) Title added in v0.11.0

func (d *Document) Title() string

Title returns the document title configured via SetTitle, or the empty string when none was set. Read-only access for layout and renderer integrations.

func (*Document) Warnings added in v0.3.0

func (d *Document) Warnings() []string

Warnings returns the document's accumulated non-fatal advisories in source order. Each entry is a human-readable sentence the builder pipeline produced when it could not render a piece of input as expected — typically Markdown nodes that the bridge does not yet honor (HTML blocks, autolinks, footnotes), or links whose destination was empty.

Warnings are non-fatal: the document still renders successfully even when this slice is non-empty. CI pipelines that want strict fidelity check `len(doc.Warnings()) == 0` after AppendMarkdown.

The returned slice is the document's own backing storage; callers must not mutate it.

func (*Document) Watermark added in v0.20.0

func (d *Document) Watermark() (text string, ok bool)

Watermark reports the configured watermark text plus a boolean indicating whether SetWatermark was called. The render bridge consults this to populate pdf.Document.Watermark.

func (*Document) WatermarkResolved deprecated added in v0.20.0

func (d *Document) WatermarkResolved() (WatermarkConfig, bool)

WatermarkResolved returns the configured watermark fields with defaults applied, plus a boolean indicating whether SetWatermark was called. Used by render to populate pdf.Document.Watermark.

Deprecated: friend-package seam. Stable while exported but the surface is expected to move internal at v1.0.

type EncryptionOptions added in v0.16.0

type EncryptionOptions struct {
	UserPassword  string
	OwnerPassword string
	Permissions   Permissions
}

EncryptionOptions configures the PDF Standard Security Handler (V=4 / R=4 / AES-128). Pass to Document.SetEncryption to opt in.

UserPassword is what readers must supply to OPEN the document. An empty user password produces a "permissions-only" PDF anyone can open but only the owner password can re-edit / re-print.

OwnerPassword authorises bypassing the permissions. Empty OwnerPassword falls back to UserPassword (which is then the only credential — common for personal docs).

Permissions controls which operations a non-owner reader is allowed to perform: print, copy, modify, fill forms, etc. The zero value disallows everything. Use the convenience AllPermissions / ReadOnlyPermissions helpers, or compose individual flags via the Permission constants.

type FootnoteRef added in v0.4.0

type FootnoteRef struct {
	// contains filtered or unexported fields
}

FootnoteRef is the inline marker (typically a small superscript numeral) referenced from body text. Layout collects every FootnoteRef encountered while laying out a page and emits the matching text at the bottom of that page, separated by a thin rule.

Numbering is sequential across the whole document. The marker text shows the auto-assigned number; callers who want a custom marker (e.g. an asterisk) use FootnoteRefMarker.

func (FootnoteRef) Body added in v0.4.0

func (f FootnoteRef) Body() []Run

Body returns the inline runs that compose the footnote text shown at the bottom of the page.

func (FootnoteRef) Marker added in v0.4.0

func (f FootnoteRef) Marker() string

Marker returns the visible label for the footnote — either the caller-supplied custom string or the decimal form of Number.

func (FootnoteRef) Number added in v0.4.0

func (f FootnoteRef) Number() int

Number returns the 1-based footnote index inside the document. Useful for tests and renderers that want to format the marker differently from the default decimal.

type Heading

type Heading struct {
	// contains filtered or unexported fields
}

Heading carries a level (1–6) and inline runs. Levels above 6 are clamped at construction time to 6, mirroring HTML conventions.

func NewHeading added in v0.7.0

func NewHeading(level int, runs ...Run) Heading

NewHeading constructs a standalone Heading block at the given level. Levels are clamped to the 1..6 range to mirror HTML conventions.

func (Heading) Level

func (h Heading) Level() int

Level returns the heading level (1..6).

func (Heading) Runs

func (h Heading) Runs() []Run

Runs returns the inline runs that make up the heading.

func (Heading) WithNamedStyle

func (h Heading) WithNamedStyle(name string) Heading

WithNamedStyle returns a copy of h that resolves through the given named style instead of the level-derived default (H1..H6).

func (Heading) WithStyle

func (h Heading) WithStyle(s Style) Heading

WithStyle returns a copy of h carrying s as an inline style override. See Paragraph.WithStyle for the resolution rules.

type HeadingBuilder

type HeadingBuilder struct {
	// contains filtered or unexported fields
}

HeadingBuilder is the fluent counterpart for Heading blocks.

func (*HeadingBuilder) Done

func (b *HeadingBuilder) Done() *Document

Done commits the heading and returns the underlying *Document.

func (*HeadingBuilder) WithNamedStyle

func (b *HeadingBuilder) WithNamedStyle(name string) *HeadingBuilder

WithNamedStyle selects a named style for resolution.

func (*HeadingBuilder) WithStyle

func (b *HeadingBuilder) WithStyle(s Style) *HeadingBuilder

WithStyle attaches an inline Style override to the heading.

type HorizontalRule added in v0.7.0

type HorizontalRule struct {
	Thickness Length // 0 means the layout default (0.5pt)
	Color     Color  // zero value (black) means the layout default (gray)
	Padding   Length // 0 means the layout default (6pt)
}

HorizontalRule is a thin filled line stretched across the content area, used to separate sections of body text. Defaults to a 0.5pt gray line with 6pt of vertical padding above and below; the zero value renders without explicit configuration.

type Image added in v0.2.0

type Image struct {
	// contains filtered or unexported fields
}

Image is the block carrying a raster image. Width and Height are expressed in PDF points; if both are zero the layout engine substitutes the image's natural pixel dimensions converted to points at 72 DPI. If exactly one is set, the other is derived from the source aspect ratio so the image is never distorted.

func (Image) Alignment added in v0.2.0

func (i Image) Alignment() Alignment

Alignment returns the horizontal placement of the image inside the page's content area.

func (Image) Data added in v0.2.0

func (i Image) Data() []byte

Data returns the raw bytes that the renderer will embed. Read-only: callers must not mutate the slice.

func (Image) Format added in v0.2.0

func (i Image) Format() ImageFormat

Format reports the on-disk encoding of Data.

func (Image) Height added in v0.2.0

func (i Image) Height() Length

Height returns the requested target height in points.

func (Image) Width added in v0.2.0

func (i Image) Width() Length

Width returns the requested target width in points (zero means "derive from height or natural size").

type ImageBuilder added in v0.2.0

type ImageBuilder struct {
	// contains filtered or unexported fields
}

ImageBuilder accumulates customisation for an image before the caller commits it to the document via Build. Functional helpers (Width / Height / Center / etc.) keep the builder fluent.

func (*ImageBuilder) AlignRight added in v0.2.0

func (b *ImageBuilder) AlignRight() *ImageBuilder

AlignRight right-aligns the image in the page's content area.

func (*ImageBuilder) Build added in v0.2.0

func (b *ImageBuilder) Build() *Document

Build appends the image to the parent document and returns the document so the caller can resume the top-level chain. Builder-side errors (read failure, unrecognised format) are folded into the document's deferred error.

When the image carries a caption (or a label), Build wraps the anchor + image + caption sequence inside a KeepTogether group so the figure and its caption never split across pages. Plain captionless, label-less images still emit as a bare Image block so existing layouts stay untouched.

func (*ImageBuilder) Caption added in v0.7.0

func (b *ImageBuilder) Caption(text string) *ImageBuilder

Caption attaches a single-string caption that renders as a centered paragraph immediately below the image. When the image also carries a label, Build prefixes the caption with the canonical "Figure N: " marker so the on-page label matches what doc.Ref(label) resolves to.

Callers needing rich runs (italics, bold) inside the caption use CaptionRuns instead.

func (*ImageBuilder) CaptionRuns added in v0.7.0

func (b *ImageBuilder) CaptionRuns(runs ...Run) *ImageBuilder

CaptionRuns is the rich-content variant of Caption: callers supply a fully-styled run sequence and Build keeps the runs intact, only prepending "Figure N: " when a label is also set.

func (*ImageBuilder) Center added in v0.2.0

func (b *ImageBuilder) Center() *ImageBuilder

Center horizontally centers the image in the page's content area.

func (*ImageBuilder) Height added in v0.2.0

func (b *ImageBuilder) Height(h Length) *ImageBuilder

Height sets the image's target height. Pair with Width for explicit sizing or call alone to derive the width from the source aspect ratio.

func (*ImageBuilder) Label added in v0.7.0

func (b *ImageBuilder) Label(name string) *ImageBuilder

Label tags the image with a cross-reference label. Build will register the label, increment the figure counter, and emit an invisible anchor immediately before the image so doc.Ref(label) hyperlinks resolve to its position in the rendered PDF. An empty label is ignored.

func (*ImageBuilder) Width added in v0.2.0

func (b *ImageBuilder) Width(w Length) *ImageBuilder

Width sets the image's target width. Pair with Height for explicit sizing or call alone to derive the height from the source aspect ratio.

type ImageFormat added in v0.2.0

type ImageFormat uint8

ImageFormat identifies the supported on-disk encodings. JPEG carries straight through into the PDF; PNG is decoded and re-encoded as raw RGB + FlateDecode (transparency is flattened against white in v0.2).

const (
	// ImageFormatUnknown is the zero value. Builders treat it as an error.
	ImageFormatUnknown ImageFormat = iota
	ImageFormatJPEG
	ImageFormatPNG
	// ImageFormatSVG is recognised by the leading XML / <svg> bytes.
	// The renderer converts a useful subset of SVG (basic shapes,
	// path subset, groups, fill/stroke) into a PDF Form XObject so
	// the embedded vector graphic stays sharp at any scale. See
	// internal/svg for the supported feature list.
	ImageFormatSVG
)

func (ImageFormat) String added in v0.2.0

func (f ImageFormat) String() string

String returns a human-readable label, mainly for error messages.

type KeepTogether added in v0.7.0

type KeepTogether struct {
	// contains filtered or unexported fields
}

KeepTogether wraps a slice of inner blocks so the layout engine guarantees they all land on the same page. The canonical use case is binding a heading to the first paragraph that follows it: the engine never produces a page that ends with the heading and starts the next page with the paragraph.

When the group is taller than a single page, KeepTogether degrades gracefully: the engine flushes once to start the group on a fresh page, then allows the inner blocks to overflow naturally onto further pages. This avoids an infinite-flush loop on oversized groups.

func NewKeepTogether added in v0.7.0

func NewKeepTogether(blocks ...Block) KeepTogether

NewKeepTogether returns a KeepTogether group containing the supplied blocks in document order. The slice is copied so further mutation by the caller does not affect the document.

func (KeepTogether) Blocks added in v0.7.0

func (k KeepTogether) Blocks() []Block

Blocks returns the inner blocks of the group. The returned slice is the group's own backing storage; callers must not mutate it.

type Leader added in v0.8.0

type Leader struct {
	// contains filtered or unexported fields
}

Leader is a one-line block that places left runs at the left margin and right runs at the right margin, filling the gap with a row of dots. The canonical use case is a "Skill........80%" or "Senator (R-CA)......$1,200,000" row in a CV / financial layout.

Construct via NewLeader; the type's fields stay unexported so future versions can add fill characters or alignment knobs without breaking callers. The block resolves its style through StyleDefault unless a named or explicit style is attached on top via WithStyle.

func NewLeader added in v0.8.0

func NewLeader(left, right []Run) Leader

NewLeader returns a Leader block with the given left and right run sequences. Pass either side empty for a one-sided dotted line.

func (Leader) Left added in v0.8.0

func (l Leader) Left() []Run

Left returns the left-aligned runs of the leader. Read-only access for layout integrations.

func (Leader) Right added in v0.8.0

func (l Leader) Right() []Run

Right returns the right-aligned runs of the leader.

type Length

type Length float64

Length is a typed dimension expressed internally in PDF user-space units (1/72 of an inch). Constructors Pt, Mm, Cm, In convert from common units.

Using a distinct type prevents accidental mixing of raw float64 sizes from different unit systems at API boundaries.

func Cm

func Cm(v float64) Length

Cm returns a Length converted from centimeters.

func In

func In(v float64) Length

In returns a Length converted from inches.

func Mm

func Mm(v float64) Length

Mm returns a Length converted from millimeters.

func Pt

func Pt(v float64) Length

Pt returns a Length expressed in PDF points (1/72 inch).

func (Length) Millimeters

func (l Length) Millimeters() float64

Millimeters returns the Length value in millimeters.

func (Length) Points

func (l Length) Points() float64

Points returns the Length value in PDF points.

type LineBreakAlgorithm added in v0.18.0

type LineBreakAlgorithm uint8

LineBreakAlgorithm selects the paragraph line-breaking strategy the renderer uses when laying out text blocks. Pass to Document.SetLineBreakAlgorithm.

The default (LineBreakFirstFit) is the v0.1-era greedy first-fit breaker plus the v0.4 Knuth-Liang hyphenation fallback. It is fast, predictable, and produces output identical to every prior release.

LineBreakOptimal switches to the Knuth-Plass DP optimum-fit algorithm: lines are chosen to minimise summed badness² across the paragraph, distributing whitespace more evenly and reducing rivers in justified text. The algorithm is O(n²) in the number of break candidates but stays sub-millisecond for paragraph-size inputs.

v0.18.0 introduces the algorithm behind a per-document feature flag so callers can opt in without disturbing existing layout fixtures. Hyphenation candidates inside long words are not yet woven into the optimal-mode DP — overflowing paragraphs fall back to the greedy breaker per-paragraph; v0.18.x will add the hyphen penalty path.

const (
	// LineBreakFirstFit keeps the legacy greedy breaker. Default.
	LineBreakFirstFit LineBreakAlgorithm = iota
	// LineBreakOptimal switches to Knuth-Plass DP optimum-fit.
	LineBreakOptimal
)

type List added in v0.3.0

type List struct {
	// contains filtered or unexported fields
}

List is a vertical sequence of bulleted or numbered items, each of which can carry inline runs and optionally nested sub-lists. The layout engine indents nested lists and rotates the bullet shape so the level is visually obvious.

func SubList added in v0.3.0

func SubList(style ListStyle, items ...ListItem) List

SubList constructs a nested List value (without committing to a document) so it can be passed to ListBuilder.Nested. The same Style rules as the top-level builder apply.

func (List) Items added in v0.3.0

func (l List) Items() []ListItem

Items returns the list's items in source order.

func (List) Style added in v0.3.0

func (l List) Style() ListStyle

Style returns the marker style for the list.

type ListBuilder added in v0.3.0

type ListBuilder struct {
	// contains filtered or unexported fields
}

ListBuilder accumulates items before the List block is appended to the parent document. Build returns the document so callers can resume the top-level chain.

func (*ListBuilder) Build added in v0.3.0

func (b *ListBuilder) Build() *Document

Build appends the constructed List to the parent document and returns the document for chained subsequent calls. An empty list (no items) appends nothing — empty lists are not an error, simply a no-op so callers can guard with conditional `Item` calls without special-casing.

func (*ListBuilder) Item added in v0.3.0

func (b *ListBuilder) Item(runs ...Run) *ListBuilder

Item appends one entry whose content is the supplied inline runs. For nested items, callers use Nested.

func (*ListBuilder) Nested added in v0.3.0

func (b *ListBuilder) Nested(runs []Run, children ...List) *ListBuilder

Nested appends an item carrying inline runs plus one or more nested sub-lists rendered indented below the item's own content. Nested lists may themselves contain further nesting; the layout engine indents one step per level.

type ListItem added in v0.3.0

type ListItem struct {
	Runs     []Run
	Children []List
}

ListItem is a single entry in a List. Runs is the inline content shown to the right of the marker; Children optionally nests another List one level deeper.

type ListStyle added in v0.3.0

type ListStyle uint8

ListStyle selects the marker used for items in a List.

const (
	// ListUnordered prefixes each item with a bullet (•). Nested
	// levels rotate through bullet, hollow circle, square.
	ListUnordered ListStyle = iota
	// ListOrdered prefixes each item with its 1-based decimal index
	// followed by a period (1., 2., 3.). Nested levels reuse the
	// same numeral by default; per-level markers may be added later.
	ListOrdered
)

type Margins

type Margins struct {
	Top, Right, Bottom, Left Length
}

Margins describes the four printable insets of a page. All four sides are independent; the symmetric presets (MarginsNarrow / Normal / Wide) are expressed in centimeters following the values Word uses by default.

func Symmetric

func Symmetric(v Length) Margins

Symmetric returns Margins where all four sides equal the same value.

type Math added in v0.3.0

type Math struct {
	// contains filtered or unexported fields
}

Math is the block carrying a LaTeX math expression. Display-style math centers the formula on its own line at the surrounding font size; inline math (planned via a Run-level constructor) flows at the surrounding x-height.

v0.3 ships display math only. Inline-flow math (mixing math runs inside a paragraph) is queued for v0.4 alongside Markdown's `$...$` parsing.

func (Math) Display added in v0.3.0

func (m Math) Display() bool

Display reports whether this Math block should be typeset in display style (large operators, limits above/below) versus inline style.

func (Math) Source added in v0.3.0

func (m Math) Source() string

Source returns the raw LaTeX text the parser will consume. Read-only access for layout / rendering integrations.

type Orientation

type Orientation uint8

Orientation defines whether a page is taller than wide (Portrait) or wider than tall (Landscape). Applied at the PageSetup level.

const (
	Portrait Orientation = iota
	Landscape
)

type PageBreak

type PageBreak struct{}

PageBreak forces the layout engine to start the next block on a new page.

type PageSetup

type PageSetup struct {
	Size        PageSize
	Orientation Orientation
	Margins     Margins

	// Columns sets the number of vertical columns that body content
	// flows through. 0 and 1 are equivalent (single-column, the
	// default). 2 produces the canonical two-column résumé / academic
	// paper layout. Headers, footers, and section chrome ignore the
	// column setting — they always span the full content width.
	Columns int

	// ColumnGap is the horizontal gap between columns. Zero means the
	// engine default (12pt — about 0.4 of a 1-em em-square at body
	// size). Ignored when Columns <= 1.
	ColumnGap Length
}

PageSetup couples a page size, orientation and margins. A Document holds one PageSetup per Section; the first Section inherits the values passed to New.

func SetupOf added in v0.10.0

func SetupOf(size PageSize, margins Margins) PageSetup

SetupOf composes a PageSetup from a size + margins pair, defaulting orientation to Portrait. Convenience for the most common NewSection invocation:

doc.NewSection(kardec.SetupOf(kardec.PageLetter, kardec.MarginsNarrow))

For explicit orientation, columns, or gap, build the PageSetup directly.

type PageSize

type PageSize struct {
	Name          string
	Width, Height Length
}

PageSize describes the printable medium dimensions before margins are subtracted. Width is the short side in Portrait, the long side in Landscape; the rendering layer swaps them based on Orientation.

func CustomPage

func CustomPage(name string, w, h Length) PageSize

CustomPage builds a non-standard PageSize. The caller is responsible for passing a sensible (width, height) pair; Kardec does not enforce minimums since some use cases (labels, badges) rely on small media.

type Paragraph

type Paragraph struct {
	// contains filtered or unexported fields
}

Paragraph is a body-text block of one or more inline Runs.

func NewParagraph added in v0.7.0

func NewParagraph(runs ...Run) Paragraph

NewParagraph constructs a standalone Paragraph block. Callers that build blocks outside the fluent Document chain — most commonly when supplying children to KeepTogether — use this. WithStyle and WithNamedStyle compose on the returned value.

func (Paragraph) Alignment

func (p Paragraph) Alignment() Alignment

Alignment returns the paragraph's alignment, or AlignLeft when the builder did not set one explicitly.

func (Paragraph) LineHeight

func (p Paragraph) LineHeight() float64

LineHeight returns the paragraph's line-height multiplier, or 0 when the style default should apply.

func (Paragraph) Runs

func (p Paragraph) Runs() []Run

Runs returns the inline runs that make up the paragraph.

func (Paragraph) WithNamedStyle

func (p Paragraph) WithNamedStyle(name string) Paragraph

WithNamedStyle returns a copy of p that resolves through the given named style before falling back to the block kind's default. Passing "" clears the named style.

func (Paragraph) WithStyle

func (p Paragraph) WithStyle(s Style) Paragraph

WithStyle returns a copy of p carrying s as an inline style override. Style resolution merges s on top of any named style and the block kind's default during layout.

type ParagraphRef added in v0.9.0

type ParagraphRef struct {
	*Document
	// contains filtered or unexported fields
}

ParagraphRef is the return type of Document.Paragraph: a thin wrapper over the just-appended Paragraph block plus the *Document the caller continues to chain off of. The Document is embedded so doc methods (Heading, Image, Table, ...) flow through field promotion without the caller ever having to drop back to a *Document value.

Style overrides on the ref mutate the appended block in place by reading the interface entry from the section's slice, mutating, and writing back. This keeps Block as a value type while still allowing retroactive configuration of the most-recently-added paragraph.

func (*ParagraphRef) Align added in v0.9.0

func (r *ParagraphRef) Align(a Alignment) *ParagraphRef

Align sets the paragraph's horizontal alignment.

func (*ParagraphRef) Justify added in v0.9.0

func (r *ParagraphRef) Justify() *ParagraphRef

Justify shortcut for AlignJustify.

func (*ParagraphRef) LineHeight added in v0.9.0

func (r *ParagraphRef) LineHeight(v float64) *ParagraphRef

LineHeight sets the paragraph's line-height multiplier (e.g. 1.4 for 140% leading). Zero clears the override and falls back to the resolved style's lineHeight.

func (*ParagraphRef) WithNamedStyle added in v0.9.0

func (r *ParagraphRef) WithNamedStyle(name string) *ParagraphRef

WithNamedStyle selects a named style for the appended paragraph.

func (*ParagraphRef) WithStyle added in v0.9.0

func (r *ParagraphRef) WithStyle(s Style) *ParagraphRef

WithStyle attaches an inline Style override to the appended paragraph.

type Permissions added in v0.16.0

type Permissions struct {
	Print             bool // bit 3 — basic print resolution
	Modify            bool // bit 4 — modify document contents
	Copy              bool // bit 5 — extract text / images
	Annotate          bool // bit 6 — add comments / annotations
	FillForms         bool // bit 9 — fill interactive form fields
	AccessibilityCopy bool // bit 10 — extract for accessibility
	AssembleDocument  bool // bit 11 — rotate / insert / delete pages
	PrintHighRes      bool // bit 12 — high-resolution print
}

Permissions enumerates the standard-security-handler permission bits per PDF 1.7 §7.6.3.2 Table 22. Each field maps to a single bit; the zero value denies everything.

func AllPermissions added in v0.16.0

func AllPermissions() Permissions

AllPermissions grants every standard permission. Useful when the caller only wants password-protection without restricting ops.

func ReadOnlyPermissions added in v0.16.0

func ReadOnlyPermissions() Permissions

ReadOnlyPermissions allows only viewing + accessibility. The canonical "no print, no copy, no modify" configuration for distribution-controlled documents.

type QRErrorLevel added in v0.23.0

type QRErrorLevel uint8

QRErrorLevel selects the QR redundancy tier. Higher levels recover from more pixel damage at the cost of a denser code.

QRLow    — 7% recovery; smallest grid; fragile.
QRMedium — 15% recovery; the spec's "M" level; standard.
QRQuart  — 25% recovery; print-grade; tolerates folds.
QRHigh   — 30% recovery; densest; for hostile environments.
const (
	QRLow QRErrorLevel = iota
	QRMedium
	QRQuart
	QRHigh
)

type Row added in v0.2.0

type Row struct {
	Cells []Cell
}

Row is one tabular line. Each entry in Cells corresponds positionally to the column slice declared on the Table.

type Run

type Run struct {
	// contains filtered or unexported fields
}

Run is an inline fragment of text with optional style overrides. Runs are the leaf content nodes that paragraphs and headings carry. Construct them via Text, Bold, Italic and similar helpers; do not instantiate the struct directly so future fields stay backward-compatible.

func Bold

func Bold(s string) Run

Bold returns a Run rendered in bold weight.

func BoldItalic

func BoldItalic(s string) Run

BoldItalic returns a Run rendered in both bold weight and italic style.

func Colored

func Colored(r Run, c Color) Run

Colored wraps a Run, attaching an explicit color override.

func InlineMath added in v0.21.0

func InlineMath(src string) Run

InlineMath returns a Run carrying a LaTeX math expression that will render at the surrounding paragraph's font size, inline with the body text. The supported subset matches Document.Math: greek letters, fractions, square roots, sub/superscripts, sums and integrals (the latter two laid out in inline style — small operators with limits at the side rather than above/below).

Use it to mix math into ordinary prose:

doc.Paragraph(
    Text("By Pythagoras, "),
    InlineMath("a^2 + b^2 = c^2"),
    Text(" for any right triangle."),
)

Parsing failures degrade to a "[math: <error>]" plain-text fallback at render time so a typo in one expression never aborts the surrounding paragraph.

func Italic

func Italic(s string) Run

Italic returns a Run rendered in italic style.

func Link(text, url string) Run

Link returns a Run that, in addition to carrying the visible text, becomes a clickable hyperlink in the rendered PDF. The url is emitted as an external `/URI` action; relative URLs are passed through unchanged so callers may target intra-document anchors via "#anchor" once the outline track exposes them.

The returned Run is plain text by default; callers may further decorate it (e.g. wrap with Colored) before adding to a paragraph.

func Strikethrough added in v0.7.0

func Strikethrough(s string) Run

Strikethrough returns a Run drawn with a thin line through its glyphs, the typographic convention for retracted text.

func Text

func Text(s string) Run

Text returns a plain Run carrying no inline overrides.

func Underline added in v0.7.0

func Underline(s string) Run

Underline returns a Run drawn with a thin line under its glyphs. Compose with Bold / Italic via the Decorate helpers when more than one inline attribute is needed.

func WithStrikethrough added in v0.7.0

func WithStrikethrough(r Run) Run

WithStrikethrough returns a copy of r with the strikethrough decoration set.

func WithUnderline added in v0.7.0

func WithUnderline(r Run) Run

WithUnderline returns a copy of r with the underline decoration set. Lets callers stack decorations on a base run without re-typing the text.

func (Run) Bold

func (r Run) Bold() bool

Bold reports whether the run carries the bold weight flag.

func (Run) ColorOverride

func (r Run) ColorOverride() (Color, bool)

ColorOverride returns the run's explicit color override, if any.

func (Run) FootnoteRef added in v0.4.0

func (r Run) FootnoteRef() int

FootnoteRef returns the 1-based footnote number this run belongs to (its visible marker), or 0 when the run is not a footnote reference. Layout uses the value to look up the matching body in Document.Footnotes.

func (Run) Italic

func (r Run) Italic() bool

Italic reports whether the run carries the italic style flag.

func (r Run) Link() string

Link returns the run's hyperlink target (its `url` argument when constructed via Link), or the empty string when the run is plain.

func (Run) MathSource added in v0.21.0

func (r Run) MathSource() string

MathSource returns the LaTeX math source carried by an inline-math Run, or "" when the Run is plain text. The layout track inspects this seam to route InlineMath runs through the math layout engine instead of the body line breaker.

func (r *Run) SetLink(url string)

SetLink replaces the run's hyperlink target in place.

Deprecated: internal seam used by AppendMarkdown to retrofit goldmark inline-link destinations onto already-walked Run children. End-user code must use the Link constructor for new content; mutating a Run after construction breaks the expected-immutable contract that other accessors assume. The method may move behind an internal helper at v1.0.

func (Run) SizeOverride

func (r Run) SizeOverride() (Length, bool)

SizeOverride returns the run's explicit size override, if any.

func (Run) Strikethrough added in v0.7.0

func (r Run) Strikethrough() bool

Strikethrough reports whether the run carries the strikethrough decoration.

func (Run) Text

func (r Run) Text() string

Text returns the textual payload of a Run.

func (Run) Underline added in v0.7.0

func (r Run) Underline() bool

Underline reports whether the run carries the underline decoration.

type Section

type Section struct {
	Setup  PageSetup
	Blocks []Block
	Header []Run
	Footer []Run

	// First-page header / footer variants. Has* distinguish
	// "no override" from "explicit empty override" so a caller
	// suppressing the running header on a cover page can pass
	// no runs and still mean it.
	FirstPageHeader    []Run
	FirstPageFooter    []Run
	HasFirstPageHeader bool
	HasFirstPageFooter bool

	// Even-page header / footer variants. Used by book-style
	// two-sided layouts where verso (even) and recto (odd)
	// carry different running content.
	EvenPageHeader    []Run
	EvenPageFooter    []Run
	HasEvenPageHeader bool
	HasEvenPageFooter bool

	// BackgroundImage is rendered behind every page's content in
	// the section. Raw image bytes (PNG/JPEG/SVG); format is
	// auto-detected.
	BackgroundImage []byte
}

Header and Footer are inline runs reprinted at the top and bottom of every page in the section. They support the token substitutions documented on Document.Header / Document.Footer.

type Spacer

type Spacer struct {
	Height Length
}

Spacer reserves vertical whitespace of the given height.

type Style

type Style struct {
	// Family is the font family name (e.g. "Liberation Sans"). Resolution
	// against an actual font registry is the typography track's concern.
	Family string

	// Size is the glyph em size; zero means "inherit".
	Size Length

	// Weight selects a face within the family.
	Weight Weight

	// Italic toggles italic/oblique style. Additive across the chain.
	Italic bool

	// Color is the glyph color.
	Color Color

	// SpaceBefore and SpaceAfter add vertical whitespace around the block.
	SpaceBefore Length
	SpaceAfter  Length

	// LineHeight is a multiplier of the font size: 1.0 = single-spaced,
	// 1.5 = one-and-a-half. Zero means "inherit".
	LineHeight float64

	// Alignment controls horizontal text arrangement.
	Alignment Alignment

	// KeepWithNext asks the layout engine not to break a page between this
	// block and the following one. Additive across the chain.
	KeepWithNext bool

	// KeepTogether asks the layout engine to render this block on a single
	// page if at all possible. Additive.
	KeepTogether bool

	// PageBreakBefore forces a page break before this block. Additive.
	PageBreakBefore bool

	// ParentStyle names the style this one inherits from. The empty string
	// means "inherit from Default" (unless this Style is itself Default).
	ParentStyle string
}

Style is the value-type carrier for every text-formatting attribute Kardec understands. Styles compose by inheritance (see Document.ResolveStyle): a child Style fills in only the fields it cares about, and missing fields fall through to the parent identified by ParentStyle.

"Missing" is encoded as the Go zero value for each field. This works because all defaults flow from the Default style, which sets every field to a sensible non-zero value; an explicit zero on a child therefore means "do not override", not "force zero". The lone exception is bool fields (Italic, KeepWithNext, KeepTogether, PageBreakBefore), which can only be true to override — they are additive.

type Table added in v0.2.0

type Table struct {
	// contains filtered or unexported fields
}

Table is a block of tabular data composed of column descriptors and rows of cells. Each cell is a slice of inline Runs, so callers can mix styled fragments inside a single cell ("R$ ", Bold("1.000")).

Borders, header shading and alternate-row shading are all opt-in via the matching TableBuilder setters. The defaults produce the same visually quiet table v0.2 shipped.

func (Table) AlternateRowShading added in v0.4.0

func (t Table) AlternateRowShading() (Color, bool)

AlternateRowShading returns the alternate-row background color and a flag indicating whether one was set. The body rows at odd indices (1, 3, 5, ...) receive the shading; the header row is never shaded through this knob, even when AlternateRowShading is set.

func (Table) BorderStyle added in v0.4.0

func (t Table) BorderStyle() TableBorderStyle

BorderStyle returns the table's selected border configuration.

func (Table) Columns added in v0.2.0

func (t Table) Columns() []Column

Columns returns the table's column descriptors. Layout code reads widths and alignments from this slice; callers should not mutate the returned values.

func (Table) HeaderShading added in v0.4.0

func (t Table) HeaderShading() (Color, bool)

HeaderShading returns the row-0 background color and a flag indicating whether one was set. Layout reads this to emit a shading rectangle behind the header row before placing text.

func (Table) RepeatHeader added in v0.2.0

func (t Table) RepeatHeader() bool

RepeatHeader reports whether the first row should be reprinted at the top of every page the table spans. Only meaningful for tables wider than one page in height.

func (Table) Rows added in v0.2.0

func (t Table) Rows() []Row

Rows returns the table's data rows in order.

type TableBorderStyle added in v0.4.0

type TableBorderStyle uint8

TableBorderStyle selects which lines the layout engine draws around and between table cells. The default zero value (BordersNone) keeps tables visually quiet — useful when the surrounding document already separates rows through whitespace.

const (
	// TableBordersNone draws no lines. Cells flow as text blocks.
	TableBordersNone TableBorderStyle = iota
	// TableBordersHorizontal draws only the rules between rows plus
	// the outer top and bottom borders. Common for typographically
	// clean tables (no vertical dividers).
	TableBordersHorizontal
	// TableBordersAll draws a full grid: outer rectangle plus every
	// row and column boundary. Closest analogue to Word's "All
	// Borders".
	TableBordersAll
)

type TableBuilder added in v0.2.0

type TableBuilder struct {
	// contains filtered or unexported fields
}

TableBuilder accumulates column descriptors, rows and rendering hints before the Table block is appended to the parent document. Build returns the document so callers can resume the top-level chain.

func (*TableBuilder) AlternateRowShading added in v0.4.0

func (b *TableBuilder) AlternateRowShading(c Color) *TableBuilder

AlternateRowShading paints a colored rectangle behind every other body row (indices 1, 3, 5, ...). The header row is never shaded by this knob — set HeaderShading separately if both are wanted.

func (*TableBuilder) Borders added in v0.4.0

func (b *TableBuilder) Borders(style TableBorderStyle) *TableBuilder

Borders selects the table's border configuration. The default zero value (BordersNone) leaves cells without lines; BordersHorizontal draws between rows plus top/bottom; BordersAll draws a full grid.

func (*TableBuilder) Build added in v0.2.0

func (b *TableBuilder) Build() *Document

Build appends the constructed Table to the parent document and returns the document for chained subsequent calls. If the builder has no columns, the document captures a deferred error and the table is not appended.

func (*TableBuilder) Columns added in v0.2.0

func (b *TableBuilder) Columns(cols ...Column) *TableBuilder

Columns sets the table's column descriptors. Subsequent calls override; the last call wins. Provide at least one column or Build will record a deferred error on the document.

func (*TableBuilder) HeaderShading added in v0.4.0

func (b *TableBuilder) HeaderShading(c Color) *TableBuilder

HeaderShading paints a colored rectangle behind the table's first row before the cell text is placed. Pair with RepeatHeader to keep the highlight visible on every continuation page.

func (*TableBuilder) Label added in v0.7.0

func (b *TableBuilder) Label(name string) *TableBuilder

Label tags the table with a cross-reference label. Build registers the label, increments the table counter, and emits an invisible anchor immediately before the table so doc.Ref(label) hyperlinks resolve to its position in the rendered PDF. An empty label is ignored.

func (*TableBuilder) RepeatHeader added in v0.2.0

func (b *TableBuilder) RepeatHeader() *TableBuilder

RepeatHeader marks the table's first row as a header that the layout engine reprints on every page the table spans.

func (*TableBuilder) Row added in v0.2.0

func (b *TableBuilder) Row(cells ...string) *TableBuilder

Row appends one row of cells. Each argument is the plain text for the corresponding column; richer cell content goes through RowCells.

func (*TableBuilder) RowCells added in v0.2.0

func (b *TableBuilder) RowCells(cells ...Cell) *TableBuilder

RowCells appends a row composed of pre-built Cell values, allowing per-cell rich runs (bold, italic, color overrides). Cells beyond the configured column count are kept; cells short of the column count are padded with empty cells at render time.

type TableOfContents added in v0.4.0

type TableOfContents struct {
	// contains filtered or unexported fields
}

TableOfContents is the block that, after layout, expands into a list of every Heading in the document with its title, a dot leader and the page number on which it appears.

The block must be placed before any heading the caller wants indexed; headings appearing before the block are skipped because their page number is already known when we reach the block, but the contract simplifies if the TOC sits at the top of the document.

Levels selects the maximum heading depth indexed (1 = H1 only, 6 = every level). Zero means "all levels".

func (TableOfContents) MaxLevel added in v0.4.0

func (t TableOfContents) MaxLevel() int

MaxLevel returns the deepest heading level included in the TOC. Zero means unlimited.

type Template added in v0.2.0

type Template struct {
	// contains filtered or unexported fields
}

Template is a Markdown source with `text/template` placeholders. Calling Render(data) executes the template against data, parses the resulting Markdown, and returns a fresh Document ready to render to PDF.

Typical usage: hold one Template, generate many Documents from a slice of records (one invoice per customer, one report per month, etc.).

tpl, err := kardec.NewTemplate(`
# Invoice {{.ID}}

**Customer:** {{.Customer.Name}}
**Total:** R$ {{.Total}}
`)
if err != nil { return err }
doc, err := tpl.Render(invoice)
if err != nil { return err }
doc.Render("invoice.pdf")

A Template is safe for concurrent use; an underlying *Document is not.

func MustNewTemplate added in v0.2.0

func MustNewTemplate(src string, opts ...TemplateOption) *Template

MustNewTemplate is the panicking variant of NewTemplate, useful for templates declared at package init where a failure must be fatal.

func NewTemplate added in v0.2.0

func NewTemplate(src string, opts ...TemplateOption) (*Template, error)

NewTemplate parses src as a Markdown template. Any text/template syntax errors are returned eagerly; field references that do not resolve are only detected at Render time.

func (*Template) Render added in v0.2.0

func (t *Template) Render(data any) (*Document, error)

Render executes the template against data, then builds a Document by feeding the rendered Markdown to AppendMarkdown. Errors in template execution are returned; errors in Markdown parsing surface through Document.Err.

type TemplateOption added in v0.2.0

type TemplateOption func(*templateOptions)

TemplateOption customizes a Template at construction time.

func WithMargins added in v0.2.0

func WithMargins(m Margins) TemplateOption

WithMargins overrides the default margins (Normal) used by documents produced from the template.

func WithName added in v0.2.0

func WithName(name string) TemplateOption

WithName labels the underlying text/template instance, surfacing the chosen name in error messages produced during Execute.

func WithPageSize added in v0.2.0

func WithPageSize(size PageSize) TemplateOption

WithPageSize overrides the default page size (A4) used by documents produced from the template.

type WatermarkConfig added in v0.20.0

type WatermarkConfig struct {
	Text     string
	Color    Color
	Opacity  float64
	AngleDeg float64
	FontSize float64
}

WatermarkConfig is the resolved per-document watermark configuration the render bridge consumes. Its fields mirror the inputs SetWatermark accepted, with defaults already filled in so callers do not need to re-derive them.

This type is the friend-package seam: the render package reads WatermarkConfig to populate the internal pdf.Watermark struct. User code rarely constructs one directly — use SetWatermark and the public WatermarkOptions instead.

type WatermarkOptions added in v0.20.0

type WatermarkOptions struct {
	Color    Color
	Opacity  float64
	AngleDeg float64
	FontSize float64
}

WatermarkOptions tunes the appearance of a document watermark. The zero value renders a sensible default (gray, 30 % opacity, 45° diagonal, 60 pt) so callers needing the canonical "DRAFT" stamp pass an empty struct.

Color is the device-RGB fill colour of the rendered glyphs. When zero (R=G=B=0 — pure black), the renderer substitutes a neutral gray so the stamp doesn't look like body text.

Opacity is in [0, 1]. Values outside that range are clamped; opacity == 1 omits the /ExtGState alpha entry (fully opaque).

AngleDeg is the counter-clockwise rotation in degrees applied around the page centre. 0 renders the watermark horizontally across the middle; 45 (the default) gives the canonical diagonal layout.

FontSize is the rendered point size. Scales with page size — landscape A3 documents may want 100+ pt for the stamp to read at thumbnail scale.

type Weight

type Weight uint8

Weight selects a font face within a family. Concrete glyph mapping happens in the typography track; here we only model the abstract weight ordinal so styles can declare intent without depending on a font registry.

The "Weight" prefix on each constant disambiguates them from same-named run helpers (Bold, Italic) that already exist in the inline content API.

const (
	WeightRegular  Weight = iota // 400 in OpenType terms
	WeightMedium                 // 500
	WeightSemiBold               // 600
	WeightBold                   // 700
	WeightBlack                  // 900
)

Weight constants follow the common five-step subset of the OpenType usWeightClass scale. Additional intermediate weights may be added later without breaking the existing names.

Directories

Path Synopsis
Package chart renders simple charts (bar, line, pie) into SVG byte streams that drop straight into a kardec.Document via Document.Image.
Package chart renders simple charts (bar, line, pie) into SVG byte streams that drop straight into a kardec.Document via Document.Image.
cmd
kardec command
Command kardec is a CLI front-end for the Kardec library.
Command kardec is a CLI front-end for the Kardec library.
reprocheck command
Command reprocheck renders a canonical Kardec document twice with a pinned creation date and asserts both renders produce identical bytes.
Command reprocheck renders a canonical Kardec document twice with a pinned creation date and asserts both renders produce identical bytes.
examples
bookstyle command
Bookstyle demonstrates two book-grade chrome features:
Bookstyle demonstrates two book-grade chrome features:
chart command
Chart demonstrates kardec/chart — bar, line, and pie charts rendered as SVG and embedded as vector Form XObjects.
Chart demonstrates kardec/chart — bar, line, and pie charts rendered as SVG and embedded as vector Form XObjects.
encryption command
Encryption demonstrates Kardec's PDF Standard Security Handler integration.
Encryption demonstrates Kardec's PDF Standard Security Handler integration.
hello command
Hello demonstrates the smallest meaningful Kardec document.
Hello demonstrates the smallest meaningful Kardec document.
image command
Image demonstrates the raster-image embedding pipeline.
Image demonstrates the raster-image embedding pipeline.
inlinemath command
InlineMath demonstrates Kardec's Run-level math: a LaTeX expression embedded inside a paragraph, sitting on the body baseline next to surrounding prose.
InlineMath demonstrates Kardec's Run-level math: a LaTeX expression embedded inside a paragraph, sitting on the body baseline next to surrounding prose.
invoice command
Invoice demonstrates Kardec's templating layer: a single Markdown template renders one PDF per record.
Invoice demonstrates Kardec's templating layer: a single Markdown template renders one PDF per record.
markdown command
Markdown demonstrates AppendMarkdown — feeding raw CommonMark to a Document and rendering the result.
Markdown demonstrates AppendMarkdown — feeding raw CommonMark to a Document and rendering the result.
math command
Math demonstrates the LaTeX math subset shipping in v0.3.
Math demonstrates the LaTeX math subset shipping in v0.3.
qrcode command
QRCode demonstrates Kardec's built-in QR encoder.
QRCode demonstrates Kardec's built-in QR encoder.
report command
Report builds a multi-page document that exercises Kardec's style system end-to-end: a corporate-blue heading scale, a colored body run, page breaks between sections, and a code-style monospace block.
Report builds a multi-page document that exercises Kardec's style system end-to-end: a corporate-blue heading scale, a colored body run, page breaks between sections, and a code-style monospace block.
signature command
Signature demonstrates the kardec/sign subpackage: render a PDF, then apply a PKCS#7 detached signature so Acrobat (and ICP-Brasil-aware viewers) report it as "Signed by X".
Signature demonstrates the kardec/sign subpackage: render a PDF, then apply a PKCS#7 detached signature so Acrobat (and ICP-Brasil-aware viewers) report it as "Signed by X".
svg command
SVG demonstrates Kardec's vector SVG embedding.
SVG demonstrates Kardec's vector SVG embedding.
tagged command
Tagged demonstrates Kardec's PDF/UA tagging integration.
Tagged demonstrates Kardec's PDF/UA tagging integration.
templates_invoice command
Templates demonstrates the ready-made document scaffolds shipped under kardec/templates.
Templates demonstrates the ready-made document scaffolds shipped under kardec/templates.
watermark command
Watermark demonstrates Kardec's per-page diagonal watermark stamp.
Watermark demonstrates Kardec's per-page diagonal watermark stamp.
Package httpx is the three-line ergonomic helper every Go shop pastes into their first PDF endpoint.
Package httpx is the three-line ergonomic helper every Go shop pastes into their first PDF endpoint.
internal
hyphenation
Package hyphenation produces candidate break points for words that would otherwise overflow a line.
Package hyphenation produces candidate break points for words that would otherwise overflow a line.
layout
Package layout turns a Kardec Document tree into positioned glyph runs ready for the PDF writer track to emit.
Package layout turns a Kardec Document tree into positioned glyph runs ready for the PDF writer track to emit.
math
Package math models a small, well-defined subset of LaTeX-style math source as a typed expression tree.
Package math models a small, well-defined subset of LaTeX-style math source as a typed expression tree.
mathadapter
Package mathadapter wraps the parser's concrete AST nodes (internal/math) into the interface shape the layout engine (internal/mathlayout) expects, and bridges typography.MathFont onto mathlayout.Font.
Package mathadapter wraps the parser's concrete AST nodes (internal/math) into the interface shape the layout engine (internal/mathlayout) expects, and bridges typography.MathFont onto mathlayout.Font.
mathlayout
Package mathlayout positions a math expression tree into a tree of boxes ready for the renderer.
Package mathlayout positions a math expression tree into a tree of boxes ready for the renderer.
pdf
Package pdf is Kardec's PDF 1.7 writer.
Package pdf is Kardec's PDF 1.7 writer.
svg
Package svg converts a small subset of SVG into the PDF graphics operators a Form XObject content stream consumes.
Package svg converts a small subset of SVG into the PDF graphics operators a Form XObject content stream consumes.
typography
Package typography is the internal font registry, embedded font bundle, and OpenType measurement layer that backs the public Kardec DSL.
Package typography is the internal font registry, embedded font bundle, and OpenType measurement layer that backs the public Kardec DSL.
Package render is the orchestrator that turns a kardec.Document into a PDF byte stream.
Package render is the orchestrator that turns a kardec.Document into a PDF byte stream.
Package sign attaches a PKCS#7 detached signature to a kardec-rendered PDF, producing a document Adobe Acrobat (and every other PDF reader that respects signatures) reports as "Signed by <X>".
Package sign attaches a PKCS#7 detached signature to a kardec-rendered PDF, producing a document Adobe Acrobat (and every other PDF reader that respects signatures) reports as "Signed by <X>".
Package templates ships ready-made document scaffolds — Invoice, Certificate, Report, Contract — that cover the most common real-world "I need a PDF for X" cases.
Package templates ships ready-made document scaffolds — Invoice, Certificate, Report, Contract — that cover the most common real-world "I need a PDF for X" cases.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL