2 * Copyright (c) 2014 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 1989 - 1992, 2002, 2004, 2007, 2008
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
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
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.
24 #include "eqn-config.h"
36 script_box(box
*, box
*, box
*);
38 int compute_metrics(int);
46 /* The idea is that the script should attach to the rightmost box
47 of a list. For example, given `2x sup 3', the superscript should
48 attach to `x' rather than `2x'. */
50 box
*make_script_box(box
*nuc
, box
*sub
, box
*sup
)
52 list_box
*b
= nuc
->to_list_box();
54 b
->list
.p
[b
->list
.len
-1] = make_script_box(b
->list
.p
[b
->list
.len
- 1],
60 return new script_box(nuc
, sub
, sup
);
63 script_box::script_box(box
*pp
, box
*qq
, box
*rr
)
64 : pointer_box(pp
), sub(qq
), sup(rr
)
68 script_box::~script_box()
74 int script_box::left_is_italic()
76 return p
->left_is_italic();
79 int script_box::compute_metrics(int style
)
81 int res
= p
->compute_metrics(style
);
82 p
->compute_subscript_kern();
83 printf(".nr " SIZE_FORMAT
" \\n[.ps]\n", uid
);
84 if (!(style
<= SCRIPT_STYLE
&& one_size_reduction_flag
))
86 printf(".nr " SMALL_SIZE_FORMAT
" \\n[.ps]\n", uid
);
88 sub
->compute_metrics(cramped_style(script_style(style
)));
90 sup
->compute_metrics(script_style(style
));
93 printf(".nr " SUP_RAISE_FORMAT
" 0\n", uid
);
94 printf(".nr " SUB_LOWER_FORMAT
" 0\n", uid
);
97 printf(".nr " SUP_RAISE_FORMAT
" \\n[" HEIGHT_FORMAT
"]-%dM>?0\n",
98 uid
, p
->uid
, sup_drop
);
99 printf(".nr " SUB_LOWER_FORMAT
" \\n[" DEPTH_FORMAT
"]+%dM\n",
100 uid
, p
->uid
, sub_drop
);
102 printf(".ps \\n[" SIZE_FORMAT
"]u\n", uid
);
106 printf(".nr " SUB_LOWER_FORMAT
" \\n[" SUB_LOWER_FORMAT
"]>?%dM>?(\\n["
107 HEIGHT_FORMAT
"]-(%dM*4/5))\n",
108 uid
, uid
, sub1
, sub
->uid
, x_height
);
114 if (style
== DISPLAY_STYLE
)
116 else if (style
& 1) // not cramped
120 printf(".nr " SUP_RAISE_FORMAT
" \\n[" SUP_RAISE_FORMAT
121 "]>?%dM>?(\\n[" DEPTH_FORMAT
"]+(%dM/4))\n",
122 uid
, uid
, pos
, sup
->uid
, x_height
);
125 printf(".nr " SUB_LOWER_FORMAT
" \\n[" SUB_LOWER_FORMAT
"]>?%dM\n",
128 printf(".nr " TEMP_REG
" \\n[" DEPTH_FORMAT
"]-\\n["
129 SUP_RAISE_FORMAT
"]+\\n[" HEIGHT_FORMAT
"]-\\n["
130 SUB_LOWER_FORMAT
"]+(4*%dM)\n",
131 sup
->uid
, uid
, sub
->uid
, uid
, default_rule_thickness
);
132 printf(".if \\n[" TEMP_REG
"] \\{");
133 printf(".nr " SUB_LOWER_FORMAT
" +\\n[" TEMP_REG
"]\n", uid
);
134 printf(".nr " TEMP_REG
" (%dM*4/5)-\\n[" SUP_RAISE_FORMAT
135 "]+\\n[" DEPTH_FORMAT
"]>?0\n",
136 x_height
, uid
, sup
->uid
);
137 printf(".nr " SUP_RAISE_FORMAT
" +\\n[" TEMP_REG
"]\n", uid
);
138 printf(".nr " SUB_LOWER_FORMAT
" -\\n[" TEMP_REG
"]\n", uid
);
142 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]", uid
, p
->uid
);
143 if (sub
!= 0 && sup
!= 0)
144 printf("+((\\n[" WIDTH_FORMAT
"]-\\n[" SUB_KERN_FORMAT
"]>?\\n["
145 WIDTH_FORMAT
"])+%dM)>?0\n",
146 sub
->uid
, p
->uid
, sup
->uid
, script_space
);
148 printf("+(\\n[" WIDTH_FORMAT
"]-\\n[" SUB_KERN_FORMAT
"]+%dM)>?0\n",
149 sub
->uid
, p
->uid
, script_space
);
151 printf("+(\\n[" WIDTH_FORMAT
"]+%dM)>?0\n", sup
->uid
, script_space
);
154 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]",
157 printf(">?(\\n[" SUP_RAISE_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
160 printf(">?(-\\n[" SUB_LOWER_FORMAT
"]+\\n[" HEIGHT_FORMAT
"])",
163 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]",
166 printf(">?(\\n[" SUB_LOWER_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
169 printf(">?(-\\n[" SUP_RAISE_FORMAT
"]+\\n[" DEPTH_FORMAT
"])",
175 void script_box::output()
177 if (output_format
== troff
) {
180 printf("\\Z" DELIMITER_CHAR
);
181 printf("\\v'-\\n[" SUP_RAISE_FORMAT
"]u'", uid
);
182 printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]u]", uid
);
184 printf("\\s[\\n[" SIZE_FORMAT
"]u]", uid
);
185 printf(DELIMITER_CHAR
);
188 printf("\\Z" DELIMITER_CHAR
);
189 printf("\\v'\\n[" SUB_LOWER_FORMAT
"]u'", uid
);
190 printf("\\s[\\n[" SMALL_SIZE_FORMAT
"]u]", uid
);
191 printf("\\h'-\\n[" SUB_KERN_FORMAT
"]u'", p
->uid
);
193 printf("\\s[\\n[" SIZE_FORMAT
"]u]", uid
);
194 printf(DELIMITER_CHAR
);
196 printf("\\h'\\n[" WIDTH_FORMAT
"]u-\\n[" WIDTH_FORMAT
"]u'",
199 else if (output_format
== mathml
) {
200 if (sup
!= 0 && sub
!= 0) {
205 printf("</msubsup>");
222 void script_box::hint(unsigned flags
)
224 p
->hint(flags
& ~HINT_NEXT_IS_ITALIC
);
227 void script_box::debug_print()
229 fprintf(stderr
, "{ ");
231 fprintf(stderr
, " }");
233 fprintf(stderr
, " sub { ");
235 fprintf(stderr
, " }");
238 fprintf(stderr
, " sup { ");
240 fprintf(stderr
, " }");
244 void script_box::check_tabs(int level
)
247 sup
->check_tabs(level
+ 1);
249 sub
->check_tabs(level
+ 1);
250 p
->check_tabs(level
);