1
4
5# include "luametatex.h"
6
7
32
33halfword tex_aux_scan_rule_spec(rule_types type, halfword code)
34{
35
36 halfword rule = tex_new_rule_node((quarterword) code);
37 halfword attr = node_attr(rule);
38 if (code == strut_rule_code) {
39 rule_width(rule) = 0;
40 switch (type) {
41 case h_rule_type:
42 rule_options(rule) |= rule_option_horizontal;
43 break;
44 case v_rule_type:
45 rule_options(rule) |= rule_option_vertical;
46 break;
47 default:
48 break;
49 }
50 } else {
51 switch (type) {
52 case h_rule_type:
53 rule_height(rule) = default_rule;
54 rule_depth(rule) = 0;
55 rule_options(rule) |= rule_option_horizontal;
56 break;
57 case v_rule_type:
58 rule_options(rule) |= rule_option_vertical;
59
60 case m_rule_type:
61 rule_width(rule) = default_rule;
62 break;
63 }
64 }
65 while (1) {
66 switch (tex_scan_character("awhdpxylrtbcfoAWHDPXYLRTBCFO", 0, 1, 0)) {
67 case 0:
68 goto DONE;
69 case 'a': case 'A':
70 if (tex_scan_mandate_keyword("attr", 1)) {
71 attr = tex_scan_attribute(attr);
72 }
73 break;
74 case 'w': case 'W':
75 if (tex_scan_mandate_keyword("width", 1)) {
76 rule_width(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
77 }
78 break;
79 case 'h': case 'H':
80 if (tex_scan_mandate_keyword("height", 1)) {
81 rule_height(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
82 }
83 break;
84 case 'd': case 'D':
85
86
87
88 switch (tex_scan_character("eiEI", 0, 0, 0)) {
89 case 'e': case 'E':
90 if (tex_scan_mandate_keyword("depth", 2)) {
91 rule_depth(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
92 }
93 break;
94 case 'i': case 'I':
95 if (tex_scan_mandate_keyword("discardable", 2)) {
96 rule_options(rule) |= rule_option_discardable;
97 }
98 break;
99 default:
100 tex_aux_show_keyword_error("depth|discardable");
101 goto DONE;
102 }
103 break;
104 case 'p': case 'P':
105 if (tex_scan_mandate_keyword("pair", 1)) {
106 rule_height(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
107 rule_depth(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
108 }
109 break;
110 case 'l': case 'L':
111 if (code != virtual_rule_code) {
112 if (tex_scan_mandate_keyword("left", 1)) {
113 rule_left(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
114 }
115 } else {
116 goto DONE;
117 }
118 break;
119 case 'r': case 'R':
120 if (code != virtual_rule_code) {
121 switch (tex_scan_character("uiUI", 0, 0, 0)) {
122 case 'u': case 'U':
123 if (tex_scan_mandate_keyword("running", 2)) {
124 rule_width(rule) = null_flag;
125 rule_height(rule) = null_flag;
126 rule_depth(rule) = null_flag;
127 }
128 break;
129 case 'i': case 'I':
130 if (tex_scan_mandate_keyword("right", 2)) {
131 rule_right(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
132 }
133 break;
134 default:
135 tex_aux_show_keyword_error("right|running");
136 goto DONE;
137 }
138 } else {
139 if (tex_scan_mandate_keyword("running", 1)) {
140 tex_set_rule_font(rule, tex_scan_font_identifier(NULL));
141 }
142 }
143 break;
144 case 't': case 'T':
145 if (code != virtual_rule_code) {
146 if (tex_scan_mandate_keyword("top", 1)) {
147 rule_left(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
148 }
149 break;
150 } else {
151 goto DONE;
152 }
153 case 'b': case 'B':
154 if (code != virtual_rule_code) {
155 if (tex_scan_mandate_keyword("bottom", 1)) {
156 rule_right(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
157 }
158 break;
159 } else {
160 goto DONE;
161 }
162 case 'x': case 'X':
163 if (tex_scan_mandate_keyword("xoffset", 1)) {
164 rule_x_offset(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
165 }
166 break;
167 case 'y': case 'Y':
168 if (tex_scan_mandate_keyword("yoffset", 1)) {
169 rule_y_offset(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
170 }
171 break;
172 case 'f': case 'F':
173 if (code != virtual_rule_code) {
174 switch (tex_scan_character("aoAO", 0, 0, 0)) {
175 case 'o': case 'O':
176 if (tex_scan_mandate_keyword("font", 2)) {
177 tex_set_rule_font(rule, tex_scan_font_identifier(NULL));
178 }
179 break;
180 case 'a': case 'A':
181 if (tex_scan_mandate_keyword("fam", 2)) {
182 tex_set_rule_family(rule, tex_scan_math_family_number());
183 }
184 break;
185 default:
186 tex_aux_show_keyword_error("font|fam");
187 goto DONE;
188 }
189 break;
190 } else {
191 goto DONE;
192 }
193 case 'o': case 'O':
194 if (code == normal_rule_code) {
195 switch (tex_scan_character("nfNF", 0, 0, 0)) {
196 case 'n': case 'N':
197 rule_line_on(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
198 break;
199 case 'f': case 'F':
200 if (tex_scan_mandate_keyword("off", 2)) {
201 rule_line_off(rule) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
202 }
203 break;
204 default:
205 tex_aux_show_keyword_error("on|off");
206 goto DONE;
207 }
208 break;
209 } else {
210 goto DONE;
211 }
212 case 'c': case 'C':
213 if (code == strut_rule_code) {
214 if (tex_scan_mandate_keyword("char", 1)) {
215 rule_strut_character(rule) = tex_scan_char_number(0);
216 }
217 break;
218 } else {
219 goto DONE;
220 }
221 default:
222 goto DONE;
223 }
224 }
225 DONE:
226
227 if (attr) {
228
229 tex_attach_attribute_list_attribute(rule, attr);
230 }
231 switch (code) {
232 case strut_rule_code:
233 if (type == v_rule_type) {
234 tex_aux_check_text_strut_rule(rule, text_style);
235 }
236 break;
237 case virtual_rule_code:
238 rule_virtual_width(rule) = rule_width(rule);
239 rule_virtual_height(rule) = rule_height(rule);
240 rule_virtual_depth(rule) = rule_depth(rule);
241 rule_width(rule) = 0;
242 rule_height(rule) = 0;
243 rule_depth(rule) = 0;
244 break;
245 }
246 if (type == h_rule_type) {
247 if (rule_width(rule) == null_flag) {
248 rule_options(rule) |= rule_option_running;
249 }
250 } else {
251 if (rule_height(rule) == null_flag && rule_width(rule) == null_flag) {
252 rule_options(rule) |= rule_option_running;
253 }
254 }
255 return rule;
256}
257
258void tex_aux_run_vrule(void)
259{
260 tex_tail_append(tex_aux_scan_rule_spec(v_rule_type, cur_chr));
261 cur_list.space_factor = default_space_factor;
262}
263
264void tex_aux_run_hrule(void)
265{
266 tex_tail_append(tex_aux_scan_rule_spec(h_rule_type, cur_chr));
267 cur_list.prev_depth = ignore_depth_criterion_par;
268}
269
270void tex_aux_run_mrule(void)
271{
272 tex_tail_append(tex_aux_scan_rule_spec(m_rule_type, cur_chr));
273}
274
275void tex_aux_check_math_strut_rule(halfword rule, halfword style)
276{
277 if (node_subtype(rule) == strut_rule_subtype) {
278 scaled ht = rule_height(rule);
279 scaled dp = rule_depth(rule);
280 if (ht == null_flag || dp == null_flag) {
281 halfword fnt = tex_get_rule_font(rule, style);
282 halfword chr = rule_strut_character(rule);
283 if (fnt > 0 && chr && tex_char_exists(fnt, chr)) {
284 if (ht == null_flag) {
285 ht = tex_math_font_char_ht(fnt, chr, style);
286 }
287 if (dp == null_flag) {
288 dp = tex_math_font_char_dp(fnt, chr, style);
289 }
290 } else {
291 if (ht == null_flag) {
292 ht = tex_get_math_y_parameter(style, math_parameter_rule_height);
293 }
294 if (dp == null_flag) {
295 dp = tex_get_math_y_parameter(style, math_parameter_rule_depth);
296 }
297 }
298 rule_height(rule) = ht;
299 rule_depth(rule) = dp;
300 }
301 }
302}
303
304void tex_aux_check_text_strut_rule(halfword rule, halfword style)
305{
306 if (node_subtype(rule) == strut_rule_subtype) {
307 scaled ht = rule_height(rule);
308 scaled dp = rule_depth(rule);
309 if (ht == null_flag || dp == null_flag) {
310 halfword fnt = tex_get_rule_font(rule, style);
311 halfword chr = rule_strut_character(rule);
312 if (fnt > 0 && chr && tex_char_exists(fnt, chr)) {
313 scaledwhd whd = tex_char_whd_from_font(fnt, chr);
314 if (ht == null_flag) {
315 rule_height(rule) = whd.ht;
316 }
317 if (dp == null_flag) {
318 rule_depth(rule) = whd.dp;
319 }
320 }
321 }
322 }
323}
324
325halfword tex_get_rule_font(halfword n, halfword style)
326{
327 if (node_subtype(n) != virtual_rule_subtype) {
328 halfword fnt = rule_strut_font(n);
329 if (fnt >= rule_font_fam_offset) {
330 halfword fam = fnt - rule_font_fam_offset;
331 if (fam_par_in_range(fam)) {
332 fnt = tex_fam_fnt(fam, tex_size_of_style(style));
333 }
334 }
335 if (fnt < 0 || fnt >= max_n_of_fonts) {
336 return null_font;
337 } else {
338 return fnt;
339 }
340 } else {
341 return null_font;
342 }
343}
344
345halfword tex_get_rule_family(halfword n)
346{
347 if (node_subtype(n) != virtual_rule_subtype) {
348 halfword fnt = rule_strut_font(n);
349 if (fnt >= rule_font_fam_offset) {
350 halfword fam = fnt - rule_font_fam_offset;
351 if (fam_par_in_range(fam)) {
352 return fam;
353 }
354 }
355 }
356 return 0;
357}
358
359void tex_set_rule_font(halfword n, halfword fnt)
360{
361 if (node_subtype(n) != virtual_rule_subtype) {
362 if (fnt < 0 || fnt >= rule_font_fam_offset) {
363 rule_strut_font(n) = 0;
364 } else {
365 rule_strut_font(n) = fnt;
366 }
367 }
368}
369
370void tex_set_rule_family(halfword n, halfword fam)
371{
372 if (node_subtype(n) != virtual_rule_subtype) {
373 if (fam < 0 || fam >= max_n_of_math_families) {
374 rule_strut_font(n) = rule_font_fam_offset;
375 } else {
376 rule_strut_font(n) = rule_font_fam_offset + fam;
377 }
378 }
379}
380
381halfword tex_get_rule_left(halfword n)
382{
383 return node_subtype(n) == virtual_rule_subtype ? 0 : rule_left(n);
384}
385
386halfword tex_get_rule_right(halfword n)
387{
388 return node_subtype(n) == virtual_rule_subtype ? 0 : rule_right(n);
389}
390
391void tex_set_rule_left(halfword n, halfword value)
392{
393 if (node_subtype(n) != virtual_rule_subtype) {
394 rule_left(n) = value;
395 }
396}
397
398void tex_set_rule_right(halfword n, halfword value)
399{
400 if (node_subtype(n) != virtual_rule_subtype) {
401 rule_right(n) = value;
402 }
403}
404
405halfword tex_get_rule_on(halfword n)
406{
407 return node_subtype(n) == normal_rule_subtype ? rule_line_on(n) : 0;
408}
409
410halfword tex_get_rule_off(halfword n)
411{
412 return node_subtype(n) == normal_rule_subtype ? rule_line_off(n) : 0;
413}
414
415void tex_set_rule_on(halfword n, halfword value)
416{
417 if (node_subtype(n) == normal_rule_subtype) {
418 rule_line_on(n) = value;
419 }
420}
421
422void tex_set_rule_off(halfword n, halfword value)
423{
424 if (node_subtype(n) == normal_rule_subtype) {
425 rule_line_off(n) = value;
426 }
427}
428
429
430 |