Using the command line interface

The command line interface (CLI) for the bag tool allows you to create and manipulate PDF files using a simple command structure. Below is the usage information for the bag command. It accepts a filename as an argument.

bag - a frontend for boxes and glue
-h, --help                   Show this help
    --loglevel=LVL           Set the log level (debug, info, warn, error)

Commands
      help                   Show the help message
      version                Print version and exit

Usage: bag [options] <filename>

The CLI does not create any files by itself. The script is expected to open a PDF file for writing.

Hello world example explained

The sample program from the start page is analyzed here in detail. The program creates a PDF file with a single page containing some nonsense text on the page.

now := time.now()
...
printf("finished in %.2fms\n",time.since(now) * 1000)

This is just to measure the time it takes to run the program. The time package is one of the builtin packages by the risor language.

tr := `The quick brown fox jumps
over the lazy dog with a very long line that should be wrapped
at some point. This is a test to see how the text is formatted
when it is too long to fit on one line. The quick brown fox jumps
over the lazy dog with a very long line that should be wrapped`

str = strings.join(strings.fields(str)," ")

Creates a string without newlines.

f := frontend.new("out.pdf")

creates a new PDF document with the filename out.pdf. The file is opened for writing. The frontend module is part of the CLI (see below for available modules) and mainly provides convenience functions for font loading and text formatting. The frontend module is a high-level interface for creating PDF documents.

backend_doc := f.doc

The backend document is a main boxes and glue library object that represents the PDF document. It is used to access low-level features of the PDF writing process.

backend_doc.language = frontend.get_language("en")
backend_doc.title = "A test document"

The language is used for hyphenation. The frontend module includes hyphenation patterns for several languages, including English. The title is used in the PDF metadata.

// f is the frontend document
func setup_fonts(f) {
    ff := f.new_fontfamily("text")

    fs := frontend.new_fontsource({
        location: filepath.join("fonts","CrimsonPro-Regular.ttf"),
        features: ["kern","liga"],
        })

    ff.add_member({source: fs, weight: 400, style: "normal"})
    return ff
}

...

ff := setup_fonts(f)

The frontend collects all the fonts in font families. The setup_fonts function is a helper function that creates a font family with a single font member. The font is loaded from the fonts directory, which should contain the font files. The features option specifies which font features to enable, such as kerning and ligatures.

p := f.doc.new_page()

This creates a new page in the PDF document. The page is not added to the PDF document until the p.shipout() function is called.

para := frontend.new_text()
para.items = [str]
vlist := f.format_paragraph({
	text: para,
	width: bag.sp("225pt"),
	leading: bag.sp("14pt"),
	font_size: bag.sp("12pt"),
	family: ff,
})
p.output_at(bag.sp("1cm"), bag.sp("10cm"), vlist)

The new_text() function creates a text object. A text object is a hierarchical structure that contains items. These items ca be a string or another text object. Each text object can be styled individually. Think for example of some italic text in a paragraph.

In the code above, the str variable (the nonsense text from above) is the only member of the items list. There is no special styling of the text.

The format_paragraph() function turns the text object into a vertical list (vlist) that can be placed on the page. The width, leading, and font_size parameters control the layout of the text. The family parameter specifies the font family to use for the text.

Finally, the output_at() function places the vertical list on the page at the specified coordinates (1cm from the left and 10cm from the top).

All of the length parameters are of type scaled point (sp). The bag module provides a convenient way to create scaled points from strings, such as “1cm” or “12pt”.

p.shipout()

f.doc.finish()

The shipout() function finalizes the page and adds it to the PDF document. The finish() function closes the PDF document and writes it to the file.

Available (preloaded) modules

Module Description
frontend Nice to have functions
bag Scaled point type and logging
node Low level items for typesetting
font backend module for font features and shaping
cxpath XPath module
baselinepdf Low level PDF writing module