source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Implement in-line equations, much needed by Xenocara manuals.
@ 2014-10-16  1:11 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2014-10-16  1:11 UTC (permalink / raw)
  To: source

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 <kristaps@bsd.lv>
+ * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
  *
  * 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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-10-16  1:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-16  1:11 mdocml: Implement in-line equations, much needed by Xenocara manuals schwarze

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).