xref: /freebsd/contrib/libxo/doc/formatting.rst (revision 983afe3373c427a080f06dccec820b20891be186)
1*983afe33SPhil Shafer
2*983afe33SPhil ShaferFormatting with libxo
3*983afe33SPhil Shafer=====================
4*983afe33SPhil Shafer
5*983afe33SPhil ShaferMost unix commands emit text output aimed at humans.  It is designed
6*983afe33SPhil Shaferto be parsed and understood by a user.  Humans are gifted at
7*983afe33SPhil Shaferextracting details and pattern matching in such output.  Often
8*983afe33SPhil Shaferprogrammers need to extract information from this human-oriented
9*983afe33SPhil Shaferoutput.  Programmers use tools like grep, awk, and regular expressions
10*983afe33SPhil Shaferto ferret out the pieces of information they need.  Such solutions are
11*983afe33SPhil Shaferfragile and require maintenance when output contents change or evolve,
12*983afe33SPhil Shaferalong with testing and validation.
13*983afe33SPhil Shafer
14*983afe33SPhil ShaferModern tool developers favor encoding schemes like XML and JSON,
15*983afe33SPhil Shaferwhich allow trivial parsing and extraction of data.  Such formats are
16*983afe33SPhil Shafersimple, well understood, hierarchical, easily parsed, and often
17*983afe33SPhil Shaferintegrate easier with common tools and environments.  Changes to
18*983afe33SPhil Shafercontent can be done in ways that do not break existing users of the
19*983afe33SPhil Shaferdata, which can reduce maintenance costs and increase feature velocity.
20*983afe33SPhil Shafer
21*983afe33SPhil ShaferIn addition, modern reality means that more output ends up in web
22*983afe33SPhil Shaferbrowsers than in terminals, making HTML output valuable.
23*983afe33SPhil Shafer
24*983afe33SPhil Shaferlibxo allows a single set of function calls in source code to generate
25*983afe33SPhil Shafertraditional text output, as well as XML and JSON formatted data.  HTML
26*983afe33SPhil Shafercan also be generated; "<div>" elements surround the traditional text
27*983afe33SPhil Shaferoutput, with attributes that detail how to render the data.
28*983afe33SPhil Shafer
29*983afe33SPhil ShaferA single libxo function call in source code is all that's required::
30*983afe33SPhil Shafer
31*983afe33SPhil Shafer    xo_emit("Connecting to {:host}.{:domain}...\n", host, domain);
32*983afe33SPhil Shafer
33*983afe33SPhil Shafer    TEXT:
34*983afe33SPhil Shafer      Connecting to my-box.example.com...
35*983afe33SPhil Shafer    XML:
36*983afe33SPhil Shafer      <host>my-box</host>
37*983afe33SPhil Shafer      <domain>example.com</domain>
38*983afe33SPhil Shafer    JSON:
39*983afe33SPhil Shafer      "host": "my-box",
40*983afe33SPhil Shafer      "domain": "example.com"
41*983afe33SPhil Shafer    HTML:
42*983afe33SPhil Shafer       <div class="line">
43*983afe33SPhil Shafer         <div class="text">Connecting to </div>
44*983afe33SPhil Shafer         <div class="data" data-tag="host"
45*983afe33SPhil Shafer              data-xpath="/top/host">my-box</div>
46*983afe33SPhil Shafer         <div class="text">.</div>
47*983afe33SPhil Shafer         <div class="data" data-tag="domain"
48*983afe33SPhil Shafer              data-xpath="/top/domain">example.com</div>
49*983afe33SPhil Shafer         <div class="text">...</div>
50*983afe33SPhil Shafer       </div>
51*983afe33SPhil Shafer
52*983afe33SPhil ShaferEncoding Styles
53*983afe33SPhil Shafer---------------
54*983afe33SPhil Shafer
55*983afe33SPhil ShaferThere are four encoding styles supported by libxo:
56*983afe33SPhil Shafer
57*983afe33SPhil Shafer- TEXT output can be display on a terminal session, allowing
58*983afe33SPhil Shafer  compatibility with traditional command line usage.
59*983afe33SPhil Shafer- XML output is suitable for tools like XPath and protocols like
60*983afe33SPhil Shafer  NETCONF.
61*983afe33SPhil Shafer- JSON output can be used for RESTful APIs and integration with
62*983afe33SPhil Shafer  languages like Javascript and Python.
63*983afe33SPhil Shafer- HTML can be matched with a small CSS file to permit rendering in any
64*983afe33SPhil Shafer  HTML5 browser.
65*983afe33SPhil Shafer
66*983afe33SPhil ShaferIn general, XML and JSON are suitable for encoding data, while TEXT is
67*983afe33SPhil Shafersuited for terminal output and HTML is suited for display in a web
68*983afe33SPhil Shaferbrowser (see :ref:`xohtml`).
69*983afe33SPhil Shafer
70*983afe33SPhil ShaferText Output
71*983afe33SPhil Shafer~~~~~~~~~~~
72*983afe33SPhil Shafer
73*983afe33SPhil ShaferMost traditional programs generate text output on standard output,
74*983afe33SPhil Shaferwith contents like::
75*983afe33SPhil Shafer
76*983afe33SPhil Shafer    36      ./src
77*983afe33SPhil Shafer    40      ./bin
78*983afe33SPhil Shafer    90      .
79*983afe33SPhil Shafer
80*983afe33SPhil ShaferIn this example (taken from *du* source code), the code to generate this
81*983afe33SPhil Shaferdata might look like::
82*983afe33SPhil Shafer
83*983afe33SPhil Shafer    printf("%d\t%s\n", num_blocks, path);
84*983afe33SPhil Shafer
85*983afe33SPhil ShaferSimple, direct, obvious.  But it's only making text output.  Imagine
86*983afe33SPhil Shaferusing a single code path to make TEXT, XML, JSON or HTML, deciding at
87*983afe33SPhil Shaferrun time which to generate.
88*983afe33SPhil Shafer
89*983afe33SPhil Shaferlibxo expands on the idea of printf format strings to make a single
90*983afe33SPhil Shaferformat containing instructions for creating multiple output styles::
91*983afe33SPhil Shafer
92*983afe33SPhil Shafer    xo_emit("{:blocks/%d}\t{:path/%s}\n", num_blocks, path);
93*983afe33SPhil Shafer
94*983afe33SPhil ShaferThis line will generate the same text output as the earlier printf
95*983afe33SPhil Shafercall, but also has enough information to generate XML, JSON, and HTML.
96*983afe33SPhil Shafer
97*983afe33SPhil ShaferThe following sections introduce the other formats.
98*983afe33SPhil Shafer
99*983afe33SPhil ShaferXML Output
100*983afe33SPhil Shafer~~~~~~~~~~
101*983afe33SPhil Shafer
102*983afe33SPhil ShaferXML output consists of a hierarchical set of elements, each encoded
103*983afe33SPhil Shaferwith a start tag and an end tag.  The element should be named for data
104*983afe33SPhil Shafervalue that it is encoding::
105*983afe33SPhil Shafer
106*983afe33SPhil Shafer    <item>
107*983afe33SPhil Shafer      <blocks>36</blocks>
108*983afe33SPhil Shafer      <path>./src</path>
109*983afe33SPhil Shafer    </item>
110*983afe33SPhil Shafer    <item>
111*983afe33SPhil Shafer      <blocks>40</blocks>
112*983afe33SPhil Shafer      <path>./bin</path>
113*983afe33SPhil Shafer    </item>
114*983afe33SPhil Shafer    <item>
115*983afe33SPhil Shafer      <blocks>90</blocks>
116*983afe33SPhil Shafer      <path>.</path>
117*983afe33SPhil Shafer    </item>
118*983afe33SPhil Shafer
119*983afe33SPhil Shafer`XML`_ is the W3C standard for encoding data.
120*983afe33SPhil Shafer
121*983afe33SPhil Shafer.. _XML: https://w3c.org/TR/xml
122*983afe33SPhil Shafer
123*983afe33SPhil ShaferJSON Output
124*983afe33SPhil Shafer~~~~~~~~~~~
125*983afe33SPhil Shafer
126*983afe33SPhil ShaferJSON output consists of a hierarchical set of objects and lists, each
127*983afe33SPhil Shaferencoded with a quoted name, a colon, and a value.  If the value is a
128*983afe33SPhil Shaferstring, it must be quoted, but numbers are not quoted.  Objects are
129*983afe33SPhil Shaferencoded using braces; lists are encoded using square brackets.
130*983afe33SPhil ShaferData inside objects and lists is separated using commas::
131*983afe33SPhil Shafer
132*983afe33SPhil Shafer    items: [
133*983afe33SPhil Shafer        { "blocks": 36, "path" : "./src" },
134*983afe33SPhil Shafer        { "blocks": 40, "path" : "./bin" },
135*983afe33SPhil Shafer        { "blocks": 90, "path" : "./" }
136*983afe33SPhil Shafer    ]
137*983afe33SPhil Shafer
138*983afe33SPhil ShaferHTML Output
139*983afe33SPhil Shafer~~~~~~~~~~~
140*983afe33SPhil Shafer
141*983afe33SPhil ShaferHTML output is designed to allow the output to be rendered in a web
142*983afe33SPhil Shaferbrowser with minimal effort.  Each piece of output data is rendered
143*983afe33SPhil Shaferinside a <div> element, with a class name related to the role of the
144*983afe33SPhil Shaferdata.  By using a small set of class attribute values, a CSS
145*983afe33SPhil Shaferstylesheet can render the HTML into rich text that mirrors the
146*983afe33SPhil Shafertraditional text content.
147*983afe33SPhil Shafer
148*983afe33SPhil ShaferAdditional attributes can be enabled to provide more details about the
149*983afe33SPhil Shaferdata, including data type, description, and an XPath location::
150*983afe33SPhil Shafer
151*983afe33SPhil Shafer    <div class="line">
152*983afe33SPhil Shafer      <div class="data" data-tag="blocks">36</div>
153*983afe33SPhil Shafer      <div class="padding">      </div>
154*983afe33SPhil Shafer      <div class="data" data-tag="path">./src</div>
155*983afe33SPhil Shafer    </div>
156*983afe33SPhil Shafer    <div class="line">
157*983afe33SPhil Shafer      <div class="data" data-tag="blocks">40</div>
158*983afe33SPhil Shafer      <div class="padding">      </div>
159*983afe33SPhil Shafer      <div class="data" data-tag="path">./bin</div>
160*983afe33SPhil Shafer    </div>
161*983afe33SPhil Shafer    <div class="line">
162*983afe33SPhil Shafer      <div class="data" data-tag="blocks">90</div>
163*983afe33SPhil Shafer      <div class="padding">      </div>
164*983afe33SPhil Shafer      <div class="data" data-tag="path">./</div>
165*983afe33SPhil Shafer    </div>
166