1*260e9a87SYuri Pankov /* $Id: eqn_term.c,v 1.8 2015/01/01 15:36:08 schwarze Exp $ */ 295c635efSGarrett D'Amore /* 395c635efSGarrett D'Amore * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4*260e9a87SYuri Pankov * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> 595c635efSGarrett D'Amore * 695c635efSGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any 795c635efSGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above 895c635efSGarrett D'Amore * copyright notice and this permission notice appear in all copies. 995c635efSGarrett D'Amore * 1095c635efSGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1195c635efSGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1295c635efSGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1395c635efSGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1495c635efSGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1595c635efSGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1695c635efSGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1795c635efSGarrett D'Amore */ 1895c635efSGarrett D'Amore #include "config.h" 19*260e9a87SYuri Pankov 20*260e9a87SYuri Pankov #include <sys/types.h> 2195c635efSGarrett D'Amore 2295c635efSGarrett D'Amore #include <assert.h> 2395c635efSGarrett D'Amore #include <stdio.h> 2495c635efSGarrett D'Amore #include <stdlib.h> 2595c635efSGarrett D'Amore #include <string.h> 2695c635efSGarrett D'Amore 2795c635efSGarrett D'Amore #include "mandoc.h" 2895c635efSGarrett D'Amore #include "out.h" 2995c635efSGarrett D'Amore #include "term.h" 3095c635efSGarrett D'Amore 3195c635efSGarrett D'Amore static const enum termfont fontmap[EQNFONT__MAX] = { 3295c635efSGarrett D'Amore TERMFONT_NONE, /* EQNFONT_NONE */ 3395c635efSGarrett D'Amore TERMFONT_NONE, /* EQNFONT_ROMAN */ 3495c635efSGarrett D'Amore TERMFONT_BOLD, /* EQNFONT_BOLD */ 3595c635efSGarrett D'Amore TERMFONT_BOLD, /* EQNFONT_FAT */ 3695c635efSGarrett D'Amore TERMFONT_UNDER /* EQNFONT_ITALIC */ 3795c635efSGarrett D'Amore }; 3895c635efSGarrett D'Amore 3995c635efSGarrett D'Amore static void eqn_box(struct termp *, const struct eqn_box *); 4095c635efSGarrett D'Amore 41*260e9a87SYuri Pankov 4295c635efSGarrett D'Amore void 4395c635efSGarrett D'Amore term_eqn(struct termp *p, const struct eqn *ep) 4495c635efSGarrett D'Amore { 4595c635efSGarrett D'Amore 4695c635efSGarrett D'Amore eqn_box(p, ep->root); 47*260e9a87SYuri Pankov p->flags &= ~TERMP_NOSPACE; 4895c635efSGarrett D'Amore } 4995c635efSGarrett D'Amore 5095c635efSGarrett D'Amore static void 5195c635efSGarrett D'Amore eqn_box(struct termp *p, const struct eqn_box *bp) 5295c635efSGarrett D'Amore { 53*260e9a87SYuri Pankov const struct eqn_box *child; 5495c635efSGarrett D'Amore 55*260e9a87SYuri Pankov if (bp->type == EQN_LIST || 56*260e9a87SYuri Pankov (bp->type == EQN_PILE && (bp->prev || bp->next)) || 57*260e9a87SYuri Pankov (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { 58*260e9a87SYuri Pankov if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) 59*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 60*260e9a87SYuri Pankov term_word(p, bp->left != NULL ? bp->left : "("); 61*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 62*260e9a87SYuri Pankov } 63*260e9a87SYuri Pankov if (bp->font != EQNFONT_NONE) 6495c635efSGarrett D'Amore term_fontpush(p, fontmap[(int)bp->font]); 6595c635efSGarrett D'Amore 66*260e9a87SYuri Pankov if (bp->text != NULL) 6795c635efSGarrett D'Amore term_word(p, bp->text); 6895c635efSGarrett D'Amore 69*260e9a87SYuri Pankov if (bp->pos == EQNPOS_SQRT) { 70*260e9a87SYuri Pankov term_word(p, "sqrt"); 71*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 7295c635efSGarrett D'Amore eqn_box(p, bp->first); 73*260e9a87SYuri Pankov } else if (bp->type == EQN_SUBEXPR) { 74*260e9a87SYuri Pankov child = bp->first; 75*260e9a87SYuri Pankov eqn_box(p, child); 76*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 77*260e9a87SYuri Pankov term_word(p, bp->pos == EQNPOS_OVER ? "/" : 78*260e9a87SYuri Pankov (bp->pos == EQNPOS_SUP || 79*260e9a87SYuri Pankov bp->pos == EQNPOS_TO) ? "^" : "_"); 80*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 81*260e9a87SYuri Pankov child = child->next; 82*260e9a87SYuri Pankov if (child != NULL) { 83*260e9a87SYuri Pankov eqn_box(p, child); 84*260e9a87SYuri Pankov if (bp->pos == EQNPOS_FROMTO || 85*260e9a87SYuri Pankov bp->pos == EQNPOS_SUBSUP) { 86*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 87*260e9a87SYuri Pankov term_word(p, "^"); 88*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 89*260e9a87SYuri Pankov child = child->next; 90*260e9a87SYuri Pankov if (child != NULL) 91*260e9a87SYuri Pankov eqn_box(p, child); 92*260e9a87SYuri Pankov } 93*260e9a87SYuri Pankov } 94*260e9a87SYuri Pankov } else { 95*260e9a87SYuri Pankov child = bp->first; 96*260e9a87SYuri Pankov if (bp->type == EQN_MATRIX && child->type == EQN_LIST) 97*260e9a87SYuri Pankov child = child->first; 98*260e9a87SYuri Pankov while (child != NULL) { 99*260e9a87SYuri Pankov eqn_box(p, 100*260e9a87SYuri Pankov bp->type == EQN_PILE && 101*260e9a87SYuri Pankov child->type == EQN_LIST && 102*260e9a87SYuri Pankov child->args == 1 ? 103*260e9a87SYuri Pankov child->first : child); 104*260e9a87SYuri Pankov child = child->next; 105*260e9a87SYuri Pankov } 106*260e9a87SYuri Pankov } 10795c635efSGarrett D'Amore 108*260e9a87SYuri Pankov if (bp->font != EQNFONT_NONE) 10995c635efSGarrett D'Amore term_fontpop(p); 110*260e9a87SYuri Pankov if (bp->type == EQN_LIST || 111*260e9a87SYuri Pankov (bp->type == EQN_PILE && (bp->prev || bp->next)) || 112*260e9a87SYuri Pankov (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { 113*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 114*260e9a87SYuri Pankov term_word(p, bp->right != NULL ? bp->right : ")"); 115*260e9a87SYuri Pankov if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL) 116*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 117*260e9a87SYuri Pankov } 11895c635efSGarrett D'Amore 119*260e9a87SYuri Pankov if (bp->top != NULL) { 120*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 121*260e9a87SYuri Pankov term_word(p, bp->top); 122*260e9a87SYuri Pankov } 123*260e9a87SYuri Pankov if (bp->bottom != NULL) { 124*260e9a87SYuri Pankov p->flags |= TERMP_NOSPACE; 125*260e9a87SYuri Pankov term_word(p, "_"); 126*260e9a87SYuri Pankov } 12795c635efSGarrett D'Amore } 128