From df94129842c8c239dc0d4cbdbdffddeff6ad6595 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 21 Jan 2023 02:06:30 +0000 Subject: sync from pdftex r890: shipout keyword for delayed expansion of \special and \literal, from phelype git-svn-id: svn://tug.org/texlive/trunk@65602 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/pdftexdir/ChangeLog | 14 +++ Build/source/texk/web2c/pdftexdir/NEWS | 2 + Build/source/texk/web2c/pdftexdir/pdftex.web | 175 +++++++++++++++++---------- 3 files changed, 126 insertions(+), 65 deletions(-) diff --git a/Build/source/texk/web2c/pdftexdir/ChangeLog b/Build/source/texk/web2c/pdftexdir/ChangeLog index 2244d67fd24..9da9a4b31a1 100644 --- a/Build/source/texk/web2c/pdftexdir/ChangeLog +++ b/Build/source/texk/web2c/pdftexdir/ChangeLog @@ -1,3 +1,17 @@ +2023-01-20 Phelype Oleinik + + * pdftex.web: implement shipout keyword for delayed expansion + with \pdfliteral and \special, like non-\immediate \write. + (pdf_out_literal): check for pdf_lateliteral_node. + (pdf_special): check for latespecial_node. + (latespecial_node): new @d (4) + (pdf_lateliteral_node): new @d (pdftex_first_extension_code + 1). + (Implement \.{\\special}), + (Implement \.{\\pdfliteral}): look for `shipout' keyword. + (scan_pdf_ext_late_toks): new procedure. + (Display the whatsit) : + new cases. + 2022-12-28 Thanh Han The * pdftex.web (Display the whatsit...) : indicate diff --git a/Build/source/texk/web2c/pdftexdir/NEWS b/Build/source/texk/web2c/pdftexdir/NEWS index 6962c0fc03d..894113bf3c4 100644 --- a/Build/source/texk/web2c/pdftexdir/NEWS +++ b/Build/source/texk/web2c/pdftexdir/NEWS @@ -1,5 +1,7 @@ pdfTeX 3.141592653-2.6-1.40.25 - changes: + - new keyword `shipout' for \special and \pdfliteral, delaying + expansion until the node is shipped out, like non-\immediate \write. - new primitive \pdfinfoomitdict to omit /Info dictionary completely. - new primitive \pdfomitprocset to control omitting /ProcSet array; /ProcSet is included if this parameter is negative, or if this diff --git a/Build/source/texk/web2c/pdftexdir/pdftex.web b/Build/source/texk/web2c/pdftexdir/pdftex.web index fb7700e4593..49a9cbb3582 100644 --- a/Build/source/texk/web2c/pdftexdir/pdftex.web +++ b/Build/source/texk/web2c/pdftexdir/pdftex.web @@ -1,4 +1,4 @@ -% Copyright 1996-2022 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, +% Copyright 1996-2023 Han Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh, % % This file is part of pdfTeX. @@ -18501,8 +18501,16 @@ need to declare some procedures needed in |pdf_hlist_out| and |pdf_vlist_out|. procedure pdf_out_literal(p:pointer); var old_setting:0..max_selector; {holds print |selector|} s: str_number; -begin - old_setting:=selector; selector:=new_string; + @!q,@!r:pointer; {temporary variables for list manipulation} + @!old_mode:integer; {saved |mode|} +begin + old_setting:=selector; + if subtype(p)=pdf_lateliteral_node then + begin @; + pdf_literal_data(p):=def_ref; + end; + selector:=new_string; show_token_list(link(pdf_literal_data(p)),null,pool_size-pool_ptr); selector:=old_setting; s := make_string; @@ -18618,8 +18626,17 @@ end; procedure pdf_special(p: pointer); var old_setting:0..max_selector; {holds print |selector|} s: str_number; -begin - old_setting:=selector; selector:=new_string; + @!q,@!r:pointer; {temporary variables for list manipulation} + @!old_mode:integer; {saved |mode|} +begin + old_setting:=selector; + selector:=selector; + if subtype(p)=latespecial_node then + begin @; + write_tokens(p):=def_ref; + end; + selector:=new_string; show_token_list(link(write_tokens(p)),null,pool_size-pool_ptr); selector:=old_setting; s := make_string; @@ -33624,7 +33641,8 @@ to hold the string numbers for name, area, and extension. @d write_node=1 {|subtype| in whatsits that represent things to \.{\\write}} @d close_node=2 {|subtype| in whatsits that represent streams to \.{\\closeout}} @d special_node=3 {|subtype| in whatsits that represent \.{\\special} things} -@d language_node=4 {|subtype| in whatsits that change the current language} +@d latespecial_node==4 {|subtype| in whatsits that represent \.{\\special} things expanded during output} +@d language_node=5 {|subtype| in whatsits that change the current language} @d what_lang(#)==link(#+1) {language number, in the range |0..255|} @d what_lhm(#)==type(#+1) {minimum left fragment, in the range |1..63|} @d what_rhm(#)==subtype(#+1) {minimum right fragment, in the range |1..63|} @@ -33651,52 +33669,53 @@ for k:=0 to 17 do write_open[k]:=false; |extension| with a modifier, whenever possible, so that |main_control| stays the same. -@d immediate_code=4 {command modifier for \.{\\immediate}} -@d set_language_code=5 {command modifier for \.{\\setlanguage}} -@d pdftex_first_extension_code = 6 +@d immediate_code=5 {command modifier for \.{\\immediate}} +@d set_language_code=6 {command modifier for \.{\\setlanguage}} +@d pdftex_first_extension_code = 7 @d pdf_literal_node == pdftex_first_extension_code + 0 -@d pdf_obj_code == pdftex_first_extension_code + 1 -@d pdf_refobj_node == pdftex_first_extension_code + 2 -@d pdf_xform_code == pdftex_first_extension_code + 3 -@d pdf_refxform_node == pdftex_first_extension_code + 4 -@d pdf_ximage_code == pdftex_first_extension_code + 5 -@d pdf_refximage_node == pdftex_first_extension_code + 6 -@d pdf_annot_node == pdftex_first_extension_code + 7 -@d pdf_start_link_node == pdftex_first_extension_code + 8 -@d pdf_end_link_node == pdftex_first_extension_code + 9 -@d pdf_outline_code == pdftex_first_extension_code + 10 -@d pdf_dest_node == pdftex_first_extension_code + 11 -@d pdf_thread_node == pdftex_first_extension_code + 12 -@d pdf_start_thread_node == pdftex_first_extension_code + 13 -@d pdf_end_thread_node == pdftex_first_extension_code + 14 -@d pdf_save_pos_node == pdftex_first_extension_code + 15 -@d pdf_info_code == pdftex_first_extension_code + 16 -@d pdf_catalog_code == pdftex_first_extension_code + 17 -@d pdf_names_code == pdftex_first_extension_code + 18 -@d pdf_font_attr_code == pdftex_first_extension_code + 19 -@d pdf_include_chars_code == pdftex_first_extension_code + 20 -@d pdf_map_file_code == pdftex_first_extension_code + 21 -@d pdf_map_line_code == pdftex_first_extension_code + 22 -@d pdf_trailer_code == pdftex_first_extension_code + 23 -@d pdf_trailer_id_code == pdftex_first_extension_code + 24 -@d reset_timer_code == pdftex_first_extension_code + 25 -@d pdf_font_expand_code == pdftex_first_extension_code + 26 -@d set_random_seed_code == pdftex_first_extension_code + 27 -@d pdf_snap_ref_point_node == pdftex_first_extension_code + 28 -@d pdf_snapy_node == pdftex_first_extension_code + 29 -@d pdf_snapy_comp_node == pdftex_first_extension_code + 30 -@d pdf_glyph_to_unicode_code == pdftex_first_extension_code + 31 -@d pdf_colorstack_node == pdftex_first_extension_code + 32 -@d pdf_setmatrix_node == pdftex_first_extension_code + 33 -@d pdf_save_node == pdftex_first_extension_code + 34 -@d pdf_restore_node == pdftex_first_extension_code + 35 -@d pdf_nobuiltin_tounicode_code== pdftex_first_extension_code + 36 -@d pdf_interword_space_on_node == pdftex_first_extension_code + 37 -@d pdf_interword_space_off_node== pdftex_first_extension_code + 38 -@d pdf_fake_space_node == pdftex_first_extension_code + 39 -@d pdf_running_link_off_node == pdftex_first_extension_code + 40 -@d pdf_running_link_on_node == pdftex_first_extension_code + 41 -@d pdftex_last_extension_code == pdftex_first_extension_code + 41 +@d pdf_lateliteral_node == pdftex_first_extension_code + 1 +@d pdf_obj_code == pdftex_first_extension_code + 2 +@d pdf_refobj_node == pdftex_first_extension_code + 3 +@d pdf_xform_code == pdftex_first_extension_code + 4 +@d pdf_refxform_node == pdftex_first_extension_code + 5 +@d pdf_ximage_code == pdftex_first_extension_code + 6 +@d pdf_refximage_node == pdftex_first_extension_code + 7 +@d pdf_annot_node == pdftex_first_extension_code + 8 +@d pdf_start_link_node == pdftex_first_extension_code + 9 +@d pdf_end_link_node == pdftex_first_extension_code + 10 +@d pdf_outline_code == pdftex_first_extension_code + 11 +@d pdf_dest_node == pdftex_first_extension_code + 12 +@d pdf_thread_node == pdftex_first_extension_code + 13 +@d pdf_start_thread_node == pdftex_first_extension_code + 14 +@d pdf_end_thread_node == pdftex_first_extension_code + 15 +@d pdf_save_pos_node == pdftex_first_extension_code + 16 +@d pdf_info_code == pdftex_first_extension_code + 17 +@d pdf_catalog_code == pdftex_first_extension_code + 18 +@d pdf_names_code == pdftex_first_extension_code + 19 +@d pdf_font_attr_code == pdftex_first_extension_code + 20 +@d pdf_include_chars_code == pdftex_first_extension_code + 21 +@d pdf_map_file_code == pdftex_first_extension_code + 22 +@d pdf_map_line_code == pdftex_first_extension_code + 23 +@d pdf_trailer_code == pdftex_first_extension_code + 24 +@d pdf_trailer_id_code == pdftex_first_extension_code + 25 +@d reset_timer_code == pdftex_first_extension_code + 26 +@d pdf_font_expand_code == pdftex_first_extension_code + 27 +@d set_random_seed_code == pdftex_first_extension_code + 28 +@d pdf_snap_ref_point_node == pdftex_first_extension_code + 29 +@d pdf_snapy_node == pdftex_first_extension_code + 30 +@d pdf_snapy_comp_node == pdftex_first_extension_code + 31 +@d pdf_glyph_to_unicode_code == pdftex_first_extension_code + 32 +@d pdf_colorstack_node == pdftex_first_extension_code + 33 +@d pdf_setmatrix_node == pdftex_first_extension_code + 34 +@d pdf_save_node == pdftex_first_extension_code + 35 +@d pdf_restore_node == pdftex_first_extension_code + 36 +@d pdf_nobuiltin_tounicode_code== pdftex_first_extension_code + 37 +@d pdf_interword_space_on_node == pdftex_first_extension_code + 38 +@d pdf_interword_space_off_node== pdftex_first_extension_code + 39 +@d pdf_fake_space_node == pdftex_first_extension_code + 40 +@d pdf_running_link_off_node == pdftex_first_extension_code + 41 +@d pdf_running_link_on_node == pdftex_first_extension_code + 42 +@d pdftex_last_extension_code == pdftex_first_extension_code + 42 @= primitive("openout",extension,open_node);@/ @@ -33965,12 +33984,17 @@ begin new_write_whatsit(write_node_size); write_tokens(tail):=null; end @ When `\.{\\special\{...\}}' appears, we expand the macros in the token -list as in \.{\\xdef} and \.{\\mark}. +list as in \.{\\xdef} and \.{\\mark}. When marked with \.{shipout}, we keep +tokens unexpanded for now. @= +begin if scan_keyword("shipout") then +begin new_whatsit(latespecial_node,write_node_size); write_stream(tail):=null; +p:=scan_toks(false,false); write_tokens(tail):=def_ref; +end else begin new_whatsit(special_node,write_node_size); write_stream(tail):=null; p:=scan_toks(false,true); write_tokens(tail):=def_ref; -end +end; end @ @= read_expand_font @@ -34022,6 +34046,11 @@ begin call_func(scan_toks(false, true)); {like \.{\\special}} end; +procedure scan_pdf_ext_late_toks; +begin + call_func(scan_toks(false, false)); {like \.{\\special}, but doesn't expand} +end; + procedure compare_strings; {to implement \.{\\pdfstrcmp}} label done; var s1, s2: str_number; @@ -34065,14 +34094,17 @@ end; @ @= begin check_pdfoutput("\pdfliteral", true); - new_whatsit(pdf_literal_node, write_node_size); + if scan_keyword("shipout") then k:=pdf_lateliteral_node + else k:=pdf_literal_node; + new_whatsit(k, write_node_size); if scan_keyword("direct") then pdf_literal_mode(tail) := direct_always else if scan_keyword("page") then pdf_literal_mode(tail) := direct_page else pdf_literal_mode(tail) := set_origin; - scan_pdf_ext_toks; + if k=pdf_literal_node then + scan_pdf_ext_toks else scan_pdf_ext_late_toks; pdf_literal_data(tail) := def_ref; end @@ -35406,13 +35438,17 @@ close_node:print_write_whatsit("closeout",p); special_node:begin print_esc("special"); print_mark(write_tokens(p)); end; +latespecial_node:begin print_esc("special"); print(" shipout"); + print_mark(write_tokens(p)); + end; language_node:begin print_esc("setlanguage"); print_int(what_lang(p)); print(" (hyphenmin "); print_int(what_lhm(p)); print_char(","); print_int(what_rhm(p)); print_char(")"); end; -pdf_literal_node: begin +pdf_literal_node,pdf_lateliteral_node: begin print_esc("pdfliteral"); + if subtype(p)=pdf_lateliteral_node then print(" shipout"); case pdf_literal_mode(p) of set_origin: do_nothing; @@ -35620,13 +35656,13 @@ endcases case subtype(p) of open_node: begin r:=get_node(open_node_size); words:=open_node_size; end; -write_node,special_node: begin r:=get_node(write_node_size); +write_node,special_node,latespecial_node: begin r:=get_node(write_node_size); add_token_ref(write_tokens(p)); words:=write_node_size; end; close_node,language_node: begin r:=get_node(small_node_size); words:=small_node_size; end; -pdf_literal_node: begin +pdf_literal_node,pdf_lateliteral_node: begin r := get_node(write_node_size); add_token_ref(pdf_literal_data(p)); words := write_node_size; @@ -35731,11 +35767,11 @@ endcases @ @= begin case subtype(p) of open_node: free_node(p,open_node_size); -write_node,special_node: begin delete_token_ref(write_tokens(p)); +write_node,special_node,latespecial_node: begin delete_token_ref(write_tokens(p)); free_node(p,write_node_size); goto done; end; close_node,language_node: free_node(p,small_node_size); -pdf_literal_node: begin +pdf_literal_node,pdf_lateliteral_node: begin delete_token_ref(pdf_literal_data(p)); free_node(p, write_node_size); end; @@ -35884,8 +35920,17 @@ that actually send out the requested data. Let's do \.{\\special} first procedure special_out(@!p:pointer); var old_setting:0..max_selector; {holds print |selector|} @!k:pool_pointer; {index into |str_pool|} +@!q,@!r:pointer; {temporary variables for list manipulation} +@!old_mode:integer; {saved |mode|} begin synch_h; synch_v;@/ old_setting:=selector; selector:=new_string; +selector:=old_setting; +if subtype(p)=latespecial_node then + begin @; + write_tokens(p):=def_ref; + end; +selector:=new_string; show_token_list(link(write_tokens(p)),null,pool_size-pool_ptr); selector:=old_setting; str_room(1); @@ -35972,7 +36017,7 @@ var j:small_number; {write stream number} begin case subtype(p) of open_node,write_node,close_node:@; -special_node:special_out(p); +special_node,latespecial_node:special_out(p); language_node:do_nothing; pdf_save_pos_node: @; @@ -36817,7 +36862,7 @@ end @ @= case subtype(p) of -pdf_literal_node: +pdf_literal_node,pdf_lateliteral_node: pdf_out_literal(p); pdf_colorstack_node: pdf_out_colorstack(p); @@ -36848,7 +36893,7 @@ pdf_end_thread_node: end_thread; pdf_save_pos_node: @; -special_node: +special_node,latespecial_node: pdf_special(p); pdf_snap_ref_point_node: @; @@ -36903,7 +36948,7 @@ begin cur_v:=cur_v+pdf_height(p); save_v:=cur_v; @ @= case subtype(p) of -pdf_literal_node: +pdf_literal_node,pdf_lateliteral_node: pdf_out_literal(p); pdf_colorstack_node: pdf_out_colorstack(p); @@ -36935,7 +36980,7 @@ pdf_end_thread_node: pdf_error("ext4", "\pdfendthread ended up in hlist"); pdf_save_pos_node: @; -special_node: +special_node,latespecial_node: pdf_special(p); pdf_snap_ref_point_node: @; -- cgit v1.2.3