xref: /freebsd/contrib/libxo/doc/field-modifiers.rst (revision 76afb20c58adb296f09857aed214b91464242264)
1*983afe33SPhil Shafer
2*983afe33SPhil Shafer.. index:: Field Modifiers
3*983afe33SPhil Shafer.. _field-modifiers:
4*983afe33SPhil Shafer
5*983afe33SPhil ShaferField Modifiers
6*983afe33SPhil Shafer~~~~~~~~~~~~~~~
7*983afe33SPhil Shafer
8*983afe33SPhil ShaferField modifiers are flags which modify the way content emitted for
9*983afe33SPhil Shaferparticular output styles:
10*983afe33SPhil Shafer
11*983afe33SPhil Shafer  === =============== ===================================================
12*983afe33SPhil Shafer   M   Name            Description
13*983afe33SPhil Shafer  === =============== ===================================================
14*983afe33SPhil Shafer   a   argument        The content appears as a 'const char \*' argument
15*983afe33SPhil Shafer   c   colon           A colon (":") is appended after the label
16*983afe33SPhil Shafer   d   display         Only emit field for display styles (text/HTML)
17*983afe33SPhil Shafer   e   encoding        Only emit for encoding styles (XML/JSON)
18*983afe33SPhil Shafer   g   gettext         Call gettext on field's render content
19*983afe33SPhil Shafer   h   humanize (hn)   Format large numbers in human-readable style
20*983afe33SPhil Shafer  \    hn-space        Humanize: Place space between numeric and unit
21*983afe33SPhil Shafer  \    hn-decimal      Humanize: Add a decimal digit, if number < 10
22*983afe33SPhil Shafer  \    hn-1000         Humanize: Use 1000 as divisor instead of 1024
23*983afe33SPhil Shafer   k   key             Field is a key, suitable for XPath predicates
24*983afe33SPhil Shafer   l   leaf-list       Field is a leaf-list
25*983afe33SPhil Shafer   n   no-quotes       Do not quote the field when using JSON style
26*983afe33SPhil Shafer   p   plural          Gettext: Use comma-separated plural form
27*983afe33SPhil Shafer   q   quotes          Quote the field when using JSON style
28*983afe33SPhil Shafer   t   trim            Trim leading and trailing whitespace
29*983afe33SPhil Shafer   w   white           A blank (" ") is appended after the label
30*983afe33SPhil Shafer  === =============== ===================================================
31*983afe33SPhil Shafer
32*983afe33SPhil ShaferRoles and modifiers can also use more verbose names, when preceded by
33*983afe33SPhil Shafera comma.  For example, the modifier string "Lwc" (or "L,white,colon")
34*983afe33SPhil Shafermeans the field has a label role (text that describes the next field)
35*983afe33SPhil Shaferand should be followed by a colon ('c') and a space ('w').  The
36*983afe33SPhil Shafermodifier string "Vkq" (or ":key,quote") means the field has a value
37*983afe33SPhil Shaferrole (the default role), that it is a key for the current instance,
38*983afe33SPhil Shaferand that the value should be quoted when encoded for JSON.
39*983afe33SPhil Shafer
40*983afe33SPhil Shafer.. index:: Field Modifiers; Argument
41*983afe33SPhil Shafer.. _argument-modifier:
42*983afe33SPhil Shafer
43*983afe33SPhil ShaferThe Argument Modifier ({a:})
44*983afe33SPhil Shafer++++++++++++++++++++++++++++
45*983afe33SPhil Shafer
46*983afe33SPhil Shafer.. index:: Field Modifiers; Argument
47*983afe33SPhil Shafer
48*983afe33SPhil ShaferThe argument modifier indicates that the content of the field
49*983afe33SPhil Shaferdescriptor will be placed as a UTF-8 string (const char \*) argument
50*983afe33SPhil Shaferwithin the xo_emit parameters::
51*983afe33SPhil Shafer
52*983afe33SPhil Shafer    EXAMPLE:
53*983afe33SPhil Shafer        xo_emit("{La:} {a:}\n", "Label text", "label", "value");
54*983afe33SPhil Shafer    TEXT:
55*983afe33SPhil Shafer        Label text value
56*983afe33SPhil Shafer    JSON:
57*983afe33SPhil Shafer        "label": "value"
58*983afe33SPhil Shafer    XML:
59*983afe33SPhil Shafer        <label>value</label>
60*983afe33SPhil Shafer
61*983afe33SPhil ShaferThe argument modifier allows field names for value fields to be passed
62*983afe33SPhil Shaferon the stack, avoiding the need to build a field descriptor using
63*983afe33SPhil Shafersnprintf.  For many field roles, the argument modifier is not needed,
64*983afe33SPhil Shafersince those roles have specific mechanisms for arguments, such as
65*983afe33SPhil Shafer"{C:fg-%s}".
66*983afe33SPhil Shafer
67*983afe33SPhil Shafer.. index:: Field Modifiers; Colon
68*983afe33SPhil Shafer.. _colon-modifier:
69*983afe33SPhil Shafer
70*983afe33SPhil ShaferThe Colon Modifier ({c:})
71*983afe33SPhil Shafer+++++++++++++++++++++++++
72*983afe33SPhil Shafer
73*983afe33SPhil Shafer.. index:: Field Modifiers; Colon
74*983afe33SPhil Shafer
75*983afe33SPhil ShaferThe colon modifier appends a single colon to the data value::
76*983afe33SPhil Shafer
77*983afe33SPhil Shafer    EXAMPLE:
78*983afe33SPhil Shafer        xo_emit("{Lc:Name}{:name}\n", "phil");
79*983afe33SPhil Shafer    TEXT:
80*983afe33SPhil Shafer        Name:phil
81*983afe33SPhil Shafer
82*983afe33SPhil ShaferThe colon modifier is only used for the TEXT and HTML output
83*983afe33SPhil Shaferstyles. It is commonly combined with the space modifier ('{w:}').
84*983afe33SPhil ShaferIt is purely a convenience feature.
85*983afe33SPhil Shafer
86*983afe33SPhil Shafer.. index:: Field Modifiers; Display
87*983afe33SPhil Shafer.. _display-modifier:
88*983afe33SPhil Shafer
89*983afe33SPhil ShaferThe Display Modifier ({d:})
90*983afe33SPhil Shafer+++++++++++++++++++++++++++
91*983afe33SPhil Shafer
92*983afe33SPhil Shafer.. index:: Field Modifiers; Display
93*983afe33SPhil Shafer
94*983afe33SPhil ShaferThe display modifier indicated the field should only be generated for
95*983afe33SPhil Shaferthe display output styles, TEXT and HTML::
96*983afe33SPhil Shafer
97*983afe33SPhil Shafer    EXAMPLE:
98*983afe33SPhil Shafer        xo_emit("{Lcw:Name}{d:name} {:id/%d}\n", "phil", 1);
99*983afe33SPhil Shafer    TEXT:
100*983afe33SPhil Shafer        Name: phil 1
101*983afe33SPhil Shafer    XML:
102*983afe33SPhil Shafer        <id>1</id>
103*983afe33SPhil Shafer
104*983afe33SPhil ShaferThe display modifier is the opposite of the encoding modifier, and
105*983afe33SPhil Shaferthey are often used to give to distinct views of the underlying data.
106*983afe33SPhil Shafer
107*983afe33SPhil Shafer.. index:: Field Modifiers; Encoding
108*983afe33SPhil Shafer.. _encoding-modifier:
109*983afe33SPhil Shafer
110*983afe33SPhil ShaferThe Encoding Modifier ({e:})
111*983afe33SPhil Shafer++++++++++++++++++++++++++++
112*983afe33SPhil Shafer
113*983afe33SPhil Shafer.. index:: Field Modifiers; Encoding
114*983afe33SPhil Shafer
115*983afe33SPhil ShaferThe display modifier indicated the field should only be generated for
116*983afe33SPhil Shaferthe display output styles, TEXT and HTML::
117*983afe33SPhil Shafer
118*983afe33SPhil Shafer    EXAMPLE:
119*983afe33SPhil Shafer        xo_emit("{Lcw:Name}{:name} {e:id/%d}\n", "phil", 1);
120*983afe33SPhil Shafer    TEXT:
121*983afe33SPhil Shafer        Name: phil
122*983afe33SPhil Shafer    XML:
123*983afe33SPhil Shafer        <name>phil</name><id>1</id>
124*983afe33SPhil Shafer
125*983afe33SPhil ShaferThe encoding modifier is the opposite of the display modifier, and
126*983afe33SPhil Shaferthey are often used to give to distinct views of the underlying data.
127*983afe33SPhil Shafer
128*983afe33SPhil Shafer.. index:: Field Modifiers; Gettext
129*983afe33SPhil Shafer.. _gettext-modifier:
130*983afe33SPhil Shafer
131*983afe33SPhil ShaferThe Gettext Modifier ({g:})
132*983afe33SPhil Shafer+++++++++++++++++++++++++++
133*983afe33SPhil Shafer
134*983afe33SPhil Shafer.. index:: Field Modifiers; Gettext
135*983afe33SPhil Shafer.. index:: gettext
136*983afe33SPhil Shafer
137*983afe33SPhil ShaferThe gettext modifier is used to translate individual fields using the
138*983afe33SPhil Shafergettext domain (typically set using the "`{G:}`" role) and current
139*983afe33SPhil Shaferlanguage settings.  Once libxo renders the field value, it is passed
140*983afe33SPhil Shaferto gettext(3), where it is used as a key to find the native language
141*983afe33SPhil Shafertranslation.
142*983afe33SPhil Shafer
143*983afe33SPhil ShaferIn the following example, the strings "State" and "full" are passed
144*983afe33SPhil Shaferto gettext() to find locale-based translated strings::
145*983afe33SPhil Shafer
146*983afe33SPhil Shafer    xo_emit("{Lgwc:State}{g:state}\n", "full");
147*983afe33SPhil Shafer
148*983afe33SPhil ShaferSee :ref:`gettext-role`, :ref:`plural-modifier`, and
149*983afe33SPhil Shafer:ref:`i18n` for additional details.
150*983afe33SPhil Shafer
151*983afe33SPhil Shafer.. index:: Field Modifiers; Humanize
152*983afe33SPhil Shafer.. _humanize-modifier:
153*983afe33SPhil Shafer
154*983afe33SPhil ShaferThe Humanize Modifier ({h:})
155*983afe33SPhil Shafer++++++++++++++++++++++++++++
156*983afe33SPhil Shafer
157*983afe33SPhil Shafer.. index:: Field Modifiers; Humanize
158*983afe33SPhil Shafer
159*983afe33SPhil ShaferThe humanize modifier is used to render large numbers as in a
160*983afe33SPhil Shaferhuman-readable format.  While numbers like "44470272" are completely
161*983afe33SPhil Shaferreadable to computers and savants, humans will generally find "44M"
162*983afe33SPhil Shafermore meaningful.
163*983afe33SPhil Shafer
164*983afe33SPhil Shafer"hn" can be used as an alias for "humanize".
165*983afe33SPhil Shafer
166*983afe33SPhil ShaferThe humanize modifier only affects display styles (TEXT and HMTL).
167*983afe33SPhil ShaferThe "`no-humanize`" option (See :ref:`options`) will block
168*983afe33SPhil Shaferthe function of the humanize modifier.
169*983afe33SPhil Shafer
170*983afe33SPhil ShaferThere are a number of modifiers that affect details of humanization.
171*983afe33SPhil ShaferThese are only available in as full names, not single characters.  The
172*983afe33SPhil Shafer"`hn-space`" modifier places a space between the number and any
173*983afe33SPhil Shafermultiplier symbol, such as "M" or "K" (ex: "44 K").  The
174*983afe33SPhil Shafer"`hn-decimal`" modifier will add a decimal point and a single tenths
175*983afe33SPhil Shaferdigit when the number is less than 10 (ex: "4.4K").  The "`hn-1000`"
176*983afe33SPhil Shafermodifier will use 1000 as divisor instead of 1024, following the
177*983afe33SPhil ShaferJEDEC-standard instead of the more natural binary powers-of-two
178*983afe33SPhil Shafertradition::
179*983afe33SPhil Shafer
180*983afe33SPhil Shafer    EXAMPLE:
181*983afe33SPhil Shafer        xo_emit("{h:input/%u}, {h,hn-space:output/%u}, "
182*983afe33SPhil Shafer	    "{h,hn-decimal:errors/%u}, {h,hn-1000:capacity/%u}, "
183*983afe33SPhil Shafer	    "{h,hn-decimal:remaining/%u}\n",
184*983afe33SPhil Shafer            input, output, errors, capacity, remaining);
185*983afe33SPhil Shafer    TEXT:
186*983afe33SPhil Shafer        21, 57 K, 96M, 44M, 1.2G
187*983afe33SPhil Shafer
188*983afe33SPhil ShaferIn the HTML style, the original numeric value is rendered in the
189*983afe33SPhil Shafer"data-number" attribute on the <div> element::
190*983afe33SPhil Shafer
191*983afe33SPhil Shafer    <div class="data" data-tag="errors"
192*983afe33SPhil Shafer         data-number="100663296">96M</div>
193*983afe33SPhil Shafer
194*983afe33SPhil Shafer.. index:: Field Modifiers; Key
195*983afe33SPhil Shafer.. _key-modifier:
196*983afe33SPhil Shafer
197*983afe33SPhil ShaferThe Key Modifier ({k:})
198*983afe33SPhil Shafer+++++++++++++++++++++++
199*983afe33SPhil Shafer
200*983afe33SPhil Shafer.. index:: Field Modifiers; Key
201*983afe33SPhil Shafer
202*983afe33SPhil ShaferThe key modifier is used to indicate that a particular field helps
203*983afe33SPhil Shaferuniquely identify an instance of list data::
204*983afe33SPhil Shafer
205*983afe33SPhil Shafer    EXAMPLE:
206*983afe33SPhil Shafer        xo_open_list("user");
207*983afe33SPhil Shafer        for (i = 0; i < num_users; i++) {
208*983afe33SPhil Shafer	    xo_open_instance("user");
209*983afe33SPhil Shafer            xo_emit("User {k:name} has {:count} tickets\n",
210*983afe33SPhil Shafer               user[i].u_name, user[i].u_tickets);
211*983afe33SPhil Shafer            xo_close_instance("user");
212*983afe33SPhil Shafer        }
213*983afe33SPhil Shafer        xo_close_list("user");
214*983afe33SPhil Shafer
215*983afe33SPhil Shafer.. index:: XOF_XPATH
216*983afe33SPhil Shafer
217*983afe33SPhil ShaferCurrently the key modifier is only used when generating XPath value
218*983afe33SPhil Shaferfor the HTML output style when XOF_XPATH is set, but other uses are
219*983afe33SPhil Shaferlikely in the near future.
220*983afe33SPhil Shafer
221*983afe33SPhil Shafer.. index:: Field Modifiers; Leaf-List
222*983afe33SPhil Shafer.. _leaf-list:
223*983afe33SPhil Shafer
224*983afe33SPhil ShaferThe Leaf-List Modifier ({l:})
225*983afe33SPhil Shafer+++++++++++++++++++++++++++++
226*983afe33SPhil Shafer
227*983afe33SPhil Shafer.. index:: Field Modifiers; Leaf-List
228*983afe33SPhil Shafer
229*983afe33SPhil ShaferThe leaf-list modifier is used to distinguish lists where each
230*983afe33SPhil Shaferinstance consists of only a single value.  In XML, these are
231*983afe33SPhil Shaferrendered as single elements, where JSON renders them as arrays::
232*983afe33SPhil Shafer
233*983afe33SPhil Shafer    EXAMPLE:
234*983afe33SPhil Shafer        for (i = 0; i < num_users; i++) {
235*983afe33SPhil Shafer            xo_emit("Member {l:user}\n", user[i].u_name);
236*983afe33SPhil Shafer        }
237*983afe33SPhil Shafer    XML:
238*983afe33SPhil Shafer        <user>phil</user>
239*983afe33SPhil Shafer        <user>pallavi</user>
240*983afe33SPhil Shafer    JSON:
241*983afe33SPhil Shafer        "user": [ "phil", "pallavi" ]
242*983afe33SPhil Shafer
243*983afe33SPhil ShaferThe name of the field must match the name of the leaf list.
244*983afe33SPhil Shafer
245*983afe33SPhil Shafer.. index:: Field Modifiers; No-Quotes
246*983afe33SPhil Shafer.. _no-quotes-modifier:
247*983afe33SPhil Shafer
248*983afe33SPhil ShaferThe No-Quotes Modifier ({n:})
249*983afe33SPhil Shafer+++++++++++++++++++++++++++++
250*983afe33SPhil Shafer
251*983afe33SPhil Shafer.. index:: Field Modifiers; No-Quotes
252*983afe33SPhil Shafer
253*983afe33SPhil ShaferThe no-quotes modifier (and its twin, the 'quotes' modifier) affect
254*983afe33SPhil Shaferthe quoting of values in the JSON output style.  JSON uses quotes for
255*983afe33SPhil Shaferstring value, but no quotes for numeric, boolean, and null data.
256*983afe33SPhil Shaferxo_emit applies a simple heuristic to determine whether quotes are
257*983afe33SPhil Shaferneeded, but often this needs to be controlled by the caller::
258*983afe33SPhil Shafer
259*983afe33SPhil Shafer    EXAMPLE:
260*983afe33SPhil Shafer        const char *bool = is_true ? "true" : "false";
261*983afe33SPhil Shafer        xo_emit("{n:fancy/%s}", bool);
262*983afe33SPhil Shafer    JSON:
263*983afe33SPhil Shafer        "fancy": true
264*983afe33SPhil Shafer
265*983afe33SPhil Shafer.. index:: Field Modifiers; Plural
266*983afe33SPhil Shafer.. _plural-modifier:
267*983afe33SPhil Shafer
268*983afe33SPhil ShaferThe Plural Modifier ({p:})
269*983afe33SPhil Shafer++++++++++++++++++++++++++
270*983afe33SPhil Shafer
271*983afe33SPhil Shafer.. index:: Field Modifiers; Plural
272*983afe33SPhil Shafer.. index:: gettext
273*983afe33SPhil Shafer
274*983afe33SPhil ShaferThe plural modifier selects the appropriate plural form of an
275*983afe33SPhil Shaferexpression based on the most recent number emitted and the current
276*983afe33SPhil Shaferlanguage settings.  The contents of the field should be the singular
277*983afe33SPhil Shaferand plural English values, separated by a comma::
278*983afe33SPhil Shafer
279*983afe33SPhil Shafer    xo_emit("{:bytes} {Ngp:byte,bytes}\n", bytes);
280*983afe33SPhil Shafer
281*983afe33SPhil ShaferThe plural modifier is meant to work with the gettext modifier ({g:})
282*983afe33SPhil Shaferbut can work independently.  See :ref:`gettext-modifier`.
283*983afe33SPhil Shafer
284*983afe33SPhil ShaferWhen used without the gettext modifier or when the message does not
285*983afe33SPhil Shaferappear in the message catalog, the first token is chosen when the last
286*983afe33SPhil Shafernumeric value is equal to 1; otherwise the second value is used,
287*983afe33SPhil Shafermimicking the simple pluralization rules of English.
288*983afe33SPhil Shafer
289*983afe33SPhil ShaferWhen used with the gettext modifier, the ngettext(3) function is
290*983afe33SPhil Shafercalled to handle the heavy lifting, using the message catalog to
291*983afe33SPhil Shaferconvert the singular and plural forms into the native language.
292*983afe33SPhil Shafer
293*983afe33SPhil Shafer.. index:: Field Modifiers; Quotes
294*983afe33SPhil Shafer.. _quotes-modifier:
295*983afe33SPhil Shafer
296*983afe33SPhil ShaferThe Quotes Modifier ({q:})
297*983afe33SPhil Shafer++++++++++++++++++++++++++
298*983afe33SPhil Shafer
299*983afe33SPhil Shafer.. index:: Field Modifiers; Quotes
300*983afe33SPhil Shafer
301*983afe33SPhil ShaferThe quotes modifier (and its twin, the 'no-quotes' modifier) affect
302*983afe33SPhil Shaferthe quoting of values in the JSON output style.  JSON uses quotes for
303*983afe33SPhil Shaferstring value, but no quotes for numeric, boolean, and null data.
304*983afe33SPhil Shaferxo_emit applies a simple heuristic to determine whether quotes are
305*983afe33SPhil Shaferneeded, but often this needs to be controlled by the caller::
306*983afe33SPhil Shafer
307*983afe33SPhil Shafer    EXAMPLE:
308*983afe33SPhil Shafer        xo_emit("{q:time/%d}", 2014);
309*983afe33SPhil Shafer    JSON:
310*983afe33SPhil Shafer        "year": "2014"
311*983afe33SPhil Shafer
312*983afe33SPhil ShaferThe heuristic is based on the format; if the format uses any of the
313*983afe33SPhil Shaferfollowing conversion specifiers, then no quotes are used::
314*983afe33SPhil Shafer
315*983afe33SPhil Shafer    d i o u x X D O U e E f F g G a A c C p
316*983afe33SPhil Shafer
317*983afe33SPhil Shafer.. index:: Field Modifiers; Trim
318*983afe33SPhil Shafer.. _trim-modifier:
319*983afe33SPhil Shafer
320*983afe33SPhil ShaferThe Trim Modifier ({t:})
321*983afe33SPhil Shafer++++++++++++++++++++++++
322*983afe33SPhil Shafer
323*983afe33SPhil Shafer.. index:: Field Modifiers; Trim
324*983afe33SPhil Shafer
325*983afe33SPhil ShaferThe trim modifier removes any leading or trailing whitespace from
326*983afe33SPhil Shaferthe value::
327*983afe33SPhil Shafer
328*983afe33SPhil Shafer    EXAMPLE:
329*983afe33SPhil Shafer        xo_emit("{t:description}", "   some  input   ");
330*983afe33SPhil Shafer    JSON:
331*983afe33SPhil Shafer        "description": "some input"
332*983afe33SPhil Shafer
333*983afe33SPhil Shafer.. index:: Field Modifiers; White Space
334*983afe33SPhil Shafer.. _white-space-modifier:
335*983afe33SPhil Shafer
336*983afe33SPhil ShaferThe White Space Modifier ({w:})
337*983afe33SPhil Shafer+++++++++++++++++++++++++++++++
338*983afe33SPhil Shafer
339*983afe33SPhil Shafer.. index:: Field Modifiers; White Space
340*983afe33SPhil Shafer
341*983afe33SPhil ShaferThe white space modifier appends a single space to the data value::
342*983afe33SPhil Shafer
343*983afe33SPhil Shafer    EXAMPLE:
344*983afe33SPhil Shafer        xo_emit("{Lw:Name}{:name}\n", "phil");
345*983afe33SPhil Shafer    TEXT:
346*983afe33SPhil Shafer        Name phil
347*983afe33SPhil Shafer
348*983afe33SPhil ShaferThe white space modifier is only used for the TEXT and HTML output
349*983afe33SPhil Shaferstyles. It is commonly combined with the colon modifier ('{c:}').
350*983afe33SPhil ShaferIt is purely a convenience feature.
351*983afe33SPhil Shafer
352*983afe33SPhil ShaferNote that the sense of the 'w' modifier is reversed for the units role
353*983afe33SPhil Shafer({Uw:}); a blank is added before the contents, rather than after it.
354