summaryrefslogtreecommitdiff
path: root/static/freebsd/man5/xo_format.5
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man5/xo_format.5')
-rw-r--r--static/freebsd/man5/xo_format.5984
1 files changed, 984 insertions, 0 deletions
diff --git a/static/freebsd/man5/xo_format.5 b/static/freebsd/man5/xo_format.5
new file mode 100644
index 00000000..3c7ddc9d
--- /dev/null
+++ b/static/freebsd/man5/xo_format.5
@@ -0,0 +1,984 @@
+.\" #
+.\" # Copyright (c) 2014, Juniper Networks, Inc.
+.\" # All rights reserved.
+.\" # This SOFTWARE is licensed under the LICENSE provided in the
+.\" # ../Copyright file. By downloading, installing, copying, or
+.\" # using the SOFTWARE, you agree to be bound by the terms of that
+.\" # LICENSE.
+.\" # Phil Shafer, July 2014
+.\"
+.Dd December 4, 2014
+.Dt LIBXO 3
+.Os
+.Sh NAME
+.Nm xo_format
+.Nd content of format descriptors for xo_emit
+.Sh DESCRIPTION
+.Pp
+.Nm libxo
+uses format strings to control the rendering of data into
+various output styles, including
+.Em text ,
+.Em XML ,
+.Em JSON ,
+and
+.Em HTML .
+Each format string contains a set of zero or more
+.Dq "field descriptions" ,
+which describe independent data fields.
+Each field description contains a set of
+.Dq modifiers ,
+a
+.Dq "content string" ,
+and zero, one, or two
+.Dq "format descriptors" .
+The modifiers tell
+.Nm libxo
+what the field is and how to treat it, while the format descriptors are
+formatting instructions using
+.Xr printf 3 Ns -style
+format strings, telling
+.Nm libxo
+how to format the field.
+The field description is placed inside
+a set of braces, with a colon
+.Ql ( \&: )
+after the modifiers and a slash
+.Ql ( \&/ )
+before each format descriptors.
+Text may be intermixed with
+field descriptions within the format string.
+.Pp
+The field description is given as follows:
+.Bd -literal -offset indent
+ \(aq{\(aq [ role | modifier ]* [\(aq,\(aq long\-names ]* \(aq:\(aq [ content ]
+ [ \(aq/\(aq field\-format [ \(aq/\(aq encoding\-format ]] \(aq}\(aq
+.Ed
+.Pp
+The role describes the function of the field, while the modifiers
+enable optional behaviors.
+The contents, field\-format, and
+encoding\-format are used in varying ways, based on the role.
+These are described in the following sections.
+.Pp
+Braces can be escaped by using double braces, similar to "%%" in
+.Xr printf 3 .
+The format string "{{braces}}" would emit "{braces}".
+.Pp
+In the following example, three field descriptors appear.
+The first
+is a padding field containing three spaces of padding, the second is a
+label ("In stock"), and the third is a value field ("in\-stock").
+The in\-stock field has a "%u" format that will parse the next argument
+passed to the
+.Xr xo_emit 3 ,
+function as an unsigned integer.
+.Bd -literal -offset indent
+ xo_emit("{P: }{Lwc:In stock}{:in\-stock/%u}\\n", 65);
+.Ed
+.Pp
+This single line of code can generate text ("In stock: 65\\n"), XML
+("<in\-stock>65</in\-stock>"), JSON (\(aq"in\-stock": 65\(aq), or HTML (too
+lengthy to be listed here).
+.Pp
+While roles and modifiers typically use single character for brevity,
+there are alternative names for each which allow more verbose
+formatting strings.
+These names must be preceded by a comma, and may follow any
+single\-character values:
+.Bd -literal -offset indent
+ xo_emit("{L,white,colon:In stock}{,key:in\-stock/%u}\\n", 65);
+.Ed
+.Ss "Field Roles"
+Field roles are optional, and indicate the role and formatting of the
+content.
+The roles are listed below; only one role is permitted:
+.Bl -column "M" "Name12341234"
+.It Sy "M" "Name " "Description"
+.It C "color " "Field is a color or effect"
+.It D "decoration " "Field is non\-text (e.g. colon, comma)"
+.It E "error " "Field is an error message"
+.It L "label " "Field is text that prefixes a value"
+.It N "note " "Field is text that follows a value"
+.It P "padding " "Field is spaces needed for vertical alignment"
+.It T "title " "Field is a title value for headings"
+.It U "units " "Field is the units for the previous value field"
+.It V "value " "Field is the name of field (the default)"
+.It W "warning " "Field is a warning message"
+.It \&[ "start\-anchor" "Begin a section of anchored variable\-width text"
+.It \&] "stop\-anchor " "End a section of anchored variable\-width text"
+.El
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{L:Free}{D::}{P: }{:free/%u} {U:Blocks}\\n",
+ free_blocks);
+.Ed
+.Pp
+When a role is not provided, the "value" role is used as the default.
+.Pp
+Roles and modifiers can also use more verbose names, when preceded by
+a comma:
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{,label:Free}{,decoration::}{,padding: }"
+ "{,value:free/%u} {,units:Blocks}\\n",
+ free_blocks);
+.Ed
+.Ss "The Color Role ({C:})"
+Colors and effects control how text values are displayed; they are
+used for display styles (TEXT and HTML).
+.Bd -literal -offset indent
+ xo_emit("{C:bold}{:value}{C:no\-bold}\\n", value);
+.Ed
+.Pp
+Colors and effects remain in effect until modified by other "C"\-role
+fields.
+.Bd -literal -offset indent
+ xo_emit("{C:bold}{C:inverse}both{C:no\-bold}only inverse\\n");
+.Ed
+.Pp
+If the content is empty, the "reset" action is performed.
+.Bd -literal -offset indent
+ xo_emit("{C:both,underline}{:value}{C:}\\n", value);
+.Ed
+.Pp
+The content should be a comma\-separated list of zero or more colors or
+display effects.
+.Bd -literal -offset indent
+ xo_emit("{C:bold,underline,inverse}All three{C:no\-bold,no\-inverse}\\n");
+.Ed
+.Pp
+The color content can be either static, when placed directly within
+the field descriptor, or a printf\-style format descriptor can be used,
+if preceded by a slash ("/"):
+.Bd -literal -offset indent
+ xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "",
+ need_underline ? "underline" : "", value);
+.Ed
+.Pp
+Color names are prefixed with either "fg\-" or "bg\-" to change the
+foreground and background colors, respectively.
+.Bd -literal -offset indent
+ xo_emit("{C:/fg\-%s,bg\-%s}{Lwc:Cost}{:cost/%u}{C:reset}\\n",
+ fg_color, bg_color, cost);
+.Ed
+.Pp
+The following table lists the supported effects:
+.Bl -column "no\-underline"
+.It Sy "Name " "Description"
+.It "bg\-xxxxx " "Change background color"
+.It "bold " "Start bold text effect"
+.It "fg\-xxxxx " "Change foreground color"
+.It "inverse " "Start inverse (aka reverse) text effect"
+.It "no\-bold " "Stop bold text effect"
+.It "no\-inverse " "Stop inverse (aka reverse) text effect"
+.It "no\-underline " "Stop underline text effect"
+.It "normal " "Reset effects (only)"
+.It "reset " "Reset colors and effects (restore defaults)"
+.It "underline " "Start underline text effect"
+.El
+.Pp
+The following color names are supported:
+.Bl -column "no\-underline"
+.It Sy "Name"
+.It black
+.It blue
+.It cyan
+.It default
+.It green
+.It magenta
+.It red
+.It white
+.It yellow
+.El
+.Ss "The Decoration Role ({D:})"
+Decorations are typically punctuation marks such as colons,
+semi\-colons, and commas used to decorate the text and make it simpler
+for human readers.
+By marking these distinctly, HTML usage scenarios
+can use CSS to direct their display parameters.
+.Bd -literal -offset indent
+ xo_emit("{D:((}{:name}{D:))}\\n", name);
+.Ed
+.Ss "The Gettext Role ({G:})"
+.Nm libxo
+supports internationalization (i18n) through its use of
+.Xr gettext 3 .
+Use the "{G:}" role to request that the remaining part of
+the format string, following the "{G:}" field, be handled using
+.Fn gettext .
+Since
+.Fn gettext
+uses the string as the key into the message catalog,
+.Nm libxo
+uses a simplified version of the format string that removes
+unimportant field formatting and modifiers, stopping minor formatting
+changes from impacting the expensive translation process.
+A developer
+change such as changing "/%06d" to "/%08d" should not force hand
+inspection of all .po files.
+.Pp
+The simplified version can be generated for a single message using the
+"xopo \-s <text>" command, or an entire .pot can be translated using
+the "xopo \-f <input> \-o <output>" command.
+.Bd -literal -offset indent
+ xo_emit("{G:}Invalid token\\n");
+.Ed
+.Pp
+The {G:} role allows a domain name to be set.
+.Fn gettext
+calls will
+continue to use that domain name until the current format string
+processing is complete, enabling a library function to emit strings
+using it\(aqs own catalog.
+The domain name can be either static as the
+content of the field, or a format can be used to get the domain name
+from the arguments.
+.Bd -literal -offset indent
+ xo_emit("{G:libc}Service unavailable in restricted mode\\n");
+.Ed
+.Ss "The Label Role ({L:})"
+Labels are text that appears before a value.
+.Bd -literal -offset indent
+ xo_emit("{Lwc:Cost}{:cost/%u}\\n", cost);
+.Ed
+.Pp
+If a label needs to include a slash, it must be escaped using two
+backslashes, one for the C compiler and one for
+.Nm libxo .
+.Bd -literal -offset indent
+ xo_emit("{Lc:Low\\\\/warn level}{:level/%s}\\n", level);
+.Ed
+.Ss "The Note Role ({N:})"
+Notes are text that appears after a value.
+.Bd -literal -offset indent
+ xo_emit("{:cost/%u} {N:per year}\\n", cost);
+.Ed
+.Ss "The Padding Role ({P:})"
+Padding represents whitespace used before and between fields.
+The padding content can be either static, when placed directly within
+the field descriptor, or a printf\-style format descriptor can be used,
+if preceded by a slash ("/"):
+.Bd -literal -offset indent
+ xo_emit("{P: }{Lwc:Cost}{:cost/%u}\\n", cost);
+ xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\\n", "", cost);
+.Ed
+.Ss "The Title Role ({T:})"
+Titles are heading or column headers that are meant to be displayed to
+the user.
+The title can be either static, when placed directly within
+the field descriptor, or a printf\-style format descriptor can be used,
+if preceded by a slash ("/"):
+.Bd -literal -offset indent
+ xo_emit("{T:Interface Statistics}\\n");
+ xo_emit("{T:/%20.20s}{T:/%6.6s}\\n", "Item Name", "Cost");
+.Ed
+.Ss "The Units Role ({U:})"
+Units are the dimension by which values are measured, such as degrees,
+miles, bytes, and decibels.
+The units field carries this information
+for the previous value field.
+.Bd -literal -offset indent
+ xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\\n", miles);
+.Ed
+.Pp
+Note that the sense of the \(aqw\(aq modifier is reversed for units;
+a blank is added before the contents, rather than after it.
+.Pp
+When the
+.Dv XOF_UNITS
+flag is set, units are rendered in XML as the
+.Dq units
+attribute:
+.Bd -literal -offset indent
+ <distance units="miles">50</distance>
+.Ed
+.Pp
+Units can also be rendered in HTML as the "data\-units" attribute:
+.Bd -literal -offset indent
+ <div class="data" data\-tag="distance" data\-units="miles"
+ data\-xpath="/top/data/distance">50</div>
+.Ed
+.Ss "The Value Role ({V:} and {:})"
+The value role is used to represent the a data value that is
+interesting for the non\-display output styles (XML and JSON).
+Value
+is the default role; if no other role designation is given, the field
+is a value.
+The field name must appear within the field descriptor,
+followed by one or two format descriptors.
+The first format
+descriptor is used for display styles (TEXT and HTML), while the
+second one is used for encoding styles (XML and JSON).
+If no second
+format is given, the encoding format defaults to the first format,
+with any minimum width removed.
+If no first format is given, both
+format descriptors default to "%s".
+.Bd -literal -offset indent
+ xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\\n",
+ length, width, height);
+ xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\\n,
+ author, poem, year);
+.Ed
+.Ss "The Anchor Roles ({[:} and {]:})"
+The anchor roles allow a set of strings by be padded as a group,
+but still be visible to
+.Xr xo_emit 3
+as distinct fields.
+Either the start
+or stop anchor can give a field width and it can be either directly in
+the descriptor or passed as an argument.
+Any fields between the start
+and stop anchor are padded to meet the minimum width given.
+.Pp
+To give a width directly, encode it as the content of the anchor tag:
+.Bd -literal -offset indent
+ xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\\n", min, max);
+.Ed
+.Pp
+To pass a width as an argument, use "%d" as the format, which must
+appear after the "/".
+Note that only "%d" is supported for widths.
+Using any other value could ruin your day.
+.Bd -literal -offset indent
+ xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\\n", width, min, max);
+.Ed
+.Pp
+If the width is negative, padding will be added on the right, suitable
+for left justification.
+Otherwise the padding will be added to the
+left of the fields between the start and stop anchors, suitable for
+right justification.
+If the width is zero, nothing happens.
+If the
+number of columns of output between the start and stop anchors is less
+than the absolute value of the given width, nothing happens.
+.Pp
+Widths over 8k are considered probable errors and not supported.
+If
+.Dv XOF_WARN
+is set, a warning will be generated.
+.Ss "Field Modifiers"
+Field modifiers are flags which modify the way content emitted for
+particular output styles:
+.Bl -column M "Name123456789"
+.It Sy M "Name " "Description"
+.It a "argument " "The content appears as a ""const char *"" argument"
+.It c "colon " "A colon ("":"") is appended after the label"
+.It d "display " "Only emit field for display styles (text/HTML)"
+.It e "encoding " "Only emit for encoding styles (XML/JSON)"
+.It h "humanize (hn) " "Format large numbers in human\-readable style"
+.It " " "hn\-space " "Humanize: Place space between numeric and unit"
+.It " " "hn\-decimal " "Humanize: Add a decimal digit, if number < 10"
+.It " " "hn\-1000 " "Humanize: Use 1000 as divisor instead of 1024"
+.It k "key " "Field is a key, suitable for XPath predicates"
+.It l "leaf\-list " "Field is a leaf\-list, a list of leaf values"
+.It n "no\-quotes " "Do not quote the field when using JSON style"
+.It q "quotes " "Quote the field when using JSON style"
+.It t "trim " "Trim leading and trailing whitespace"
+.It w "white space " "A blank ("" "") is appended after the label"
+.El
+.Pp
+For example, the modifier string "Lwc" means the field has a label
+role (text that describes the next field) and should be followed by a
+colon (\(aqc\(aq) and a space (\(aqw\(aq).
+The modifier string "Vkq" means the
+field has a value role, that it is a key for the current instance, and
+that the value should be quoted when encoded for JSON.
+.Pp
+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 (\(aqc\(aq) and a space (\(aqw\(aq).
+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.
+.Ss "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.
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{La:} {a:}\\n", "Label text", "label", "value");
+ TEXT:
+ Label text value
+ JSON:
+ "label": "value"
+ XML:
+ <label>value</label>
+.Ed
+.Pp
+The argument modifier allows field names for value fields to be passed
+on the stack, avoiding the need to build a field descriptor using
+.Xr snprintf 1 .
+For many field roles, the argument modifier is not needed,
+since those roles have specific mechanisms for arguments,
+such as "{C:fg\-%s}".
+.Ss "The Colon Modifier ({c:})"
+The colon modifier appends a single colon to the data value:
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{Lc:Name}{:name}\\n", "phil");
+ TEXT:
+ Name:phil
+.Ed
+.Pp
+The colon modifier is only used for the TEXT and HTML output
+styles.
+It is commonly combined with the space modifier (\(aq{w:}\(aq).
+It is purely a convenience feature.
+.Ss "The Display Modifier ({d:})"
+The display modifier indicated the field should only be generated for
+the display output styles, TEXT and HTML.
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{Lcw:Name}{d:name} {:id/%d}\\n", "phil", 1);
+ TEXT:
+ Name: phil 1
+ XML:
+ <id>1</id>
+.Ed
+.Pp
+The display modifier is the opposite of the encoding modifier, and
+they are often used to give to distinct views of the underlying data.
+.Ss "The Encoding Modifier ({e:})"
+The encoding modifier indicated the field should only be generated for
+the encoding output styles, such as JSON and XML.
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{Lcw:Name}{:name} {e:id/%d}\\n", "phil", 1);
+ TEXT:
+ Name: phil
+ XML:
+ <name>phil</name><id>1</id>
+.Ed
+.Pp
+The encoding modifier is the opposite of the display modifier, and
+they are often used to give to distinct views of the underlying data.
+.Ss "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.
+.Pp
+"hn" can be used as an alias for "humanize".
+.Pp
+The humanize modifier only affects display styles (TEXT and HMTL).
+The "no\-humanize" option will block the function of the humanize modifier.
+.Pp
+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.
+.Bd -literal -offset indent
+ 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
+.Ed
+.Pp
+In the HTML style, the original numeric value is rendered in the
+"data\-number" attribute on the <div> element:
+.Bd -literal -offset indent
+ <div class="data" data\-tag="errors"
+ data\-number="100663296">96M</div>
+.Ed
+.Ss "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
+.Xr gettext 3 ,
+where it is used as a key to find the native language
+translation.
+.Pp
+In the following example, the strings "State" and "full" are passed
+to
+.Fn gettext
+to find locale\-based translated strings.
+.Bd -literal -offset indent
+ xo_emit("{Lgwc:State}{g:state}\\n", "full");
+.Ed
+.Ss "The Key Modifier ({k:})"
+The key modifier is used to indicate that a particular field helps
+uniquely identify an instance of list data.
+.Bd -literal -offset indent
+ 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");
+.Ed
+.Pp
+Currently the key modifier is only used when generating XPath values
+for the HTML output style when
+.Dv XOF_XPATH
+is set, but other uses are likely in the near future.
+.Ss "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.
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_open_list("user");
+ for (i = 0; i < num_users; i++) {
+ xo_emit("Member {l:name}\\n", user[i].u_name);
+ }
+ xo_close_list("user");
+ XML:
+ <user>phil</user>
+ <user>pallavi</user>
+ JSON:
+ "user": [ "phil", "pallavi" ]
+.Ed
+.Ss "The No\-Quotes Modifier ({n:})"
+The no\-quotes modifier (and its twin, the \(aqquotes\(aq modifier) affect
+the quoting of values in the JSON output style.
+JSON uses quotes for
+string values, but no quotes for numeric, boolean, and null data.
+.Xr xo_emit 3
+applies a simple heuristic to determine whether quotes are
+needed, but often this needs to be controlled by the caller.
+.Bd -literal -offset indent
+ EXAMPLE:
+ const char *bool = is_true ? "true" : "false";
+ xo_emit("{n:fancy/%s}", bool);
+ JSON:
+ "fancy": true
+.Ed
+.Ss "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:
+.Bd -literal -offset indent
+ xo_emit("{:bytes} {Ngp:byte,bytes}\\n", bytes);
+.Ed
+.Pp
+The plural modifier is meant to work with the gettext modifier ({g:})
+but can work independently.
+.Pp
+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.
+.Pp
+When used with the gettext modifier, the
+.Xr 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.
+.Ss "The Quotes Modifier ({q:})"
+The quotes modifier (and its twin, the \(aqno-quotes\(aq modifier) affect
+the quoting of values in the JSON output style.
+JSON uses quotes for
+string values, but no quotes for numeric, boolean, and null data.
+.Xr xo_emit 3
+applies a simple heuristic to determine whether quotes are
+needed, but often this needs to be controlled by the caller.
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{q:time/%d}", 2014);
+ JSON:
+ "year": "2014"
+.Ed
+.Ss "The White Space Modifier ({w:})"
+The white space modifier appends a single space to the data value:
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("{Lw:Name}{:name}\\n", "phil");
+ TEXT:
+ Name phil
+.Ed
+.Pp
+The white space modifier is only used for the TEXT and HTML output
+styles.
+It is commonly combined with the colon modifier (\(aq{c:}\(aq).
+It is purely a convenience feature.
+.Pp
+Note that the sense of the \(aqw\(aq modifier is reversed for the units role
+({Uw:}); a blank is added before the contents, rather than after it.
+.Ss "Field Formatting"
+The field format is similar to the format string for
+.Xr printf 3 .
+Its use varies based on the role of the field, but generally is used to
+format the field\(aqs contents.
+.Pp
+If the format string is not provided for a value field, it defaults
+to "%s".
+.Pp
+Note a field definition can contain zero or more printf\-style
+.Dq directives ,
+which are sequences that start with a \(aq%\(aq and end with
+one of following characters: "diouxXDOUeEfFgGaAcCsSp".
+Each directive
+is matched by one of more arguments to the
+.Xr xo_emit 3
+function.
+.Pp
+The format string has the form:
+.Bd -literal -offset indent
+ \(aq%\(aq format\-modifier * format\-character
+.Ed
+.Pp
+The format\-modifier can be:
+.Bl -bullet
+.It
+a \(aq#\(aq character, indicating the output value should be prefixed with
+"0x", typically to indicate a base 16 (hex) value.
+.It
+a minus sign (\(aq\-\(aq), indicating the output value should be padded on
+the right instead of the left.
+.It
+a leading zero (\(aq0\(aq) indicating the output value should be padded on the
+left with zeroes instead of spaces (\(aq \(aq).
+.It
+one or more digits (\(aq0\(aq \- \(aq9\(aq) indicating the minimum width of the
+argument.
+If the width in columns of the output value is less than
+the minimum width, the value will be padded to reach the minimum.
+.It
+a period followed by one or more digits indicating the maximum
+number of bytes which will be examined for a string argument, or the maximum
+width for a non\-string argument.
+When handling ASCII strings this
+functions as the field width but for multi\-byte characters, a single
+character may be composed of multiple bytes.
+.Xr xo_emit 3
+will never dereference memory beyond the given number of bytes.
+.It
+a second period followed by one or more digits indicating the maximum
+width for a string argument.
+This modifier cannot be given for non\-string arguments.
+.It
+one or more \(aqh\(aq characters, indicating shorter input data.
+.It
+one or more \(aql\(aq characters, indicating longer input data.
+.It
+a \(aqz\(aq character, indicating a \(aqsize_t\(aq argument.
+.It
+a \(aqt\(aq character, indicating a \(aqptrdiff_t\(aq argument.
+.It
+a \(aq \(aq character, indicating a space should be emitted before
+positive numbers.
+.It
+a \(aq+\(aq character, indicating sign should emitted before any number.
+.El
+.Pp
+Note that \(aqq\(aq, \(aqD\(aq, \(aqO\(aq, and \(aqU\(aq are considered deprecated and will be
+removed eventually.
+.Pp
+The format character is described in the following table:
+.Bl -column C "Argument Type12"
+.It Sy "C" "Argument Type " "Format"
+.It d "int " "base 10 (decimal)"
+.It i "int " "base 10 (decimal)"
+.It o "int " "base 8 (octal)"
+.It u "unsigned " "base 10 (decimal)"
+.It x "unsigned " "base 16 (hex)"
+.It X "unsigned long " "base 16 (hex)"
+.It D "long " "base 10 (decimal)"
+.It O "unsigned long " "base 8 (octal)"
+.It U "unsigned long " "base 10 (decimal)"
+.It e "double " "[\-]d.ddde+\-dd"
+.It E "double " "[\-]d.dddE+\-dd"
+.It f "double " "[\-]ddd.ddd"
+.It F "double " "[\-]ddd.ddd"
+.It g "double " "as \(aqe\(aq or \(aqf\(aq"
+.It G "double " "as \(aqE\(aq or \(aqF\(aq"
+.It a "double " "[\-]0xh.hhhp[+\-]d"
+.It A "double " "[\-]0Xh.hhhp[+\-]d"
+.It c "unsigned char " "a character"
+.It C "wint_t " "a character"
+.It s "char * " "a UTF\-8 string"
+.It S "wchar_t * " "a unicode/WCS string"
+.It p "void * " "\(aq%#lx\(aq"
+.El
+.Pp
+The \(aqh\(aq and \(aql\(aq modifiers affect the size and treatment of the
+argument:
+.Bl -column "Mod" "d, i " "o, u, x, X "
+.It Sy "Mod" "d, i " "o, u, x, X"
+.It "hh " "signed char " "unsigned char"
+.It "h " "short " "unsigned short"
+.It "l " "long " "unsigned long"
+.It "ll " "long long " "unsigned long long"
+.It "j " "intmax_t " "uintmax_t"
+.It "t " "ptrdiff_t " "ptrdiff_t"
+.It "z " "size_t " "size_t"
+.It "q " "quad_t " "u_quad_t"
+.El
+.Ss "UTF\-8 and Locale Strings"
+All strings for
+.Nm libxo
+must be UTF\-8.
+.Nm libxo
+will handle turning them
+into locale\-based strings for display to the user.
+.Pp
+For strings, the \(aqh\(aq and \(aql\(aq modifiers affect the interpretation of
+the bytes pointed to argument.
+The default \(aq%s\(aq string is a \(aqchar *\(aq
+pointer to a string encoded as UTF\-8.
+Since UTF\-8 is compatible with
+.Em ASCII
+data, a normal 7\-bit
+.Em ASCII
+string can be used.
+"%ls" expects a
+"wchar_t *" pointer to a wide\-character string, encoded as 32\-bit
+Unicode values.
+"%hs" expects a "char *" pointer to a multi\-byte
+string encoded with the current locale, as given by the
+.Ev LC_CTYPE ,
+.Ev LANG ,
+or
+.Ev LC_ALL
+environment variables.
+The first of this list of
+variables is used and if none of the variables are set, the locale defaults to
+.Em UTF\-8 .
+.Pp
+.Nm libxo
+will
+convert these arguments as needed to either UTF\-8 (for XML, JSON, and
+HTML styles) or locale\-based strings for display in text style.
+.Bd -literal -offset indent
+ xo_emit("All strings are utf\-8 content {:tag/%ls}",
+ L"except for wide strings");
+.Ed
+.Pp
+"%S" is equivalent to "%ls".
+.Pp
+For example, a function is passed a locale\-base name, a hat size,
+and a time value.
+The hat size is formatted in a UTF\-8 (ASCII)
+string, and the time value is formatted into a wchar_t string.
+.Bd -literal -offset indent
+ void print_order (const char *name, int size,
+ struct tm *timep) {
+ char buf[32];
+ const char *size_val = "unknown";
+
+ if (size > 0)
+ snprintf(buf, sizeof(buf), "%d", size);
+ size_val = buf;
+ }
+
+ wchar_t when[32];
+ wcsftime(when, sizeof(when), L"%d%b%y", timep);
+
+ xo_emit("The hat for {:name/%hs} is {:size/%s}.\\n",
+ name, size_val);
+ xo_emit("It was ordered on {:order\-time/%ls}.\\n",
+ when);
+ }
+.Ed
+.Pp
+It is important to note that
+.Xr xo_emit 3
+will perform the conversion
+required to make appropriate output.
+Text style output uses the
+current locale (as described above), while XML, JSON, and HTML use
+UTF\-8.
+.Pp
+UTF\-8 and locale\-encoded strings can use multiple bytes to encode one
+column of data.
+The traditional "precision" (aka "max\-width") value
+for "%s" printf formatting becomes overloaded since it specifies both
+the number of bytes that can be safely referenced and the maximum
+number of columns to emit.
+.Xr xo_emit 3
+uses the precision as the former,
+and adds a third value for specifying the maximum number of columns.
+.Pp
+In this example, the name field is printed with a minimum of 3 columns
+and a maximum of 6.
+Up to ten bytes are in used in filling those columns.
+.Bd -literal -offset indent
+ xo_emit("{:name/%3.10.6s}", name);
+.Ed
+.Ss "Characters Outside of Field Definitions"
+Characters in the format string that are not part of a field definition are
+copied to the output for the TEXT style, and are ignored for the JSON
+and XML styles.
+For HTML, these characters are placed in a <div> with class "text".
+.Bd -literal -offset indent
+ EXAMPLE:
+ xo_emit("The hat is {:size/%s}.\\n", size_val);
+ TEXT:
+ The hat is extra small.
+ XML:
+ <size>extra small</size>
+ JSON:
+ "size": "extra small"
+ HTML:
+ <div class="text">The hat is </div>
+ <div class="data" data\-tag="size">extra small</div>
+ <div class="text">.</div>
+.Ed
+.Ss "\(aq%n\(aq is Not Supported"
+.Nm libxo
+does not support the \(aq%n\(aq directive.
+It is a bad idea and we
+just do not do it.
+.Ss "The Encoding Format (eformat)"
+The "eformat" string is the format string used when encoding the field
+for JSON and XML.
+If not provided, it defaults to the primary format
+with any minimum width removed.
+If the primary is not given, both default to "%s".
+.Sh EXAMPLE
+In this example, the value for the number of items in stock is emitted:
+.Bd -literal -offset indent
+ xo_emit("{P: }{Lwc:In stock}{:in\-stock/%u}\\n",
+ instock);
+.Ed
+.Pp
+This call will generate the following output:
+.Bd -literal -offset indent
+ TEXT:
+ In stock: 144
+ XML:
+ <in\-stock>144</in\-stock>
+ JSON:
+ "in\-stock": 144,
+ HTML:
+ <div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data\-tag="in\-stock">144</div>
+ </div>
+.Ed
+.Pp
+Clearly HTML wins the verbosity award, and this output does
+not include
+.Dv XOF_XPATH
+or
+.Dv XOF_INFO
+data, which would expand the penultimate line to:
+.Bd -literal -offset indent
+ <div class="data" data\-tag="in\-stock"
+ data\-xpath="/top/data/item/in\-stock"
+ data\-type="number"
+ data\-help="Number of items in stock">144</div>
+.Ed
+.Sh WHAT MAKES A GOOD FIELD NAME?
+To make useful, consistent field names, follow these guidelines:
+.Ss "Use lower case, even for TLAs"
+Lower case is more civilized.
+Even TLAs should be lower case
+to avoid scenarios where the differences between "XPath" and
+"Xpath" drive your users crazy.
+Using "xpath" is simpler and better.
+.Ss "Use hyphens, not underscores"
+Use of hyphens is traditional in XML, and the
+.Dv XOF_UNDERSCORES
+flag can be used to generate underscores in JSON, if desired.
+But the raw field name should use hyphens.
+.Ss "Use full words"
+Do not abbreviate especially when the abbreviation is not obvious or
+not widely used.
+Use "data\-size", not "dsz" or "dsize".
+Use
+"interface" instead of "ifname", "if\-name", "iface", "if", or "intf".
+.Ss "Use <verb>\-<units>"
+Using the form <verb>\-<units> or <verb>\-<classifier>\-<units> helps in
+making consistent, useful names, avoiding the situation where one app
+uses "sent\-packet" and another "packets\-sent" and another
+"packets\-we\-have\-sent".
+The <units> can be dropped when it is
+obvious, as can obvious words in the classification.
+Use "receive\-after\-window\-packets" instead of
+"received\-packets\-of\-data\-after\-window".
+.Ss "Reuse existing field names"
+Nothing is worse than writing expressions like:
+.Bd -literal -offset indent
+ if ($src1/process[pid == $pid]/name ==
+ $src2/proc\-table/proc/p[process\-id == $pid]/proc\-name) {
+ ...
+ }
+.Ed
+.Pp
+Find someone else who is expressing similar data and follow their
+fields and hierarchy.
+Remember the quote is not
+.Dq "Consistency is the hobgoblin of little minds"
+but
+.Dq "A foolish consistency is the hobgoblin of little minds" .
+.Ss "Think about your users"
+Have empathy for your users, choosing clear and useful fields that
+contain clear and useful data.
+You may need to augment the display content with
+.Xr xo_attr 3
+calls or "{e:}" fields to make the data useful.
+.Ss "Do not use an arbitrary number postfix"
+What does "errors2" mean?
+No one will know.
+"errors\-after\-restart" would be a better choice.
+Think of your users, and think of the future.
+If you make "errors2", the next guy will happily make
+"errors3" and before you know it, someone will be asking what is the
+difference between errors37 and errors63.
+.Ss "Be consistent, uniform, unsurprising, and predictable"
+Think of your field vocabulary as an API.
+You want it useful,
+expressive, meaningful, direct, and obvious.
+You want the client
+application\(aqs programmer to move between without the need to
+understand a variety of opinions on how fields are named.
+They should
+see the system as a single cohesive whole, not a sack of cats.
+.Pp
+Field names constitute the means by which client programmers interact
+with our system.
+By choosing wise names now, you are making their lives better.
+.Pp
+After using
+.Xr xolint 1
+to find errors in your field descriptors, use
+.Dq "xolint \-V"
+to spell check your field names and to detect different
+names for the same data.
+.Dq dropped\-short
+and
+.Dq dropped\-too\-short
+are both reasonable names, but using them both will lead users to ask the
+difference between the two fields.
+If there is no difference,
+use only one of the field names.
+If there is a difference, change the
+names to make that difference more obvious.
+.Sh SEE ALSO
+.Xr libxo 3 ,
+.Xr xolint 1 ,
+.Xr xo_emit 3
+.Sh HISTORY
+The
+.Nm libxo
+library first appeared in
+.Fx 11.0 .
+.Sh AUTHORS
+.Nm libxo
+was written by
+.An Phil Shafer Aq Mt phil@freebsd.org .
+