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
}
Output:
Index ¶
- Constants
- Variables
- func BibAnchorName(num int) string
- func BuiltinStyles() map[string]Style
- func HeadingStyleName(level int) string
- func RefAnchorName(label string) string
- func SetRenderImpl(f func(*Document, io.Writer) error)deprecated
- type Alignment
- type Anchor
- type BibEntry
- type Block
- type Cell
- type Color
- type Column
- type ColumnOption
- type Document
- func (d *Document) AddHeading(level int, runs ...Run) *HeadingBuilder
- func (d *Document) Anchor(name string) *Document
- func (d *Document) AppendMarkdown(src string) *Document
- func (d *Document) Author() string
- func (d *Document) Bibliography(entries ...BibEntry) *Document
- func (d *Document) Bytes() ([]byte, error)
- func (d *Document) Cite(key string) Run
- func (d *Document) CitedKeys() []string
- func (d *Document) Clause(level int, runs ...Run) *Document
- func (d *Document) ClauseAt(number string, runs ...Run) *Document
- func (d *Document) CreationDate() (time.Time, bool)
- func (d *Document) CurrentSection() *Section
- func (d *Document) DefineStyle(name string, s Style) *Document
- func (d *Document) DisableFontSubsetting() *Document
- func (d *Document) DisablePDFA() *Document
- func (d *Document) DisableTagging() *Document
- func (d *Document) EnableFontSubsetting() *Document
- func (d *Document) EnablePDFA() *Document
- func (d *Document) Encryption() (EncryptionOptions, bool)
- func (d *Document) Err() error
- func (d *Document) EvenPageFooter(runs ...Run) *Document
- func (d *Document) EvenPageHeader(runs ...Run) *Document
- func (d *Document) FirstPageFooter(runs ...Run) *Document
- func (d *Document) FirstPageHeader(runs ...Run) *Document
- func (d *Document) FontRegistry() *typography.Registrydeprecated
- func (d *Document) FontSubsetEnabled() bool
- func (d *Document) Footer(runs ...Run) *Document
- func (d *Document) Footnote(body string) Run
- func (d *Document) FootnoteWith(marker string, body ...Run) Run
- func (d *Document) Footnotes() []FootnoteRef
- func (d *Document) Header(runs ...Run) *Document
- func (d *Document) Heading(level int, runs ...Run) *Document
- func (d *Document) HorizontalRule(rule ...HorizontalRule) *Document
- func (d *Document) ICCProfile() ([]byte, int)
- func (d *Document) Image(data []byte) *ImageBuilder
- func (d *Document) ImageFile(path string) *ImageBuilder
- func (d *Document) KeepTogether(blocks ...Block) *Document
- func (d *Document) Keywords() string
- func (d *Document) Leader(left, right []Run) *Document
- func (d *Document) LineBreakAlgorithm() LineBreakAlgorithm
- func (d *Document) List() *ListBuilder
- func (d *Document) MarkdownBaseDir() string
- func (d *Document) Math(src string) *Document
- func (d *Document) MathFont() typography.MathFont
- func (d *Document) MeasureText(text string, family string, size Length, weight Weight, italic bool) (Length, bool)
- func (d *Document) NewSection(setup PageSetup) *Document
- func (d *Document) OrderedList() *ListBuilder
- func (d *Document) PDFAEnabled() bool
- func (d *Document) PageBreak() *Document
- func (d *Document) Paragraph(runs ...Run) *ParagraphRef
- func (d *Document) QRCode(data string, errorLevel QRErrorLevel, size Length) *ImageBuilder
- func (d *Document) Ref(label string) Run
- func (d *Document) RefPage(label string) Run
- func (d *Document) RegisterFont(family string, weight Weight, italic bool, ttfBytes []byte) *Document
- func (d *Document) RegisteredFamilies() []string
- func (d *Document) Render(path string) error
- func (d *Document) RenderTo(w io.Writer) error
- func (d *Document) ResolveBlockStyle(b Block) Style
- func (d *Document) ResolveStyle(name string) Style
- func (d *Document) Sections() []*Section
- func (d *Document) SetAuthor(author string) *Document
- func (d *Document) SetBackgroundImage(data []byte) *Document
- func (d *Document) SetCreationDate(t time.Time) *Document
- func (d *Document) SetEncryption(opts EncryptionOptions) *Document
- func (d *Document) SetICCProfile(profile []byte, components int) *Document
- func (d *Document) SetKeywords(keywords string) *Document
- func (d *Document) SetLineBreakAlgorithm(a LineBreakAlgorithm) *Document
- func (d *Document) SetMarkdownBaseDir(dir string) *Document
- func (d *Document) SetSubject(subject string) *Document
- func (d *Document) SetTagged(lang string) *Document
- func (d *Document) SetTitle(title string) *Document
- func (d *Document) SetWatermark(text string, opts ...WatermarkOptions) *Document
- func (d *Document) Signature(name, role string) *Document
- func (d *Document) Spacer(h Length) *Document
- func (d *Document) Subject() string
- func (d *Document) Table() *TableBuilder
- func (d *Document) TableOfContents(maxLevel int) *Document
- func (d *Document) Tagged() (lang string, ok bool)
- func (d *Document) Title() string
- func (d *Document) Warnings() []string
- func (d *Document) Watermark() (text string, ok bool)
- func (d *Document) WatermarkResolved() (WatermarkConfig, bool)deprecated
- type EncryptionOptions
- type FootnoteRef
- type Heading
- type HeadingBuilder
- type HorizontalRule
- type Image
- type ImageBuilder
- func (b *ImageBuilder) AlignRight() *ImageBuilder
- func (b *ImageBuilder) Build() *Document
- func (b *ImageBuilder) Caption(text string) *ImageBuilder
- func (b *ImageBuilder) CaptionRuns(runs ...Run) *ImageBuilder
- func (b *ImageBuilder) Center() *ImageBuilder
- func (b *ImageBuilder) Height(h Length) *ImageBuilder
- func (b *ImageBuilder) Label(name string) *ImageBuilder
- func (b *ImageBuilder) Width(w Length) *ImageBuilder
- type ImageFormat
- type KeepTogether
- type Leader
- type Length
- type LineBreakAlgorithm
- type List
- type ListBuilder
- type ListItem
- type ListStyle
- type Margins
- type Math
- type Orientation
- type PageBreak
- type PageSetup
- type PageSize
- type Paragraph
- type ParagraphRef
- type Permissions
- type QRErrorLevel
- type Row
- type Run
- func Bold(s string) Run
- func BoldItalic(s string) Run
- func Colored(r Run, c Color) Run
- func InlineMath(src string) Run
- func Italic(s string) Run
- func Link(text, url string) Run
- func Strikethrough(s string) Run
- func Text(s string) Run
- func Underline(s string) Run
- func WithStrikethrough(r Run) Run
- func WithUnderline(r Run) Run
- func (r Run) Bold() bool
- func (r Run) ColorOverride() (Color, bool)
- func (r Run) FootnoteRef() int
- func (r Run) Italic() bool
- func (r Run) Link() string
- func (r Run) MathSource() string
- func (r *Run) SetLink(url string)deprecated
- func (r Run) SizeOverride() (Length, bool)
- func (r Run) Strikethrough() bool
- func (r Run) Text() string
- func (r Run) Underline() bool
- type Section
- type Spacer
- type Style
- type Table
- type TableBorderStyle
- type TableBuilder
- func (b *TableBuilder) AlternateRowShading(c Color) *TableBuilder
- func (b *TableBuilder) Borders(style TableBorderStyle) *TableBuilder
- func (b *TableBuilder) Build() *Document
- func (b *TableBuilder) Columns(cols ...Column) *TableBuilder
- func (b *TableBuilder) HeaderShading(c Color) *TableBuilder
- func (b *TableBuilder) Label(name string) *TableBuilder
- func (b *TableBuilder) RepeatHeader() *TableBuilder
- func (b *TableBuilder) Row(cells ...string) *TableBuilder
- func (b *TableBuilder) RowCells(cells ...Cell) *TableBuilder
- type TableOfContents
- type Template
- type TemplateOption
- type WatermarkConfig
- type WatermarkOptions
- type Weight
Examples ¶
Constants ¶
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:" )
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" 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.
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.
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 ¶
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.
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.
var ( MarginsNarrow = Symmetric(Cm(1.27)) MarginsNormal = Symmetric(Cm(2.54)) MarginsWide = Symmetric(Cm(5.08)) )
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.
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
BibAnchorName returns the anchor name Bibliography emits for the given 1-based citation number.
func BuiltinStyles ¶
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 ¶
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
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
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.
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
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
}
Output:
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
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
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.
type Column ¶ added in v0.2.0
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 ¶
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
}
Output:
func NewWithSetup ¶ added in v0.8.0
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
}
Output:
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
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
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
}
Output:
func (*Document) Author ¶ added in v0.11.0
Author returns the document author configured via SetAuthor.
func (*Document) Bibliography ¶ added in v0.8.0
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 ¶
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
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
}
Output:
func (*Document) CitedKeys ¶ added in v0.8.0
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
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
}
Output:
func (*Document) ClauseAt ¶ added in v0.8.0
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
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
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 ¶
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
DisableFontSubsetting clears the subset flag set by EnableFontSubsetting, restoring the full-font embed path.
func (*Document) DisablePDFA ¶ added in v0.10.0
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
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
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
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 ¶
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
EvenPageFooter mirrors EvenPageHeader for the bottom of even- numbered pages.
func (*Document) EvenPageHeader ¶ added in v0.23.0
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
FirstPageFooter mirrors FirstPageHeader for the bottom of the first page in the current section.
func (*Document) FirstPageHeader ¶ added in v0.23.0
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
FontSubsetEnabled reports whether the next render will subset embedded fonts.
func (*Document) Footer ¶ added in v0.3.0
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
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
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
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 ¶
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
}
Output:
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
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
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
}
Output:
func (*Document) Keywords ¶ added in v0.11.0
Keywords returns the keyword string configured via SetKeywords.
func (*Document) Leader ¶ added in v0.8.0
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
}
Output:
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
MarkdownBaseDir returns the configured directory or "" when none.
func (*Document) Math ¶ added in v0.3.0
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
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
PDFAEnabled reports whether PDF/A markers will be emitted.
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
}
Output:
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
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."),
)
}
Output:
func (*Document) RefPage ¶ added in v0.7.0
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
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 ¶
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) ResolveBlockStyle ¶
ResolveBlockStyle returns the effective Style for a Block, applying the priority chain documented in RFC-001 §6:
- Block-level WithStyle override (Paragraph.style / Heading.style)
- Block-level WithNamedStyle (Paragraph.styleName / Heading.styleName)
- The block kind's default named style (H1..H6 for Heading by level, Default for Paragraph)
- ParentStyle chain of whichever named style was selected
- DefaultStyle as the absolute floor
Run-level inline overrides apply during typography (per-glyph) and are therefore out of scope here.
func (*Document) ResolveStyle ¶
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 ¶
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
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
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
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
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
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
SetMarkdownBaseDir configures the directory inline `` 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
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
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
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
Signature is the fluent builder shortcut for SignatureBlock. Pass an empty role to omit the second line.
func (*Document) Subject ¶ added in v0.11.0
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
}
Output:
func (*Document) TableOfContents ¶ added in v0.4.0
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
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
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
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
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
NewHeading constructs a standalone Heading block at the given level. Levels are clamped to the 1..6 range to mirror HTML conventions.
func (Heading) WithNamedStyle ¶
WithNamedStyle returns a copy of h that resolves through the given named style instead of the level-derived default (H1..H6).
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
Alignment returns the horizontal placement of the image inside the page's content area.
func (Image) Data ¶ added in v0.2.0
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.
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
NewLeader returns a Leader block with the given left and right run sequences. Pass either side empty for a one-sided dotted line.
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 (Length) Millimeters ¶
Millimeters returns the Length value in millimeters.
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
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.
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
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.
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.
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
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 ¶
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 ¶
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
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 ¶
Alignment returns the paragraph's alignment, or AlignLeft when the builder did not set one explicitly.
func (Paragraph) LineHeight ¶
LineHeight returns the paragraph's line-height multiplier, or 0 when the style default should apply.
func (Paragraph) WithNamedStyle ¶
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.
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 BoldItalic ¶
BoldItalic returns a Run rendered in both bold weight and italic style.
func InlineMath ¶ added in v0.21.0
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 Link ¶ added in v0.3.0
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
Strikethrough returns a Run drawn with a thin line through its glyphs, the typographic convention for retracted text.
func Underline ¶ added in v0.7.0
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
WithStrikethrough returns a copy of r with the strikethrough decoration set.
func WithUnderline ¶ added in v0.7.0
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) ColorOverride ¶
ColorOverride returns the run's explicit color override, if any.
func (Run) FootnoteRef ¶ added in v0.4.0
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) Link ¶ added in v0.3.0
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
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 (*Run) SetLink
deprecated
added in
v0.3.0
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 ¶
SizeOverride returns the run's explicit size override, if any.
func (Run) Strikethrough ¶ added in v0.7.0
Strikethrough reports whether the run carries the strikethrough decoration.
type Section ¶
type Section struct {
Setup PageSetup
Blocks []Block
Header []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
HasFirstPageHeader 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
HasEvenPageHeader 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
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
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
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
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.
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.
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
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.
Source Files
¶
- bibliography.go
- block.go
- clause.go
- color.go
- crossref.go
- determinism.go
- doc.go
- document.go
- encryption.go
- footnote.go
- image.go
- internal_access.go
- length.go
- linebreak.go
- list.go
- markdown.go
- math.go
- math_font.go
- metadata.go
- page.go
- qrcode.go
- run.go
- section.go
- signature.go
- style.go
- table.go
- tagged.go
- template.go
- toc.go
- typography.go
- warnings.go
- watermark.go
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. |