diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-01-04 15:02:00 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-01-04 15:02:00 +0000 |
commit | 169a2d82c18ba1ee663ba1da329795f3e1753e8d (patch) | |
tree | 26abfc46221fcb93c3697f6ed426ea8c590cb98d | |
parent | 6f6927e6a5ffb72da4a382768a7d53d045cf5590 (diff) | |
download | mandoc-169a2d82c18ba1ee663ba1da329795f3e1753e8d.tar.gz |
Support `T{' and `T}' data blocks. When a standalone `T{' is
encountered as a line's last data cell, move into TBL_PART_CDATA mode
whilst leaving the cell's designation as TBL_DATA_NONE. When new data
arrives that's not a standalone `T}', append it to the cell contends.
Close out and warn appropriately.
-rw-r--r-- | libroff.h | 4 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | mandoc.h | 2 | ||||
-rw-r--r-- | roff.7 | 5 | ||||
-rw-r--r-- | tbl.c | 9 | ||||
-rw-r--r-- | tbl_data.c | 57 | ||||
-rw-r--r-- | tbl_html.c | 3 | ||||
-rw-r--r-- | tbl_term.c | 12 |
8 files changed, 78 insertions, 15 deletions
@@ -22,7 +22,8 @@ __BEGIN_DECLS enum tbl_part { TBL_PART_OPTS, /* in options (first line) */ TBL_PART_LAYOUT, /* describing layout */ - TBL_PART_DATA /* creating data rows */ + TBL_PART_DATA, /* creating data rows */ + TBL_PART_CDATA /* continue previous row */ }; struct tbl_node { @@ -52,6 +53,7 @@ enum rofferr tbl_read(struct tbl_node *, int, const char *, int); int tbl_option(struct tbl_node *, int, const char *); int tbl_layout(struct tbl_node *, int, const char *); int tbl_data(struct tbl_node *, int, const char *); +int tbl_cdata(struct tbl_node *, int, const char *); const struct tbl_span *tbl_span(const struct tbl_node *); void tbl_end(struct tbl_node *); @@ -190,6 +190,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no table layout cells specified", "no table data cells specified", "ignore data in cell", + "data block still open", "input stack limit exceeded, infinite loop?", "skipping bad character", @@ -112,6 +112,7 @@ enum mandocerr { MANDOCERR_TBLNOLAYOUT, /* no table layout cells specified */ MANDOCERR_TBLNODATA, /* no table data cells specified */ MANDOCERR_TBLIGNDATA, /* ignore data in cell */ + MANDOCERR_TBLBLOCK, /* data block still open */ MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */ MANDOCERR_BADCHAR, /* skipping bad character */ @@ -224,6 +225,7 @@ struct tbl_row { }; enum tbl_datt { + TBL_DATA_NONE, TBL_DATA_DATA, TBL_DATA_HORIZ, TBL_DATA_DHORIZ, @@ -736,6 +736,11 @@ or .Cm \e= is specified, a line is drawn within the data field (i.e., terminating within the cell and not draw to the border). +If the last cell of a line is +.Cm T{ , +all subsequent lines are included as part of the cell until +.Cm T} +is specified on its own line. .Sh COMPATIBILITY This section documents compatibility between mandoc and other other .Nm @@ -52,7 +52,9 @@ tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs) return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); case (TBL_PART_LAYOUT): return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR); - case (TBL_PART_DATA): + case (TBL_PART_CDATA): + return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN); + default: break; } @@ -122,6 +124,8 @@ tbl_free(struct tbl_node *p) void tbl_restart(int line, int pos, struct tbl_node *tbl) { + if (TBL_PART_CDATA == tbl->part) + TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos); tbl->part = TBL_PART_LAYOUT; tbl->line = line; @@ -148,5 +152,8 @@ tbl_end(struct tbl_node *tbl) if (tbl->last_span) tbl->last_span->flags |= TBL_SPAN_LAST; + + if (TBL_PART_CDATA == tbl->part) + TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos); } @@ -14,6 +14,10 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <assert.h> #include <ctype.h> #include <stdlib.h> @@ -24,10 +28,10 @@ #include "libmandoc.h" #include "libroff.h" -static void data(struct tbl_node *, struct tbl_span *, +static int data(struct tbl_node *, struct tbl_span *, int, const char *, int *); -void +static int data(struct tbl_node *tbl, struct tbl_span *dp, int ln, const char *p, int *pos) { @@ -47,10 +51,9 @@ data(struct tbl_node *tbl, struct tbl_span *dp, TBL_CELL_DVERT == cp->pos)) cp = cp->next; - /* FIXME: warn about losing data contents if cell is HORIZ. */ - dat = mandoc_calloc(1, sizeof(struct tbl_dat)); dat->layout = cp; + dat->pos = TBL_DATA_NONE; if (NULL == dat->layout) TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos); @@ -65,6 +68,17 @@ data(struct tbl_node *tbl, struct tbl_span *dp, while (p[*pos] && p[*pos] != tbl->opts.tab) (*pos)++; + /* + * Check for a continued-data scope opening. This consists of a + * trailing `T{' at the end of the line. Subsequent lines, + * until a standalone `T}', are included in our cell. + */ + + if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) { + tbl->part = TBL_PART_CDATA; + return(0); + } + dat->string = mandoc_malloc(*pos - sv + 1); memcpy(dat->string, &p[sv], *pos - sv); dat->string[*pos - sv] = '\0'; @@ -83,10 +97,40 @@ data(struct tbl_node *tbl, struct tbl_span *dp, else dat->pos = TBL_DATA_DATA; + if (NULL == dat->layout) + return(1); + if (TBL_CELL_HORIZ == dat->layout->pos || TBL_CELL_DHORIZ == dat->layout->pos) if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string) TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv); + + return(1); +} + +int +tbl_cdata(struct tbl_node *tbl, int ln, const char *p) +{ + struct tbl_dat *dat; + size_t sz; + + if (0 == strcmp(p, "T}")) { + tbl->part = TBL_PART_DATA; + return(1); + } + + dat = tbl->last_span->last; + dat->pos = TBL_DATA_DATA; + + if (dat->string) { + sz = strlen(p) + strlen(dat->string) + 2; + dat->string = mandoc_realloc(dat->string, sz); + strlcat(dat->string, " ", sz); + strlcat(dat->string, p, sz); + } else + dat->string = mandoc_strdup(p); + + return(0); } int @@ -141,8 +185,11 @@ tbl_data(struct tbl_node *tbl, int ln, const char *p) dp->pos = TBL_SPAN_DATA; + /* This returns 0 when TBL_PART_CDATA is entered. */ + while ('\0' != p[pos]) - data(tbl, dp, ln, p, &pos); + if ( ! data(tbl, dp, ln, p, &pos)) + return(0); return(1); } @@ -63,7 +63,8 @@ print_tbl(struct html *h, const struct tbl_span *sp) } tt = print_otag(h, TAG_TD, 0, NULL); if (dp) { - print_text(h, dp->string); + if (dp->string) + print_text(h, dp->string); dp = dp->next; } print_tagq(h, tt); @@ -253,6 +253,9 @@ tbl_data(struct termp *tp, const struct tbl *tbl, } switch (dp->pos) { + case (TBL_DATA_NONE): + tbl_char(tp, ASCII_NBRSP, tbp->width); + return; case (TBL_DATA_HORIZ): /* FALLTHROUGH */ case (TBL_DATA_NHORIZ): @@ -420,14 +423,9 @@ tbl_calc(struct termp *tp, const struct tbl_span *sp) hp = sp->head; for ( ; sp; sp = sp->next) { - switch (sp->pos) { - case (TBL_DATA_HORIZ): - /* FALLTHROUGH */ - case (TBL_DATA_DHORIZ): + if (TBL_SPAN_DATA != sp->pos) continue; - default: - break; - } + for (dp = sp->first; dp; dp = dp->next) { if (NULL == dp->layout) continue; |