Adapt src/pre-eqn (src/preproc/eqn)
[s-roff.git] / src / pre-eqn / limit.cpp
blob1ee7e77e1d2185fdfd9138fb8c0aa5167a05698b
1 /*@
2 * Copyright (c) 2014 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 1989 - 1992, 2002, 2007
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * groff is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2, or (at your option) any later
11 * version.
13 * groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with groff; see the file COPYING. If not, write to the Free Software
20 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "config.h"
24 #include "eqn-config.h"
26 #include "eqn.h"
27 #include "pbox.h"
29 class limit_box
30 : public box
32 box *p;
33 box *from;
34 box *to;
36 public:
37 limit_box(box *, box *, box *);
38 ~limit_box();
39 int compute_metrics(int);
40 void output();
41 void debug_print();
42 void check_tabs(int);
45 box *make_limit_box(box *pp, box *qq, box *rr)
47 return new limit_box(pp, qq, rr);
50 limit_box::limit_box(box *pp, box *qq, box *rr)
51 : p(pp), from(qq), to(rr)
53 spacing_type = p->spacing_type;
56 limit_box::~limit_box()
58 delete p;
59 delete from;
60 delete to;
63 int limit_box::compute_metrics(int style)
65 printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
66 if (!(style <= SCRIPT_STYLE && one_size_reduction_flag))
67 set_script_size();
68 printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
69 int res = 0;
70 int mark_uid = -1;
71 if (from != 0) {
72 res = from->compute_metrics(cramped_style(script_style(style)));
73 if (res)
74 mark_uid = from->uid;
76 if (to != 0) {
77 int r = to->compute_metrics(script_style(style));
78 if (res && r)
79 error("multiple marks and lineups");
80 else {
81 mark_uid = to->uid;
82 res = r;
85 printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
86 int r = p->compute_metrics(style);
87 p->compute_subscript_kern();
88 if (res && r)
89 error("multiple marks and lineups");
90 else {
91 mark_uid = p->uid;
92 res = r;
94 printf(".nr " LEFT_WIDTH_FORMAT " "
95 "0\\n[" WIDTH_FORMAT "]",
96 uid, p->uid);
97 if (from != 0)
98 printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
99 p->uid, from->uid);
100 if (to != 0)
101 printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
102 p->uid, to->uid);
103 printf("/2\n");
104 printf(".nr " WIDTH_FORMAT " "
105 "0\\n[" WIDTH_FORMAT "]",
106 uid, p->uid);
107 if (from != 0)
108 printf(">?(-\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
109 p->uid, from->uid);
110 if (to != 0)
111 printf(">?(\\n[" SUB_KERN_FORMAT "]+\\n[" WIDTH_FORMAT "])",
112 p->uid, to->uid);
113 printf("/2+\\n[" LEFT_WIDTH_FORMAT "]\n", uid);
114 printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]", uid, p->uid);
115 if (to != 0)
116 printf(">?\\n[" WIDTH_FORMAT "]", to->uid);
117 if (from != 0)
118 printf(">?\\n[" WIDTH_FORMAT "]", from->uid);
119 printf("\n");
120 if (res)
121 printf(".nr " MARK_REG " +(\\n[" LEFT_WIDTH_FORMAT "]"
122 "-(\\n[" WIDTH_FORMAT "]/2))\n",
123 uid, mark_uid);
124 if (to != 0) {
125 printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT
126 "]>?%dM+\\n[" HEIGHT_FORMAT "]\n",
127 uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid);
128 printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
129 HEIGHT_FORMAT "]+%dM\n",
130 uid, uid, to->uid, big_op_spacing5);
132 else
133 printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
134 if (from != 0) {
135 printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT
136 "]>?%dM+\\n[" DEPTH_FORMAT "]\n",
137 uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid);
138 printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
139 DEPTH_FORMAT "]+%dM\n",
140 uid, uid, from->uid, big_op_spacing5);
142 else
143 printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
144 return res;
147 void limit_box::output()
149 if (output_format == troff) {
150 printf("\\s[\\n[" SMALL_SIZE_FORMAT "]u]", uid);
151 if (to != 0) {
152 printf("\\Z" DELIMITER_CHAR);
153 printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
154 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
155 "+(-\\n[" WIDTH_FORMAT "]u+\\n[" SUB_KERN_FORMAT "]u/2u)'",
156 uid, to->uid, p->uid);
157 to->output();
158 printf(DELIMITER_CHAR);
160 if (from != 0) {
161 printf("\\Z" DELIMITER_CHAR);
162 printf("\\v'\\n[" SUB_LOWER_FORMAT "]u'", uid);
163 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
164 "+(-\\n[" SUB_KERN_FORMAT "]u-\\n[" WIDTH_FORMAT "]u/2u)'",
165 uid, p->uid, from->uid);
166 from->output();
167 printf(DELIMITER_CHAR);
169 printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
170 printf("\\Z" DELIMITER_CHAR);
171 printf("\\h'\\n[" LEFT_WIDTH_FORMAT "]u"
172 "-(\\n[" WIDTH_FORMAT "]u/2u)'",
173 uid, p->uid);
174 p->output();
175 printf(DELIMITER_CHAR);
176 printf("\\h'\\n[" WIDTH_FORMAT "]u'", uid);
178 else if (output_format == mathml) {
179 if (from != 0 && to != 0) {
180 printf("<munderover>");
181 p->output();
182 from->output();
183 to->output();
184 printf("</munderover>");
186 else if (from != 0) {
187 printf("<munder>");
188 p->output();
189 from->output();
190 printf("</munder>");
192 else if (to != 0) {
193 printf("<mover>");
194 p->output();
195 to->output();
196 printf("</mover>");
201 void limit_box::debug_print()
203 fprintf(stderr, "{ ");
204 p->debug_print();
205 fprintf(stderr, " }");
206 if (from) {
207 fprintf(stderr, " from { ");
208 from->debug_print();
209 fprintf(stderr, " }");
211 if (to) {
212 fprintf(stderr, " to { ");
213 to->debug_print();
214 fprintf(stderr, " }");
218 void limit_box::check_tabs(int level)
220 if (to)
221 to->check_tabs(level + 1);
222 if (from)
223 from->check_tabs(level + 1);
224 p->check_tabs(level + 1);
227 // s-it2-mode