frontend module

The glu.frontend module

The glu.frontend module provides a high-level interface for creating PDF documents. It allows you to create and manipulate text, tables, and other elements. Fonts are organized in font families, and settings like font weight and style are handled automatically.

local frontend = require("glu.frontend")

Module functions

Name Parameters Description
frontend.new() filename (string) Create a new document
frontend.text() [settings] (table) Create a new Text object
frontend.fontsource() options (table) Create a new font source
frontend.table() options (table) Create a new Table object
frontend.color() options (table) Create a new Color object
frontend.sp() points (number) Create a ScaledPoint from points
frontend.sp_string() dimension (string) Create a ScaledPoint from string

ScaledPoint

ScaledPoint is a type-safe dimension type that prevents confusion between raw numbers and dimensions. It wraps the internal scaled point unit (1/65536 of a DTP point).

Creating ScaledPoints

local frontend = require("glu.frontend")

-- From points (number)
local sp1 = frontend.sp(72)           -- 72 points = 1 inch

-- From string with unit
local sp2 = frontend.sp_string("2cm")
local sp3 = frontend.sp_string("10mm")
local sp4 = frontend.sp_string("1in")
local sp5 = frontend.sp_string("72pt")

Arithmetic operations

ScaledPoints support arithmetic with other ScaledPoints, strings with units, and numbers (interpreted as points):

local sp = frontend.sp_string("10cm")

-- ScaledPoint operations
local sp2 = frontend.sp_string("2cm")
local result = sp + sp2              -- ScaledPoint + ScaledPoint
local diff = sp - sp2                -- ScaledPoint - ScaledPoint

-- Mixed operations with strings
local wider = sp + "5mm"             -- ScaledPoint + string
local narrower = sp - "1cm"          -- ScaledPoint - string

-- Operations with numbers (interpreted as points)
local adjusted = sp + 72             -- adds 72 points (1 inch)
local half = sp / 2                  -- ScaledPoint / number
local doubled = sp * 2               -- ScaledPoint * number
local neg = -sp                      -- unary minus

-- Division of two ScaledPoints returns a ratio (number)
local ratio = sp / sp2               -- returns 5.0

Comparison operations

local a = frontend.sp_string("5cm")
local b = frontend.sp_string("50mm")

print(a == b)    -- true (5cm equals 50mm)
print(a < b)     -- false
print(a <= b)    -- true

Conversion methods

local sp = frontend.sp_string("2.54cm")  -- 1 inch

-- Properties (read-only)
print(sp.pt)     -- 72.0 (value in points)
print(sp.sp)     -- 4718592 (raw scaled point value)

-- Methods
print(sp:to_pt())  -- 72.0
print(sp:to_mm())  -- 25.4
print(sp:to_cm())  -- 2.54
print(sp:to_in())  -- 1.0

-- String representation
print(sp)          -- "72pt"

Usage with dimensions

All dimension parameters (page sizes, positions, font sizes, etc.) accept ScaledPoints directly:

local page = doc:new_page()
page.width = frontend.sp_string("210mm")
page.height = frontend.sp_string("297mm")

-- Arithmetic in output_at
local margin = frontend.sp_string("2cm")
local y = frontend.sp_string("28cm")
page:output_at(margin, y - "1cm", vlist)

-- Reading dimensions returns ScaledPoints
local w = page.width           -- ScaledPoint
local h = vlist.height         -- ScaledPoint
local new_y = y - h - "5mm"    -- arithmetic with ScaledPoints and strings

Document

local frontend = require("glu.frontend")
local doc = frontend.new("output.pdf")

Attributes

Name R/W Type Description
title R/W string Document title
author R/W string Document author
subject R/W string Document subject
creator R/W string Creator application
keywords R/W string Document keywords
format R/W string PDF format (see below)
language W Language Default document language
additional_xml_metadata R/W string Additional XMP metadata

Format values: "PDF", "PDF/A-3b", "PDF/X-3", "PDF/X-4", "PDF/UA"

Methods

Name Parameters Returns Description
new_font_family() name (string) FontFamily Create a new font family
find_font_family() name (string) FontFamily Find an existing font family
create_text() - Text Create a new Text object
format_paragraph() text, width, [options] VList, info Format text into a paragraph
build_table() table VList array Build a table
define_color() name (string), color - Define a named color
get_color() spec (string) Color Get color by name or CSS value
get_language() name (string) Language Get language for hyphenation
new_page() - Page Create a new page
load_imagefile() filename, [page], [box] Imagefile Load an image or PDF file
create_image_node() imagefile, [page], [box] ImageNode Create image node for placement
load_colorprofile() filename ColorProfile Load ICC color profile
attach_file() options (table) - Attach a file to the PDF
finish() - - Finalize the PDF

format_paragraph()

local vlist, info = doc:format_paragraph(text, width, options)
Parameter Type Description
text Text object The text to format
width dimension The width of the paragraph
options table Optional settings (see below)

Options table:

Name Type Description
leading dimension Line height
font_size dimension Font size
font_family FontFamily Font family to use
language Language Language for hyphenation
halign string Horizontal alignment
indent_left dimension Left indentation

Text

local txt = frontend.text()

Attributes

Name R/W Type Description
items W table Set content items (strings, Text, etc.)
settings R proxy Access settings via txt.settings.key

Methods

Name Parameters Returns Description
append() item, … self Append strings, Text, VList, or Table
set() key, value self Set a single setting (chainable)
apply() table self Set multiple settings at once (chainable)

Setting text properties

There are several ways to set text properties:

-- 1. In the constructor (recommended)
local txt = frontend.text({
    font_family = ff,
    font_size = "12pt",
    color = "black"
})

-- 2. Using set() with chaining
local txt = frontend.text()
    :set("font_family", ff)
    :set("font_size", "12pt")
    :set("color", "black")

-- 3. Using settings proxy - for individual assignments
local txt = frontend.text()
txt.settings.font_family = ff
txt.settings.font_size = "12pt"
txt.settings.color = "black"

-- 4. Using apply() to add settings later
local txt = frontend.text()
txt:apply({
    font_family = ff,
    font_size = "12pt"
})

You can set items directly or use append:

-- Using items property
txt.items = {"Hello, ", boldText, "!"}

-- Using append (chainable)
txt:append("Hello, ", boldText, "!")

Text settings

Name Type Description
font_family FontFamily The font family to use
font_size dimension Font size (e.g. 12 or "12pt")
font_weight string or int "regular", "bold", or 100-900
font_style string "normal" or "italic"
color string or Color Text color
leading dimension Line height
halign string "left", "right", "center", "justified"
valign string "top", "middle", "bottom"
margin_left dimension Left margin
margin_right dimension Right margin
margin_top dimension Top margin
margin_bottom dimension Bottom margin
padding_left dimension Left padding
padding_right dimension Right padding
padding_top dimension Top padding
padding_bottom dimension Bottom padding
background_color string or Color Background color
hyperlink string URL for hyperlink
underline boolean Underline text
line_through boolean Strikethrough text

Example:

local txt = frontend.text({
    font_family = ff,
    font_size = "12pt",
    color = "rebeccapurple"
})
txt:append("Hello, ")

-- Nested styled text
local bold = frontend.text({ font_weight = "bold" })
bold:append("world")

txt:append(bold, "!")

FontFamily

local ff = doc:new_font_family("body")

Methods

Name Parameters Returns Description
add_member() fontsource, weight, style self Add a font to the family

FontSource

local fs = frontend.fontsource({
    location = "path/to/font.ttf",
    index = 0,           -- optional, for font collections
    size_adjust = 1.0,   -- optional
    features = {"kern", "liga"}  -- optional OpenType features
})
ff:add_member(fs, "regular", "normal")
ff:add_member(fs_bold, "bold", "normal")
ff:add_member(fs_italic, "regular", "italic")

-- Alternative: table-based add_member
ff:add_member({ source = fs, weight = 400, style = "normal" })

Weight values: "regular", "bold", or numbers 100 - 900

Style values: "normal", "italic"

Page

local page = doc:new_page()

Attributes

Name R/W Type Description
width R/W ScaledPoint Page width (returns ScaledPoint on read)
height R/W ScaledPoint Page height (returns ScaledPoint on read)

Methods

Name Parameters Returns Description
output_at() x, y, vlist self Place VList at position
shipout() - - Finalize the page

Example:

local page = doc:new_page()
page.width = "21cm"
page.height = "29.7cm"
page:output_at("2cm", "27cm", vlist)
page:shipout()

Table

local tbl = frontend.table({
    max_width = "15cm",
    stretch = true,
    font_family = ff,
    font_size = "10pt",
    leading = "12pt"
})

Methods

Name Parameters Returns Description
set_columns() widths (table) self Set column widths
add_row() - TableRow Add a new row

TableRow Methods

Name Parameters Returns Description
add_cell() - TableCell Add a new cell

TableCell Attributes

Name R/W Type Description
halign R/W string Horizontal alignment
valign R/W string Vertical alignment
colspan R/W integer Column span
rowspan R/W integer Row span
padding_left W dimension Left padding
padding_right W dimension Right padding
padding_top W dimension Top padding
padding_bottom W dimension Bottom padding
border_left_width W dimension Left border width
border_right_width W dimension Right border width
border_top_width W dimension Top border width
border_bottom_width W dimension Bottom border width

TableCell Methods

Name Parameters Returns Description
set_contents() item, … self Set cell contents

Example:

local tbl = frontend.table({ max_width = "15cm" })
tbl:set_columns({ "5cm", "10cm" })

local row = tbl:add_row()
local cell1 = row:add_cell()
cell1:set_contents("Column 1")
cell1.halign = "left"

local cell2 = row:add_cell()
cell2:set_contents("Column 2")

local vlists = doc:build_table(tbl)
for _, vl in ipairs(vlists) do
    page:output_at("2cm", y, vl)
end

VList

A VList (vertical list) is the result of formatting text or building tables. It contains the typeset content ready for placement on a page.

local vlist, info = doc:format_paragraph(text, "15cm", { leading = "14pt" })
page:output_at("2cm", "27cm", vlist)

Attributes

Name R Type Description
width R ScaledPoint Width of the VList
height R ScaledPoint Height of the VList
depth R ScaledPoint Depth of the VList

The dimension attributes return ScaledPoint values, allowing arithmetic operations:

local vlist = doc:format_paragraph(text, "15cm")
local y = frontend.sp_string("28cm")

-- Position next element below the vlist
local next_y = y - vlist.height - "5mm"
page:output_at("2cm", next_y, next_vlist)

Color

local red = frontend.color({
    model = "rgb",
    r = 1.0, g = 0.0, b = 0.0
})

local cyan = frontend.color({
    model = "cmyk",
    c = 1.0, m = 0.0, y = 0.0, k = 0.0
})

local gray = frontend.color({
    model = "gray",
    g = 0.5
})

doc:define_color("myred", red)
local col = doc:get_color("myred")
local blue = doc:get_color("#0000ff")

Language

local en = doc:get_language("en")   -- English
local de = doc:get_language("de")   -- German
local fr = doc:get_language("fr")   -- French

Use in format_paragraph options or text settings for hyphenation.

Imagefile

Represents a loaded image or PDF file.

local imgfile = doc:load_imagefile("image.pdf", 1, "/MediaBox")

Attributes

Name R Type Description
filename R string Original filename
format R string Image format
width R integer Image width in pixels
height R integer Image height in pixels
scale_x R number X scale factor
scale_y R number Y scale factor
number_of_pages R integer Number of pages (for PDFs)
internal_name R string Internal PDF name

ImageNode

An image node ready for placement on a page.

local imgnode = doc:create_image_node(imgfile, 1, "/MediaBox")
imgnode.width = "5cm"
imgnode.height = "3cm"

-- Use node.vpack to create a VList
local node = require("glu.node")
local vl = node.vpack(imgnode)
page:output_at("2cm", "25cm", vl)

Attributes

Name R/W Type Description
width R/W ScaledPoint Image width (returns ScaledPoint on read)
height R/W ScaledPoint Image height (returns ScaledPoint on read)

ColorProfile

ICC color profile for PDF/A and PDF/X compliance.

local cp = doc:load_colorprofile("AdobeRGB1998.icc")
cp.identifier = "AdobeRGB1998"
cp.registry = "Adobe"
cp.info = "Adobe RGB (1998)"
cp.condition = "RGB"
cp.colors = 3

Attributes

Name R/W Type Description
identifier R/W string Profile identifier
registry R/W string Registry name
info R/W string Profile description
condition R/W string Color condition (e.g. “RGB”)
colors R/W integer Number of color components