From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from krisdoz.my.domain (schwarze@localhost [127.0.0.1]) by krisdoz.my.domain (8.14.5/8.14.5) with ESMTP id s9G1BKKG009170 for ; Wed, 15 Oct 2014 21:11:20 -0400 (EDT) Received: (from schwarze@localhost) by krisdoz.my.domain (8.14.5/8.14.3/Submit) id s9G1BK7Y003235; Wed, 15 Oct 2014 21:11:20 -0400 (EDT) Date: Wed, 15 Oct 2014 21:11:20 -0400 (EDT) Message-Id: <201410160111.s9G1BK7Y003235@krisdoz.my.domain> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Implement in-line equations, much needed by Xenocara manuals. X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Implement in-line equations, much needed by Xenocara manuals. Put the steering into the roff parser rather than into the mdoc parser such that it works for all macro languages and on both text and macro lines. Line breaks and blank characters generated before and after in-line equations are not perfect yet, but let's do one thing at a time. Modified Files: -------------- mdocml: TODO eqn.c libmandoc.h libroff.h mdoc.c roff.c Revision Data ------------- Index: eqn.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/eqn.c,v retrieving revision 1.53 retrieving revision 1.54 diff -Leqn.c -Leqn.c -u -p -r1.53 -r1.54 --- eqn.c +++ eqn.c @@ -588,6 +588,30 @@ eqn_box_makebinary(struct eqn_node *ep, } /* + * Parse the "delim" control statement. + */ +static void +eqn_delim(struct eqn_node *ep) +{ + const char *start; + size_t sz; + + if ((start = eqn_nextrawtok(ep, &sz)) == NULL) + mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse, + ep->eqn.ln, ep->eqn.pos, "delim"); + else if (strncmp(start, "off", 3) == 0) + ep->delim = 0; + else if (strncmp(start, "on", 2) == 0) { + if (ep->odelim && ep->cdelim) + ep->delim = 1; + } else if (start[1] != '\0') { + ep->odelim = start[0]; + ep->cdelim = start[1]; + ep->delim = 1; + } +} + +/* * Undefine a previously-defined string. */ static int @@ -698,6 +722,8 @@ this_tok: EQN_MSG(MANDOCERR_EQNEOF, ep); break; case (EQN_TOK_DELIM): + eqn_delim(ep); + break; case (EQN_TOK_GFONT): if (eqn_nextrawtok(ep, NULL) == NULL) mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse, Index: TODO =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/TODO,v retrieving revision 1.184 retrieving revision 1.185 diff -LTODO -LTODO -u -p -r1.184 -r1.185 --- TODO +++ TODO @@ -224,9 +224,6 @@ are mere guesses, and some may be wrong. --- missing eqn features ----------------------------------------------- -- delim - loc ** exist ** algo ** size * imp *** - - The "size" keyword is parsed, but ignored by the formatter. loc * exist * algo * size * imp * @@ -514,6 +511,9 @@ are mere guesses, and some may be wrong. is this useful? - mention /usr/share/misc/mdoc.template in mdoc(7)? + +- Is all the content from http://www.std.com/obi/BSD/doc/usd/28.tbl/tbl + covered in tbl(7)? ************************************************************************ * performance issues Index: mdoc.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.c,v retrieving revision 1.225 retrieving revision 1.226 diff -Lmdoc.c -Lmdoc.c -u -p -r1.225 -r1.226 --- mdoc.c +++ mdoc.c @@ -91,9 +91,6 @@ static struct mdoc_node *node_alloc(stru enum mdoct, enum mdoc_type); static int node_append(struct mdoc *, struct mdoc_node *); -#if 0 -static int mdoc_preptext(struct mdoc *, int, char *, int); -#endif static int mdoc_ptext(struct mdoc *, int, char *, int); static int mdoc_pmacro(struct mdoc *, int, char *, int); @@ -608,60 +605,6 @@ mdoc_node_relink(struct mdoc *mdoc, stru mdoc_node_unlink(mdoc, p); return(node_append(mdoc, p)); } - -#if 0 -/* - * 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 *mdoc, 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(mdoc->roff))) - if (NULL != (start = strchr(buf + offs, delim))) - *start++ = '\0'; - - /* Parse text as normal. */ - if ( ! mdoc_ptext(mdoc, 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(mdoc->roff, NULL, line, offs, buf); - - /* Process a finished equation? */ - if (roff_closeeqn(mdoc->roff)) - if ( ! mdoc_addeqn(mdoc, roff_eqn(mdoc->roff))) - return(0); - offs += (end - (buf + offs)); - } - - return(1); -} -#endif /* * Parse free-form text, that is, a line that does not begin with the Index: roff.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/roff.c,v retrieving revision 1.229 retrieving revision 1.230 diff -Lroff.c -Lroff.c -u -p -r1.229 -r1.230 --- roff.c +++ roff.c @@ -120,6 +120,7 @@ struct roff { struct eqn_node *last_eqn; /* last equation parsed */ struct eqn_node *first_eqn; /* first equation parsed */ struct eqn_node *eqn; /* current equation being parsed */ + int eqn_inline; /* current equation is inline */ int options; /* parse options */ int rstacksz; /* current size limit of rstack */ int rstackpos; /* position in rstack */ @@ -183,6 +184,8 @@ static enum rofferr roff_cond(ROFF_ARGS static enum rofferr roff_cond_text(ROFF_ARGS); static enum rofferr roff_cond_sub(ROFF_ARGS); static enum rofferr roff_ds(ROFF_ARGS); +static enum rofferr roff_eqndelim(struct roff *, + char **, size_t *, int); static int roff_evalcond(const char *, int *); static int roff_evalnum(const char *, int *, int *, int); static int roff_evalpar(const char *, int *, int *); @@ -724,10 +727,17 @@ roff_parseln(struct roff *r, int ln, cha enum rofferr e; int ppos, ctl; - /* - * Run the reserved-word filter only if we have some reserved - * words to fill in. - */ + /* Handle in-line equation delimiters. */ + + if (r->last_eqn != NULL && r->last_eqn->delim && + (r->eqn == NULL || r->eqn_inline)) { + e = roff_eqndelim(r, bufp, szp, pos); + if (e == ROFF_REPARSE) + return(e); + assert(e == ROFF_CONT); + } + + /* Expand some escape sequences. */ e = roff_res(r, bufp, szp, ln, pos); if (ROFF_IGN == e) @@ -1841,14 +1851,48 @@ roff_T_(ROFF_ARGS) return(ROFF_IGN); } -#if 0 -static int -roff_closeeqn(struct roff *r) +/* + * Handle in-line equation delimiters. + */ +static enum rofferr +roff_eqndelim(struct roff *r, char **bufp, size_t *szp, int pos) { + char *cp1, *cp2; - return(r->eqn && ROFF_EQN == eqn_end(&r->eqn) ? 1 : 0); + /* + * Outside equations, look for an opening delimiter. + * If we are inside an equation, we already know it is + * in-line, or this function wouldn't have been called; + * so look for a closing delimiter. + */ + + cp1 = *bufp + pos; + cp2 = strchr(cp1, r->eqn == NULL ? + r->last_eqn->odelim : r->last_eqn->cdelim); + if (cp2 == NULL) + return(ROFF_CONT); + + /* Found a delimiter; get rid of surrounding blanks. */ + + cp1 = cp2++; + while (cp2[0] == ' ') + cp2++; + while (cp1[-1] == ' ') + cp1--; + *cp1 = '\0'; + + /* Replace the delimiter with an equation macro. */ + + *szp = mandoc_asprintf(&cp1, "%s\n.E%c\n\\&%s", *bufp, + r->eqn == NULL ? 'Q' : 'N', cp2) + 1; + free(*bufp); + *bufp = cp1; + + /* Toggle the in-line state of the eqn subsystem. */ + + r->eqn_inline = r->eqn == NULL; + return(ROFF_REPARSE); } -#endif static void roff_openeqn(struct roff *r, const char *name, int line, @@ -1860,9 +1904,12 @@ roff_openeqn(struct roff *r, const char assert(NULL == r->eqn); e = eqn_alloc(name, offs, line, r->parse); - if (r->last_eqn) + if (r->last_eqn) { r->last_eqn->next = e; - else + e->delim = r->last_eqn->delim; + e->odelim = r->last_eqn->odelim; + e->cdelim = r->last_eqn->cdelim; + } else r->first_eqn = r->last_eqn = e; r->eqn = r->last_eqn = e; Index: libroff.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libroff.h,v retrieving revision 1.29 retrieving revision 1.30 diff -Llibroff.h -Llibroff.h -u -p -r1.29 -r1.30 --- libroff.h +++ libroff.h @@ -1,6 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons + * Copyright (c) 2014 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -43,16 +44,19 @@ struct tbl_node { }; struct eqn_node { - struct eqn_def *defs; - size_t defsz; - char *data; - size_t rew; - size_t cur; - size_t sz; - int gsize; - struct eqn eqn; - struct mparse *parse; - struct eqn_node *next; + struct eqn eqn; /* syntax tree of this equation */ + struct mparse *parse; /* main parser, for error reporting */ + struct eqn_node *next; /* singly linked list of equations */ + struct eqn_def *defs; /* array of definitions */ + char *data; /* source code of this equation */ + size_t defsz; /* number of definitions */ + size_t sz; /* length of the source code */ + size_t cur; /* parse point in the source code */ + size_t rew; /* beginning of the current token */ + int gsize; /* default point size */ + int delim; /* in-line delimiters enabled */ + char odelim; /* in-line opening delimiter */ + char cdelim; /* in-line closing delimiter */ }; struct eqn_def { Index: libmandoc.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/libmandoc.h,v retrieving revision 1.43 retrieving revision 1.44 diff -Llibmandoc.h -Llibmandoc.h -u -p -r1.43 -r1.44 --- libmandoc.h +++ libmandoc.h @@ -78,12 +78,6 @@ char *roff_strdup(const struct roff *, int roff_getcontrol(const struct roff *, const char *, int *); int roff_getformat(const struct roff *); -#if 0 -char roff_eqndelim(const struct roff *); -void roff_openeqn(struct roff *, const char *, - int, int, const char *); -int roff_closeeqn(struct roff *); -#endif const struct tbl_span *roff_span(const struct roff *); const struct eqn *roff_eqn(const struct roff *); -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv