diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2017-06-21 20:50:50 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2017-06-21 20:50:50 +0000 |
commit | 71437bd441b0bdd5a2c07c587dcdd303d04f9310 (patch) | |
tree | f05c6312ea191c33b52e5339fefc0db2269b40b5 /eqn.c | |
parent | b7aded9d3d9c8e14d502f76fdce6a33095650b2e (diff) | |
download | mandoc-71437bd441b0bdd5a2c07c587dcdd303d04f9310.tar.gz |
Outside explicit font context, give every letter its own box.
The formatters need this to correctly select fonts.
Missing feature reported by bentley@.
Diffstat (limited to 'eqn.c')
-rw-r--r-- | eqn.c | 59 |
1 files changed, 45 insertions, 14 deletions
@@ -1,4 +1,4 @@ -/* $Id$ */ +/* $OpenBSD: eqn.c,v 1.29 2017/06/21 20:47:46 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -20,6 +20,7 @@ #include <sys/types.h> #include <assert.h> +#include <ctype.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -718,8 +719,8 @@ static enum rofferr eqn_parse(struct eqn_node *ep, struct eqn_box *parent) { char sym[64]; - struct eqn_box *cur; - const char *start; + struct eqn_box *cur, *fontp, *nbox; + const char *cp, *cpn, *start; char *p; size_t sz; enum eqn_tok tok, subtok; @@ -1092,21 +1093,51 @@ this_tok: */ while (parent->args == parent->expectargs) parent = parent->parent; - if (tok == EQN_TOK_FUNC) { - for (cur = parent; cur != NULL; cur = cur->parent) - if (cur->font != EQNFONT_NONE) - break; - if (cur == NULL || cur->font != EQNFONT_ROMAN) { - parent = eqn_box_alloc(ep, parent); - parent->type = EQN_LISTONE; - parent->font = EQNFONT_ROMAN; - parent->expectargs = 1; - } + /* + * Wrap well-known function names in a roman box, + * unless they already are in roman context. + */ + for (fontp = parent; fontp != NULL; fontp = fontp->parent) + if (fontp->font != EQNFONT_NONE) + break; + if (tok == EQN_TOK_FUNC && + (fontp == NULL || fontp->font != EQNFONT_ROMAN)) { + parent = fontp = eqn_box_alloc(ep, parent); + parent->type = EQN_LISTONE; + parent->font = EQNFONT_ROMAN; + parent->expectargs = 1; } cur = eqn_box_alloc(ep, parent); cur->type = EQN_TEXT; cur->text = p; - + /* + * If not inside any explicit font context, + * give every letter its own box. + */ + if (fontp == NULL && *p != '\0') { + cp = p; + for (;;) { + cpn = cp + 1; + if (*cp == '\\') + mandoc_escape(&cpn, NULL, NULL); + if (*cpn == '\0') + break; + if (isalpha((unsigned char)*cp) == 0 && + isalpha((unsigned char)*cpn) == 0) { + cp = cpn; + continue; + } + nbox = eqn_box_alloc(ep, parent); + nbox->type = EQN_TEXT; + nbox->text = mandoc_strdup(cpn); + p = mandoc_strndup(cur->text, + cpn - cur->text); + free(cur->text); + cur->text = p; + cur = nbox; + cp = nbox->text; + } + } /* * Post-process list status. */ |