Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2017 06:29:21 +0000 (UTC)
From:      Phil Shafer <phil@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r319999 - in head: contrib/libxo/doc contrib/libxo/libxo contrib/libxo/tests/core contrib/libxo/tests/core/saved contrib/libxo/xohtml usr.bin/xohtml usr.bin/xolint usr.bin/xopo
Message-ID:  <201706160629.v5G6TLQb001048@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: phil
Date: Fri Jun 16 06:29:21 2017
New Revision: 319999
URL: https://svnweb.freebsd.org/changeset/base/319999

Log:
  Merge libxo-0.8.2:
  - xohtml: Add "-w" option to pull support files from gh_pages
  - Add "upload-xohtml-files" target to publish support files in gh_pages/
  - add HISTORY/AUTHORS section to man pages
  - xohtml: Add div.units as standard CSS text
  - Don't treat values as format strings; they are not
  - add "-p" to "mkdir -p build" in setup.sh
  - add test case for {U:%%} (from df.c)
  - detect end-of-string in '%' and '' escaping
  - make xo_simple_field, for common simple cases
  - xohtml: nuke "n" in "echo" commands
  - rename "format" to "fmt" for consistency; same for "str" to "value"
  - update test cases
  
  Submitted by:	phil

Added:
  head/usr.bin/xohtml/
  head/usr.bin/xohtml/Makefile   (contents, props changed)
  head/usr.bin/xohtml/xohtml.sh   (contents, props changed)
  head/usr.bin/xolint/
  head/usr.bin/xolint/Makefile   (contents, props changed)
  head/usr.bin/xopo/
  head/usr.bin/xopo/Makefile   (contents, props changed)
Modified:
  head/contrib/libxo/doc/libxo-manual.html
  head/contrib/libxo/libxo/libxo.c
  head/contrib/libxo/tests/core/saved/test_01.E.out
  head/contrib/libxo/tests/core/saved/test_01.H.out
  head/contrib/libxo/tests/core/saved/test_01.HIPx.out
  head/contrib/libxo/tests/core/saved/test_01.HP.out
  head/contrib/libxo/tests/core/saved/test_01.J.out
  head/contrib/libxo/tests/core/saved/test_01.JP.out
  head/contrib/libxo/tests/core/saved/test_01.T.out
  head/contrib/libxo/tests/core/saved/test_01.X.out
  head/contrib/libxo/tests/core/saved/test_01.XP.out
  head/contrib/libxo/tests/core/saved/test_02.J.out
  head/contrib/libxo/tests/core/saved/test_02.JP.out
  head/contrib/libxo/tests/core/test_01.c
  head/contrib/libxo/xohtml/xohtml.css
  head/contrib/libxo/xohtml/xohtml.sh.in
Directory Properties:
  head/contrib/libxo/   (props changed)

Modified: head/contrib/libxo/doc/libxo-manual.html
==============================================================================
--- head/contrib/libxo/doc/libxo-manual.html	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/doc/libxo-manual.html	Fri Jun 16 06:29:21 2017	(r319999)
@@ -22011,7 +22011,7 @@ jQuery(function ($) {
 </tr>
 <tr>
 <td class="header left"></td>
-<td class="header right">June 8, 2017</td>
+<td class="header right">June 14, 2017</td>
 </tr>
 </table></div>
 <p id="title" class="title">libxo: The Easy Way to Generate text, XML, JSON, and HTML output<br><span class="filename">libxo-manual</span></p>

Modified: head/contrib/libxo/libxo/libxo.c
==============================================================================
--- head/contrib/libxo/libxo/libxo.c	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/libxo/libxo.c	Fri Jun 16 06:29:21 2017	(r319999)
@@ -95,6 +95,14 @@
 #include <libintl.h>
 #endif /* HAVE_GETTEXT */
 
+/* Rather lame that we can't count on these... */
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
 /*
  * Three styles of specifying thread-local variables are supported.
  * configure.ac has the brains to run each possibility through the
@@ -473,6 +481,7 @@ static void
 xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
 		   const char *name, ssize_t nlen,
 		   const char *value, ssize_t vlen,
+		   const char *fmt, ssize_t flen,
 		   const char *encoding, ssize_t elen);
 
 static void
@@ -1761,7 +1770,8 @@ xo_message_hcv (xo_handle_t *xop, int code, const char
 		    rc += rc2;
 	    }
 
-	    xo_buf_append_div(xop, "message", 0, NULL, 0, bp, rc, NULL, 0);
+	    xo_buf_append_div(xop, "message", 0, NULL, 0, bp, rc,
+			      NULL, 0, NULL, 0);
 	}
 	break;
 
@@ -2703,6 +2713,8 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t
 	    if ((flags & XFF_UNESCAPE) && (*cp == '\\' || *cp == '%')) {
 		cp += 1;
 		len -= 1;
+		if (len == 0 || *cp == '\0')
+		    break;
 	    }
 	}
 
@@ -3644,6 +3656,10 @@ xo_do_format_field (xo_handle_t *xop, xo_buffer_t *xbp
     return 0;
 }
 
+/*
+ * Remove any numeric precision/width format from the format string by
+ * inserting the "%" after the [0-9]+, returning the substring.
+ */
 static char *
 xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding)
 {
@@ -3657,8 +3673,7 @@ xo_fix_encoding (xo_handle_t *xop UNUSED, char *encodi
 	    break;
     }
 
-    cp -= 1;
-    *cp = '%';
+    *--cp = '%';		/* Back off and insert the '%' */
 
     return cp;
 }
@@ -3777,10 +3792,35 @@ xo_format_humanize (xo_handle_t *xop, xo_buffer_t *xbp
     }
 }
 
+/*
+ * Convenience function that either append a fixed value (if one is
+ * given) or formats a field using a format string.  If it's
+ * encode_only, then we can't skip formatting the field, since it may
+ * be pulling arguments off the stack.
+ */
+static inline void
+xo_simple_field (xo_handle_t *xop, unsigned encode_only,
+		      const char *value, ssize_t vlen,
+		      const char *fmt, ssize_t flen, xo_xff_flags_t flags)
+{
+    if (encode_only)
+	flags |= XFF_NO_OUTPUT;
+
+    if (vlen == 0)
+	xo_do_format_field(xop, NULL, fmt, flen, flags);
+    else if (!encode_only)
+	xo_data_append_content(xop, value, vlen, flags);
+}
+
+/*
+ * Html mode: append a <div> to the output buffer contain a field
+ * along with all the supporting information indicated by the flags.
+ */
 static void
 xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
 		   const char *name, ssize_t nlen,
 		   const char *value, ssize_t vlen,
+		   const char *fmt, ssize_t flen,
 		   const char *encoding, ssize_t elen)
 {
     static char div_start[] = "<div class=\"";
@@ -3791,10 +3831,10 @@ xo_buf_append_div (xo_handle_t *xop, const char *class
     static char div_close[] = "</div>";
 
     /* The encoding format defaults to the normal format */
-    if (encoding == NULL) {
-	char *enc  = alloca(vlen + 1);
-	memcpy(enc, value, vlen);
-	enc[vlen] = '\0';
+    if (encoding == NULL && fmt != NULL) {
+	char *enc  = alloca(flen + 1);
+	memcpy(enc, fmt, flen);
+	enc[flen] = '\0';
 	encoding = xo_fix_encoding(xop, enc);
 	elen = strlen(encoding);
     }
@@ -3861,10 +3901,10 @@ xo_buf_append_div (xo_handle_t *xop, const char *class
 	/*
 	 * Even if this is encode-only, we need to go through the
 	 * work of formatting it to make sure the args are cleared
-	 * from xo_vap.
+	 * from xo_vap.  This is not true when vlen is zero, since
+	 * that means our "value" isn't on the stack.
 	 */
-	xo_do_format_field(xop, NULL, encoding, elen,
-		       flags | XFF_NO_OUTPUT);
+	xo_simple_field(xop, TRUE, NULL, 0, encoding, elen, flags);
 	return;
     }
 
@@ -3972,7 +4012,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class
     save.xhs_columns = xop->xo_columns;
     save.xhs_anchor_columns = xop->xo_anchor_columns;
 
-    xo_do_format_field(xop, NULL, value, vlen, flags);
+    xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
 
     if (flags & XFF_HUMANIZE) {
 	/*
@@ -4023,14 +4063,14 @@ xo_format_text (xo_handle_t *xop, const char *str, ssi
 	break;
 
     case XO_STYLE_HTML:
-	xo_buf_append_div(xop, "text", 0, NULL, 0, str, len, NULL, 0);
+	xo_buf_append_div(xop, "text", 0, NULL, 0, str, len, NULL, 0, NULL, 0);
 	break;
     }
 }
 
 static void
 xo_format_title (xo_handle_t *xop, xo_field_info_t *xfip,
-		 const char *str, ssize_t len)
+		 const char *value, ssize_t vlen)
 {
     const char *fmt = xfip->xfi_format;
     ssize_t flen = xfip->xfi_flen;
@@ -4054,8 +4094,7 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xf
 	 * Even though we don't care about text, we need to do
 	 * enough parsing work to skip over the right bits of xo_vap.
 	 */
-	if (len == 0)
-	    xo_do_format_field(xop, NULL, fmt, flen, flags | XFF_NO_OUTPUT);
+	xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	return;
     }
 
@@ -4074,17 +4113,17 @@ xo_format_title (xo_handle_t *xop, xo_field_info_t *xf
     }
 
     start = xbp->xb_curp - xbp->xb_bufp; /* Reset start */
-    if (len) {
+    if (vlen) {
 	char *newfmt = alloca(flen + 1);
 	memcpy(newfmt, fmt, flen);
 	newfmt[flen] = '\0';
 
 	/* If len is non-zero, the format string apply to the name */
-	char *newstr = alloca(len + 1);
-	memcpy(newstr, str, len);
-	newstr[len] = '\0';
+	char *newstr = alloca(vlen + 1);
+	memcpy(newstr, value, vlen);
+	newstr[vlen] = '\0';
 
-	if (newstr[len - 1] == 's') {
+	if (newstr[vlen - 1] == 's') {
 	    char *bp;
 
 	    rc = snprintf(NULL, 0, newfmt, newstr);
@@ -4166,8 +4205,9 @@ xo_arg (xo_handle_t *xop)
 
 static void
 xo_format_value (xo_handle_t *xop, const char *name, ssize_t nlen,
-                const char *format, ssize_t flen,
-                const char *encoding, ssize_t elen, xo_xff_flags_t flags)
+		 const char *value, ssize_t vlen,
+		 const char *fmt, ssize_t flen,
+		 const char *encoding, ssize_t elen, xo_xff_flags_t flags)
 {
     int pretty = XOF_ISSET(xop, XOF_PRETTY);
     int quote;
@@ -4253,7 +4293,7 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	save.xhs_columns = xop->xo_columns;
 	save.xhs_anchor_columns = xop->xo_anchor_columns;
 
-	xo_do_format_field(xop, NULL, format, flen, flags);
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
 
 	if (flags & XFF_HUMANIZE)
 	    xo_format_humanize(xop, xbp, &save, flags);
@@ -4263,8 +4303,8 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	if (flags & XFF_ENCODE_ONLY)
 	    flags |= XFF_NO_OUTPUT;
 
-	xo_buf_append_div(xop, "data", flags, name, nlen,
-			  format, flen, encoding, elen);
+	xo_buf_append_div(xop, "data", flags, name, nlen, value, vlen,
+			  fmt, flen, encoding, elen);
 	break;
 
     case XO_STYLE_XML:
@@ -4273,25 +4313,24 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	 * let the formatting code handle the va_arg popping.
 	 */
 	if (flags & XFF_DISPLAY_ONLY) {
-	    flags |= XFF_NO_OUTPUT;
-	    xo_do_format_field(xop, NULL, format, flen, flags);
+	    xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	    break;
 	}
 
 	if (encoding) {
-   	    format = encoding;
+   	    fmt = encoding;
 	    flen = elen;
 	} else {
 	    char *enc  = alloca(flen + 1);
-	    memcpy(enc, format, flen);
+	    memcpy(enc, fmt, flen);
 	    enc[flen] = '\0';
-	    format = xo_fix_encoding(xop, enc);
-	    flen = strlen(format);
+	    fmt = xo_fix_encoding(xop, enc);
+	    flen = strlen(fmt);
 	}
 
 	if (nlen == 0) {
 	    static char missing[] = "missing-field-name";
-	    xo_failure(xop, "missing field name: %s", format);
+	    xo_failure(xop, "missing field name: %s", fmt);
 	    name = missing;
 	    nlen = sizeof(missing) - 1;
 	}
@@ -4327,7 +4366,9 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	}
 
 	xo_data_append(xop, ">", 1);
-	xo_do_format_field(xop, NULL, format, flen, flags);
+
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
 	xo_data_append(xop, "</", 2);
 	xo_data_escape(xop, name, nlen);
 	xo_data_append(xop, ">", 1);
@@ -4337,20 +4378,19 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 
     case XO_STYLE_JSON:
 	if (flags & XFF_DISPLAY_ONLY) {
-	    flags |= XFF_NO_OUTPUT;
-	    xo_do_format_field(xop, NULL, format, flen, flags);
+	    xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	    break;
 	}
 
 	if (encoding) {
-	    format = encoding;
+	    fmt = encoding;
 	    flen = elen;
 	} else {
 	    char *enc  = alloca(flen + 1);
-	    memcpy(enc, format, flen);
+	    memcpy(enc, fmt, flen);
 	    enc[flen] = '\0';
-	    format = xo_fix_encoding(xop, enc);
-	    flen = strlen(format);
+	    fmt = xo_fix_encoding(xop, enc);
+	    flen = strlen(fmt);
 	}
 
 	int first = (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
@@ -4362,18 +4402,20 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	    quote = 1;
 	else if (flags & XFF_NOQUOTE)
 	    quote = 0;
+	else if (vlen != 0)
+	    quote = 1;
 	else if (flen == 0) {
 	    quote = 0;
-	    format = "true";	/* JSON encodes empty tags as a boolean true */
+	    fmt = "true";	/* JSON encodes empty tags as a boolean true */
 	    flen = 4;
-	} else if (strchr("diouDOUeEfFgG", format[flen - 1]) == NULL)
+	} else if (strchr("diouDOUeEfFgG", fmt[flen - 1]) == NULL)
 	    quote = 1;
 	else
 	    quote = 0;
 
 	if (nlen == 0) {
 	    static char missing[] = "missing-field-name";
-	    xo_failure(xop, "missing field name: %s", format);
+	    xo_failure(xop, "missing field name: %s", fmt);
 	    name = missing;
 	    nlen = sizeof(missing) - 1;
 	}
@@ -4407,7 +4449,7 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	if (quote)
 	    xo_data_append(xop, "\"", 1);
 
-	xo_do_format_field(xop, NULL, format, flen, flags);
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
 
 	if (quote)
 	    xo_data_append(xop, "\"", 1);
@@ -4415,39 +4457,39 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 
     case XO_STYLE_SDPARAMS:
 	if (flags & XFF_DISPLAY_ONLY) {
-	    flags |= XFF_NO_OUTPUT;
-	    xo_do_format_field(xop, NULL, format, flen, flags);
+	    xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	    break;
 	}
 
 	if (encoding) {
-	    format = encoding;
+	    fmt = encoding;
 	    flen = elen;
 	} else {
 	    char *enc  = alloca(flen + 1);
-	    memcpy(enc, format, flen);
+	    memcpy(enc, fmt, flen);
 	    enc[flen] = '\0';
-	    format = xo_fix_encoding(xop, enc);
-	    flen = strlen(format);
+	    fmt = xo_fix_encoding(xop, enc);
+	    flen = strlen(fmt);
 	}
 
 	if (nlen == 0) {
 	    static char missing[] = "missing-field-name";
-	    xo_failure(xop, "missing field name: %s", format);
+	    xo_failure(xop, "missing field name: %s", fmt);
 	    name = missing;
 	    nlen = sizeof(missing) - 1;
 	}
 
 	xo_data_escape(xop, name, nlen);
 	xo_data_append(xop, "=\"", 2);
-	xo_do_format_field(xop, NULL, format, flen, flags);
+
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
 	xo_data_append(xop, "\" ", 2);
 	break;
 
     case XO_STYLE_ENCODER:
 	if (flags & XFF_DISPLAY_ONLY) {
-	    flags |= XFF_NO_OUTPUT;
-	    xo_do_format_field(xop, NULL, format, flen, flags);
+	    xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	    break;
 	}
 
@@ -4457,27 +4499,27 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	    quote = 0;
 	else if (flen == 0) {
 	    quote = 0;
-	    format = "true";	/* JSON encodes empty tags as a boolean true */
+	    fmt = "true";	/* JSON encodes empty tags as a boolean true */
 	    flen = 4;
-	} else if (strchr("diouxXDOUeEfFgGaAcCp", format[flen - 1]) == NULL)
+	} else if (strchr("diouxXDOUeEfFgGaAcCp", fmt[flen - 1]) == NULL)
 	    quote = 1;
 	else
 	    quote = 0;
 
 	if (encoding) {
-	    format = encoding;
+	    fmt = encoding;
 	    flen = elen;
 	} else {
 	    char *enc  = alloca(flen + 1);
-	    memcpy(enc, format, flen);
+	    memcpy(enc, fmt, flen);
 	    enc[flen] = '\0';
-	    format = xo_fix_encoding(xop, enc);
-	    flen = strlen(format);
+	    fmt = xo_fix_encoding(xop, enc);
+	    flen = strlen(fmt);
 	}
 
 	if (nlen == 0) {
 	    static char missing[] = "missing-field-name";
-	    xo_failure(xop, "missing field name: %s", format);
+	    xo_failure(xop, "missing field name: %s", fmt);
 	    name = missing;
 	    nlen = sizeof(missing) - 1;
 	}
@@ -4487,7 +4529,9 @@ xo_format_value (xo_handle_t *xop, const char *name, s
 	xo_data_append(xop, "", 1);
 
 	ssize_t value_offset = xo_buf_offset(&xop->xo_data);
-	xo_do_format_field(xop, NULL, format, flen, flags);
+
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
+
 	xo_data_append(xop, "", 1);
 
 	xo_encoder_handle(xop, quote ? XO_OP_STRING : XO_OP_CONTENT,
@@ -4536,37 +4580,27 @@ xo_set_gettext_domain (xo_handle_t *xop, xo_field_info
 static void
 xo_format_content (xo_handle_t *xop, const char *class_name,
 		   const char *tag_name,
-		   const char *str, ssize_t len, const char *fmt, ssize_t flen,
+		   const char *value, ssize_t vlen,
+		   const char *fmt, ssize_t flen,
 		   xo_xff_flags_t flags)
 {
     switch (xo_style(xop)) {
     case XO_STYLE_TEXT:
-	if (len)
-	    xo_data_append_content(xop, str, len, flags);
-	else
-	    xo_do_format_field(xop, NULL, fmt, flen, flags);
+	xo_simple_field(xop, FALSE, value, vlen, fmt, flen, flags);
 	break;
 
     case XO_STYLE_HTML:
-	if (len == 0) {
-	    str = fmt;
-	    len = flen;
-	}
-
-	xo_buf_append_div(xop, class_name, flags, NULL, 0, str, len, NULL, 0);
+	xo_buf_append_div(xop, class_name, flags, NULL, 0,
+			  value, vlen, fmt, flen, NULL, 0);
 	break;
 
     case XO_STYLE_XML:
     case XO_STYLE_JSON:
     case XO_STYLE_SDPARAMS:
 	if (tag_name) {
-	    if (len == 0) {
-		str = fmt;
-		len = flen;
-	    }
-
 	    xo_open_container_h(xop, tag_name);
-	    xo_format_value(xop, "message", 7, str, len, NULL, 0, flags);
+	    xo_format_value(xop, "message", 7, value, vlen,
+			    fmt, flen, NULL, 0, flags);
 	    xo_close_container_h(xop, tag_name);
 
 	} else {
@@ -4574,16 +4608,12 @@ xo_format_content (xo_handle_t *xop, const char *class
 	     * Even though we don't care about labels, we need to do
 	     * enough parsing work to skip over the right bits of xo_vap.
 	     */
-	    if (len == 0)
-		xo_do_format_field(xop, NULL, fmt, flen,
-				   flags | XFF_NO_OUTPUT);
+	    xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	}
 	break;
 
     case XO_STYLE_ENCODER:
-	if (len == 0)
-	    xo_do_format_field(xop, NULL, fmt, flen,
-			       flags | XFF_NO_OUTPUT);
+	xo_simple_field(xop, TRUE, value, vlen, fmt, flen, flags);
 	break;
     }
 }
@@ -4898,7 +4928,7 @@ xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *
 
 static void
 xo_format_colors (xo_handle_t *xop, xo_field_info_t *xfip,
-		  const char *str, ssize_t len)
+		  const char *value, ssize_t vlen)
 {
     const char *fmt = xfip->xfi_format;
     ssize_t flen = xfip->xfi_flen;
@@ -4906,13 +4936,13 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *x
     xo_buffer_t xb;
 
     /* If the string is static and we've in an encoding style, bail */
-    if (len != 0 && xo_style_is_encoding(xop))
+    if (vlen != 0 && xo_style_is_encoding(xop))
 	return;
 
     xo_buf_init(&xb);
 
-    if (len)
-	xo_buf_append(&xb, str, len);
+    if (vlen)
+	xo_buf_append(&xb, value, vlen);
     else if (flen)
 	xo_do_format_field(xop, &xb, fmt, flen, 0);
     else
@@ -4972,7 +5002,7 @@ xo_format_colors (xo_handle_t *xop, xo_field_info_t *x
 
 static void
 xo_format_units (xo_handle_t *xop, xo_field_info_t *xfip,
-		 const char *str, ssize_t len)
+		 const char *value, ssize_t vlen)
 {
     const char *fmt = xfip->xfi_format;
     ssize_t flen = xfip->xfi_flen;
@@ -4982,7 +5012,7 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xf
     static char units_start_html[] = " data-units=\"";
 
     if (!XOIF_ISSET(xop, XOIF_UNITS_PENDING)) {
-	xo_format_content(xop, "units", NULL, str, len, fmt, flen, flags);
+	xo_format_content(xop, "units", NULL, value, vlen, fmt, flen, flags);
 	return;
     }
 
@@ -4997,8 +5027,8 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xf
     else
 	return;
 
-    if (len)
-	xo_data_escape(xop, str, len);
+    if (vlen)
+	xo_data_escape(xop, value, vlen);
     else
 	xo_do_format_field(xop, NULL, fmt, flen, flags);
 
@@ -5026,7 +5056,7 @@ xo_format_units (xo_handle_t *xop, xo_field_info_t *xf
 
 static ssize_t
 xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip,
-	       const char *str, ssize_t len)
+	       const char *value, ssize_t vlen)
 {
     const char *fmt = xfip->xfi_format;
     ssize_t flen = xfip->xfi_flen;
@@ -5035,10 +5065,10 @@ xo_find_width (xo_handle_t *xop, xo_field_info_t *xfip
     char *bp;
     char *cp;
 
-    if (len) {
-	bp = alloca(len + 1);	/* Make local NUL-terminated copy of str */
-	memcpy(bp, str, len);
-	bp[len] = '\0';
+    if (vlen) {
+	bp = alloca(vlen + 1);	/* Make local NUL-terminated copy of value */
+	memcpy(bp, value, vlen);
+	bp[vlen] = '\0';
 
 	width = strtol(bp, &cp, 0);
 	if (width == LONG_MIN || width == LONG_MAX
@@ -5075,7 +5105,7 @@ xo_anchor_clear (xo_handle_t *xop)
  */
 static void
 xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xfip,
-		 const char *str, ssize_t len)
+		 const char *value, ssize_t vlen)
 {
     if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
 	return;
@@ -5092,12 +5122,12 @@ xo_anchor_start (xo_handle_t *xop, xo_field_info_t *xf
      * Now we find the width, if possible.  If it's not there,
      * we'll get it on the end anchor.
      */
-    xop->xo_anchor_min_width = xo_find_width(xop, xfip, str, len);
+    xop->xo_anchor_min_width = xo_find_width(xop, xfip, value, vlen);
 }
 
 static void
 xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip,
-		 const char *str, ssize_t len)
+		 const char *value, ssize_t vlen)
 {
     if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
 	return;
@@ -5109,7 +5139,7 @@ xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfi
 
     XOIF_CLEAR(xop, XOIF_UNITS_PENDING);
 
-    ssize_t width = xo_find_width(xop, xfip, str, len);
+    ssize_t width = xo_find_width(xop, xfip, value, vlen);
     if (width == 0)
 	width = xop->xo_anchor_min_width;
 
@@ -6213,12 +6243,12 @@ xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *
 	    if (flags & XFF_WS) {
 		xo_format_content(xop, "padding", NULL, " ", 1,
 				  NULL, 0, flags);
-		flags &= ~XFF_WS; /* Block later handling of this */
+		flags &= ~XFF_WS; /* Prevent later handling of this flag */
 	    }
 	}
 
 	if (ftype == 'V')
-	    xo_format_value(xop, content, clen,
+	    xo_format_value(xop, content, clen, NULL, 0,
 			    xfip->xfi_format, xfip->xfi_flen,
 			    xfip->xfi_encoding, xfip->xfi_elen, flags);
 	else if (ftype == '[')
@@ -7899,7 +7929,8 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_lis
     case XO_STYLE_HTML:
 	va_copy(xop->xo_vap, vap);
 	
-	xo_buf_append_div(xop, "error", 0, NULL, 0, fmt, strlen(fmt), NULL, 0);
+	xo_buf_append_div(xop, "error", 0, NULL, 0, NULL, 0,
+			  fmt, strlen(fmt), NULL, 0);
 
 	if (XOIF_ISSET(xop, XOIF_DIV_OPEN))
 	    xo_line_close(xop);
@@ -7915,7 +7946,8 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_lis
 	va_copy(xop->xo_vap, vap);
 
 	xo_open_container_h(xop, "error");
-	xo_format_value(xop, "message", 7, fmt, strlen(fmt), NULL, 0, 0);
+	xo_format_value(xop, "message", 7, NULL, 0,
+			fmt, strlen(fmt), NULL, 0, 0);
 	xo_close_container_h(xop, "error");
 
 	va_end(xop->xo_vap);
@@ -8132,7 +8164,7 @@ xo_emit_warn_hcv (xo_handle_t *xop, int as_warning, in
 
 	xo_buffer_t *src = &temp.xo_data;
 	xo_format_value(xop, "message", 7, src->xb_bufp,
-			src->xb_curp - src->xb_bufp, NULL, 0, 0);
+			src->xb_curp - src->xb_bufp, NULL, 0, NULL, 0, 0);
 
 	xo_free(temp.xo_stack);
 	xo_buf_cleanup(src);

Modified: head/contrib/libxo/tests/core/saved/test_01.E.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.E.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.E.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,5 +1,6 @@
 op create: [] [] [0]
 op open_container: [top] [] [0x810]
+op content: [used-percent] [12] [0]
 op content: [kve_start] [0xdeadbeef] [0x8]
 op content: [kve_end] [0xcabb1e] [0x8]
 op string: [host] [my-box] [0x200000]
@@ -129,6 +130,9 @@ op string: [mode_octal] [octal] [0x8]
 op string: [links] [links] [0x1000]
 op string: [user] [user] [0x1000]
 op string: [group] [group] [0x1000]
+op string: [pre] [that] [0x8]
+op content: [links] [3] [0x1000]
+op string: [post] [this] [0x1000]
 op string: [mode] [/some/file] [0x1000]
 op content: [mode_octal] [640] [0x8]
 op content: [links] [1] [0x1000]

Modified: head/contrib/libxo/tests/core/saved/test_01.H.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.H.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.H.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,2 +1,2 @@
-<div class="line"><div class="text">testing argument modifier </div><div class="data" data-tag="host">my-box</div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="text">testing argument modifier with encoding to </div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="label">Label text</div><div class="text"> </div><div class="data" data-tag="label">value</div></div><div class="line"><div class="data" data-tag="max-chaos">  very  </div><div class="data" data-tag="min-chaos">42</div><div class="data" data-tag="some-chaos">42
-</div><div class="text">Connecting to </div><div class="data" data-tag="host">my-box</div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="title">Item      </div><div class="title">  Total Sold</div><div class="title">    In Stock</div><div class="title">    On Order</div><div class="title">  SKU</div></div><div class="line"><div class="data" data-tag="name" data-key="key">gum       </div><div class="data" data-tag="sold">        1412</div><div class="data" data-tag="in-stock">          54</div><div class="data" data-tag="on-order">          10</div><div class="data" data-tag="sku" data-key="key">  GRO-000-415</div></div><div class="line"><div class="data" data-tag="name" data-key="key">rope      </div><div class="data" data-tag="sold">          85</div><div class="data" data-tag="in-stock">           4</div><div class="data" data-tag="on-order">           2</div><div class="data" data-tag="s
 ku" data-key="key">  HRD-000-212</div></div><div class="line"><div class="data" data-tag="name" data-key="key">ladder    </div><div class="data" data-tag="sold">           0</div><div class="data" data-tag="in-stock">           2</div><div class="data" data-tag="on-order">           1</div><div class="data" data-tag="sku" data-key="key">  HRD-000-517</div></div><div class="line"><div class="data" data-tag="name" data-key="key">bolt      </div><div class="data" data-tag="sold">        4123</div><div class="data" data-tag="in-stock">         144</div><div class="data" data-tag="on-order">          42</div><div class="data" data-tag="sku" data-key="key">  HRD-000-632</div></div><div class="line"><div class="data" data-tag="name" data-key="key">water     </div><div class="data" data-tag="sold">          17</div><div class="data" data-tag="in-stock">          14</div><div class="data" data-tag="on-order">           2</div><div class="data" data-tag="sku" data-key="key">  GRO-000-2331</di
 v></div><div class="line"></div><div class="!
 line"></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">gum</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1412.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">54</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">10</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-415</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="nam
 e" data-key="key">rope</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">85.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">4</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-212</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">ladder</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div clas
 s="label">Total sold</div><div class="text">!
 : </div><!
 div class="data" data-tag="sold">0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">2</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-517</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">bolt</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">4123.0</div></div><div class="line"><div class="padding">   </div><div class="label">In s
 tock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">144</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">42</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-632</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">water</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">17.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">14</div>
 </div><div class="line"><div class="padding"!
 >   </div!
 ><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-2331</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">fish</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1321.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">45</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data
 -tag="on-order">1</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-533</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">gum</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">rope</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">ladder</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">bolt</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">water</div></div><div class="l
 ine"><div class="text">X</div><div class="te!
 xt">X</di!
 v><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div></div><div class="line"><div class="text">X</div><div class="padding">        </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">425</div></div><div class="line"><div class="text">X</div><div class="padding">                              </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">455</div></div><div class="line"><div class="text"> </div><div class="data" data-tag="links">links</div><div class="text"> </div><div class="data" data-tag="user">user</div><div class="text">  </div><div class="data" data-tag="group">group</div><div class="text">  </div></div><div class="line"><div class="data" data-tag="mode">/some/file</div><div cl
 ass="text"> </div><div class="data" data-tag="links">       1</div><div class="text"> </div><div class="data" data-tag="user">user      </div><div class="text">  </div><div class="data" data-tag="group">group       </div><div class="text">  </div></div>
\ No newline at end of file
+<div class="line"><div class="text">df </div><div class="data" data-tag="used-percent">   12</div><div class="units">%</div></div><div class="line"><div class="text">testing argument modifier </div><div class="data" data-tag="host">my-box</div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="text">testing argument modifier with encoding to </div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="label">Label text</div><div class="text"> </div><div class="data" data-tag="label">value</div></div><div class="line"><div class="data" data-tag="max-chaos">  very  </div><div class="data" data-tag="min-chaos">42</div><div class="data" data-tag="some-chaos">42
+</div><div class="text">Connecting to </div><div class="data" data-tag="host">my-box</div><div class="text">.</div><div class="data" data-tag="domain">example.com</div><div class="text">...</div></div><div class="line"><div class="title">Item      </div><div class="title">  Total Sold</div><div class="title">    In Stock</div><div class="title">    On Order</div><div class="title">  SKU</div></div><div class="line"><div class="data" data-tag="name" data-key="key">gum       </div><div class="data" data-tag="sold">        1412</div><div class="data" data-tag="in-stock">          54</div><div class="data" data-tag="on-order">          10</div><div class="data" data-tag="sku" data-key="key">  GRO-000-415</div></div><div class="line"><div class="data" data-tag="name" data-key="key">rope      </div><div class="data" data-tag="sold">          85</div><div class="data" data-tag="in-stock">           4</div><div class="data" data-tag="on-order">           2</div><div class="data" data-tag="s
 ku" data-key="key">  HRD-000-212</div></div><div class="line"><div class="data" data-tag="name" data-key="key">ladder    </div><div class="data" data-tag="sold">           0</div><div class="data" data-tag="in-stock">           2</div><div class="data" data-tag="on-order">           1</div><div class="data" data-tag="sku" data-key="key">  HRD-000-517</div></div><div class="line"><div class="data" data-tag="name" data-key="key">bolt      </div><div class="data" data-tag="sold">        4123</div><div class="data" data-tag="in-stock">         144</div><div class="data" data-tag="on-order">          42</div><div class="data" data-tag="sku" data-key="key">  HRD-000-632</div></div><div class="line"><div class="data" data-tag="name" data-key="key">water     </div><div class="data" data-tag="sold">          17</div><div class="data" data-tag="in-stock">          14</div><div class="data" data-tag="on-order">           2</div><div class="data" data-tag="sku" data-key="key">  GRO-000-2331</di
 v></div><div class="line"></div><div class="!
 line"></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">gum</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1412.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">54</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">10</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-415</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="nam
 e" data-key="key">rope</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">85.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">4</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-212</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">ladder</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div clas
 s="label">Total sold</div><div class="text">!
 : </div><!
 div class="data" data-tag="sold">0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">2</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-517</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">bolt</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">4123.0</div></div><div class="line"><div class="padding">   </div><div class="label">In s
 tock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">144</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">42</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-632</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">water</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">17.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">14</div>
 </div><div class="line"><div class="padding"!
 >   </div!
 ><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-2331</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">fish</div><div class="text">':</div></div><div class="line"><div class="padding">   </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1321.0</div></div><div class="line"><div class="padding">   </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">45</div></div><div class="line"><div class="padding">   </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data
 -tag="on-order">1</div></div><div class="line"><div class="padding">   </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-533</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">gum</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">rope</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">ladder</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">bolt</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">water</div></div><div class="l
 ine"><div class="text">X</div><div class="te!
 xt">X</di!
 v><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div></div><div class="line"><div class="text">X</div><div class="padding">        </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">425</div></div><div class="line"><div class="text">X</div><div class="padding">                              </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">455</div></div><div class="line"><div class="text"> </div><div class="data" data-tag="links">links</div><div class="text"> </div><div class="data" data-tag="user">user</div><div class="text">  </div><div class="data" data-tag="group">group</div><div class="text">  </div></div><div class="line"><div class="data" data-tag="links">3       </div><div cla
 ss="data" data-tag="post">this    </div></div><div class="line"><div class="data" data-tag="mode">/some/file</div><div class="text"> </div><div class="data" data-tag="links">       1</div><div class="text"> </div><div class="data" data-tag="user">user      </div><div class="text">  </div><div class="data" data-tag="group">group       </div><div class="text">  </div></div>
\ No newline at end of file

Modified: head/contrib/libxo/tests/core/saved/test_01.HIPx.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.HIPx.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.HIPx.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,4 +1,9 @@
 <div class="line">
+  <div class="text">df </div>
+  <div class="data" data-tag="used-percent" data-xpath="/top/used-percent">   12</div>
+  <div class="units">%</div>
+</div>
+<div class="line">
   <div class="text">testing argument modifier </div>
   <div class="data" data-tag="host" data-xpath="/top/host">my-box</div>
   <div class="text">.</div>
@@ -331,6 +336,10 @@
   <div class="text">  </div>
   <div class="data" data-tag="group" data-xpath="/top/group">group</div>
   <div class="text">  </div>
+</div>
+<div class="line">
+  <div class="data" data-tag="links" data-xpath="/top/links">3       </div>
+  <div class="data" data-tag="post" data-xpath="/top/post">this    </div>
 </div>
 <div class="line">
   <div class="data" data-tag="mode" data-xpath="/top/mode">/some/file</div>

Modified: head/contrib/libxo/tests/core/saved/test_01.HP.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.HP.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.HP.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,4 +1,9 @@
 <div class="line">
+  <div class="text">df </div>
+  <div class="data" data-tag="used-percent">   12</div>
+  <div class="units">%</div>
+</div>
+<div class="line">
   <div class="text">testing argument modifier </div>
   <div class="data" data-tag="host">my-box</div>
   <div class="text">.</div>
@@ -331,6 +336,10 @@
   <div class="text">  </div>
   <div class="data" data-tag="group">group</div>
   <div class="text">  </div>
+</div>
+<div class="line">
+  <div class="data" data-tag="links">3       </div>
+  <div class="data" data-tag="post">this    </div>
 </div>
 <div class="line">
   <div class="data" data-tag="mode">/some/file</div>

Modified: head/contrib/libxo/tests/core/saved/test_01.J.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.J.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.J.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,2 +1,2 @@
-{"top": {"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"w
 ater","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}
+{"top": {"used-percent":12,"kve_start":"0xdeadbeef","kve_end":"0xcabb1e","host":"my-box","domain":"example.com","host":"my-box","domain":"example.com","label":"value","max-chaos":"very","min-chaos":42,"some-chaos":"[42]","host":"my-box","domain":"example.com", "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data2": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-0
 00-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data3": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data4": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455,"mode":"mode","mode_octal":"octal","links":"links","user":"user","group":"group","pre":"that","links":3,"post":"this","mode":"/some/file","mode_octal":640,"links":1,"user":"user","group":"group"}
 }

Modified: head/contrib/libxo/tests/core/saved/test_01.JP.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.JP.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.JP.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,5 +1,6 @@
 {
   "top": {
+    "used-percent": 12,
     "kve_start": "0xdeadbeef",
     "kve_end": "0xcabb1e",
     "host": "my-box",
@@ -117,6 +118,9 @@
     "links": "links",
     "user": "user",
     "group": "group",
+    "pre": "that",
+    "links": 3,
+    "post": "this",
     "mode": "/some/file",
     "mode_octal": 640,
     "links": 1,

Modified: head/contrib/libxo/tests/core/saved/test_01.T.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.T.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.T.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,3 +1,4 @@
+df    12%
 testing argument modifier my-box.example.com...
 testing argument modifier with encoding to .example.com...
 Label text value
@@ -50,4 +51,5 @@ XXXXXXXX
 X        XCost: 425
 X                              XCost: 455
  links user  group  
+3       this    
 /some/file        1 user        group         

Modified: head/contrib/libxo/tests/core/saved/test_01.X.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.X.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.X.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1 +1 @@
-<top><kve_start>0xdeadbeef</kve_start><kve_end>0xcabb1e</kve_end><host>my-box</host><domain>example.com</domain><host>my-box</host><domain>example.com</domain><label>value</label><max-chaos>very</max-chaos><min-chaos>42</min-chaos><some-chaos>[42]</some-chaos><host>my-box</host><domain>example.com</domain><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key
 ="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data2><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data2><data3><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data3><data4><item test4="value4">gum</item><item test4="value4">rope
 </item><item test4="value4">ladder</item><it!
 em test4="value4">bolt</item><item test4="value4">water</item></data4><cost>425</cost><cost>455</cost><mode>mode</mode><mode_octal>octal</mode_octal><links>links</links><user>user</user><group>group</group><mode>/some/file</mode><mode_octal>640</mode_octal><links>1</links><user>user</user><group>group</group></top>
\ No newline at end of file
+<top><used-percent>12</used-percent><kve_start>0xdeadbeef</kve_start><kve_end>0xcabb1e</kve_end><host>my-box</host><domain>example.com</domain><host>my-box</host><domain>example.com</domain><label>value</label><max-chaos>very</max-chaos><min-chaos>42</min-chaos><some-chaos>[42]</some-chaos><host>my-box</host><domain>example.com</domain><data test="value"><item test2="value2"><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="k
 ey">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data2><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data2><data3><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data3><data4><item test4="value4">gum<
 /item><item test4="value4">rope</item><item !
 test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data4><cost>425</cost><cost>455</cost><mode>mode</mode><mode_octal>octal</mode_octal><links>links</links><user>user</user><group>group</group><pre>that</pre><links>3</links><post>this</post><mode>/some/file</mode><mode_octal>640</mode_octal><links>1</links><user>user</user><group>group</group></top>
\ No newline at end of file

Modified: head/contrib/libxo/tests/core/saved/test_01.XP.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_01.XP.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_01.XP.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,4 +1,5 @@
 <top>
+  <used-percent>12</used-percent>
   <kve_start>0xdeadbeef</kve_start>
   <kve_end>0xcabb1e</kve_end>
   <host>my-box</host>
@@ -108,6 +109,9 @@
   <links>links</links>
   <user>user</user>
   <group>group</group>
+  <pre>that</pre>
+  <links>3</links>
+  <post>this</post>
   <mode>/some/file</mode>
   <mode_octal>640</mode_octal>
   <links>1</links>

Modified: head/contrib/libxo/tests/core/saved/test_02.J.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_02.J.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_02.J.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -1,2 +1,2 @@
-{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":30,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":this is an warning}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey!  She's a-pumpin' mud!  <>!,\"!<>\n"}}}
+{"top": {"data": {"what":"braces","length":"abcdef","fd":-1,"error":"Bad file descriptor","test":"good","fd":-1,"error":"Bad fi","test":"good","lines":20,"words":30,"characters":40, "bytes": [0,1,2,3,4],"mbuf-current":10,"mbuf-cache":20,"mbuf-total":30,"distance":50,"location":"Boston","memory":64,"total":640,"memory":64,"total":640,"ten":10,"eleven":11,"unknown":1010,"unknown":1010,"min":15,"cur":20,"max":30,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"min":15,"cur":20,"max":125,"val1":21,"val2":58368,"val3":100663296,"val4":44470272,"val5":1342172800, "flag": ["one","two","three"],"works":null,"empty-tag":true,"t1":"1000","t2":"test5000","t3":"ten-longx","t4":"xtest", "__error": {"message":"this is an error"}, "__error": {"message":"two more errors"}, "__warning": {"message":"this is an warning"}, "__warning": {"message":"two more warnings"},"count":10,"test":4, "error": {"message":"Shut 'er down, Clancey!  She's a-pumpin' mud!  <>!,\"!<>\n"}}}
 }

Modified: head/contrib/libxo/tests/core/saved/test_02.JP.out
==============================================================================
--- head/contrib/libxo/tests/core/saved/test_02.JP.out	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/saved/test_02.JP.out	Fri Jun 16 06:29:21 2017	(r319999)
@@ -67,7 +67,7 @@
         "message": "two more errors"
       },
       "__warning": {
-        "message": this is an warning
+        "message": "this is an warning"
       },
       "__warning": {
         "message": "two more warnings"

Modified: head/contrib/libxo/tests/core/test_01.c
==============================================================================
--- head/contrib/libxo/tests/core/test_01.c	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/tests/core/test_01.c	Fri Jun 16 06:29:21 2017	(r319999)
@@ -80,6 +80,8 @@ main (int argc, char **argv)
 
     xo_open_container_h(NULL, "top");
 
+    xo_emit("df {:used-percent/%5.0f}{U:%%}\n", (double) 12);
+
     xo_emit("{e:kve_start/%#jx}", (uintmax_t) 0xdeadbeef);
     xo_emit("{e:kve_end/%#jx}", (uintmax_t) 0xcabb1e);
 
@@ -189,6 +191,8 @@ main (int argc, char **argv)
 	    "{t:user/%s}  {t:group/%s}  \n",
 	    "mode", "octal", "links",
 	    "user", "group", "extra1", "extra2", "extra3");
+
+    xo_emit("{e:pre/%s}{t:links/%-*u}{t:post/%-*s}\n", "that", 8, 3, 8, "this");
 
     xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} "
 	    "{t:user/%-*s}  {t:group/%-*s}  \n",

Modified: head/contrib/libxo/xohtml/xohtml.css
==============================================================================
--- head/contrib/libxo/xohtml/xohtml.css	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/xohtml/xohtml.css	Fri Jun 16 06:29:21 2017	(r319999)
@@ -124,7 +124,7 @@ div.muxer-buttons {
     padding: 20px;
 }
 
-div.text, div.decoration, div.data, div.header, div.pad, div.item {
+div.text, div.decoration, div.data, div.header, div.pad, div.item, div.units {
     font-family: monospace;
     display: inline;
     vertical-align: middle;

Modified: head/contrib/libxo/xohtml/xohtml.sh.in
==============================================================================
--- head/contrib/libxo/xohtml/xohtml.sh.in	Fri Jun 16 06:15:26 2017	(r319998)
+++ head/contrib/libxo/xohtml/xohtml.sh.in	Fri Jun 16 06:29:21 2017	(r319999)
@@ -57,7 +57,8 @@ if [ "$CMD" = "cat" -a -t 0 ]; then
     do_help
 fi
 
-echo "<html>\n<head>\n"
+echo '<html>'
+echo '<head>'
 echo '<meta http-equiv="content-type" content="text/html; charset=utf-8"/>'
 echo '<link rel="stylesheet" href="'$BASE'/xohtml.css">'
 echo '<link rel="stylesheet" href="'$BASE'/external/jquery.qtip.css"/>'
@@ -66,10 +67,12 @@ echo '<script type="text/javascript" src="'$BASE'/exte
 echo '<script type="text/javascript" src="'$BASE'/xohtml.js"></script>'
 echo '<script>'
 echo '</script>'
-echo "</head>\n<body>\n"
+echo '</head>'
+echo '<body>'
 
 $CMD
 
-echo "</body>\n</html>\n"
+echo '</body>'
+echo '</html>'
 
 exit 0

Added: head/usr.bin/xohtml/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/xohtml/Makefile	Fri Jun 16 06:29:21 2017	(r319999)
@@ -0,0 +1,31 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+LIBXOSRC=	${SRCTOP}/contrib/libxo
+
+.PATH:
+.PATH:	${LIBXOSRC}/xohtml
+
+SCRIPTS= xohtml.sh
+MAN=	xohtml.1
+
+EXTERNAL_FILES = \
+    external/jquery.js \
+    external/jquery.qtip.css \
+    external/jquery.qtip.js
+
+INTERNAL_FILES = \
+    xohtml.js \
+    xohtml.css
+
+FILES=          ${INTERNAL_FILES} ${EXTERNAL_FILES}
+FILESDIR=       /usr/share/xohtml
+FILESMODE=      ${NOBINMODE}
+
+beforeinstall: mkfilesdir
+mkfilesdir:
+	test -d ${DESTDIR}${FILESDIR} \
+	   || ${INSTALL} -d -o ${FILESOWN} -g ${FILESGRP} -m 755 ${DESTDIR}${FILESDIR}
+
+.include <bsd.prog.mk>

Added: head/usr.bin/xohtml/xohtml.sh
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/xohtml/xohtml.sh	Fri Jun 16 06:29:21 2017	(r319999)
@@ -0,0 +1,79 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# Copyright (c) 2014, Juniper Networks, Inc.
+# All rights reserved.
+# This SOFTWARE is licensed under the LICENSE provided in the
+# ../Copyright file. By downloading, installing, copying, or otherwise
+# using the SOFTWARE, you agree to be bound by the terms of that
+# LICENSE.
+# Phil Shafer, July 2014
+#
+
+BASE=/usr/share/libxo
+CMD=cat
+DONE=
+
+do_help () {
+    echo "xohtml: wrap libxo-enabled output in HTML"
+    echo "Usage: xohtml [options] [command [arguments]]"
+    echo "Valid options are:"
+    echo "    -b <basepath> | --base <basepath>"
+    echo "    -c <command> | --command <command>"
+    echo "    -f <output-file> | --file <output-file>"
+    exit 1
+}
+
+while [ -z "$DONE" -a ! -z "$1" ]; do
+    case "$1" in
+        -b|--base)
+            shift;
+            BASE="$1";
+	    shift;
+            ;;
+        -c|--command)
+            shift;
+            CMD="$1";
+	    shift;
+            ;;
+        -f|--file)
+            shift;
+            FILE="$1";
+	    shift;
+	    exec > "$FILE";
+            ;;
+	-*)
+	    do_help
+	    ;;
+	*)
+	    DONE=1;
+	    XX=$1;
+	    shift;
+	    CMD="$XX --libxo=html $@"
+	    ;;
+    esac
+done
+
+if [ "$CMD" = "cat" -a -t 0 ]; then
+    do_help
+fi
+
+echo '<html>'
+echo '<head>'
+echo '<meta http-equiv="content-type" content="text/html; charset=utf-8"/>'
+echo '<link rel="stylesheet" href="'$BASE'/xohtml.css">'
+echo '<link rel="stylesheet" href="'$BASE'/external/jquery.qtip.css"/>'
+echo '<script type="text/javascript" src="'$BASE'/external/jquery.js"></script>'
+echo '<script type="text/javascript" src="'$BASE'/external/jquery.qtip.js"></script>'
+echo '<script type="text/javascript" src="'$BASE'/xohtml.js"></script>'
+echo '<script>'
+echo '</script>'
+echo '</head>'
+echo '<body>'
+
+$CMD
+
+echo '</body>'
+echo '</html>'
+
+exit 0

Added: head/usr.bin/xolint/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/xolint/Makefile	Fri Jun 16 06:29:21 2017	(r319999)
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+LIBXOSRC=	${SRCTOP}/contrib/libxo
+
+.PATH:
+.PATH:	${LIBXOSRC}/xolint
+
+SCRIPTS= xolint.pl
+MAN=	xolint.1
+
+.include <bsd.prog.mk>

Added: head/usr.bin/xopo/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/xopo/Makefile	Fri Jun 16 06:29:21 2017	(r319999)
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+.include <src.opts.mk>

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706160629.v5G6TLQb001048>