diff options
author | Luigi Scarso <luigi.scarso@gmail.com> | 2023-02-17 23:30:17 +0000 |
---|---|---|
committer | Luigi Scarso <luigi.scarso@gmail.com> | 2023-02-17 23:30:17 +0000 |
commit | 40f7db304a155502cef39ce83478a33907e97030 (patch) | |
tree | c6fd1beabff67716c5bc08204ed3877608d236c2 /Build/source/texk/web2c/luatexdir/tex | |
parent | 35c8bd5c065403e14361f540d6633de184ea2c89 (diff) |
new "late special" feature by Phelype Oleinik,heavily adapted by H.Hagen.
git-svn-id: svn://tug.org/texlive/trunk@65866 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/backend.c | 5 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/commands.c | 3 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/commands.h | 3 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/extensions.c | 105 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/extensions.h | 3 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/maincontrol.c | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/texnodes.c | 18 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/texnodes.h | 27 |
8 files changed, 115 insertions, 51 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/backend.c b/Build/source/texk/web2c/luatexdir/tex/backend.c index 3115a88a7e3..fff6cd047f1 100644 --- a/Build/source/texk/web2c/luatexdir/tex/backend.c +++ b/Build/source/texk/web2c/luatexdir/tex/backend.c @@ -32,7 +32,10 @@ static void init_pdf_backend_functions(void) p->node_fu[rule_node] = &pdf_place_rule; p->node_fu[glyph_node] = &pdf_place_glyph; p->whatsit_fu[special_node] = &pdf_special; + p->whatsit_fu[late_special_node] = &pdf_special; + p->whatsit_fu[late_lua_node] = &late_lua; p->whatsit_fu[pdf_literal_node] = &pdf_out_literal; + p->whatsit_fu[pdf_late_literal_node] = &pdf_out_literal; p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj; p->whatsit_fu[pdf_annot_node] = &do_annot; p->whatsit_fu[pdf_start_link_node] = &do_link; @@ -40,7 +43,6 @@ static void init_pdf_backend_functions(void) p->whatsit_fu[pdf_dest_node] = &do_dest; p->whatsit_fu[pdf_thread_node] = &do_thread; p->whatsit_fu[pdf_end_thread_node] = &end_thread; - p->whatsit_fu[late_lua_node] = &late_lua; p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack; p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix; p->whatsit_fu[pdf_save_node] = &pdf_out_save; @@ -63,6 +65,7 @@ static void init_dvi_backend_functions(void) p->node_fu[rule_node] = &dvi_place_rule; p->node_fu[glyph_node] = &dvi_place_glyph; p->whatsit_fu[special_node] = &dvi_special; + p->whatsit_fu[late_special_node] = &dvi_special; p->whatsit_fu[late_lua_node] = &late_lua; p->control_fu[backend_control_push_list] = &dvi_push_list; p->control_fu[backend_control_pop_list] = &dvi_pop_list; diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.c b/Build/source/texk/web2c/luatexdir/tex/commands.c index b502cf287fe..1c768cb174b 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.c +++ b/Build/source/texk/web2c/luatexdir/tex/commands.c @@ -714,7 +714,8 @@ void initialize_commands(void) primitive_tex("special", extension_cmd, special_code, 0); cs_text(frozen_special) = maketexstring("special"); eqtb[frozen_special] = eqtb[cur_val]; - primitive_tex("immediate", extension_cmd, immediate_code, 0); + primitive_tex("immediate", extension_cmd, reserved_immediate_code, 0); + primitive_tex("deferred", extension_cmd, reserved_deferred_code, 0); primitive_luatex("localinterlinepenalty", assign_int_cmd, int_base + local_inter_line_penalty_code, int_base); primitive_luatex("localbrokenpenalty", assign_int_cmd, int_base + local_broken_penalty_code, int_base); primitive_luatex("pagedir", assign_dir_cmd, int_base + page_direction_code, dir_base); diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h index 9ae92c0e6f0..7a08bf65390 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.h +++ b/Build/source/texk/web2c/luatexdir/tex/commands.h @@ -352,7 +352,8 @@ typedef enum { gp_code_base = 7 } font_codes ; -# define immediate_code 4 /* command modifier for \.{\\immediate} */ +# define immediate_code 4 /* reserved_immediate_code */ /* command modifier for \.{\\immediate} */ +# define deferred_code 5 /* reserved_deferred_code */ /* command modifier for \.{\\deferred} */ extern void initialize_commands(void); extern void initialize_etex_commands(void); diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.c b/Build/source/texk/web2c/luatexdir/tex/extensions.c index aa7538acf43..5d763ac8c46 100644 --- a/Build/source/texk/web2c/luatexdir/tex/extensions.c +++ b/Build/source/texk/web2c/luatexdir/tex/extensions.c @@ -116,38 +116,60 @@ int last_saved_image_pages ; int last_saved_box_index ; scaledpos last_position = { 0, 0 }; -static void do_extension_dvi(int immediate) +static void do_extension_dvi_literal(int deferred) +{ + new_whatsit(deferred ? late_special_node : special_node); + write_stream(tail) = null; + scan_toks(false, ! deferred); + write_tokens(tail) = def_ref; +} + +static void do_extension_dvi(int immediate, int deferred) { if (scan_keyword("literal")) { - new_whatsit(special_node); - write_stream(tail) = null; - scan_toks(false, true); - write_tokens(tail) = def_ref; + /* immediate is the default here */ + if (scan_keyword("shipout")) { + deferred = 1; + } + do_extension_dvi_literal(deferred); + } else if (scan_keyword("lateliteral")) { + do_extension_dvi_literal(1); } else { tex_error("unexpected use of \\dviextension",null); } } -static void do_extension_pdf(int immediate) +static void do_extension_pdf_literal(int deferred) +{ + new_whatsit(deferred ? pdf_late_literal_node : pdf_literal_node); + if (scan_keyword("direct")) + set_pdf_literal_mode(tail, direct_always); + else if (scan_keyword("page")) + set_pdf_literal_mode(tail, direct_page); + else if (scan_keyword("text")) + set_pdf_literal_mode(tail, direct_text); + else if (scan_keyword("raw")) + set_pdf_literal_mode(tail, direct_raw); + else if (scan_keyword("origin")) + set_pdf_literal_mode(tail, set_origin); + else + set_pdf_literal_mode(tail, set_origin); + scan_toks(false, ! deferred); + set_pdf_literal_type(tail, normal); + set_pdf_literal_data(tail, def_ref); +} + +static void do_extension_pdf(int immediate, int deferred) { int i; if (scan_keyword("literal")) { - new_whatsit(pdf_literal_node); - if (scan_keyword("direct")) - set_pdf_literal_mode(tail, direct_always); - else if (scan_keyword("page")) - set_pdf_literal_mode(tail, direct_page); - else if (scan_keyword("text")) - set_pdf_literal_mode(tail, direct_text); - else if (scan_keyword("raw")) - set_pdf_literal_mode(tail, direct_raw); - else if (scan_keyword("origin")) - set_pdf_literal_mode(tail, set_origin); - else - set_pdf_literal_mode(tail, set_origin); - scan_toks(false, true); - set_pdf_literal_type(tail, normal); - set_pdf_literal_data(tail, def_ref); + /* immediate is the default here */ + if (scan_keyword("shipout")) { + deferred = 1; + } + do_extension_pdf_literal(deferred); + } else if (scan_keyword("lateliteral")) { + do_extension_pdf_literal(1); } else if (scan_keyword("dest")) { scan_pdfdest(static_pdf); } else if (scan_keyword("annot")) { @@ -341,7 +363,7 @@ static void do_resource_pdf(int immediate, int code) The extensions are backend related. The next subroutine uses |cur_chr| to decide what sort of whatsit is involved, and also inserts a |write_stream| - number. + number. */ @@ -363,10 +385,17 @@ static void new_write_whatsit(int w, int check) write_stream(tail) = cur_val; } -void do_extension(int immediate) +/* + Specials and literals are immediate by default but can be deferred as well. We have two prefixes that + don't accumulate but trigger a next token pickup. Writes and resources are deferred by default. The + (wish for a) shipout key scanner comes from similar features in the other engines. So, we're + compatible but also conceptually a bit more consistent by introducing a |\deferred| prefix. +*/ + +void do_extension(int immediate, int deferred) { /*tex All-purpose pointers. */ - halfword k,p; + halfword k, p; if (cur_cmd == extension_cmd) { /*tex These have their own range starting at 0. */ switch (cur_chr) { @@ -431,17 +460,25 @@ void do_extension(int immediate) /*tex When `\.{\\special\{...\}}' appears, we expand the macros in - the token list as in \.{\\xdef} and \.{\\mark}. + the token list as in \.{\\xdef} and \.{\\mark}. When marked with \.{shipout}, we keep + tokens unexpanded for now. */ - new_whatsit(special_node); + if (scan_keyword("shipout")) { + deferred = 1; + } + new_whatsit(deferred ? late_special_node : special_node); write_stream(tail) = null; - p = scan_toks(false, true); + p = scan_toks(false, ! deferred); write_tokens(tail) = def_ref; break; - case immediate_code: + case reserved_immediate_code: + get_x_token(); + do_extension(1, 0); + break; + case reserved_deferred_code: get_x_token(); - do_extension(1); + do_extension(0, 1); break; case end_local_code: if (tracing_nesting_par > 2) { @@ -467,11 +504,11 @@ void do_extension(int immediate) /*tex Backend extensions have their own range starting at 32. */ case dvi_extension_code: if (get_o_mode() == OMODE_DVI) - do_extension_dvi(immediate); + do_extension_dvi(immediate, deferred); break; case pdf_extension_code: if (get_o_mode() == OMODE_PDF) - do_extension_pdf(immediate); + do_extension_pdf(immediate, deferred); break; /*tex Done. */ default: @@ -523,7 +560,7 @@ void expand_macros_in_tokenlist(halfword p) token_link(q) = r; token_info(r) = end_write_token; begin_token_list(q, inserted); - begin_token_list(write_tokens(p), write_text); + begin_token_list(p, write_text); q = get_avail(); token_info(q) = left_brace_token + '{'; begin_token_list(q, inserted); @@ -573,7 +610,7 @@ void write_out(halfword p) lstring *s = NULL; int callback_id; int lua_retval; - expand_macros_in_tokenlist(p); + expand_macros_in_tokenlist(write_tokens(p)); old_setting = selector; j = write_stream(p); if (file_can_be_written(j)) { diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.h b/Build/source/texk/web2c/luatexdir/tex/extensions.h index 5e22ddf26c3..9ba88188738 100644 --- a/Build/source/texk/web2c/luatexdir/tex/extensions.h +++ b/Build/source/texk/web2c/luatexdir/tex/extensions.h @@ -42,7 +42,7 @@ extern scaled neg_ht; extern halfword write_loc; -extern void do_extension(int immediate); +extern void do_extension(int immediate, int deferred); /* User defined whatsits can be inserted into node lists to pass data @@ -130,6 +130,7 @@ typedef enum { close_code, reserved_extension_code, // 3: we moved special below immediate // reserved_immediate_code, // 4: same number as main codes, expected value // + reserved_deferred_code, /* backend specific implementations */ special_code, save_box_resource_code, diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c b/Build/source/texk/web2c/luatexdir/tex/maincontrol.c index 0353930d1db..5be4577ad38 100644 --- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c +++ b/Build/source/texk/web2c/luatexdir/tex/maincontrol.c @@ -624,7 +624,7 @@ static void run_par_token (void) { } static void run_extension (void) { - do_extension(0); + do_extension(0, 0); } static void run_normal (void) { diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.c index b332dbdcbc5..76da864e5f4 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.c @@ -961,6 +961,7 @@ node_info whatsit_node_data[] = { { write_node, write_node_size, NULL, node_fields_whatsit_write, NULL, -1, 0 }, { close_node, close_node_size, NULL, node_fields_whatsit_close, NULL, -1, 0 }, { special_node, special_node_size, NULL, node_fields_whatsit_special, NULL, -1, 0 }, + { late_special_node, special_node_size, NULL, node_fields_whatsit_special, NULL, -1, 0 }, { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, { save_pos_node, save_pos_node_size, NULL, node_fields_whatsit_save_pos, NULL, -1, 0 }, @@ -972,7 +973,6 @@ node_info whatsit_node_data[] = { { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, - { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 }, /*tex Here starts the \DVI\ backend section, todo: a separate list. */ @@ -980,7 +980,8 @@ node_info whatsit_node_data[] = { /*tex Here starts the \PDF\ backend section, todo: a separate list. */ - { pdf_literal_node, write_node_size, NULL, node_fields_whatsit_pdf_literal, NULL, -1, 0 }, + { pdf_literal_node, literal_node_size, NULL, node_fields_whatsit_pdf_literal, NULL, -1, 0 }, + { pdf_late_literal_node, literal_node_size, NULL, node_fields_whatsit_pdf_literal, NULL, -1, 0 }, { pdf_refobj_node, pdf_refobj_node_size, NULL, node_fields_whatsit_pdf_refobj, NULL, -1, 0 }, { pdf_annot_node, pdf_annot_node_size, NULL, node_fields_whatsit_pdf_annot, NULL, -1, 0 }, { pdf_start_link_node, pdf_annot_node_size, NULL, node_fields_whatsit_pdf_start_link, NULL, -1, 0 }, @@ -1009,6 +1010,7 @@ void l_set_whatsit_data(void) { init_node_key(whatsit_node_data, write_node, write) init_node_key(whatsit_node_data, close_node, close) init_node_key(whatsit_node_data, special_node, special) + init_node_key(whatsit_node_data, late_special_node, late_special) init_node_key(whatsit_node_data, save_pos_node, save_pos) init_node_key(whatsit_node_data, late_lua_node, late_lua) init_node_key(whatsit_node_data, user_defined_node, user_defined) @@ -1050,6 +1052,7 @@ void l_set_whatsit_data(void) { init_field_nop(node_fields_whatsit_write, 3); init_node_key(whatsit_node_data, pdf_literal_node, pdf_literal) + init_node_key(whatsit_node_data, pdf_late_literal_node,pdf_late_literal) init_node_key(whatsit_node_data, pdf_refobj_node, pdf_refobj) init_node_key(whatsit_node_data, pdf_annot_node, pdf_annot) init_node_key(whatsit_node_data, pdf_start_link_node, pdf_start_link) @@ -1942,6 +1945,7 @@ static void copy_node_wrapup_core(halfword p, halfword r) switch (subtype(p)) { case write_node: case special_node: + case late_special_node: add_token_ref(write_tokens(p)); break; case late_lua_node: @@ -1980,6 +1984,7 @@ void copy_node_wrapup_pdf(halfword p, halfword r) { switch(subtype(p)) { case pdf_literal_node: + case pdf_late_literal_node: copy_pdf_literal(r, p); break; case pdf_colorstack_node: @@ -2201,6 +2206,7 @@ static void flush_node_wrapup_core(halfword p) case save_pos_node: break; case special_node: + case late_special_node: delete_token_ref(write_tokens(p)); break; case late_lua_node: @@ -2257,6 +2263,7 @@ void flush_node_wrapup_pdf(halfword p) case pdf_end_thread_node: break; case pdf_literal_node: + case pdf_late_literal_node: free_pdf_literal(p); break; case pdf_colorstack_node: @@ -2481,6 +2488,7 @@ static void check_node_wrapup_core(halfword p) switch (subtype(p)) { /*tex Frontend code. */ case special_node: + case late_special_node: check_token_ref(p); break; case user_defined_node: @@ -2519,6 +2527,7 @@ void check_node_wrapup_pdf(halfword p) { switch (subtype(p)) { case pdf_literal_node: + case pdf_late_literal_node: if (pdf_literal_type(p) == normal) check_token_ref(p); break; @@ -3475,6 +3484,10 @@ static void show_node_wrapup_core(int p) tprint_esc("special"); print_mark(write_tokens(p)); break; + case late_special_node: + tprint_esc("latespecial"); + print_mark(write_tokens(p)); + break; case late_lua_node: show_late_lua(p); break; @@ -3518,6 +3531,7 @@ void show_node_wrapup_pdf(int p) { switch (subtype(p)) { case pdf_literal_node: + case pdf_late_literal_node: show_pdf_literal(p); break; case pdf_colorstack_node: diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h index b65efe7b8bc..14ff06243fe 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h +++ b/Build/source/texk/web2c/luatexdir/tex/texnodes.h @@ -710,6 +710,7 @@ typedef enum { write_node, close_node, special_node, + late_special_node, /* done a la pdftex, more natural is to use special with a flag instead */ use_box_resource_node, use_image_resource_node, save_pos_node, @@ -719,6 +720,7 @@ typedef enum { dvi_literal_node = 15, /* pdf backend */ pdf_literal_node = 16, + pdf_late_literal_node, /* done a la pdftex, more natural is to use special with a flag instead */ pdf_refobj_node, pdf_annot_node, pdf_start_link_node, @@ -737,16 +739,19 @@ typedef enum { pdf_link_state_node, } whatsit_types; -# define first_common_whatsit 0 +# define first_common_whatsit open_node # define last_common_whatsit user_defined_node -# define backend_first_dvi_whatsit 15 -# define backend_last_dvi_whatsit 15 -# define backend_first_pdf_whatsit 16 -# define backend_last_pdf_whatsit 32 - -/* add some slack for the future */ +# define backend_first_dvi_whatsit dvi_literal_node +# define backend_last_dvi_whatsit dvi_literal_node +# define backend_first_pdf_whatsit pdf_literal_node +# define backend_last_pdf_whatsit pdf_link_state_node /* Don't forget to adapt this when extending! */ + +/* + We add quite some slack for future usage because who knows how we need to be compatible with + other engines. +*/ -# define MAX_WHATSIT_TYPE 34 +# define MAX_WHATSIT_TYPE 48 # define known_whatsit_type(i) ( \ (i >= first_common_whatsit && i <= last_common_whatsit) || \ @@ -810,8 +815,6 @@ typedef enum { # define boundary_node_size 3 # define boundary_value(a) vinfo((a)+2) -# define special_node_size 3 - typedef enum { normal_dir = 0, cancel_dir, @@ -826,10 +829,14 @@ typedef enum { # define dir_cur_v(a) vlink((a)+4) # define write_node_size 3 +# define literal_node_size 3 +# define special_node_size 3 # define close_node_size 3 # define write_tokens(a) vlink(a+2) # define write_stream(a) vinfo(a+2) +# define special_tokens write_tokens + # define open_node_size 4 # define open_name(a) vlink((a)+2) # define open_area(a) vinfo((a)+3) |