summaryrefslogtreecommitdiffstats
path: root/eqn.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-06-21 20:50:50 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-06-21 20:50:50 +0000
commit71437bd441b0bdd5a2c07c587dcdd303d04f9310 (patch)
treef05c6312ea191c33b52e5339fefc0db2269b40b5 /eqn.c
parentb7aded9d3d9c8e14d502f76fdce6a33095650b2e (diff)
downloadmandoc-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.c59
1 files changed, 45 insertions, 14 deletions
diff --git a/eqn.c b/eqn.c
index e598ebcd..915a9715 100644
--- a/eqn.c
+++ b/eqn.c
@@ -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.
*/