diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2018-01-09 23:43:20 +0000 |
commit | aa5d0e8bf3515c424ba0594a2d4e06ae31da7796 (patch) | |
tree | e56fd10d89732547ddb207c1998a1ded4360382e /Build/source/texk/web2c/luatexdir/tex | |
parent | d33684eeca435784c95c62c7981dd02f7818b263 (diff) |
Imported Luatex 1.06.3 (Lua 5.2.4)
git-svn-id: svn://tug.org/texlive/trunk@46269 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex')
20 files changed, 857 insertions, 480 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h index fc61ffd46c8..8eabaa4e7cc 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.h +++ b/Build/source/texk/web2c/luatexdir/tex/commands.h @@ -142,6 +142,7 @@ typedef enum { boundary_cmd, /* insert boundry node with value ( \.{\\*boundary} ) */ radical_cmd, /* square root and similar signs ( \.{\\radical} ) */ super_sub_script_cmd, /* explicit super- or subscript */ + no_super_sub_script_cmd, /* explicit no super- or subscript */ math_shift_cs_cmd, /* start- and endmath */ end_cs_name_cmd, /* end control sequence ( \.{\\endcsname} ) */ char_ghost_cmd, /* \.{\\leftghost}, \.{\\rightghost} character for kerning */ @@ -259,7 +260,6 @@ typedef enum { format_name_code, /* command code for \.{\\AlephVersion} */ luatex_banner_code, /* command code for \.{\\luatexbanner}: */ luatex_revision_code, /* command code for \.{\\luatexrevision} */ - luatex_date_code, /* command code for \.{\\luatexdate} */ etex_code, /* command code for \.{\\eTeXVersion} */ eTeX_revision_code, /* command code for \.{\\eTeXrevision} */ font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */ diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.w b/Build/source/texk/web2c/luatexdir/tex/commands.w index 84235914c64..0a34b750116 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.w +++ b/Build/source/texk/web2c/luatexdir/tex/commands.w @@ -1,4 +1,4 @@ -% commands.w +f% commands.w % % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org> % @@ -52,6 +52,7 @@ void initialize_commands(void) primitive_tex("thickmuskip", assign_mu_glue_cmd, glue_base + thick_mu_skip_code, glue_base + thin_mu_skip_code); primitive_luatex("mathsurroundskip", assign_glue_cmd, glue_base + math_skip_code, glue_base); primitive_luatex("mathsurroundmode", assign_int_cmd, int_base + math_skip_mode_code, int_base); + primitive_luatex("mathscriptboxmode", assign_int_cmd, int_base + math_script_box_mode_code, int_base); primitive_tex("output", assign_toks_cmd, output_routine_loc, local_base); primitive_tex("everypar", assign_toks_cmd, every_par_loc, local_base); primitive_tex("everymath", assign_toks_cmd, every_math_loc, local_base); @@ -74,9 +75,13 @@ void initialize_commands(void) primitive_tex("displaywidowpenalty", assign_int_cmd, int_base + display_widow_penalty_code, int_base); primitive_tex("brokenpenalty", assign_int_cmd, int_base + broken_penalty_code, int_base); primitive_tex("binoppenalty", assign_int_cmd, int_base + bin_op_penalty_code, int_base); + primitive_luatex("prerelpenalty", assign_int_cmd, int_base + pre_rel_penalty_code, int_base); + primitive_luatex("prebinoppenalty", assign_int_cmd, int_base + pre_bin_op_penalty_code, int_base); primitive_tex("relpenalty", assign_int_cmd, int_base + rel_penalty_code, int_base); primitive_tex("predisplaypenalty", assign_int_cmd, int_base + pre_display_penalty_code, int_base); primitive_tex("postdisplaypenalty", assign_int_cmd, int_base + post_display_penalty_code, int_base); + primitive_luatex("mathpenaltiesmode", assign_int_cmd, int_base + math_penalties_mode_code, int_base); + primitive_luatex("mathdelimitersmode", assign_int_cmd, int_base + math_delimiters_mode_code, int_base); primitive_tex("interlinepenalty", assign_int_cmd, int_base + inter_line_penalty_code, int_base); primitive_tex("doublehyphendemerits", assign_int_cmd, int_base + double_hyphen_demerits_code, int_base); primitive_tex("finalhyphendemerits", assign_int_cmd, int_base + final_hyphen_demerits_code, int_base); @@ -160,6 +165,8 @@ void initialize_commands(void) primitive_luatex("hyphenpenaltymode", assign_int_cmd, int_base + hyphen_penalty_mode_code, int_base); primitive_luatex("automatichyphenpenalty", assign_int_cmd, int_base + automatic_hyphen_penalty_code, int_base); primitive_luatex("explicithyphenpenalty", assign_int_cmd, int_base + explicit_hyphen_penalty_code, int_base); + primitive_luatex("automatichyphenmode", assign_int_cmd, int_base + automatic_hyphen_mode_code, int_base); + primitive_luatex("breakafterdirmode", assign_int_cmd, int_base + break_after_dir_mode_code, int_base); /* Many of \TeX's primitives need no |equiv|, since they are identifiable by their |eq_type| alone. These primitives are loaded into the hash table @@ -317,7 +324,6 @@ void initialize_commands(void) primitive_tex("fontname", convert_cmd, font_name_code, 0); primitive_luatex("fontid", convert_cmd, font_id_code, 0); primitive_luatex("luatexrevision", convert_cmd, luatex_revision_code, 0); - primitive_luatex("luatexdatestamp", convert_cmd, luatex_date_code, 0); primitive_luatex("luatexbanner", convert_cmd, luatex_banner_code, 0); primitive_luatex("leftmarginkern", convert_cmd, left_margin_kern_code, 0); primitive_luatex("rightmarginkern", convert_cmd, right_margin_kern_code, 0); @@ -445,8 +451,10 @@ void initialize_commands(void) primitive_tex("unhcopy", un_hbox_cmd, copy_code, 0); primitive_tex("unvbox", un_vbox_cmd, box_code, 0); primitive_tex("unvcopy", un_vbox_cmd, copy_code, 0); - primitive_tex("-", discretionary_cmd, explicit_disc, 0); + primitive_tex("-", discretionary_cmd, explicit_disc, 0); /* good old tex */ primitive_tex("discretionary", discretionary_cmd, discretionary_disc, 0); + primitive_luatex("explicitdiscretionary", discretionary_cmd, explicit_disc, 0); + primitive_luatex("automaticdiscretionary", discretionary_cmd, automatic_disc, 0); primitive_luatex("localleftbox", assign_local_box_cmd, 0, 0); primitive_luatex("localrightbox", assign_local_box_cmd, 1, 0); @@ -479,6 +487,8 @@ void initialize_commands(void) primitive_luatex("crampedscriptscriptstyle", math_style_cmd, cramped_script_script_style, 0); primitive_luatex("Usuperscript", super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd); primitive_luatex("Usubscript", super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd); + primitive_luatex("Unosuperscript", no_super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd); + primitive_luatex("Unosubscript", no_super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd); primitive_tex("above", above_cmd, above_code, 0); primitive_tex("over", above_cmd, over_code, 0); primitive_tex("atop", above_cmd, atop_code, 0); @@ -752,6 +762,7 @@ void initialize_etex_commands(void) primitive_etex("savinghyphcodes", assign_int_cmd, int_base + saving_hyph_codes_code, int_base); primitive_luatex("suppressfontnotfounderror", assign_int_cmd, int_base + suppress_fontnotfound_error_code, int_base); primitive_luatex("suppresslongerror", assign_int_cmd, int_base + suppress_long_error_code, int_base); + primitive_luatex("suppressprimitiveerror", assign_int_cmd, int_base + suppress_primitive_error_code, int_base); primitive_luatex("suppressmathparerror", assign_int_cmd, int_base + suppress_mathpar_error_code, int_base); primitive_luatex("suppressifcsnameerror", assign_int_cmd, int_base + suppress_ifcsname_error_code, int_base); primitive_luatex("suppressoutererror", assign_int_cmd, int_base + suppress_outer_error_code, int_base); diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.w b/Build/source/texk/web2c/luatexdir/tex/conditional.w index 268786add75..318775141a8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/conditional.w +++ b/Build/source/texk/web2c/luatexdir/tex/conditional.w @@ -152,6 +152,7 @@ static boolean test_for_cs(void) halfword q; /*for traversing token lists in \.{\\ifx} tests */ halfword n = get_avail(); halfword p = n; /*head of the list of characters */ +is_in_csname += 1; while (1) { get_x_token(); if (cur_cs != 0) @@ -165,6 +166,7 @@ static boolean test_for_cs(void) get_x_token(); } while (cur_cmd != end_cs_name_cmd); flush_list(n); +is_in_csname -= 1; return b; } else { complain_missing_csname(); @@ -205,6 +207,7 @@ static boolean test_for_cs(void) b = (eq_type(cur_cs) != undefined_cs_cmd); flush_list(n); last_cs_name = cur_cs; +is_in_csname -= 1; return b; } diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w index aa0d1655d6d..9d06f1c8ed4 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.w +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.w @@ -23,7 +23,7 @@ /* we start with 907: the sum of the values of the bytes of "don knuth" */ -#define FORMAT_ID (907+28) +#define FORMAT_ID (907+37) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h index d7ca036e25a..f478b4a41b2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h @@ -291,8 +291,18 @@ the |number_regs| \.{\\dimen} registers. # define hyphen_penalty_mode_code 100 # define automatic_hyphen_penalty_code 101 # define explicit_hyphen_penalty_code 102 +# define automatic_hyphen_mode_code 103 +# define break_after_dir_mode_code 104 -# define math_option_code (explicit_hyphen_penalty_code+1) +# define pre_bin_op_penalty_code 105 +# define pre_rel_penalty_code 106 +# define math_penalties_mode_code 107 +# define math_delimiters_mode_code 108 +# define math_script_box_mode_code 109 + +# define suppress_primitive_error_code 110 + +# define math_option_code (suppress_primitive_error_code+1) # define mathoption_int_base_code (math_option_code+1) /* one reserve */ # define mathoption_int_last_code (mathoption_int_base_code+8) @@ -648,6 +658,11 @@ extern halfword last_cs_name; #define delimiter_factor_par int_par(delimiter_factor_code) #define bin_op_penalty_par int_par(bin_op_penalty_code) #define rel_penalty_par int_par(rel_penalty_code) +#define pre_bin_op_penalty_par int_par(pre_bin_op_penalty_code) +#define pre_rel_penalty_par int_par(pre_rel_penalty_code) +#define math_penalties_mode_par int_par(math_penalties_mode_code) +#define math_delimiters_mode_par int_par(math_delimiters_mode_code) +#define math_script_box_mode_par int_par(math_script_box_mode_code) #define null_delimiter_space_par dimen_par(null_delimiter_space_code) #define disable_lig_par int_par(disable_lig_code) #define disable_kern_par int_par(disable_kern_code) @@ -740,6 +755,7 @@ extern halfword last_cs_name; #define suppress_mathpar_error_par int_par(suppress_mathpar_error_code) #define suppress_fontnotfound_error_par int_par(suppress_fontnotfound_error_code) #define suppress_ifcsname_error_par int_par(suppress_ifcsname_error_code) +#define suppress_primitive_error_par int_par(suppress_primitive_error_code) #define error_context_lines_par int_par(error_context_lines_code) #define math_old_par mathoption_int_par(c_mathoption_old_code) @@ -773,6 +789,8 @@ extern halfword last_cs_name; #define hyphen_penalty_mode_par int_par(hyphen_penalty_mode_code) #define automatic_hyphen_penalty_par int_par(automatic_hyphen_penalty_code) #define explicit_hyphen_penalty_par int_par(explicit_hyphen_penalty_code) +#define automatic_hyphen_mode_par int_par(automatic_hyphen_mode_code) +#define break_after_dir_mode_par int_par(break_after_dir_mode_code) #define cur_lang_par int_par(cur_lang_code) #define cur_font_par equiv(cur_font_loc) diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.h b/Build/source/texk/web2c/luatexdir/tex/errors.h index 3eae1c8a927..39fdf6b46e2 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.h +++ b/Build/source/texk/web2c/luatexdir/tex/errors.h @@ -37,6 +37,8 @@ typedef enum { extern int interaction; /* current level of interaction */ extern int interactionoption; /* set from command line */ +extern int defaultexitcode; /* the exit code can be overloaded */ + extern void initialize_errors(void); extern char *last_error; diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.w b/Build/source/texk/web2c/luatexdir/tex/errors.w index cec9a144f1c..93dbe141b91 100644 --- a/Build/source/texk/web2c/luatexdir/tex/errors.w +++ b/Build/source/texk/web2c/luatexdir/tex/errors.w @@ -215,6 +215,8 @@ boolean use_err_help; /* should the |err_help| list be shown? */ exits the program. It is used when there is no recovery from a particular error. @c +int defaultexitcode = 0; /* the exit code can be overloaded */ + __attribute__ ((noreturn)) void do_final_end(void) { @@ -224,7 +226,7 @@ void do_final_end(void) if ((history != spotless) && (history != warning_issued)) uexit(1); else - uexit(0); + uexit(defaultexitcode); } __attribute__ ((noreturn)) diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.w b/Build/source/texk/web2c/luatexdir/tex/expand.w index 731345eb66e..c912863b2a1 100644 --- a/Build/source/texk/web2c/luatexdir/tex/expand.w +++ b/Build/source/texk/web2c/luatexdir/tex/expand.w @@ -209,7 +209,7 @@ void expand(void) iloc = p; istart = p; } - } else { + } else if (suppress_primitive_error_par == 0) { print_err("Missing primitive name"); help2 ("The control sequence marked <to be read again> does not", diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.w b/Build/source/texk/web2c/luatexdir/tex/linebreak.w index 48705ad8cad..345a1a42456 100644 --- a/Build/source/texk/web2c/luatexdir/tex/linebreak.w +++ b/Build/source/texk/web2c/luatexdir/tex/linebreak.w @@ -755,6 +755,14 @@ Replacement texts and discretionary texts are supposed to contain only character nodes, kern nodes, and box or rule nodes. @c +#define bad_node_in_disc_error(p) { \ + if (type(p) == whatsit_node) { \ + formatted_error("linebreak","invalid node with type %s and subtype %i found in discretionary",node_data[type(p)].name,subtype(p)); \ + } else { \ + formatted_error("linebreak","invalid node with type %s found in discretionary",node_data[type(p)].name); \ + } \ +} + static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, scaled * widths) { while (s != null) { @@ -783,7 +791,8 @@ static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, sc case disc_node: /* TH temp */ break; default: - confusion("invalid node found in discretionary"); /* todo: report type */ + bad_node_in_disc_error(s); + break; } } s = vlink(s); @@ -825,7 +834,7 @@ static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing, case disc_node: /* TH temp */ break; default: - confusion("invalid node found in discretionary"); /* todo: report type */ + bad_node_in_disc_error(s); break; } } @@ -1857,20 +1866,16 @@ void ext_do_line_break(int paragraph_dir, to see whether or not a breakpoint is legal at |cur_p|, as explained above. - The |precedes_break| test also considers dir nodes and prohibits - a break after an opening dir_node (positive dir). In |\textdir TRT x| - the space after |TRT| is preserved and therefore the dir node - is bound to the |x|. Being more clever makes no sense: users - should code their input properly. + We only break after certain nodes (see texnodes.h), a font related + kern and a dir node when |\breakafterdirmode=1|. */ if (auto_breaking) { halfword prev_p = alink(cur_p); if (prev_p != temp_head && ( is_char_node(prev_p) || precedes_break(prev_p) - || ( (type(prev_p) == kern_node) && ( - subtype(prev_p) == font_kern || subtype(prev_p) == accent_kern) - ) + || precedes_kern(prev_p) + || precedes_dir(prev_p) )) { ext_try_break(0, unhyphenated_node, line_break_dir, adjust_spacing, par_shape_ptr, adj_demerits, diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.h b/Build/source/texk/web2c/luatexdir/tex/mainbody.h index 158893631d7..4a5cb93a164 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.h +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.h @@ -23,7 +23,6 @@ extern int luatex_version; extern int luatex_revision; -extern int luatex_date_info; extern const char *luatex_version_string; extern const char *engine_name; @@ -218,7 +217,6 @@ is conditionally compiled in the C code. extern int get_luatexversion(void); extern str_number get_luatexrevision(void); -extern int get_luatex_date_info(void); extern int ready_already; diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.w b/Build/source/texk/web2c/luatexdir/tex/mainbody.w index faa6e1992da..4d38b9d4a47 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mainbody.w +++ b/Build/source/texk/web2c/luatexdir/tex/mainbody.w @@ -230,12 +230,6 @@ str_number get_luatexrevision(void) return luatex_revision; } -int get_luatex_date_info(void) -{ - return luatex_date_info; /* todo, silly value */ -} - - @ This is it: the part of \TeX\ that executes all those procedures we have written. @@ -524,7 +518,18 @@ void close_files_and_terminate(void) /* rubish, these pdf arguments, passed, needs to be fixed, e.g. with a dummy in dvi */ wrapup_backend(); /* Close {\sl Sync\TeX} file and write status */ - synctexterminate(log_opened_global); /* Let the {\sl Sync\TeX} controller close its files. */ + synctexterminate(log_opened_global); + /* + The following is needed because synctex removes files and we want to keep them which + means renaming a temp file .. we can't bypass the terminate because it might do mem + cleanup. + */ + if (synctex_get_mode() > 0) { + callback_id = callback_defined(finish_synctex_callback); + if (callback_id > 0) { + run_callback(callback_id, "->"); + } + } free_text_codes(); free_math_codes(); if (log_opened_global) { diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w index 0baba872e8e..7b4cf9065ca 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.w +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.w @@ -705,6 +705,7 @@ static void init_main_control (void) { non_math(sup_mark_cmd, insert_dollar_sign); non_math(sub_mark_cmd, insert_dollar_sign); non_math(super_sub_script_cmd, insert_dollar_sign); + non_math(no_super_sub_script_cmd, insert_dollar_sign); non_math(math_comp_cmd, insert_dollar_sign); non_math(delim_num_cmd, insert_dollar_sign); non_math(left_right_cmd, insert_dollar_sign); @@ -825,6 +826,7 @@ static void init_main_control (void) { jump_table[mmode + sub_mark_cmd] = sub_sup; jump_table[mmode + sup_mark_cmd] = sub_sup; jump_table[mmode + super_sub_script_cmd] = sub_sup; + jump_table[mmode + no_super_sub_script_cmd] = no_sub_sup; jump_table[mmode + left_right_cmd] = math_left_right; jump_table[mmode + math_shift_cmd] = run_math_shift; jump_table[mmode + math_shift_cs_cmd] = run_math_shift; @@ -1759,18 +1761,42 @@ void append_discretionary(void) if (cur_chr == explicit_disc) { /* \- */ c = get_pre_hyphen_char(cur_lang_par); - if (c != 0) { + if (c > 0) { vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c); alink(vlink(pre_break(tail))) = pre_break(tail); tlink(pre_break(tail)) = vlink(pre_break(tail)); } c = get_post_hyphen_char(cur_lang_par); - if (c != 0) { + if (c > 0) { vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c); alink(vlink(post_break(tail))) = post_break(tail); tlink(post_break(tail)) = vlink(post_break(tail)); } set_explicit_disc_penalty(tail); + } else if (cur_chr == automatic_disc) { + /* - as done in hyphenator */ + c = get_pre_exhyphen_char(cur_lang_par); + if (c <= 0) { + c = ex_hyphen_char_par; + } + if (c > 0) { + vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(pre_break(tail))) = pre_break(tail); + tlink(pre_break(tail)) = vlink(pre_break(tail)); + } + c = get_post_exhyphen_char(cur_lang_par); + if (c > 0) { + vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(post_break(tail))) = post_break(tail); + tlink(post_break(tail)) = vlink(post_break(tail)); + } + c = ex_hyphen_char_par; + if (c > 0) { + vlink(no_break(tail)) = new_char(equiv(cur_font_loc), c); + alink(vlink(no_break(tail))) = no_break(tail); + tlink(no_break(tail)) = vlink(no_break(tail)); + } + set_automatic_disc_penalty(tail); } else { /* \discretionary */ if (scan_keyword("penalty")) { @@ -3601,6 +3627,9 @@ void initialize(void) hang_after_par = 1; max_dead_cycles_par = 25; math_pre_display_gap_factor_par = 2000; + pre_bin_op_penalty_par = inf_penalty; + math_script_box_mode_par = 1; + pre_rel_penalty_par = inf_penalty; escape_char_par = '\\'; end_line_char_par = carriage_return; set_del_code('.', 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */ @@ -3632,7 +3661,9 @@ void initialize(void) set_eq_level(end_write, level_one); set_eq_type(end_write, outer_call_cmd); set_equiv(end_write, null); - + /* bah */ + set_pdf_major_version(1); + set_pdf_minor_version(0); } synctexoffset = int_base + synctex_code; diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.w b/Build/source/texk/web2c/luatexdir/tex/mlist.w index 7a002c2843d..291ce8c4868 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.w +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.w @@ -1348,29 +1348,30 @@ static void endless_loop_error(internal_font_number g, int y) tex_error(s, hlp); } -static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, int cur_style, boolean shift, boolean *stack, scaled *delta) +static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, int cur_style, boolean shift, boolean *stack, scaled *delta, int *same) { - pointer b; /* the box that will be constructed */ - internal_font_number f, g; /* best-so-far and tentative font codes */ - int c, i, x, y; /* best-so-far and tentative character codes */ - scaled u; /* height-plus-depth of a tentative character */ - scaled w; /* largest height-plus-depth so far */ - int z; /* runs through font family members */ - boolean large_attempt; /* are we trying the ``large'' variant? */ - pointer att; /* to save the current attribute list */ - boolean do_parts; + pointer b; /* the box that will be constructed */ + internal_font_number f, g; /* best-so-far and tentative font codes */ + int c, i, x, y; /* best-so-far and tentative character codes */ + scaled u; /* height-plus-depth of a tentative character */ + scaled w = 0; /* largest height-plus-depth so far */ + int z; /* runs through font family members */ + boolean large_attempt = false; /* are we trying the ``large'' variant? */ + pointer att = null; /* to save the current attribute list */ + int emas = 0 ; + boolean do_parts = false; extinfo *ext; - att = null; f = null_font; c = 0; - w = 0; - do_parts = false; - large_attempt = false; if (d == null) goto FOUND; z = small_fam(d); x = small_char(d); i = 0; + if (same != NULL) { + emas = *same ; + same = 0; + } while (true) { /* The search process is complicated slightly by the facts that some of the @@ -1448,6 +1449,9 @@ static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, if (stack != NULL) *stack = true ; } else { + if (same != NULL && x == c) { + *same = emas; + } b = char_box(f, c, att); if (!do_new_math(f)) { /* italic gets added to width */ @@ -1475,10 +1479,12 @@ static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, *stack = false ; } if (!flat) { - /* vertical variant */ - shift_amount(b) = half(height(b) - depth(b)); - if (shift) { - shift_amount(b) -= math_axis_size(s); + if (emas == 0 || ! delimitermodenoshift) { + /* vertical variant */ + shift_amount(b) = half(height(b) - depth(b)); + if (shift) { + shift_amount(b) -= math_axis_size(s); + } } } delete_attribute_ref(att); @@ -1605,7 +1611,7 @@ static void math_kern(pointer p, scaled m) f = f + unity; } width(p) = mu_mult(width(p)); - subtype(p) = italic_kern; + subtype(p) = italic_kern; /* this is weird, it's not a italic but explicit_kern */ } } @@ -1666,21 +1672,21 @@ static pointer clean_box(pointer p, int s, int cur_style) pointer r; /* temporary pointer */ pointer mlist = null; /* beginning of mlist to be translated */ switch (type(p)) { - case math_char_node: - mlist = new_noad(); - r = math_clone(p); - nucleus(mlist) = r; - break; - case sub_box_node: - q = math_list(p); - goto FOUND; - break; - case sub_mlist_node: - mlist = math_list(p); - break; - default: - q = new_null_box(); - goto FOUND; + case math_char_node: + mlist = new_noad(); + r = math_clone(p); + nucleus(mlist) = r; + break; + case sub_box_node: + q = math_list(p); + goto FOUND; + break; + case sub_mlist_node: + mlist = math_list(p); + break; + default: + q = new_null_box(); + goto FOUND; } mlist_to_hlist(mlist, false, s); q = vlink(temp_head); /* recursive call */ @@ -1857,7 +1863,7 @@ static void make_hextension(pointer q, int cur_style) pointer e, p; halfword w; boolean stack = false; - e = do_delimiter(q, left_delimiter(q), cur_size, radicalwidth(q), true, cur_style, true, &stack, NULL); + e = do_delimiter(q, left_delimiter(q), cur_size, radicalwidth(q), true, cur_style, true, &stack, NULL, NULL); w = width(e); if (!stack&& (radicalwidth(q) != 0) && (radicalwidth(q) != width(e))) { if (radicalmiddle(q)) { @@ -1887,7 +1893,7 @@ static void make_radical(pointer q, int cur_style) if (theta == undefined_math_parameter) { /* a real radical */ theta = fraction_rule(cur_style); - y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL); /* If |y| is a composite then set |theta| to the height of its top character, else set it to the height of |y|. @@ -1907,7 +1913,7 @@ static void make_radical(pointer q, int cur_style) } } else { /* not really a radical but we use its node, historical sharing (like in mathml) */ - y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL); } left_delimiter(q) = null; delta = (depth(y) + height(y) - theta) - (height(x) + depth(x) + clr); @@ -2034,7 +2040,7 @@ static void make_over_delimiter(pointer q, int cur_style) boolean stack; x = clean_box(nucleus(q), sub_style(cur_style), cur_style); check_widths(q,x); - y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,y,x); fixup_widths(q, x, y); @@ -2061,7 +2067,7 @@ static void make_under_delimiter(pointer q, int cur_style) boolean stack; y = clean_box(nucleus(q), sup_style(cur_style), cur_style); check_widths(q,y); - x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL); + x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,x,y); fixup_widths(q, x, y); @@ -2088,7 +2094,7 @@ static void make_delimiter_over(pointer q, int cur_style) boolean stack; y = clean_box(nucleus(q), cur_style, cur_style); check_widths(q,y); - x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL); + x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,x,y); fixup_widths(q, x, y); @@ -2115,7 +2121,7 @@ static void make_delimiter_under(pointer q, int cur_style) boolean stack; x = clean_box(nucleus(q), cur_style, cur_style); check_widths(q,x); - y = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL); + y = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; check_radical(q,stack,y,x); fixup_widths(q, x, y); @@ -2182,11 +2188,24 @@ static boolean compute_accent_skew(pointer q, int flags, scaled *s) * use the positioning of the nucleus of that noad, recursing until * the inner most |accent_noad|. This way multiple stacked accents are * aligned to the inner most one. + + the vlink test was added in version 1.06, so that we only consider a lone + noad: + + $ + \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } r } \quad + \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } r } \quad + \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } } \quad + \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } } \quad + \Umathaccent bottom 0 0 "023DF { l r } + $ + */ p = math_list(nucleus(q)); - if (type(p) == accent_noad) { + if (type(p) == accent_noad && vlink(p) == null) { s_is_absolute = compute_accent_skew(p, flags, s); } + } else { } return s_is_absolute; @@ -2423,7 +2442,7 @@ static void make_fraction(pointer q, int cur_style) if (middle_delimiter(q) != null) { delta = 0; - m = do_delimiter(q, middle_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + m = do_delimiter(q, middle_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); middle_delimiter(q) = null; } else { m = null ; @@ -2592,9 +2611,9 @@ static void make_fraction(pointer q, int cur_style) } else { delta = fraction_del_size_old(cur_style); } - l = do_delimiter(q, left_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + l = do_delimiter(q, left_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); left_delimiter(q) = null; - r = do_delimiter(q, right_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL); + r = do_delimiter(q, right_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL); right_delimiter(q) = null; couple_nodes(l,v); couple_nodes(v,r); @@ -2619,7 +2638,7 @@ the limits have been set above and below the operator. In that case, @c static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift); -static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style); +static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same); static scaled make_op(pointer q, int cur_style) { @@ -2644,7 +2663,7 @@ static scaled make_op(pointer q, int cur_style) reset_attributes(y, node_attr(q)); small_fam(y) = math_fam(nucleus(q)); small_char(y) = math_character(nucleus(q)); - x = do_delimiter(q, y, text_size, ok_size, false, cur_style, true, NULL, &delta); + x = do_delimiter(q, y, text_size, ok_size, false, cur_style, true, NULL, &delta, NULL); if (delta != 0) { if (do_new_math(cur_f)) { /* we never added italic correction */ @@ -2705,7 +2724,7 @@ static scaled make_op(pointer q, int cur_style) delta = half(delta) ; } */ - p = check_nucleus_complexity(q, &dummy, cur_style); + p = check_nucleus_complexity(q, &dummy, cur_style, NULL); if ((subscr(q) == null) && (supscr(q) == null)) { assign_new_hlist(q, p); } else { @@ -2752,7 +2771,7 @@ static scaled make_op(pointer q, int cur_style) delta = 0; } else { /* similar code then the caller (before CHECK_DIMENSIONS) */ - p = check_nucleus_complexity(q, &delta, cur_style); + p = check_nucleus_complexity(q, &delta, cur_style, NULL); if ((subscr(q) == null) && (supscr(q) == null)) { assign_new_hlist(q, p); } else { @@ -2923,6 +2942,7 @@ static void make_ord(pointer q) /* add italic correction */ if (do_new_math(cur_f) && (char_italic(cur_f,math_character(nucleus(q))) != 0)) { p = new_kern(char_italic(cur_f,math_character(nucleus(q)))); + subtype(p) = italic_kern; reset_attributes(p, node_attr(q)); couple_nodes(p,vlink(q)); couple_nodes(q,p); @@ -3082,7 +3102,8 @@ static scaled find_math_kern(internal_font_number l_f, int l_c, { scaled corr_height_top = 0, corr_height_bot = 0; scaled krn_l = 0, krn_r = 0, krn = 0; - if ((!do_new_math(l_f)) || (!do_new_math(r_f)) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) +// if ((!do_new_math(l_f)) || (!do_new_math(r_f)) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) + if ((!(do_new_math(l_f) || do_new_math(r_f))) || (!char_exists(l_f, l_c)) || (!char_exists(r_f, r_c))) return MATH_KERN_NOT_FOUND; if (cmd == sup_mark_cmd) { @@ -3203,39 +3224,91 @@ kerns assuming that is italic correction. The heuristics are unreliable for the new fonts so eventualy there will be an option to ignore such corrections. @ @c -#define analyze_script(init,su_n,su_f,su_c) do { \ - su_n = init; \ - if (su_n != null) { \ - if (type(su_n) == sub_mlist_node && math_list(su_n)) { \ - su_n = math_list(su_n); \ - if (su_n != null) { \ - while (su_n) { \ - if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) {\ - su_n = vlink(su_n); \ - } else if (type(su_n) == simple_noad) { \ - su_n = nucleus(su_n); \ - if (type(su_n) != math_char_node) { \ - su_n = null; \ - } \ - break; \ - } else { \ - su_n = null; \ - break; \ - } \ - } \ - } \ - } \ - if ((su_n != null) && (type(su_n) == math_char_node)) { \ - fetch(su_n); \ - if (char_exists(cur_f, cur_c)) { \ - su_f = cur_f; \ - su_c = cur_c; \ - } else { \ - su_n = null; \ - } \ - } \ - } \ - } while (0) +#define analyze_script(init,su_n,su_f,su_c) do { \ + su_n = init; \ + if (su_n != null) { \ + if (math_script_box_mode_par > 0 && type(su_n) == sub_mlist_node) { \ + su_n = math_list(su_n); \ + while (su_n != null) { \ + if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if (type(su_n) == simple_noad) { \ + su_n = nucleus(su_n); \ + if (type(su_n) == math_char_node) { \ + fetch(su_n); \ + if (char_exists(cur_f, cur_c)) { \ + su_f = cur_f; \ + su_c = cur_c; \ + } else { \ + su_n = null; \ + } \ + } else { \ + su_n = null; \ + } \ + break; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } else if (type(su_n) == sub_box_node) { \ + su_n = math_list(su_n); \ + if (su_n != null) { \ + if (type(su_n) == hlist_node) { \ + su_n = list_ptr(su_n); \ + } \ + if (su_n != null) { \ + if (math_script_box_mode_par == 2) { \ + while (su_n != null) { \ + if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if (type(su_n) == glyph_node) { \ + if (char_exists(font(su_n), character(su_n))) { \ + su_f = font(su_n); \ + su_c = character(su_n); \ + } else { \ + su_n = null; \ + } \ + break ; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } else if (math_script_box_mode_par == 3) { \ + int boundary = -1; \ + while (su_n != null) { \ + if ((type(su_n) == boundary_node) && (subtype(su_n) == user_boundary)) { \ + boundary = boundary_value(su_n); \ + su_n = vlink(su_n); \ + } else if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \ + su_n = vlink(su_n); \ + } else if ((boundary > -1) && (type(su_n) == glyph_node)) { \ + if (char_exists(font(su_n), character(su_n))) { \ + su_f = font(su_n); \ + su_c = character(su_n); \ + } else { \ + su_n = null; \ + } \ + break ; \ + } else { \ + su_n = null; \ + break; \ + } \ + } \ + } \ + } \ + } else { \ + su_n = null; \ + } \ + } else { \ + su_n = null; \ + } \ + } \ + } while (0) \ + +#define x_su_style(n,cur_style,su_style) \ + (noadoptionnosubscript(n) ? cur_style : su_style(cur_style)) static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift) { @@ -3265,6 +3338,7 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled if ((subscr(q) == null) && (delta1 != 0)) { /* todo: selective */ x = new_kern(delta1); /* italic correction */ + subtype(x) = italic_kern; reset_attributes(x, node_attr(nucleus(q))); couple_nodes(p,x); delta1 = 0; @@ -3296,7 +3370,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled when there is a subscript without a superscript, the top of the subscript should not exceed the baseline plus four-fifths of the x-height. */ - x = clean_box(subscr(q), sub_style(cur_style), cur_style); + /* x = clean_box(subscr(q), sub_style(cur_style), cur_style); */ + x = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style); width(x) = width(x) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3346,7 +3421,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled the bottom of a superscript should never descend below the baseline plus one-fourth of the x-height. */ - x = clean_box(supscr(q), sup_style(cur_style), cur_style); + /* x = clean_box(supscr(q), sup_style(cur_style), cur_style); */ + x = clean_box(supscr(q), (noadoptionnosupscript(q) ? cur_style : sup_style(cur_style)), cur_style); width(x) = width(x) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3401,7 +3477,8 @@ static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled both subscript and superscript move up so that the bottom of the superscript is at least as high as the baseline plus four-fifths of the x-height */ - y = clean_box(subscr(q), sub_style(cur_style), cur_style); + /* y = clean_box(subscr(q) sub_style(cur_style), cur_style); */ + y = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style); width(y) = width(y) + space_after_script(cur_style); switch (math_scripts_mode_par) { case 1: @@ -3508,23 +3585,17 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m { scaled delta; pointer tmp, lst; - scaled hd_asked = 0; scaled ic = 0; boolean stack = false; boolean axis = false; - /* - scaled hd_done = 0; - boolean fitting = true; - boolean fence = false; - int chr = 0; - int cls = 0; - */ + int same = subtype(q); + setup_cur_size(style); if ((delimiterheight(q)!=0) || (delimiterdepth(q)!=0)) { - hd_asked = delimiterheight(q) + delimiterdepth(q); - tmp = do_delimiter(q, delimiter(q), cur_size, hd_asked, false, style, false, &stack, &ic); + delta = delimiterheight(q) + delimiterdepth(q); + tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, false, &stack, &ic, &same); delimiteritalic(q) = ic; /* beware, a stacked delimiter has a shift but no corrected height/depth (yet) */ @@ -3533,19 +3604,6 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m shift_amount(tmp) = delimiterdepth(q); } - /* - hd_done = height(tmp) + depth(tmp); - fitting = stack || ((hd_done-hd_asked) == 0); - - if (type(delimiter(q)) == delim_node && (small_char(delimiter(q)) != 0)) { - chr = small_char(delimiter(q)); - cls = get_math_code(chr).class_value ; - fence = (cls == 4) || (cls == 5) ; - } - - printf("delimiter stack %i fence %i fitting %i\n",stack,fence,fitting); - */ - if (delimiterexact(q)) { delimiterheight(q) = height(tmp) - shift_amount(tmp); delimiterdepth(q) = depth(tmp) + shift_amount(tmp); @@ -3566,19 +3624,18 @@ static small_number make_left_right(pointer q, int style, scaled max_d, scaled m } else { axis = ! delimiternoaxis(q); delta = get_delimiter_height(max_d,max_h,axis); - tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, axis, &stack, &ic); + tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, axis, &stack, &ic, &same); delimiteritalic(q) = ic; } delimiter(q) = null; assign_new_hlist(q, tmp); + delimitersamesize(q) = same; /* new */ if (delimiterclass(q) >= ord_noad_type) { if (delimiterclass(q) <= inner_noad_type) { return delimiterclass(q); } else { return ord_noad_type; } - } else if (subtype(q) == no_noad_side) { - return open_noad_type; } else if (subtype(q) == left_noad_side) { return open_noad_type; } else { @@ -3797,58 +3854,67 @@ static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu) } @ @c -static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style) +static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same) { pointer p = null; + pointer t = null; + if (same != NULL) { + *same = 0; + } switch (type(nucleus(q))) { - case math_char_node: - case math_text_char_node: - fetch(nucleus(q)); - if (char_exists(cur_f, cur_c)) { - /* we could look at neighbours */ - if (do_new_math(cur_f)) { - *delta = 0 ; /* cf spec only the last one */ - } else { - *delta = char_italic(cur_f, cur_c); - } - p = new_glyph(cur_f, cur_c); - reset_attributes(p, node_attr(nucleus(q))); - if (do_new_math(cur_f)) { - if (! math_no_char_italic_par) { - /* keep italic, but bad with two successive letters */ - } else if (get_char_cat_code(cur_c) == 11) { + case math_char_node: + case math_text_char_node: + fetch(nucleus(q)); + if (char_exists(cur_f, cur_c)) { + /* we could look at neighbours */ + if (do_new_math(cur_f)) { + *delta = 0 ; /* cf spec only the last one */ + } else { + *delta = char_italic(cur_f, cur_c); + } + p = new_glyph(cur_f, cur_c); + reset_attributes(p, node_attr(nucleus(q))); + if (do_new_math(cur_f)) { + if (! math_no_char_italic_par) { + /* keep italic, but bad with two successive letters */ + } else if (get_char_cat_code(cur_c) == 11) { + /* no italic correction in mid-word of text font */ + *delta = 0; + } + } else { /* no italic correction in mid-word of text font */ - *delta = 0; + if (((type(nucleus(q))) == math_text_char_node) && (space(cur_f) != 0)) { + *delta = 0; + } } - } else { - /* no italic correction in mid-word of text font */ - if (((type(nucleus(q))) == math_text_char_node) && (space(cur_f) != 0)) { + /* so we only add italic correction when we have no scripts */ + if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) { + pointer x = new_kern(*delta); + subtype(x) = italic_kern; + reset_attributes(x, node_attr(nucleus(q))); + couple_nodes(p,x); *delta = 0; + } else /* needs checking but looks ok */ + if (do_new_math(cur_f)) { + *delta = char_italic(cur_f, cur_c); /* must be more selective */ } } - /* so we only add italic correction when we have no scripts */ - if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) { - pointer x = new_kern(*delta); - reset_attributes(x, node_attr(nucleus(q))); - couple_nodes(p,x); - *delta = 0; - } - if (do_new_math(cur_f)) { - *delta = char_italic(cur_f, cur_c); /* must be more selective */ - } - } - break; - case sub_box_node: - p = math_list(nucleus(q)); - break; - case sub_mlist_node: - mlist_to_hlist(math_list(nucleus(q)), false, cur_style); /* recursive call */ - setup_cur_size(cur_style); - p = hpack(vlink(temp_head), 0, additional, -1); - reset_attributes(p, node_attr(nucleus(q))); - break; - default: - confusion("mlist2"); /* this can't happen mlist2 */ + break; + case sub_box_node: + p = math_list(nucleus(q)); + break; + case sub_mlist_node: + t = math_list(nucleus(q)); + mlist_to_hlist(t, false, cur_style); /* recursive call */ +if (same != NULL && type(t) == fence_noad && delimitersamesize(t)) { + *same = delimitersamesize(t) ; +} + setup_cur_size(cur_style); + p = hpack(vlink(temp_head), 0, additional, -1); + reset_attributes(p, node_attr(nucleus(q))); + break; + default: + confusion("mlist2"); /* this can't happen mlist2 */ } return p; } @@ -3867,9 +3933,12 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) int t; /* the effective |type| of noad |q| during the second pass */ int t_subtype; /* the effective |subtype| of noad |q| during the second pass */ pointer p = null; + pointer pp = null; pointer z = null; halfword nxt ; + int same = 0; int pen; /* a penalty to be inserted */ + int prepen; /* a penalty to be inserted */ scaled max_hl = 0; /* maximum height of the list translated so far */ scaled max_d = 0; /* maximum depth of the list translated so far */ scaled delta; /* italic correction offset for subscript and superscript */ @@ -3877,6 +3946,10 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) r_subtype = op_noad_type_normal; setup_cur_size(cur_style); cur_mu = x_over_n(get_math_quad_size(cur_size), 18); + if (math_penalties_mode_par) { + /* we could do this via the callback but it's nice to have it as primitive too */ + penalties = 1; + } while (q != null) { /* we use the fact that no character nodes appear in an mlist, hence @@ -3891,179 +3964,180 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) delta = 0; nxt = vlink(q); switch (type(q)) { - case simple_noad: - switch (subtype(q)) { - case bin_noad_type: - switch (r_type) { - case simple_noad: - switch (r_subtype) { - case bin_noad_type: - case op_noad_type_normal: - case op_noad_type_limits: - case op_noad_type_no_limits: - case rel_noad_type: - case open_noad_type: - case punct_noad_type: - subtype(q) = ord_noad_type; - goto RESWITCH; + case simple_noad: + switch (subtype(q)) { + case bin_noad_type: + switch (r_type) { + case simple_noad: + switch (r_subtype) { + case bin_noad_type: + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + case rel_noad_type: + case open_noad_type: + case punct_noad_type: + subtype(q) = ord_noad_type; + goto RESWITCH; + break; + } + break; + case fence_noad: + if (r_subtype == left_noad_side) { + subtype(q) = ord_noad_type; /* so these can best be the same size */ + goto RESWITCH; + } break; } break; - case fence_noad: - if (r_subtype == left_noad_side) { - subtype(q) = ord_noad_type; /* so these can best be the same size */ - goto RESWITCH; + case over_noad_type: + make_over(q, cur_style, cur_size, math_rules_fam_par); + break; + case under_noad_type: + make_under(q, cur_style, cur_size, math_rules_fam_par); + break; + case vcenter_noad_type: + make_vcenter(q); + break; + case rel_noad_type: + case close_noad_type: + case punct_noad_type: + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; /* assumes the same size .. can't this go */ + subtype(r) = ord_noad_type; } break; + case op_noad_type_normal: + case op_noad_type_limits: + case op_noad_type_no_limits: + delta = make_op(q, cur_style); + if ((subtype(q) == op_noad_type_limits) || (subtype(q) == op_noad_type_no_limits)) + goto CHECK_DIMENSIONS; + break; + case ord_noad_type: + make_ord(q); + break; + case open_noad_type: + case inner_noad_type: + break; } break; - case over_noad_type: - make_over(q, cur_style, cur_size, math_rules_fam_par); - break; - case under_noad_type: - make_under(q, cur_style, cur_size, math_rules_fam_par); - break; - case vcenter_noad_type: - make_vcenter(q); - break; - case rel_noad_type: - case close_noad_type: - case punct_noad_type: - if (r_type == simple_noad && r_subtype == bin_noad_type) { - type(r) = simple_noad; /* assumes the same size .. can't this go */ - subtype(r) = ord_noad_type; + case fence_noad: + if (subtype(q) != left_noad_side) { + if (r_type == simple_noad && r_subtype == bin_noad_type) { + type(r) = simple_noad; /* assumes the same size */ + subtype(r) = ord_noad_type; + } } + goto DONE_WITH_NOAD; break; - case op_noad_type_normal: - case op_noad_type_limits: - case op_noad_type_no_limits: - delta = make_op(q, cur_style); - if ((subtype(q) == op_noad_type_limits) || (subtype(q) == op_noad_type_no_limits)) - goto CHECK_DIMENSIONS; + case fraction_noad: + make_fraction(q, cur_style); + goto CHECK_DIMENSIONS; break; - case ord_noad_type: - make_ord(q); + case radical_noad: + if (subtype(q) == 7) + make_hextension(q, cur_style); + else if (subtype(q) == 6) + make_delimiter_over(q, cur_style); + else if (subtype(q) == 5) + make_delimiter_under(q, cur_style); + else if (subtype(q) == 4) + make_over_delimiter(q, cur_style); + else if (subtype(q) == 3) + make_under_delimiter(q, cur_style); + else + make_radical(q, cur_style); break; - case open_noad_type: - case inner_noad_type: + case accent_noad: + make_math_accent(q, cur_style); break; - } - break; - case fence_noad: - if (subtype(q) != left_noad_side) - if (r_type == simple_noad && r_subtype == bin_noad_type) { - type(r) = simple_noad; /* assumes the same size */ - subtype(r) = ord_noad_type; - } - goto DONE_WITH_NOAD; - break; - case fraction_noad: - make_fraction(q, cur_style); - goto CHECK_DIMENSIONS; - break; - case radical_noad: - if (subtype(q) == 7) - make_hextension(q, cur_style); - else if (subtype(q) == 6) - make_delimiter_over(q, cur_style); - else if (subtype(q) == 5) - make_delimiter_under(q, cur_style); - else if (subtype(q) == 4) - make_over_delimiter(q, cur_style); - else if (subtype(q) == 3) - make_under_delimiter(q, cur_style); - else - make_radical(q, cur_style); - break; - case accent_noad: - make_math_accent(q, cur_style); - break; - case style_node: - cur_style = subtype(q); - setup_cur_size(cur_style); - cur_mu = x_over_n(get_math_quad_style(cur_style), 18); - goto DONE_WITH_NODE; - break; - case choice_node: - switch (cur_style / 2) { - case 0: /* |display_style=0| */ - choose_mlist(display_mlist); + case style_node: + cur_style = subtype(q); + setup_cur_size(cur_style); + cur_mu = x_over_n(get_math_quad_style(cur_style), 18); + goto DONE_WITH_NODE; break; - case 1: /* |text_style=2| */ - choose_mlist(text_mlist); + case choice_node: + switch (cur_style / 2) { + case 0: /* |display_style=0| */ + choose_mlist(display_mlist); + break; + case 1: /* |text_style=2| */ + choose_mlist(text_mlist); + break; + case 2: /* |script_style=4| */ + choose_mlist(script_mlist); + break; + case 3: /* |script_script_style=6| */ + choose_mlist(script_script_mlist); + break; + } + flush_node_list(display_mlist(q)); + flush_node_list(text_mlist(q)); + flush_node_list(script_mlist(q)); + flush_node_list(script_script_mlist(q)); + type(q) = style_node; + subtype(q) = (quarterword) cur_style; + if (p != null) { + z = vlink(q); + couple_nodes(q,p); + while (vlink(p) != null) + p = vlink(p); + try_couple_nodes(p,z); + } + goto DONE_WITH_NODE; break; - case 2: /* |script_style=4| */ - choose_mlist(script_mlist); + case ins_node: + case mark_node: + case adjust_node: + case boundary_node: + case whatsit_node: + case penalty_node: + case disc_node: + goto DONE_WITH_NODE; break; - case 3: /* |script_script_style=6| */ - choose_mlist(script_script_mlist); + case rule_node: + if (height(q) > max_hl) + max_hl = height(q); + if (depth(q) > max_d) + max_d = depth(q); + goto DONE_WITH_NODE; break; - } - flush_node_list(display_mlist(q)); - flush_node_list(text_mlist(q)); - flush_node_list(script_mlist(q)); - flush_node_list(script_script_mlist(q)); - type(q) = style_node; - subtype(q) = (quarterword) cur_style; - if (p != null) { - z = vlink(q); - couple_nodes(q,p); - while (vlink(p) != null) - p = vlink(p); - try_couple_nodes(p,z); - } - goto DONE_WITH_NODE; - break; - case ins_node: - case mark_node: - case adjust_node: - case boundary_node: - case whatsit_node: - case penalty_node: - case disc_node: - goto DONE_WITH_NODE; - break; - case rule_node: - if (height(q) > max_hl) - max_hl = height(q); - if (depth(q) > max_d) - max_d = depth(q); - goto DONE_WITH_NODE; - break; - case glue_node: - /* - conditional math glue (`\.{\\nonscript}') results in a |glue_node| - pointing to |zero_glue|, with |subtype(q)=cond_math_glue|; in such a case - the node following will be eliminated if it is a glue or kern node and if the - current size is different from |text_size| + case glue_node: + /* + conditional math glue (`\.{\\nonscript}') results in a |glue_node| + pointing to |zero_glue|, with |subtype(q)=cond_math_glue|; in such a case + the node following will be eliminated if it is a glue or kern node and if the + current size is different from |text_size| - unconditional math glue (`\.{\\muskip}') is converted to normal glue by - multiplying the dimensions by |cur_mu| + unconditional math glue (`\.{\\muskip}') is converted to normal glue by + multiplying the dimensions by |cur_mu| - */ - if (subtype(q) == mu_glue) { - math_glue_to_glue(q, cur_mu); - } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) { - p = vlink(q); - if (p != null) - if ((type(p) == glue_node) || (type(p) == kern_node)) { - if (vlink(p) != null) { - couple_nodes(q,vlink(p)); - vlink(p) = null; - } else { - vlink(q) = null; + */ + if (subtype(q) == mu_glue) { + math_glue_to_glue(q, cur_mu); + } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) { + p = vlink(q); + if (p != null) + if ((type(p) == glue_node) || (type(p) == kern_node)) { + if (vlink(p) != null) { + couple_nodes(q,vlink(p)); + vlink(p) = null; + } else { + vlink(q) = null; + } + flush_node_list(p); } - flush_node_list(p); - } - } - goto DONE_WITH_NODE; - break; - case kern_node: - math_kern(q, cur_mu); - goto DONE_WITH_NODE; - break; - default: - confusion("mlist1"); + } + goto DONE_WITH_NODE; + break; + case kern_node: + math_kern(q, cur_mu); + goto DONE_WITH_NODE; + break; + default: + confusion("mlist1"); } /* When we get to the following part of the program, we have ``fallen through'' @@ -4077,7 +4151,11 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) when both are present. */ - p = check_nucleus_complexity(q, &delta, cur_style); +same = 0 ; + p = check_nucleus_complexity(q, &delta, cur_style, &same); +if (same) { + noadextra4(q) = same ; +} if ((subscr(q) == null) && (supscr(q) == null)) { /* Adding italic correction here is kind of fuzzy because some @@ -4094,9 +4172,13 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) case open_noad_type: case close_noad_type: case punct_noad_type: - case inner_noad_type: delta = 0; break; + case inner_noad_type: + if (! delimitermodeitalics) { + delta = 0; + } + break; case op_noad_type_normal: case op_noad_type_limits: case op_noad_type_no_limits: @@ -4110,6 +4192,7 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) } if (delta != 0) { pointer d = new_kern(delta); + subtype(d) = italic_kern; reset_attributes(d, node_attr(q)); couple_nodes(p,d); } @@ -4178,15 +4261,18 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) t = simple_noad; t_subtype = ord_noad_type; pen = inf_penalty; + prepen = inf_penalty; switch (type(q)) { case simple_noad: t_subtype = subtype(q); switch (t_subtype) { case bin_noad_type: pen = bin_op_penalty_par; + prepen = pre_bin_op_penalty_par; break; case rel_noad_type: pen = rel_penalty_par; + prepen = pre_rel_penalty_par; break; case vcenter_noad_type: case over_noad_type: @@ -4233,12 +4319,24 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style) /* Append inter-element spacing based on |r_type| and |t| */ if (r_type > 0) { /* not the first noad */ + pp = p; +if (delimitermodeordinal && t_subtype == inner_noad_type && noadextra4(q) == 1) { + z = math_spacing_glue(r_subtype, ord_noad_type, cur_style, cur_mu); +} else { z = math_spacing_glue(r_subtype, t_subtype, cur_style, cur_mu); +} if (z != null) { reset_attributes(z, node_attr(p)); couple_nodes(p,z); p = z; } + if (penalties && prepen < inf_penalty && type(pp) != penalty_node) { + /* no checking of prev node type */ + z = new_penalty(prepen,noad_penalty); + reset_attributes(z, node_attr(p)); + couple_nodes(p,z); + p = z; + } } /* Append any |new_hlist| entries for |q|, and any appropriate penalties diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.w b/Build/source/texk/web2c/luatexdir/tex/printing.w index 006392810b9..72444156480 100644 --- a/Build/source/texk/web2c/luatexdir/tex/printing.w +++ b/Build/source/texk/web2c/luatexdir/tex/printing.w @@ -838,25 +838,66 @@ int font_in_short_display; /* an internal font number */ sort of ``complicated'' are indicated only by printing `\.{[]}'. @c + +/* +So, 0, 1 as well as any large value will behave the same as before. The reason +for this extension is that a \name not always makes sense. + +0 \foo xyz +1 \foo (bar) +2 <bar> xyz +3 <bar @@ ..> xyz +4 <id> +5 <id: bar> +6 <id: bar @@ ..> xyz + +*/ + void print_font_identifier(internal_font_number f) { str_number fonttext; fonttext = font_id_text(f); - if (fonttext > 0) { - print_esc(fonttext); + if (tracing_fonts_par >= 2 && tracing_fonts_par <= 6) { + /* < > is less likely to clash with text parenthesis */ + tprint("<"); + if (tracing_fonts_par >= 2 && tracing_fonts_par <= 3) { + print_font_name(f); + if (tracing_fonts_par >= 3 || font_size(f) != font_dsize(f)) { + tprint(" @@ "); + print_scaled(font_size(f)); + tprint("pt"); + } + } else if (tracing_fonts_par >= 4 && tracing_fonts_par <= 6) { + print_int(f); + if (tracing_fonts_par >= 5) { + tprint(": "); + print_font_name(f); + if (tracing_fonts_par >= 6 || font_size(f) != font_dsize(f)) { + tprint(" @@ "); + print_scaled(font_size(f)); + tprint("pt"); + } + } + } + print_char('>'); } else { - tprint_esc("FONT"); - print_int(f); - } - if (tracing_fonts_par > 0) { - tprint(" ("); - print_font_name(f); - if (font_size(f) != font_dsize(f)) { - tprint("@@"); - print_scaled(font_size(f)); - tprint("pt"); + /* old method, inherited from pdftex */ + if (fonttext > 0) { + print_esc(fonttext); + } else { + tprint_esc("FONT"); + print_int(f); + } + if (tracing_fonts_par > 0) { + tprint(" ("); + print_font_name(f); + if (font_size(f) != font_dsize(f)) { + tprint("@@"); + print_scaled(font_size(f)); + tprint("pt"); + } + print_char(')'); } - print_char(')'); } } diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.w b/Build/source/texk/web2c/luatexdir/tex/texfileio.w index 2281de12c4c..a10e9ba63d0 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texfileio.w +++ b/Build/source/texk/web2c/luatexdir/tex/texfileio.w @@ -150,9 +150,6 @@ char *luatex_find_file(const char *s, int callback_index) case find_enc_file_callback: ftemp = kpse_find_file(s, kpse_enc_format, 0); break; - case find_sfd_file_callback: - ftemp = kpse_find_file(s, kpse_sfd_format, 0); - break; case find_map_file_callback: ftemp = kpse_find_file(s, kpse_fontmap_format, 0); break; @@ -967,13 +964,13 @@ void start_input(void) update_terminal(); istate = new_line; /* Prepare new file {\sl Sync\TeX} information */ - synctexstartinput(); /* Give control to the {\sl Sync\TeX} controller */ - + if (! synctex_get_no_files()) { + synctexstartinput(); /* Give control to the {\sl Sync\TeX} controller */ + } /* Read the first line of the new file */ /* Here we have to remember to tell the |lua_input_ln| routine not to start with a |get|. If the file is empty, it is considered to contain a single blank line. */ - line = 1; if (lua_input_ln(cur_file, 0, false)) { ; diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.h b/Build/source/texk/web2c/luatexdir/tex/texmath.h index e5ad6798257..24bb34dc977 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.h +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.h @@ -70,6 +70,7 @@ extern void math_ac(void); extern pointer new_style(small_number); extern void append_choices(void); extern void sub_sup(void); +extern void no_sub_sup(void); extern void math_fraction(void); extern void math_left_right(void); extern void after_math(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.w b/Build/source/texk/web2c/luatexdir/tex/texmath.w index eeeb75bd792..6d4b87a3864 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.w +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.w @@ -1353,6 +1353,17 @@ is sufficiently large, the |cur_chr| is treated as an active character and nothing is appended. @c +#define math_class_to_type(target,source) \ + switch (source) { \ + case 0: target = ord_noad_type; break; \ + case 1: target = op_noad_type_normal; break; \ + case 2: target = bin_noad_type; break; \ + case 3: target = rel_noad_type; break; \ + case 4: target = open_noad_type; break; \ + case 5: target = close_noad_type; break; \ + case 6: target = punct_noad_type; break; \ + } + void set_math_char(mathcodeval mval) { pointer p; /* the new noad */ @@ -1375,17 +1386,7 @@ void set_math_char(mathcodeval mval) math_fam(nucleus(p)) = cur_fam_par; subtype(p) = ord_noad_type; } else { - switch (mval.class_value) { - /* *INDENT-OFF* */ - case 0: subtype(p) = ord_noad_type; break; - case 1: subtype(p) = op_noad_type_normal; break; - case 2: subtype(p) = bin_noad_type; break; - case 3: subtype(p) = rel_noad_type; break; - case 4: subtype(p) = open_noad_type; break; - case 5: subtype(p) = close_noad_type; break; - case 6: subtype(p) = punct_noad_type; break; - /* *INDENT-ON* */ - } + math_class_to_type(subtype(p),mval.class_value); } vlink(tail) = p; tail = p; @@ -1727,7 +1728,7 @@ void build_choices(void) action procedure called |sub_sup|. @c -void sub_sup(void) +static void do_sub_sup(int no) { pointer q; if (tail == head || (!scripts_allowed(tail))) { @@ -1745,6 +1746,9 @@ void sub_sup(void) nucleus(tail) = q; tex_error("Double superscript", hlp); } + if (no) { + noadoptions(tail) = noadoptions(tail) | noad_option_no_super_script ; + } q = new_node(math_char_node, 0); supscr(tail) = q; (void) scan_math(supscr(tail), sup_style(m_style)); @@ -1758,12 +1762,26 @@ void sub_sup(void) nucleus(tail) = q; tex_error("Double subscript", hlp); } + if (no) { + noadoptions(tail) = noadoptions(tail) | noad_option_no_sub_script ; + } q = new_node(math_char_node, 0); subscr(tail) = q; (void) scan_math(subscr(tail), sub_style(m_style)); } } +void sub_sup(void) +{ + do_sub_sup(0); +} + +void no_sub_sup(void) +{ + do_sub_sup(1); +} + + @ An operation like `\.{\\over}' causes the current mlist to go into a state of suspended animation: |incompleat_noad| points to a |fraction_noad| that contains the mlist-so-far as its numerator, while the denominator @@ -1991,7 +2009,7 @@ void math_left_right(void) options = options | noad_option_exact ; } else if (scan_keyword("class")) { scan_int(); - type = cur_val ; + math_class_to_type(type,cur_val); } else { break; } @@ -2029,9 +2047,9 @@ void math_left_right(void) delimiteroptions(p) = options; delimiterclass(p) = type; delimiteritalic(p) = 0; + delimitersamesize(p) = 0; scan_delimiter(delimiter(p), no_mathcode); - if (t == no_noad_side) { tail_append(new_noad()); subtype(tail) = inner_noad_type; @@ -2133,36 +2151,41 @@ At this time we are in vertical mode (or internal vertical mode). @c #define inject_display_skip_before(g) \ - switch (display_skip_mode_par) { \ - case 0 : /* normal tex */ \ - tail_append(new_param_glue(g)); \ - break;\ - case 1 : /* always */ \ - tail_append(new_param_glue(g)); \ - break; \ - case 2 : /* non-zero */ \ - if (g != 0 && ! glue_is_zero(glue_par(g))) \ + if (g > 0) { \ + switch (display_skip_mode_par) { \ + case 0 : /* normal tex | always */ \ + case 1 : /* always */ \ + tail_append(new_param_glue(g)); \ + break; \ + case 2 : /* non-zero */ \ + if (! glue_is_zero(glue_par(g))) \ + tail_append(new_param_glue(g)); \ + break; \ + case 3: /* ignore */ \ + break; \ + default: /* > 3 reserved for future use */ \ tail_append(new_param_glue(g)); \ - break; \ - case 3: /* ignore */ \ - break; \ + break; \ + } \ } #define inject_display_skip_after(g) \ - switch (display_skip_mode_par) { \ - case 0 : /* normal tex */ \ - if (g != 0 && glue_is_positive(glue_par(g))) \ + if (g > 0) { \ + switch (display_skip_mode_par) { \ + case 0 : /* normal tex | always */ \ + case 1 : /* always */ \ tail_append(new_param_glue(g)); \ - break; \ - case 1 : /* always */ \ - tail_append(new_param_glue(g)); \ - break; \ - case 2 : /* non-zero */ \ - if (g != 0 && ! glue_is_zero(glue_par(g))) \ + break; \ + case 2 : /* non-zero */ \ + if (! glue_is_zero(glue_par(g))) \ + tail_append(new_param_glue(g)); \ + break; \ + case 3: /* ignore */ \ + break; \ + default: /* > 3 reserved for future use */ \ tail_append(new_param_glue(g)); \ - break; \ - case 3: /* ignore */ \ - break; \ + break; \ + } \ } static void finish_displayed_math(boolean l, pointer eqno_box, pointer p) diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index b838dd0a2f9..2bdd432e570 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -23,19 +23,6 @@ #ifndef __NODES_H__ # define __NODES_H__ -/* these are in texlang.c */ - -# define set_vlink(a,b) vlink(a)=b -# define get_vlink(a) vlink(a) -# define get_character(a) character(a) - -extern halfword insert_discretionary(halfword t, halfword pre, halfword post, halfword replace, int penalty); -extern halfword insert_syllable_discretionary(halfword t, lang_variables * lan); -extern halfword insert_word_discretionary(halfword t, lang_variables * lan); -extern halfword insert_complex_discretionary(halfword t, lang_variables * lan, halfword pre, halfword post, halfword replace); -extern halfword insert_character(halfword t, int n); -extern void set_disc_field(halfword f, halfword t); - # define varmemcast(a) (memory_word *)(a) extern memory_word *volatile varmem; @@ -297,15 +284,17 @@ typedef enum { # define adjust_pre subtype # define adjust_ptr(a) vlink(a+2) -# define glyph_node_size 6 -# define character(a) vinfo((a)+2) -# define font(a) vlink((a)+2) -# define lang_data(a) vinfo((a)+3) -# define lig_ptr(a) vlink((a)+3) -# define x_displace(a) vinfo((a)+4) -# define y_displace(a) vlink((a)+4) -# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */ -# define x_advance(a) vlink((a)+5) +# define glyph_node_size 7 +# define character(a) vinfo((a)+2) +# define font(a) vlink((a)+2) +# define lang_data(a) vinfo((a)+3) +# define lig_ptr(a) vlink((a)+3) +# define x_displace(a) vinfo((a)+4) +# define y_displace(a) vlink((a)+4) +# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */ +# define x_advance(a) vlink((a)+5) /* obsolete, can become user field */ +# define synctex_tag_glyph(a) vinfo((a)+6) +# define synctex_line_glyph(a) vlink((a)+6) # define is_char_node(a) (a!=null && type(a)==glyph_node) @@ -432,6 +421,8 @@ typedef enum { */ # define precedes_break(a) (type(a)<=last_preceding_break_node) +# define precedes_kern(a) ((type(a) == kern_node) && (subtype(a) == font_kern || subtype(a) == accent_kern)) +# define precedes_dir(a) ((type(a) == dir_node) && (break_after_dir_mode_par == 1)) # define non_discardable(a) (type(a)<=last_non_discardable_node) # define known_node_type(i) ( i >= 0 && i <= MAX_NODE_TYPE) @@ -492,9 +483,9 @@ typedef enum { # define noadheight(a) vlink((a)+5) # define noaddepth(a) vinfo((a)+5) # define noadextra1(a) vlink((a)+6) /* we need to match delimiter (saves copy) */ -# define noadextra2(a) vinfo((a)+6) +# define noadoptions(a) vinfo((a)+6) # define noadextra3(a) vlink((a)+7) /* see (!) below */ -# define noadextra4(a) vinfo((a)+7) +# define noadextra4(a) vinfo((a)+7) /* used to store samesize */ /* accent noads */ @@ -506,28 +497,31 @@ typedef enum { /* left and right noads */ -# define fence_noad_size 8 /* needs to match noad size */ -# define delimiteritalic(a) vlink((a)+4) -/* define delimiterwidth(a) vinfo((a)+4) */ -# define delimiterheight(a) vlink((a)+5) -# define delimiterdepth(a) vinfo((a)+5) -# define delimiter(a) vlink((a)+6) /* |delimiter| field in left and right noads */ -# define delimiteroptions(a) vinfo((a)+6) -# define delimiterclass(a) vlink((a)+7) /* (!) we could probably pack some more in 6 */ -# define delimiterextra1(a) vinfo((a)+7) /* not used */ +# define fence_noad_size 8 /* needs to match noad size */ +# define delimiteritalic(a) vlink((a)+4) +/* define delimiterwidth(a) vinfo((a)+4) */ +# define delimiterheight(a) vlink((a)+5) +# define delimiterdepth(a) vinfo((a)+5) +# define delimiter(a) vlink((a)+6) /* |delimiter| field in left and right noads */ +# define delimiteroptions(a) vinfo((a)+6) +# define delimiterclass(a) vlink((a)+7) /* (!) we could probably pack some more in 6 */ +# define delimitersamesize(a) vinfo((a)+7) /* set by engine */ /* when dimensions then axis else noaxis */ typedef enum { - noad_option_set = 0x08, - noad_option_unused_1 = 0x00 + 0x08, - noad_option_unused_2 = 0x01 + 0x08, - noad_option_axis = 0x02 + 0x08, - noad_option_no_axis = 0x04 + 0x08, - noad_option_exact = 0x10 + 0x08, - noad_option_left = 0x11 + 0x08, - noad_option_middle = 0x12 + 0x08, - noad_option_right = 0x14 + 0x08, + noad_option_set = 0x08, + noad_option_unused_1 = 0x00 + 0x08, + noad_option_unused_2 = 0x01 + 0x08, + noad_option_axis = 0x02 + 0x08, + noad_option_no_axis = 0x04 + 0x08, + noad_option_exact = 0x10 + 0x08, + noad_option_left = 0x11 + 0x08, + noad_option_middle = 0x12 + 0x08, + noad_option_right = 0x14 + 0x08, + noad_option_no_sub_script = 0x21 + 0x08, + noad_option_no_super_script = 0x22 + 0x08, + noad_option_no_script = 0x23 + 0x08, } delimiter_options ; # define delimiteroptionset(a) ((delimiteroptions(a) & noad_option_set ) == noad_option_set ) @@ -535,6 +529,23 @@ typedef enum { # define delimiternoaxis(a) ((delimiteroptions(a) & noad_option_no_axis) == noad_option_no_axis) # define delimiterexact(a) ((delimiteroptions(a) & noad_option_exact ) == noad_option_exact ) +# define noadoptionnosubscript(a) ( (type(a) == simple_noad) && ( \ + ((delimiteroptions(a) & noad_option_no_sub_script ) == noad_option_no_sub_script) || \ + ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) )) +# define noadoptionnosupscript(a) ( (type(a) == simple_noad) && ( \ + ((delimiteroptions(a) & noad_option_no_super_script) == noad_option_no_super_script) || \ + ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) )) + +typedef enum { + noad_delimiter_mode_noshift = 0x01, + noad_delimiter_mode_italics = 0x02, + noad_delimiter_mode_ordinal = 0x04, +} delimiter_modes ; + +# define delimitermodenoshift ((math_delimiters_mode_par & noad_delimiter_mode_noshift) == noad_delimiter_mode_noshift) +# define delimitermodeitalics ((math_delimiters_mode_par & noad_delimiter_mode_italics) == noad_delimiter_mode_italics) +# define delimitermodeordinal ((math_delimiters_mode_par & noad_delimiter_mode_ordinal) == noad_delimiter_mode_ordinal) + /* subtype of fence noads */ # define left_noad_side 1 @@ -928,7 +939,7 @@ extern halfword do_copy_node_list(halfword, halfword); extern halfword copy_node_list(halfword); extern halfword copy_node(const halfword); extern void check_node(halfword); -extern void fix_node_list(halfword); +extern halfword fix_node_list(halfword); extern int fix_node_lists; extern char *sprint_node_mem_usage(void); extern halfword raw_glyph_node(void); @@ -1013,5 +1024,16 @@ extern int lua_properties_use_metatable ; extern halfword make_local_par_node(int mode); +extern void synctex_set_mode(int mode); +extern int synctex_get_mode(void); +extern void synctex_set_tag(int tag); +extern void synctex_set_line(int line); +extern void synctex_force_tag(int tag); +extern void synctex_force_line(int tag); +extern int synctex_get_tag(void); +extern void synctex_set_no_files(int flag); +extern int synctex_get_no_files(void); +extern int synctex_get_line(void); + #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.w b/Build/source/texk/web2c/luatexdir/tex/texnodes.w index 7967006ec35..d0008b08fc8 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.w +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.w @@ -656,11 +656,14 @@ static int test_count = 1; #define check_action_ref(a) { dorangetest(p,a,var_mem_max); } #define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); } -#define check_token_ref(a) { \ + +/* hm, we can just pass p then */ + +#define check_token_ref(p) { \ if (type(p) == whatsit_node) { \ - formatted_error("nodes","fuzzy token cleanup in whatsit node with id %i and subtype %i",type(p),subtype(p)); \ + formatted_error("nodes","fuzzy token cleanup in whatsit node with type %s and subtype %i",node_data[type(p)].name,subtype(p)); \ } else { \ - formatted_error("nodes","fuzzy token cleanup in node with id %i",type(p)); \ + formatted_error("nodes","fuzzy token cleanup in node with type %s",node_data[type(p)].name); \ } \ } @@ -828,6 +831,67 @@ static int copy_error(halfword p) } @ @c +static halfword synctex_anyway_mode = 0; /* 2 also glyphs */ +static halfword synctex_line_field = 0; +static halfword synctex_no_files = 0; + +void synctex_set_mode(int m) +{ + synctex_anyway_mode = m; +}; + +int synctex_get_mode(void) +{ + return synctex_anyway_mode; +}; + +void synctex_set_no_files(int f) +{ + synctex_no_files = f; +}; + +int synctex_get_no_files(void) +{ + return (int) synctex_no_files ; +}; + +void synctex_set_tag(int t) +{ + cur_input.synctex_tag_field = t; +}; + +int synctex_get_tag(void) +{ + return (int) cur_input.synctex_tag_field; +}; + + +int synctex_get_line(void) +{ + return (int) synctex_line_field; +}; + +static int forced_tag = 0; +static int forced_line = 0; + +void synctex_force_tag(int t) +{ + forced_tag = t; +}; + +void synctex_force_line(int t) +{ + forced_line = t; +}; + +void synctex_set_line(int l) +{ + synctex_line_field = l; +}; + +@ @c +/* if_stack is called a lot so maybe optimize */ + halfword new_node(int i, int j) { int s = get_node_size(i, j); @@ -892,13 +956,54 @@ halfword new_node(int i, int j) default: break; } - if (synctex_par) { - /* handle synctex extension */ + if (synctex_anyway_mode) { switch (i) { - case math_node: - synctex_tag_math(n) = cur_input.synctex_tag_field; - synctex_line_math(n) = line; + /* 1 = all but glyphs */ + /* 2 = also glyphs */ + /* 3 = glyphs and glue */ + /* 4 = only glyphs */ + case glyph_node: + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case glue_node: + if (synctex_anyway_mode < 4) { + synctex_tag_glue(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glue(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case kern_node: + if (synctex_anyway_mode < 3) { + synctex_tag_kern(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_kern(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case hlist_node: + case vlist_node: + case unset_node: /* useless */ + if (synctex_anyway_mode < 3) { + synctex_tag_box(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_box(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + case rule_node: + if (synctex_anyway_mode < 3) { + synctex_tag_rule(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_rule(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } break; + case math_node: /* noads probably make more sense */ + if (synctex_anyway_mode < 3) { + synctex_tag_math(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_math(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + break; + } + } else if (synctex_par) { + /* handle synctex extension */ + switch (i) { case glue_node: synctex_tag_glue(n) = cur_input.synctex_tag_field; synctex_line_glue(n) = line; @@ -919,6 +1024,10 @@ halfword new_node(int i, int j) synctex_tag_rule(n) = cur_input.synctex_tag_field; synctex_line_rule(n) = line; break; + case math_node: + synctex_tag_math(n) = cur_input.synctex_tag_field; + synctex_line_math(n) = line; + break; } } /* take care of attributes */ @@ -935,6 +1044,10 @@ halfword raw_glyph_node(void) { register halfword n = get_node(glyph_node_size); (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } type(n) = glyph_node; subtype(n) = 0; return n; @@ -944,6 +1057,10 @@ halfword new_glyph_node(void) { register halfword n = get_node(glyph_node_size); (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1))); + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } type(n) = glyph_node; subtype(n) = 0; build_attribute_list(n); @@ -1102,7 +1219,16 @@ halfword copy_node(const halfword p) } */ - if (synctex_par) { + if (synctex_anyway_mode) { + /* + if (t == glyph_node) { + if (synctex_anyway_mode > 1) { + synctex_tag_glyph(r) = forced_tag ? forced_tag : cur_input.synctex_tag_field; + synctex_line_glyph(r) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line; + } + } + */ + } else if (synctex_par) { /* handle synctex extension */ switch (t) { case math_node: @@ -1520,7 +1646,7 @@ static void check_node_wrapup_core(halfword p) switch (subtype(p)) { /* frontend code */ case special_node: - check_token_ref(write_tokens(p)); + check_token_ref(p); break; case user_defined_node: switch (user_node_type(p)) { @@ -1528,7 +1654,7 @@ static void check_node_wrapup_core(halfword p) check_attribute_ref(user_node_value(p)); break; case 't': - check_token_ref(user_node_value(p)); + check_token_ref(p); break; case 'n': dorangetest(p, user_node_value(p), var_mem_max); @@ -1558,39 +1684,39 @@ void check_node_wrapup_pdf(halfword p) switch (subtype(p)) { case pdf_literal_node: if (pdf_literal_type(p) == normal) - check_token_ref(pdf_literal_data(p)); + check_token_ref(p); break; case pdf_colorstack_node: if (pdf_colorstack_cmd(p) <= colorstack_data) - check_token_ref(pdf_colorstack_data(p)); + check_token_ref(p); break; case pdf_setmatrix_node: - check_token_ref(pdf_setmatrix_data(p)); + check_token_ref(p); break; case late_lua_node: if (late_lua_name(p) > 0) - check_token_ref(late_lua_name(p)); + check_token_ref(p); if (late_lua_type(p) == normal) - check_token_ref(late_lua_data(p)); + check_token_ref(p); break; case pdf_annot_node: - check_token_ref(pdf_annot_data(p)); + check_token_ref(p); break; case pdf_start_link_node: if (pdf_link_attr(p) != null) - check_token_ref(pdf_link_attr(p)); + check_token_ref(p); check_action_ref(pdf_link_action(p)); break; case pdf_dest_node: if (pdf_dest_named_id(p) > 0) - check_token_ref(pdf_dest_id(p)); + check_token_ref(p); break; case pdf_thread_node: case pdf_start_thread_node: if (pdf_thread_named_id(p) > 0) - check_token_ref(pdf_thread_id(p)); + check_token_ref(p); if (pdf_thread_attr(p) != null) - check_token_ref(pdf_thread_attr(p)); + check_token_ref(p); break; case pdf_save_node: case pdf_restore_node: @@ -1718,18 +1844,19 @@ void check_node(halfword p) } @ @c -void fix_node_list(halfword head) +halfword fix_node_list(halfword head) { - halfword p, q; + halfword next, tail; if (head == null) - return; - p = head; - q = vlink(p); - while (q != null) { - alink(q) = p; - p = q; - q = vlink(p); + return null; + tail = head; + next = vlink(head); + while (next != null) { + alink(next) = tail; + tail = next; + next = vlink(tail); } + return tail; } @ @c diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.w b/Build/source/texk/web2c/luatexdir/tex/textoken.w index f0b6a0c6e75..bf14a96148e 100644 --- a/Build/source/texk/web2c/luatexdir/tex/textoken.w +++ b/Build/source/texk/web2c/luatexdir/tex/textoken.w @@ -2311,6 +2311,7 @@ static int do_variable_pdf(halfword c) else if (scan_keyword("imageresolution")) { do_variable_backend_int(c_pdf_image_resolution); } else if (scan_keyword("pkresolution")) { do_variable_backend_int(c_pdf_pk_resolution); } else if (scan_keyword("uniqueresname")) { do_variable_backend_int(c_pdf_unique_resname); } + else if (scan_keyword("majorversion")) { do_variable_backend_int(c_pdf_major_version); } else if (scan_keyword("minorversion")) { do_variable_backend_int(c_pdf_minor_version); } else if (scan_keyword("pagebox")) { do_variable_backend_int(c_pdf_pagebox); } else if (scan_keyword("inclusionerrorlevel")) { do_variable_backend_int(c_pdf_inclusion_errorlevel); } @@ -2775,11 +2776,6 @@ void conv_toks(void) print(get_luatexrevision()); pop_selector; break; - case luatex_date_code: - push_selector; - print_int(get_luatex_date_info()); - pop_selector; - break; case etex_code: push_selector; tprint(eTeX_version_string); @@ -3008,9 +3004,6 @@ str_number the_convert_string(halfword c, int i) case luatex_revision_code: print(get_luatexrevision()); break; - case luatex_date_code: - print_int(get_luatex_date_info()); - break; case etex_code: tprint(eTeX_version_string); break; |