diff options
author | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-07-25 15:37:00 +0000 |
---|---|---|
committer | Kristaps Dzonsons <kristaps@bsd.lv> | 2011-07-25 15:37:00 +0000 |
commit | 50079d4076610ce94c315c3ead86fa3dd19dc673 (patch) | |
tree | a0a462e3767cedd8ddb18951887372ecbe0ebe93 | |
parent | 9e5a4ae8da2d23137cf7342e8fe27ed1172b98f5 (diff) | |
download | mandoc-50079d4076610ce94c315c3ead86fa3dd19dc673.tar.gz |
Implement the first steps of equation parsing from within libmdoc.
This consists of a shim around the text parser that calls out to libroff
if equation components exist on the line. Right now this will do
nothing, as the equation delimiter always returns nil.
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | eqn.c | 11 | ||||
-rw-r--r-- | libmandoc.h | 4 | ||||
-rw-r--r-- | libroff.h | 4 | ||||
-rw-r--r-- | mdoc.c | 54 | ||||
-rw-r--r-- | roff.c | 49 | ||||
-rw-r--r-- | tbl.c | 6 |
7 files changed, 113 insertions, 20 deletions
@@ -332,6 +332,11 @@ clean: rm -f config.h config.log $(COMPAT_OBJS) $(COMPAT_LNS) rm -f mdocml.tar.gz mdocml-win32.zip rm -f index.html $(INDEX_OBJS) + rm -rf test-strlcpy.DSYM + rm -rf test-strlcat.DSYM + rm -rf test-strptime.DSYM + rm -rf test-mmap.DSYM + rm -rf test-getsubopt.DSYM install: all mkdir -p $(DESTDIR)$(BINDIR) @@ -294,8 +294,7 @@ eqn_read(struct eqn_node **epp, int ln, */ if (0 == strncmp(p, ".EN", 3)) { - er = eqn_end(ep); - *epp = NULL; + er = eqn_end(epp); p += 3; while (' ' == *p || '\t' == *p) p++; @@ -333,7 +332,7 @@ eqn_alloc(const char *name, int pos, int line, struct mparse *parse) p = mandoc_calloc(1, sizeof(struct eqn_node)); - if ('\0' != *name) { + if (name && '\0' != *name) { sz = strlen(name); assert(sz); do { @@ -352,11 +351,15 @@ eqn_alloc(const char *name, int pos, int line, struct mparse *parse) } enum rofferr -eqn_end(struct eqn_node *ep) +eqn_end(struct eqn_node **epp) { + struct eqn_node *ep; struct eqn_box *root; enum eqn_rest c; + ep = *epp; + *epp = NULL; + ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box)); root = ep->eqn.root; diff --git a/libmandoc.h b/libmandoc.h index 7a79257a..c7f0b41d 100644 --- a/libmandoc.h +++ b/libmandoc.h @@ -76,6 +76,10 @@ void roff_endparse(struct roff *); int roff_regisset(const struct roff *, enum regs); unsigned int roff_regget(const struct roff *, enum regs); void roff_regunset(struct roff *, enum regs); +char roff_eqndelim(const struct roff *); +void roff_openeqn(struct roff *, const char *, + int, int, const char *); +int roff_closeeqn(struct roff *); const struct tbl_span *roff_span(const struct roff *); const struct eqn *roff_eqn(const struct roff *); @@ -72,9 +72,9 @@ 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(struct tbl_node *); -void tbl_end(struct tbl_node *); +void tbl_end(struct tbl_node **); struct eqn_node *eqn_alloc(const char *, int, int, struct mparse *); -enum rofferr eqn_end(struct eqn_node *); +enum rofferr eqn_end(struct eqn_node **); void eqn_free(struct eqn_node *); enum rofferr eqn_read(struct eqn_node **, int, const char *, int, int *); @@ -97,6 +97,7 @@ static struct mdoc_node *node_alloc(struct mdoc *, int, int, enum mdoct, enum mdoc_type); static int node_append(struct mdoc *, struct mdoc_node *); +static int mdoc_preptext(struct mdoc *, int, char *, int); static int mdoc_ptext(struct mdoc *, int, char *, int); static int mdoc_pmacro(struct mdoc *, int, char *, int); @@ -299,7 +300,7 @@ mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs) return(mandoc_getcontrol(buf, &offs) ? mdoc_pmacro(m, ln, buf, offs) : - mdoc_ptext(m, ln, buf, offs)); + mdoc_preptext(m, ln, buf, offs)); } int @@ -650,6 +651,57 @@ mdoc_node_delete(struct mdoc *m, struct mdoc_node *p) mdoc_node_free(p); } +/* + * Pre-treat a text line. + * Text lines can consist of equations, which must be handled apart from + * the regular text. + * Thus, use this function to step through a line checking if it has any + * equations embedded in it. + * This must handle multiple equations AND equations that do not end at + * the end-of-line, i.e., will re-enter in the next roff parse. + */ +static int +mdoc_preptext(struct mdoc *m, int line, char *buf, int offs) +{ + char *start, *end; + char delim; + + while ('\0' != buf[offs]) { + /* Mark starting position if eqn is set. */ + start = NULL; + if ('\0' != (delim = roff_eqndelim(m->roff))) + if (NULL != (start = strchr(buf + offs, delim))) + *start++ = '\0'; + + /* Parse text as normal. */ + if ( ! mdoc_ptext(m, line, buf, offs)) + return(0); + + /* Continue only if an equation exists. */ + if (NULL == start) + break; + + /* Read past the end of the equation. */ + offs += start - (buf + offs); + assert(start == &buf[offs]); + if (NULL != (end = strchr(buf + offs, delim))) { + *end++ = '\0'; + while (' ' == *end) + end++; + } + + /* Parse the equation itself. */ + roff_openeqn(m->roff, NULL, line, offs, buf); + + /* Process a finished equation? */ + if (roff_closeeqn(m->roff)) + if ( ! mdoc_addeqn(m, roff_eqn(m->roff))) + return(0); + offs += (end - (buf + offs)); + } + + return(1); +} /* * Parse free-form text, that is, a line that does not begin with the @@ -584,15 +584,13 @@ roff_endparse(struct roff *r) if (r->eqn) { mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse, r->eqn->eqn.ln, r->eqn->eqn.pos, NULL); - eqn_end(r->eqn); - r->eqn = NULL; + eqn_end(&r->eqn); } if (r->tbl) { mandoc_msg(MANDOCERR_SCOPEEXIT, r->parse, r->tbl->line, r->tbl->pos, NULL); - tbl_end(r->tbl); - r->tbl = NULL; + tbl_end(&r->tbl); } } @@ -1182,9 +1180,8 @@ roff_TE(ROFF_ARGS) if (NULL == r->tbl) mandoc_msg(MANDOCERR_NOSCOPE, r->parse, ln, ppos, NULL); else - tbl_end(r->tbl); + tbl_end(&r->tbl); - r->tbl = NULL; return(ROFF_IGN); } @@ -1201,14 +1198,22 @@ roff_T_(ROFF_ARGS) return(ROFF_IGN); } -/* ARGSUSED */ -static enum rofferr -roff_EQ(ROFF_ARGS) +int +roff_closeeqn(struct roff *r) { - struct eqn_node *e; + + return(r->eqn && ROFF_EQN == eqn_end(&r->eqn) ? 1 : 0); +} + +void +roff_openeqn(struct roff *r, const char *name, int line, + int offs, const char *buf) +{ + struct eqn_node *e; + int poff; assert(NULL == r->eqn); - e = eqn_alloc(*bufp + pos, ppos, ln, r->parse); + e = eqn_alloc(name, offs, line, r->parse); if (r->last_eqn) r->last_eqn->next = e; @@ -1216,6 +1221,19 @@ roff_EQ(ROFF_ARGS) r->first_eqn = r->last_eqn = e; r->eqn = r->last_eqn = e; + + if (buf) { + poff = 0; + eqn_read(&r->eqn, line, buf, offs, &poff); + } +} + +/* ARGSUSED */ +static enum rofferr +roff_EQ(ROFF_ARGS) +{ + + roff_openeqn(r, *bufp + pos, ln, ppos, NULL); return(ROFF_IGN); } @@ -1236,7 +1254,7 @@ roff_TS(ROFF_ARGS) if (r->tbl) { mandoc_msg(MANDOCERR_SCOPEBROKEN, r->parse, ln, ppos, NULL); - tbl_end(r->tbl); + tbl_end(&r->tbl); } t = tbl_alloc(ppos, ln, r->parse); @@ -1472,3 +1490,10 @@ roff_eqn(const struct roff *r) return(r->last_eqn ? &r->last_eqn->eqn : NULL); } + +char +roff_eqndelim(const struct roff *r) +{ + + return('\0'); +} @@ -154,8 +154,12 @@ tbl_span(struct tbl_node *tbl) } void -tbl_end(struct tbl_node *tbl) +tbl_end(struct tbl_node **tblp) { + struct tbl_node *tbl; + + tbl = *tblp; + *tblp = NULL; if (NULL == tbl->first_span || NULL == tbl->first_span->first) mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse, |