1
4
5# include "luametatex.h"
6
7
19
20
114
115math_state_info lmt_math_state = {
116 .size = 0,
117 .level = 0,
118 .par_head = NULL,
119 .fam_head = NULL,
120 .last_left = 0,
121 .last_right = 0,
122 .last_atom = 0,
123 .scale = scaling_factor,
124 .single = 0,
125 .padding = 0,
126};
127
128
129
130typedef enum saved_math_entries {
131 saved_math_direction_entry = 0,
132 saved_math_n_of_records = 1,
133} saved_math_entries;
134
135# define saved_math_direction saved_value_1(saved_math_direction_entry)
136
137static inline void saved_math_initialize(void)
138{
139 saved_type(0) = saved_record_0;
140 saved_record(0) = math_save_type;
141}
142
143int tex_show_math_record(void)
144{
145 tex_print_str("math ");
146 switch (saved_type(0)) {
147 case saved_record_0:
148 tex_print_format("direction %i", saved_value_1(0));
149 break;
150 default:
151 return 0;
152 }
153 return 1;
154}
155
156
157
158typedef enum saved_equation_number_entries {
159 saved_equation_number_location_entry = 0,
160 saved_equation_number_n_of_records = 1,
161} saved_equation_number_entries;
162
163# define saved_equation_number_location saved_value_1(saved_equation_number_location_entry)
164
165static inline void saved_equation_number_initialize(void)
166{
167 saved_type(0) = saved_record_0;
168 saved_record(0) = number_save_type;
169}
170
171void tex_show_math_number_group(void)
172{
173 tex_print_cmd_chr(equation_number_cmd, saved_equation_number_location);
174}
175
176int tex_show_math_number_record(void)
177{
178 tex_print_str("equation number ");
179 switch (saved_type(0)) {
180 case saved_record_0:
181 tex_print_format("location %i", saved_value_1(0));
182 break;
183 default:
184 return 0;
185 }
186 return 1;
187}
188
189
190
191typedef enum saved_choice_entries {
192 saved_choice_count_entry = 0,
193 saved_choice_n_of_records = 1,
194} saved_choice_entries;
195
196# define saved_choice_count saved_value_1(saved_choice_count_entry)
197
198static inline void saved_choice_initialize(void)
199{
200 saved_type(0) = saved_record_0;
201 saved_record(0) = choice_save_type;
202}
203
204static inline int saved_choice_current_component(void)
205{
206 return saved_type(saved_choice_count_entry - saved_choice_n_of_records) == saved_record_0
207 ? saved_value_1(saved_choice_count_entry - saved_choice_n_of_records) : -1 ;
208}
209
210static inline void saved_choice_update_component(void)
211{
212 saved_value_1(saved_choice_count_entry - saved_choice_n_of_records) += 1;
213}
214
215void tex_show_math_choice_group(void)
216{
217 tex_print_str_esc("mathchoice");
218 tex_aux_show_group_count(saved_choice_count);
219}
220
221int tex_show_math_choice_record(void)
222{
223 tex_print_str("choice ");
224 switch (saved_type(0)) {
225 case saved_record_0:
226 tex_print_format("count %i", saved_value_1(0));
227 break;
228 default:
229 return 0;
230 }
231 return 1;
232}
233
234
235
236typedef enum saved_fraction_entries {
237 saved_fraction_variant_entry = 0,
238 saved_fraction_userstyle_entry = 0,
239 saved_fraction_autostyle_entry = 0,
240 saved_fraction_n_of_records = 1,
241} saved_fraction_entries;
242
243# define saved_fraction_variant saved_value_1(saved_fraction_variant_entry)
244# define saved_fraction_userstyle saved_value_2(saved_fraction_userstyle_entry)
245# define saved_fraction_autostyle saved_value_3(saved_fraction_autostyle_entry)
246
247static inline void saved_fraction_initialize(void)
248{
249 saved_type(0) = saved_record_0;
250 saved_record(0) = fraction_save_type;
251}
252
253static inline int saved_fraction_current_component(void)
254{
255 return saved_type(saved_fraction_variant_entry - saved_fraction_n_of_records) == saved_record_0
256 ? saved_value_1(saved_fraction_variant_entry - saved_fraction_n_of_records) : -1 ;
257}
258
259static inline void saved_fraction_update_component(void)
260{
261 saved_value_1(saved_fraction_variant_entry - saved_fraction_n_of_records) += 1;
262}
263
264static inline int saved_fraction_current_userstyle(void)
265{
266 return saved_value_2(saved_fraction_userstyle_entry - saved_fraction_n_of_records);
267}
268
269static inline int saved_fraction_current_autostyle(void)
270{
271 return saved_value_3(saved_fraction_autostyle_entry - saved_fraction_n_of_records);
272}
273
274void tex_show_math_fraction_group(void)
275{
276 tex_print_str_esc("fraction");
277 tex_aux_show_group_count(saved_fraction_variant);
278}
279
280int tex_show_math_fraction_record(void)
281{
282 tex_print_str("fraction ");
283 switch (saved_type(0)) {
284 case saved_record_0:
285 tex_print_format("variant %i, userstyle %i, autostyle %i", saved_value_1(0), saved_value_2(0), saved_value_3(0));
286 break;
287 default:
288 return 0;
289 }
290 return 1;
291}
292
293
294
295typedef enum saved_radical_entries {
296 saved_radical_degree_done_entry = 0,
297 saved_radical_style_entry = 0,
298 saved_radical_n_of_records = 1,
299} saved_radical_entries;
300
301# define saved_radical_degree_done saved_value_1(saved_radical_degree_done_entry)
302# define saved_radical_style saved_value_2(saved_radical_style_entry)
303
304static inline void saved_radical_initialize(void)
305{
306 saved_type(0) = saved_record_0;
307 saved_record(0) = radical_save_type;
308}
309
310static inline int saved_radical_current_component(void)
311{
312 return saved_type(saved_radical_degree_done_entry - saved_radical_n_of_records) == saved_record_0
313 ? saved_value_1(saved_radical_degree_done_entry - saved_radical_n_of_records) : -1 ;
314}
315
316static inline int saved_radical_current_style(void)
317{
318 return saved_value_2(saved_radical_style_entry - saved_radical_n_of_records);
319}
320
321static inline void saved_radical_update_component(void)
322{
323 saved_value_1(saved_radical_degree_done_entry - saved_radical_n_of_records) += 1;
324}
325
326void tex_show_math_radical_group(void)
327{
328 tex_print_str_esc("radical");
329 tex_aux_show_group_count(saved_radical_degree_done);
330}
331
332int tex_show_math_radical_record(void)
333{
334 tex_print_str("radical ");
335 switch (saved_type(0)) {
336 case saved_record_0:
337 tex_print_format("degree %i, style %i", saved_value_1(0), saved_value_2(0));
338 break;
339 default:
340 return 0;
341 }
342 return 1;
343}
344
345
346
347typedef enum saved_operator_entries {
348 saved_operator_variant_entry = 0,
349 saved_operator_n_of_records = 1,
350} saved_operator_entries;
351
352# define saved_operator_variant saved_value_1(saved_operator_variant_entry)
353
354static inline void saved_operator_initialize(void)
355{
356 saved_type(0) = saved_record_0;
357 saved_record(0) = operator_save_type;
358}
359
360static inline int saved_operator_current_component(void)
361{
362 return saved_type(saved_operator_variant_entry - saved_operator_n_of_records) == saved_record_0
363 ? saved_value_1(saved_operator_variant_entry - saved_operator_n_of_records) : -1 ;
364}
365
366static inline void saved_operator_update_component(void)
367{
368 saved_value_1(saved_operator_variant_entry - saved_operator_n_of_records) += 1;
369}
370
371void tex_show_math_operator_group(void)
372{
373 tex_print_str_esc("operator");
374 tex_aux_show_group_count(saved_operator_variant);
375}
376
377int tex_show_math_operator_record(void)
378{
379 tex_print_str("operator ");
380 switch (saved_type(0)) {
381 case saved_record_0:
382 tex_print_format("variant %i", saved_value_1(0));
383 break;
384 default:
385 return 0;
386 }
387 return 1;
388}
389
390
391
392typedef enum saved_math_group_entries {
393 saved_math_group_pointer_entry = 0,
394 saved_math_group_all_class_entry = 0,
395 saved_math_group_n_of_records = 1,
396} saved_math_group_entries;
397
398# define saved_math_group_pointer saved_value_1(saved_math_group_pointer_entry)
399# define saved_math_group_all_class saved_value_2(saved_math_group_all_class_entry)
400
401static inline void saved_math_group_initialize(void)
402{
403 saved_type(0) = saved_record_0;
404 saved_record(0) = math_group_save_type;
405}
406
407int tex_show_math_group_record(void)
408{
409 tex_print_str("math group ");
410 switch (saved_type(0)) {
411 case saved_record_0:
412 tex_print_format("pointer %i, allclass %i", saved_value_1(0), saved_value_2(0));
413 break;
414 default:
415 return 0;
416 }
417 return 1;
418}
419
420
421
422static int tex_aux_scan_math (halfword p, halfword style, int usetextfont, halfword toks, halfword toks_text, int nocomponent, halfword cls, halfword all);
423static halfword tex_aux_finish_math_list (halfword p);
424static void tex_aux_math_math_component (halfword n, int append);
425
426# define cramped 1
427
428# define cramped_style(A) (2 * ((A) / 2) + cramped)
429# define sub_style(A) (2 * ((A) / 4) + script_style + cramped)
430# define sup_style(A) (2 * ((A) / 4) + script_style + ((A) % 2))
431# define small_style sup_style
432# define num_style(A) ((A) + 2 - 2 * ((A) / 6))
433# define smaller_style num_style
434# define denom_style(A) (2 * ((A) / 2) + cramped + 2 - 2 * ((A) / 6))
435# define sup_sup_style(A) sup_style(sup_style((A)))
436
437static inline mathdictval tex_fake_math_dict(halfword chr)
438{
439 mathdictval d = tex_no_dict_code();
440 if (math_dict_properties_par || math_dict_group_par) {
441 d.properties = (unsigned short) math_dict_properties_par;
442 d.group = (unsigned short) math_dict_group_par;
443 d.index = (unsigned int) chr;
444 }
445 return d;
446}
447
448void tex_math_copy_char_data(halfword target, halfword source, int wipelist)
449{
450 if (node_type(source) == math_char_node) {
451 kernel_math_family(target) = kernel_math_family(source);
452 kernel_math_character(target) = kernel_math_character(source);
453 kernel_math_options(target) = kernel_math_options(source);
454 kernel_math_properties(target) = kernel_math_properties(source);
455 kernel_math_group(target) = kernel_math_group(source);
456 kernel_math_index(target) = kernel_math_index(source);
457 } else {
458 kernel_math_list(target) = kernel_math_list(source);
459 if (wipelist) {
460 kernel_math_list(source) = null;
461 }
462 }
463}
464
465static inline void tex_math_set_scripts_options(halfword n)
466{
467 if (math_scripts_mode_par & fixed_super_or_sub_script_code) {
468 noad_options(n) |= noad_option_fixed_super_or_sub_script;
469 }
470 if (math_scripts_mode_par & fixed_super_and_sub_script_code) {
471 noad_options(n) |= noad_option_fixed_super_and_sub_script;
472 }
473 if (math_scripts_mode_par & ignore_empty_super_script_code) {
474 noad_options(n) |= noad_option_ignore_empty_super_script;
475 }
476 if (math_scripts_mode_par & ignore_empty_sub_script_code) {
477 noad_options(n) |= noad_option_ignore_empty_sub_script;
478 }
479 if (math_scripts_mode_par & ignore_empty_prime_script_code) {
480 noad_options(n) |= noad_option_ignore_empty_prime_script;
481 }
482}
483
484
485
486# define display_style_nibble(a) (a << 28)
487# define cramped_display_style_nibble(a) (a << 24)
488# define text_style_nibble(a) (a << 20)
489# define cramped_text_style_nibble(a) (a << 16)
490# define script_style_nibble(a) (a << 12)
491# define cramped_script_style_nibble(a) (a << 8)
492# define script_script_style_nibble(a) (a << 4)
493# define cramped_script_script_style_nibble(a) (a << 0)
494
495static const unsigned int math_variant_presets[last_math_style_variant+1] = {
496
497
498 (unsigned int) (0
499 + display_style_nibble (display_style )
500 + cramped_display_style_nibble (cramped_display_style )
501 + text_style_nibble (text_style )
502 + cramped_text_style_nibble (cramped_text_style )
503 + script_style_nibble (script_style )
504 + cramped_script_style_nibble (cramped_script_style )
505 + script_script_style_nibble (script_script_style )
506 + cramped_script_script_style_nibble(cramped_script_script_style)
507 ),
508
509
510 (unsigned int) (0
511 + display_style_nibble (cramped_display_style )
512 + cramped_display_style_nibble (cramped_display_style )
513 + text_style_nibble (cramped_text_style )
514 + cramped_text_style_nibble (cramped_text_style )
515 + script_style_nibble (cramped_script_style )
516 + cramped_script_style_nibble (cramped_script_style )
517 + script_script_style_nibble (cramped_script_script_style)
518 + cramped_script_script_style_nibble(cramped_script_script_style)
519 ),
520
521
522 (unsigned int) (0
523 + display_style_nibble (cramped_script_style )
524 + cramped_display_style_nibble (cramped_script_style )
525 + text_style_nibble (cramped_script_style )
526 + cramped_text_style_nibble (cramped_script_style )
527 + script_style_nibble (cramped_script_script_style)
528 + cramped_script_style_nibble (cramped_script_script_style)
529 + script_script_style_nibble (cramped_script_script_style)
530 + cramped_script_script_style_nibble(cramped_script_script_style)
531 ),
532
533
534 (unsigned int) (0
535 + display_style_nibble (script_style )
536 + cramped_display_style_nibble (cramped_script_style )
537 + text_style_nibble (script_style )
538 + cramped_text_style_nibble (cramped_script_style )
539 + script_style_nibble (script_script_style )
540 + cramped_script_style_nibble (cramped_script_script_style)
541 + script_script_style_nibble (script_script_style )
542 + cramped_script_script_style_nibble(cramped_script_script_style)
543 ),
544
545 (unsigned int) (0
546 + display_style_nibble (script_style )
547 + cramped_display_style_nibble (cramped_script_style )
548 + text_style_nibble (script_style )
549 + cramped_text_style_nibble (cramped_script_style )
550 + script_style_nibble (script_script_style )
551 + cramped_script_style_nibble (cramped_script_script_style)
552 + script_script_style_nibble (script_script_style )
553 + cramped_script_script_style_nibble(cramped_script_script_style)
554 ),
555
556
557 (unsigned int) (0
558 + display_style_nibble (text_style )
559 + cramped_display_style_nibble (cramped_text_style )
560 + text_style_nibble (script_style )
561 + cramped_text_style_nibble (cramped_script_style )
562 + script_style_nibble (script_script_style )
563 + cramped_script_style_nibble (cramped_script_script_style)
564 + script_script_style_nibble (script_script_style )
565 + cramped_script_script_style_nibble(cramped_script_script_style)
566 ),
567
568 (unsigned int) (0
569 + display_style_nibble (text_style )
570 + cramped_display_style_nibble (cramped_text_style )
571 + text_style_nibble (script_style )
572 + cramped_text_style_nibble (cramped_script_style )
573 + script_style_nibble (script_script_style )
574 + cramped_script_style_nibble (cramped_script_script_style)
575 + script_script_style_nibble (script_script_style )
576 + cramped_script_script_style_nibble(cramped_script_script_style)
577 ),
578
579 (unsigned int) (0
580 + display_style_nibble (cramped_text_style )
581 + cramped_display_style_nibble (cramped_text_style )
582 + text_style_nibble (cramped_script_style )
583 + cramped_text_style_nibble (cramped_script_style )
584 + script_style_nibble (cramped_script_script_style)
585 + cramped_script_style_nibble (cramped_script_script_style)
586 + script_script_style_nibble (cramped_script_script_style)
587 + cramped_script_script_style_nibble(cramped_script_script_style)
588 ),
589
590
591 (unsigned int) (0
592 + display_style_nibble (script_script_style )
593 + cramped_display_style_nibble (cramped_script_script_style)
594 + text_style_nibble (script_script_style )
595 + cramped_text_style_nibble (cramped_script_script_style)
596 + script_style_nibble (script_script_style )
597 + cramped_script_style_nibble (cramped_script_script_style)
598 + script_script_style_nibble (script_script_style )
599 + cramped_script_script_style_nibble(cramped_script_script_style)
600 ),
601};
602
603int tex_get_math_variant_preset(int i)
604{
605 return valid_math_style_variant(i) ? math_variant_presets[i] : 0;
606}
607
608
611
612halfword tex_size_of_style(halfword style)
613{
614 switch (style) {
615 case script_style:
616 case cramped_script_style:
617 return script_size;
618 case script_script_style:
619 case cramped_script_script_style:
620 return script_script_size;
621 default:
622 return text_size;
623 }
624}
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652halfword tex_math_style_variant(halfword style, halfword parameter)
653{
654 return ((unsigned int) tex_get_math_parameter(style,parameter,NULL) >> (4 * (7 - style))) & 0xF;
655}
656
657int tex_math_has_class_option(halfword cls, int option)
658{
659 halfword value = count_parameter(first_math_options_code + cls);
660 if (value == no_class_options) {
661 unsigned parent = (unsigned) count_parameter(first_math_parent_code + cls);
662 cls = (parent >> 16) & 0xFF;
663 if (! valid_math_class_code(cls)) {
664 return 0;
665 }
666 value = count_parameter(first_math_options_code + cls);
667 }
668 return (value & option) == option;
669}
670
671int tex_math_has_class_parent(halfword cls)
672{
673 halfword value = count_parameter(first_math_options_code + cls);
674 if (value == no_class_options) {
675 unsigned parent = (unsigned) count_parameter(first_math_parent_code + cls);
676 return (parent >> 16) & 0xFF;
677 }
678 return 0;
679}
680
681static void tex_aux_unsave_math(void)
682{
683 tex_unsave();
684 lmt_save_state.save_stack_data.ptr -= saved_math_n_of_records;
685 tex_flush_node_list(lmt_dir_state.text_dir_ptr);
686 lmt_dir_state.text_dir_ptr = saved_math_direction;
687}
688
689
695
696void tex_flush_math(void)
697{
698 halfword head = cur_list.head;
699 tex_flush_node_list(node_next(head));
700 tex_flush_node_list(cur_list.incomplete_noad);
701 node_next(head) = null;
702 cur_list.tail = head;
703 cur_list.incomplete_noad = null;
704}
705
706
707
708static void tex_aux_print_parameter(const char *what, halfword style, halfword param, halfword indirect, halfword value)
709{
710 tex_begin_diagnostic();
711 tex_print_format("{%s ", what);
712 if (indirect >= 0 && indirect <= last_math_indirect) {
713 tex_print_str(lmt_interface.math_indirect_values[indirect].name);
714 tex_print_char(' ');
715 }
716 if (param < math_parameter_last) {
717 tex_print_cmd_chr(math_parameter_cmd, param);
718 } else {
719 tex_print_format("%x %x ", math_parameter_spacing_left(param), math_parameter_spacing_right(param));
720 }
721 tex_print_cmd_chr(math_style_cmd, style);
722 tex_print_char('=');
723 switch (math_parameter_value_type(param)) {
724 case math_integer_parameter:
725 case math_style_parameter:
726 tex_print_int(value);
727 break;
728 case math_dimension_parameter:
729 tex_print_dimension(value, pt_unit);
730 break;
731 case math_muglue_parameter:
732 tex_print_spec(value, mu_unit);
733 break;
734 default:
735 tex_print_int(value);
736 break;
737 }
738 tex_print_char('}');
739 tex_end_diagnostic();
740}
741
742static void tex_aux_print_fam(const char *what, halfword size, halfword fam)
743{
744 tex_begin_diagnostic();
745 tex_print_format("{%s %C family %i: %F}", what, define_family_cmd, size, fam, tex_fam_fnt(fam, size));
746 tex_end_diagnostic();
747}
748
749
753
754int tex_fam_fnt(int fam, int size)
755{
756
757 sa_tree_item item;
758 sa_get_item_4(lmt_math_state.fam_head, fam + (256 * size), &item);
759 return (int) item.int_value;
760}
761
762void tex_def_fam_fnt(int fam, int size, int fnt, int level)
763{
764 sa_tree_item item;
765 item.int_value = fnt;
766 sa_set_item_4(lmt_math_state.fam_head, fam + (256 * size), item, level);
767 if (tracing_assigns_par > 1) {
768 tex_aux_print_fam("assigning", size, fam);
769 }
770 tex_fixup_math_parameters(fam, size, fnt, level);
771}
772
773static void tex_aux_unsave_math_fam_data(int gl)
774{
775 if (lmt_math_state.fam_head->stack) {
776 while (lmt_math_state.fam_head->sa_stack_ptr > 0 && abs(lmt_math_state.fam_head->stack[lmt_math_state.fam_head->sa_stack_ptr].level) >= (int) gl) {
777 sa_stack_item item = lmt_math_state.fam_head->stack[lmt_math_state.fam_head->sa_stack_ptr];
778 if (item.level > 0) {
779 sa_rawset_item_4(lmt_math_state.fam_head, item.code, item.value_1);
780
781 if (tracing_restores_par > 1) {
782 int size = item.code / 256;
783 int fam = item.code % 256;
784 tex_aux_print_fam("restoring", size, fam);
785 }
786 }
787 --lmt_math_state.fam_head->sa_stack_ptr;
788 }
789 }
790}
791
792
793
794void tex_def_math_parameter(int style, int param, scaled value, int level, int indirect, int fixup)
795{
796 if (fixup && ignore_math_parameter(param) == 2) {
797 return;
798 } else {
799 sa_tree_item item1, item2;
800 int different = 1;
801 if (level <= 1) {
802 if (math_parameter_value_type(param) == math_muglue_parameter) {
803 sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item1, &item2);
804 if (item2.int_value == indirect_math_regular && item1.int_value > thick_muskip_code) {
805 if (lmt_node_memory_state.nodesizes[item1.int_value]) {
806 tex_free_node(item1.int_value, glue_spec_size);
807 }
808 }
809 }
810 } else {
811
812 sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item1, &item2);
813 different = item1.int_value != value || item2.int_value != indirect;
814 }
815
816 item1.int_value = value;
817 item2.int_value = indirect;
818 sa_set_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), item1, item2, level);
819 if (different && tracing_assigns_par > 1) {
820 tex_aux_print_parameter("assigning", style, param, indirect, value);
821 }
822
823 }
824}
825
826
827
828scaled tex_get_math_parameter(int style, int param, halfword *type)
829{
830 halfword indirect, value;
831 sa_tree_item v1, v2;
832 sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v1, &v2);
833 indirect = v2.int_value == lmt_math_state.par_head->dflt.int_value ? indirect_math_unset : v2.uint_value;
834 value = v1.int_value;
835 switch (indirect) {
836 case indirect_math_unset:
837 if (type) {
838 *type = no_val_level;
839 }
840 return MATHPARAMDEFAULT;
841
842 case indirect_math_regular:
843 switch (math_parameter_value_type(param)) {
844 case math_dimension_parameter:
845 if (type) {
846 *type = dimension_val_level;
847 }
848 return value;
849 case math_muglue_parameter:
850 if (type) {
851 *type = muglue_val_level;
852 }
853 return value <= thick_muskip_code ? muglue_parameter(value) : value;
854
855
856 default:
857 if (type) {
858 *type = integer_val_level;
859 }
860 return value;
861 }
862
863 case indirect_math_integer:
864 if (! value) {
865 if (type) {
866 *type = integer_val_level;
867 }
868 return value;
869 } else if (eq_type(value) == integer_cmd) {
870 if (type) {
871 *type = integer_val_level;
872 }
873 return eq_value(value);
874 } else {
875 goto MISMATCH;
876 }
877 case indirect_math_dimension:
878 if (! value) {
879 if (type) {
880 *type = dimension_val_level;
881 }
882 return value;
883 } else if (eq_type(value) == dimension_cmd) {
884 if (type) {
885 *type = dimension_val_level;
886 }
887 return eq_value(value);
888 } else if (eq_type(value) == posit_cmd) {
889 if (type) {
890 *type = dimension_val_level;
891 }
892 return tex_posit_to_dimension(eq_value(value));
893 } else {
894 goto MISMATCH;
895 }
896 case indirect_math_mugluespec:
897 if (! value) {
898 if (type) {
899 *type = muglue_val_level;
900 }
901 return value;
902 } else {
903 switch (eq_type(value)) {
904 case mugluespec_cmd:
905 if (type) {
906 *type = muglue_val_level;
907 }
908 return eq_value(value);
909 default:
910 goto MISMATCH;
911 }
912
913 }
914 case indirect_math_gluespec:
915 if (! value) {
916 if (type) {
917 *type = glue_val_level;
918 }
919 return value;
920 } else {
921 switch (eq_type(value)) {
922 case gluespec_cmd:
923 if (type) {
924 *type = glue_val_level;
925 }
926 return eq_value(value);
927 default:
928 goto MISMATCH;
929 }
930 }
931
932 case indirect_math_register_integer:
933 if (! value) {
934 if (type) {
935 *type = integer_val_level;
936 }
937 return value;
938 } else if (eq_type(value) == register_integer_reference_cmd) {
939 if (type) {
940 *type = integer_val_level;
941 }
942 return eq_value(value);
943 } else {
944 goto MISMATCH;
945 }
946 case indirect_math_register_dimension:
947 if (! value) {
948 if (type) {
949 *type = dimension_val_level;
950 }
951 return value;
952 } else if (eq_type(value) == register_dimension_reference_cmd) {
953 if (type) {
954 *type = dimension_val_level;
955 }
956 return eq_value(value);
957 } else {
958 goto MISMATCH;
959 }
960 case indirect_math_register_gluespec:
961 if (! value) {
962 if (type) {
963 *type = glue_val_level;
964 }
965 return value;
966 } else if (eq_type(value) == register_glue_reference_cmd) {
967 if (type) {
968 *type = glue_val_level;
969 }
970 return eq_value(value);
971 } else {
972 goto MISMATCH;
973 }
974 case indirect_math_register_mugluespec:
975 if (! value) {
976 if (type) {
977 *type = muglue_val_level;
978 }
979 return value;
980 } else if (eq_type(value) == register_muglue_reference_cmd) {
981 if (type) {
982 *type = muglue_val_level;
983 }
984 return eq_value(value);
985 } else {
986 goto MISMATCH;
987 }
988 case indirect_math_internal_integer:
989 if (! value) {
990 if (type) {
991 *type = integer_val_level;
992 }
993 return value;
994 } else if (eq_type(value) == internal_integer_reference_cmd) {
995 if (type) {
996 *type = integer_val_level;
997 }
998 return eq_value(value);
999 } else {
1000 goto MISMATCH;
1001 }
1002 case indirect_math_internal_dimension:
1003 if (! value) {
1004 if (type) {
1005 *type = dimension_val_level;
1006 }
1007 return value;
1008 } else if (eq_type(value) == internal_dimension_reference_cmd) {
1009 if (type) {
1010 *type = dimension_val_level;
1011 }
1012 return eq_value(value);
1013 } else {
1014 goto MISMATCH;
1015 }
1016 case indirect_math_internal_gluespec:
1017 if (! value) {
1018 if (type) {
1019 *type = glue_val_level;
1020 }
1021 return value;
1022 } else if (eq_type(value) == internal_glue_reference_cmd) {
1023 if (type) {
1024 *type = glue_val_level;
1025 }
1026 return eq_value(value);
1027 } else {
1028 goto MISMATCH;
1029 }
1030 case indirect_math_internal_mugluespec:
1031 if (! value) {
1032 if (type) {
1033 *type = muglue_val_level;
1034 }
1035 return value;
1036 } else if (eq_type(value) == internal_muglue_reference_cmd) {
1037 if (type) {
1038 *type = muglue_val_level;
1039 }
1040 return eq_value(value);
1041 } else {
1042 goto MISMATCH;
1043 }
1044 default:
1045 MISMATCH:
1046 tex_handle_error(
1047 normal_error_type,
1048 "Invalid inherited math parameter",
1049 "You probably changed the type of the inherited math parameter, so I will "
1050 "use zero instead."
1051 );
1052 return 0;
1053 }
1054}
1055
1056int tex_has_math_parameter(int style, int param)
1057{
1058 sa_tree_item v1, v2;
1059 sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v1, &v2);
1060 return v2.int_value == lmt_math_state.par_head->dflt.int_value ? indirect_math_unset : v2.uint_value;
1061}
1062
1063static void tex_aux_unsave_math_parameter_data(int gl)
1064{
1065 if (lmt_math_state.par_head->stack) {
1066
1067 while (lmt_math_state.par_head->sa_stack_ptr > 0 && abs(lmt_math_state.par_head->stack[lmt_math_state.par_head->sa_stack_ptr].level) >= gl) {
1068 sa_stack_item item = lmt_math_state.par_head->stack[lmt_math_state.par_head->sa_stack_ptr];
1069 if (item.level > 0) {
1070 int param = item.code % math_parameter_max_range;
1071 int style = item.code / math_parameter_max_range;
1072 if (math_parameter_value_type(param) == math_muglue_parameter) {
1073 sa_tree_item item1, item2;
1074 sa_get_item_8(lmt_math_state.par_head, item.code, &item1, &item2);
1075 if (item2.int_value == indirect_math_regular && item1.int_value > thick_muskip_code) {
1076
1077 if (lmt_node_memory_state.nodesizes[item1.int_value]) {
1078
1079 tex_free_node(item1.int_value, glue_spec_size);
1080 } else {
1081
1082 }
1083 }
1084 }
1085 sa_rawset_item_8(lmt_math_state.par_head, item.code, item.value_1, item.value_2);
1086
1087 if (tracing_restores_par > 1) {
1088 int indirect = item.value_2.int_value;
1089 tex_aux_print_parameter("restoring", style, param, indirect, tex_get_math_parameter(style, param, NULL));
1090 }
1091 }
1092
1093 --lmt_math_state.par_head->sa_stack_ptr;
1094 }
1095 }
1096}
1097
1098
1099
1100void tex_unsave_math_data(int grouplevel)
1101{
1102 tex_aux_unsave_math_fam_data(grouplevel);
1103 tex_aux_unsave_math_parameter_data(grouplevel);
1104}
1105
1106
1107
1108void tex_dump_math_data(dumpstream f)
1109{
1110 if (! lmt_math_state.fam_head) {
1111 lmt_math_state.fam_head = sa_new_tree(mathfont_sparse_identifier, MATHFONTSTACK, MATHFONTSTEP, 4, (sa_tree_item) { .int_value = MATHFONTDEFAULT });
1112 }
1113 sa_dump_tree(f, lmt_math_state.fam_head);
1114 if (! lmt_math_state.par_head) {
1115 lmt_math_state.par_head = sa_new_tree(mathparam_sparse_identifier, MATHPARAMSTACK, MATHPARAMSTEP, 8, (sa_tree_item) { .int_value = MATHPARAMDEFAULT });
1116 }
1117 sa_dump_tree(f, lmt_math_state.par_head);
1118}
1119
1120void tex_undump_math_data(dumpstream f)
1121{
1122 lmt_math_state.fam_head = sa_undump_tree(f);
1123 lmt_math_state.par_head = sa_undump_tree(f);
1124}
1125
1126void tex_initialize_math(void)
1127{
1128 if (! lmt_math_state.fam_head) {
1129 lmt_math_state.fam_head = sa_new_tree(mathfont_sparse_identifier, MATHFONTSTACK, MATHFONTSTEP, 4, (sa_tree_item) { .int_value = MATHFONTDEFAULT });
1130 }
1131 if (! lmt_math_state.par_head) {
1132 lmt_math_state.par_head = sa_new_tree(mathparam_sparse_identifier, MATHPARAMSTACK, MATHPARAMSTEP, 8, (sa_tree_item) { .int_value = MATHPARAMDEFAULT });
1133 tex_initialize_math_spacing();
1134 }
1135 return;
1136}
1137
1138
1176
1177halfword tex_new_sub_box(halfword curbox)
1178{
1179 halfword noad = tex_new_node(simple_noad, ordinary_noad_subtype);
1180 halfword sbox = tex_new_node(sub_box_node, 0);
1181 noad_nucleus(noad) = sbox;
1182 kernel_math_list(sbox) = curbox;
1183 return noad;
1184}
1185
1186static quarterword tex_aux_set_math_char(halfword target, mathcodeval *mval, mathdictval *dval)
1187{
1188 halfword hmcode = tex_get_hm_code(mval->character_value);
1189 kernel_math_character(target) = mval->character_value;
1190 if (variable_family_par == -2) {
1191
1192 kernel_math_family(target) = cur_fam_par_in_range ? cur_fam_par : mval->family_value;
1193 node_subtype(target) = mval->class_value;
1194 } else if (mval->class_value == math_use_current_family_code) {
1195
1196 kernel_math_family(target) = cur_fam_par_in_range ? cur_fam_par : mval->family_value;
1197 node_subtype(target) = ordinary_noad_subtype;
1198 } else if (mval->family_value == variable_family_par) {
1199 kernel_math_family(target) = cur_fam_par_in_range ? cur_fam_par : mval->family_value;
1200 node_subtype(target) = mval->class_value;
1201 } else {
1202 kernel_math_family(target) = mval->family_value;
1203 node_subtype(target) = mval->class_value;
1204 }
1205 if (dval) {
1206 kernel_math_properties(target) = dval->properties;
1207 kernel_math_group(target) = dval->group;
1208 kernel_math_index(target) = dval->index;
1209 }
1210 if ((hmcode & auto_discretionary_normal) == auto_discretionary_normal) {
1211 math_kernel_node_set_option(target, math_kernel_auto_discretionary);
1212 }
1213 if ((hmcode & auto_discretionary_italic) == auto_discretionary_italic) {
1214 math_kernel_node_set_option(target, math_kernel_full_discretionary);
1215 }
1216 return node_subtype(target);
1217}
1218
1219
1248
1249void tex_run_math_style(void) {
1250 switch (cur_chr) {
1251 case yet_unset_math_style:
1252 {
1253 halfword style = tex_scan_math_style_identifier(1, 0);
1254 if (is_valid_math_style(style)) {
1255 halfword noad = tex_new_node(style_node, (quarterword) style);
1256 cur_list.math_style = style;
1257 tex_tail_append(noad);
1258 }
1259 }
1260 break;
1261 case scaled_math_style:
1262 {
1263 halfword noad = tex_new_node(style_node, scaled_math_style);
1264 style_scale(noad) = tex_scan_integer(0, NULL, NULL);
1265
1266 cur_list.math_scale = style_scale(noad);
1267 tex_tail_append(noad);
1268 }
1269 break;
1270 case currently_set_math_style:
1271
1272 break;
1273 default:
1274 if (is_valid_math_style(cur_chr)) {
1275 halfword noad = tex_new_node(style_node, (quarterword) cur_chr);
1276 cur_list.math_style = cur_chr;
1277 tex_tail_append(noad);
1278 } else {
1279
1280 }
1281 }
1282}
1283
1284
1300
1301static void tex_aux_display_choice_noad (halfword n, int threshold, int max);
1302static void tex_aux_display_parameter_node (halfword n);
1303static void tex_aux_display_simple_noad (halfword n, int threshold, int max);
1304static void tex_aux_display_radical_noad (halfword n, int threshold, int max);
1305static void tex_aux_display_accent_noad (halfword n, int threshold, int max);
1306static void tex_aux_display_fence_noad (halfword n, int threshold, int max);
1307static void tex_aux_display_fraction_noad (halfword n, int threshold, int max);
1308
1309static void tex_aux_print_fam_and_char(halfword n)
1310{
1311 tex_print_format(", family %x, character %x, original %x", kernel_math_family(n), kernel_math_character(n));
1312 tex_aux_show_dictionary(n, kernel_math_properties(n), kernel_math_group(n), kernel_math_index(n), tex_fam_fnt(kernel_math_family(n), 0), kernel_math_character(n));
1313}
1314
1315int tex_show_math_node(halfword n, int threshold, int max)
1316{
1317 switch (node_type(n)) {
1318 case style_node:
1319
1320 break;
1321 case choice_node:
1322 tex_aux_display_choice_noad(n, threshold, max);
1323 break;
1324 case parameter_node:
1325 tex_aux_display_parameter_node(n);
1326 break;
1327 case simple_noad:
1328 tex_aux_display_simple_noad(n, threshold, max);
1329 break;
1330 case radical_noad:
1331 tex_aux_display_radical_noad(n, threshold, max);
1332 break;
1333 case accent_noad:
1334 tex_aux_display_accent_noad(n, threshold, max);
1335 break;
1336 case fence_noad:
1337 tex_aux_display_fence_noad(n, threshold, max);
1338 break;
1339 case fraction_noad:
1340 tex_aux_display_fraction_noad(n, threshold, max);
1341 break;
1342 case math_text_char_node:
1343 case math_char_node:
1344 tex_aux_print_fam_and_char(n);
1345 break;
1346 case sub_box_node:
1347 tex_print_node_list(kernel_math_list(n), NULL, threshold, max);
1348 break;
1349 case sub_mlist_node:
1350 if (kernel_math_list(n)) {
1351 tex_print_node_list(kernel_math_list(n), NULL, threshold, max);
1352 } else {
1353 tex_print_str(", empty");
1354 }
1355 break;
1356 default:
1357 return 0;
1358 }
1359 return 1;
1360}
1361
1362static inline halfword tex_aux_valid_delimiter(halfword d)
1363{
1364 return (d && (delimiter_small_family(d) || delimiter_small_character(d) || delimiter_large_family(d) || delimiter_large_character(d))) ? d : null;
1365}
1366
1367static void tex_aux_print_delimiter(halfword d)
1368{
1369 if (delimiter_small_family(d) < 0) {
1370
1371 tex_print_int(-1);
1372 } else if (delimiter_small_family(d) < 16 && delimiter_large_family(d) < 16 && delimiter_small_character(d) < 256 && delimiter_large_character(d) < 256) {
1373
1374 int a = delimiter_small_family(d) * 256 + delimiter_small_character(d);
1375 a = a * 0x1000 + delimiter_large_family(d) * 256 + delimiter_large_character(d);
1376 tex_print_format(", code %x", a);
1377 } else if ((delimiter_large_family(d) == 0 && delimiter_large_character(d) == 0) || delimiter_small_character(d) > 65535 || delimiter_large_character(d) > 65535) {
1378
1379 tex_print_format(", family %x, character %x", delimiter_small_family(d), delimiter_small_character(d));
1380 }
1381}
1382
1383
1394
1395static void tex_aux_display_common_noad(halfword n, int threshold, int max)
1396{
1397 tex_print_node_list(noad_nucleus(n), "nucleus", threshold, max);
1398 tex_print_node_list(noad_supscr(n), "superscript", threshold, max);
1399 tex_print_node_list(noad_subscr(n), "subscript", threshold, max);
1400 tex_print_node_list(noad_supprescr(n), "superprescript", threshold, max);
1401 tex_print_node_list(noad_subprescr(n), "subprescript", threshold, max);
1402 tex_print_node_list(noad_prime(n), "primescript", threshold, max);
1403 tex_print_node_list(noad_new_hlist(n), "newhlist", threshold, max);
1404}
1405
1406static void tex_aux_display_parameter_node(halfword n)
1407{
1408 tex_print_format(", id %i, style %i", parameter_name(n), parameter_style(n));
1409}
1410
1411static void tex_aux_display_choice_noad(halfword n, int threshold, int max)
1412{
1413 switch (node_subtype(n)) {
1414 case normal_choice_subtype:
1415 tex_print_node_list(choice_display_mlist(n), "display", threshold, max);
1416 tex_print_node_list(choice_text_mlist(n), "text", threshold, max);
1417 tex_print_node_list(choice_script_mlist(n), "script", threshold, max);
1418 tex_print_node_list(choice_script_script_mlist(n), "scriptscript", threshold, max);
1419 break;
1420 case discretionary_choice_subtype:
1421 tex_print_format(", class %i", choice_class(n));
1422 tex_print_node_list(choice_pre_break(n), "pre", threshold, max);
1423 tex_print_node_list(choice_post_break(n), "post", threshold, max);
1424 tex_print_node_list(choice_no_break(n), "replace", threshold, max);
1425 break;
1426 }
1427}
1428
1429static void tex_aux_display_simple_noad(halfword n, int threshold, int max)
1430{
1431 if (noad_source(n)) {
1432 tex_print_format(", source %i", noad_source(n));
1433 }
1434 tex_aux_display_common_noad(n, threshold, max);
1435}
1436
1437static void tex_aux_display_radical_noad(halfword n, int threshold, int max)
1438{
1439 if (noad_width(n)) {
1440 tex_print_format(", width %p", noad_width(n));
1441 }
1442 if (radical_height(n)) {
1443 tex_print_format(", height %p", radical_height(n));
1444 }
1445 if (radical_depth(n)) {
1446 tex_print_format(", depth %p", radical_depth(n));
1447 }
1448 if (radical_size(n)) {
1449 tex_print_format(", size %i", radical_size(n));
1450 }
1451 if (noad_source(n) != 0) {
1452 tex_print_format(", source %i", noad_source(n));
1453 }
1454 if (noad_options(n)) {
1455 tex_print_format(", options %x", noad_options(n));
1456 }
1457 if (radical_left_delimiter(n)) {
1458 tex_print_str(", left");
1459 tex_aux_print_delimiter(radical_left_delimiter(n));
1460 }
1461 if (radical_right_delimiter(n)) {
1462 tex_print_str(", right");
1463 tex_aux_print_delimiter(radical_right_delimiter(n));
1464 }
1465 if (radical_degree(n)) {
1466 tex_print_node_list(radical_degree(n), "degree", threshold, max);
1467 }
1468 tex_aux_display_common_noad(n, threshold, max);
1469}
1470
1471static void tex_aux_display_accent_noad(halfword n, int threshold, int max)
1472{
1473 halfword top_char = accent_top_character(n);
1474 halfword bottom_char = accent_bottom_character(n);
1475 halfword fraction = accent_fraction(n);
1476 if (fraction) {
1477 tex_print_str(", fraction ");
1478 tex_print_int(fraction);
1479 }
1480 switch (node_subtype(n)) {
1481 case bothflexible_accent_subtype:
1482 if (top_char) {
1483 tex_print_str(", top ");
1484 tex_aux_print_fam_and_char(top_char);
1485 }
1486 if (bottom_char) {
1487 tex_print_str(", bottom ");
1488 tex_aux_print_fam_and_char(bottom_char);
1489 }
1490 if (! (top_char || bottom_char)) {
1491 tex_print_str(", overlay ");
1492 tex_aux_print_fam_and_char(accent_middle_character(n));
1493 }
1494 break;
1495 case fixedtop_accent_subtype:
1496 if (top_char) {
1497 tex_print_str(", fixed top ");
1498 tex_aux_print_fam_and_char(top_char);
1499 }
1500 if (bottom_char) {
1501 tex_print_str(", bottom ");
1502 tex_aux_print_fam_and_char(bottom_char);
1503 }
1504 break;
1505 case fixedbottom_accent_subtype:
1506 if (top_char) {
1507 tex_print_str(", top ");
1508 tex_aux_print_fam_and_char(top_char);
1509 }
1510 if (bottom_char) {
1511 tex_print_str(", fixed bottom ");
1512 tex_aux_print_fam_and_char(bottom_char);
1513 }
1514 break;
1515 case fixedboth_accent_subtype:
1516 if (top_char) {
1517 tex_print_str(", fixed top ");
1518 tex_aux_print_fam_and_char(top_char);
1519 }
1520 if (bottom_char) {
1521 tex_print_str(", fixed bottom ");
1522 tex_aux_print_fam_and_char(bottom_char);
1523 }
1524 break;
1525 }
1526 tex_aux_display_common_noad(n, threshold, max);
1527}
1528
1529static void tex_aux_display_fence_noad(halfword n, int threshold, int max)
1530{
1531 if (noad_height(n)) {
1532 tex_print_format(", height %p", noad_height(n));
1533 }
1534 if (noad_depth(n)) {
1535 tex_print_format(", depth %p", noad_depth(n));
1536 }
1537 if (fence_top_overshoot(n)) {
1538 tex_print_format(", top %p", fence_top_overshoot(n));
1539 }
1540 if (fence_bottom_overshoot(n)) {
1541 tex_print_format(", top %p", fence_bottom_overshoot(n));
1542 }
1543 if (get_noad_main_class(n) != unset_noad_class) {
1544 tex_print_format(", class %i", get_noad_main_class(n));
1545 }
1546 if (get_noad_left_class(n) != unset_noad_class) {
1547 tex_print_format(", leftclass %i", get_noad_left_class(n));
1548 }
1549 if (get_noad_right_class(n) != unset_noad_class) {
1550 tex_print_format(", rightclass %i", get_noad_right_class(n));
1551 }
1552 if (noad_source(n) != 0) {
1553 tex_print_format(", source %i", noad_source(n));
1554 }
1555 if (noad_options(n)) {
1556 tex_print_format(", options %x", noad_options(n));
1557 }
1558 tex_aux_print_delimiter(fence_delimiter(n));
1559 tex_print_node_list(fence_delimiter_top(n), "top", threshold, max);
1560 tex_print_node_list(fence_delimiter_bottom(n), "bottom", threshold, max);
1561}
1562
1563static void tex_aux_display_fraction_noad(halfword n, int threshold, int max)
1564{
1565 halfword leftdelimiter = tex_aux_valid_delimiter(fraction_left_delimiter(n));
1566 halfword rightdelimiter = tex_aux_valid_delimiter(fraction_right_delimiter(n));
1567 tex_print_str(", thickness ");
1568 if (fraction_rule_thickness(n) == preset_rule_thickness) {
1569 tex_print_str("default");
1570 } else {
1571 tex_print_dimension(fraction_rule_thickness(n), pt_unit);
1572 }
1573 if (leftdelimiter) {
1574 tex_print_str(", leftdelimiter ");
1575 tex_aux_print_delimiter(leftdelimiter);
1576 }
1577 if (rightdelimiter) {
1578 tex_print_str(", rightdelimiter ");
1579 tex_aux_print_delimiter(rightdelimiter);
1580 }
1581 if (noad_source(n) != 0) {
1582 tex_print_str(", source ");
1583 tex_print_int(noad_source(n));
1584 }
1585 if (noad_options(n)) {
1586 tex_print_str(", options ");
1587 tex_print_qhex(noad_options(n));
1588 }
1589 tex_print_node_list(fraction_numerator(n), "numerator", threshold, max);
1590 tex_print_node_list(fraction_denominator(n), "denominator", threshold, max);
1591}
1592
1593
1604
1605static void tex_aux_new_save_level_math(quarterword group)
1606{
1607 halfword direction = math_direction_par;
1608 saved_math_initialize();
1609 saved_math_direction = lmt_dir_state.text_dir_ptr;
1610 lmt_save_state.save_stack_data.ptr += saved_math_n_of_records;
1611 lmt_dir_state.text_dir_ptr = tex_new_dir(normal_dir_subtype, direction);
1612 tex_new_save_level(group);
1613 update_tex_par_direction(direction);
1614 update_tex_text_direction(direction);
1615}
1616
1617static void tex_aux_push_math(quarterword group, int style, int outerstyle)
1618{
1619 halfword main_style = cur_list.math_main_style;
1620 halfword parent_style = cur_list.math_style;
1621 if (math_direction_par != text_direction_par) {
1622 cur_list.math_dir = 1;
1623 }
1624 cur_list.math_begin = math_begin_class_par;
1625 cur_list.math_end = math_end_class_par;
1626 if (outerstyle >= 0) {
1627 cur_list.math_main_style = outerstyle;
1628 main_style = outerstyle;
1629 cur_list.math_parent_style = outerstyle;
1630 parent_style = outerstyle;
1631 }
1632 tex_push_nest();
1633 cur_list.mode = inline_mmode;
1634 cur_list.incomplete_noad = null;
1635 cur_list.math_style = style;
1636 cur_list.math_main_style = main_style;
1637 cur_list.math_parent_style = parent_style;
1638 cur_list.math_scale = internal_math_scale_par;
1639 tex_aux_new_save_level_math(group);
1640 update_tex_math_left_class(unset_noad_class);
1641 update_tex_math_right_class(unset_noad_class);
1642}
1643
1644static void tex_aux_enter_inline_math(int style, int where)
1645{
1646 (void) where;
1647 tex_aux_push_math(math_inline_group, style, style);
1648 update_tex_family(0, unused_math_family);
1649 if (every_math_par) {
1650 tex_begin_token_list(every_math_par, every_math_text);
1651 }
1652}
1653
1654static void tex_aux_enter_display_math(halfword cmd, int where);
1655
1656
1663
1664void tex_run_math_initialize(void)
1665{
1666 switch(cur_cmd) {
1667 case math_shift_cmd:
1668
1669 lmt_nest_state.math_mode = 1;
1670 tex_get_token();
1671 lmt_nest_state.math_mode = 0;
1672 if (cur_cmd == math_shift_cmd && cur_list.mode > nomode) {
1673 tex_aux_enter_display_math(math_shift_cmd, 1);
1674 } else {
1675 tex_back_input(cur_tok);
1676 tex_aux_enter_inline_math(text_style, 1);
1677 }
1678 break;
1679 case math_shift_cs_cmd:
1680 if (cur_chr == begin_math_mode_code) {
1681 tex_aux_enter_inline_math(tex_scan_math_style_identifier(0, 0), 2);
1682 } else if (cur_chr == begin_display_math_code && cur_list.mode > nomode) {
1683 tex_aux_enter_display_math(begin_display_math_code, 2);
1684 } else if (cur_chr == begin_inline_math_code) {
1685 tex_aux_enter_inline_math(text_style, 3);
1686 } else {
1687 tex_you_cant_error("math shift 1");
1688 }
1689 break;
1690 default:
1691 tex_you_cant_error("math shift 2");
1692 break;
1693 }
1694}
1695
1696
1704
1705void tex_run_math_equation_number(void) {
1706 if (cur_group == math_display_group) {
1707 saved_equation_number_initialize();
1708 saved_equation_number_location = cur_chr;
1709 lmt_save_state.save_stack_data.ptr += saved_equation_number_n_of_records;
1710 tex_aux_enter_inline_math(text_style, 4);
1711 } else {
1712 tex_off_save();
1713 }
1714}
1715
1716
1731
1732void tex_run_math_left_brace(void)
1733{
1734 if (math_grouping_mode_par) {
1735
1736 tex_new_save_level(math_simple_group);
1737 update_tex_internal_math_style(cur_mode == mmode ? cur_list.math_style : -1);
1738 update_tex_internal_math_scale(cur_mode == mmode ? cur_list.math_scale : -1);
1739 } else {
1740 halfword q = tex_new_node(math_char_node, 0);
1741 halfword n = tex_new_node(simple_noad, ordinary_noad_subtype);
1742 tex_tail_append(n);
1743 noad_nucleus(n) = q;
1744 tex_back_input(cur_tok);
1745 tex_aux_scan_math(q, cur_list.math_style, 0, 0, 0, 0, unset_noad_class, unset_noad_class);
1746 }
1747}
1748
1749
1761
1762static int tex_aux_pre_math_par_direction(void)
1763{
1764 return tex_located_save_value(internal_integer_location(par_direction_code));
1765}
1766
1767
1787
1788static void tex_aux_enter_display_math(halfword cmd, int where)
1789{
1790 (void) where;
1791 if (math_display_mode_par) {
1792 tex_aux_push_math(math_inline_group, display_style, display_style);
1793 cur_list.math_mode = cmd;
1794 cur_list.mode = inline_mmode;
1795 update_tex_family(0, unused_math_family);
1796 if (every_display_par) {
1797 tex_begin_token_list(every_display_par, every_display_text);
1798 }
1799 } else {
1800
1801 scaled size;
1802
1803 scaled width;
1804
1805 scaled indent;
1806
1809 if (cur_list.head == cur_list.tail) {
1810
1811 tex_pop_nest();
1812 size = - max_dimension;
1813 } else if (empty_paragraph_mode_par && ! node_next(cur_list.tail) && tex_is_effectively_empty(node_next(cur_list.head), empty_paragraph_mode_par)) {
1814
1818 tex_flush_node_list(node_next(cur_list.head));
1819 node_next(cur_list.head) = null;
1820 cur_list.tail = cur_list.head;
1821 tex_pop_nest();
1822 size = - max_dimension;
1823 } else {
1824 tex_line_break(math_display_group, math_par_context, 1);
1825
1826 size = tex_actual_box_width(lmt_linebreak_state.just_box, scaledround((tex_get_font_em_width(cur_font_par) / scaling_factor_double) * math_pre_display_gap_factor_par));
1827 }
1828
1833 if (par_shape_par) {
1834
1835 int n = tex_get_specification_count(par_shape_par);
1836 if (n > 0) {
1837 if (cur_list.prev_graf + 2 < n) {
1838 n = cur_list.prev_graf + 2;
1839 }
1840 indent = tex_get_specification_indent(par_shape_par, n) ;
1841 width = tex_get_specification_width(par_shape_par, n);
1842 indent = swap_parshape_indent(pre_display_direction_par, indent, width);
1843 } else {
1844 width = hsize_par;
1845 indent = 0;
1846 }
1847 } else if ((hang_indent_par != 0) && (((hang_after_par >= 0) && (cur_list.prev_graf + 2 > hang_after_par)) || (cur_list.prev_graf + 1 < -hang_after_par))) {
1848 halfword hangindent = swap_hang_indent(pre_display_direction_par, hang_indent_par);
1849 width = hsize_par - abs(hangindent);
1850 indent = hangindent > 0 ? hangindent : 0;
1851 } else {
1852 width = hsize_par;
1853 indent = 0;
1854 }
1855 tex_aux_push_math(math_display_group, display_style, display_style);
1856 cur_list.mode = mmode;
1857 update_tex_family(0, unused_math_family);
1858 update_tex_pre_display_size(size);
1859 update_tex_display_width(width);
1860 update_tex_display_indent(indent);
1861 update_tex_pre_display_direction(tex_aux_pre_math_par_direction());
1862 if (every_display_par) {
1863 tex_begin_token_list(every_display_par, every_display_text);
1864 }
1865 if (lmt_nest_state.nest_data.ptr == 1) {
1866 tex_build_page(before_display_page_context, 0);
1867 }
1868 }
1869}
1870
1871
1878
1879static delcodeval tex_aux_scan_extdef_del_code(int extcode, int doclass)
1880{
1881 delcodeval d = tex_no_del_code();
1882 switch (extcode) {
1883 case tex_mathcode:
1884
1885 {
1886 halfword v = tex_scan_integer(0, NULL, NULL);
1887
1888 if (doclass) {
1889 d.small.class_value = (short) (v / 0x1000000);
1890 v = (v & 0xFFFFFF);
1891 }
1892 if (v > 0xFFFFFF) {
1893 tex_handle_error(
1894 normal_error_type,
1895 "Invalid delimiter code",
1896 "I'm going to use 0 instead of that illegal code value."
1897 );
1898 v = 0;
1899 }
1900 d.small.family_value = (short) (v / 0x100000);
1901 d.small.character_value = (v % 0x100000) / 0x1000;
1902 d.large.family_value = (short) ((v & 0xFFF) / 0x100);
1903 d.large.character_value = (v % 0x100);
1904
1905 d.small.character_value = math_character_part(d.small.character_value);
1906 d.large.character_value = math_character_part(d.large.character_value);
1907 }
1908 break;
1909 case umath_mathcode:
1910
1911 {
1912 if (doclass) {
1913 d.small.class_value = (short) tex_scan_math_class_number(0);
1914 }
1915 d.small.family_value = (short) tex_scan_math_family_number();
1916 d.small.character_value = tex_scan_math_char_number();
1917 if (d.small.family_value < 0 || d.small.family_value > max_math_family_index) {
1918 tex_handle_error(
1919 normal_error_type,
1920 "Invalid delimiter family",
1921 "I'm going to use family 0 instead."
1922 );
1923 d.small.family_value = 0;
1924 d.small.character_value = 0;
1925 }
1926 }
1927 break;
1928 default:
1929
1930 tex_confusion("unknown extcode, case 1");
1931 break;
1932 }
1933 d.large.class_value = d.small.class_value;
1934 return d;
1935}
1936
1937void tex_scan_extdef_del_code(int level, int extcode)
1938{
1939 delcodeval d;
1940 int chr = tex_scan_char_number(0);
1941 tex_scan_optional_equals();
1942 d = tex_aux_scan_extdef_del_code(extcode, 0);
1943 tex_set_del_code(chr, d, (quarterword) level);
1944}
1945
1946mathdictval tex_scan_mathdict(void)
1947{
1948 mathdictval d = tex_no_dict_code();
1949 d.properties = (unsigned short) tex_scan_math_properties_number();
1950 d.group = (unsigned short) tex_scan_math_group_number();
1951 d.index = (unsigned int) tex_scan_math_index_number();
1952 return d;
1953}
1954
1955
1963
1964mathcodeval tex_scan_mathchar(int extcode)
1965{
1966 mathcodeval d = tex_no_math_code();
1967 switch (extcode) {
1968 case tex_mathcode:
1969
1970 {
1971 halfword v = tex_scan_integer(0, NULL, NULL);
1972 if (v >= 0) {
1973 if (v > 0xFFFF) {
1974 v = 0xFFFF;
1975 }
1976 d.class_value = (short) math_old_class_part(v);
1977 d.family_value = (short) math_old_family_part(v);
1978 d.character_value = math_old_character_part(v);
1979 }
1980 }
1981 break;
1982 case umath_mathcode:
1983
1984 {
1985 d.class_value = (short) tex_scan_math_class_number(0);
1986 d.family_value = (short) tex_scan_math_family_number();
1987 d.character_value = tex_scan_math_char_number();
1988 }
1989 break;
1990 default:
1991 tex_confusion("unknown extcode, case 2");
1992 break;
1993 }
1994 if (d.class_value < 0 || d.character_value > max_math_character_code || d.class_value > max_math_class_code || d.family_value > max_math_family_index) {
1995 tex_handle_error(
1996 normal_error_type,
1997 "Invalid math code",
1998 "I'm going to use 0 instead of that illegal code value."
1999 );
2000 d.class_value = 0;
2001 d.family_value = 0;
2002 d.character_value = 0;
2003 }
2004 return d;
2005}
2006
2007halfword tex_new_math_spec(mathcodeval m, quarterword code)
2008{
2009 halfword s = tex_new_node(math_spec_node, code);
2010 math_spec_class(s) = (singleword) m.class_value;
2011 math_spec_family(s) = (singleword) m.family_value;
2012 math_spec_character(s) = m.character_value;
2013 return s;
2014}
2015
2016halfword tex_new_math_dict_spec(mathdictval d, mathcodeval m, quarterword code)
2017{
2018 halfword s = tex_new_node(math_spec_node, code);
2019 math_spec_class(s) = (singleword) m.class_value;
2020 math_spec_family(s) = (singleword) m.family_value;
2021 math_spec_character(s) = m.character_value;
2022 math_spec_properties(s) = (quarterword) d.properties;
2023 math_spec_group(s) = (quarterword) d.group;
2024 math_spec_index(s) = d.index;
2025 return s;
2026}
2027
2028mathcodeval tex_get_math_spec(halfword s)
2029{
2030 mathcodeval m = tex_no_math_code();
2031 if (s) {
2032 m.class_value = math_spec_class(s);
2033 m.family_value = math_spec_family(s);
2034 m.character_value = math_spec_character(s);
2035 }
2036 return m;
2037}
2038
2039mathdictval tex_get_math_dict(halfword s)
2040{
2041 mathdictval d = tex_no_dict_code();
2042 if (s) {
2043 d.properties = math_spec_properties(s);
2044 d.group = math_spec_group(s);
2045 d.index = math_spec_index(s);
2046 }
2047 return d;
2048}
2049
2050halfword tex_scan_math_spec(int optional_equal)
2051{
2052 mathcodeval m;
2053 if (optional_equal) {
2054 tex_scan_optional_equals();
2055 }
2056 m = tex_scan_mathchar(umath_mathcode);
2057 return tex_new_math_spec(m, mathspec_mathcode);
2058}
2059
2060void tex_scan_extdef_math_code(int level, int extcode)
2061{
2062 mathcodeval d;
2063 int chr = tex_scan_char_number(0);
2064 tex_scan_optional_equals();
2065 d = tex_scan_mathchar(extcode);
2066 tex_set_math_code(chr, d, (quarterword) level);
2067}
2068
2069
2070
2071mathcodeval tex_scan_delimiter_as_mathchar(int extcode)
2072{
2073 delcodeval dval = tex_aux_scan_extdef_del_code(extcode, 1);
2074 return dval.small;
2075}
2076
2077
2091
2092
2095
2096static void tex_aux_report_active(int where, const char *what, int code, int character)
2097{
2098 tex_begin_diagnostic();
2099 tex_print_format("[active: location %i, %s, code %i, char %i]",where, what, code, character);
2100 tex_end_diagnostic();
2101}
2102
2103static void tex_aux_append_math_char(mathcodeval mval, mathdictval dval, int automatic);
2104
2105int tex_check_active_math_char(int character)
2106{
2107 halfword code = tex_get_am_code(character);
2108 if (code) {
2109 switch (code) {
2110 case alignment_tab_cmd:
2111 case superscript_cmd:
2112 case subscript_cmd:
2113 case letter_cmd:
2114 case other_char_cmd:
2115 case active_char_cmd:
2116 cur_cmd = code;
2117 cur_chr = character;
2118 cur_tok = token_val(cur_cmd, cur_chr);
2119 if (tracing_commands_par >= 4) {
2120 switch (code) {
2121 case alignment_tab_cmd:
2122 case superscript_cmd:
2123 case subscript_cmd:
2124 tex_aux_report_active(4, "control", code, character);
2125 break;
2126 case letter_cmd:
2127 case other_char_cmd:
2128 tex_aux_report_active(4, "inject", code, character);
2129 break;
2130 case active_char_cmd:
2131 tex_aux_report_active(4, "active", code, character);
2132 break;
2133 }
2134 }
2135 return 1;
2136 default:
2137 if (tracing_commands_par >= 4) {
2138 tex_aux_report_active(4, "ignore", code, character);
2139 }
2140 return 1;
2141 }
2142 } else {
2143 return 0;
2144 }
2145}
2146
2147int tex_pass_active_math_char(int character)
2148{
2149 halfword code = tex_get_am_code(character);
2150 if (code) {
2151 return 1;
2152 } else {
2153 return 0;
2154 }
2155}
2156
2157static int tex_aux_scan_active_math_char(mathcodeval *mval, int where)
2158{
2159 halfword character = mval->character_value;
2160 halfword code = tex_get_am_code(character);
2161 if (code) {
2162 switch (code) {
2163 case alignment_tab_cmd:
2164 case superscript_cmd:
2165 case subscript_cmd:
2166 cur_cmd = code;
2167 cur_chr = character;
2168 cur_tok = token_val(cur_cmd, cur_chr);
2169 tex_back_input(cur_tok);
2170 if (tracing_commands_par >= 4) {
2171 tex_aux_report_active(where, "control", code, character);
2172 }
2173 return 1;
2174 case letter_cmd:
2175 case other_char_cmd:
2176 cur_cmd = code;
2177 cur_chr = character;
2178 cur_tok = token_val(cur_cmd, cur_chr);
2179 if (tracing_commands_par >= 4) {
2180 tex_aux_report_active(where, "inject", code, character);
2181 }
2182 return 0;
2183 case active_char_cmd:
2184
2188 tex_set_am_code(character, other_char_cmd, cur_level);
2189 goto COMMON;
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199 default:
2200 if (tracing_commands_par >= 4) {
2201 tex_aux_report_active(where, "ignore", code, character);
2202 }
2203 return 1;
2204 }
2205 } else if (mval->class_value == active_math_class_value) {
2206
2207 COMMON:
2208 cur_cs = tex_active_to_cs(character, 1);
2209 cur_cmd = eq_type(cur_cs);
2210 cur_chr = eq_value(cur_cs);
2211 tex_x_token();
2212 tex_back_input(cur_tok);
2213 if (tracing_commands_par >= 4) {
2214 tex_aux_report_active(where, "active", code, character);
2215 }
2216 return 1;
2217 } else {
2218
2219
2220
2221 return 0;
2222 }
2223}
2224
2225static int tex_aux_scan_math(halfword target, halfword style, int usetextfont, halfword toks, halfword toks_text, int nocomponent, halfword cls, halfword all)
2226{
2227 mathcodeval mval = tex_no_math_code();
2228 mathdictval dval = tex_no_dict_code();
2229 lmt_math_state.last_atom = cls;
2230 RESTART:
2231 do {
2232 tex_get_x_token();
2233 } while (cur_cmd == spacer_cmd || cur_cmd == relax_cmd);
2234
2235 switch (cur_cmd) {
2236 case char_number_cmd:
2237
2238 cur_chr = tex_scan_char_number(0);
2239
2240 case letter_cmd:
2241 case other_char_cmd:
2242 case char_given_cmd:
2243 mval = tex_get_math_code(cur_chr);
2244 if (tex_aux_scan_active_math_char(&mval, 1)) {
2245 goto RESTART;
2246 } else {
2247 dval = tex_fake_math_dict(mval.character_value);
2248 break;
2249 }
2250
2251
2252
2253
2254
2255 case math_char_number_cmd:
2256 switch (cur_chr) {
2257 case math_char_number_code:
2258 mval = tex_scan_mathchar(tex_mathcode);
2259
2260 break;
2261 case math_xchar_number_code:
2262 mval = tex_scan_mathchar(umath_mathcode);
2263 dval = tex_fake_math_dict(mval.character_value);
2264 break;
2265 case math_char_ignore_code:
2266 break;
2267 default:
2268 tex_confusion("scan math char, case 1");
2269 break;
2270 }
2271 break;
2272 case mathspec_cmd:
2273 mval = tex_get_math_spec(cur_chr);
2274 dval = tex_get_math_dict(cur_chr);
2275 break;
2276 case delimiter_number_cmd:
2277 switch (cur_chr) {
2278 case math_delimiter_code:
2279 mval = tex_scan_delimiter_as_mathchar(tex_mathcode);
2280 break;
2281 case math_udelimiter_code:
2282 mval = tex_scan_delimiter_as_mathchar(umath_mathcode);
2283 break;
2284 default:
2285 tex_confusion("scan math char, case 2");
2286 break;
2287 }
2288 break;
2289 case math_component_cmd:
2290 if (nocomponent) {
2291 goto DEFAULT;
2292 } else {
2293 saved_math_group_initialize();
2294 saved_math_group_all_class = unset_noad_class;
2295 saved_math_group_pointer = target;
2296 lmt_save_state.save_stack_data.ptr += saved_math_group_n_of_records;
2297 tex_aux_push_math(math_component_group, style, -1);
2298 if (usetextfont) {
2299 tex_set_math_text_font(style, usetextfont);
2300 }
2301 tex_aux_math_math_component(cur_list.tail, 0);
2302 tex_finish_math_group();
2303 return 1;
2304 }
2305 case left_brace_cmd:
2306 goto SCAN_SUBFORMULA;
2307 default:
2308
2312 DEFAULT:
2313 tex_back_input(cur_tok);
2314 tex_scan_left_brace();
2315 SCAN_SUBFORMULA:
2316 saved_math_group_initialize();
2317 saved_math_group_all_class = all;
2318 saved_math_group_pointer = target;
2319 lmt_save_state.save_stack_data.ptr += saved_math_group_n_of_records;
2320 tex_aux_push_math(math_group, style, -1);
2321 toks = every_math_atom_par;
2322 toks_text = every_math_atom_text;
2323 if (toks) {
2324 tex_begin_token_list(toks, (quarterword) toks_text);
2325 }
2326 if (usetextfont) {
2327 tex_set_math_text_font(style, usetextfont);
2328 }
2329 return 1;
2330 }
2331 node_type(target) = math_char_node;
2332 if (glyph_options_par & glyph_option_no_italic_correction) {
2333 math_kernel_node_set_option(target, math_kernel_no_italic_correction);
2334 }
2335 if (glyph_options_par & glyph_option_no_left_kern) {
2336 math_kernel_node_set_option(target, math_kernel_no_left_pair_kern);
2337 }
2338 if (glyph_options_par & glyph_option_no_right_kern) {
2339 math_kernel_node_set_option(target, math_kernel_no_right_pair_kern);
2340 }
2341 tex_aux_set_math_char(target, &mval, &dval);
2342 return 0;
2343}
2344
2345
2352
2353static void tex_aux_append_math_accent(mathcodeval mval, mathdictval dval)
2354{
2355 halfword accent = tex_new_node(accent_noad, bothflexible_accent_subtype);
2356 quarterword subtype = ordinary_noad_subtype;
2357 tex_tail_append(accent);
2358 if (! (mval.character_value == 0 && mval.family_value == 0)) {
2359 halfword q = tex_new_node(math_char_node, 0);
2360 subtype = tex_aux_set_math_char(q, &mval, &dval);
2361 accent_top_character(accent) = q;
2362 }
2363 {
2364 halfword q = tex_new_node(math_char_node, subtype);
2365 noad_nucleus(accent) = q;
2366 tex_aux_scan_math(q, tex_math_style_variant(cur_list.math_style, math_parameter_accent_variant), 0, 0, 0, 0, unset_noad_class, unset_noad_class);
2367 }
2368}
2369
2370
2375
2376static void tex_aux_append_math_fence(halfword fence, quarterword mathclass)
2377{
2378 switch (mathclass) {
2379 case open_noad_subtype:
2380 {
2381 tex_aux_push_math(math_fence_group, cur_list.math_style, -1);
2382 node_subtype(fence) = left_fence_side;
2383 node_next(cur_list.head) = fence;
2384 cur_list.tail = fence;
2385 cur_list.delimiter = fence;
2386 }
2387 break;
2388 case close_noad_subtype:
2389 {
2390 halfword q = tex_aux_finish_math_list(fence);
2391 halfword n = tex_new_node(simple_noad, fenced_noad_subtype);
2392 halfword l = tex_new_node(sub_mlist_node, 0);
2393 tex_aux_unsave_math();
2394 tex_tail_append(n);
2395 node_subtype(fence) = right_fence_side;
2396 noad_nucleus(n) = l;
2397 noad_options(n) |= noad_option_unpack_list;
2398 kernel_math_list(noad_nucleus(n)) = q;
2399 }
2400 break;
2401 case middle_noad_subtype:
2402 {
2403 halfword q = tex_aux_finish_math_list(fence);
2404 tex_aux_unsave_math();
2405 tex_aux_push_math(math_fence_group, cur_list.math_style, -1);
2406 node_subtype(fence) = middle_fence_side;
2407 node_next(cur_list.head) = q;
2408 cur_list.tail = fence;
2409 cur_list.delimiter = fence;
2410 }
2411 break;
2412 }
2413}
2414
2415static void tex_aux_append_math_fence_val(mathcodeval mval, mathdictval dval, quarterword mathclass)
2416{
2417 halfword fence = tex_new_node(fence_noad, middle_fence_side);
2418 halfword delimiter = tex_new_node(delimiter_node, mval.class_value);
2419 (void) dval;
2420 fence_delimiter(fence) = delimiter;
2421 delimiter_small_family(delimiter) = mval.family_value;
2422 delimiter_small_character(delimiter) = mval.character_value;
2423 delimiter_large_family(delimiter) = mval.family_value;
2424 delimiter_large_character(delimiter) = mval.character_value;
2425 tex_set_noad_classes(fence, mval.class_value);
2426
2427 noad_options(fence) |= noad_option_no_check;
2428 if (mathclass == middle_noad_subtype && cur_group != math_fence_group) {
2429 tex_aux_append_math_fence_val(tex_no_math_code(), tex_no_dict_code(), open_noad_subtype);
2430 }
2431 tex_aux_append_math_fence(fence, mathclass);
2432}
2433
2434static void tex_trace_continuation_atom(const char *s)
2435{
2436 if (tracing_math_par >= 2) {
2437 tex_begin_diagnostic();
2438 tex_print_format("[math: continuation atom %s]", s);
2439 tex_end_diagnostic();
2440 }
2441}
2442
2443halfword tex_new_math_continuation_atom(halfword node, halfword attr)
2444{
2445 if (! node) {
2446
2447 halfword list = tex_new_node(sub_mlist_node, 0);
2448 node = tex_new_node(simple_noad, ordinary_noad_subtype);
2449 noad_nucleus(node) = list;
2450 tex_trace_continuation_atom("added");
2451 } else if (! tex_math_scripts_allowed(node)) {
2452 tex_trace_continuation_atom("not allowed");
2453 return node;
2454 } else {
2455 tex_trace_continuation_atom("updated");
2456 }
2457 if (math_double_script_mode_par >= 0) {
2458
2459 int options = (math_double_script_mode_par >> 24) & 0xFF;
2460 node_subtype(node) = (math_double_script_mode_par >> 16) & 0xFF;
2461 noad_class_left(node) = (math_double_script_mode_par >> 8) & 0xFF;
2462 noad_class_right(node) = (math_double_script_mode_par >> 0) & 0xFF;
2463 if (options & inherit_class_double_atom_option) {
2464 noad_options(node) |= noad_option_inherit_class;
2465 }
2466 if (options & discard_shape_kern_double_atom_option) {
2467 noad_options(node) |= noad_option_discard_shape_kern;
2468 }
2469 if (options & realign_scripts_double_atom_option) {
2470 noad_options(node) |= noad_option_realign_scripts;
2471 }
2472 if (options & reorder_double_pre_script_atom_option) {
2473 noad_options(node) |= noad_option_reorder_pre_scripts;
2474 }
2475 }
2476 noad_options(node) |= noad_option_continuation;
2477 if (attr) {
2478 tex_attach_attribute_list_copy(node, attr);
2479 }
2480 return node;
2481}
2482
2483static halfword tex_math_double_atom(int followup)
2484{
2485 halfword tail = tex_new_math_continuation_atom(null, cur_list.tail);
2486 tex_math_set_scripts_options(tail);
2487 if (followup && ! has_noad_option_continuation(cur_list.tail)) {
2488 noad_options(cur_list.tail) |= noad_option_continuation_head;
2489 noad_options(cur_list.tail) |= noad_option_continuation_kernel;
2490
2491 }
2492 tex_tail_append(tail);
2493 return tail;
2494}
2495
2496static void tex_aux_append_math_char(mathcodeval mval, mathdictval dval, int automatic)
2497{
2498 if (tex_aux_scan_active_math_char(&mval, 2)) {
2499 return;
2500 } else {
2501 if (automatic && tex_math_has_class_option(mval.class_value, auto_inject_class_option)) {
2502 switch (mval.class_value) {
2503 case accent_noad_subtype:
2504 tex_aux_append_math_accent(mval, dval);
2505 return;
2506 case open_noad_subtype:
2507 case close_noad_subtype:
2508 case middle_noad_subtype:
2509 tex_aux_append_math_fence_val(mval, dval, mval.class_value);
2510 return;
2511 }
2512 }
2513 {
2514 halfword q = tex_new_node(math_char_node, 0);
2515 halfword tail = cur_list.tail;
2516 if (mval.class_value == prime_noad_subtype && tex_math_scripts_allowed(tail)) {
2517 tex_aux_set_math_char(q, &mval, &dval);
2518 if (noad_prime(tail)) {
2519 switch (node_type(noad_prime(tail))) {
2520 case math_char_node:
2521 {
2522 halfword n = tex_new_node(sub_mlist_node, 0);
2523 halfword a = tex_new_node(simple_noad, ordinary_noad_subtype);
2524 halfword b = tex_new_node(simple_noad, ordinary_noad_subtype);
2525 noad_nucleus(a) = noad_prime(tail);
2526 noad_nucleus(b) = q;
2527 tex_couple_nodes(a, b);
2528 kernel_math_list(n) = a;
2529 noad_prime(tail) = n;
2530 break;
2531 }
2532 case sub_mlist_node:
2533 {
2534 halfword n = tex_new_node(simple_noad, ordinary_noad_subtype);
2535 noad_nucleus(n) = q;
2536 tex_couple_nodes(tex_tail_of_node_list(kernel_math_list(noad_prime(tail))),n);
2537 break;
2538 }
2539 default:
2540 {
2541
2542 tex_flush_node_list(noad_prime(tail));
2543 noad_prime(tail) = q;
2544 break;
2545 }
2546 }
2547 } else {
2548 noad_prime(tail) = q;
2549 if (! noad_script_order(tail)) {
2550 noad_script_order(tail) = script_primescript_first;
2551 }
2552 }
2553 } else {
2554 halfword p = tex_new_node(simple_noad, ordinary_noad_subtype);
2555 noad_nucleus(p) = q;
2556 if (glyph_options_par & glyph_option_no_italic_correction) {
2557 math_kernel_node_set_option(q, math_kernel_no_italic_correction);
2558 }
2559 node_subtype(p) = tex_aux_set_math_char(q, &mval, &dval);
2560 tex_math_set_scripts_options(p);
2561 tex_tail_append(p);
2562 }
2563 }
2564 }
2565}
2566
2567
2574
2575static void tex_aux_append_math_char_in_text(mathcodeval mval, mathdictval dval)
2576{
2577 (void) dval;
2578 if (tex_aux_scan_active_math_char(&mval, 3)) {
2579 return;
2580 } else {
2581 halfword p = tex_new_char_node(glyph_character_subtype, tex_fam_fnt(mval.family_value, text_size), mval.character_value, 1);
2582 tex_tail_append(p);
2583 }
2584}
2585
2586void tex_run_math_letter(void)
2587{
2588 tex_aux_append_math_char(tex_get_math_code(cur_chr), tex_fake_math_dict(cur_chr), 1);
2589}
2590
2591void tex_run_math_char_number(void) {
2592
2596 mathcodeval mval = tex_no_math_code();
2597 mathdictval dval = tex_no_dict_code();
2598 cur_chr = tex_scan_char_number(0);
2599 mval.character_value = cur_chr;
2600 mval.family_value = (short) cur_fam_par;
2601
2602 tex_aux_append_math_char(mval, dval, 1);
2603}
2604
2605void tex_run_math_math_spec(void)
2606{
2607 tex_aux_append_math_char(tex_get_math_spec(cur_chr), tex_get_math_dict(cur_chr), 1);
2608}
2609
2610void tex_run_text_math_spec(void)
2611{
2612 tex_aux_append_math_char_in_text(tex_get_math_spec(cur_chr), tex_get_math_dict(cur_chr));
2613}
2614
2615int tex_scan_math_cmd_val(mathcodeval *mval, mathdictval *dval)
2616{
2617 do {
2618 tex_get_x_token();
2619 } while (cur_cmd == spacer_cmd);
2620 switch (cur_cmd) {
2621 case mathspec_cmd:
2622 *mval = tex_get_math_spec(cur_chr);
2623 break;
2624 case math_char_number_cmd:
2625 switch (cur_chr) {
2626 case math_char_number_code:
2627 *mval = tex_scan_mathchar(tex_mathcode);
2628 break;
2629 case math_xchar_number_code:
2630 *mval = tex_scan_mathchar(umath_mathcode);
2631 *dval = tex_fake_math_dict(mval->character_value);
2632 break;
2633 case math_dictionary_number_code:
2634 *dval = tex_scan_mathdict();
2635 *mval = tex_scan_mathchar(umath_mathcode);
2636 break;
2637 case math_char_ignore_code:
2638 break;
2639 default:
2640
2641 return 0;
2642 }
2643 break;
2644 case delimiter_number_cmd:
2645 switch (cur_chr) {
2646 case math_delimiter_code:
2647 *mval = tex_scan_delimiter_as_mathchar(tex_mathcode);
2648 break;
2649 case math_udelimiter_code:
2650 *mval = tex_scan_delimiter_as_mathchar(umath_mathcode);
2651 break;
2652 default:
2653
2654 return 0;
2655 }
2656 break;
2657
2663
2664
2665
2666
2667 default:
2668
2672 {
2673 halfword n = 0;
2674 tex_back_input(cur_tok);
2675 n = tex_scan_integer(0, NULL, NULL);
2676 *mval = tex_mathchar_from_integer(n, umath_mathcode);
2677 }
2678 break;
2679 }
2680 return 1;
2681}
2682
2683int tex_scan_math_code_val(halfword code, mathcodeval *mval, mathdictval *dval)
2684{
2685 switch (code) {
2686 case math_char_number_code:
2687 *mval = tex_scan_mathchar(tex_mathcode);
2688 break;
2689 case math_xchar_number_code:
2690 *mval = tex_scan_mathchar(umath_mathcode);
2691 *dval = tex_fake_math_dict(mval->character_value);
2692 break;
2693 case math_dictionary_number_code:
2694 *dval = tex_scan_mathdict();
2695 *mval = tex_scan_mathchar(umath_mathcode);
2696 break;
2697 case math_class_number_code:
2698 {
2699 halfword family = cur_fam_par;
2700 halfword mathclass = tex_scan_math_class_number(0);
2701 tex_scan_math_cmd_val(mval, dval);
2702 mval->class_value = (short) mathclass;
2703 mval->family_value = (short) family;
2704 }
2705 break;
2706 case math_char_ignore_code:
2707 break;
2708 default:
2709
2710 tex_back_input(cur_tok);
2711 return 0;
2712 }
2713 return 1;
2714}
2715
2716void tex_run_text_math_char_number(void) {
2717 mathcodeval mval = tex_no_math_code();
2718 mathdictval dval = tex_no_dict_code();
2719 if (tex_scan_math_code_val(cur_chr, &mval, &dval)) {
2720 tex_aux_append_math_char_in_text(mval, dval);
2721 }
2722}
2723
2724void tex_run_math_math_char_number(void) {
2725 mathcodeval mval = tex_no_math_code();
2726 mathdictval dval = tex_no_dict_code();
2727 if (tex_scan_math_code_val(cur_chr, &mval, &dval)) {
2728 tex_aux_append_math_char(mval, dval, 1);
2729 }
2730}
2731
2732void tex_run_math_delimiter_number(void) {
2733 switch (cur_chr) {
2734 case math_delimiter_code:
2735 tex_aux_append_math_char(tex_scan_delimiter_as_mathchar(tex_mathcode), tex_no_dict_code(), 0);
2736 break;
2737 case math_udelimiter_code:
2738 tex_aux_append_math_char(tex_scan_delimiter_as_mathchar(umath_mathcode), tex_no_dict_code(), 0);
2739 break;
2740 }
2741}
2742
2743
2748
2749static void tex_aux_math_math_component(halfword target, int append)
2750{
2751 quarterword subtype = unset_noad_class;
2752 quarterword allclass = unset_noad_class;
2753 halfword style = cur_list.math_style;
2754 int usetextfont = math_atom_no_font_option;
2755 tex_reset_noad_classes(target);
2756 switch (cur_chr) {
2757 case math_component_ordinary_code:
2758 subtype = ordinary_noad_subtype;
2759 break;
2760 case math_component_operator_code:
2761 subtype = operator_noad_subtype;
2762 break;
2763 case math_component_binary_code:
2764 subtype = binary_noad_subtype;
2765 break;
2766 case math_component_relation_code:
2767 subtype = relation_noad_subtype;
2768 break;
2769 case math_component_open_code:
2770 subtype = open_noad_subtype;
2771 break;
2772 case math_component_close_code:
2773 subtype = close_noad_subtype;
2774 break;
2775 case math_component_punctuation_code:
2776 subtype = punctuation_noad_subtype;
2777 break;
2778 case math_component_variable_code:
2779 subtype = variable_noad_subtype;
2780 break;
2781 case math_component_inner_code:
2782 subtype = inner_noad_subtype;
2783 break;
2784 case math_component_under_code:
2785 subtype = under_noad_subtype;
2786 style = tex_math_style_variant(style, math_parameter_under_line_variant);
2787 break;
2788 case math_component_over_code:
2789 subtype = over_noad_subtype;
2790 style = tex_math_style_variant(style, math_parameter_over_line_variant);
2791 break;
2792 case math_component_fraction_code:
2793 subtype = fraction_noad_subtype;
2794 break;
2795 case math_component_radical_code:
2796 subtype = radical_noad_subtype;
2797 break;
2798 case math_component_middle_code:
2799 subtype = middle_noad_subtype;
2800 break;
2801 case math_component_accent_code:
2802 subtype = accent_noad_subtype;
2803 break;
2804 case math_component_fenced_code:
2805 subtype = fenced_noad_subtype;
2806 break;
2807 case math_component_ghost_code:
2808 subtype = ghost_noad_subtype;
2809 break;
2810 case math_component_atom_code:
2811 {
2812 halfword attrlist = null;
2813 while (1) {
2814 switch (tex_scan_character("aclmnoprstuvACLMNOPRSTUV", 0, 1, 0)) {
2815 case 'a': case 'A':
2816 switch (tex_scan_character("ltLT", 0, 0, 0)) {
2817 case 'l': case 'L':
2818 if (tex_scan_mandate_keyword("all", 2)) {
2819 allclass = (quarterword) tex_scan_math_class_number(0);
2820 if (! valid_math_class_code(allclass)) {
2821 allclass = unset_noad_class;
2822 }
2823 }
2824 break;
2825 case 't': case 'T':
2826 if (tex_scan_mandate_keyword("attr", 2)) {
2827 attrlist = tex_scan_attribute(attrlist);
2828 }
2829 break;
2830 default:
2831 tex_aux_show_keyword_error("attr|all");
2832 goto DONE;
2833 }
2834 break;
2835 case 'c': case 'C':
2836 switch (tex_scan_character("aloLAO", 0, 0, 0)) {
2837 case 'a': case 'A':
2838 if (tex_scan_mandate_keyword("carryover", 2)) {
2839 noad_options(target) |= noad_option_carry_over_classes;
2840 }
2841 break;
2842 case 'l': case 'L':
2843 if (tex_scan_mandate_keyword("class", 2)) {
2844 subtype = (quarterword) tex_scan_math_class_number(0);
2845 if (! valid_math_class_code(subtype)) {
2846 subtype = ordinary_noad_subtype;
2847 }
2848 set_noad_main_class(target, subtype);
2849 }
2850 break;
2851 case 'o': case 'O':
2852 if (tex_scan_mandate_keyword("continuation", 2)) {
2853 noad_options(target) |= noad_option_continuation;
2854 }
2855 break;
2856 default:
2857 tex_aux_show_keyword_error("class|continuation");
2858 goto DONE;
2859 }
2860 break;
2861 case 'l': case 'L':
2862 switch (tex_scan_character("eiEI", 0, 0, 0)) {
2863 case 'e': case 'E':
2864 if (tex_scan_mandate_keyword("leftclass", 2)) {
2865 halfword c = tex_scan_math_class_number(0);
2866 if (! valid_math_class_code(c)) {
2867 c = ordinary_noad_subtype;
2868 }
2869 set_noad_left_class(target, c);
2870 }
2871 break;
2872 case 'i': case 'I':
2873 if (tex_scan_mandate_keyword("limits", 2)) {
2874 noad_options(target) |= noad_option_limits;
2875 }
2876 break;
2877 default:
2878 tex_aux_show_keyword_error("leftclass|limits");
2879 goto DONE;
2880 }
2881 break;
2882 case 'm': case 'M':
2883 if (tex_scan_mandate_keyword("mathfont", 1)) {
2884 usetextfont = math_atom_math_font_option;
2885 }
2886 break;
2887 case 'n': case 'N':
2888
2889 if (tex_scan_character("oO", 0, 0, 0)) {
2890 switch (tex_scan_character("loLO", 0, 0, 0)) {
2891 case 'l': case 'L':
2892 if (tex_scan_mandate_keyword("nolimits", 3)) {
2893 noad_options(target) |= noad_option_no_limits;
2894 }
2895 break;
2896 case 'o': case 'O':
2897 if (tex_scan_mandate_keyword("nooverflow", 3)) {
2898 noad_options(target) |= noad_option_no_overflow;
2899 }
2900 break;
2901 default:
2902 tex_aux_show_keyword_error("nolimits|nooverflow");
2903 goto DONE;
2904 }
2905 }
2906 break;
2907 case 'o': case 'O':
2908
2909 if (tex_scan_mandate_keyword("options", 1)) {
2910 noad_options(target) = tex_scan_integer(0, NULL, NULL);
2911 }
2912 break;
2913 case 'p': case 'P':
2914 if (tex_scan_mandate_keyword("phantom", 1)) {
2915 noad_options(target) |= noad_option_phantom;
2916 }
2917 break;
2918 case 'r': case 'R':
2919 if (tex_scan_mandate_keyword("rightclass", 1)) {
2920 halfword c = tex_scan_math_class_number(0);
2921 if (! valid_math_class_code(c)) {
2922 c = ordinary_noad_subtype;
2923 }
2924 set_noad_right_class(target, c);
2925 }
2926 break;
2927 case 's': case 'S':
2928 switch (tex_scan_character("ioIO", 0, 0, 0)) {
2929 case 'i': case 'I':
2930 if (tex_scan_mandate_keyword("single", 2)) {
2931 noad_options(target) |= noad_option_single;
2932 }
2933 break;
2934 case 'o': case 'O':
2935 if (tex_scan_mandate_keyword("source", 2)) {
2936 noad_source(target) = tex_scan_integer(0, NULL, NULL);
2937 }
2938 break;
2939 default:
2940 tex_aux_show_keyword_error("single|source");
2941 goto DONE;
2942 }
2943 break;
2944 case 't': case 'T':
2945 if (tex_scan_mandate_keyword("textfont", 1)) {
2946 usetextfont = math_atom_text_font_option;
2947 }
2948 break;
2949 case 'u': case 'U':
2950
2951 if (tex_scan_character("nN", 0, 0, 0)) {
2952 switch (tex_scan_character("prPR", 0, 0, 0)) {
2953 case 'p': case 'P':
2954 if (tex_scan_mandate_keyword("unpack", 3)) {
2955 noad_options(target) |= noad_option_unpack_list;
2956 }
2957 break;
2958 case 'r': case 'R':
2959 if (tex_scan_mandate_keyword("unroll", 3)) {
2960 noad_options(target) |= noad_option_unroll_list;
2961 }
2962 break;
2963 default:
2964 tex_aux_show_keyword_error("unpack|unroll");
2965 goto DONE;
2966 }
2967 }
2968 break;
2969 case 'v': case 'V':
2970 if (tex_scan_mandate_keyword("void", 1)) {
2971 noad_options(target) |= noad_option_void;
2972 }
2973 break;
2974 default:
2975 goto DONE;
2976 }
2977 }
2978 DONE:
2979 if (attrlist) {
2980 tex_attach_attribute_list_attribute(target, attrlist);
2981 }
2982 if (subtype == unset_noad_class) {
2983 if (get_noad_left_class(target) != unset_noad_class && get_noad_right_class(target) != unset_noad_class) {
2984 subtype = ordinary_noad_subtype;
2985 } else {
2986
2987 subtype = (quarterword) tex_scan_math_class_number(0);
2988 }
2989 }
2990 }
2991 break;
2992 }
2993 if (! valid_math_class_code(subtype)) {
2994 subtype = ordinary_noad_subtype;
2995 }
2996
2999 {
3000 halfword content = tex_new_node(math_char_node, 0);
3001 noad_nucleus(target) = content;
3002 node_subtype(target) = subtype;
3003 if (append) {
3004 tex_tail_append(target);
3005 }
3006 tex_aux_scan_math(content, style, usetextfont, 0, 0, 0, subtype, allclass);
3007 }
3008}
3009
3010void tex_run_math_math_component(void)
3011{
3012 halfword n = tex_new_node(simple_noad, ordinary_noad_subtype);
3013 tex_math_set_scripts_options(n);
3014 tex_aux_math_math_component(n, 1);
3015}
3016
3017int tex_is_math_disc(halfword n)
3018{
3019 return
3020 n && node_type(n) == hlist_node && box_list(n) && node_type(box_list(n)) == disc_node &&
3021 disc_class(box_list(n)) != unset_disc_class && ! node_next(box_list(n));
3022}
3023
3024halfword tex_math_make_disc(halfword d)
3025{
3026 halfword q = tex_new_node(sub_mlist_node, 0);
3027 halfword n = tex_new_node(simple_noad, (quarterword) disc_class(d));
3028 kernel_math_list(q) = d;
3029 noad_nucleus(n) = q;
3030 noad_options(n) = noad_option_unpack_list;
3031 return n;
3032}
3033
3034
3038
3039void tex_run_math_modifier(void)
3040{
3041 halfword tail = cur_list.tail;
3042 if (cur_list.head != tail) {
3043 switch (node_type(tail)) {
3044 case simple_noad:
3045 switch (cur_chr) {
3046 case adapt_to_left_modifier_code:
3047 noad_options(tail) = unset_option(noad_options(tail), noad_option_adapt_to_right_size);
3048 noad_options(tail) |= noad_option_adapt_to_left_size;
3049 break;
3050 case adapt_to_right_modifier_code:
3051 noad_options(tail) = unset_option(noad_options(tail), noad_option_adapt_to_left_size);
3052 noad_options(tail) |= noad_option_adapt_to_right_size;
3053 break;
3054
3055 case axis_modifier_code:
3056 noad_options(tail) |= noad_option_axis;
3057 break;
3058 case no_axis_modifier_code:
3059 noad_options(tail) |= noad_option_no_axis;
3060 break;
3061 case phantom_modifier_code:
3062 noad_options(tail) |= noad_option_phantom;
3063 break;
3064 case void_modifier_code:
3065 noad_options(tail) |= noad_option_void;
3066 break;
3067 case source_modifier_code:
3068 if (tex_scan_keyword("nucleus")) {
3069 noad_options(tail) |= noad_option_source_on_nucleus;
3070 }
3071 noad_source(tail) = tex_scan_integer(0, NULL, NULL);
3072 break;
3073 case openup_height_modifier_code:
3074 noad_options(tail) |= noad_option_openup_height;
3075 noad_height(tail) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
3076 break;
3077 case openup_depth_modifier_code:
3078 noad_options(tail) |= noad_option_openup_depth;
3079 noad_depth(tail) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
3080 break;
3081 case display_limits_modifier_code:
3082 noad_options(tail) = unset_option(noad_options(tail), noad_option_limits | noad_option_no_limits);
3083 break;
3084 case limits_modifier_code:
3085 noad_options(tail) = unset_option(noad_options(tail), noad_option_no_limits);
3086 noad_options(tail) |= noad_option_limits;
3087 break;
3088 case no_limits_modifier_code:
3089 noad_options(tail) = unset_option(noad_options(tail), noad_option_limits);
3090 noad_options(tail) |= noad_option_no_limits;
3091 break;
3092 }
3093 default:
3094 switch (node_type(tail)) {
3095 case accent_noad:
3096 switch (cur_chr) {
3097 case source_modifier_code:
3098 if (tex_scan_keyword("nucleus")) {
3099 noad_options(tail) |= noad_option_source_on_nucleus;
3100 }
3101 noad_source(tail) = tex_scan_integer(0, NULL, NULL);
3102 break;
3103 }
3104
3105 }
3106 break;
3107 }
3108 }
3109}
3110
3111
3118
3119static void tex_aux_scan_delimiter(halfword target, int code, int mathclass)
3120{
3121 delcodeval dval = tex_no_del_code();
3122 mathcodeval mval = tex_no_math_code();
3123 switch (code) {
3124 case no_mathcode:
3125
3126 do {
3127 tex_get_x_token();
3128 } while (cur_cmd == spacer_cmd || cur_cmd == relax_cmd);
3129 switch (cur_cmd) {
3130 case letter_cmd:
3131 case other_char_cmd:
3132 dval = tex_get_del_code(cur_chr);
3133 if (tex_has_del_code(dval)) {
3134 goto REALDELIMITER;
3135 } else {
3136 mval = tex_get_math_code(cur_chr);
3137 goto FAKEDELIMITER;
3138 }
3139 case delimiter_number_cmd:
3140 switch (cur_chr) {
3141 case math_delimiter_code:
3142
3143 dval = tex_aux_scan_extdef_del_code(tex_mathcode, 1);
3144 break;
3145 case math_udelimiter_code:
3146
3147 dval = tex_aux_scan_extdef_del_code(umath_mathcode, 1);
3148 break;
3149 default:
3150 tex_confusion("scan delimiter, case 1");
3151 break;
3152 }
3153 goto REALDELIMITER;
3154 case mathspec_cmd:
3155 mval = tex_get_math_spec(cur_chr);
3156 goto FAKEDELIMITER;
3157 case math_char_number_cmd:
3158 switch (cur_chr) {
3159 case math_char_number_code:
3160 mval = tex_scan_mathchar(tex_mathcode);
3161 break;
3162 case math_xchar_number_code:
3163 mval = tex_scan_mathchar(umath_mathcode);
3164 break;
3165 case math_char_ignore_code:
3166 break;
3167 default:
3168 tex_confusion("scan math char, case 1");
3169 break;
3170 }
3171 goto FAKEDELIMITER;
3172 }
3173 break;
3174 case tex_mathcode:
3175
3176 dval = tex_aux_scan_extdef_del_code(tex_mathcode, 1);
3177 goto REALDELIMITER;
3178 case umath_mathcode:
3179
3180 dval = tex_aux_scan_extdef_del_code(umath_mathcode, 0);
3181 goto REALDELIMITER;
3182 default:
3183 tex_confusion("scan delimiter, case 2");
3184 goto REALDELIMITER;
3185 }
3186 FAKEDELIMITER:
3187 if (mathclass != unset_noad_class) {
3188 mval.class_value = (short) mathclass;
3189 }
3190 dval.small = mval;
3191 dval.large = mval;
3192 REALDELIMITER:
3193 if (! target) {
3194 return;
3195 } else if (tex_has_del_code(dval)) {
3196 mathdictval dict = tex_fake_math_dict(dval.small.character_value);
3197 node_subtype(target) = dval.small.class_value;
3198 delimiter_small_family(target) = dval.small.family_value;
3199 delimiter_small_character(target) = dval.small.character_value;
3200 delimiter_large_family(target) = dval.large.family_value;
3201 delimiter_large_character(target) = dval.large.character_value;
3202 delimiter_math_properties(target) = dict.properties;
3203 delimiter_math_group(target) = dict.group;
3204 delimiter_math_index(target) = dict.index;
3205 } else {
3206 tex_back_input(cur_tok);
3207 tex_handle_error(
3208 normal_error_type,
3209 "Missing delimiter (. inserted)",
3210 "I was expecting to see something like '(' or '\\{' or '\\}' here. Acceptable\n"
3211 "delimiters are characters whose \\delcode is nonnegative, or you can use\n"
3212 "'\\delimiter <delimiter code>'."
3213 );
3214 node_subtype(target) = unset_noad_class;
3215 delimiter_small_family(target) = 0;
3216 delimiter_small_character(target) = 0;
3217 delimiter_large_family(target) = 0;
3218 delimiter_large_character(target) = 0;
3219 }
3220 return;
3221}
3222
3223void tex_run_math_radical(void)
3224{
3225 halfword code = cur_chr;
3226 fullword options = 0;
3227 halfword radical = tex_new_node(radical_noad, (quarterword) code);
3228 halfword style = yet_unset_math_style;
3229 halfword variant = 0;
3230 halfword attrlist = null;
3231 halfword symbolattrlist = null;
3232 halfword top = null;
3233 halfword bottom = null;
3234 tex_tail_append_callback(radical);
3235
3236 while (1) {
3237 switch (tex_scan_character("abdehlmnrstuwABDEHLMNRSTUW", 0, 1, 0)) {
3238 case 0:
3239 goto DONE;
3240 case 'a': case 'A':
3241 if (tex_scan_mandate_keyword("attr", 1)) {
3242 attrlist = tex_scan_attribute(attrlist);
3243 }
3244 break;
3245 case 'b': case 'B':
3246 if (tex_scan_mandate_keyword("bottom", 1)) {
3247 bottom = 1;
3248 }
3249 break;
3250 case 'd': case 'D':
3251 if (tex_scan_mandate_keyword("depth", 1)) {
3252 radical_depth(radical) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
3253 }
3254 break;
3255 case 'e': case 'E':
3256 if (tex_scan_mandate_keyword("exact", 1)) {
3257 options = options | noad_option_exact;
3258 }
3259 break;
3260 case 'h': case 'H':
3261 if (tex_scan_mandate_keyword("height", 1)) {
3262 radical_height(radical) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
3263 }
3264 break;
3265 case 'l': case 'L':
3266 if (tex_scan_mandate_keyword("left", 1)) {
3267 options = options | noad_option_left;
3268 }
3269 break;
3270 case 'm': case 'M':
3271 if (tex_scan_mandate_keyword("middle", 1)) {
3272 options = options | noad_option_middle;
3273 }
3274 break;
3275 case 'n': case 'N':
3276 switch (tex_scan_character("oO", 0, 0, 0)) {
3277 case 'o': case 'O':
3278 switch (tex_scan_character("orOR", 0, 0, 0)) {
3279 case 'r': case 'R':
3280 if (tex_scan_mandate_keyword("norule", 3)) {
3281 options |= noad_option_no_rule;
3282 }
3283 break;
3284 case 'o': case 'O':
3285 if (tex_scan_mandate_keyword("nooverflow", 3)) {
3286 options |= noad_option_no_overflow;
3287 }
3288 break;
3289 default:
3290 tex_aux_show_keyword_error("norule|nooverflow");
3291 goto DONE;
3292 }
3293 break;
3294 default:
3295 tex_aux_show_keyword_error("norule|nooverflow");
3296 goto DONE;
3297 }
3298 break;
3299 case 'r': case 'R':
3300 switch (tex_scan_character("ieIE", 0, 0, 0)) {
3301 case 'i': case 'I':
3302 if (tex_scan_mandate_keyword("right", 2)) {
3303 options = options | noad_option_right;
3304 }
3305 break;
3306 case 'e': case 'E':
3307 if (tex_scan_mandate_keyword("reflected", 2)) {
3308 options |= noad_option_reflected;
3309 }
3310 break;
3311 default:
3312 tex_aux_show_keyword_error("right|reflected");
3313 goto DONE;
3314 }
3315 break;
3316 case 's': case 'S':
3317 switch (tex_scan_character("hiotyHIOTY", 0, 0, 0)) {
3318 case 'h': case 'H':
3319 if (tex_scan_mandate_keyword("shrink", 2)) {
3320 options = options | noad_option_shrink;
3321 }
3322 break;
3323 case 'i': case 'I':
3324 if (tex_scan_mandate_keyword("size", 2)) {
3325 radical_size(radical) = tex_scan_integer(0, NULL, NULL);
3326 }
3327 break;
3328 case 't': case 'T':
3329 switch (tex_scan_character("ryRY", 0, 0, 0)) {
3330 case 'r': case 'R':
3331 if (tex_scan_mandate_keyword("stretch", 3)) {
3332 options = options | noad_option_stretch;
3333 }
3334 break;
3335 case 'y': case 'Y':
3336 if (tex_scan_mandate_keyword("style", 3)) {
3337 switch (code) {
3338 case normal_radical_subtype:
3339 case radical_radical_subtype:
3340 case root_radical_subtype:
3341 case rooted_radical_subtype:
3342 case delimited_radical_subtype:
3343 style = tex_scan_math_style_identifier(1, 0);
3344 if (style < 0) {
3345 style = yet_unset_math_style;
3346 }
3347 break;
3348 default:
3349
3350 break;
3351 }
3352 }
3353 break;
3354 default:
3355 tex_aux_show_keyword_error("style|stretch");
3356 goto DONE;
3357 }
3358 break;
3359 case 'o': case 'O':
3360 if (tex_scan_mandate_keyword("source", 2)) {
3361 noad_source(radical) = tex_scan_integer(0, NULL, NULL);
3362 }
3363 break;
3364 case 'y': case 'Y':
3365 if (tex_scan_mandate_keyword("symbolattr", 2)) {
3366 symbolattrlist = tex_scan_extra_attribute(symbolattrlist);
3367 }
3368 break;
3369 default:
3370 tex_aux_show_keyword_error("style|source|stretch|shrink|symbolattr");
3371 goto DONE;
3372 }
3373 break;
3374 case 't': case 'T':
3375 if (tex_scan_mandate_keyword("top", 1)) {
3376 top = 1;
3377 }
3378 break;
3379 case 'u': case 'U':
3380 if (tex_scan_mandate_keyword("usecallback", 1)) {
3381 options = options | noad_option_use_callback;
3382 }
3383 break;
3384 case 'w': case 'W':
3385 if (tex_scan_mandate_keyword("width", 1)) {
3386 noad_width(radical) = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
3387 }
3388 break;
3389 default:
3390 goto DONE;
3391 }
3392 }
3393 DONE:
3394 if (style == yet_unset_math_style) {
3395 switch (code) {
3396 case normal_radical_subtype:
3397 case radical_radical_subtype:
3398 case root_radical_subtype:
3399 variant = math_parameter_radical_variant;
3400 break;
3401 case under_delimiter_radical_subtype:
3402 variant = math_parameter_under_delimiter_variant;
3403 break;
3404 case over_delimiter_radical_subtype:
3405 variant = math_parameter_over_delimiter_variant;
3406 break;
3407 case delimiter_under_radical_subtype:
3408 variant = math_parameter_delimiter_under_variant;
3409 break;
3410 case delimiter_over_radical_subtype:
3411 variant = math_parameter_delimiter_over_variant;
3412 break;
3413 case delimited_radical_subtype:
3414 variant = math_parameter_radical_variant;
3415 break;
3416 case h_extensible_radical_subtype:
3417 variant = math_parameter_h_extensible_variant;
3418 break;
3419 }
3420 style = variant ? tex_math_style_variant(cur_list.math_style, variant) : cur_list.math_style;
3421 }
3422 if (attrlist) {
3423 tex_attach_attribute_list_attribute(radical, attrlist);
3424 }
3425 if (symbolattrlist) {
3426 add_attribute_reference(symbolattrlist);
3427 noad_extra_attr(radical) = symbolattrlist;
3428 }
3429 noad_options(radical) = options;
3430 set_noad_style(radical, style);
3431 {
3432 switch (code) {
3433 case normal_radical_subtype:
3434 {
3435 halfword left = tex_new_node(delimiter_node, 0);
3436 radical_left_delimiter(radical) = left;
3437 tex_aux_scan_delimiter(left, tex_mathcode, unset_noad_class);
3438 }
3439 break;
3440 case radical_radical_subtype:
3441 case root_radical_subtype:
3442 case rooted_radical_subtype:
3443 case delimited_radical_subtype:
3444 {
3445 halfword left = tex_new_node(delimiter_node, 0);
3446 radical_left_delimiter(radical) = left;
3447 tex_aux_scan_delimiter(left, umath_mathcode, unset_noad_class);
3448 }
3449 switch (code) {
3450 case rooted_radical_subtype:
3451 case delimited_radical_subtype:
3452 {
3453 halfword right = tex_new_node(delimiter_node, 0);
3454 radical_right_delimiter(radical) = right;
3455 tex_aux_scan_delimiter(right, umath_mathcode, unset_noad_class);
3456 }
3457 }
3458 break;
3459 case under_delimiter_radical_subtype:
3460 case over_delimiter_radical_subtype:
3461 case delimiter_under_radical_subtype:
3462 case delimiter_over_radical_subtype:
3463 case h_extensible_radical_subtype:
3464 {
3465 halfword left = tex_new_node(delimiter_node, 0);
3466 radical_left_delimiter(radical) = left;
3467 tex_aux_scan_delimiter(left, umath_mathcode, unset_noad_class);
3468 }
3469 break;
3470 default:
3471 tex_confusion("scan math radical");
3472 break;
3473 }
3474 if (top) {
3475 top = tex_new_node(delimiter_node, 0);
3476 radical_top_delimiter(radical) = top;
3477 tex_aux_scan_delimiter(top, umath_mathcode, unset_noad_class);
3478 }
3479 if (bottom) {
3480 bottom = tex_new_node(delimiter_node, 0);
3481 radical_bottom_delimiter(radical) = bottom;
3482 tex_aux_scan_delimiter(bottom, umath_mathcode, unset_noad_class);
3483 }
3484 }
3485 switch (code) {
3486 case h_extensible_radical_subtype:
3487
3488 {
3489 halfword q = tex_new_node(sub_box_node, 0);
3490 noad_nucleus(radical) = q;
3491 break;
3492 }
3493 case root_radical_subtype:
3494 case rooted_radical_subtype:
3495 {
3496
3497 saved_radical_initialize();
3498 saved_radical_degree_done = 0;
3499 saved_radical_style = style;
3500 lmt_save_state.save_stack_data.ptr += saved_radical_n_of_records;
3501 tex_aux_push_math(math_radical_group, tex_math_style_variant(style, math_parameter_degree_variant), -1);
3502 tex_scan_left_brace();
3503 break;
3504 }
3505 default :
3506 {
3507 halfword q = tex_new_node(math_char_node, 0);
3508 noad_nucleus(radical) = q;
3509 tex_aux_scan_math(q, tex_math_style_variant(style, variant ? variant : math_parameter_radical_variant), 0, 0, 0, 0, unset_noad_class, unset_noad_class);
3510 break;
3511 }
3512 }
3513}
3514
3515void tex_finish_math_radical(void)
3516{
3517 tex_aux_unsave_math();
3518 {
3519 halfword whatever = tex_new_node(sub_mlist_node, 0);
3520 halfword content = tex_aux_finish_math_list(null);
3521 halfword radical = cur_list.tail;
3522 kernel_math_list(whatever) = content;
3523 switch (saved_radical_current_component()) {
3524 case 0:
3525 {
3526 halfword style = saved_radical_current_style();
3527 radical_degree(radical) = whatever;
3528 saved_radical_update_component();
3529 tex_aux_push_math(math_radical_group, tex_math_style_variant(style, math_parameter_radical_variant), -1);
3530 tex_scan_left_brace();
3531 }
3532 break;
3533 case 1:
3534 {
3535 noad_nucleus(radical) = whatever;
3536 lmt_save_state.save_stack_data.ptr -= saved_radical_n_of_records;
3537 }
3538 break;
3539 default:
3540 tex_confusion("scan radical");
3541 break;
3542 }
3543 }
3544}
3545
3546void tex_run_math_accent(void)
3547{
3548 mathcodeval t = tex_no_math_code();
3549 mathcodeval b = tex_no_math_code();
3550 mathcodeval o = tex_no_math_code();
3551 halfword code = cur_chr;
3552 halfword accent = tex_new_node(accent_noad, bothflexible_accent_subtype);
3553 quarterword subtype = ordinary_noad_subtype;
3554 halfword mathclass = accent_noad_subtype;
3555 halfword attrlist = null;
3556 halfword symbolattrlist = null;
3557 if (cur_cmd == accent_cmd) {
3558 tex_handle_error(
3559 normal_error_type,
3560 "Please use \\mathaccent for accents in math mode",
3561 "I'm changing \\accent to \\mathaccent here; wish me luck. (Accents are not the\n"
3562 "same in formulas as they are in text.)" );
3563 }
3564 tex_tail_append_callback(accent);
3565 switch (code) {
3566 case math_accent_code:
3567
3568 t = tex_scan_mathchar(tex_mathcode);
3569 break;
3570 case math_uaccent_code:
3571
3572 while (1) {
3573 switch (tex_scan_character("abcefknostuABCEFKNOSTU", 0, 1, 0)) {
3574 case 'a': case 'A':
3575 switch (tex_scan_character("txTX", 0, 0, 0)) {
3576 case 't': case 'T':
3577 if (tex_scan_mandate_keyword("attr", 2)) {
3578 attrlist = tex_scan_attribute(attrlist);
3579 }
3580 break;
3581
3582
3583
3584
3585
3586 default:
3587
3588 tex_aux_show_keyword_error("attr");
3589 goto DONE;
3590 }
3591 break;
3592 case 'b': case 'B':
3593 switch (tex_scan_character("aoAo", 0, 0, 0)) {
3594 case 'a': case 'A':
3595 if (tex_scan_mandate_keyword("base", 2)) {
3596 noad_options(accent) |= noad_option_auto_base;
3597 }
3598 break;
3599 case 'o': case 'O':
3600
3601
3602 if (tex_scan_character("t", 0, 0, 0)) {
3603 switch (tex_scan_character("htHT", 0, 0, 0)) {
3604 case 'h': case 'H':
3605
3606 if (tex_scan_keyword("fixed")) {
3607 node_subtype(accent) = fixedtop_accent_subtype;
3608 }
3609 t = tex_scan_mathchar(umath_mathcode);
3610 if (tex_scan_keyword("fixed")) {
3611 node_subtype(accent) = fixedboth_accent_subtype;
3612 }
3613 b = tex_scan_mathchar(umath_mathcode);
3614 goto DONE;
3615 case 't': case 'T':
3616 if (tex_scan_mandate_keyword("bottom", 4)) {
3617
3618 if (tex_scan_keyword("fixed")) {
3619 node_subtype(accent) = fixedbottom_accent_subtype;
3620 }
3621 b = tex_scan_mathchar(umath_mathcode);
3622 }
3623 goto DONE;
3624 default:
3625 tex_aux_show_keyword_error("both|bottom");
3626 goto DONE;
3627 }
3628 }
3629 goto DONE;
3630 default:
3631 tex_aux_show_keyword_error("base|both|bottom");
3632 goto DONE;
3633 }
3634 break;
3635 case 'c': case 'C':
3636 switch (tex_scan_character("elEL", 0, 0, 0)) {
3637 case 'e': case 'E':
3638 if (tex_scan_mandate_keyword("center", 2)) {
3639 noad_options(accent) |= noad_option_center;
3640 }
3641 break;
3642 case 'l': case 'L':
3643 if (tex_scan_mandate_keyword("class", 2)) {
3644 halfword c = (quarterword) tex_scan_math_class_number(0);
3645 if (valid_math_class_code(c)) {
3646 mathclass = c;
3647 }
3648 }
3649 break;
3650 default:
3651 tex_aux_show_keyword_error("center|class");
3652 goto DONE;
3653 }
3654 break;
3655 case 'e': case 'E':
3656 if (tex_scan_mandate_keyword("exact", 1)) {
3657 noad_options(accent) |= noad_option_exact;
3658 }
3659 break;
3660 case 'f': case 'F':
3661 switch (tex_scan_character("frFR", 0, 0, 0)) {
3662 case 'r': case 'R':
3663 if (tex_scan_mandate_keyword("fraction", 2)) {
3664 accent_fraction(accent) = tex_scan_integer(0, NULL, NULL);
3665 }
3666 break;
3667 case 'f': case 'F':
3668
3669 if (tex_scan_mandate_keyword("fixed", 2)) {
3670 node_subtype(accent) = fixedtop_accent_subtype;
3671 t = tex_scan_mathchar(umath_mathcode);
3672 }
3673 goto DONE;
3674 default:
3675 tex_aux_show_keyword_error("fraction|fixed");
3676 goto DONE;
3677 }
3678 case 'k': case 'K':
3679 if (tex_scan_mandate_keyword("keepbase", 1)) {
3680 noad_options(accent) |= noad_option_keep_base;
3681 }
3682 break;
3683 case 'n': case 'N':
3684 if (tex_scan_mandate_keyword("nooverflow", 1)) {
3685
3689 noad_options(accent) |= noad_option_no_overflow;
3690 }
3691 break;
3692 case 'o': case 'O':
3693
3694 if (tex_scan_mandate_keyword("overlay", 1)) {
3695 if (tex_scan_keyword("fixed")) {
3696 node_subtype(accent) = fixedtop_accent_subtype;
3697 }
3698 o = tex_scan_mathchar(umath_mathcode);
3699 }
3700 goto DONE;
3701 case 's': case 'S':
3702 switch (tex_scan_character("hiotyHIOTY", 0, 0, 0)) {
3703 case 'h': case 'H':
3704 if (tex_scan_mandate_keyword("shrink", 2)) {
3705 noad_options(accent) |= noad_option_shrink;
3706 }
3707 break;
3708 case 'i': case 'I':
3709 if (tex_scan_mandate_keyword("single", 2)) {
3710 noad_options(accent) |= noad_option_single;
3711 }
3712 break;
3713 case 'o': case 'O':
3714 if (tex_scan_mandate_keyword("source", 2)) {
3715 noad_source(accent) = tex_scan_integer(0, NULL, NULL);
3716 }
3717 break;
3718 case 't': case 'T':
3719 if (tex_scan_mandate_keyword("stretch", 2)) {
3720 noad_options(accent) |= noad_option_stretch;
3721 }
3722 break;
3723 case 'y': case 'Y':
3724 if (tex_scan_mandate_keyword("symbolattr", 2)) {
3725 symbolattrlist = tex_scan_extra_attribute(symbolattrlist);
3726 }
3727 break;
3728 default:
3729 tex_aux_show_keyword_error("source|stretch|shrink|single|symbolattr");
3730 goto DONE;
3731 }
3732 break;
3733 case 't': case 'T':
3734
3735 if (tex_scan_mandate_keyword("top", 1)) {
3736 if (tex_scan_keyword("fixed")) {
3737 node_subtype(accent) = fixedtop_accent_subtype;
3738 }
3739 t = tex_scan_mathchar(umath_mathcode);
3740 }
3741 goto DONE;
3742 case 'u': case 'U':
3743 if (tex_scan_mandate_keyword("usecallback", 1)) {
3744 noad_options(accent) |= noad_option_use_callback;
3745 }
3746 break;
3747 default:
3748
3749 t = tex_scan_mathchar(umath_mathcode);
3750 goto DONE;
3751 }
3752 }
3753 default:
3754 tex_confusion("scan math accent");
3755 }
3756 DONE:
3757 if (attrlist) {
3758 tex_attach_attribute_list_attribute(accent, attrlist);
3759 }
3760 if (symbolattrlist) {
3761 add_attribute_reference(symbolattrlist);
3762 noad_extra_attr(accent) = symbolattrlist;
3763 }
3764 if (! (t.character_value == 0 && t.family_value == 0)) {
3765 halfword n = tex_new_node(math_char_node, 0);
3766 subtype = tex_aux_set_math_char(n, &t, NULL);
3767 accent_top_character(accent) = n;
3768 }
3769 if (! (b.character_value == 0 && b.family_value == 0)) {
3770 halfword n = tex_new_node(math_char_node, 0);
3771 subtype = tex_aux_set_math_char(n, &b, NULL);
3772 accent_bottom_character(accent) = n;
3773 }
3774 if (! (o.character_value == 0 && o.family_value == 0)) {
3775 halfword n = tex_new_node(math_char_node, 0);
3776 subtype = tex_aux_set_math_char(n, &o, NULL);
3777 accent_middle_character(accent) = n;
3778 }
3779 {
3780 halfword n = tex_new_node(math_char_node, subtype);
3781 noad_nucleus(accent) = n;
3782 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_accent_variant), 0, 0, 0, 0, unset_noad_class, unset_noad_class);
3783 }
3784 set_noad_main_class(accent, mathclass);
3785}
3786
3787
3795
3796void tex_run_math_choice(void) {
3797 switch (cur_chr) {
3798 case math_choice_code:
3799
3800 {
3801 halfword n = tex_new_node(choice_node, normal_choice_subtype);
3802 tex_tail_append(n);
3803 saved_choice_initialize();
3804 saved_choice_count = math_display_choice;
3805 lmt_save_state.save_stack_data.ptr += saved_choice_n_of_records;
3806 tex_aux_push_math(math_choice_group, display_style, -1);
3807 tex_scan_left_brace();
3808 break;
3809 }
3810 case math_discretionary_code:
3811
3812 {
3813 halfword n = tex_new_node(choice_node, discretionary_choice_subtype);
3814 choice_class(n) = unset_noad_class;
3815 while (1) {
3816 switch (tex_scan_character("cC", 0, 1, 0)) {
3817 case 0:
3818 goto DONE;
3819 case 'c': case 'C':
3820 if (tex_scan_mandate_keyword("class", 1)) {
3821 choice_class(n) = tex_scan_math_class_number(0);
3822 }
3823 break;
3824 default:
3825 goto DONE;
3826 }
3827 }
3828 DONE:
3829 tex_tail_append(n);
3830 saved_choice_initialize();
3831 saved_choice_count = math_pre_break_choice;
3832 lmt_save_state.save_stack_data.ptr += saved_choice_n_of_records;
3833 tex_aux_push_math(math_choice_group, cur_list.math_style, -1);
3834 tex_scan_left_brace();
3835 break;
3836 }
3837 case math_stack_code:
3838
3839 {
3840
3841 halfword m = tex_new_node(math_char_node, 0);
3842 halfword n = tex_new_node(simple_noad, ordinary_noad_subtype);
3843 halfword s = tex_math_style_variant(cur_list.math_style, math_parameter_stack_variant);
3844 tex_tail_append(n);
3845 noad_nucleus(n) = m;
3846 tex_scan_left_brace();
3847 saved_math_group_initialize();
3848 saved_math_group_pointer = m;
3849 saved_math_group_all_class = unset_noad_class;
3850 lmt_save_state.save_stack_data.ptr += saved_math_group_n_of_records;
3851 tex_aux_push_math(math_stack_group, s, -1);
3852 break;
3853 }
3854 }
3855}
3856
3857int tex_current_math_style(void)
3858{
3859 return is_m_mode(cur_list.mode) ? cur_list.math_style : -1;
3860}
3861
3862int tex_current_math_main_style(void)
3863{
3864 return is_m_mode(cur_list.mode) ? cur_list.math_main_style : -1;
3865}
3866
3867int tex_current_math_parent_style(void)
3868{
3869 return is_m_mode(cur_list.mode) ? cur_list.math_parent_style : -1;
3870}
3871
3872void tex_finish_math_choice(void)
3873{
3874 tex_aux_unsave_math();
3875 {
3876 halfword content = tex_aux_finish_math_list(null);
3877 halfword choice = saved_choice_current_component();
3878 if (choice >= 0) {
3879 int style = cur_list.math_style;
3880 switch (node_subtype(cur_list.tail)) {
3881 case normal_choice_subtype:
3882 switch (choice) {
3883 case math_display_choice:
3884 choice_display_mlist(cur_list.tail) = content;
3885 style = text_style;
3886 break;
3887 case math_text_choice:
3888 choice_text_mlist(cur_list.tail) = content;
3889 style = script_style;
3890 break;
3891 case math_script_choice:
3892 choice_script_mlist(cur_list.tail) = content;
3893 style = script_script_style;
3894 break;
3895 case math_script_script_choice:
3896 choice_script_script_mlist(cur_list.tail) = content;
3897 lmt_save_state.save_stack_data.ptr -= saved_choice_n_of_records;
3898 return;
3899 }
3900 break;
3901 case discretionary_choice_subtype:
3902 switch (choice) {
3903 case math_pre_break_choice:
3904 choice_pre_break(cur_list.tail) = content;
3905 style = display_style;
3906 break;
3907 case math_post_break_choice:
3908 choice_post_break(cur_list.tail) = content;
3909 style = text_style;
3910 break;
3911 case math_no_break_choice:
3912 choice_no_break(cur_list.tail) = content;
3913 style = script_style;
3914 lmt_save_state.save_stack_data.ptr -= saved_choice_n_of_records;
3915 return;
3916 }
3917 break;
3918 }
3919 saved_choice_update_component();
3920 tex_aux_push_math(math_choice_group, style, -1);
3921 tex_scan_left_brace();
3922 } else {
3923 tex_confusion("scan build choices");
3924 }
3925 }
3926}
3927
3928void tex_finish_math_fraction(void)
3929{
3930 tex_aux_unsave_math();
3931 {
3932 halfword content = tex_aux_finish_math_list(null);
3933 halfword over = saved_fraction_current_component();
3934 if (over >= 0) {
3935 halfword autostyle = saved_fraction_current_autostyle();
3936 halfword userstyle = saved_fraction_current_userstyle();
3937 halfword fraction = cur_list.tail;
3938 set_noad_style(fraction, userstyle);
3939 switch (over) {
3940 case math_numerator_above:
3941 kernel_math_list(fraction_numerator(fraction)) = content;
3942 break;
3943 case math_denominator_above:
3944 kernel_math_list(fraction_denominator(fraction)) = content;
3945 lmt_save_state.save_stack_data.ptr -= saved_fraction_n_of_records;
3946 return;
3947 }
3948 saved_fraction_update_component();
3949 tex_aux_push_math(math_fraction_group, autostyle, -1);
3950 tex_scan_left_brace();
3951 } else {
3952 tex_confusion("scan build fraction");
3953 }
3954 }
3955}
3956
3957void tex_finish_math_operator(void)
3958{
3959 tex_aux_unsave_math();
3960 {
3961 halfword content = tex_aux_finish_math_list(null);
3962 halfword over = saved_operator_current_component();
3963 if (over >= 0) {
3964 halfword fenced = cur_list.tail;
3965 switch (over) {
3966 case math_limits_top:
3967 if (content) {
3968 halfword top = tex_new_node(sub_mlist_node, 0);
3969 fence_delimiter_top(fenced) = top;
3970 kernel_math_list(top) = content;
3971 }
3972 break;
3973 case math_limits_bottom:
3974 if (content) {
3975 halfword bottom = tex_new_node(sub_mlist_node, 0);
3976 fence_delimiter_bottom(fenced) = bottom;
3977 kernel_math_list(bottom) = content;
3978 }
3979 lmt_save_state.save_stack_data.ptr -= saved_operator_n_of_records;
3980 return;
3981 }
3982 saved_operator_update_component();
3983 tex_aux_push_math(math_operator_group, tex_math_style_variant(cur_list.math_style, math_parameter_subscript_variant), -1);
3984 tex_scan_left_brace();
3985 } else {
3986 tex_confusion("math operator");
3987 }
3988 }
3989}
3990
3991
3997
3998void tex_run_math_script(void)
3999{
4000 int code = cur_chr;
4001 halfword tail = cur_list.tail;
4002 switch (cur_cmd) {
4003 case subscript_cmd:
4004 code = math_sub_script_code;
4005 break;
4006 case superscript_cmd:
4007 code = math_super_script_code;
4008 break;
4009 }
4010 switch (code) {
4011 case math_no_script_space_code:
4012 {
4013 halfword glue = tex_new_glue_node(zero_glue, conditional_math_glue);
4014 tex_tail_append(glue);
4015 tex_add_glue_option(glue, glue_option_no_auto_break);
4016 }
4017 return;
4018 case math_no_ruling_space_code:
4019 {
4020 halfword glue = tex_new_glue_node(zero_glue, rulebased_math_glue);
4021 tex_tail_append(glue);
4022 tex_add_glue_option(glue, glue_option_no_auto_break);
4023 }
4024 return;
4025 case math_sub_script_code:
4026 tex_get_token();
4027 if (cur_tok == underscore_token || cur_cmd == subscript_cmd) {
4028 tex_get_token();
4029 if (cur_tok == underscore_token || cur_cmd == subscript_cmd) {
4030 tex_get_token();
4031 if (cur_tok == underscore_token || cur_cmd == subscript_cmd) {
4032 code = math_indexed_sub_pre_script_code;
4033 } else {
4034 tex_back_input(cur_tok);
4035 code = math_sub_pre_script_code;
4036 }
4037 } else {
4038 tex_back_input(cur_tok);
4039 code = math_indexed_sub_script_code;
4040 }
4041 } else {
4042 tex_back_input(cur_tok);
4043 }
4044 break;
4045 case math_super_script_code:
4046 tex_get_token();
4047 if (cur_tok == circumflex_token || cur_cmd == superscript_cmd) {
4048 tex_get_token();
4049 if (cur_tok == circumflex_token || cur_cmd == superscript_cmd) {
4050 tex_get_token();
4051 if (cur_tok == circumflex_token || cur_cmd == superscript_cmd) {
4052 code = math_indexed_super_pre_script_code;
4053 } else {
4054 tex_back_input(cur_tok);
4055 code = math_super_pre_script_code;
4056 }
4057 } else {
4058 tex_back_input(cur_tok);
4059 code = math_indexed_super_script_code;
4060 }
4061 } else {
4062 tex_back_input(cur_tok);
4063 }
4064 break;
4065 case math_no_script_code:
4066 if (tex_math_scripts_allowed(cur_list.tail)) {
4067 noad_options(cur_list.tail) |= noad_option_no_more_scripts;
4068 }
4069 return;
4070 }
4071 if (tail == cur_list.head) {
4072 tail = tex_math_double_atom(0);
4073 } else if (tex_math_no_more_scripts(tail)) {
4074 tail = tex_math_double_atom(1);
4075 } else if (! tex_math_scripts_allowed(tail)) {
4076 tail = tex_math_double_atom(0);
4077 }
4078 switch (code) {
4079 case math_sub_script_code:
4080 case math_no_sub_script_code:
4081 case math_indexed_sub_script_code:
4082 {
4083 if (noad_subscr(tail)) {
4084 tail = tex_math_double_atom(1);
4085 if (math_double_script_mode_par < 0) {
4086 tex_handle_error(
4087 normal_error_type,
4088 "Double subscript",
4089 "I treat 'x_1_2' essentially like 'x_1{}_2'."
4090 );
4091 }
4092 }
4093 switch (code) {
4094 case math_no_sub_script_code:
4095 noad_options(tail) |= noad_option_no_sub_script;
4096 break;
4097 case math_indexed_sub_script_code:
4098 noad_options(tail) |= noad_option_indexed_sub_script;
4099 break;
4100 }
4101 {
4102 halfword n = tex_new_node(math_char_node, 0);
4103 noad_subscr(tail) = n;
4104 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_subscript_variant), 0, 0, 0, 1, unset_noad_class, unset_noad_class);
4105 if (! noad_script_order(tail)) {
4106 noad_script_order(tail) = script_subscript_first;
4107 }
4108 }
4109 break;
4110 }
4111 case math_sub_pre_script_code:
4112 case math_no_sub_pre_script_code:
4113 case math_indexed_sub_pre_script_code:
4114 {
4115 if (noad_subprescr(tail)) {
4116 int limitation = node_type(tail) == fraction_noad;
4117 tail = tex_math_double_atom(1);
4118 if (math_double_script_mode_par < 0) {
4119 tex_handle_error(
4120 normal_error_type,
4121 limitation ? "Fractions take no pre subscript directly" : "Double pre subscript",
4122 "I just ignore it; consider wrapping this element."
4123 );
4124 }
4125 }
4126 switch (code) {
4127 case math_no_sub_pre_script_code:
4128 noad_options(tail) |= noad_option_no_sub_pre_script;
4129 break;
4130 case math_indexed_sub_pre_script_code:
4131 noad_options(tail) |= noad_option_indexed_sub_pre_script;
4132 break;
4133 }
4134 {
4135 halfword n = tex_new_node(math_char_node, 0);
4136 noad_subprescr(tail) = n;
4137 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_subscript_variant), 0, 0, 0, 1, unset_noad_class, unset_noad_class);
4138 }
4139 break;
4140 }
4141 case math_super_script_code:
4142 case math_no_super_script_code:
4143 case math_indexed_super_script_code:
4144 {
4145 if (noad_supscr(tail)) {
4146 tail = tex_math_double_atom(1);
4147 if (math_double_script_mode_par < 0) {
4148 tex_handle_error(
4149 normal_error_type,
4150 "Double superscript",
4151 "I treat 'x^1^2' essentially like 'x^1{}^2'."
4152 );
4153 }
4154 }
4155 switch (code) {
4156 case math_no_super_script_code:
4157 noad_options(tail) |= noad_option_no_super_script;
4158 break;
4159 case math_indexed_super_script_code:
4160 noad_options(tail) |= noad_option_indexed_super_script;
4161 break;
4162 }
4163 {
4164 halfword n = tex_new_node(math_char_node, 0);
4165 noad_supscr(tail) = n;
4166 if (! noad_script_order(tail)) {
4167 noad_script_order(tail) = script_superscript_first;
4168 }
4169 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_superscript_variant), 0, 0, 0, 1, unset_noad_class, unset_noad_class);
4170 }
4171 break;
4172 }
4173 case math_super_pre_script_code:
4174 case math_no_super_pre_script_code:
4175 case math_indexed_super_pre_script_code:
4176 {
4177 if (noad_supprescr(tail)) {
4178 int limitation = node_type(tail) == fraction_noad;
4179 tail = tex_math_double_atom(1);
4180 if (math_double_script_mode_par < 0) {
4181 tex_handle_error(
4182 normal_error_type,
4183 limitation ? "Fractions take no pre superscript directly" : "Double pre superscript",
4184 "I just ignore it; consider wrapping this element."
4185 );
4186 }
4187 }
4188 switch (code) {
4189 case math_no_super_script_code:
4190 noad_options(tail) |= noad_option_no_super_pre_script;
4191 break;
4192 case math_indexed_super_pre_script_code:
4193 noad_options(tail) |= noad_option_indexed_super_pre_script;
4194 break;
4195 }
4196 {
4197 halfword n = tex_new_node(math_char_node, 0);
4198 noad_supprescr(tail) = n;
4199 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_superscript_variant), 0, 0, 0, 1, unset_noad_class, unset_noad_class);
4200 }
4201 break;
4202 }
4203 case math_prime_script_code:
4204 {
4205 if (noad_prime(tail)) {
4206 tail = tex_math_double_atom(1);
4207 if (math_double_script_mode_par < 0) {
4208 tex_handle_error(
4209 normal_error_type,
4210 "Double prime script",
4211 "I'll add a dummy nucleus."
4212 );
4213 }
4214 }
4215 {
4216 halfword n = tex_new_node(math_char_node, 0);
4217 noad_prime(tail) = n;
4218 if (! noad_script_order(tail)) {
4219 noad_script_order(tail) = script_primescript_first;
4220 }
4221
4222 tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_superscript_variant), 0, 0, 0, 1, unset_noad_class, unset_noad_class);
4223 }
4224 break;
4225 }
4226 }
4227}
4228
4229
4241
4242void tex_run_math_fraction(void)
4243{
4244
4245 halfword code = cur_chr;
4246 if (cur_list.incomplete_noad) {
4247
4248 switch (code) {
4249 case math_above_delimited_code:
4250 case math_over_delimited_code:
4251 case math_atop_delimited_code:
4252 case math_u_above_delimited_code:
4253 case math_u_over_delimited_code:
4254 case math_u_atop_delimited_code:
4255 case math_u_skewed_delimited_code:
4256 case math_u_stretched_delimited_code:
4257 tex_aux_scan_delimiter(null, no_mathcode, unset_noad_class);
4258 tex_aux_scan_delimiter(null, no_mathcode, unset_noad_class);
4259 break;
4260 }
4261 switch (code) {
4262 case math_above_code:
4263 case math_above_delimited_code:
4264 case math_u_above_code:
4265 case math_u_above_delimited_code:
4266 tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4267 break;
4268 }
4269
4270 tex_handle_error(
4271 normal_error_type,
4272 "Ambiguous; you need another { and }",
4273 "I'm ignoring this fraction specification, since I don't know whether a\n"
4274 "construction like 'x \\over y \\over z' means '{x \\over y} \\over z' or\n"
4275 "'x \\over {y \\over z}'."
4276 );
4277 } else {
4278 halfword fraction = tex_new_node(fraction_noad, 0);
4279 halfword numerator = tex_new_node(sub_mlist_node, 0);
4280 halfword denominator = null;
4281 halfword autostyle = tex_math_style_variant(cur_list.math_style, math_parameter_fraction_variant);
4282 halfword userstyle = -1;
4283 halfword attrlist = null;
4284 halfword symbolattrlist = null;
4285 fullword options = 0;
4286 halfword mathclass = fraction_noad_subtype;
4287 halfword rulethickness = preset_rule_thickness;
4288 int ruledone = 0;
4289 fraction_h_factor(fraction) = scaling_factor;
4290 fraction_v_factor(fraction) = scaling_factor;
4291 switch (code) {
4292 case math_above_code:
4293 case math_above_delimited_code:
4294 node_subtype(fraction) = above_fraction_subtype;
4295 goto NEXTSTEP1;
4296 case math_over_code:
4297 case math_over_delimited_code:
4298 node_subtype(fraction) = over_fraction_subtype;
4299 goto NEXTSTEP1;
4300 case math_atop_code:
4301 case math_atop_delimited_code:
4302 node_subtype(fraction) = atop_fraction_subtype;
4303 NEXTSTEP1:
4304 {
4305 cur_list.incomplete_noad = fraction;
4306 fraction_numerator(fraction) = numerator;
4307 kernel_math_list(numerator) = node_next(cur_list.head);
4308 node_next(cur_list.head) = null;
4309 cur_list.tail = cur_list.head;
4310 cur_list.math_style = autostyle;
4311 break;
4312 }
4313 case math_u_above_code:
4314 case math_u_above_delimited_code:
4315 node_subtype(fraction) = above_fraction_subtype;
4316 goto NEXTSTEP2;
4317 case math_u_over_code:
4318 case math_u_over_delimited_code:
4319 node_subtype(fraction) = over_fraction_subtype;
4320 goto NEXTSTEP2;
4321 case math_u_atop_code:
4322 case math_u_atop_delimited_code:
4323 node_subtype(fraction) = atop_fraction_subtype;
4324 goto NEXTSTEP2;
4325 case math_u_skewed_code:
4326 case math_u_skewed_delimited_code:
4327 node_subtype(fraction) = skewed_fraction_subtype;
4328 goto NEXTSTEP2;
4329 case math_u_stretched_code:
4330 case math_u_stretched_delimited_code:
4331 node_subtype(fraction) = stretched_fraction_subtype;
4332 NEXTSTEP2:
4333 {
4334 cur_list.incomplete_noad = null;
4335 denominator = tex_new_node(sub_mlist_node, 0);
4336 tex_tail_append_callback(fraction);
4337 fraction_numerator(fraction) = numerator;
4338 fraction_denominator(fraction) = denominator;
4339 break;
4340 }
4341 }
4342 switch (code) {
4343 case math_u_skewed_code:
4344 case math_u_skewed_delimited_code:
4345 case math_u_stretched_code:
4346 case math_u_stretched_delimited_code:
4347 {
4348 halfword q = tex_new_node(delimiter_node, 0);
4349 fraction_middle_delimiter(fraction) = q;
4350 tex_aux_scan_delimiter(q, no_mathcode, unset_noad_class);
4351 break;
4352 }
4353 }
4354 switch (code) {
4355 case math_above_delimited_code:
4356 case math_over_delimited_code:
4357 case math_atop_delimited_code:
4358 case math_u_above_delimited_code:
4359 case math_u_over_delimited_code:
4360 case math_u_atop_delimited_code:
4361 case math_u_skewed_delimited_code:
4362 case math_u_stretched_delimited_code:
4363 {
4364 halfword left = tex_new_node(delimiter_node, 0);
4365 halfword right = tex_new_node(delimiter_node, 0);
4366 fraction_left_delimiter(fraction) = left;
4367 fraction_right_delimiter(fraction) = right;
4368 tex_aux_scan_delimiter(left, no_mathcode, open_noad_subtype);
4369 tex_aux_scan_delimiter(right, no_mathcode, close_noad_subtype);
4370 break;
4371 }
4372 }
4373 switch (code) {
4374
4375 case math_above_code:
4376 case math_above_delimited_code:
4377 rulethickness = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4378 break;
4379 case math_over_code:
4380 case math_over_delimited_code:
4381 rulethickness = preset_rule_thickness;
4382 break;
4383 case math_atop_code:
4384 case math_atop_delimited_code:
4385 break;
4386
4390 case math_u_above_code:
4391 case math_u_above_delimited_code:
4392 goto OPTIONS;
4393 case math_u_atop_code:
4394 case math_u_atop_delimited_code:
4395 case math_u_over_code:
4396 case math_u_over_delimited_code:
4397 ruledone = 1;
4398 goto OPTIONS;
4399 case math_u_stretched_code:
4400 case math_u_stretched_delimited_code:
4401 case math_u_skewed_code:
4402 case math_u_skewed_delimited_code:
4403 ruledone = 1;
4404 OPTIONS:
4405 while (1) {
4406 switch (tex_scan_character("acefhnpstuvACEFHNPSTUV", 0, 1, 0)) {
4407 case 'a': case 'A':
4408 if (tex_scan_mandate_keyword("attr", 1)) {
4409 attrlist = tex_scan_attribute(attrlist);
4410 }
4411 break;
4412 case 'c': case 'C':
4413 if (tex_scan_mandate_keyword("class", 1)) {
4414 halfword c = (quarterword) tex_scan_math_class_number(0);
4415 if (valid_math_class_code(c)) {
4416 mathclass = c;
4417 }
4418 }
4419 break;
4420 case 'e': case 'E':
4421
4422 if (tex_scan_mandate_keyword("exact", 1)) {
4423 options |= noad_option_exact;
4424 }
4425 break;
4426 case 'f': case 'F':
4427 if (tex_scan_mandate_keyword("font", 1)) {
4428 ruledone = 1;
4429 options |= noad_option_prefer_font_thickness;
4430 }
4431 break;
4432 case 'h': case 'H':
4433 if (tex_scan_mandate_keyword("hfactor", 1)) {
4434 fraction_h_factor(fraction) = tex_scan_integer(0, NULL, NULL);
4435 }
4436 break;
4437 case 'n': case 'N':
4438
4439 if (tex_scan_character("oO", 0, 0, 0)) {
4440 switch (tex_scan_character("aoAO", 0, 0, 0)) {
4441 case 'a': case 'A':
4442 if (tex_scan_mandate_keyword("noaxis", 3)) {
4443 options |= noad_option_no_axis;
4444 }
4445 break;
4446 case 'o': case 'O':
4447 if (tex_scan_mandate_keyword("nooverflow", 3)) {
4448 options |= noad_option_no_overflow;
4449 }
4450 break;
4451 default:
4452 tex_aux_show_keyword_error("noaxis|nooverflow");
4453 goto DONE;
4454 }
4455 }
4456 break;
4457 case 'p': case 'P':
4458
4459 if (tex_scan_mandate_keyword("proportional", 1)) {
4460 options |= noad_option_proportional;
4461 }
4462 break;
4463 case 's': case 'S':
4464 switch (tex_scan_character("toyTOY", 0, 0, 0)) {
4465 case 't': case 'T':
4466 if (tex_scan_mandate_keyword("style", 2)) {
4467 halfword style = tex_scan_math_style_identifier(1, 0);
4468 if (denominator && style >= 0) {
4469 userstyle = style;
4470 } else {
4471
4472 }
4473 }
4474 break;
4475 case 'o': case 'O':
4476 if (tex_scan_mandate_keyword("source", 2)) {
4477 noad_source(fraction) = tex_scan_integer(0, NULL, NULL);
4478 }
4479 break;
4480 case 'y': case 'Y':
4481 if (tex_scan_mandate_keyword("symbolattr", 2)) {
4482 symbolattrlist = tex_scan_extra_attribute(symbolattrlist);
4483 }
4484 break;
4485 default:
4486 tex_aux_show_keyword_error("style|source|symbolattr");
4487 goto DONE;
4488 }
4489 break;
4490 case 't': case 'T':
4491 if (tex_scan_mandate_keyword("thickness", 1)) {
4492 ruledone = 1;
4493 rulethickness = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4494 }
4495 break;
4496 case 'u': case 'U':
4497 if (tex_scan_mandate_keyword("usecallback", 1)) {
4498 ruledone = 1;
4499 options |= noad_option_use_callback;
4500 }
4501 break;
4502 case 'v': case 'V':
4503 if (tex_scan_mandate_keyword("vfactor", 1)) {
4504 fraction_v_factor(fraction) = tex_scan_integer(0, NULL, NULL);
4505 }
4506 break;
4507 default:
4508 goto DONE;
4509 }
4510 }
4511 DONE:
4512 if (! ruledone) {
4513 rulethickness = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4514 }
4515 break;
4516 }
4517 fraction_rule_thickness(fraction) = rulethickness;
4518 noad_options(fraction) = options;
4519 set_noad_main_class(fraction, mathclass);
4520 if (attrlist) {
4521 tex_attach_attribute_list_attribute(fraction, attrlist);
4522 }
4523 if (symbolattrlist) {
4524 add_attribute_reference(symbolattrlist);
4525 noad_extra_attr(fraction) = symbolattrlist;
4526 }
4527 if (denominator) {
4528
4532 saved_fraction_initialize();
4533 saved_fraction_variant = math_numerator_above;
4534 saved_fraction_autostyle = autostyle;
4535 saved_fraction_userstyle = userstyle;
4536 lmt_save_state.save_stack_data.ptr += saved_fraction_n_of_records;
4537 cur_list.math_flatten = 0;
4538 tex_aux_push_math(math_fraction_group, autostyle, -1);
4539 tex_scan_left_brace();
4540 } else {
4541
4545 }
4546 }
4547}
4548
4549
4557
4558static halfword tex_aux_finish_math_list(halfword p)
4559{
4560 halfword q = null;
4561
4562 if (cur_list.incomplete_noad) {
4563 halfword denominator = fraction_denominator(cur_list.incomplete_noad);
4564 if (denominator) {
4565 node_type(denominator) = sub_mlist_node;
4566 } else {
4567 denominator = tex_new_node(sub_mlist_node, 0);
4568 fraction_denominator(cur_list.incomplete_noad) = denominator;
4569 q = denominator;
4570 }
4571 kernel_math_list(denominator) = node_next(cur_list.head);
4572 if (p) {
4573 halfword numerator = fraction_numerator(cur_list.incomplete_noad);
4574 q = kernel_math_list(numerator);
4575 if ((node_type(q) != fence_noad) || (node_subtype(q) != left_fence_side) || (! cur_list.delimiter)) {
4576 tex_confusion("right fence");
4577 }
4578 kernel_math_list(numerator) = node_next(cur_list.delimiter);
4579 node_next(cur_list.delimiter) = cur_list.incomplete_noad;
4580 node_next(cur_list.incomplete_noad) = p;
4581 } else {
4582 q = cur_list.incomplete_noad;
4583 }
4584 } else {
4585 node_next(cur_list.tail) = p;
4586 q = node_next(cur_list.head);
4587 }
4588 tex_pop_nest();
4589 return q;
4590}
4591
4592
4600
4601static void tex_aux_flatten_math_list(halfword parent)
4602{
4603 halfword p = kernel_math_list(parent);
4604 if (p && ! node_next(p)) {
4605 switch (node_type(p)) {
4606 case simple_noad:
4607 {
4608
4609 if (! noad_has_following_scripts(p) && tex_math_has_class_option(node_subtype(p), flatten_class_option) && ! noad_source(p)) {
4610 halfword n = noad_nucleus(p);
4611 halfword s = parent;
4612 node_type(s) = node_type(n);
4613 tex_math_copy_char_data(s, n, 1);
4614 tex_attach_attribute_list_copy(s, n);
4615 tex_flush_node(p);
4616 }
4617 break;
4618 }
4619 case accent_noad:
4620 {
4621 halfword tail = cur_list.tail;
4622 if (saved_math_group_pointer == noad_nucleus(tail) && node_type(tail) == simple_noad) {
4623 switch (node_subtype(tail)) {
4624 case ordinary_noad_subtype:
4625 tex_couple_nodes(node_prev(tail), p);
4626 noad_nucleus(tail) = null;
4627 noad_subscr(tail) = null;
4628 noad_supscr(tail) = null;
4629 noad_prime(tail) = null;
4630 tex_attach_attribute_list_copy(p, tail);
4631 tex_flush_node(tail);
4632 cur_list.tail = p;
4633 break;
4634 }
4635 }
4636 break;
4637 }
4638 }
4639 }
4640}
4641
4642
4650
4651void tex_finish_math_group(void)
4652{
4653 int old_style = cur_list.math_style;
4654 halfword p, parent;
4655 quarterword allclass;
4656 tex_aux_unsave_math();
4657 lmt_save_state.save_stack_data.ptr -= saved_math_group_n_of_records;
4658 parent = saved_math_group_pointer;
4659 allclass = (quarterword) saved_math_group_all_class;
4660 node_type(parent) = sub_mlist_node;
4661 p = tex_aux_finish_math_list(null);
4662 kernel_math_list(parent) = p;
4663 if (cur_list.math_flatten) {
4664 tex_aux_flatten_math_list(parent);
4665 }
4666
4670 if (allclass != unset_noad_class) {
4671 while (p) {
4672 if (node_type(p) == simple_noad) {
4673
4674 if (get_noad_main_class(p) == unset_noad_class) {
4675 set_noad_main_class(p, allclass);
4676 }
4677 if (get_noad_left_class(p) == unset_noad_class) {
4678 set_noad_left_class(p, allclass);
4679 }
4680 if (get_noad_right_class(p) == unset_noad_class) {
4681 set_noad_right_class(p, allclass);
4682 }
4683 }
4684 p = node_next(p);
4685 }
4686
4687 }
4688 if (node_next(saved_math_group_pointer) > 0) {
4689 halfword q = tex_new_node(math_char_node, 0);
4690 noad_nucleus(node_next(saved_math_group_pointer)) = q;
4691 node_next(saved_math_group_pointer) = null;
4692 saved_math_group_pointer = q;
4693 tex_aux_scan_math(q, old_style, 0, 0, 0, 0, unset_noad_class, unset_noad_class);
4694
4695 }
4696}
4697
4698
4705
4706void tex_run_math_fence(void)
4707{
4708 scaled ht = 0;
4709 scaled dp = 0;
4710 scaled top = 0;
4711 scaled bottom = 0;
4712 fullword options = 0;
4713 halfword variant = 0;
4714 halfword mainclass = unset_noad_class;
4715 halfword leftclass = unset_noad_class;
4716 halfword rightclass = unset_noad_class;
4717 halfword source = 0;
4718 halfword factor = scaling_factor;
4719 halfword attrlist = null;
4720 halfword symbolattrlist = null;
4721 quarterword st = (quarterword) cur_chr;
4722 halfword style = cur_list.math_style;
4723 halfword call = tex_tail_fetch_callback();
4724 if (math_check_fences_par) {
4725 options |= noad_option_no_check;
4726 }
4727 switch (st) {
4728 case left_operator_side:
4729 case no_fence_side:
4730 break;
4731 case extended_left_fence_side:
4732 st = left_fence_side;
4733 break;
4734 case extended_middle_fence_side:
4735 st = middle_fence_side;
4736 break;
4737 case extended_right_fence_side:
4738 st = right_fence_side;
4739 break;
4740 default :
4741 goto CHECK_PAIRING;
4742 }
4743 while (1) {
4744
4745 switch (tex_scan_character("abcdefhlmnprstuvABCDEFHLMNPRSTUV", 0, 1, 0)) {
4746 case 0:
4747 goto CHECK_PAIRING;
4748 case 'a': case 'A':
4749 switch (tex_scan_character("tuxTUX", 0, 0, 0)) {
4750 case 't': case 'T':
4751 if (tex_scan_mandate_keyword("attr", 2)) {
4752 attrlist = tex_scan_attribute(attrlist);
4753 }
4754 break;
4755 case 'u': case 'U':
4756 if (tex_scan_mandate_keyword("auto", 2)) {
4757 options |= noad_option_auto;
4758 }
4759 break;
4760 case 'x': case 'X':
4761 if (tex_scan_mandate_keyword("axis", 2)) {
4762 options |= noad_option_axis;
4763 }
4764 break;
4765 default:
4766 tex_aux_show_keyword_error("auto|attr|axis");
4767 goto CHECK_PAIRING;
4768 }
4769 break;
4770 case 'b': case 'B':
4771 if (tex_scan_mandate_keyword("bottom", 1)) {
4772 bottom = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4773 }
4774 break;
4775 case 'c': case 'C':
4776 if (tex_scan_mandate_keyword("class", 1)) {
4777 mainclass = tex_scan_math_class_number(0);
4778 }
4779 break;
4780 case 'd': case 'D':
4781 if (tex_scan_mandate_keyword("depth", 1)) {
4782 dp = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4783 }
4784 break;
4785 case 'e': case 'E':
4786 if (tex_scan_mandate_keyword("exact", 1)) {
4787 options |= noad_option_exact;
4788 }
4789 break;
4790 case 'f': case 'F':
4791 if (tex_scan_mandate_keyword("factor", 1)) {
4792 factor = tex_scan_integer(0, NULL, NULL);
4793 }
4794 break;
4795 case 'h': case 'H':
4796 if (tex_scan_mandate_keyword("height", 1)) {
4797 ht = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4798 }
4799 break;
4800 case 'l': case 'L':
4801 switch (tex_scan_character("eiEI", 0, 0, 0)) {
4802 case 'e': case 'E':
4803 if (tex_scan_mandate_keyword("leftclass", 2)) {
4804 halfword c = tex_scan_math_class_number(0);
4805
4806 if (valid_math_class_code(c)) {
4807 leftclass = c;
4808 }
4809 }
4810 break;
4811 case 'i': case 'I':
4812 if (tex_scan_mandate_keyword("limits", 2)) {
4813 options = unset_option(options, noad_option_no_limits);
4814 options |= noad_option_limits;
4815 }
4816 break;
4817 default:
4818 tex_aux_show_keyword_error("leftclass|limits");
4819 goto CHECK_PAIRING;
4820 }
4821 break;
4822 case 'n': case 'N':
4823 switch (tex_scan_character("oO", 0, 0, 0)) {
4824 case 'o': case 'O':
4825 switch (tex_scan_character("acloACLO", 0, 0, 0)) {
4826 case 'a': case 'A':
4827 if (tex_scan_mandate_keyword("noaxis", 3)) {
4828 options |= noad_option_no_axis;
4829 }
4830 break;
4831 case 'c': case 'C':
4832 if (tex_scan_mandate_keyword("nocheck", 3)) {
4833 options |= noad_option_no_check;
4834 }
4835 break;
4836 case 'l': case 'L':
4837 if (tex_scan_mandate_keyword("nolimits", 3)) {
4838 options = unset_option(options, noad_option_limits);
4839 options |= noad_option_no_limits;
4840 }
4841 break;
4842 case 'o': case 'O':
4843 if (tex_scan_mandate_keyword("nooverflow", 3)) {
4844 options |= noad_option_no_overflow;
4845 }
4846 break;
4847 default:
4848 tex_aux_show_keyword_error("noaxis|nolimits|nocheck|nooverflow");
4849 goto CHECK_PAIRING;
4850 }
4851 break;
4852 default:
4853 goto CHECK_PAIRING;
4854 }
4855 break;
4856 case 'm': case 'M':
4857 if (tex_scan_mandate_keyword("middle", 1)) {
4858 options |= noad_option_auto_middle;
4859 }
4860 break;
4861 case 'p': case 'P':
4862 if (tex_scan_mandate_keyword("phantom", 1)) {
4863 options |= noad_option_phantom;
4864 }
4865 break;
4866 case 'r': case 'R':
4867 if (tex_scan_mandate_keyword("rightclass", 1)) {
4868 halfword c = tex_scan_math_class_number(0);
4869
4870 if (valid_math_class_code(c)) {
4871 rightclass = c;
4872 }
4873 }
4874 break;
4875 case 's': case 'S':
4876 switch (tex_scan_character("cioyCIOY", 0, 0, 0)) {
4877 case 'c': case 'C':
4878 if (tex_scan_mandate_keyword("scale", 2)) {
4879 options |= noad_option_scale;
4880 }
4881 break;
4882 case 'i': case 'I':
4883 if (tex_scan_mandate_keyword("single", 2)) {
4884 options |= noad_option_single;
4885 }
4886 break;
4887 case 'o': case 'O':
4888 if (tex_scan_mandate_keyword("source", 2)) {
4889 source = tex_scan_integer(0, NULL, NULL);
4890 }
4891 break;
4892 case 'y': case 'Y':
4893 if (tex_scan_mandate_keyword("symbolattr", 2)) {
4894 symbolattrlist = tex_scan_extra_attribute(symbolattrlist);
4895 }
4896 break;
4897 default:
4898 tex_aux_show_keyword_error("scale|source|single|size|symbolattr");
4899 goto CHECK_PAIRING;
4900 }
4901 break;
4902 case 't': case 'T':
4903 if (tex_scan_mandate_keyword("top", 1)) {
4904 top = tex_scan_dimension(0, 0, 0, 0, NULL, NULL);
4905 }
4906 break;
4907 case 'u': case 'U':
4908 if (tex_scan_mandate_keyword("usecallback", 1)) {
4909 options |= noad_option_use_callback;
4910 }
4911 break;
4912 case 'v': case 'V':
4913 switch (tex_scan_character("aoAO", 0, 0, 0)) {
4914 case 'a': case 'A':
4915 if (tex_scan_mandate_keyword("variant", 2)) {
4916 variant = tex_scan_integer(0, NULL, NULL);
4917 }
4918 break;
4919 case 'o': case 'O':
4920 if (tex_scan_mandate_keyword("void", 2)) {
4921 options |= noad_option_void;
4922 }
4923 break;
4924 default:
4925 tex_aux_show_keyword_error("void|variant");
4926 goto CHECK_PAIRING;
4927 }
4928 break;
4929 default:
4930 goto CHECK_PAIRING;
4931 }
4932 }
4933 CHECK_PAIRING:
4934 switch (st) {
4935 case no_fence_side:
4936 case left_fence_side:
4937 break;
4938 case left_operator_side:
4939 {
4940
4941 int indisplay = style == display_style || style == cramped_display_style;
4942
4943 if (! (has_option(options, noad_option_limits) || has_option(options, noad_option_no_limits))) {
4944
4945 options |= indisplay ? noad_option_limits : noad_option_no_limits;
4946 }
4947 }
4948 break;
4949 default:
4950 if (cur_group != math_fence_group) {
4951 tex_aux_append_math_fence_val(tex_no_math_code(), tex_no_dict_code(), open_noad_subtype);
4952 }
4953 switch (cur_group) {
4954 case math_fence_group:
4955 break;
4956 case math_inline_group:
4957 case math_display_group:
4958 case math_number_group:
4959 tex_aux_scan_delimiter(null, no_mathcode, unset_noad_class);
4960 if (st == middle_fence_side) {
4961 tex_handle_error(
4962 normal_error_type,
4963 "Extra \\middle",
4964 "I'm ignoring a \\middle that had no matching \\left."
4965 );
4966 } else {
4967 tex_handle_error(
4968 normal_error_type,
4969 "Extra \\right",
4970 "I'm ignoring a \\right that had no matching \\left."
4971 );
4972 }
4973 break;
4974 default:
4975 tex_off_save();
4976 }
4977 }
4978
4981 {
4982 halfword fence = tex_new_node(fence_noad, st);
4983 halfword delimiter = tex_new_node(delimiter_node, 0);
4984 halfword autoclass = unset_noad_class;
4985 fence_delimiter(fence) = delimiter;
4986 fence_delimiter_variant(fence) = variant;
4987 noad_height(fence) = ht;
4988 noad_depth(fence) = dp;
4989 noad_options(fence) = options;
4990 tex_set_noad_classes(fence, mainclass);
4991 if (leftclass != unset_noad_class) {
4992 set_noad_left_class(fence, leftclass);
4993 }
4994 if (rightclass != unset_noad_class) {
4995 set_noad_right_class(fence, rightclass);
4996 }
4997 noad_italic(fence) = 0;
4998 noad_source(fence) = source;
4999
5000 fence_top_overshoot(fence) = top;
5001 fence_bottom_overshoot(fence) = bottom;
5002
5003 if (symbolattrlist) {
5004 add_attribute_reference(symbolattrlist);
5005 noad_extra_attr(fence) = symbolattrlist;
5006 }
5007
5012 if (mainclass == unset_noad_class) {
5013 mainclass = node_subtype(delimiter);
5014 if (mainclass == unset_noad_class || mainclass == ordinary_noad_subtype) {
5015 switch (st) {
5016 case left_fence_side:
5017 mainclass = open_noad_subtype;
5018 break;
5019 case middle_fence_side:
5020 mainclass = middle_noad_subtype;
5021 break;
5022 case right_fence_side:
5023 mainclass = close_noad_subtype;
5024 break;
5025 }
5026 }
5027 set_noad_main_class(fence, mainclass);
5028 }
5029
5030 switch (st) {
5031 case left_fence_side:
5032 autoclass = open_noad_subtype;
5033 break;
5034 case middle_fence_side:
5035 autoclass = middle_noad_subtype;
5036 break;
5037 case right_fence_side:
5038 autoclass = close_noad_subtype;
5039 break;
5040 }
5041
5042 tex_aux_scan_delimiter(delimiter, no_mathcode, autoclass);
5043
5044 if (attrlist) {
5045 tex_attach_attribute_list_attribute(fence, attrlist);
5046 tex_attach_attribute_list_attribute(delimiter, attrlist);
5047 }
5048 switch (st) {
5049 case left_fence_side:
5050 tex_aux_append_math_fence(fence, open_noad_subtype);
5051 fence_nesting_factor(fence) = factor;
5052 break;
5053 case middle_fence_side:
5054 tex_aux_append_math_fence(fence, middle_noad_subtype);
5055 break;
5056 case right_fence_side:
5057 tex_aux_append_math_fence(fence, close_noad_subtype);
5058 fence_nesting_factor(fence) = factor;
5059 break;
5060 case left_operator_side:
5061 {
5062 tex_aux_push_math(math_fence_group, style, -1);
5063 node_next(cur_list.head) = fence;
5064 cur_list.tail = fence;
5065 cur_list.delimiter = fence;
5066 saved_operator_initialize();
5067 saved_operator_variant = math_limits_top;
5068 lmt_save_state.save_stack_data.ptr += saved_operator_n_of_records;
5069 tex_aux_push_math(math_operator_group, tex_math_style_variant(style, math_parameter_superscript_variant), -1);
5070 tex_scan_left_brace();
5071 }
5072 break;
5073 case no_fence_side:
5074 {
5075 halfword n = tex_new_node(simple_noad, fenced_noad_subtype);
5076 halfword l = tex_new_node(sub_mlist_node, 0);
5077 if (attrlist) {
5078 tex_attach_attribute_list_attribute(n, attrlist);
5079 tex_attach_attribute_list_attribute(l, attrlist);
5080 }
5081 tex_tail_append(n);
5082 set_noad_main_class(n, mainclass);
5083 noad_nucleus(n) = l;
5084 kernel_math_list(noad_nucleus(n)) = fence;
5085 }
5086 break;
5087 default:
5088 tex_confusion("left right fence");
5089 break;
5090 }
5091 if (! tex_tail_apply_callback(fence, call)) {
5092 tex_confusion("messed up fence");
5093 }
5094 }
5095}
5096
5097
5103
5104static void tex_aux_check_second_math_shift(void)
5105{
5106 tex_get_x_token();
5107 if (cur_cmd != math_shift_cmd) {
5108 tex_back_input(cur_tok);
5109 tex_handle_error(
5110 normal_error_type,
5111 "Display math should end with $$",
5112 "The '$' that I just saw supposedly matches a previous '$$'. So I shall assume\n"
5113 "that you typed '$$' both times."
5114 );
5115 }
5116}
5117
5118static void tex_aux_check_display_math_end(void)
5119{
5120 switch (cur_chr) {
5121 case end_display_math_code:
5122 case end_math_mode_code:
5123 return;
5124 }
5125 tex_handle_error(
5126 normal_error_type,
5127 "Display math should end with \\Ustopdisplaymath or \\Ustopmathmode",
5128 "I shall assume that you typed that."
5129 );
5130}
5131
5132static void tex_aux_check_inline_math_end(void)
5133{
5134 switch (cur_chr) {
5135 case end_inline_math_code:
5136 case end_math_mode_code:
5137 return;
5138 }
5139 tex_handle_error(
5140 normal_error_type,
5141 "Inline math should end with \\Ustopmath or \\Ustopmathmode",
5142 "I shall assume that you typed that."
5143 );
5144}
5145
5146static void tex_aux_resume_after_display(void)
5147{
5148 switch (cur_group) {
5149 case math_display_group:
5150 tex_aux_unsave_math();
5151 cur_list.prev_graf += 3;
5152 tex_push_nest();
5153 cur_list.mode = hmode;
5154 cur_list.space_factor = default_space_factor;
5155
5159 tex_tail_append(tex_new_par_node(parameter_par_subtype));
5160 tex_get_x_token();
5161 if (cur_cmd != spacer_cmd) {
5162 tex_back_input(cur_tok);
5163 }
5164 if (lmt_nest_state.nest_data.ptr == 1) {
5165 tex_build_page(after_display_page_context, 0);
5166 }
5167 break;
5168 default:
5169 tex_confusion("finishing display math");
5170 break;
5171 }
5172}
5173
5174
5191
5192static void tex_aux_inject_display_skip(quarterword param, quarterword subtype)
5193{
5194 if (param > 0) {
5195 switch (display_skip_mode_par) {
5196 case display_skip_default :
5197 case display_skip_always :
5198 break;
5199 case display_skip_non_zero:
5200 if (tex_glue_is_zero(glue_parameter(param))) {
5201 return;
5202 } else {
5203 break;
5204 }
5205 case display_skip_ignore:
5206 return;
5207 default:
5208
5209 break;
5210 }
5211 tex_tail_append(tex_new_param_glue_node(param, subtype));
5212 }
5213}
5214
5215static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfword equation)
5216{
5217
5218 halfword equation_box;
5219
5220 scaled equation_width;
5221
5222 scaled line_width;
5223
5224 scaled number_width;
5225
5226 scaled number_plus_gap_width;
5227
5228 scaled indent;
5229
5230 scaled displacement;
5231
5232 quarterword glue_above, glue_below;
5233
5234 quarterword subtype_above, subtype_below;
5235
5236 scaled eqno_width;
5237
5238 int swap_dir = math_direction_par != pre_display_direction_par;
5239 if (eqnumber && swap_dir) {
5240 atleft = ! atleft;
5241 }
5242
5243 lmt_packaging_state.post_adjust_tail = post_adjust_head;
5244 lmt_packaging_state.pre_adjust_tail = pre_adjust_head;
5245 lmt_packaging_state.post_migrate_tail = post_migrate_head;
5246 lmt_packaging_state.pre_migrate_tail = pre_migrate_head;
5247
5248 equation_box = tex_hpack(equation, 0, packing_additional, direction_unknown, holding_none_option, box_limit_none);
5249 node_subtype(equation_box) = equation_list;
5250 attach_current_attribute_list(equation_box);
5251 equation = box_list(equation_box);
5252
5253 equation_width = box_width(equation_box);
5254 line_width = display_width_par;
5255 indent = display_indent_par;
5256 if (eqnumber) {
5257 number_width = box_width(eqnumber);
5258 eqno_width = number_width;
5259 number_plus_gap_width = number_width + tex_round_xn_over_d(math_eqno_gap_step_par, tex_get_math_quad_style(text_style), scaling_factor);
5260 node_subtype(eqnumber) = equation_number_list;
5261
5262 } else {
5263 number_width = 0;
5264 eqno_width = 0;
5265 number_plus_gap_width = 0;
5266 }
5267 if (equation_width + number_plus_gap_width > line_width) {
5268
5274 if ((number_width != 0) && ((equation_width - lmt_packaging_state.total_shrink[normal_glue_order] + number_plus_gap_width <= line_width)
5275 || (lmt_packaging_state.total_shrink[fi_glue_order] != 0)
5276 || (lmt_packaging_state.total_shrink[fil_glue_order] != 0)
5277 || (lmt_packaging_state.total_shrink[fill_glue_order] != 0)
5278 || (lmt_packaging_state.total_shrink[filll_glue_order] != 0))) {
5279 box_list(equation_box) = null;
5280 tex_flush_node(equation_box);
5281 equation_box = tex_hpack(equation, line_width - number_plus_gap_width, packing_exactly, direction_unknown, holding_none_option, box_limit_none);
5282 node_subtype(equation_box) = equation_list;
5283 attach_current_attribute_list(equation_box);
5284 } else {
5285 number_width = 0;
5286 if (equation_width > line_width) {
5287 box_list(equation_box) = null;
5288 tex_flush_node(equation_box);
5289 equation_box = tex_hpack(equation, line_width, packing_exactly, direction_unknown, holding_none_option, box_limit_none);
5290 node_subtype(equation_box) = equation_list;
5291 attach_current_attribute_list(equation_box);
5292 }
5293 }
5294 equation_width = box_width(equation_box);
5295 }
5296
5306 displacement = tex_half_scaled(line_width - equation_width);
5307 if ((number_width > 0) && (displacement < 2 * number_width)) {
5308
5309 displacement = tex_half_scaled(line_width - equation_width - number_width);
5310
5314 if (equation && node_type(equation) == glue_node) {
5315 displacement = 0;
5316 }
5317 }
5318 tex_tail_append(tex_new_penalty_node(pre_display_penalty_par, before_display_penalty_subtype));
5319 if ((displacement + indent <= pre_display_size_par) || ((cur_list.math_dir == dir_lefttoright) && atleft)
5320 || ((cur_list.math_dir == dir_righttoleft) && ! atleft)) {
5321
5322 glue_above = above_display_skip_code;
5323 subtype_above = above_display_skip_glue;
5324 glue_below = below_display_skip_code;
5325 subtype_below = below_display_skip_glue;
5326 } else {
5327 glue_above = above_display_short_skip_code;
5328 subtype_above = above_display_short_skip_glue;
5329 glue_below = below_display_short_skip_code;
5330 subtype_below = below_display_short_skip_glue;
5331 }
5332
5341 if (eqnumber && atleft && (number_width == 0)) {
5342
5343 box_shift_amount(eqnumber) = 0;
5344
5345
5346 tex_append_to_vlist(eqnumber, lua_key_index(equation_number), NULL);
5347 tex_tail_append(tex_new_penalty_node(infinite_penalty, equation_number_penalty_subtype));
5348 } else {
5349 tex_aux_inject_display_skip(glue_above, subtype_above);
5350 }
5351 if (number_width != 0) {
5352
5356 scaled shift = line_width - equation_width - number_width - displacement;
5357 halfword move = tex_new_kern_node(shift, explicit_kern_subtype);
5358 if (atleft) {
5359 scaled amount;
5360 if (math_direction_par == dir_lefttoright) {
5361
5362
5363 amount = shift + number_width;
5364 } else {
5365
5366
5367 amount = line_width - equation_width;
5368 }
5369 {
5370 halfword kern = tex_new_kern_node(amount, explicit_kern_subtype);
5371 tex_try_couple_nodes(eqnumber, move);
5372 tex_try_couple_nodes(move, equation_box);
5373 tex_try_couple_nodes(equation_box, kern);
5374 equation_box = eqnumber;
5375 }
5376 } else {
5377 scaled amount;
5378 if (swap_dir) {
5379 if (math_direction_par == dir_lefttoright) {
5380
5381 amount = line_width - equation_width;
5382 } else {
5383
5384 amount = shift + equation_width;
5385 }
5386 } else {
5387 if (math_direction_par == dir_lefttoright) {
5388
5389 amount = displacement;
5390 } else {
5391
5392 amount = shift + number_width;
5393 }
5394 }
5395 {
5396 halfword kern = tex_new_kern_node(amount, explicit_kern_subtype);
5397 tex_try_couple_nodes(kern, equation_box);
5398 tex_try_couple_nodes(equation_box, move);
5399 tex_try_couple_nodes(move, eqnumber);
5400 equation_box = kern;
5401 }
5402 }
5403 equation_box = tex_hpack(equation_box, 0, packing_additional, direction_unknown, holding_none_option, box_limit_none);
5404 node_subtype(equation_box) = equation_list;
5405 attach_current_attribute_list(equation_box);
5406 box_shift_amount(equation_box) = indent;
5407 } else {
5408 box_shift_amount(equation_box) = indent + displacement;
5409 }
5410
5411 if (pre_adjust_head != lmt_packaging_state.pre_adjust_tail) {
5412 tex_inject_adjust_list(pre_adjust_head, 1, lmt_linebreak_state.just_box, NULL);
5413 }
5414 lmt_packaging_state.pre_adjust_tail = null;
5415
5416 if (pre_migrate_head != lmt_packaging_state.pre_migrate_tail) {
5417 tex_append_list(pre_migrate_head, lmt_packaging_state.pre_migrate_tail);
5418
5419
5420
5421 }
5422
5423 tex_append_to_vlist(equation_box, lua_key_index(equation), NULL);
5424 if (eqnumber && number_width == 0 && ! atleft) {
5425 tex_tail_append(tex_new_penalty_node(infinite_penalty, equation_number_penalty_subtype));
5426
5427 box_shift_amount(eqnumber) = indent + line_width - eqno_width ;
5428
5429
5430 tex_append_to_vlist(eqnumber, lua_key_index(equation_number), NULL);
5431 glue_below = 0;
5432 }
5433
5434 if (post_migrate_head != lmt_packaging_state.post_migrate_tail) {
5435 tex_append_list(post_migrate_head, lmt_packaging_state.post_migrate_tail);
5436
5437
5438
5439 }
5440 lmt_packaging_state.post_migrate_tail = null;
5441 if (lmt_packaging_state.post_adjust_tail) {
5442 if (post_adjust_head != lmt_packaging_state.post_adjust_tail) {
5443 tex_inject_adjust_list(post_adjust_head, 1, null, NULL);
5444 }
5445 lmt_packaging_state.post_adjust_tail = null;
5446 }
5447 lmt_packaging_state.except = 0;
5448
5449 tex_tail_append(tex_new_penalty_node(post_display_penalty_par, after_display_penalty_subtype));
5450 tex_aux_inject_display_skip(glue_below, subtype_below);
5451 tex_aux_resume_after_display();
5452}
5453
5454
5465
5466
5467
5468static inline int tex_aux_class_from_glyph(halfword n)
5469{
5470 return node_subtype(n) - (node_subtype(n) > glyph_math_extra_subtype ? glyph_math_extra_subtype : glyph_math_ordinary_subtype);
5471}
5472
5473static inline int tex_aux_class_from_list(halfword n)
5474{
5475 switch (node_subtype(n)) {
5476 case math_fraction_list:
5477 return fraction_noad_subtype;
5478 case math_accent_list:
5479 return accent_noad_subtype;
5480 case math_radical_list:
5481 return radical_noad_subtype;
5482 default:
5483 return 0;
5484 }
5485}
5486
5487static int tex_aux_short_math(halfword m)
5488{
5489
5490 if (m) {
5491
5501 switch (node_type(m)) {
5502 case kern_node:
5503
5504 m = node_next(m);
5505 break;
5506 case hlist_node:
5507 case vlist_node:
5508
5512 if (! node_next(m) && tex_math_has_class_option(tex_aux_class_from_list(m), short_inline_class_option)) {
5513 scaled threshold = short_inline_math_threshold_par;
5514 if (threshold > 0 && box_width(m) <= threshold) {
5515 return 1;
5516 }
5517 }
5518 return 0;
5519 }
5520
5521 if (m) {
5522 switch (node_type(m)) {
5523 case glyph_node:
5524 if (tex_math_has_class_option(tex_aux_class_from_glyph(m), short_inline_class_option)) {
5525 m = node_next(m);
5526 break;
5527 } else {
5528 return 0;
5529 }
5530 default:
5531 return 0;
5532 }
5533 } else {
5534 return 0;
5535 }
5536
5537 if (m) {
5538 switch (node_type(m)) {
5539 case vlist_node:
5540 case hlist_node:
5541 switch (node_subtype(m)) {
5542 case math_sup_list:
5543 case math_sub_list:
5544 case math_prime_list:
5545 case math_pre_post_sup_list:
5546 case math_pre_post_sub_list:
5547 case math_scripts_list:
5548 m = node_next(m);
5549 break;
5550 }
5551
5552 }
5553 }
5554
5555 if (m && node_type(m) == kern_node) {
5556 m = node_next(m);
5557 }
5558 return ! m;
5559 }
5560 return 0;
5561}
5562
5563void tex_run_math_shift(void)
5564{
5565 switch (cur_group) {
5566 case math_inline_group:
5567 case math_display_group:
5568 case math_number_group:
5569 {
5570
5571 halfword eqnumber = null;
5572
5573 int atleft = 0;
5574
5575 int mode = cur_list.mode;
5576 int mathmode = cur_list.math_mode;
5577
5578 halfword mathlist = tex_aux_finish_math_list(null);
5579 int mathleft = cur_list.math_begin;
5580 int mathright = cur_list.math_end;
5581 if (cur_cmd == math_shift_cs_cmd) {
5582 switch (cur_chr) {
5583 case begin_inline_math_code:
5584 case begin_display_math_code:
5585 case begin_math_mode_code:
5586 tex_you_cant_error(NULL);
5587 break;
5588 }
5589 }
5590 if (cur_list.mode == -mode) {
5591
5592 AGAIN:
5593 switch (cur_cmd) {
5594 case math_shift_cmd:
5595 tex_aux_check_second_math_shift();
5596 break;
5597 case end_paragraph_cmd:
5598 tex_get_x_token();
5599 goto AGAIN;
5600 default:
5601 tex_aux_check_display_math_end();
5602 break;
5603 }
5604 tex_run_mlist_to_hlist(mathlist, 0, text_style, unset_noad_class, unset_noad_class);
5605 eqnumber = tex_hpack(node_next(temp_head), 0, packing_additional, direction_unknown, holding_none_option, box_limit_none);
5606 attach_current_attribute_list(eqnumber);
5607 tex_aux_unsave_math();
5608
5609 lmt_save_state.save_stack_data.ptr -= saved_equation_number_n_of_records;
5610
5611 atleft = saved_equation_number_location == left_location_code;
5612 mode = cur_list.mode;
5613 mathlist = tex_aux_finish_math_list(null);
5614
5615
5616
5617 }
5618 if (mode == inline_mmode) {
5619
5620
5628 halfword beginmath = tex_new_node(math_node, begin_inline_math);
5629 halfword endmath = tex_new_node(math_node, end_inline_math);
5630 halfword shortmath = 0;
5631 switch (cur_list.math_main_style) {
5632 case display_style:
5633 case cramped_display_style:
5634 math_options(beginmath) |= math_option_display;
5635 math_options(endmath) |= math_option_display;
5636 break;
5637 }
5638 switch (cur_list.math_main_style) {
5639 case cramped_display_style:
5640 case cramped_text_style:
5641 case cramped_script_style:
5642 case cramped_script_script_style:
5643 math_options(beginmath) |= math_option_cramped;
5644 math_options(endmath) |= math_option_cramped;
5645 break;
5646 }
5647 if (mathmode) {
5648 switch (cur_cmd) {
5649 case math_shift_cs_cmd:
5650 if (cur_chr != end_display_math_code && cur_chr != end_math_mode_code) {
5651 tex_aux_check_second_math_shift();
5652 }
5653 break;
5654 case math_shift_cmd:
5655 tex_aux_check_second_math_shift();
5656 break;
5657 }
5658 } else if (cur_cmd == math_shift_cs_cmd) {
5659 tex_aux_check_inline_math_end();
5660 }
5661 tex_tail_append(beginmath);
5662 if (pre_inline_penalty_par != max_integer) {
5663 math_penalty(beginmath) = pre_inline_penalty_par;
5664 }
5665
5666 switch (math_skip_mode_par) {
5667 case math_skip_surround_when_zero:
5668 if (! tex_glue_is_zero(math_skip_par)) {
5669 tex_copy_glue_values(beginmath, math_skip_par);
5670 } else {
5671 math_surround(beginmath) = math_surround_par;
5672 }
5673 break ;
5674 case math_skip_always_left:
5675 case math_skip_always_both:
5676 case math_skip_only_when_skip:
5677 tex_copy_glue_values(beginmath, math_skip_par);
5678 break ;
5679 case math_skip_always_right:
5680 case math_skip_ignore:
5681 break ;
5682 case math_skip_always_surround:
5683 default:
5684 math_surround(beginmath) = math_surround_par;
5685 break;
5686 }
5687
5688 if (cur_list.math_dir) {
5689 tex_tail_append(tex_new_dir(normal_dir_subtype, math_direction_par));
5690 }
5691 tex_run_mlist_to_hlist(mathlist, cur_list.mode > nomode, is_valid_math_style(cur_list.math_main_style) ? cur_list.math_main_style : text_style, cur_list.math_begin, cur_list.math_end);
5692 shortmath = tex_aux_short_math(node_next(temp_head));
5693 tex_try_couple_nodes(cur_list.tail, node_next(temp_head));
5694 cur_list.tail = tex_tail_of_node_list(cur_list.tail);
5695 if (cur_list.math_dir) {
5696 tex_tail_append(tex_new_dir(cancel_dir_subtype, math_direction_par));
5697 }
5698 cur_list.math_dir = 0;
5699 tex_tail_append(endmath);
5700
5701 if (post_inline_penalty_par != max_integer) {
5702 math_penalty(endmath) = post_inline_penalty_par;
5703 }
5704
5705 switch (math_skip_mode_par) {
5706 case math_skip_surround_when_zero :
5707 if (! tex_glue_is_zero(math_skip_par)) {
5708 tex_copy_glue_values(endmath, math_skip_par);
5709 math_surround(endmath) = 0;
5710 } else {
5711 math_surround(endmath) = math_surround_par;
5712 }
5713 break;
5714 case math_skip_always_right:
5715 case math_skip_always_both:
5716 case math_skip_only_when_skip:
5717 tex_copy_glue_values(endmath, math_skip_par);
5718 break;
5719 case math_skip_always_left:
5720 case math_skip_ignore:
5721 break;
5722 case math_skip_always_surround:
5723 default:
5724 math_surround(endmath) = math_surround_par;
5725 break;
5726 }
5727
5728 if (shortmath) {
5729 if (pre_short_inline_penalty_par != max_integer) {
5730 math_penalty(beginmath) = pre_short_inline_penalty_par;
5731 }
5732 if (post_short_inline_penalty_par != max_integer) {
5733 math_penalty(endmath) = post_short_inline_penalty_par;
5734 }
5735 tex_add_math_option(beginmath, math_option_short);
5736 tex_add_math_option(endmath, math_option_short);
5737 }
5738 cur_list.space_factor = default_space_factor;
5739 mathleft = cur_list.math_begin;
5740 mathright = cur_list.math_end;
5741 math_tolerance(beginmath) = math_tolerance_par;
5742 math_pre_tolerance(beginmath) = math_pre_tolerance_par;
5743 math_tolerance(endmath) = tolerance_par;
5744 math_pre_tolerance(endmath) = pre_tolerance_par;
5745 tex_aux_unsave_math();
5746 } else {
5747 if (! eqnumber) {
5748 if (cur_cmd == math_shift_cmd) {
5749 tex_aux_check_second_math_shift();
5750 } else {
5751 tex_aux_check_display_math_end();
5752 }
5753 }
5754 tex_run_mlist_to_hlist(mathlist, 0, display_style, cur_list.math_begin, cur_list.math_end);
5755 mathleft = cur_list.math_begin;
5756 mathright = cur_list.math_end;
5757 tex_aux_finish_displayed_math(atleft, eqnumber, node_next(temp_head));
5758 }
5759
5760 update_tex_math_left_class(mathleft);
5761 update_tex_math_right_class(mathright);
5762
5763 lmt_math_state.last_left = mathleft;
5764 lmt_math_state.last_right = mathright;
5765 }
5766 break;
5767 default:
5768 tex_off_save();
5769 break;
5770 }
5771}
5772
5773
5780
5781void tex_finish_display_alignment(halfword head, halfword tail, halfword prevdepth)
5782{
5783 tex_handle_assignments();
5784 AGAIN:
5785 switch (cur_cmd) {
5786 case math_shift_cmd:
5787 tex_aux_check_second_math_shift();
5788 break;
5789 case end_paragraph_cmd:
5790 tex_get_x_token();
5791 goto AGAIN;
5792 default:
5793 tex_aux_check_display_math_end();
5794 break;
5795 }
5796 tex_pop_nest();
5797 tex_tail_append(tex_new_penalty_node(pre_display_penalty_par, before_display_penalty_subtype));
5798 tex_aux_inject_display_skip(above_display_skip_code, above_display_skip_glue);
5799 node_next(cur_list.tail) = head;
5800 if (head && tail) {
5801 cur_list.tail = tail;
5802 }
5803 tex_tail_append(tex_new_penalty_node(post_display_penalty_par, after_display_penalty_subtype));
5804 tex_aux_inject_display_skip(below_display_skip_code, below_display_skip_glue);
5805 cur_list.prev_depth = prevdepth;
5806 tex_aux_resume_after_display();
5807}
5808
5809
5815
5816static void tex_aux_define_inl_math_parameters(int size, int param, scaled value, int level)
5817{
5818 switch (size) {
5819 case script_size:
5820 tex_def_math_parameter(script_style, param, value, level, indirect_math_regular, 1);
5821 tex_def_math_parameter(cramped_script_style, param, value, level, indirect_math_regular, 1);
5822 break;
5823 case script_script_size:
5824 tex_def_math_parameter(script_script_style, param, value, level, indirect_math_regular, 1);
5825 tex_def_math_parameter(cramped_script_script_style, param, value, level, indirect_math_regular, 1);
5826 break;
5827 default:
5828 tex_def_math_parameter(text_style, param, value, level, indirect_math_regular, 1);
5829 tex_def_math_parameter(cramped_text_style, param, value, level, indirect_math_regular, 1);
5830 break;
5831 }
5832}
5833
5834static void tex_aux_define_dis_math_parameters(int size, int param, scaled value, int level)
5835{
5836 if (size == text_size) {
5837 tex_def_math_parameter(display_style, param, value, level, indirect_math_regular, 1);
5838 tex_def_math_parameter(cramped_display_style, param, value, level, indirect_math_regular, 1);
5839 }
5840}
5841
5842
5862
5863static void tex_aux_define_all_math_parameters(int size, int param, scaled value, int level)
5864{
5865 switch (size) {
5866 case script_size:
5867 tex_def_math_parameter(script_style, param, value, level, indirect_math_regular, 1);
5868 tex_def_math_parameter(cramped_script_style, param, value, level, indirect_math_regular, 1);
5869 break;
5870 case script_script_size:
5871 tex_def_math_parameter(script_script_style, param, value, level, indirect_math_regular, 1);
5872 tex_def_math_parameter(cramped_script_script_style, param, value, level, indirect_math_regular, 1);
5873 break;
5874 default:
5875 tex_def_math_parameter(text_style, param, value, level, indirect_math_regular, 1);
5876 tex_def_math_parameter(cramped_text_style, param, value, level, indirect_math_regular, 1);
5877 tex_def_math_parameter(display_style, param, value, level, indirect_math_regular, 1);
5878 tex_def_math_parameter(cramped_display_style, param, value, level, indirect_math_regular, 1);
5879 break;
5880 }
5881}
5882
5883
5896
5897# define total_mathsy_parameters 22
5898# define total_mathex_parameters 13
5899
5900# define mathsy(A,B) font_parameter(tex_fam_fnt(2,A),B)
5901# define mathex(A,B) font_parameter(tex_fam_fnt(3,A),B)
5902
5903# define math_x_height(A) mathsy(A,5)
5904# define math_quad(A) mathsy(A,6)
5905# define num1(A) mathsy(A,8)
5906# define num2(A) mathsy(A,9)
5907# define num3(A) mathsy(A,10)
5908# define denom1(A) mathsy(A,11)
5909# define denom2(A) mathsy(A,12)
5910# define sup1(A) mathsy(A,13)
5911# define sup2(A) mathsy(A,14)
5912# define sup3(A) mathsy(A,15)
5913# define sub1(A) mathsy(A,16)
5914# define sub2(A) mathsy(A,17)
5915# define sup_drop(A) mathsy(A,18)
5916# define sub_drop(A) mathsy(A,19)
5917# define delim1(A) mathsy(A,20)
5918# define delim2(A) mathsy(A,21)
5919# define axis_height(A) mathsy(A,22)
5920
5921# define default_rule_thickness(A) mathex(A,8)
5922# define big_operator_spacing1(A) mathex(A,9)
5923# define big_operator_spacing2(A) mathex(A,10)
5924# define big_operator_spacing3(A) mathex(A,11)
5925# define big_operator_spacing4(A) mathex(A,12)
5926# define big_operator_spacing5(A) mathex(A,13)
5927
5928# define math_parameter(a,b) ((font_math_parameter_count(a) >= b) ? font_math_parameter(a,b) : undefined_math_parameter)
5929
5930static inline scaled tex_aux_get_font_math_parameter(scaled scale, halfword f, int id)
5931{
5932 scaled v = math_parameter(f, id);
5933 if (v == undefined_math_parameter) {
5934 return v;
5935 } else {
5936 return v ? scaledround(0.001 * scale * v) : 0;
5937 }
5938}
5939
5940static inline scaled tex_aux_get_font_math_quantity(scaled scale, halfword v)
5941{
5942 return v ? scaledround(0.001 * scale * v) : 0;
5943}
5944
5945
5949
5950void tex_fixup_math_parameters(int fam, int size, int f, int level)
5951{
5952 scaled scale = tex_get_math_font_scale(f, size);
5953
5954 if (tracing_math_par > 1) {
5955 tex_begin_diagnostic();
5956 tex_print_format("[math: fixing up font, family %i, size %i, font %i, level %i]", fam, size, f, level);
5957 tex_end_diagnostic();
5958 }
5959
5960
5961
5962
5963 tex_aux_define_all_math_parameters(size, math_parameter_quad, tex_aux_get_font_math_quantity (scale, font_size(f)), level);
5964 tex_aux_define_all_math_parameters(size, math_parameter_exheight, tex_aux_get_font_math_quantity (scale, font_parameter(f, ex_height_code)), level);
5965 tex_aux_define_all_math_parameters(size, math_parameter_axis, tex_aux_get_font_math_parameter(scale, f, AxisHeight), level);
5966
5967 tex_aux_define_all_math_parameters(size, math_parameter_accent_base_height, tex_aux_get_font_math_parameter(scale, f, AccentBaseHeight), level);
5968 tex_aux_define_all_math_parameters(size, math_parameter_accent_base_depth, tex_aux_get_font_math_parameter(scale, f, AccentBaseDepth), level);
5969 tex_aux_define_all_math_parameters(size, math_parameter_flattened_accent_base_height, tex_aux_get_font_math_parameter(scale, f, FlattenedAccentBaseHeight), level);
5970 tex_aux_define_all_math_parameters(size, math_parameter_flattened_accent_base_depth, tex_aux_get_font_math_parameter(scale, f, FlattenedAccentBaseDepth), level);
5971 tex_aux_define_all_math_parameters(size, math_parameter_overbar_kern, tex_aux_get_font_math_parameter(scale, f, OverbarExtraAscender), level);
5972 tex_aux_define_all_math_parameters(size, math_parameter_overbar_rule, tex_aux_get_font_math_parameter(scale, f, OverbarRuleThickness), level);
5973 tex_aux_define_all_math_parameters(size, math_parameter_overbar_vgap, tex_aux_get_font_math_parameter(scale, f, OverbarVerticalGap), level);
5974 tex_aux_define_all_math_parameters(size, math_parameter_underbar_kern, tex_aux_get_font_math_parameter(scale, f, UnderbarExtraDescender), level);
5975 tex_aux_define_all_math_parameters(size, math_parameter_underbar_rule, tex_aux_get_font_math_parameter(scale, f, UnderbarRuleThickness ), level);
5976 tex_aux_define_all_math_parameters(size, math_parameter_underbar_vgap, tex_aux_get_font_math_parameter(scale, f, UnderbarVerticalGap), level);
5977 tex_aux_define_all_math_parameters(size, math_parameter_under_delimiter_vgap, tex_aux_get_font_math_parameter(scale, f, StretchStackGapAboveMin), level);
5978 tex_aux_define_all_math_parameters(size, math_parameter_under_delimiter_bgap, tex_aux_get_font_math_parameter(scale, f, StretchStackBottomShiftDown), level);
5979 tex_aux_define_all_math_parameters(size, math_parameter_over_delimiter_vgap, tex_aux_get_font_math_parameter(scale, f, StretchStackGapBelowMin), level);
5980 tex_aux_define_all_math_parameters(size, math_parameter_over_delimiter_bgap, tex_aux_get_font_math_parameter(scale, f, StretchStackTopShiftUp), level);
5981 tex_aux_define_all_math_parameters(size, math_parameter_radical_kern, tex_aux_get_font_math_parameter(scale, f, RadicalExtraAscender), level);
5982 tex_aux_define_all_math_parameters(size, math_parameter_radical_rule, tex_aux_get_font_math_parameter(scale, f, RadicalRuleThickness), level);
5983 tex_aux_define_all_math_parameters(size, math_parameter_radical_degree_before, tex_aux_get_font_math_parameter(scale, f, RadicalKernBeforeDegree), level);
5984 tex_aux_define_all_math_parameters(size, math_parameter_radical_degree_after, tex_aux_get_font_math_parameter(scale, f, RadicalKernAfterDegree), level);
5985 tex_aux_define_all_math_parameters(size, math_parameter_subscript_shift_drop, tex_aux_get_font_math_parameter(scale, f, SubscriptBaselineDropMin), level);
5986 tex_aux_define_all_math_parameters(size, math_parameter_superscript_shift_drop, tex_aux_get_font_math_parameter(scale, f, SuperscriptBaselineDropMax), level);
5987 tex_aux_define_all_math_parameters(size, math_parameter_subscript_shift_down, tex_aux_get_font_math_parameter(scale, f, SubscriptShiftDown), level);
5988 tex_aux_define_all_math_parameters(size, math_parameter_prime_shift_drop, tex_aux_get_font_math_parameter(scale, f, PrimeBaselineDropMax), level);
5989 tex_aux_define_all_math_parameters(size, math_parameter_subscript_top_max, tex_aux_get_font_math_parameter(scale, f, SubscriptTopMax), level);
5990 tex_aux_define_all_math_parameters(size, math_parameter_superscript_bottom_min, tex_aux_get_font_math_parameter(scale, f, SuperscriptBottomMin), level);
5991 tex_aux_define_all_math_parameters(size, math_parameter_superscript_subscript_bottom_max, tex_aux_get_font_math_parameter(scale, f, SuperscriptBottomMaxWithSubscript), level);
5992 tex_aux_define_all_math_parameters(size, math_parameter_subscript_superscript_vgap, tex_aux_get_font_math_parameter(scale, f, SubSuperscriptGapMin), level);
5993 tex_aux_define_all_math_parameters(size, math_parameter_limit_above_vgap, tex_aux_get_font_math_parameter(scale, f, UpperLimitGapMin), level);
5994 tex_aux_define_all_math_parameters(size, math_parameter_limit_above_bgap, tex_aux_get_font_math_parameter(scale, f, UpperLimitBaselineRiseMin), level);
5995 tex_aux_define_all_math_parameters(size, math_parameter_limit_below_vgap, tex_aux_get_font_math_parameter(scale, f, LowerLimitGapMin), level);
5996 tex_aux_define_all_math_parameters(size, math_parameter_limit_below_bgap, tex_aux_get_font_math_parameter(scale, f, LowerLimitBaselineDropMin), level);
5997 tex_aux_define_all_math_parameters(size, math_parameter_nolimit_sub_factor, tex_aux_get_font_math_parameter(scale, f, NoLimitSubFactor), level);
5998 tex_aux_define_all_math_parameters(size, math_parameter_nolimit_sup_factor, tex_aux_get_font_math_parameter(scale, f, NoLimitSupFactor), level);
5999 tex_aux_define_all_math_parameters(size, math_parameter_skewed_fraction_hgap, tex_aux_get_font_math_parameter(scale, f, SkewedFractionHorizontalGap), level);
6000 tex_aux_define_all_math_parameters(size, math_parameter_skewed_fraction_vgap, tex_aux_get_font_math_parameter(scale, f, SkewedFractionVerticalGap), level);
6001 tex_aux_define_all_math_parameters(size, math_parameter_space_before_script, tex_aux_get_font_math_parameter(scale, f, SpaceBeforeScript), level);
6002 tex_aux_define_all_math_parameters(size, math_parameter_space_between_script, tex_aux_get_font_math_parameter(scale, f, SpaceBetweenScript), level);
6003 tex_aux_define_all_math_parameters(size, math_parameter_space_after_script, tex_aux_get_font_math_parameter(scale, f, SpaceAfterScript), level);
6004 tex_aux_define_all_math_parameters(size, math_parameter_connector_overlap_min, tex_aux_get_font_math_parameter(scale, f, MinConnectorOverlap), level);
6005 tex_aux_define_all_math_parameters(size, math_parameter_superscript_snap, tex_aux_get_font_math_parameter(scale, f, SuperscriptSnap), level);
6006 tex_aux_define_all_math_parameters(size, math_parameter_subscript_snap, tex_aux_get_font_math_parameter(scale, f, SubscriptSnap), level);
6007 tex_aux_define_all_math_parameters(size, math_parameter_fraction_rule, tex_aux_get_font_math_parameter(scale, f, FractionRuleThickness), level);
6008
6009 tex_aux_define_all_math_parameters(size, math_parameter_prime_space_after, tex_aux_get_font_math_parameter(scale, f, PrimeSpaceAfter), level);
6010 tex_aux_define_all_math_parameters(size, math_parameter_skewed_delimiter_tolerance, tex_aux_get_font_math_parameter(scale, f, SkewedDelimiterTolerance), level);
6011 tex_aux_define_all_math_parameters(size, math_parameter_accent_top_shift_up, tex_aux_get_font_math_parameter(scale, f, AccentTopShiftUp), level);
6012 tex_aux_define_all_math_parameters(size, math_parameter_accent_bottom_shift_down, tex_aux_get_font_math_parameter(scale, f, AccentBottomShiftDown), level);
6013 tex_aux_define_all_math_parameters(size, math_parameter_accent_top_overshoot, tex_aux_get_font_math_parameter(scale, f, AccentTopOvershoot), level);
6014 tex_aux_define_all_math_parameters(size, math_parameter_accent_bottom_overshoot, tex_aux_get_font_math_parameter(scale, f, AccentBottomOvershoot), level);
6015 tex_aux_define_all_math_parameters(size, math_parameter_accent_superscript_drop, tex_aux_get_font_math_parameter(scale, f, AccentSuperscriptDrop), level);
6016 tex_aux_define_all_math_parameters(size, math_parameter_accent_superscript_percent, tex_aux_get_font_math_parameter(scale, f, AccentSuperscriptPercent), level);
6017 tex_aux_define_all_math_parameters(size, math_parameter_accent_extend_margin, tex_aux_get_font_math_parameter(scale, f, AccentExtendMargin), level);
6018 tex_aux_define_all_math_parameters(size, math_parameter_flattened_accent_top_shift_up, tex_aux_get_font_math_parameter(scale, f, FlattenedAccentTopShiftUp), level);
6019 tex_aux_define_all_math_parameters(size, math_parameter_flattened_accent_bottom_shift_down, tex_aux_get_font_math_parameter(scale, f, FlattenedAccentBottomShiftDown), level);
6020 tex_aux_define_all_math_parameters(size, math_parameter_delimiter_extend_margin, tex_aux_get_font_math_parameter(scale, f, DelimiterExtendMargin), level);
6021 tex_aux_define_all_math_parameters(size, math_parameter_radical_extensible_after, tex_aux_get_font_math_parameter(scale, f, RadicalKernAfterExtensible), level);
6022 tex_aux_define_all_math_parameters(size, math_parameter_radical_extensible_before, tex_aux_get_font_math_parameter(scale, f, RadicalKernBeforeExtensible), level);
6023
6024
6025
6026 tex_aux_define_all_math_parameters(size, math_parameter_prime_raise, math_parameter(f, PrimeRaisePercent), level);
6027 tex_aux_define_all_math_parameters(size, math_parameter_prime_raise_composed, math_parameter(f, PrimeRaiseComposedPercent), level);
6028 tex_aux_define_all_math_parameters(size, math_parameter_radical_degree_raise, math_parameter(f, RadicalDegreeBottomRaisePercent), level);
6029
6030
6031
6032 tex_aux_define_all_math_parameters(size, math_parameter_x_scale, scaling_factor, level);
6033 tex_aux_define_all_math_parameters(size, math_parameter_y_scale, scaling_factor, level);
6034
6035
6036
6037 tex_aux_define_all_math_parameters(size, math_parameter_limit_above_kern, 0, level);
6038 tex_aux_define_all_math_parameters(size, math_parameter_limit_below_kern, 0, level);
6039 tex_aux_define_all_math_parameters(size, math_parameter_extra_superscript_shift, 0, level);
6040 tex_aux_define_all_math_parameters(size, math_parameter_extra_subscript_shift, 0, level);
6041 tex_aux_define_all_math_parameters(size, math_parameter_extra_superprescript_shift, 0, level);
6042 tex_aux_define_all_math_parameters(size, math_parameter_extra_subprescript_shift, 0, level);
6043 tex_aux_define_all_math_parameters(size, math_parameter_rule_height, 0, level);
6044 tex_aux_define_all_math_parameters(size, math_parameter_rule_depth, 0, level);
6045 tex_aux_define_all_math_parameters(size, math_parameter_extra_superscript_space, 0, level);
6046 tex_aux_define_all_math_parameters(size, math_parameter_extra_subscript_space, 0, level);
6047 tex_aux_define_all_math_parameters(size, math_parameter_extra_superprescript_space, 0, level);
6048 tex_aux_define_all_math_parameters(size, math_parameter_extra_subprescript_space, 0, level);
6049
6050
6051
6052 if (math_parameter(f, SubscriptShiftDownWithSuperscript) != undefined_math_parameter) {
6053 tex_aux_define_all_math_parameters(size, math_parameter_subscript_superscript_shift_down, tex_aux_get_font_math_parameter(scale, f, SubscriptShiftDownWithSuperscript), level);
6054 } else {
6055 tex_aux_define_all_math_parameters(size, math_parameter_subscript_superscript_shift_down, tex_aux_get_font_math_parameter(scale, f, SubscriptShiftDown), level);
6056 }
6057
6058
6059
6060 tex_aux_define_dis_math_parameters(size, math_parameter_delimiter_percent, math_parameter(f, DelimiterDisplayPercent), level);
6061 tex_aux_define_inl_math_parameters(size, math_parameter_delimiter_percent, math_parameter(f, DelimiterPercent), level);
6062
6063 tex_aux_define_dis_math_parameters(size, math_parameter_operator_size, tex_aux_get_font_math_parameter(scale, f, DisplayOperatorMinHeight), level);
6064 tex_aux_define_inl_math_parameters(size, math_parameter_radical_vgap, tex_aux_get_font_math_parameter(scale, f, RadicalVerticalGap), level);
6065 tex_aux_define_dis_math_parameters(size, math_parameter_radical_vgap, tex_aux_get_font_math_parameter(scale, f, RadicalDisplayStyleVerticalGap), level);
6066 tex_aux_define_inl_math_parameters(size, math_parameter_stack_num_up, tex_aux_get_font_math_parameter(scale, f, StackTopShiftUp), level);
6067 tex_aux_define_dis_math_parameters(size, math_parameter_stack_num_up, tex_aux_get_font_math_parameter(scale, f, StackTopDisplayStyleShiftUp), level);
6068 tex_aux_define_inl_math_parameters(size, math_parameter_stack_denom_down, tex_aux_get_font_math_parameter(scale, f, StackBottomShiftDown), level);
6069 tex_aux_define_dis_math_parameters(size, math_parameter_stack_denom_down, tex_aux_get_font_math_parameter(scale, f, StackBottomDisplayStyleShiftDown), level);
6070 tex_aux_define_inl_math_parameters(size, math_parameter_stack_vgap, tex_aux_get_font_math_parameter(scale, f, StackGapMin), level);
6071 tex_aux_define_dis_math_parameters(size, math_parameter_stack_vgap, tex_aux_get_font_math_parameter(scale, f, StackDisplayStyleGapMin), level);
6072 tex_aux_define_inl_math_parameters(size, math_parameter_fraction_num_vgap, tex_aux_get_font_math_parameter(scale, f, FractionNumeratorGapMin), level);
6073 tex_aux_define_dis_math_parameters(size, math_parameter_fraction_num_vgap, tex_aux_get_font_math_parameter(scale, f, FractionNumeratorDisplayStyleGapMin), level);
6074 tex_aux_define_inl_math_parameters(size, math_parameter_fraction_num_up, tex_aux_get_font_math_parameter(scale, f, FractionNumeratorShiftUp), level);
6075 tex_aux_define_dis_math_parameters(size, math_parameter_fraction_num_up, tex_aux_get_font_math_parameter(scale, f, FractionNumeratorDisplayStyleShiftUp), level);
6076 tex_aux_define_inl_math_parameters(size, math_parameter_fraction_denom_vgap, tex_aux_get_font_math_parameter(scale, f, FractionDenominatorGapMin), level);
6077 tex_aux_define_dis_math_parameters(size, math_parameter_fraction_denom_vgap, tex_aux_get_font_math_parameter(scale, f, FractionDenominatorDisplayStyleGapMin), level);
6078 tex_aux_define_inl_math_parameters(size, math_parameter_fraction_denom_down, tex_aux_get_font_math_parameter(scale, f, FractionDenominatorShiftDown), level);
6079 tex_aux_define_dis_math_parameters(size, math_parameter_fraction_denom_down, tex_aux_get_font_math_parameter(scale, f, FractionDenominatorDisplayStyleShiftDown), level);
6080 tex_aux_define_inl_math_parameters(size, math_parameter_fraction_del_size, tex_aux_get_font_math_parameter(scale, f, FractionDelimiterSize), level);
6081 tex_aux_define_dis_math_parameters(size, math_parameter_fraction_del_size, tex_aux_get_font_math_parameter(scale, f, FractionDelimiterDisplayStyleSize), level);
6082
6083 tex_aux_define_dis_math_parameters(size, math_parameter_delimiter_shortfall, tex_aux_get_font_math_parameter(scale, f, DelimiterDisplayShortfall), level);
6084 tex_aux_define_inl_math_parameters(size, math_parameter_delimiter_shortfall, tex_aux_get_font_math_parameter(scale, f, DelimiterShortfall), level);
6085
6086
6087
6088 switch (size) {
6089 case script_size:
6090 tex_def_math_parameter(script_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUp), level, indirect_math_regular, 1);
6091 tex_def_math_parameter(cramped_script_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUpCramped), level, indirect_math_regular, 1);
6092 tex_def_math_parameter(script_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUp), level, indirect_math_regular, 1);
6093 tex_def_math_parameter(cramped_script_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUpCramped), level, indirect_math_regular, 1);
6094 break;
6095 case script_script_size:
6096 tex_def_math_parameter(script_script_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUp), level, indirect_math_regular, 1);
6097 tex_def_math_parameter(cramped_script_script_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUpCramped), level, indirect_math_regular, 1);
6098 tex_def_math_parameter(script_script_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUp), level, indirect_math_regular, 1);
6099 tex_def_math_parameter(cramped_script_script_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUpCramped), level, indirect_math_regular, 1);
6100 break;
6101 default:
6102 tex_def_math_parameter(display_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUp), level, indirect_math_regular, 1);
6103 tex_def_math_parameter(cramped_display_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUpCramped), level, indirect_math_regular, 1);
6104 tex_def_math_parameter(text_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUp), level, indirect_math_regular, 1);
6105 tex_def_math_parameter(cramped_text_style, math_parameter_superscript_shift_up, tex_aux_get_font_math_parameter(scale, f, SuperscriptShiftUpCramped), level, indirect_math_regular, 1);
6106 tex_def_math_parameter(display_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUp), level, indirect_math_regular, 1);
6107 tex_def_math_parameter(cramped_display_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUpCramped), level, indirect_math_regular, 1);
6108 tex_def_math_parameter(text_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUp), level, indirect_math_regular, 1);
6109 tex_def_math_parameter(cramped_text_style, math_parameter_prime_shift_up, tex_aux_get_font_math_parameter(scale, f, PrimeShiftUpCramped), level, indirect_math_regular, 1);
6110 break;
6111 }
6112
6113}
6114
6115
6123
6124void tex_set_display_styles(halfword code, halfword value, halfword level, halfword indirect)
6125{
6126 tex_def_math_parameter(display_style, code, value, level, indirect, 0);
6127 tex_def_math_parameter(cramped_display_style, code, value, level, indirect, 0);
6128}
6129
6130void tex_set_text_styles(halfword code, halfword value, halfword level, halfword indirect)
6131{
6132 tex_def_math_parameter(text_style, code, value, level, indirect, 0);
6133 tex_def_math_parameter(cramped_text_style, code, value, level, indirect, 0);
6134}
6135
6136void tex_set_main_styles(halfword code, halfword value, halfword level, halfword indirect)
6137{
6138 for (int style = display_style; style <= cramped_text_style; style++) {
6139 tex_def_math_parameter(style, code, value, level, indirect, 0);
6140 }
6141}
6142
6143void tex_set_script_styles(halfword code, halfword value, halfword level, halfword indirect)
6144{
6145 tex_def_math_parameter(script_style, code, value, level, indirect, 0);
6146 tex_def_math_parameter(cramped_script_style, code, value, level, indirect, 0);
6147}
6148
6149void tex_set_script_script_styles(halfword code, halfword value, halfword level, halfword indirect)
6150{
6151 tex_def_math_parameter(script_script_style, code, value, level, indirect, 0);
6152 tex_def_math_parameter(cramped_script_script_style, code, value, level, indirect, 0);
6153}
6154
6155void tex_set_all_styles(halfword code, halfword value, halfword level, halfword indirect)
6156{
6157 for (int style = display_style; style <= cramped_script_script_style; style++) {
6158 tex_def_math_parameter(style, code, value, level, indirect, 0);
6159 }
6160}
6161
6162void tex_set_uncramped_styles(halfword code, halfword value, halfword level, halfword indirect)
6163{
6164 for (int style = display_style; style <= script_script_style; style += 2) {
6165 tex_def_math_parameter(style, code, value, level, indirect, 0);
6166 }
6167}
6168
6169void tex_set_cramped_styles(halfword code, halfword value, halfword level, halfword indirect)
6170{
6171 for (int style = cramped_display_style; style <= cramped_script_script_style; style += 2) {
6172 tex_def_math_parameter(style, code, value, level, indirect, 0);
6173 }
6174}
6175
6176void tex_set_split_styles(halfword code, halfword value, halfword level, halfword indirect)
6177{
6178 tex_set_display_styles (code, value, level, indirect);
6179 tex_set_text_styles (code, value, level, indirect);
6180 tex_set_script_styles (code, 0, level, indirect);
6181 tex_set_script_script_styles(code, 0, level, indirect);
6182}
6183
6184void tex_set_unsplit_styles(halfword code, halfword value, halfword level, halfword indirect)
6185{
6186 tex_set_script_styles (code, value, level, indirect);
6187 tex_set_script_script_styles(code, value, level, indirect);
6188}
6189
6190void tex_reset_all_styles(halfword level)
6191{
6192 for (int code = math_parameter_atom_pairs_first; code <= math_parameter_atom_pairs_last; code++) {
6193 tex_set_all_styles(code, zero_muskip_code, level, indirect_math_unset);
6194 }
6195}
6196
6197static inline halfword tex_aux_math_class_default(halfword mathclass) {
6198 return (mathclass << 24) + (mathclass << 16) + (mathclass << 8) + mathclass;
6199}
6200
6201static inline void tex_set_math_class_default(halfword mathclass, halfword parent, halfword options)
6202{
6203 tex_word_define(0, internal_integer_location(first_math_class_code + mathclass), tex_aux_math_class_default(parent));
6204 tex_word_define(0, internal_integer_location(first_math_atom_code + mathclass), tex_aux_math_class_default(mathclass));
6205 tex_word_define(0, internal_integer_location(first_math_options_code + mathclass), options);
6206 tex_word_define(0, internal_integer_location(first_math_parent_code + mathclass), tex_aux_math_class_default(mathclass));
6207}
6208
6209static void tex_aux_set_math_atom_rule(halfword left, halfword right, halfword newleft, halfword newright)
6210{
6211 tex_set_all_styles(math_parameter_rules_pair(left, right), (newleft << 16) + newright, level_one, indirect_math_regular);
6212}
6213
6214
6223
6224void tex_initialize_math_spacing(void)
6225{
6226
6227 for (int mathclass = 0; mathclass <= max_math_class_code; mathclass++) {
6228 tex_set_math_class_default(mathclass, mathclass, no_class_options);
6229
6230 tex_word_define(0, internal_integer_location(first_math_pre_penalty_code + mathclass), math_default_penalty);
6231 tex_word_define(0, internal_integer_location(first_math_post_penalty_code + mathclass), math_default_penalty);
6232 tex_word_define(0, internal_integer_location(first_math_display_pre_penalty_code + mathclass), math_default_penalty);
6233 tex_word_define(0, internal_integer_location(first_math_display_post_penalty_code + mathclass), math_default_penalty);
6234 }
6235
6236 tex_reset_all_styles(level_one);
6237
6238 tex_set_math_class_default(ordinary_noad_subtype, ordinary_noad_subtype, no_italic_correction_class_option |
6239 check_ligature_class_option |
6240 check_kern_pair_class_option |
6241 flatten_class_option);
6242 tex_set_math_class_default(operator_noad_subtype, operator_noad_subtype, check_ligature_class_option |
6243 check_kern_pair_class_option);
6244 tex_set_math_class_default(binary_noad_subtype, binary_noad_subtype, no_italic_correction_class_option |
6245 check_ligature_class_option |
6246 check_kern_pair_class_option |
6247 flatten_class_option);
6248 tex_set_math_class_default(relation_noad_subtype, relation_noad_subtype, no_italic_correction_class_option |
6249 check_ligature_class_option |
6250 check_kern_pair_class_option |
6251 flatten_class_option |
6252 omit_penalty_class_option);
6253 tex_set_math_class_default(open_noad_subtype, open_noad_subtype, no_italic_correction_class_option |
6254
6255 check_ligature_class_option |
6256 check_kern_pair_class_option);
6257 tex_set_math_class_default(close_noad_subtype, close_noad_subtype, no_italic_correction_class_option |
6258
6259 check_ligature_class_option |
6260 check_kern_pair_class_option);
6261 tex_set_math_class_default(punctuation_noad_subtype, punctuation_noad_subtype, no_italic_correction_class_option |
6262 check_ligature_class_option |
6263 check_kern_pair_class_option |
6264 flatten_class_option);
6265 tex_set_math_class_default(variable_noad_subtype, ordinary_noad_subtype, no_italic_correction_class_option);
6266 tex_set_math_class_default(active_noad_subtype, ordinary_noad_subtype, no_italic_correction_class_option);
6267 tex_set_math_class_default(inner_noad_subtype, inner_noad_subtype, flatten_class_option);
6268 tex_set_math_class_default(under_noad_subtype, ordinary_noad_subtype, no_class_options);
6269 tex_set_math_class_default(over_noad_subtype, ordinary_noad_subtype, no_class_options);
6270 tex_set_math_class_default(fraction_noad_subtype, ordinary_noad_subtype, no_class_options);
6271 tex_set_math_class_default(radical_noad_subtype, ordinary_noad_subtype, no_class_options);
6272 tex_set_math_class_default(middle_noad_subtype, open_noad_subtype, no_italic_correction_class_option);
6273 tex_set_math_class_default(accent_noad_subtype, ordinary_noad_subtype, no_class_options);
6274 tex_set_math_class_default(fenced_noad_subtype, inner_noad_subtype , no_class_options);
6275 tex_set_math_class_default(ghost_noad_subtype, ordinary_noad_subtype, no_class_options);
6276 tex_set_math_class_default(vcenter_noad_subtype, ordinary_noad_subtype, no_class_options);
6277 tex_set_math_class_default(prime_noad_subtype, ordinary_noad_subtype, no_class_options);
6278
6279 tex_aux_set_math_atom_rule(math_begin_class, binary_noad_subtype, ordinary_noad_subtype, ordinary_noad_subtype);
6280 tex_aux_set_math_atom_rule(binary_noad_subtype, math_end_class, ordinary_noad_subtype, ordinary_noad_subtype);
6281
6282 tex_aux_set_math_atom_rule(binary_noad_subtype, binary_noad_subtype, binary_noad_subtype, ordinary_noad_subtype);
6283 tex_aux_set_math_atom_rule(operator_noad_subtype, binary_noad_subtype, operator_noad_subtype, ordinary_noad_subtype);
6284 tex_aux_set_math_atom_rule(open_noad_subtype, binary_noad_subtype, open_noad_subtype, ordinary_noad_subtype);
6285 tex_aux_set_math_atom_rule(punctuation_noad_subtype, binary_noad_subtype, punctuation_noad_subtype, ordinary_noad_subtype);
6286 tex_aux_set_math_atom_rule(relation_noad_subtype, binary_noad_subtype, relation_noad_subtype, ordinary_noad_subtype);
6287
6288 tex_aux_set_math_atom_rule(binary_noad_subtype, close_noad_subtype, ordinary_noad_subtype, close_noad_subtype);
6289 tex_aux_set_math_atom_rule(binary_noad_subtype, punctuation_noad_subtype, ordinary_noad_subtype, punctuation_noad_subtype);
6290 tex_aux_set_math_atom_rule(binary_noad_subtype, relation_noad_subtype, ordinary_noad_subtype, relation_noad_subtype);
6291
6292 tex_aux_set_math_atom_rule(relation_noad_subtype, close_noad_subtype, ordinary_noad_subtype, close_noad_subtype);
6293 tex_aux_set_math_atom_rule(relation_noad_subtype, punctuation_noad_subtype, ordinary_noad_subtype, punctuation_noad_subtype);
6294
6295
6296
6297
6298
6299 tex_set_all_styles (math_parameter_spacing_pair(ordinary_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6300 tex_set_split_styles (math_parameter_spacing_pair(ordinary_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6301 tex_set_split_styles (math_parameter_spacing_pair(ordinary_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6302 tex_set_split_styles (math_parameter_spacing_pair(ordinary_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6303
6304 tex_set_all_styles (math_parameter_spacing_pair(operator_noad_subtype, ordinary_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6305 tex_set_all_styles (math_parameter_spacing_pair(operator_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6306 tex_set_split_styles (math_parameter_spacing_pair(operator_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6307 tex_set_split_styles (math_parameter_spacing_pair(operator_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6308
6309 tex_set_all_styles (math_parameter_spacing_pair(operator_noad_subtype, fraction_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6310 tex_set_all_styles (math_parameter_spacing_pair(operator_noad_subtype, radical_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6311 tex_set_all_styles (math_parameter_spacing_pair(fraction_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6312 tex_set_all_styles (math_parameter_spacing_pair(radical_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6313
6314 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, ordinary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6315 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, operator_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6316 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, open_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6317 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, inner_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6318
6319 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, middle_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6320 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, fraction_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6321 tex_set_split_styles (math_parameter_spacing_pair(binary_noad_subtype, radical_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6322 tex_set_split_styles (math_parameter_spacing_pair(middle_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6323 tex_set_split_styles (math_parameter_spacing_pair(fraction_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6324 tex_set_split_styles (math_parameter_spacing_pair(radical_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6325
6326 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, ordinary_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6327 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, operator_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6328 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, open_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6329 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, inner_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6330
6331 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, middle_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6332 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, fraction_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6333 tex_set_split_styles (math_parameter_spacing_pair(relation_noad_subtype, radical_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6334 tex_set_split_styles (math_parameter_spacing_pair(middle_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6335 tex_set_split_styles (math_parameter_spacing_pair(fraction_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6336 tex_set_split_styles (math_parameter_spacing_pair(radical_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6337
6338 tex_set_all_styles (math_parameter_spacing_pair(close_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6339 tex_set_split_styles (math_parameter_spacing_pair(close_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6340 tex_set_split_styles (math_parameter_spacing_pair(close_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6341 tex_set_split_styles (math_parameter_spacing_pair(close_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6342
6343 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, ordinary_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6344 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6345 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, relation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6346 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, open_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6347 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, close_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6348 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, punctuation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6349 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6350
6351 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, fraction_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6352 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, middle_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6353 tex_set_split_styles (math_parameter_spacing_pair(punctuation_noad_subtype, radical_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6354 tex_set_split_styles (math_parameter_spacing_pair(fraction_noad_subtype, punctuation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6355 tex_set_split_styles (math_parameter_spacing_pair(middle_noad_subtype, punctuation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6356 tex_set_split_styles (math_parameter_spacing_pair(radical_noad_subtype, punctuation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6357
6358 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, ordinary_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6359 tex_set_all_styles (math_parameter_spacing_pair(inner_noad_subtype, operator_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6360 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, binary_noad_subtype), med_muskip_code, level_one, indirect_math_regular);
6361 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, relation_noad_subtype), thick_muskip_code, level_one, indirect_math_regular);
6362 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, open_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6363 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, punctuation_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6364 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6365
6366 tex_set_split_styles (math_parameter_spacing_pair(inner_noad_subtype, middle_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6367 tex_set_split_styles (math_parameter_spacing_pair(fraction_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6368 tex_set_split_styles (math_parameter_spacing_pair(radical_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6369 tex_set_split_styles (math_parameter_spacing_pair(middle_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6370 tex_set_split_styles (math_parameter_spacing_pair(fraction_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6371 tex_set_split_styles (math_parameter_spacing_pair(radical_noad_subtype, inner_noad_subtype), thin_muskip_code, level_one, indirect_math_regular);
6372
6373
6374
6375 tex_set_all_styles (math_parameter_x_scale, scaling_factor, level_one, indirect_math_regular);
6376 tex_set_all_styles (math_parameter_y_scale, scaling_factor, level_one, indirect_math_regular);
6377
6378
6379
6380 tex_set_all_styles (math_parameter_over_line_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6381 tex_set_all_styles (math_parameter_under_line_variant, math_variant_presets[math_normal_style_variant], level_one, indirect_math_regular);
6382 tex_set_all_styles (math_parameter_over_delimiter_variant, math_variant_presets[math_small_style_variant], level_one, indirect_math_regular);
6383 tex_set_all_styles (math_parameter_under_delimiter_variant, math_variant_presets[math_small_style_variant], level_one, indirect_math_regular);
6384 tex_set_all_styles (math_parameter_delimiter_over_variant, math_variant_presets[math_normal_style_variant], level_one, indirect_math_regular);
6385 tex_set_all_styles (math_parameter_delimiter_under_variant, math_variant_presets[math_normal_style_variant], level_one, indirect_math_regular);
6386 tex_set_all_styles (math_parameter_h_extensible_variant, math_variant_presets[math_normal_style_variant], level_one, indirect_math_regular);
6387 tex_set_all_styles (math_parameter_v_extensible_variant, math_variant_presets[math_normal_style_variant], level_one, indirect_math_regular);
6388 tex_set_all_styles (math_parameter_fraction_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6389 tex_set_all_styles (math_parameter_radical_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6390 tex_set_all_styles (math_parameter_degree_variant, math_variant_presets[math_double_superscript_variant], level_one, indirect_math_regular);
6391 tex_set_all_styles (math_parameter_accent_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6392 tex_set_all_styles (math_parameter_top_accent_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6393 tex_set_all_styles (math_parameter_bottom_accent_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6394 tex_set_all_styles (math_parameter_overlay_accent_variant, math_variant_presets[math_cramped_style_variant], level_one, indirect_math_regular);
6395 tex_set_all_styles (math_parameter_numerator_variant, math_variant_presets[math_numerator_style_variant], level_one, indirect_math_regular);
6396 tex_set_all_styles (math_parameter_denominator_variant, math_variant_presets[math_denominator_style_variant], level_one, indirect_math_regular);
6397 tex_set_all_styles (math_parameter_superscript_variant, math_variant_presets[math_superscript_style_variant], level_one, indirect_math_regular);
6398 tex_set_all_styles (math_parameter_subscript_variant, math_variant_presets[math_subscript_style_variant], level_one, indirect_math_regular);
6399 tex_set_all_styles (math_parameter_prime_variant, math_variant_presets[math_superscript_style_variant], level_one, indirect_math_regular);
6400 tex_set_all_styles (math_parameter_stack_variant, math_variant_presets[math_numerator_style_variant], level_one, indirect_math_regular);
6401}
6402
6403
6409
6410void tex_finalize_math_parameters(void)
6411{
6412 int saved_trace = tracing_assigns_par;
6413 tracing_assigns_par = 0;
6414 if (tex_get_math_parameter(display_style, math_parameter_space_after_script, NULL) == undefined_math_parameter) {
6415 tex_def_math_parameter(display_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6416 tex_def_math_parameter(text_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6417 tex_def_math_parameter(script_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6418 tex_def_math_parameter(script_script_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6419 tex_def_math_parameter(cramped_display_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6420 tex_def_math_parameter(cramped_text_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6421 tex_def_math_parameter(cramped_script_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6422 tex_def_math_parameter(cramped_script_script_style, math_parameter_space_after_script, script_space_par, level_one, indirect_math_regular, 1);
6423 }
6424 tracing_assigns_par = saved_trace;
6425}
6426
6427static void tex_aux_math_parameter_error(int style, int param, const char *name)
6428{
6429 if (param >= 0) {
6430 tex_handle_error(
6431 normal_error_type,
6432 "Math error: parameter '%s' with id %i in style %i is not set",
6433 name, param, style,
6434 "Sorry, but I can't typeset math unless various parameters have been set. This is\n"
6435 "normally done by loading special math fonts into the math family slots. Your font\n"
6436 "set is lacking at least the parameter mentioned earlier."
6437 );
6438 } else {
6439 tex_formatted_error("math", "invalid parameter '%s' in style %i", name, style);
6440 }
6441 return;
6442}
6443
6444
6447
6448static inline scaled tex_aux_max_scale(int style, int param)
6449{
6450 scaled scale = tex_get_math_parameter(style, param, NULL);
6451 if (scale > max_math_scaling_factor) {
6452 return max_math_scaling_factor;
6453 } else if (scale < 0) {
6454 return 0;
6455 } else {
6456 return scale;
6457 }
6458}
6459
6460
6466
6467scaled tex_get_math_quad_style(int style)
6468{
6469 scaled scale = tex_aux_max_scale(style, math_parameter_x_scale);
6470 scaled value = tex_get_math_parameter(style, math_parameter_quad, NULL);
6471 if (value == undefined_math_parameter) {
6472 tex_aux_math_parameter_error(style, -1, "quad");
6473 return 0;
6474 } else {
6475 return scaledround(0.001 * value * scale);
6476 }
6477}
6478
6479
6485
6486scaled tex_get_math_axis_size(int size)
6487{
6488 scaled value;
6489 switch (size) {
6490 case script_size : size = script_style; break;
6491 case script_script_size: size = script_script_style; break;
6492 default : size = text_style; break;
6493 }
6494 value = tex_get_math_parameter(size, math_parameter_axis, NULL);
6495 if (value == undefined_math_parameter) {
6496 tex_aux_math_parameter_error(size, -1, "axis");
6497 return 0;
6498 } else {
6499 return value;
6500 }
6501}
6502
6503scaled tex_get_math_quad_size(int size)
6504{
6505 switch (size) {
6506 case script_size : size = script_style; break;
6507 case script_script_size: size = script_script_style; break;
6508 default : size = text_style; break;
6509 }
6510 return tex_get_math_parameter(size, math_parameter_quad, NULL);
6511}
6512
6513scaled tex_get_math_exheight_size(int size)
6514{
6515 switch (size) {
6516 case script_size : size = script_style; break;
6517 case script_script_size: size = script_script_style; break;
6518 default : size = text_style; break;
6519 }
6520 return tex_get_math_parameter(size, math_parameter_exheight, NULL);
6521}
6522
6523scaled tex_get_math_quad_size_scaled(int size)
6524{
6525 scaled value, scale;
6526 switch (size) {
6527 case script_size : size = script_style; break;
6528 case script_script_size: size = script_script_style; break;
6529 default : size = text_style; break;
6530 }
6531 value = tex_get_math_parameter(size, math_parameter_quad, NULL);
6532 scale = tex_aux_max_scale(size, math_parameter_x_scale);
6533
6534 return scaledround(0.001 * value * scale / 18.0);
6535}
6536
6537scaled tex_get_math_quad_size_unscaled(int size)
6538{
6539 switch (size) {
6540 case script_size : size = script_style; break;
6541 case script_script_size: size = script_script_style; break;
6542 default : size = text_style; break;
6543 }
6544 return scaledround(tex_get_math_parameter(size, math_parameter_quad, NULL) / 18.0);
6545}
6546
6547static int tex_aux_math_parameter_okay(int param)
6548{
6549 if (ignore_math_parameter(param) == 1) {
6550 if (tracing_math_par > 1) {
6551 tex_begin_diagnostic();
6552 tex_print_format("[math: parameter, name %s, ignored]", lmt_name_of_math_parameter(param));
6553 tex_end_diagnostic();
6554 }
6555 return 0;
6556 } else {
6557 return 1;
6558 }
6559}
6560
6561scaled tex_get_math_parameter_checked(int style, int param)
6562{
6563 if (tex_aux_math_parameter_okay(param)) {
6564 scaled value = tex_get_math_parameter(style, param, NULL);
6565 if (value == undefined_math_parameter) {
6566 tex_aux_math_parameter_error(style, param, lmt_name_of_math_parameter(param));
6567 return 0;
6568 } else {
6569 return value;
6570 }
6571 } else {
6572 return 0;
6573 }
6574}
6575
6576scaled tex_get_math_parameter_default(int style, int param, scaled dflt)
6577{
6578 if (tex_aux_math_parameter_okay(param)) {
6579 scaled value = tex_get_math_parameter(style, param, NULL);
6580 if (value == undefined_math_parameter) {
6581 return dflt;
6582 } else {
6583 return value;
6584 }
6585 } else {
6586 return dflt;
6587 }
6588}
6589
6590void tex_run_math_italic_correction(void) {
6591 if (cur_chr == italic_correction_code) {
6592 tex_tail_append(tex_new_kern_node(0, explicit_kern_subtype));
6593 }
6594}
6595
6596
6597
6598scaled tex_get_math_x_parameter(int style, int param)
6599{
6600 if (tex_aux_math_parameter_okay(param)) {
6601 scaled scale = tex_aux_max_scale(style, math_parameter_x_scale);
6602 scaled value = tex_get_math_parameter(style, param, NULL);
6603 if (value == undefined_math_parameter) {
6604 return value;
6605 } else {
6606 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_x_scale_par * value * scale) : 0;
6607 }
6608 } else {
6609 return 0;
6610 }
6611}
6612
6613scaled tex_get_math_x_parameter_checked(int style, int param)
6614{
6615 if (tex_aux_math_parameter_okay(param)) {
6616 scaled scale = tex_aux_max_scale(style, math_parameter_x_scale);
6617 scaled value = tex_get_math_parameter(style, param, NULL);
6618 if (value == undefined_math_parameter) {
6619 tex_aux_math_parameter_error(style, param, lmt_name_of_math_parameter(param));
6620 return 0;
6621 } else {
6622 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_x_scale_par * value * scale) : 0;
6623 }
6624 } else {
6625 return 0;
6626 }
6627}
6628
6629scaled tex_get_math_x_parameter_default(int style, int param, scaled dflt)
6630{
6631 if (tex_aux_math_parameter_okay(param)) {
6632 scaled scale = tex_aux_max_scale(style, math_parameter_x_scale);
6633 scaled value = tex_get_math_parameter(style, param, NULL);
6634 if (value == undefined_math_parameter) {
6635 return dflt;
6636 } else{
6637 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_x_scale_par * value * scale) : 0;
6638 }
6639 } else {
6640 return dflt;
6641 }
6642}
6643
6644scaled tex_get_math_y_parameter(int style, int param)
6645{
6646 if (tex_aux_math_parameter_okay(param)) {
6647 scaled scale = tex_aux_max_scale(style, math_parameter_y_scale);
6648 scaled value = tex_get_math_parameter(style, param, NULL);
6649 if (value == undefined_math_parameter) {
6650 return value;
6651 } else{
6652 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_y_scale_par * value * scale) : 0;
6653 }
6654 } else {
6655 return 0;
6656 }
6657}
6658
6659scaled tex_get_math_y_parameter_checked(int style, int param)
6660{
6661 if (tex_aux_math_parameter_okay(param)) {
6662 scaled scale = tex_aux_max_scale(style, math_parameter_y_scale);
6663 scaled value = tex_get_math_parameter(style, param, NULL);
6664 if (value == undefined_math_parameter) {
6665 tex_aux_math_parameter_error(style, param, lmt_name_of_math_parameter(param));
6666 return 0;
6667 } else {
6668 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_y_scale_par * value * scale) : 0;
6669 }
6670 } else {
6671 return 0;
6672 }
6673}
6674
6675scaled tex_get_math_y_parameter_default(int style, int param, scaled dflt)
6676{
6677 if (tex_aux_math_parameter_okay(param)) {
6678 scaled scale = tex_aux_max_scale(style, math_parameter_y_scale);
6679 scaled value = tex_get_math_parameter(style, param, NULL);
6680 if (value == undefined_math_parameter) {
6681 return dflt;
6682 } else {
6683 return value ? scaledround(0.000000001 * glyph_scale_par * glyph_y_scale_par * value * scale) : 0;
6684 }
6685 } else {
6686 return dflt;
6687 }
6688}
6689
6690scaled tex_get_font_math_parameter(int font, int size, int param)
6691{
6692 scaled scale = tex_get_math_font_scale(font, size);
6693 scaled value = tex_aux_get_font_math_parameter(scale, font, param);
6694 if (value == undefined_math_parameter) {
6695 return undefined_math_parameter;
6696 } else {
6697 return value ? scaledround(0.001 * glyph_scale_par * value) : 0;
6698 }
6699}
6700
6701
6702
6703scaled tex_get_font_math_y_parameter(int font, int size, int param)
6704{
6705 scaled scale = tex_get_math_font_scale(font, size);
6706 scaled value = tex_aux_get_font_math_parameter(scale, font, param);
6707 if (value == undefined_math_parameter) {
6708 return undefined_math_parameter;
6709 } else {
6710 return value ? scaledround(0.000001 * glyph_scale_par * glyph_y_scale_par * value) : 0;
6711 }
6712}
6713
6714scaled tex_get_font_math_x_parameter(int font, int size, int param)
6715{
6716 scaled scale = tex_get_math_font_scale(font, size);
6717 scaled value = tex_aux_get_font_math_parameter(scale, font, param);
6718 if (value == undefined_math_parameter) {
6719 return undefined_math_parameter;
6720 } else {
6721 return value ? scaledround(0.000001 * glyph_scale_par * glyph_x_scale_par * value) : 0;
6722 }
6723}
6724
6725halfword tex_to_math_spacing_parameter(halfword left, halfword right)
6726{
6727 halfword param = math_parameter_spacing_pair(left,right);
6728 return (param >= math_parameter_atom_pairs_first && param <= math_parameter_atom_pairs_last) ? param : -1;
6729}
6730
6731halfword tex_to_math_rules_parameter(halfword left, halfword right)
6732{
6733 halfword param = math_parameter_rules_pair(left,right);
6734 return (param >= math_parameter_atom_rules_first && param <= math_parameter_atom_rules_last) ? param : -1;
6735}
6736
6737void tex_set_default_math_codes(void)
6738{
6739 mathcodeval mval = tex_no_math_code();
6740
6741 mval.class_value = math_use_current_family_code;
6742
6743 for (int d = '0'; d <= '9'; d++) {
6744 mval.character_value = d;
6745 tex_set_math_code(d, mval, level_one);
6746 }
6747
6748 mval.family_value = 1;
6749 for (int u = 'A'; u <= 'Z'; u++) {
6750 mval.character_value = u;
6751 tex_set_math_code(u, mval, level_one);
6752 }
6753 for (int l = 'a'; l <= 'z'; l++) {
6754 mval.character_value = l;
6755 tex_set_math_code(l, mval, level_one);
6756 }
6757
6758 tex_set_del_code('.', (delcodeval) { { 0, 0, 0, }, { 0, 0, 0 } }, level_one);
6759}
6760
6761int tex_in_main_math_style(halfword style)
6762{
6763 switch (style) {
6764 case display_style:
6765 case text_style:
6766 return 1;
6767
6772 default:
6773 return 0;
6774 }
6775}
6776 |