]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libxo/libxo/xo_format.5
Import Annapurna Labs Alpine HAL to sys/contrib/
[FreeBSD/FreeBSD.git] / contrib / libxo / libxo / xo_format.5
1 .\" #
2 .\" # Copyright (c) 2014, Juniper Networks, Inc.
3 .\" # All rights reserved.
4 .\" # This SOFTWARE is licensed under the LICENSE provided in the
5 .\" # ../Copyright file. By downloading, installing, copying, or 
6 .\" # using the SOFTWARE, you agree to be bound by the terms of that
7 .\" # LICENSE.
8 .\" # Phil Shafer, July 2014
9 .\" 
10 .Dd December 4, 2014
11 .Dt LIBXO 3
12 .Os
13 .Sh NAME
14 .Nm xo_format
15 .Nd content of format descriptors for xo_emit
16 .Sh DESCRIPTION
17 .Pp
18 .Nm libxo
19 uses format strings to control the rendering of data into
20 various output styles, including
21 .Em text ,
22 .Em XML ,
23 .EM JSON ,
24 and
25 .Em HTML .
26 Each format string contains a set of zero or more
27 .Dq field descriptions ,
28 which describe independent data fields.
29 Each field description contains a set of
30 .Dq modifiers ,
31 a
32 .Dq content string ,
33 and zero, one, or two
34 .Dq format descriptors .
35 The modifiers tell
36 .Nm libxo
37 what the field is and how to treat it, while the format descriptors are
38 formatting instructions using
39 .Xr printf 3 Ns -style
40 format strings, telling
41 .Nm libxo
42 how to format the field.
43 The field description is placed inside
44 a set of braces, with a colon
45 .Ql ( \&: )
46 after the modifiers and a slash
47 .Ql ( \&/ )
48 before each format descriptors.
49 Text may be intermixed with
50 field descriptions within the format string.
51 .Pp
52 The field description is given as follows:
53 .Bd -literal -offset indent
54     '{' [ role | modifier ]* ':' [ content ]
55             [ '/' field-format [ '/' encoding-format ]] '}'
56 .Ed
57 .Pp
58 The role describes the function of the field, while the modifiers
59 enable optional behaviors.
60 The contents, field-format, and
61 encoding-format are used in varying ways, based on the role.
62 These are described in the following sections.
63 .Pp
64 In the following example, three field descriptors appear.
65 The first
66 is a padding field containing three spaces of padding, the second is a
67 label ("In stock"), and the third is a value field ("in-stock").
68 The in-stock field has a "%u" format that will parse the next argument
69 passed to the
70 .Xr xo_emit 3 ,
71 function as an unsigned integer.
72 .Bd -literal -offset indent
73         xo_emit("{P:   }{Lwc:In stock}{:in-stock/%u}\\n", 65);
74 .Ed
75 .Pp
76 This single line of code can generate text ("In stock: 65\\n"), XML
77 ("<in-stock>65</in-stock>"), JSON ('"in-stock": 65'), or HTML (too
78 lengthy to be listed here).
79 .Ss Modifier Roles
80 Modifiers are optional, and indicate the role and formatting of the
81 content.
82 The roles are listed below; only one role is permitted:
83 .Pp
84 .Bl -column "M" "Name12341234"
85 .It Sy "M  Name           Description"
86 .It D "decoration  " "Field is non-text (e.g. colon, comma)"
87 .It E "error       " "Field is an error message"
88 .It L "label       " "Field is text that prefixes a value"
89 .It N "note        " "Field is text that follows a value"
90 .It P "padding     " "Field is spaces needed for vertical alignment"
91 .It T "title       " "Field is a title value for headings"
92 .It U "units       " "Field is the units for the previous value field"
93 .It V "value       " "Field is the name of field (the default)"
94 .It W "warning     " "Field is a warning message"
95 .It \&[ "start anchor" "Begin a section of anchored variable-width text"
96 .It \&] "stop anchor " "End a section of anchored variable-width text"
97 .El
98 .Pp
99 .Ss The Color Role ({C:})
100 Colors and effects control how text values are displayed; they are
101 used for display styles (TEXT and HTML).
102 The color content can be
103 either static, when placed directly within the field descriptor, or a
104 printf-style format descriptor can be used, if preceded by a slash ("/"):
105 .Bd -literal -offset indent
106     xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost);
107     xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
108             fg_color, bg_color, cost);
109 .Ed
110 .Pp
111 The content should be a comma-separated list of zero or more colors or
112 display effects.
113 .Pp
114 Colors and effects remain in effect until modified by other "C" roles.
115 .Pp
116 If the content is empty, the "reset" action is performed.
117 .Pp
118 .Bl -column "no-underline"
119 .It Sy "Name          Description"
120 .It "bg-xxxxx     " "Change background color"
121 .It "bold         " "Start bold text effect"
122 .It "fg-xxxxx     " "Change foreground color"
123 .It "inverse      " "Start inverse (aka reverse) text effect"
124 .It "no-bold      " "Stop bold text effect"
125 .It "no-inverse   " "Stop inverse (aka reverse) text effect"
126 .It "no-underline " "Stop underline text effect"
127 .It "normal       " "Reset effects (only)"
128 .It "reset        " "Reset colors and effects (restore defaults)"
129 .It "underline    " "Start underline text effect"
130 .El
131 .Pp
132 The following color names are supported:
133 .Bl -column "no-underline"
134 .It Sy "Name"
135 .It black
136 .It blue
137 .It cyan
138 .It default
139 .It green
140 .It magenta
141 .It red
142 .It white
143 .It yellow
144 .El
145 .Pp
146 Color names are prefixed with either "fg-" or "bg-" to change the
147 foreground and background colors, respectively.
148 .Ss The Decoration Role ({D:})
149 Decorations are typically punctuation marks such as colons,
150 semi-colons, and commas used to decorate the text and make it simpler
151 for human readers.
152 By marking these distinctly, HTML usage scenarios
153 can use CSS to direct their display parameters.
154 .Bd -literal -offset indent
155     xo_emit("{D:((}{:name}{D:))}\\n", name);
156 .Ed
157 .Ss The Label Role ({L:})
158 Labels are text that appears before a value.
159 .Bd -literal -offset indent
160     xo_emit("{Lwc:Cost}{:cost/%u}\\n", cost);
161 .Ed
162 .Ss The Note Role ({N:})
163 Notes are text that appears after a value.
164 .Bd -literal -offset indent
165     xo_emit("{:cost/%u} {N:per year}\\n", cost);
166 .Ed
167 .Ss The Padding Role ({P:})
168 Padding represents whitespace used before and between fields.
169 The padding content can be either static, when placed directly within
170 the field descriptor, or a printf-style format descriptor can be used,
171 if preceded by a slash ("/"):
172 .Bd -literal -offset indent
173     xo_emit("{P:        }{Lwc:Cost}{:cost/%u}\\n", cost);
174     xo_emit("{P:/30s}{Lwc:Cost}{:cost/%u}\\n", "", cost);
175 .Ed
176 .Ss The Title Role ({T:})
177 Titles are heading or column headers that are meant to be displayed to
178 the user.
179 The title can be either static, when placed directly within
180 the field descriptor, or a printf-style format descriptor can be used,
181 if preceded by a slash ("/"):
182 .Bd -literal -offset indent
183     xo_emit("{T:Interface Statistics}\\n");
184     xo_emit("{T:/%20.20s}{T:/%6.6s}\\n", "Item Name", "Cost");
185 .Ed
186 .Ss The Units Role ({U:})
187 Units are the dimension by which values are measured, such as degrees,
188 miles, bytes, and decibels.
189 The units field carries this information
190 for the previous value field.
191 .Bd -literal -offset indent
192     xo_emit("{Lwc:Distance}{:distance/%u}{Uw:miles}\\n", miles);
193 .Ed
194 .Pp
195 Note that the sense of the 'w' modifier is reversed for units;
196 a blank is added before the contents, rather than after it.
197 .Pp
198 When the
199 .Dv XOF_UNITS
200 flag is set, units are rendered in XML as the
201 .Dq units
202 attribute:
203 .Bd -literal -offset indent
204     <distance units="miles">50</distance>
205 .Ed
206 .Pp
207 Units can also be rendered in HTML as the "data-units" attribute:
208 .Bd -literal -offset indent
209     <div class="data" data-tag="distance" data-units="miles"
210          data-xpath="/top/data/distance">50</div>
211 .Ed
212 .Ss The Value Role ({V:} and {:})
213 The value role is used to represent the a data value that is
214 interesting for the non-display output styles (XML and JSON).
215 Value
216 is the default role; if no other role designation is given, the field
217 is a value.
218 The field name must appear within the field descriptor,
219 followed by one or two format descriptors.
220 The first format
221 descriptor is used for display styles (TEXT and HTML), while the
222 second one is used for encoding styles (XML and JSON).
223 If no second
224 format is given, the encoding format defaults to the first format,
225 with any minimum width removed.
226 If no first format is given, both
227 format descriptors default to "%s".
228 .Bd -literal -offset indent
229     xo_emit("{:length/%02u}x{:width/%02u}x{:height/%02u}\\n",
230             length, width, height);
231     xo_emit("{:author} wrote \"{:poem}\" in {:year/%4d}\\n,
232             author, poem, year);
233 .Ed
234 .Ss The Anchor Modifiers ({[:} and {]:})
235 The anchor roles allow a set of strings by be padded as a group,
236 but still be visible to
237 .Xr xo_emit 3
238 as distinct fields.
239 Either the start
240 or stop anchor can give a field width and it can be either directly in
241 the descriptor or passed as an argument.
242 Any fields between the start
243 and stop anchor are padded to meet the minimum width given.
244 .Pp
245 To give a width directly, encode it as the content of the anchor tag:
246 .Bd -literal -offset indent
247     xo_emit("({[:10}{:min/%d}/{:max/%d}{]:})\\n", min, max);
248 .Ed
249 .Pp
250 To pass a width as an argument, use "%d" as the format, which must
251 appear after the "/".
252 Note that only "%d" is supported for widths.
253 Using any other value could ruin your day.
254 .Bd -literal -offset indent
255     xo_emit("({[:/%d}{:min/%d}/{:max/%d}{]:})\\n", width, min, max);
256 .Ed
257 .Pp
258 If the width is negative, padding will be added on the right, suitable
259 for left justification.
260 Otherwise the padding will be added to the
261 left of the fields between the start and stop anchors, suitable for
262 right justification.
263 If the width is zero, nothing happens.
264 If the
265 number of columns of output between the start and stop anchors is less
266 than the absolute value of the given width, nothing happens.
267 .Pp
268 Widths over 8k are considered probable errors and not supported.
269 If
270 .Dv XOF_WARN
271 is set, a warning will be generated.
272 .Ss Modifier Flags
273 The modifiers can also include the following flags, which modify the
274 content emitted for some output styles:
275 .Pp
276 .Bl -column M "Name12341234"
277 .It Sy M "Name        Description"
278 .It c "colon       " "A colon ("":"") is appended after the label"
279 .It d "display     " "Only emit field for display styles (text/HTML)"
280 .It e "encoding    " "Only emit for encoding styles (XML/JSON)"
281 .It k "key         " "Field is a key, suitable for XPath predicates"
282 .It l "leaf        " "Field is a leaf-list, a list of leaf values"
283 .It n "no-quotes   " "Do not quote the field when using JSON style"
284 .It q "quotes      " "Quote the field when using JSON style"
285 .It w "white space " "A blank ("" "") is appended after the label"
286 .El
287 .Pp
288 For example, the modifier string "Lwc" means the field has a label
289 role (text that describes the next field) and should be followed by a
290 colon ('c') and a space ('w').
291 The modifier string "Vkq" means the
292 field has a value role, that it is a key for the current instance, and
293 that the value should be quoted when encoded for JSON.
294 .Ss The Colon Modifier ({c:})
295 The colon modifier appends a single colon to the data value:
296 .Bd -literal -offset indent
297     EXAMPLE:
298       xo_emit("{Lc:Name}{:name}\\n", "phil");
299     TEXT:
300       Name:phil
301 .Ed
302 .Pp
303 The colon modifier is only used for the TEXT and HTML output
304 styles.
305 It is commonly combined with the space modifier ('{w:}').
306 It is purely a convenience feature.
307 .Ss The Display Modifier ({d:})
308 The display modifier indicated the field should only be generated for
309 the display output styles, TEXT and HTML.
310 .Bd -literal -offset indent
311     EXAMPLE:
312       xo_emit("{Lcw:Name}{d:name} {:id/%d}\\n", "phil", 1);
313     TEXT:
314       Name: phil 1
315     XML:
316       <id>1</id>
317 .Ed
318 .Pp
319 The display modifier is the opposite of the encoding modifier, and
320 they are often used to give to distinct views of the underlying data.
321 .Ss The Encoding Modifier ({e:})
322 The encoding modifier indicated the field should only be generated for
323 the encoding output styles, such as JSON and XML.
324 .Bd -literal -offset indent
325     EXAMPLE:
326       xo_emit("{Lcw:Name}{:name} {e:id/%d}\\n", "phil", 1);
327     TEXT:
328       Name: phil
329     XML:
330       <name>phil</name><id>1</id>
331 .Ed
332 .Pp
333 The encoding modifier is the opposite of the display modifier, and
334 they are often used to give to distinct views of the underlying data.
335 .Ss The Key Modifier ({k:})
336 The key modifier is used to indicate that a particular field helps
337 uniquely identify an instance of list data.
338 .Bd -literal -offset indent
339     EXAMPLE:
340         xo_open_list("user");
341         for (i = 0; i < num_users; i++) {
342             xo_open_instance("user");
343             xo_emit("User {k:name} has {:count} tickets\\n",
344                user[i].u_name, user[i].u_tickets);
345             xo_close_instance("user");
346         }
347         xo_close_list("user");
348 .Ed
349 .Pp
350 Currently the key modifier is only used when generating XPath values
351 for the HTML output style when
352 .Dv XOF_XPATH
353 is set, but other uses are likely in the near future.
354 .Ss The Leaf-List Modifier ({l:})
355 The leaf-list modifier is used to distinguish lists where each
356 instance consists of only a single value.  In XML, these are
357 rendered as single elements, where JSON renders them as arrays.
358 .Bd -literal -offset indent
359     EXAMPLE:
360         xo_open_list("user");
361         for (i = 0; i < num_users; i++) {
362             xo_emit("Member {l:name}\n", user[i].u_name);
363         }
364         xo_close_list("user");
365     XML:
366         <user>phil</user>
367         <user>pallavi</user>
368     JSON:
369         "user": [ "phil", "pallavi" ]
370 .Ed
371 .Ss The No-Quotes Modifier ({n:})
372 The no-quotes modifier (and its twin, the 'quotes' modifier) affect
373 the quoting of values in the JSON output style.
374 JSON uses quotes for
375 string values, but no quotes for numeric, boolean, and null data.
376 .Xr xo_emit 3
377 applies a simple heuristic to determine whether quotes are
378 needed, but often this needs to be controlled by the caller.
379 .Bd -literal -offset indent
380     EXAMPLE:
381       const char *bool = is_true ? "true" : "false";
382       xo_emit("{n:fancy/%s}", bool);
383     JSON:
384       "fancy": true
385 .Ed
386 .Ss The Quotes Modifier ({q:})
387 The quotes modifier (and its twin, the 'no-quotes' modifier) affect
388 the quoting of values in the JSON output style.
389 JSON uses quotes for
390 string values, but no quotes for numeric, boolean, and null data.
391 .Xr xo_emit 3
392 applies a simple heuristic to determine whether quotes are
393 needed, but often this needs to be controlled by the caller.
394 .Bd -literal -offset indent
395     EXAMPLE:
396       xo_emit("{q:time/%d}", 2014);
397     JSON:
398       "year": "2014"
399 .Ed
400 .Ss The White Space Modifier ({w:})
401 The white space modifier appends a single space to the data value:
402 .Bd -literal -offset indent
403     EXAMPLE:
404       xo_emit("{Lw:Name}{:name}\\n", "phil");
405     TEXT:
406       Name phil
407 .Ed
408 .Pp
409 The white space modifier is only used for the TEXT and HTML output
410 styles.
411 It is commonly combined with the colon modifier ('{c:}').
412 It is purely a convenience feature.
413 .Pp
414 Note that the sense of the 'w' modifier is reversed for the units role
415 ({Uw:}); a blank is added before the contents, rather than after it.
416 .Ss Field Formatting
417 The field format is similar to the format string for
418 .Xr printf 3 .
419 Its use varies based on the role of the field, but generally is used to
420 format the field's contents.
421 .Pp
422 If the format string is not provided for a value field, it defaults
423 to "%s".
424 .Pp
425 Note a field definition can contain zero or more printf-style
426 .Dq directives ,
427 which are sequences that start with a '%' and end with
428 one of following characters: "diouxXDOUeEfFgGaAcCsSp".
429 Each directive
430 is matched by one of more arguments to the
431 .Xr xo_emit 3
432 function.
433 .Pp
434 The format string has the form:
435 .Bd -literal -offset indent
436   '%' format-modifier * format-character
437 .Ed
438 .Pp
439 The format- modifier can be:
440 .Bl -bullet
441 .It
442 a '#' character, indicating the output value should be prefixed with
443 '0x', typically to indicate a base 16 (hex) value.
444 .It
445 a minus sign ('-'), indicating the output value should be padded on
446 the right instead of the left.
447 .It
448 a leading zero ('0') indicating the output value should be padded on the
449 left with zeroes instead of spaces (' ').
450 .It
451 one or more digits ('0' - '9') indicating the minimum width of the
452 argument.
453 If the width in columns of the output value is less than
454 the minimum width, the value will be padded to reach the minimum.
455 .It
456 a period followed by one or more digits indicating the maximum
457 number of bytes which will be examined for a string argument, or the maximum
458 width for a non-string argument.
459 When handling ASCII strings this
460 functions as the field width but for multi-byte characters, a single
461 character may be composed of multiple bytes.
462 .Xr xo_emit 3
463 will never dereference memory beyond the given number of bytes.
464 .It
465 a second period followed by one or more digits indicating the maximum
466 width for a string argument.
467 This modifier cannot be given for non-string arguments. 
468 .It
469 one or more 'h' characters, indicating shorter input data.
470 .It
471 one or more 'l' characters, indicating longer input data.
472 .It
473 a 'z' character, indicating a 'size_t' argument.
474 .It
475 a 't' character, indicating a 'ptrdiff_t' argument.
476 .It
477 a ' ' character, indicating a space should be emitted before
478 positive numbers.
479 .It
480 a '+' character, indicating sign should emitted before any number.
481 .El
482 .Pp
483 Note that 'q', 'D', 'O', and 'U' are considered deprecated and will be
484 removed eventually.
485 .Pp
486 The format character is described in the following table:
487 .Pp
488 .Bl -column C "Argument Type12"
489 .It Sy "C Argument Type   Format"
490 .It d "int            " "base 10 (decimal)"
491 .It i "int            " "base 10 (decimal)"
492 .It o "int            " "base 8 (octal)"
493 .It u "unsigned       " "base 10 (decimal)"
494 .It x "unsigned       " "base 16 (hex)"
495 .It X "unsigned long  " "base 16 (hex)"
496 .It D "long           " "base 10 (decimal)"
497 .It O "unsigned long  " "base 8 (octal)"
498 .It U "unsigned long  " "base 10 (decimal)"
499 .It e "double         " "[-]d.ddde+-dd"
500 .It E "double         " "[-]d.dddE+-dd"
501 .It f "double         " "[-]ddd.ddd"
502 .It F "double         " "[-]ddd.ddd"
503 .It g "double         " "as 'e' or 'f'"
504 .It G "double         " "as 'E' or 'F'"
505 .It a "double         " "[-]0xh.hhhp[+-]d"
506 .It A "double         " "[-]0Xh.hhhp[+-]d"
507 .It c "unsigned char  " "a character"
508 .It C "wint_t         " "a character"
509 .It s "char *         " "a UTF-8 string"
510 .It S "wchar_t *      " "a unicode/WCS string"
511 .It p "void *         " "'%#lx'"
512 .El
513 .Pp
514 The 'h' and 'l' modifiers affect the size and treatment of the
515 argument:
516 .Bl -column "Mod" "d, i         " "o, u, x, X         "
517 .It Sy "Mod" "d, i        " "o, u, x, X"
518 .It "hh " "signed char " "unsigned char"
519 .It "h  " "short       " "unsigned short"
520 .It "l  " "long        " "unsigned long"
521 .It "ll " "long long   " "unsigned long long"
522 .It "j  " "intmax_t    " "uintmax_t"
523 .It "t  " "ptrdiff_t   " "ptrdiff_t"
524 .It "z  " "size_t      " "size_t"
525 .It "q  " "quad_t      " "u_quad_t"
526 .El
527 .Pp
528 .Ss UTF-8 and Locale Strings
529 All strings for
530 .Nm libxo
531 must be UTF-8.
532 .Nm libxo
533 will handle turning them
534 into locale-based strings for display to the user.
535 .Pp
536 For strings, the 'h' and 'l' modifiers affect the interpretation of
537 the bytes pointed to argument.
538 The default '%s' string is a 'char *'
539 pointer to a string encoded as UTF-8.
540 Since UTF-8 is compatible with
541 .Em ASCII
542 data, a normal 7-bit
543 .Em ASCII
544 string can be used.
545 '%ls' expects a
546 'wchar_t *' pointer to a wide-character string, encoded as 32-bit
547 Unicode values.
548 '%hs' expects a 'char *' pointer to a multi-byte
549 string encoded with the current locale, as given by the
550 .Ev LC_CTYPE ,
551 .Ev LANG ,
552 or
553 .Ev LC_ALL
554 environment variables.
555 The first of this list of
556 variables is used and if none of the variables are set, the locale defaults to
557 .Em UTF-8 .
558 .Pp
559 .Nm libxo
560 will
561 convert these arguments as needed to either UTF-8 (for XML, JSON, and
562 HTML styles) or locale-based strings for display in text style.
563 .Bd -literal -offset indent
564    xo_emit("All strings are utf-8 content {:tag/%ls}",
565            L"except for wide strings");
566 .Ed
567 .Pp
568 "%S" is equivalent to "%ls".
569 .Pp
570 For example, a function is passed a locale-base name, a hat size,
571 and a time value.
572 The hat size is formatted in a UTF-8 (ASCII)
573 string, and the time value is formatted into a wchar_t string.
574 .Bd -literal -offset indent
575     void print_order (const char *name, int size,
576                       struct tm *timep) {
577         char buf[32];
578         const char *size_val = "unknown";
579
580         if (size > 0)
581             snprintf(buf, sizeof(buf), "%d", size);
582             size_val = buf;
583         }
584
585         wchar_t when[32];
586         wcsftime(when, sizeof(when), L"%d%b%y", timep);
587
588         xo_emit("The hat for {:name/%hs} is {:size/%s}.\\n",
589                 name, size_val);
590         xo_emit("It was ordered on {:order-time/%ls}.\\n",
591                 when);
592     }
593 .Ed
594 .Pp
595 It is important to note that
596 .Xr xo_emit 3
597 will perform the conversion
598 required to make appropriate output.
599 Text style output uses the
600 current locale (as described above), while XML, JSON, and HTML use
601 UTF-8.
602 .Pp
603 UTF-8 and locale-encoded strings can use multiple bytes to encode one
604 column of data.
605 The traditional "precision'" (aka "max-width") value
606 for "%s" printf formatting becomes overloaded since it specifies both
607 the number of bytes that can be safely referenced and the maximum
608 number of columns to emit.
609 .Xr xo_emit 3
610 uses the precision as the former,
611 and adds a third value for specifying the maximum number of columns.
612 .Pp
613 In this example, the name field is printed with a minimum of 3 columns
614 and a maximum of 6.
615 Up to ten bytes are in used in filling those columns. 
616 .Bd -literal -offset indent
617     xo_emit("{:name/%3.10.6s}", name);
618 .Ed
619 .Ss Characters Outside of Field Definitions
620 Characters in the format string that are not part of a field definition are
621 copied to the output for the TEXT style, and are ignored for the JSON
622 and XML styles.
623 For HTML, these characters are placed in a <div> with class "text".
624 .Bd -literal -offset indent
625   EXAMPLE:
626       xo_emit("The hat is {:size/%s}.\\n", size_val);
627   TEXT:
628       The hat is extra small.
629   XML:
630       <size>extra small</size>
631   JSON:
632       "size": "extra small"
633   HTML:
634       <div class="text">The hat is </div>
635       <div class="data" data-tag="size">extra small</div>
636       <div class="text">.</div>
637 .Ed
638 .Ss "%n" is Not Supported
639 .Nm libxo
640 does not support the '%n' directive.
641 It is a bad idea and we
642 just do not do it.
643 .Ss The Encoding Format (eformat)
644 The "eformat" string is the format string used when encoding the field
645 for JSON and XML.
646 If not provided, it defaults to the primary format
647 with any minimum width removed.
648 If the primary is not given, both default to "%s".
649 .Sh EXAMPLE
650 In this example, the value for the number of items in stock is emitted:
651 .Bd -literal -offset indent
652         xo_emit("{P:   }{Lwc:In stock}{:in-stock/%u}\\n",
653                 instock);
654 .Ed
655 .Pp
656 This call will generate the following output:
657 .Bd -literal -offset indent
658   TEXT: 
659        In stock: 144
660   XML:
661       <in-stock>144</in-stock>
662   JSON:
663       "in-stock": 144,
664   HTML:
665       <div class="line">
666         <div class="padding">   </div>
667         <div class="label">In stock</div>
668         <div class="decoration">:</div>
669         <div class="padding"> </div>
670         <div class="data" data-tag="in-stock">144</div>
671       </div>
672 .Ed
673 .Pp
674 Clearly HTML wins the verbosity award, and this output does
675 not include
676 .Dv XOF_XPATH
677 or
678 .Dv XOF_INFO
679 data, which would expand the penultimate line to:
680 .Bd -literal -offset indent
681        <div class="data" data-tag="in-stock"
682           data-xpath="/top/data/item/in-stock"
683           data-type="number"
684           data-help="Number of items in stock">144</div>
685 .Ed
686 .Sh WHAT MAKES A GOOD FIELD NAME?
687 To make useful, consistent field names, follow these guidelines:
688 .Pp
689 .Ss Use lower case, even for TLAs
690 Lower case is more civilized.
691 Even TLAs should be lower case
692 to avoid scenarios where the differences between "XPath" and
693 "Xpath" drive your users crazy.
694 Using "xpath" is simpler and better.
695 .Ss Use hyphens, not underscores
696 Use of hyphens is traditional in XML, and the
697 .Dv XOF_UNDERSCORES
698 flag can be used to generate underscores in JSON, if desired.
699 But the raw field name should use hyphens.
700 .Ss Use full words
701 Do not abbreviate especially when the abbreviation is not obvious or
702 not widely used.
703 Use "data-size", not "dsz" or "dsize".
704 Use
705 "interface" instead of "ifname", "if-name", "iface", "if", or "intf".
706 .Ss Use <verb>-<units>
707 Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in
708 making consistent, useful names, avoiding the situation where one app
709 uses "sent-packet" and another "packets-sent" and another
710 "packets-we-have-sent".
711 The <units> can be dropped when it is
712 obvious, as can obvious words in the classification.
713 Use "receive-after-window-packets" instead of
714 "received-packets-of-data-after-window".
715 .Ss Reuse existing field names
716 Nothing is worse than writing expressions like:
717 .Bd -literal -offset indent
718     if ($src1/process[pid == $pid]/name == 
719         $src2/proc-table/proc/p[process-id == $pid]/proc-name) {
720         ...
721     }
722 .Ed
723 .Pp
724 Find someone else who is expressing similar data and follow their
725 fields and hierarchy.
726 Remember the quote is not
727 .Dq Consistency is the hobgoblin of little minds
728 but
729 .Dq A foolish consistency is the hobgoblin of little minds .
730 .Ss Think about your users
731 Have empathy for your users, choosing clear and useful fields that
732 contain clear and useful data.
733 You may need to augment the display content with
734 .Xr xo_attr 3
735 calls or "{e:}" fields to make the data useful.
736 .Ss Do not use an arbitrary number postfix
737 What does "errors2" mean?
738 No one will know.
739 "errors-after-restart" would be a better choice.
740 Think of your users, and think of the future.
741 If you make "errors2", the next guy will happily make
742 "errors3" and before you know it, someone will be asking what is the
743 difference between errors37 and errors63.
744 .Ss Be consistent, uniform, unsurprising, and predictable
745 Think of your field vocabulary as an API.
746 You want it useful,
747 expressive, meaningful, direct, and obvious.
748 You want the client
749 application's programmer to move between without the need to
750 understand a variety of opinions on how fields are named.
751 They should
752 see the system as a single cohesive whole, not a sack of cats.
753 .Pp
754 Field names constitute the means by which client programmers interact
755 with our system.
756 By choosing wise names now, you are making their lives better.
757 .Pp
758 After using
759 .Xr xolint 1
760 to find errors in your field descriptors, use
761 .Dq "xolint -V"
762 to spell check your field names and to detect different
763 names for the same data.
764 .Dq dropped-short
765 and
766 .Dq dropped-too-short
767 are both reasonable names, but using them both will lead users to ask the
768 difference between the two fields.
769 If there is no difference,
770 use only one of the field names.
771 If there is a difference, change the
772 names to make that difference more obvious.
773 .Sh ADDITIONAL DOCUMENTATION
774 Complete documentation can be found on github:
775 .Bd -literal -offset indent
776 http://juniper.github.io/libxo/libxo-manual.html
777 .Ed
778 .Pp
779 .Nm libxo
780 lives on github as:
781 .Bd -literal -offset indent
782 https://github.com/Juniper/libxo
783 .Ed
784 .Pp
785 The latest release of
786 .Nm libxo
787 is available at:
788 .Bd -literal -offset indent
789 https://github.com/Juniper/libxo/releases
790 .Ed
791 .Sh SEE ALSO
792 .Xr xolint 1 ,
793 .Xr xo_emit 3
794 .Sh HISTORY
795 The
796 .Nm libxo
797 library was added in
798 .Fx 11.0 .
799 .Sh AUTHOR
800 Phil Shafer