summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libroff.h4
-rw-r--r--main.c1
-rw-r--r--mandoc.h2
-rw-r--r--roff.75
-rw-r--r--tbl.c9
-rw-r--r--tbl_data.c57
-rw-r--r--tbl_html.c3
-rw-r--r--tbl_term.c12
8 files changed, 78 insertions, 15 deletions
diff --git a/libroff.h b/libroff.h
index 04998297..6fea1c99 100644
--- a/libroff.h
+++ b/libroff.h
@@ -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 *);
diff --git a/main.c b/main.c
index e0cc5d53..499427b5 100644
--- a/main.c
+++ b/main.c
@@ -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",
diff --git a/mandoc.h b/mandoc.h
index fbe04641..db225a39 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -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,
diff --git a/roff.7 b/roff.7
index 296a419a..12a709d7 100644
--- a/roff.7
+++ b/roff.7
@@ -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
diff --git a/tbl.c b/tbl.c
index e463eaa0..a212d70a 100644
--- a/tbl.c
+++ b/tbl.c
@@ -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);
}
diff --git a/tbl_data.c b/tbl_data.c
index 2090764f..620af8fe 100644
--- a/tbl_data.c
+++ b/tbl_data.c
@@ -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);
}
diff --git a/tbl_html.c b/tbl_html.c
index b892060f..13267dc5 100644
--- a/tbl_html.c
+++ b/tbl_html.c
@@ -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);
diff --git a/tbl_term.c b/tbl_term.c
index 6ee2d112..de0b0652 100644
--- a/tbl_term.c
+++ b/tbl_term.c
@@ -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;