xref: /freebsd/contrib/libxo/doc/xo.rst (revision 76afb20c58adb296f09857aed214b91464242264)
1983afe33SPhil Shafer.. index:: --libxo, xo
2*76afb20cSPhil Shafer.. _xo:
3983afe33SPhil Shafer
4983afe33SPhil ShaferThe "xo" Utility
5983afe33SPhil Shafer================
6983afe33SPhil Shafer
7983afe33SPhil ShaferThe `xo` utility allows command line access to the functionality of
8983afe33SPhil Shaferthe libxo library.  Using `xo`, shell scripts can emit XML, JSON, and
9983afe33SPhil ShaferHTML using the same commands that emit text output.
10983afe33SPhil Shafer
11983afe33SPhil ShaferThe style of output can be selected using a specific option: "-X" for
12983afe33SPhil ShaferXML, "-J" for JSON, "-H" for HTML, or "-T" for TEXT, which is the
13983afe33SPhil Shaferdefault.  The "--style <style>" option can also be used.  The standard
14983afe33SPhil Shaferset of "--libxo" options are available (see :ref:`options`), as well
15*76afb20cSPhil Shaferas the :ref:`LIBXO_OPTIONS <libxo-options>` environment variable.
16983afe33SPhil Shafer
17983afe33SPhil ShaferThe `xo` utility accepts a format string suitable for `xo_emit` and
18983afe33SPhil Shafera set of zero or more arguments used to supply data for that string::
19983afe33SPhil Shafer
20983afe33SPhil Shafer    xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6
21983afe33SPhil Shafer
22983afe33SPhil Shafer  TEXT:
23983afe33SPhil Shafer    The fish weighs 6 pounds.
24*76afb20cSPhil Shafer
25983afe33SPhil Shafer  XML:
26983afe33SPhil Shafer    <name>fish</name>
27983afe33SPhil Shafer    <weight>6</weight>
28*76afb20cSPhil Shafer
29983afe33SPhil Shafer  JSON:
30983afe33SPhil Shafer    "name": "fish",
31983afe33SPhil Shafer    "weight": 6
32*76afb20cSPhil Shafer
33983afe33SPhil Shafer  HTML:
34983afe33SPhil Shafer    <div class="line">
35983afe33SPhil Shafer      <div class="text">The </div>
36983afe33SPhil Shafer      <div class="data" data-tag="name">fish</div>
37983afe33SPhil Shafer      <div class="text"> weighs </div>
38983afe33SPhil Shafer      <div class="data" data-tag="weight">6</div>
39983afe33SPhil Shafer      <div class="text"> pounds.</div>
40983afe33SPhil Shafer    </div>
41983afe33SPhil Shafer
42983afe33SPhil ShaferThe `--wrap $path` option can be used to wrap emitted content in a
43983afe33SPhil Shaferspecific hierarchy.  The path is a set of hierarchical names separated
44983afe33SPhil Shaferby the '/' character::
45983afe33SPhil Shafer
46983afe33SPhil Shafer    xo --wrap top/a/b/c '{:tag}' value
47983afe33SPhil Shafer
48983afe33SPhil Shafer  XML:
49983afe33SPhil Shafer    <top>
50983afe33SPhil Shafer      <a>
51983afe33SPhil Shafer        <b>
52983afe33SPhil Shafer          <c>
53983afe33SPhil Shafer            <tag>value</tag>
54983afe33SPhil Shafer          </c>
55983afe33SPhil Shafer        </b>
56983afe33SPhil Shafer      </a>
57983afe33SPhil Shafer    </top>
58*76afb20cSPhil Shafer
59983afe33SPhil Shafer  JSON:
60983afe33SPhil Shafer    "top": {
61983afe33SPhil Shafer      "a": {
62983afe33SPhil Shafer        "b": {
63983afe33SPhil Shafer          "c": {
64983afe33SPhil Shafer            "tag": "value"
65983afe33SPhil Shafer          }
66983afe33SPhil Shafer        }
67983afe33SPhil Shafer      }
68983afe33SPhil Shafer    }
69983afe33SPhil Shafer
70983afe33SPhil ShaferThe `--open $path` and `--close $path` can be used to emit
71983afe33SPhil Shaferhierarchical information without the matching close and open
72983afe33SPhil Shafertag.  This allows a shell script to emit open tags, data, and
73983afe33SPhil Shaferthen close tags.  The `--depth` option may be used to set the
74983afe33SPhil Shaferdepth for indentation.  The `--leading-xpath` may be used to
75983afe33SPhil Shaferprepend data to the XPath values used for HTML output style::
76983afe33SPhil Shafer
77*76afb20cSPhil Shafer  EXAMPLE:
78983afe33SPhil Shafer    #!/bin/sh
79983afe33SPhil Shafer    xo --open top/data
80406a584dSPhil Shafer    xo --depth 2 '{:tag}' value
81983afe33SPhil Shafer    xo --close top/data
82*76afb20cSPhil Shafer
83983afe33SPhil Shafer  XML:
84983afe33SPhil Shafer    <top>
85983afe33SPhil Shafer      <data>
86983afe33SPhil Shafer        <tag>value</tag>
87983afe33SPhil Shafer      </data>
88983afe33SPhil Shafer    </top>
89*76afb20cSPhil Shafer
90983afe33SPhil Shafer  JSON:
91983afe33SPhil Shafer    "top": {
92983afe33SPhil Shafer      "data": {
93983afe33SPhil Shafer        "tag": "value"
94983afe33SPhil Shafer      }
95983afe33SPhil Shafer    }
96983afe33SPhil Shafer
97406a584dSPhil ShaferWhen making partial lines of output (where the format string does not
98406a584dSPhil Shaferinclude a newline), use the `--continuation` option to let secondary
99406a584dSPhil Shaferinvocations know they are adding data to an existing line.
100406a584dSPhil Shafer
101406a584dSPhil ShaferWhen emitting a series of objects, use the `--not-first` option to
102406a584dSPhil Shaferensure that any details from the previous object (e.g. commas in JSON)
103406a584dSPhil Shaferare handled correctly.
104406a584dSPhil Shafer
105406a584dSPhil ShaferUse the `--top-wrap` option to ensure any top-level object details are
106406a584dSPhil Shaferhandled correctly, e.g. wrap the entire output in a top-level set of
107406a584dSPhil Shaferbraces for JSON output.
108406a584dSPhil Shafer
109*76afb20cSPhil Shafer::
110*76afb20cSPhil Shafer
111*76afb20cSPhil Shafer  EXAMPLE:
112406a584dSPhil Shafer    #!/bin/sh
113406a584dSPhil Shafer    xo --top-wrap --open top/data
114406a584dSPhil Shafer    xo --depth 2 'First {:tag} ' value1
115406a584dSPhil Shafer    xo --depth 2 --continuation 'and then {:tag}\n' value2
116406a584dSPhil Shafer    xo --top-wrap --close top/data
117*76afb20cSPhil Shafer
118406a584dSPhil Shafer  TEXT:
119406a584dSPhil Shafer    First value1 and then value2
120*76afb20cSPhil Shafer
121406a584dSPhil Shafer  HTML:
122406a584dSPhil Shafer    <div class="line">
123406a584dSPhil Shafer      <div class="text">First </div>
124406a584dSPhil Shafer      <div class="data" data-tag="tag">value1</div>
125406a584dSPhil Shafer      <div class="text"> </div>
126406a584dSPhil Shafer      <div class="text">and then </div>
127406a584dSPhil Shafer      <div class="data" data-tag="tag">value2</div>
128406a584dSPhil Shafer    </div>
129*76afb20cSPhil Shafer
130406a584dSPhil Shafer  XML:
131406a584dSPhil Shafer    <top>
132406a584dSPhil Shafer      <data>
133406a584dSPhil Shafer        <tag>value1</tag>
134406a584dSPhil Shafer        <tag>value2</tag>
135406a584dSPhil Shafer      </data>
136406a584dSPhil Shafer    </top>
137*76afb20cSPhil Shafer
138406a584dSPhil Shafer  JSON:
139406a584dSPhil Shafer    {
140406a584dSPhil Shafer      "top": {
141406a584dSPhil Shafer        "data": {
142406a584dSPhil Shafer        "tag": "value1",
143406a584dSPhil Shafer        "tag": "value2"
144406a584dSPhil Shafer        }
145406a584dSPhil Shafer      }
146406a584dSPhil Shafer    }
147406a584dSPhil Shafer
148406a584dSPhil ShaferLists and Instances
149406a584dSPhil Shafer-------------------
150406a584dSPhil Shafer
151406a584dSPhil ShaferA "*list*" is set of one or more instances that appear under the same
152406a584dSPhil Shaferparent.  The instances contain details about a specific object.  One
153406a584dSPhil Shafercan think of instances as objects or records.  A call is needed to
154406a584dSPhil Shaferopen and close the list, while a distinct call is needed to open and
155406a584dSPhil Shaferclose each instance of the list.
156406a584dSPhil Shafer
157406a584dSPhil ShaferUse the `--open-list` and `--open-instances` to open lists and
158406a584dSPhil Shaferinstances.  Use the `--close-list` and `--close-instances` to close
159406a584dSPhil Shaferthem.  Each of these options take a `name` parameter, providing the
160406a584dSPhil Shafername of the list and instance.
161406a584dSPhil Shafer
162406a584dSPhil ShaferIn the following example, a list named "machine" is created with three
163*76afb20cSPhil Shaferinstances::
164406a584dSPhil Shafer
165406a584dSPhil Shafer    opts="--json"
166406a584dSPhil Shafer    xo $opts --open-list machine
167406a584dSPhil Shafer    NF=
168406a584dSPhil Shafer    for name in red green blue; do
169406a584dSPhil Shafer        xo $opts --depth 1 $NF --open-instance machine
170406a584dSPhil Shafer        xo $opts --depth 2 "Machine {k:name} has {:memory}\n" $name 55
171406a584dSPhil Shafer        xo $opts --depth 1 --close-instance machine
172406a584dSPhil Shafer        NF=--not-first
173406a584dSPhil Shafer    done
174406a584dSPhil Shafer    xo $opts $NF --close-list machine
175406a584dSPhil Shafer
176406a584dSPhil ShaferThe normal `libxo` functions use a state machine to help these
177406a584dSPhil Shafertransitions, but since each `xo` command is invoked independent of the
178406a584dSPhil Shaferprevious calls, the state must be passed in explicitly via these
179406a584dSPhil Shafercommand line options.
180406a584dSPhil Shafer
181*76afb20cSPhil ShaferThe `--instance` option can be used to treat a single `xo` invocation
182*76afb20cSPhil Shaferas an instance with the given set of fields::
183*76afb20cSPhil Shafer
184*76afb20cSPhil Shafer  % xo --libxo:XP --instance foo 'The {:product} is {:status}\n' stereo "in route"
185*76afb20cSPhil Shafer  <foo>
186*76afb20cSPhil Shafer    <product>stereo</product>
187*76afb20cSPhil Shafer    <status>in route</status>
188*76afb20cSPhil Shafer  </foo>
189*76afb20cSPhil Shafer
190983afe33SPhil ShaferCommand Line Options
191983afe33SPhil Shafer--------------------
192983afe33SPhil Shafer
193983afe33SPhil Shafer::
194983afe33SPhil Shafer
195983afe33SPhil Shafer  Usage: xo [options] format [fields]
196983afe33SPhil Shafer    --close <path>        Close tags for the given path
197406a584dSPhil Shafer    --close-instance <name> Close an open instance name
198406a584dSPhil Shafer    --close-list <name>   Close an open list name
199406a584dSPhil Shafer    --continuation OR -C  Output belongs on same line as previous output
200983afe33SPhil Shafer    --depth <num>         Set the depth for pretty printing
201983afe33SPhil Shafer    --help                Display this help text
202983afe33SPhil Shafer    --html OR -H          Generate HTML output
203*76afb20cSPhil Shafer    --instance OR -I <name> Wrap in an instance of the given name
204983afe33SPhil Shafer    --json OR -J          Generate JSON output
205983afe33SPhil Shafer    --leading-xpath <path> Add a prefix to generated XPaths (HTML)
206406a584dSPhil Shafer    --not-first           Indicate this object is not the first (JSON)
207983afe33SPhil Shafer    --open <path>         Open tags for the given path
208406a584dSPhil Shafer    --open-instance <name> Open an instance given by name
209406a584dSPhil Shafer    --open-list <name>   Open a list given by name
210406a584dSPhil Shafer    --option <opts> -or -O <opts>  Give formatting options
211983afe33SPhil Shafer    --pretty OR -p        Make 'pretty' output (add indent, newlines)
212983afe33SPhil Shafer    --style <style>       Generate given style (xml, json, text, html)
213983afe33SPhil Shafer    --text OR -T          Generate text output (the default style)
214406a584dSPhil Shafer    --top-wrap            Generate a top-level object wrapper (JSON)
215983afe33SPhil Shafer    --version             Display version information
216983afe33SPhil Shafer    --warn OR -W          Display warnings in text on stderr
217983afe33SPhil Shafer    --warn-xml            Display warnings in xml on stdout
218983afe33SPhil Shafer    --wrap <path>         Wrap output in a set of containers
219983afe33SPhil Shafer    --xml OR -X           Generate XML output
220*76afb20cSPhil Shafer    --xpath               Add XPath data to HTML output)
221983afe33SPhil Shafer
222983afe33SPhil ShaferExample
223983afe33SPhil Shafer-------
224983afe33SPhil Shafer
225983afe33SPhil Shafer::
226983afe33SPhil Shafer
227983afe33SPhil Shafer  % xo 'The {:product} is {:status}\n' stereo "in route"
228983afe33SPhil Shafer  The stereo is in route
229*76afb20cSPhil Shafer  % xo -p -X 'The {:product} is {:status}\n' stereo "in route"
230*76afb20cSPhil Shafer  <product>stereo</product>
231*76afb20cSPhil Shafer  <status>in route</status>
232*76afb20cSPhil Shafer  % xo --libxo xml,pretty 'The {:product} is {:status}\n' stereo "in route"
233983afe33SPhil Shafer  <product>stereo</product>
234983afe33SPhil Shafer  <status>in route</status>
235