Field Modifiers¶
Field modifiers are flags which modify the way content emitted for particular output styles:
M
Name
Description
a
argument
The content appears as a ‘const char *’ argument
c
colon
A colon (“:”) is appended after the label
d
display
Only emit field for display styles (text/HTML)
e
encoding
Only emit for encoding styles (XML/JSON)
escape-private
Escape control chars as Unicode private-use refs (XML/HTML)
escape-slash
Escape forward slashes (JSON)
escape-square
Escape control chars as U+25A1 WHITE SQUARE (XML/HTML)
g
gettext
Call gettext on field’s render content
h
humanize (hn)
Format large numbers in human-readable style
hn-space
Humanize: Place space between numeric and unit
hn-decimal
Humanize: Add a decimal digit, if number < 10
hn-1000
Humanize: Use 1000 as divisor instead of 1024
k
key
Field is a key, suitable for XPath predicates
l
leaf-list
Field is a leaf-list
n
no-quotes
Do not quote the field when using JSON style
p
plural
Gettext: Use comma-separated plural form
q
quotes
Quote the field when using JSON style
t
trim
Trim leading and trailing whitespace
w
white
A blank (” “) is appended after the label
Roles and modifiers can also use more verbose names, when preceded by a comma. For example, the modifier string “Lwc” (or “L,white,colon”) means the field has a label role (text that describes the next field) and should be followed by a colon (‘c’) and a space (‘w’). The modifier string “Vkq” (or “:key,quote”) means the field has a value role (the default role), that it is a key for the current instance, and that the value should be quoted when encoded for JSON.
The Argument Modifier ({a:})¶
The argument modifier indicates that the content of the field descriptor will be placed as a UTF-8 string (const char *) argument within the xo_emit parameters:
EXAMPLE:
xo_emit("{La:} {a:}\\n", "Label text", "label", "value");
TEXT:
Label text value
JSON:
"label": "value"
XML:
<label>value</label>
The argument modifier allows field names for value fields to be passed on the stack, avoiding the need to build a field descriptor using snprintf. For many field roles, the argument modifier is not needed, since those roles have specific mechanisms for arguments, such as “{C:fg-%s}”.
The Colon Modifier ({c:})¶
The colon modifier appends a single colon to the data value:
EXAMPLE:
xo_emit("{Lc:Name}{:name}\\n", "phil");
TEXT:
Name:phil
The colon modifier is only used for the TEXT and HTML output styles. It is commonly combined with the space modifier (‘{w:}’). It is purely a convenience feature.
The Display Modifier ({d:})¶
The display modifier indicated the field should only be generated for the display output styles, TEXT and HTML:
EXAMPLE:
xo_emit("{Lcw:Name}{d:name}{:id/%d}\\n", "phil", 1);
TEXT:
Name: phil 1
XML:
<id>1</id>
The display modifier is the opposite of the encoding modifier, and they are often used to give to distinct views of the underlying data.
The Encoding Modifier ({e:})¶
The encoding modifier indicates the field should only be generated for the encoding output styles, XML and JSON:
EXAMPLE:
xo_emit("{Lcw:Name}{:name}{e:id/%d}\\n", "phil", 1);
TEXT:
Name: phil
XML:
<name>phil</name><id>1</id>
The encoding modifier is the opposite of the display modifier, and they are often used to give to distinct views of the underlying data.
The escape-private Modifier¶
The escape-private modifier causes control characters in a field value
to be escaped as Unicode XML character references in the private-use
area (U+E000-U+E0FF).
A control character with byte value b (0x00-0x1F, excluding
newline, carriage return, and tab) is replaced with the XML character
reference , where bb is the hexadecimal byte value.
For example, byte 0x01 becomes .
This substitution is reversible: the original byte value can be recovered by subtracting 0xE000 from the Unicode code point.
The escape-private modifier only affects XML and HTML output styles. Without this modifier, control characters are replaced with spaces.
The escape-slash Modifier¶
The escape-slash modifier indicates that if the field is emitted in JSON style, any forward slashes (‘/’) should be escaped.
- EXAMPLE:
xo_emit(“{L:Tag}{:tag}\n”, “<tag/>”);
RFC 7159 allows optional escaping of forward slashes to avoid circumstances where a slash may be filtered, such as HTML.
The escape-square Modifier¶
The escape-square modifier causes control characters in a field value to be replaced with the Unicode WHITE SQUARE character (U+25A1, ☐). A control character is any byte value less than 0x20, except for newline, carriage return, and tab.
This substitution is not reversible.
The escape-square modifier only affects XML and HTML output styles. Without this modifier, control characters are replaced with spaces.
The Gettext Modifier ({g:})¶
The gettext modifier is used to translate individual fields using the
gettext domain (typically set using the “{G:}” role) and current
language settings. Once libxo renders the field value, it is passed
to gettext(3), where it is used as a key to find the native language
translation.
In the following example, the strings “State” and “full” are passed to gettext() to find locale-based translated strings:
xo_emit("{Lgwc:State}{g:state}\\n", "full");
See The Gettext Role ({G:}), The Plural Modifier ({p:}), and Howto: Internationalization (i18n) for additional details.
The Humanize Modifier ({h:})¶
The humanize modifier is used to render large numbers as in a human-readable format. While numbers like “44470272” are completely readable to computers and savants, humans will generally find “44M” more meaningful.
“hn” can be used as an alias for “humanize”.
The humanize modifier only affects display styles (TEXT and HMTL).
The “no-humanize” option (See Command-line Arguments) will block
the function of the humanize modifier.
There are a number of modifiers that affect details of humanization.
These are only available in as full names, not single characters. The
“hn-space” modifier places a space between the number and any
multiplier symbol, such as “M” or “K” (ex: “44 K”). The
“hn-decimal” modifier will add a decimal point and a single tenths
digit when the number is less than 10 (ex: “4.4K”). The “hn-1000”
modifier will use 1000 as divisor instead of 1024, following the
JEDEC-standard instead of the more natural binary powers-of-two
tradition:
EXAMPLE:
xo_emit("{h:input/%u}, {h,hn-space:output/%u}, "
"{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, "
"{h,hn-decimal:remaining/%u}\\n",
input, output, errors, capacity, remaining);
TEXT:
21, 57 K, 96M, 44M, 1.2G
In the HTML style, the original numeric value is rendered in the “data-number” attribute on the <div> element:
<div class="data" data-tag="errors"
data-number="100663296">96M</div>
The Key Modifier ({k:})¶
The key modifier is used to indicate that a particular field helps uniquely identify an instance of list data:
EXAMPLE:
xo_open_list("user");
for (i = 0; i < num_users; i++) {
xo_open_instance("user");
xo_emit("User {k:name} has {:count} tickets\\n",
user[i].u_name, user[i].u_tickets);
xo_close_instance("user");
}
xo_close_list("user");
Currently the key modifier is only used when generating XPath value for the HTML output style when XOF_XPATH is set, but other uses are likely in the near future.
The Leaf-List Modifier ({l:})¶
The leaf-list modifier is used to distinguish lists where each instance consists of only a single value. In XML, these are rendered as single elements, where JSON renders them as arrays:
EXAMPLE:
for (i = 0; i < num_users; i++) {
xo_emit("Member {l:user}\\n", user[i].u_name);
}
XML:
<user>phil</user>
<user>pallavi</user>
JSON:
"user": [ "phil", "pallavi" ]
The name of the field must match the name of the leaf list.
The No-Quotes Modifier ({n:})¶
The no-quotes modifier (and its twin, the ‘quotes’ modifier) affect the quoting of values in the JSON output style. JSON uses quotes for string value, but no quotes for numeric, boolean, and null data. xo_emit applies a simple heuristic to determine whether quotes are needed, but often this needs to be controlled by the caller:
EXAMPLE:
const char *bool = is_true ? "true" : "false";
xo_emit("{n:fancy/%s}", bool);
JSON:
"fancy": true
The Plural Modifier ({p:})¶
The plural modifier selects the appropriate plural form of an expression based on the most recent number emitted and the current language settings. The contents of the field should be the singular and plural English values, separated by a comma:
xo_emit("{:bytes} {Ngp:byte,bytes}\\n", bytes);
The plural modifier is meant to work with the gettext modifier ({g:}) but can work independently. See The Gettext Modifier ({g:}).
When used without the gettext modifier or when the message does not appear in the message catalog, the first token is chosen when the last numeric value is equal to 1; otherwise the second value is used, mimicking the simple pluralization rules of English.
When used with the gettext modifier, the ngettext(3) function is called to handle the heavy lifting, using the message catalog to convert the singular and plural forms into the native language.
The Quotes Modifier ({q:})¶
The quotes modifier (and its twin, the ‘no-quotes’ modifier) affect the quoting of values in the JSON output style. JSON uses quotes for string value, but no quotes for numeric, boolean, and null data. xo_emit applies a simple heuristic to determine whether quotes are needed, but often this needs to be controlled by the caller:
EXAMPLE:
xo_emit("{q:time/%d}", 2014);
JSON:
"year": "2014"
The heuristic is based on the format; if the format uses any of the following conversion specifiers, then no quotes are used:
d i o u x X D O U e E f F g G a A c C p
The Trim Modifier ({t:})¶
The trim modifier removes any leading or trailing whitespace from the value. This is only for the ‘encoding’ output styles:
EXAMPLE:
xo_emit("{t:description}", " some input ");
JSON:
"description": "some input"
The White Space Modifier ({w:})¶
The white space modifier appends a single space to the data value:
EXAMPLE:
xo_emit("{Lw:Name}{:name}\\n", "phil");
TEXT:
Name phil
The white space modifier is only used for the TEXT and HTML output styles. It is commonly combined with the colon modifier (‘{c:}’). It is purely a convenience feature.
Note that the sense of the ‘w’ modifier is reversed for the units role ({Uw:}); a blank is added before the contents, rather than after it.