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 |