diff options
author | Karl Berry <karl@freefriends.org> | 2023-02-13 16:43:55 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-02-13 16:43:55 +0000 |
commit | 9126877409972187cc26dec15b2a9642ec4834dd (patch) | |
tree | 0712c97d88dd3a8ce787b4b2db65541dc50e0aab /Build/source/texk/web2c/xetexdir | |
parent | f76d5cbdd3fdc27b30b766d71320ee55de5ec6ce (diff) |
shipout keyword for \special and \pdfliteral, a la pdftex
git-svn-id: svn://tug.org/texlive/trunk@65814 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/xetexdir')
-rw-r--r-- | Build/source/texk/web2c/xetexdir/ChangeLog | 10 | ||||
-rw-r--r-- | Build/source/texk/web2c/xetexdir/NEWS | 5 | ||||
-rw-r--r-- | Build/source/texk/web2c/xetexdir/xetex.web | 42 |
3 files changed, 44 insertions, 13 deletions
diff --git a/Build/source/texk/web2c/xetexdir/ChangeLog b/Build/source/texk/web2c/xetexdir/ChangeLog index ad75eb86e25..5a2fcb3c105 100644 --- a/Build/source/texk/web2c/xetexdir/ChangeLog +++ b/Build/source/texk/web2c/xetexdir/ChangeLog @@ -1,3 +1,13 @@ +2023-01-20 Phelype Oleinik <phelype.oleinik@latex-project.org> + + * xetex.web: implement shipout keyword for delayed expansion + with \pdfliteral and \special, like non-\immediate \write. + (latespecial_node): new @d (4), and step @d for following parameters. + (Implement \.{\\special}): look for `shipout' keyword. + (Display the whatsit) <latespecial_node, <pdf_lateliteral_node>: + (special_out): check for latespecial_node. + new cases. + 2021-02-17 Karl Berry <karl@tug.org> * NEWS, diff --git a/Build/source/texk/web2c/xetexdir/NEWS b/Build/source/texk/web2c/xetexdir/NEWS index 1fb4a87d727..154e222c316 100644 --- a/Build/source/texk/web2c/xetexdir/NEWS +++ b/Build/source/texk/web2c/xetexdir/NEWS @@ -1,5 +1,8 @@ ============================================================== -XeTeX 0.999995 +XeTeX 0.999995 (February 2023) + +* new keyword `shipout' for \special and \pdfliteral, delaying + expansion until the node is shipped out, like non-\immediate \write. ============================================================== XeTeX 0.999994 (February 2022) diff --git a/Build/source/texk/web2c/xetexdir/xetex.web b/Build/source/texk/web2c/xetexdir/xetex.web index bb107758871..4e2f8965dc8 100644 --- a/Build/source/texk/web2c/xetexdir/xetex.web +++ b/Build/source/texk/web2c/xetexdir/xetex.web @@ -29551,7 +29551,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} +@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|} @@ -29578,13 +29579,13 @@ 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 immediate_code=5 {command modifier for \.{\\immediate}} +@d set_language_code=6 {command modifier for \.{\\setlanguage}} -@d pdftex_first_extension_code = 6 -@d pdf_save_pos_node == pdftex_first_extension_code + 15 -@d reset_timer_code == pdftex_first_extension_code + 25 -@d set_random_seed_code == pdftex_first_extension_code + 27 +@d pdftex_first_extension_code = 7 +@d pdf_save_pos_node == pdftex_first_extension_code + 16 +@d reset_timer_code == pdftex_first_extension_code + 26 +@d set_random_seed_code == pdftex_first_extension_code + 28 @d pic_file_code=41 { command modifier for \.{\\XeTeXpicfile}, skipping codes pdfTeX might use } @d pdf_file_code=42 { command modifier for \.{\\XeTeXpdffile} } @@ -29732,12 +29733,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. @<Implement \.{\\special}@>= +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 @ @d call_func(#) == begin if # <> 0 then do_nothing end @d flushable(#) == (# = str_ptr - 1) @@ -29884,6 +29890,9 @@ 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(","); @@ -29916,7 +29925,7 @@ 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); @@ -29944,7 +29953,7 @@ endcases @ @<Wipe out the whatsit...@>= 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); @@ -30226,9 +30235,18 @@ 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;@/ doing_special:=true; old_setting:=selector; selector:=new_string; +selector:=old_setting; +if subtype(p)=latespecial_node then + begin @<Expand macros in the token list + and make |link(def_ref)| point to the result@>; + 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); @@ -30355,7 +30373,7 @@ var j:small_number; {write stream number} begin case subtype(p) of open_node,write_node,close_node:@<Do some work that has been queued up for \.{\\write}@>; -special_node:special_out(p); +special_node,latespecial_node:special_out(p); language_node:do_nothing; othercases confusion("ext4") @:this can't happen ext4}{\quad ext4@> |