From bf91378aa0490e0917301c7a0525831c1ffcc6b0 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Mon, 26 Oct 2009 04:09:45 +0000 Subject: Full `%U' support. `Lk' display fixed. Renamed arg2xxxx as a2xxxx for consistency. Renamed print_foot to print_man_foot for consistency. Removed default printing of `~' when `Lk' not provided (not sure where I got that from). --- example.style.css | 1 + man_term.c | 60 +++++++++++++++++++++--------------------- mdoc.7 | 19 ++++++++++--- mdoc.h | 4 +-- mdoc_action.c | 8 +++--- mdoc_html.c | 46 +++++++++++++++++++------------- mdoc_strings.c | 3 ++- mdoc_term.c | 79 ++++++++++++++++++++++++++++--------------------------- mdoc_validate.c | 13 +++++---- 9 files changed, 129 insertions(+), 104 deletions(-) diff --git a/example.style.css b/example.style.css index 86505404..d5ac791e 100644 --- a/example.style.css +++ b/example.style.css @@ -58,6 +58,7 @@ a.link-ext { } /* Off-site link (Lk). */ a.link-includes { } /* Include-file link (In). */ a.link-mail { } /* Mailto links (Mt). */ a.link-man { } /* Manual links (Xr). */ +a.link-ref { } /* Reference section links (%Q). */ a.link-sec { } /* Section links (Sx). */ div.emph { font-style: italic; } /* Emphasis (Bl -emphasis). */ diff --git a/man_term.c b/man_term.c index e9f4264d..4cdc9370 100644 --- a/man_term.c +++ b/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.44 2009/10/24 05:45:05 kristaps Exp $ */ +/* $Id: man_term.c,v 1.45 2009/10/26 04:09:45 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -69,14 +69,14 @@ extern size_t strlcpy(char *, const char *, size_t); extern size_t strlcat(char *, const char *, size_t); #endif -static int arg2width(const struct man_node *); -static int arg2height(const struct man_node *); +static int a2width(const struct man_node *); +static int a2height(const struct man_node *); -static void print_head(struct termp *, +static void print_man_head(struct termp *, const struct man_meta *); -static void print_body(DECL_ARGS); -static void print_node(DECL_ARGS); -static void print_foot(struct termp *, +static void print_man_body(DECL_ARGS); +static void print_man_node(DECL_ARGS); +static void print_man_foot(struct termp *, const struct man_meta *); static void print_bvspace(struct termp *, const struct man_node *); @@ -171,7 +171,7 @@ terminal_man(void *arg, const struct man *man) n = man_node(man); m = man_meta(man); - print_head(p, m); + print_man_head(p, m); p->flags |= TERMP_NOSPACE; mt.fl = 0; @@ -179,13 +179,13 @@ terminal_man(void *arg, const struct man *man) mt.offset = INDENT; if (n->child) - print_body(p, &mt, n->child, m); - print_foot(p, m); + print_man_body(p, &mt, n->child, m); + print_man_foot(p, m); } static int -arg2height(const struct man_node *n) +a2height(const struct man_node *n) { struct roffsu su; @@ -199,7 +199,7 @@ arg2height(const struct man_node *n) static int -arg2width(const struct man_node *n) +a2width(const struct man_node *n) { struct roffsu su; @@ -310,7 +310,7 @@ pre_IR(DECL_ARGS) p->under++; if (i > 0) p->flags |= TERMP_NOSPACE; - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); if ( ! (i % 2)) p->under--; } @@ -334,7 +334,7 @@ pre_RB(DECL_ARGS) if (i > 0) p->flags |= TERMP_NOSPACE; - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); if (i % 2 && MAN_RB == n->tok) p->bold--; @@ -357,7 +357,7 @@ pre_RI(DECL_ARGS) p->under++; if (i > 0) p->flags |= TERMP_NOSPACE; - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); if ( ! (i % 2)) p->under--; } @@ -384,7 +384,7 @@ pre_BI(DECL_ARGS) if (i) p->flags |= TERMP_NOSPACE; - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); if (i % 2 && MAN_BI == n->tok) p->under--; @@ -424,7 +424,7 @@ pre_sp(DECL_ARGS) { int i, len; - len = n->child ? arg2height(n->child) : 1; + len = n->child ? a2height(n->child) : 1; if (0 == len) term_newln(p); @@ -471,7 +471,7 @@ pre_HP(DECL_ARGS) /* Calculate offset. */ if (NULL != (nn = n->parent->head->child)) - if ((ival = arg2width(nn)) >= 0) + if ((ival = a2width(nn)) >= 0) len = (size_t)ival; if (0 == len) @@ -561,7 +561,7 @@ pre_IP(DECL_ARGS) if (NULL != (nn = nn->next)) { for ( ; nn->next; nn = nn->next) /* Do nothing. */ ; - if ((ival = arg2width(nn)) >= 0) + if ((ival = a2width(nn)) >= 0) len = (size_t)ival; } @@ -581,7 +581,7 @@ pre_IP(DECL_ARGS) /* Don't print the length value. */ for (nn = n->child; nn->next; nn = nn->next) - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); return(0); case (MAN_BODY): p->offset = mt->offset + len; @@ -648,7 +648,7 @@ pre_TP(DECL_ARGS) if (NULL != (nn = n->parent->head->child)) if (NULL != nn->next) - if ((ival = arg2width(nn)) >= 0) + if ((ival = a2width(nn)) >= 0) len = (size_t)ival; switch (n->type) { @@ -663,7 +663,7 @@ pre_TP(DECL_ARGS) /* Don't print same-line elements. */ for (nn = n->child; nn; nn = nn->next) if (nn->line > n->line) - print_node(p, mt, nn, m); + print_man_node(p, mt, nn, m); if (ival >= 0) mt->lmargin = (size_t)ival; @@ -826,7 +826,7 @@ pre_RS(DECL_ARGS) return(1); } - if ((ival = arg2width(nn)) < 0) + if ((ival = a2width(nn)) < 0) return(1); mt->offset = INDENT + (size_t)ival; @@ -854,7 +854,7 @@ post_RS(DECL_ARGS) static void -print_node(DECL_ARGS) +print_man_node(DECL_ARGS) { int c, sz; @@ -890,7 +890,7 @@ print_node(DECL_ARGS) } if (c && n->child) - print_body(p, mt, n->child, m); + print_man_body(p, mt, n->child, m); if (MAN_TEXT != n->type) if (termacts[n->tok].post) @@ -899,18 +899,18 @@ print_node(DECL_ARGS) static void -print_body(DECL_ARGS) +print_man_body(DECL_ARGS) { - print_node(p, mt, n, m); + print_man_node(p, mt, n, m); if ( ! n->next) return; - print_body(p, mt, n->next, m); + print_man_body(p, mt, n->next, m); } static void -print_foot(struct termp *p, const struct man_meta *meta) +print_man_foot(struct termp *p, const struct man_meta *meta) { char buf[DATESIZ]; @@ -939,7 +939,7 @@ print_foot(struct termp *p, const struct man_meta *meta) static void -print_head(struct termp *p, const struct man_meta *meta) +print_man_head(struct termp *p, const struct man_meta *meta) { char *buf, *title; diff --git a/mdoc.7 b/mdoc.7 index 47410dc5..c0de1e0a 100644 --- a/mdoc.7 +++ b/mdoc.7 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.7,v 1.69 2009/10/24 05:52:13 kristaps Exp $ +.\" $Id: mdoc.7,v 1.70 2009/10/26 04:09:45 kristaps Exp $ .\" .\" Copyright (c) 2009 Kristaps Dzonsons .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 24 2009 $ +.Dd $Mdocdate: October 26 2009 $ .Dt MDOC 7 .Os . @@ -759,7 +759,7 @@ block. This macro may also be used in a non-bibliographical context when referring to article titles. . .Ss \&%U -URI of current document. +URI of reference document. . .Ss \&%V Volume number of an @@ -1451,6 +1451,19 @@ and .Ss \&Lb .Ss \&Li .Ss \&Lk +Format a hyperlink. The calling syntax is as follows: +.Pp +.D1 \. Ns Sx \&Lk Cm uri Op Cm name +.Pp +Examples: +.Bd -literal -offset indent +\&.Lk http://bsd.lv "The BSD.lv Project" +\&.Lk http://bsd.lv +.Ed +.Pp +See also +.Sx \&Mt . +. .Ss \&Lp .Ss \&Ms .Ss \&Mt diff --git a/mdoc.h b/mdoc.h index 8691db80..810a4d0f 100644 --- a/mdoc.h +++ b/mdoc.h @@ -1,4 +1,4 @@ -/* $Id: mdoc.h,v 1.71 2009/10/24 05:52:13 kristaps Exp $ */ +/* $Id: mdoc.h,v 1.72 2009/10/26 04:09:45 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -17,8 +17,6 @@ #ifndef MDOC_H #define MDOC_H -#include - /* * This library implements a validating scanner/parser for ``mdoc'' roff * macro documents, a.k.a. BSD manual page documents. The mdoc.c file diff --git a/mdoc_action.c b/mdoc_action.c index 52533b23..709701d4 100644 --- a/mdoc_action.c +++ b/mdoc_action.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_action.c,v 1.43 2009/10/24 05:52:13 kristaps Exp $ */ +/* $Id: mdoc_action.c,v 1.44 2009/10/26 04:09:45 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -14,13 +14,16 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef OSNAME #include +#endif #include #include #include #include #include +#include #include "libmdoc.h" @@ -174,7 +177,7 @@ static const struct actions mdoc_actions[MDOC_MAX] = { { NULL, NULL }, /* Ud */ { NULL, post_lb }, /* Lb */ { NULL, NULL }, /* Lp */ - { NULL, post_tilde }, /* Lk */ + { NULL, NULL }, /* Lk */ { NULL, NULL }, /* Mt */ { NULL, NULL }, /* Brq */ { NULL, NULL }, /* Bro */ @@ -771,7 +774,6 @@ post_tilde(POST_ARGS) np = n; m->next = MDOC_NEXT_CHILD; - /* XXX: not documented for `Lk'. */ if ( ! mdoc_word_alloc(m, n->line, n->pos, "~")) return(0); m->last = np; diff --git a/mdoc_html.c b/mdoc_html.c index 5dbad7c2..6a05a918 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.37 2009/10/24 05:52:13 kristaps Exp $ */ +/* $Id: mdoc_html.c,v 1.38 2009/10/26 04:09:45 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -1757,6 +1757,9 @@ mdoc_lk_pre(MDOC_ARGS) tag[1].val = nn->string; print_otag(h, TAG_A, 2, tag); + if (NULL == nn->next) + return(1); + for (nn = nn->next; nn; nn = nn->next) print_text(h, nn->string); @@ -2147,58 +2150,65 @@ mdoc_lb_pre(MDOC_ARGS) static int mdoc__x_pre(MDOC_ARGS) { - struct htmlpair tag; - - /* TODO: %U. */ + struct htmlpair tag[2]; switch (n->tok) { case(MDOC__A): - PAIR_CLASS_INIT(&tag, "ref-auth"); + PAIR_CLASS_INIT(&tag[0], "ref-auth"); break; case(MDOC__B): - PAIR_CLASS_INIT(&tag, "ref-book"); + PAIR_CLASS_INIT(&tag[0], "ref-book"); break; case(MDOC__C): - PAIR_CLASS_INIT(&tag, "ref-city"); + PAIR_CLASS_INIT(&tag[0], "ref-city"); break; case(MDOC__D): - PAIR_CLASS_INIT(&tag, "ref-date"); + PAIR_CLASS_INIT(&tag[0], "ref-date"); break; case(MDOC__I): - PAIR_CLASS_INIT(&tag, "ref-issue"); + PAIR_CLASS_INIT(&tag[0], "ref-issue"); break; case(MDOC__J): - PAIR_CLASS_INIT(&tag, "ref-jrnl"); + PAIR_CLASS_INIT(&tag[0], "ref-jrnl"); break; case(MDOC__N): - PAIR_CLASS_INIT(&tag, "ref-num"); + PAIR_CLASS_INIT(&tag[0], "ref-num"); break; case(MDOC__O): - PAIR_CLASS_INIT(&tag, "ref-opt"); + PAIR_CLASS_INIT(&tag[0], "ref-opt"); break; case(MDOC__P): - PAIR_CLASS_INIT(&tag, "ref-page"); + PAIR_CLASS_INIT(&tag[0], "ref-page"); break; case(MDOC__Q): - PAIR_CLASS_INIT(&tag, "ref-corp"); + PAIR_CLASS_INIT(&tag[0], "ref-corp"); break; case(MDOC__R): - PAIR_CLASS_INIT(&tag, "ref-rep"); + PAIR_CLASS_INIT(&tag[0], "ref-rep"); break; case(MDOC__T): - PAIR_CLASS_INIT(&tag, "ref-title"); + PAIR_CLASS_INIT(&tag[0], "ref-title"); print_text(h, "\\(lq"); h->flags |= HTML_NOSPACE; break; + case(MDOC__U): + PAIR_CLASS_INIT(&tag[0], "link-ref"); + break; case(MDOC__V): - PAIR_CLASS_INIT(&tag, "ref-vol"); + PAIR_CLASS_INIT(&tag[0], "ref-vol"); break; default: abort(); /* NOTREACHED */ } - print_otag(h, TAG_SPAN, 1, &tag); + if (MDOC__U != n->tok) { + print_otag(h, TAG_SPAN, 1, tag); + return(1); + } + + PAIR_HREF_INIT(&tag[1], n->child->string); + print_otag(h, TAG_A, 2, tag); return(1); } diff --git a/mdoc_strings.c b/mdoc_strings.c index d83551d6..15bf7fea 100644 --- a/mdoc_strings.c +++ b/mdoc_strings.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_strings.c,v 1.10 2009/08/20 13:32:09 kristaps Exp $ */ +/* $Id: mdoc_strings.c,v 1.11 2009/10/26 04:09:46 kristaps Exp $ */ /* * Copyright (c) 2008 Kristaps Dzonsons * @@ -20,6 +20,7 @@ #include #include #include +#include #include "libmdoc.h" diff --git a/mdoc_term.c b/mdoc_term.c index bda0a669..a7b6828c 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.95 2009/10/24 05:52:14 kristaps Exp $ */ +/* $Id: mdoc_term.c,v 1.96 2009/10/26 04:09:46 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -48,6 +48,28 @@ struct termact { void (*post)(DECL_ARGS); }; +static size_t a2width(const struct mdoc_argv *, int); +static size_t a2height(const struct mdoc_node *); +static size_t a2offs(const struct mdoc_argv *); + +static int arg_hasattr(int, const struct mdoc_node *); +static int arg_getattrs(const int *, int *, size_t, + const struct mdoc_node *); +static int arg_getattr(int, const struct mdoc_node *); +static int arg_listtype(const struct mdoc_node *); +static void print_bvspace(struct termp *, + const struct mdoc_node *, + const struct mdoc_node *); +static void print_node(DECL_ARGS); +static void print_head(DECL_ARGS); +static void print_body(DECL_ARGS); +static void print_foot(DECL_ARGS); + +#ifdef __linux__ +extern size_t strlcpy(char *, const char *, size_t); +extern size_t strlcat(char *, const char *, size_t); +#endif + static void termp____post(DECL_ARGS); static void termp_an_post(DECL_ARGS); static void termp_aq_post(DECL_ARGS); @@ -236,31 +258,9 @@ static const struct termact termacts[MDOC_MAX] = { { NULL, termp____post }, /* %Q */ { termp_sp_pre, NULL }, /* br */ { termp_sp_pre, NULL }, /* sp */ - { NULL, termp____post }, /* %U */ + { termp_under_pre, termp____post }, /* %U */ }; -#ifdef __linux__ -extern size_t strlcpy(char *, const char *, size_t); -extern size_t strlcat(char *, const char *, size_t); -#endif - -static size_t arg2width(const struct mdoc_argv *, int); -static size_t arg2height(const struct mdoc_node *); -static size_t arg2offs(const struct mdoc_argv *); - -static int arg_hasattr(int, const struct mdoc_node *); -static int arg_getattrs(const int *, int *, size_t, - const struct mdoc_node *); -static int arg_getattr(int, const struct mdoc_node *); -static int arg_listtype(const struct mdoc_node *); -static void print_bvspace(struct termp *, - const struct mdoc_node *, - const struct mdoc_node *); -static void print_node(DECL_ARGS); -static void print_head(DECL_ARGS); -static void print_body(DECL_ARGS); -static void print_foot(DECL_ARGS); - void terminal_mdoc(void *arg, const struct mdoc *mdoc) @@ -469,7 +469,7 @@ print_head(DECL_ARGS) static size_t -arg2height(const struct mdoc_node *n) +a2height(const struct mdoc_node *n) { struct roffsu su; @@ -483,7 +483,7 @@ arg2height(const struct mdoc_node *n) static size_t -arg2width(const struct mdoc_argv *arg, int pos) +a2width(const struct mdoc_argv *arg, int pos) { struct roffsu su; @@ -538,7 +538,7 @@ arg_listtype(const struct mdoc_node *n) static size_t -arg2offs(const struct mdoc_argv *arg) +a2offs(const struct mdoc_argv *arg) { struct roffsu su; @@ -717,23 +717,23 @@ termp_it_pre(DECL_ARGS) for (i = 0, nn = n->prev; nn && i < (int)bl->args->argv[vals[2]].sz; nn = nn->prev, i++) - offset += arg2width + offset += a2width (&bl->args->argv[vals[2]], i); /* Whether exceeds maximum column. */ if (i < (int)bl->args->argv[vals[2]].sz) - width = arg2width(&bl->args->argv[vals[2]], i); + width = a2width(&bl->args->argv[vals[2]], i); else width = 0; if (vals[1] >= 0) - offset += arg2offs(&bl->args->argv[vals[1]]); + offset += a2offs(&bl->args->argv[vals[1]]); break; default: if (vals[0] >= 0) - width = arg2width(&bl->args->argv[vals[0]], 0); + width = a2width(&bl->args->argv[vals[0]], 0); if (vals[1] >= 0) - offset += arg2offs(&bl->args->argv[vals[1]]); + offset += a2offs(&bl->args->argv[vals[1]]); break; } @@ -1556,7 +1556,7 @@ termp_bd_pre(DECL_ARGS) type = nn->args->argv[i].arg; break; case (MDOC_Offset): - p->offset += arg2offs(&nn->args->argv[i]); + p->offset += a2offs(&nn->args->argv[i]); break; default: break; @@ -1811,7 +1811,7 @@ termp_sp_pre(DECL_ARGS) switch (n->tok) { case (MDOC_sp): - len = n->child ? arg2height(n->child) : 1; + len = n->child ? a2height(n->child) : 1; break; case (MDOC_br): len = 0; @@ -2028,16 +2028,17 @@ termp_lk_pre(DECL_ARGS) { const struct mdoc_node *nn; - if (NULL == (nn = n->child->next)) { - p->under++; + p->under++; + nn = n->child; + + if (NULL == nn->next) return(1); - } - p->under++; term_word(p, nn->string); + p->under--; + p->flags |= TERMP_NOSPACE; term_word(p, ":"); - p->under--; p->bold++; for (nn = nn->next; nn; nn = nn->next) diff --git a/mdoc_validate.c b/mdoc_validate.c index f8e58afc..0ca6190e 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.50 2009/10/24 05:52:14 kristaps Exp $ */ +/* $Id: mdoc_validate.c,v 1.51 2009/10/26 04:09:46 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -119,19 +119,18 @@ static v_post posts_bf[] = { hwarn_le1, post_bf, NULL }; static v_post posts_bl[] = { bwarn_ge1, post_bl, NULL }; static v_post posts_bool[] = { eerr_eq1, ebool, NULL }; static v_post posts_fo[] = { hwarn_eq1, bwarn_ge1, NULL }; -static v_post posts_in[] = { eerr_eq1, NULL }; static v_post posts_it[] = { post_it, NULL }; static v_post posts_lb[] = { eerr_eq1, post_lb, NULL }; static v_post posts_nd[] = { berr_ge1, NULL }; static v_post posts_nm[] = { post_nm, NULL }; static v_post posts_notext[] = { eerr_eq0, NULL }; -static v_post posts_pf[] = { eerr_eq1, NULL }; static v_post posts_rs[] = { berr_ge1, herr_eq0, post_rs, NULL }; static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL }; static v_post posts_sp[] = { eerr_le1, NULL }; static v_post posts_ss[] = { herr_ge1, NULL }; static v_post posts_st[] = { eerr_eq1, post_st, NULL }; static v_post posts_text[] = { eerr_ge1, NULL }; +static v_post posts_text1[] = { eerr_eq1, NULL }; static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL }; static v_post posts_wtext[] = { ewarn_ge1, NULL }; static v_post posts_xr[] = { eerr_ge1, eerr_le2, NULL }; @@ -182,7 +181,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_text }, /* Fn */ { NULL, posts_wtext }, /* Ft */ { NULL, posts_text }, /* Ic */ - { NULL, posts_in }, /* In */ + { NULL, posts_text1 }, /* In */ { NULL, NULL }, /* Li */ { NULL, posts_nd }, /* Nd */ { NULL, posts_nm }, /* Nm */ @@ -230,7 +229,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Nx */ { NULL, NULL }, /* Ox */ { NULL, NULL }, /* Pc */ - { NULL, posts_pf }, /* Pf */ + { NULL, posts_text1 }, /* Pf */ { NULL, NULL }, /* Po */ { NULL, posts_wline }, /* Pq */ { NULL, NULL }, /* Qc */ @@ -261,7 +260,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_notext }, /* Ud */ { pres_lb, posts_lb }, /* Lb */ { NULL, posts_notext }, /* Lp */ - { NULL, NULL }, /* Lk */ + { NULL, posts_text }, /* Lk */ { NULL, posts_text }, /* Mt */ { NULL, posts_wline }, /* Brq */ { NULL, NULL }, /* Bro */ @@ -273,7 +272,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_text }, /* %Q */ { NULL, posts_notext }, /* br */ { NULL, posts_sp }, /* sp */ - { NULL, posts_text }, /* %U */ + { NULL, posts_text1 }, /* %U */ }; -- cgit v1.2.3-56-ge451