From efaacbc5e152b979e7091412535d15dddd047469 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Sat, 23 Jul 2011 12:01:54 +0000 Subject: Add matrix support. Also remove "above" notion, as all elements in a list are delimited by their "aboveness" and it's superfluous. --- eqn.7 | 6 ++++-- eqn.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- eqn_term.c | 8 +------- mandoc.h | 9 ++++++--- tree.c | 41 ++++++++++++++++++----------------------- 5 files changed, 86 insertions(+), 37 deletions(-) diff --git a/eqn.7 b/eqn.7 index 21d7cc19..6ebd6b61 100644 --- a/eqn.7 +++ b/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.19 2011/07/23 09:47:25 kristaps Exp $ +.\" $Id: eqn.7,v 1.20 2011/07/23 12:01:54 kristaps Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons .\" @@ -72,16 +72,18 @@ box : text | \*qundef\*q text | box pos box | box mark + | \*qmatrix\*q \*q{\*q [col \*q{\*q list \*q}\*q ]* | pile \*q{\*q list \*q}\*q | font box | \*qsize\*q text box | \*qleft\*q text eqn [\*qright\*q text] +col : \*qlcol\*q | \*qrcol\*q | \*qccol\*q text : [^space\e\*q]+ | \e\*q.*\e\*q pile : \*qlpile\*q | \*qcpile\*q | \*qrpile\*q pos : \*qover\*q | \*qsup\*q | \*qsub\*q | \*qto\*q | \*qfrom\*q mark : \*qdot\*q | \*qdotdot\*q | \*qhat\*q | \*qtilde\*q | \*qvec\*q | \*qdyad\*q | \*qbar\*q | \*qunder\*q -font : \*qroman\*q | \*qitalic\*q | \*\*qbold\*q +font : \*qroman\*q | \*qitalic\*q | \*qbold\*q list : eqn | list \*qabove\*q eqn space : [\e^~ \et] diff --git a/eqn.c b/eqn.c index e43a0f2d..4a1a9a9a 100644 --- a/eqn.c +++ b/eqn.c @@ -1,4 +1,4 @@ -/* $Id: eqn.c,v 1.31 2011/07/23 09:47:25 kristaps Exp $ */ +/* $Id: eqn.c,v 1.32 2011/07/23 12:01:54 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -144,6 +144,7 @@ static int eqn_do_set(struct eqn_node *); static int eqn_do_undef(struct eqn_node *); static enum eqn_rest eqn_eqn(struct eqn_node *, struct eqn_box *); static enum eqn_rest eqn_list(struct eqn_node *, struct eqn_box *); +static enum eqn_rest eqn_matrix(struct eqn_node *, struct eqn_box *); static const char *eqn_nexttok(struct eqn_node *, size_t *); static const char *eqn_nextrawtok(struct eqn_node *, size_t *); static const char *eqn_next(struct eqn_node *, @@ -191,6 +192,9 @@ static const struct eqnstr eqnpiles[EQNPILE__MAX] = { { "cpile", 5 }, /* EQNPILE_CPILE */ { "rpile", 5 }, /* EQNPILE_RPILE */ { "lpile", 5 }, /* EQNPILE_LPILE */ + { "ccol", 4 }, /* EQNPILE_CCOL */ + { "rcol", 4 }, /* EQNPILE_RCOL */ + { "lcol", 4 }, /* EQNPILE_LCOL */ }; static const struct eqnsym eqnsyms[EQNSYM__MAX] = { @@ -347,6 +351,55 @@ eqn_eqn(struct eqn_node *ep, struct eqn_box *last) return(c); } +static enum eqn_rest +eqn_matrix(struct eqn_node *ep, struct eqn_box *last) +{ + struct eqn_box *bp; + const char *start; + size_t sz; + enum eqn_rest c; + + bp = eqn_box_alloc(ep, last); + bp->type = EQN_MATRIX; + + if (NULL == (start = eqn_nexttok(ep, &sz))) { + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(EQN_ERR); + } + if ( ! STRNEQ(start, sz, "{", 1)) { + EQN_MSG(MANDOCERR_EQNSYNT, ep); + return(EQN_ERR); + } + + while (EQN_OK == (c = eqn_box(ep, bp))) + switch (bp->last->pile) { + case (EQNPILE_LCOL): + /* FALLTHROUGH */ + case (EQNPILE_CCOL): + /* FALLTHROUGH */ + case (EQNPILE_RCOL): + continue; + default: + EQN_MSG(MANDOCERR_EQNSYNT, ep); + return(EQN_ERR); + }; + + if (EQN_DESCOPE != c) { + if (EQN_EOF == c) + EQN_MSG(MANDOCERR_EQNEOF, ep); + return(EQN_ERR); + } + + eqn_rewind(ep); + start = eqn_nexttok(ep, &sz); + assert(start); + if (STRNEQ(start, sz, "}", 1)) + return(EQN_OK); + + EQN_MSG(MANDOCERR_EQNBADSCOPE, ep); + return(EQN_ERR); +} + static enum eqn_rest eqn_list(struct eqn_node *ep, struct eqn_box *last) { @@ -373,7 +426,6 @@ eqn_list(struct eqn_node *ep, struct eqn_box *last) assert(start); if ( ! STRNEQ(start, sz, "above", 5)) break; - bp->last->above = 1; } if (EQN_DESCOPE != c) { @@ -442,6 +494,9 @@ eqn_box(struct eqn_node *ep, struct eqn_box *last) return(c); } + if (STRNEQ(start, sz, "matrix", 6)) + return(eqn_matrix(ep, last)); + if (STRNEQ(start, sz, "left", 4)) { if (NULL == (start = eqn_nexttok(ep, &sz))) { EQN_MSG(MANDOCERR_EQNEOF, ep); diff --git a/eqn_term.c b/eqn_term.c index d1e00bf6..84eda30c 100644 --- a/eqn_term.c +++ b/eqn_term.c @@ -1,4 +1,4 @@ -/* $Id: eqn_term.c,v 1.1 2011/07/22 10:50:46 kristaps Exp $ */ +/* $Id: eqn_term.c,v 1.2 2011/07/23 12:01:54 kristaps Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -61,8 +61,6 @@ static void eqn_box_pre(struct termp *p, const struct eqn_box *bp) { - if (EQN_LIST == bp->type) - term_word(p, "{"); if (bp->left) term_word(p, bp->left); } @@ -71,12 +69,8 @@ static void eqn_box_post(struct termp *p, const struct eqn_box *bp) { - if (EQN_LIST == bp->type) - term_word(p, "}"); if (bp->right) term_word(p, bp->right); - if (bp->above) - term_word(p, "|"); } static void diff --git a/mandoc.h b/mandoc.h index 7a2a9668..502777e0 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.91 2011/07/22 14:55:07 kristaps Exp $ */ +/* $Id: mandoc.h,v 1.92 2011/07/23 12:01:54 kristaps Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * @@ -285,7 +285,8 @@ enum eqn_boxt { EQN_ROOT, /* root of parse tree */ EQN_TEXT, /* text (number, variable, whatever) */ EQN_SUBEXPR, /* nested `eqn' subexpression */ - EQN_LIST /* list of subexpressions */ + EQN_LIST, /* subexpressions list */ + EQN_MATRIX /* matrix subexpression */ }; enum eqn_markt { @@ -324,6 +325,9 @@ enum eqn_pilet { EQNPILE_CPILE, EQNPILE_RPILE, EQNPILE_LPILE, + EQNPILE_CCOL, + EQNPILE_RCOL, + EQNPILE_LCOL, EQNPILE__MAX }; @@ -346,7 +350,6 @@ struct eqn_box { enum eqn_markt mark; /* a mark about the box */ enum eqn_fontt font; /* font of box */ enum eqn_pilet pile; /* equation piling */ - int above; /* next node is above */ }; /* diff --git a/tree.c b/tree.c index f8ab4977..9e7e7590 100644 --- a/tree.c +++ b/tree.c @@ -1,4 +1,4 @@ -/* $Id: tree.c,v 1.45 2011/07/22 09:57:04 kristaps Exp $ */ +/* $Id: tree.c,v 1.46 2011/07/23 12:01:54 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -263,46 +263,41 @@ static void print_box(const struct eqn_box *ep, int indent) { int i; + const char *t; if (NULL == ep) return; for (i = 0; i < indent; i++) putchar('\t'); + t = NULL; switch (ep->type) { case (EQN_ROOT): - printf("eqn-root(%d, %d, %d, %d)\n", - EQN_DEFSIZE == ep->size ? 0 : ep->size, - ep->pos, ep->font, ep->mark); - print_box(ep->first, indent + 1); + t = "eqn-root"; break; case (EQN_LIST): - printf("eqn-list(%d, %d, %d, %d, %d, %d, \"%s\", \"%s\")\n", - EQN_DEFSIZE == ep->size ? 0 : ep->size, - ep->pos, ep->font, ep->mark, - ep->pile, ep->above, - ep->left ? ep->left : "", - ep->right ? ep->right : ""); - print_box(ep->first, indent + 1); + t = "eqn-list"; break; case (EQN_SUBEXPR): - printf("eqn-subxpr(%d, %d, %d, %d, %d, %d, \"%s\", \"%s\")\n", - EQN_DEFSIZE == ep->size ? 0 : ep->size, - ep->pos, ep->font, ep->mark, - ep->pile, ep->above, - ep->left ? ep->left : "", - ep->right ? ep->right : ""); - print_box(ep->first, indent + 1); + t = "eqn-expr"; break; case (EQN_TEXT): - printf("eqn-text(%d, %d, %d, %d): [%s]\n", - EQN_DEFSIZE == ep->size ? 0 : ep->size, - ep->pos, ep->font, ep->mark, ep->text); + t = "eqn-text"; break; - default: + case (EQN_MATRIX): + t = "eqn-matrix"; break; } + assert(t); + printf("%s(%d, %d, %d, %d, %d, \"%s\", \"%s\") %s\n", + t, EQN_DEFSIZE == ep->size ? 0 : ep->size, + ep->pos, ep->font, ep->mark, ep->pile, + ep->left ? ep->left : "", + ep->right ? ep->right : "", + ep->text ? ep->text : ""); + + print_box(ep->first, indent + 1); print_box(ep->next, indent); } -- cgit v1.2.3-56-ge451