diff options
Diffstat (limited to 'static/freebsd/man5/xo_format.5')
| -rw-r--r-- | static/freebsd/man5/xo_format.5 | 984 |
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 . + |
