Node building

Creating text nodes

What are nodes?

Text data structure

  • Hierarchical structure
func NewText() *Text
type Text struct {
	Settings TypesettingSettings
	Items    []any
}

Text can be a nested structure. Think of

<em>this is <u>emphasized and underlined</u></em>

where you can consider the underlined part as a child of the emphasized part.

ul := NewText()
ul.Settings[]
ul.Items = append(ul.Items,"emphasized and underlined")

em := NewText()
em.Settings...
em.Items = append(em.Items, "this is ")
em.Items = append(em.Items, ul

Format a paragraph

  • font family needed

This breaks a paragraph into lines:

func (fe *Document) FormatParagraph(te *Text, hsize bag.ScaledPoint, opts ...TypesettingOption) (*node.VList, *ParagraphInfo, error)

hsize is the desired horizontal size.

format paragraph calls mknodes

func (fe *Document) Mknodes(ts *Text) (head node.Node, tail node.Node, err error)

which creates a list of nodes from a nested Text data structure.

Typesetting options

The FormatParagraph() method takes a typesetting options as the last argument.

type TypesettingOption func(*Options)
Option Description
Leading(leading bag.ScaledPoint) Set the vertical distance between two baselines
Language(language *lang.Lang) Set the language used for hyphenation
FontSize(size bag.ScaledPoint) Set the font size for the paragraph
IndentLeft(size bag.ScaledPoint, rows int) Set the text indent
HorizontalAlign(a HorizontalAlignment) Sets the horizontal alignment for a paragraph

Text settings

Settings on a Text object control how its content is converted to nodes by Mknodes.

Setting Type Description
SettingFontFamily *FontFamily The font family to use
SettingSize bag.ScaledPoint Font size
SettingColor *color.Color Text color
SettingLeading bag.ScaledPoint Line height (baseline to baseline)
SettingHAlign HorizontalAlignment Horizontal alignment
SettingIndentLeft bag.ScaledPoint Left indentation
SettingIndentLeftRows int Number of rows to indent (0 = all)
SettingLeader string Leader pattern string (see below)
SettingHyperlink string URL for hyperlinks

Leaders via SettingLeader

When a Text item has a SettingLeader value, Mknodes creates a leader glue node instead of normal text. The string value (e.g. ".") is shaped into glyphs, packed into an HList pattern, and attached to a glue node with StretchFilll (order 3). The leader dominates over line-end glue, pushing trailing content to the right margin.

leaderText := frontend.NewText()
leaderText.Settings[frontend.SettingFontFamily] = ff
leaderText.Settings[frontend.SettingSize] = bag.MustSP("10pt")
leaderText.Settings[frontend.SettingLeader] = " . "

pageNum := frontend.NewText()
pageNum.Settings[frontend.SettingFontFamily] = ff
pageNum.Items = append(pageNum.Items, "42")

tocLine := frontend.NewText()
tocLine.Settings[frontend.SettingFontFamily] = ff
tocLine.Items = append(tocLine.Items, "Chapter 1")
tocLine.Items = append(tocLine.Items, leaderText)
tocLine.Items = append(tocLine.Items, pageNum)

vl, _, _ := doc.FormatParagraph(tocLine, hsize,
    frontend.Family(ff),
    frontend.HorizontalAlign(frontend.HAlignLeft))

This produces: Chapter 1 . . . . . . . . . 42 with the dots vertically aligned across lines (global grid).