1LIBXO(3)                 BSD Library Functions Manual                 LIBXO(3)
2

NAME

4     xo_format — content of format descriptors for xo_emit
5

DESCRIPTION

7     libxo uses format strings to control the rendering of data into various
8     output styles, including text, XML, JSON, and HTML.  Each format string
9     contains a set of zero or more “field descriptions”, which describe inde‐
10     pendent data fields.  Each field description contains a set of
11     “modifiers”, a “content string”, and zero, one, or two “format
12     descriptors”.  The modifiers tell libxo what the field is and how to
13     treat it, while the format descriptors are formatting instructions using
14     printf(3)-style format strings, telling libxo how to format the field.
15     The field description is placed inside a set of braces, with a colon
16     (‘:’) after the modifiers and a slash (‘/’) before each format descrip‐
17     tors.  Text may be intermixed with field descriptions within the format
18     string.
19
20     The field description is given as follows:
21
22               '{' [ role | modifier ]* [',' long-names ]* ':' [ content ]
23                       [ '/' field-format [ '/' encoding-format ]] '}'
24
25     The role describes the function of the field, while the modifiers enable
26     optional behaviors.  The contents, field-format, and encoding-format are
27     used in varying ways, based on the role.  These are described in the fol‐
28     lowing sections.
29
30     Braces can be escaped by using double braces, similar to "%%" in
31     printf(3).  The format string "{{braces}}" would emit "{braces}".
32
33     In the following example, three field descriptors appear.  The first is a
34     padding field containing three spaces of padding, the second is a label
35     ("In stock"), and the third is a value field ("in-stock").  The in-stock
36     field has a "%u" format that will parse the next argument passed to the
37     xo_emit(3), function as an unsigned integer.
38
39               xo_emit("{P:   }{Lwc:In stock}{:in-stock/%u}\n", 65);
40
41     This single line of code can generate text ("In stock: 65\n"), XML
42     ("<in-stock>65</in-stock>"), JSON ('"in-stock": 65'), or HTML (too
43     lengthy to be listed here).
44
45     While roles and modifiers typically use single character for brevity,
46     there are alternative names for each which allow more verbose formatting
47     strings.  These names must be preceded by a comma, and may follow any
48     single-character values:
49
50               xo_emit("{L,white,colon:In stock}{,key:in-stock/%u}\n", 65);
51
52   Field Roles
53     Field roles are optional, and indicate the role and formatting of the
54     content.  The roles are listed below; only one role is permitted:
55
56     M Name         Description
57     C color        Field is a color or effect
58     D decoration   Field is non-text (e.g. colon, comma)
59     E error        Field is an error message
60     L label        Field is text that prefixes a value
61     N note         Field is text that follows a value
62     P padding      Field is spaces needed for vertical alignment
63     T title        Field is a title value for headings
64     U units        Field is the units for the previous value field
65     V value        Field is the name of field (the default)
66     W warning      Field is a warning message
67     [ start-anchor Begin a section of anchored variable-width text
68     ] stop-anchor  End a section of anchored variable-width text
69
70              EXAMPLE:
71                  xo_emit("{L:Free}{D::}{P:   }{:free/%u} {U:Blocks}\n",
72                          free_blocks);
73
74     When a role is not provided, the "value" role is used as the default.
75
76     Roles and modifiers can also use more verbose names, when preceded by a
77     comma:
78
79              EXAMPLE:
80                   xo_emit("{,label:Free}{,decoration::}{,padding:   }"
81                          "{,value:free/%u} {,units:Blocks}\n",
82                          free_blocks);
83
84   The Color Role ({C:})
85     Colors and effects control how text values are displayed; they are used
86     for display styles (TEXT and HTML).
87
88               xo_emit("{C:bold}{:value}{C:no-bold}\n", value);
89
90     Colors and effects remain in effect until modified by other "C"-role
91     fields.
92
93               xo_emit("{C:bold}{C:inverse}both{C:no-bold}only inverse\n");
94
95     If the content is empty, the "reset" action is performed.
96
97               xo_emit("{C:both,underline}{:value}{C:}\n", value);
98
99     The content should be a comma-separated list of zero or more colors or
100     display effects.
101
102               xo_emit("{C:bold,underline,inverse}All three{C:no-bold,no-inverse}\n");
103
104     The color content can be either static, when placed directly within the
105     field descriptor, or a printf-style format descriptor can be used, if
106     preceded by a slash ("/"):
107
108              xo_emit("{C:/%s%s}{:value}{C:}", need_bold ? "bold" : "",
109                      need_underline ? "underline" : "", value);
110
111     Color names are prefixed with either "fg-" or "bg-" to change the fore‐
112     ground and background colors, respectively.
113
114               xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
115                       fg_color, bg_color, cost);
116
117     The following table lists the supported effects:
118
119     Name          Description
120     bg-xxxxx      Change background color
121     bold          Start bold text effect
122     fg-xxxxx      Change foreground color
123     inverse       Start inverse (aka reverse) text effect
124     no-bold       Stop bold text effect
125     no-inverse    Stop inverse (aka reverse) text effect
126     no-underline  Stop underline text effect
127     normal        Reset effects (only)
128     reset         Reset colors and effects (restore defaults)
129     underline     Start underline text effect
130
131     The following color names are supported:
132
133     Name
134     black
135     blue
136     cyan
137     default
138     green
139     magenta
140     red
141     white
142     yellow
143
144   The Decoration Role ({D:})
145     Decorations are typically punctuation marks such as colons, semi-colons,
146     and commas used to decorate the text and make it simpler for human read‐
147     ers.  By marking these distinctly, HTML usage scenarios can use CSS to
148     direct their display parameters.
149
150               xo_emit("{D:((}{:name}{D:))}\n", name);
151
152   The Gettext Role ({G:})
153     libxo supports internationalization (i18n) through its use of gettext(3).
154     Use the "{G:}" role to request that the remaining part of the format
155     string, following the "{G:}" field, be handled using gettext().  Since
156     gettext() uses the string as the key into the message catalog, libxo uses
157     a simplified version of the format string that removes unimportant field
158     formatting and modifiers, stopping minor formatting changes from impact‐
159     ing the expensive translation process.  A developer change such as chang‐
160     ing "/%06d" to "/%08d" should not force hand inspection of all .po files.
161
162     The simplified version can be generated for a single message using the
163     "xopo -s <text>" command, or an entire .pot can be translated using the
164     "xopo -f <input> -o <output>" command.
165
166              xo_emit("{G:}Invalid token\n");
167
168     The {G:} role allows a domain name to be set.  gettext() calls will con‐
169     tinue to use that domain name until the current format string processing
170     is complete, enabling a library function to emit strings using it's own
171     catalog.  The domain name can be either static as the content of the
172     field, or a format can be used to get the domain name from the arguments.
173
174              xo_emit("{G:libc}Service unavailable in restricted mode\n");
175
176   The Label Role ({L:})
177     Labels are text that appears before a value.
178
179               xo_emit("{Lwc:Cost}{:cost/%u}\n", cost);
180
181     If a label needs to include a slash, it must be escaped using two back‐
182     slashes, one for the C compiler and one for libxo.
183
184               xo_emit("{Lc:Low\\/warn level}{:level/%s}\n", level);
185
186   The Note Role ({N:})
187     Notes are text that appears after a value.
188
189               xo_emit("{:cost/%u} {N:per year}\n", cost);
190
191   The Padding Role ({P:})
192     Padding represents whitespace used before and between fields.  The pad‐
193     ding content can be either static, when placed directly within the field
194     descriptor, or a printf-style format descriptor can be used, if preceded
195     by a slash ("/"):
196
197               xo_emit("{P:        }{Lwc:Cost}{:cost/%u}\n", cost);
198               xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\n", "", cost);
199
200   The Title Role ({T:})
201     Titles are heading or column headers that are meant to be displayed to
202     the user.  The title can be either static, when placed directly within
203     the field descriptor, or a printf-style format descriptor can be used, if
204     preceded by a slash ("/"):
205
206               xo_emit("{T:Interface Statistics}\n");
207               xo_emit("{T:/%20.20s}{T:/%6.6s}\n", "Item Name", "Cost");
208
209   The Units Role ({U:})
210     Units are the dimension by which values are measured, such as degrees,
211     miles, bytes, and decibels.  The units field carries this information for
212     the previous value field.
213
214               xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\n", miles);
215
216     Note that the sense of the 'w' modifier is reversed for units; a blank is
217     added before the contents, rather than after it.
218
219     When the XOF_UNITS flag is set, units are rendered in XML as the “units”
220     attribute:
221
222               <distance units="miles">50</distance>
223
224     Units can also be rendered in HTML as the "data-units" attribute:
225
226               <div class="data" data-tag="distance" data-units="miles"
227                    data-xpath="/top/data/distance">50</div>
228
229   The Value Role ({V:} and {:})
230     The value role is used to represent the a data value that is interesting
231     for the non-display output styles (XML and JSON).  Value is the default
232     role; if no other role designation is given, the field is a value.  The
233     field name must appear within the field descriptor, followed by one or
234     two format descriptors.  The first format descriptor is used for display
235     styles (TEXT and HTML), while the second one is used for encoding styles
236     (XML and JSON).  If no second format is given, the encoding format de‐
237     faults to the first format, with any minimum width removed.  If no first
238     format is given, both format descriptors default to "%s".
239
240               xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\n",
241                       length, width, height);
242               xo_emit("{:author} wrote
243                       author, poem, year);
244
245   The Anchor Roles ({[:} and {]:})
246     The anchor roles allow a set of strings by be padded as a group, but
247     still be visible to xo_emit(3) as distinct fields.  Either the start or
248     stop anchor can give a field width and it can be either directly in the
249     descriptor or passed as an argument.  Any fields between the start and
250     stop anchor are padded to meet the minimum width given.
251
252     To give a width directly, encode it as the content of the anchor tag:
253
254               xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\n", min, max);
255
256     To pass a width as an argument, use "%d" as the format, which must appear
257     after the "/".  Note that only "%d" is supported for widths.  Using any
258     other value could ruin your day.
259
260               xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\n", width, min, max);
261
262     If the width is negative, padding will be added on the right, suitable
263     for left justification.  Otherwise the padding will be added to the left
264     of the fields between the start and stop anchors, suitable for right jus‐
265     tification.  If the width is zero, nothing happens.  If the number of
266     columns of output between the start and stop anchors is less than the ab‐
267     solute value of the given width, nothing happens.
268
269     Widths over 8k are considered probable errors and not supported.  If
270     XOF_WARN is set, a warning will be generated.
271
272   Field Modifiers
273     Field modifiers are flags which modify the way content emitted for par‐
274     ticular output styles:
275
276     M Name           Description
277     a argument       The content appears as a "const char *" argument
278     c colon          A colon (":") is appended after the label
279     d display        Only emit field for display styles (text/HTML)
280     e encoding       Only emit for encoding styles (XML/JSON)
281     h humanize (hn)  Format large numbers in human-readable style
282       hn-space      Humanize: Place space between numeric and unit
283       hn-decimal    Humanize: Add a decimal digit, if number < 10
284       hn-1000       Humanize: Use 1000 as divisor instead of 1024
285     k key            Field is a key, suitable for XPath predicates
286     l leaf-list     Field is a leaf-list, a list of leaf values
287     n no-quotes     Do not quote the field when using JSON style
288     q quotes         Quote the field when using JSON style
289     t trim           Trim leading and trailing whitespace
290     w white space    A blank (" ") is appended after the label
291
292     For example, the modifier string "Lwc" means the field has a label role
293     (text that describes the next field) and should be followed by a colon
294     ('c') and a space ('w').  The modifier string "Vkq" means the field has a
295     value role, that it is a key for the current instance, and that the value
296     should be quoted when encoded for JSON.
297
298     Roles and modifiers can also use more verbose names, when preceded by a
299     comma.  For example, the modifier string "Lwc" (or "L,white,colon") means
300     the field has a label role (text that describes the next field) and
301     should be followed by a colon ('c') and a space ('w').  The modifier
302     string "Vkq" (or ":key,quote") means the field has a value role (the de‐
303     fault role), that it is a key for the current instance, and that the
304     value should be quoted when encoded for JSON.
305
306   The Argument Modifier ({a:})
307     The argument modifier indicates that the content of the field descriptor
308     will be placed as a UTF-8 string (const char *) argument within the
309     xo_emit parameters.
310
311               EXAMPLE:
312                 xo_emit("{La:} {a:}\n", "Label text", "label", "value");
313               TEXT:
314                 Label text value
315               JSON:
316                 "label": "value"
317               XML:
318                 <label>value</label>
319
320     The argument modifier allows field names for value fields to be passed on
321     the stack, avoiding the need to build a field descriptor using
322     snprintf(1).  For many field roles, the argument modifier is not needed,
323     since those roles have specific mechanisms for arguments, such as
324     "{C:fg-%s}".
325
326   The Colon Modifier ({c:})
327     The colon modifier appends a single colon to the data value:
328
329               EXAMPLE:
330                 xo_emit("{Lc:Name}{:name}\n", "phil");
331               TEXT:
332                 Name:phil
333
334     The colon modifier is only used for the TEXT and HTML output styles.  It
335     is commonly combined with the space modifier ('{w:}').  It is purely a
336     convenience feature.
337
338   The Display Modifier ({d:})
339     The display modifier indicated the field should only be generated for the
340     display output styles, TEXT and HTML.
341
342               EXAMPLE:
343                 xo_emit("{Lcw:Name}{d:name} {:id/%d}\n", "phil", 1);
344               TEXT:
345                 Name: phil 1
346               XML:
347                 <id>1</id>
348
349     The display modifier is the opposite of the encoding modifier, and they
350     are often used to give to distinct views of the underlying data.
351
352   The Encoding Modifier ({e:})
353     The encoding modifier indicated the field should only be generated for
354     the encoding output styles, such as JSON and XML.
355
356               EXAMPLE:
357                 xo_emit("{Lcw:Name}{:name} {e:id/%d}\n", "phil", 1);
358               TEXT:
359                 Name: phil
360               XML:
361                 <name>phil</name><id>1</id>
362
363     The encoding modifier is the opposite of the display modifier, and they
364     are often used to give to distinct views of the underlying data.
365
366   The Humanize Modifier ({h:})
367     The humanize modifier is used to render large numbers as in a human-read‐
368     able format.  While numbers like "44470272" are completely readable to
369     computers and savants, humans will generally find "44M" more meaningful.
370
371     "hn" can be used as an alias for "humanize".
372
373     The humanize modifier only affects display styles (TEXT and HMTL).  The
374     "no-humanize" option will block the function of the humanize modifier.
375
376     There are a number of modifiers that affect details of humanization.
377     These are only available in as full names, not single characters.  The
378     "hn-space" modifier places a space between the number and any multiplier
379     symbol, such as "M" or "K" (ex: "44 K").  The "hn-decimal" modifier will
380     add a decimal point and a single tenths digit when the number is less
381     than 10 (ex: "4.4K").  The "hn-1000" modifier will use 1000 as divisor
382     instead of 1024, following the JEDEC-standard instead of the more natural
383     binary powers-of-two tradition.
384
385               EXAMPLE:
386                   xo_emit("{h:input/%u}, {h,hn-space:output/%u}, "
387                      "{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, "
388                      "{h,hn-decimal:remaining/%u}\n",
389                       input, output, errors, capacity, remaining);
390               TEXT:
391                   21, 57 K, 96M, 44M, 1.2G
392
393     In the HTML style, the original numeric value is rendered in the
394     "data-number" attribute on the <div> element:
395
396               <div class="data" data-tag="errors"
397                    data-number="100663296">96M</div>
398
399   The Gettext Modifier ({g:})
400     The gettext modifier is used to translate individual fields using the
401     gettext domain (typically set using the "{G:}" role) and current language
402     settings.  Once libxo renders the field value, it is passed to
403     gettext(3), where it is used as a key to find the native language trans‐
404     lation.
405
406     In the following example, the strings "State" and "full" are passed to
407     gettext() to find locale-based translated strings.
408
409               xo_emit("{Lgwc:State}{g:state}\n", "full");
410
411   The Key Modifier ({k:})
412     The key modifier is used to indicate that a particular field helps
413     uniquely identify an instance of list data.
414
415               EXAMPLE:
416                   xo_open_list("user");
417                   for (i = 0; i < num_users; i++) {
418                       xo_open_instance("user");
419                       xo_emit("User {k:name} has {:count} tickets\n",
420                          user[i].u_name, user[i].u_tickets);
421                       xo_close_instance("user");
422                   }
423                   xo_close_list("user");
424
425     Currently the key modifier is only used when generating XPath values for
426     the HTML output style when XOF_XPATH is set, but other uses are likely in
427     the near future.
428
429   The Leaf-List Modifier ({l:})
430     The leaf-list modifier is used to distinguish lists where each instance
431     consists of only a single value.  In XML, these are rendered as single
432     elements, where JSON renders them as arrays.
433
434               EXAMPLE:
435                   xo_open_list("user");
436                   for (i = 0; i < num_users; i++) {
437                       xo_emit("Member {l:name}\n", user[i].u_name);
438                   }
439                   xo_close_list("user");
440               XML:
441                   <user>phil</user>
442                   <user>pallavi</user>
443               JSON:
444                   "user": [ "phil", "pallavi" ]
445
446   The No-Quotes Modifier ({n:})
447     The no-quotes modifier (and its twin, the 'quotes' modifier) affect the
448     quoting of values in the JSON output style.  JSON uses quotes for string
449     values, but no quotes for numeric, boolean, and null data.  xo_emit(3)
450     applies a simple heuristic to determine whether quotes are needed, but
451     often this needs to be controlled by the caller.
452
453               EXAMPLE:
454                 const char *bool = is_true ? "true" : "false";
455                 xo_emit("{n:fancy/%s}", bool);
456               JSON:
457                 "fancy": true
458
459   The Plural Modifier ({p:})
460     The plural modifier selects the appropriate plural form of an expression
461     based on the most recent number emitted and the current language set‐
462     tings.  The contents of the field should be the singular and plural Eng‐
463     lish values, separated by a comma:
464
465               xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes);
466
467     The plural modifier is meant to work with the gettext modifier ({g:}) but
468     can work independently.
469
470     When used without the gettext modifier or when the message does not ap‐
471     pear in the message catalog, the first token is chosen when the last nu‐
472     meric value is equal to 1; otherwise the second value is used, mimicking
473     the simple pluralization rules of English.
474
475     When used with the gettext modifier, the ngettext(3) function is called
476     to handle the heavy lifting, using the message catalog to convert the
477     singular and plural forms into the native language.
478
479   The Quotes Modifier ({q:})
480     The quotes modifier (and its twin, the 'no-quotes' modifier) affect the
481     quoting of values in the JSON output style.  JSON uses quotes for string
482     values, but no quotes for numeric, boolean, and null data.  xo_emit(3)
483     applies a simple heuristic to determine whether quotes are needed, but
484     often this needs to be controlled by the caller.
485
486               EXAMPLE:
487                 xo_emit("{q:time/%d}", 2014);
488               JSON:
489                 "year": "2014"
490
491   The White Space Modifier ({w:})
492     The white space modifier appends a single space to the data value:
493
494               EXAMPLE:
495                 xo_emit("{Lw:Name}{:name}\n", "phil");
496               TEXT:
497                 Name phil
498
499     The white space modifier is only used for the TEXT and HTML output
500     styles.  It is commonly combined with the colon modifier ('{c:}').  It is
501     purely a convenience feature.
502
503     Note that the sense of the 'w' modifier is reversed for the units role
504     ({Uw:}); a blank is added before the contents, rather than after it.
505
506   Field Formatting
507     The field format is similar to the format string for printf(3).  Its use
508     varies based on the role of the field, but generally is used to format
509     the field's contents.
510
511     If the format string is not provided for a value field, it defaults to
512     "%s".
513
514     Note a field definition can contain zero or more printf-style
515     “directives”, which are sequences that start with a '%' and end with one
516     of following characters: "diouxXDOUeEfFgGaAcCsSp".  Each directive is
517     matched by one of more arguments to the xo_emit(3) function.
518
519     The format string has the form:
520
521             '%' format-modifier * format-character
522
523     The format-modifier can be:
524
525     a '#' character, indicating the output value should be prefixed with
526         "0x", typically to indicate a base 16 (hex) value.
527
528     a minus sign ('-'), indicating the output value should be padded on
529         the right instead of the left.
530
531     a leading zero ('0') indicating the output value should be padded on
532         the left with zeroes instead of spaces (' ').
533
534     one or more digits ('0' - '9') indicating the minimum width of the
535         argument.  If the width in columns of the output value is less than
536         the minimum width, the value will be padded to reach the minimum.
537
538     a period followed by one or more digits indicating the maximum number
539         of bytes which will be examined for a string argument, or the maximum
540         width for a non-string argument.  When handling ASCII strings this
541         functions as the field width but for multi-byte characters, a single
542         character may be composed of multiple bytes.  xo_emit(3) will never
543         dereference memory beyond the given number of bytes.
544
545     a second period followed by one or more digits indicating the maximum
546         width for a string argument.  This modifier cannot be given for
547         non-string arguments.
548
549     one or more 'h' characters, indicating shorter input data.
550
551     one or more 'l' characters, indicating longer input data.
552
553     a 'z' character, indicating a 'size_t' argument.
554
555     a 't' character, indicating a 'ptrdiff_t' argument.
556
557     a ' ' character, indicating a space should be emitted before positive
558         numbers.
559
560     a '+' character, indicating sign should emitted before any number.
561
562     Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be
563     removed eventually.
564
565     The format character is described in the following table:
566
567     C Argument Type   Format
568     d int             base 10 (decimal)
569     i int             base 10 (decimal)
570     o int             base 8 (octal)
571     u unsigned        base 10 (decimal)
572     x unsigned        base 16 (hex)
573     X unsigned long   base 16 (hex)
574     D long            base 10 (decimal)
575     O unsigned long   base 8 (octal)
576     U unsigned long   base 10 (decimal)
577     e double          [-]d.ddde+-dd
578     E double          [-]d.dddE+-dd
579     f double          [-]ddd.ddd
580     F double          [-]ddd.ddd
581     g double          as 'e' or 'f'
582     G double          as 'E' or 'F'
583     a double          [-]0xh.hhhp[+-]d
584     A double          [-]0Xh.hhhp[+-]d
585     c unsigned char   a character
586     C wint_t          a character
587     s char *          a UTF-8 string
588     S wchar_t *       a unicode/WCS string
589     p void *          '%#lx'
590
591     The 'h' and 'l' modifiers affect the size and treatment of the argument:
592
593     Mod d, i         o, u, x, X
594     hh  signed char  unsigned char
595     h   short        unsigned short
596     l   long         unsigned long
597     ll  long long    unsigned long long
598     j   intmax_t     uintmax_t
599     t   ptrdiff_t    ptrdiff_t
600     z   size_t       size_t
601     q   quad_t       u_quad_t
602
603   UTF-8 and Locale Strings
604     All strings for libxo must be UTF-8.  libxo will handle turning them into
605     locale-based strings for display to the user.
606
607     For strings, the 'h' and 'l' modifiers affect the interpretation of the
608     bytes pointed to argument.  The default '%s' string is a 'char *' pointer
609     to a string encoded as UTF-8.  Since UTF-8 is compatible with ASCII data,
610     a normal 7-bit ASCII string can be used.  "%ls" expects a "wchar_t *"
611     pointer to a wide-character string, encoded as 32-bit Unicode values.
612     "%hs" expects a "char *" pointer to a multi-byte string encoded with the
613     current locale, as given by the LC_CTYPE, LANG, or LC_ALL environment
614     variables.  The first of this list of variables is used and if none of
615     the variables are set, the locale defaults to UTF-8.
616
617     libxo will convert these arguments as needed to either UTF-8 (for XML,
618     JSON, and HTML styles) or locale-based strings for display in text style.
619
620              xo_emit("All strings are utf-8 content {:tag/%ls}",
621                      L"except for wide strings");
622
623     "%S" is equivalent to "%ls".
624
625     For example, a function is passed a locale-base name, a hat size, and a
626     time value.  The hat size is formatted in a UTF-8 (ASCII) string, and the
627     time value is formatted into a wchar_t string.
628
629               void print_order (const char *name, int size,
630                                 struct tm *timep) {
631                   char buf[32];
632                   const char *size_val = "unknown";
633
634                   if (size > 0)
635                       snprintf(buf, sizeof(buf), "%d", size);
636                       size_val = buf;
637                   }
638
639                   wchar_t when[32];
640                   wcsftime(when, sizeof(when), L"%d%b%y", timep);
641
642                   xo_emit("The hat for {:name/%hs} is {:size/%s}.\n",
643                           name, size_val);
644                   xo_emit("It was ordered on {:order-time/%ls}.\n",
645                           when);
646               }
647
648     It is important to note that xo_emit(3) will perform the conversion re‐
649     quired to make appropriate output.  Text style output uses the current
650     locale (as described above), while XML, JSON, and HTML use UTF-8.
651
652     UTF-8 and locale-encoded strings can use multiple bytes to encode one
653     column of data.  The traditional "precision" (aka "max-width") value for
654     "%s" printf formatting becomes overloaded since it specifies both the
655     number of bytes that can be safely referenced and the maximum number of
656     columns to emit.  xo_emit(3) uses the precision as the former, and adds a
657     third value for specifying the maximum number of columns.
658
659     In this example, the name field is printed with a minimum of 3 columns
660     and a maximum of 6.  Up to ten bytes are in used in filling those col‐
661     umns.
662
663               xo_emit("{:name/%3.10.6s}", name);
664
665   Characters Outside of Field Definitions
666     Characters in the format string that are not part of a field definition
667     are copied to the output for the TEXT style, and are ignored for the JSON
668     and XML styles.  For HTML, these characters are placed in a <div> with
669     class "text".
670
671             EXAMPLE:
672                 xo_emit("The hat is {:size/%s}.\n", size_val);
673             TEXT:
674                 The hat is extra small.
675             XML:
676                 <size>extra small</size>
677             JSON:
678                 "size": "extra small"
679             HTML:
680                 <div class="text">The hat is </div>
681                 <div class="data" data-tag="size">extra small</div>
682                 <div class="text">.</div>
683
684   '%n' is Not Supported
685     libxo does not support the '%n' directive.  It is a bad idea and we just
686     do not do it.
687
688   The Encoding Format (eformat)
689     The "eformat" string is the format string used when encoding the field
690     for JSON and XML.  If not provided, it defaults to the primary format
691     with any minimum width removed.  If the primary is not given, both de‐
692     fault to "%s".
693

EXAMPLE

695     In this example, the value for the number of items in stock is emitted:
696
697                   xo_emit("{P:   }{Lwc:In stock}{:in-stock/%u}\n",
698                           instock);
699
700     This call will generate the following output:
701
702             TEXT:
703                  In stock: 144
704             XML:
705                 <in-stock>144</in-stock>
706             JSON:
707                 "in-stock": 144,
708             HTML:
709                 <div class="line">
710                   <div class="padding">   </div>
711                   <div class="label">In stock</div>
712                   <div class="decoration">:</div>
713                   <div class="padding"> </div>
714                   <div class="data" data-tag="in-stock">144</div>
715                 </div>
716
717     Clearly HTML wins the verbosity award, and this output does not include
718     XOF_XPATH or XOF_INFO data, which would expand the penultimate line to:
719
720                  <div class="data" data-tag="in-stock"
721                     data-xpath="/top/data/item/in-stock"
722                     data-type="number"
723                     data-help="Number of items in stock">144</div>
724

WHAT MAKES A GOOD FIELD NAME?

726     To make useful, consistent field names, follow these guidelines:
727
728   Use lower case, even for TLAs
729     Lower case is more civilized.  Even TLAs should be lower case to avoid
730     scenarios where the differences between "XPath" and "Xpath" drive your
731     users crazy.  Using "xpath" is simpler and better.
732
733   Use hyphens, not underscores
734     Use of hyphens is traditional in XML, and the XOF_UNDERSCORES flag can be
735     used to generate underscores in JSON, if desired.  But the raw field name
736     should use hyphens.
737
738   Use full words
739     Do not abbreviate especially when the abbreviation is not obvious or not
740     widely used.  Use "data-size", not "dsz" or "dsize".  Use "interface" in‐
741     stead of "ifname", "if-name", "iface", "if", or "intf".
742
743   Use <verb>-<units>
744     Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in
745     making consistent, useful names, avoiding the situation where one app
746     uses "sent-packet" and another "packets-sent" and another "pack‐
747     ets-we-have-sent".  The <units> can be dropped when it is obvious, as can
748     obvious words in the classification.  Use "receive-after-window-packets"
749     instead of "received-packets-of-data-after-window".
750
751   Reuse existing field names
752     Nothing is worse than writing expressions like:
753
754               if ($src1/process[pid == $pid]/name ==
755                   $src2/proc-table/proc/p[process-id == $pid]/proc-name) {
756                   ...
757               }
758
759     Find someone else who is expressing similar data and follow their fields
760     and hierarchy.  Remember the quote is not “Consistency is the hobgoblin
761     of little minds” but “A foolish consistency is the hobgoblin of little
762     minds”.
763
764   Think about your users
765     Have empathy for your users, choosing clear and useful fields that con‐
766     tain clear and useful data.  You may need to augment the display content
767     with xo_attr(3) calls or "{e:}" fields to make the data useful.
768
769   Do not use an arbitrary number postfix
770     What does "errors2" mean?  No one will know.  "errors-after-restart"
771     would be a better choice.  Think of your users, and think of the future.
772     If you make "errors2", the next guy will happily make "errors3" and be‐
773     fore you know it, someone will be asking what is the difference between
774     errors37 and errors63.
775
776   Be consistent, uniform, unsurprising, and predictable
777     Think of your field vocabulary as an API.  You want it useful, expres‐
778     sive, meaningful, direct, and obvious.  You want the client application's
779     programmer to move between without the need to understand a variety of
780     opinions on how fields are named.  They should see the system as a single
781     cohesive whole, not a sack of cats.
782
783     Field names constitute the means by which client programmers interact
784     with our system.  By choosing wise names now, you are making their lives
785     better.
786
787     After using xolint(1) to find errors in your field descriptors, use
788     “xolint -V” to spell check your field names and to detect different names
789     for the same data.  “dropped-short” and “dropped-too-short” are both rea‐
790     sonable names, but using them both will lead users to ask the difference
791     between the two fields.  If there is no difference, use only one of the
792     field names.  If there is a difference, change the names to make that
793     difference more obvious.
794

SEE ALSO

796     libxo(3), xolint(1), xo_emit(3)
797

HISTORY

799     The libxo library first appeared in FreeBSD 11.0.
800

AUTHORS

802     libxo was written by Phil Shafer <phil@freebsd.org>.
803
804

ADDITIONAL DOCUMENTATION

806     FreeBSD uses libxo version 1.6.0.  Complete documentation can be found on
807     github:
808
809           https://juniper.github.io/libxo/1.6.0/html/index.html
810
811     libxo lives on github as:
812
813           https://github.com/Juniper/libxo
814
815     The latest release of libxo is available at:
816
817           https://github.com/Juniper/libxo/releases
818

HISTORY

820     The libxo library was added in FreeBSD 11.0.
821

AUTHOR

823     Phil Shafer
824
825BSD                            December 4, 2014                            BSD
Impressum