Line data Source code
1 : /* Copyright 1989-2024 Free Software Foundation, Inc. 2 : Written by James Clark (jjc@jclark.com) 3 : 4 : This file is part of groff, the GNU roff typesetting system. 5 : 6 : groff is free software; you can redistribute it and/or modify it under 7 : the terms of the GNU General Public License as published by the Free 8 : Software Foundation, either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY 12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 : for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 : 19 : #ifdef HAVE_CONFIG_H 20 : #include <config.h> 21 : #endif 22 : 23 : #include "eqn.h" 24 : #include "pbox.h" 25 : 26 : #define STRING_FORMAT PREFIX "str%d" 27 : 28 : #define SPECIAL_STRING "0s" 29 : #define SPECIAL_WIDTH_REG "0w" 30 : #define SPECIAL_HEIGHT_REG "0h" 31 : #define SPECIAL_DEPTH_REG "0d" 32 : #define SPECIAL_SUB_KERN_REG "0skern" 33 : #define SPECIAL_SKEW_REG "0skew" 34 : 35 : /* 36 : For example: 37 : 38 : .de Cl 39 : .ds 0s \Z'\\*[0s]'\v'\\n(0du'\D'l \\n(0wu -\\n(0hu-\\n(0du'\v'\\n(0hu' 40 : .. 41 : .EQ 42 : define cancel 'special Cl' 43 : .EN 44 : */ 45 : 46 : 47 : class special_box : public pointer_box { 48 : char *macro_name; 49 : public: 50 : special_box(char *, box *); 51 : ~special_box(); 52 : int compute_metrics(int); 53 : void compute_subscript_kern(); 54 : void compute_skew(); 55 : void output(); 56 : void debug_print(); 57 : }; 58 : 59 0 : box *make_special_box(char *s, box *p) 60 : { 61 0 : return new special_box(s, p); 62 : } 63 : 64 0 : special_box::special_box(char *s, box *pp) : pointer_box(pp), macro_name(s) 65 : { 66 0 : } 67 : 68 0 : special_box::~special_box() 69 : { 70 0 : delete[] macro_name; 71 0 : } 72 : 73 0 : int special_box::compute_metrics(int style) 74 : { 75 0 : int r = p->compute_metrics(style); 76 0 : p->compute_subscript_kern(); 77 0 : p->compute_skew(); 78 0 : printf(".ds " SPECIAL_STRING " \""); 79 0 : p->output(); 80 0 : printf("\n"); 81 0 : printf(".nr " SPECIAL_WIDTH_REG " 0\\n[" WIDTH_FORMAT "]\n", p->uid); 82 0 : printf(".nr " SPECIAL_HEIGHT_REG " \\n[" HEIGHT_FORMAT "]\n", p->uid); 83 0 : printf(".nr " SPECIAL_DEPTH_REG " \\n[" DEPTH_FORMAT "]\n", p->uid); 84 0 : printf(".nr " SPECIAL_SUB_KERN_REG " \\n[" SUB_KERN_FORMAT "]\n", p->uid); 85 0 : printf(".nr " SPECIAL_SKEW_REG " 0\\n[" SKEW_FORMAT "]\n", p->uid); 86 0 : printf(".%s\n", macro_name); 87 0 : printf(".rn " SPECIAL_STRING " " STRING_FORMAT "\n", uid); 88 0 : printf(".nr " WIDTH_FORMAT " 0\\n[" SPECIAL_WIDTH_REG "]\n", uid); 89 0 : printf(".nr " HEIGHT_FORMAT " 0>?\\n[" SPECIAL_HEIGHT_REG "]\n", uid); 90 0 : printf(".nr " DEPTH_FORMAT " 0>?\\n[" SPECIAL_DEPTH_REG "]\n", uid); 91 0 : printf(".nr " SUB_KERN_FORMAT " 0>?\\n[" SPECIAL_SUB_KERN_REG "]\n", uid); 92 0 : printf(".nr " SKEW_FORMAT " 0\\n[" SPECIAL_SKEW_REG "]\n", uid); 93 : // User will have to change MARK_REG if appropriate. 94 0 : return r; 95 : } 96 : 97 0 : void special_box::compute_subscript_kern() 98 : { 99 : // Already computed in compute_metrics(), so do nothing. 100 0 : } 101 : 102 0 : void special_box::compute_skew() 103 : { 104 : // Already computed in compute_metrics(), so do nothing. 105 0 : } 106 : 107 0 : void special_box::output() 108 : { 109 0 : if (output_format == troff) 110 0 : printf("\\*[" STRING_FORMAT "]", uid); 111 0 : else if (output_format == mathml) 112 0 : printf("<merror>eqn specials cannot be expressed in MathML</merror>"); 113 0 : } 114 : 115 0 : void special_box::debug_print() 116 : { 117 0 : fprintf(stderr, "special %s { ", macro_name); 118 0 : p->debug_print(); 119 0 : fprintf(stderr, " }"); 120 0 : } 121 : 122 : // Local Variables: 123 : // fill-column: 72 124 : // mode: C++ 125 : // End: 126 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: