From 40f7db304a155502cef39ce83478a33907e97030 Mon Sep 17 00:00:00 2001 From: Luigi Scarso Date: Fri, 17 Feb 2023 23:30:17 +0000 Subject: 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 --- Build/source/texk/web2c/luatexdir/ChangeLog | 5 + Build/source/texk/web2c/luatexdir/dvi/dvigen.c | 12 ++- .../source/texk/web2c/luatexdir/lua/lnewtokenlib.c | 35 +++++++ Build/source/texk/web2c/luatexdir/lua/lnodelib.c | 42 +++++---- Build/source/texk/web2c/luatexdir/lua/ltexlib.c | 3 +- Build/source/texk/web2c/luatexdir/lua/luanode.c | 5 +- Build/source/texk/web2c/luatexdir/lua/luatex-api.h | 9 +- Build/source/texk/web2c/luatexdir/lua/luatoken.c | 34 +------ .../texk/web2c/luatexdir/luatex_svnversion.h | 2 +- Build/source/texk/web2c/luatexdir/pdf/pdflistout.c | 3 + Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c | 30 +++++- Build/source/texk/web2c/luatexdir/pdf/pdftables.c | 2 + Build/source/texk/web2c/luatexdir/tex/backend.c | 5 +- Build/source/texk/web2c/luatexdir/tex/commands.c | 3 +- Build/source/texk/web2c/luatexdir/tex/commands.h | 3 +- Build/source/texk/web2c/luatexdir/tex/extensions.c | 105 ++++++++++++++------- Build/source/texk/web2c/luatexdir/tex/extensions.h | 3 +- .../source/texk/web2c/luatexdir/tex/maincontrol.c | 2 +- Build/source/texk/web2c/luatexdir/tex/texnodes.c | 18 +++- Build/source/texk/web2c/luatexdir/tex/texnodes.h | 27 ++++-- 20 files changed, 242 insertions(+), 106 deletions(-) (limited to 'Build/source') diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index e840d071144..15bb53b736a 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,3 +1,8 @@ +2023-02-18 Luigi Scarso + * new "late special" feature by Phelype Oleinik, + heavily adapted by H.Hagen. + + 2023-02-05 Luigi Scarso * Fix typos (thanks to J. Friedrich) diff --git a/Build/source/texk/web2c/luatexdir/dvi/dvigen.c b/Build/source/texk/web2c/luatexdir/dvi/dvigen.c index 8e285917a50..684818a7563 100644 --- a/Build/source/texk/web2c/luatexdir/dvi/dvigen.c +++ b/Build/source/texk/web2c/luatexdir/dvi/dvigen.c @@ -1324,11 +1324,21 @@ void dvi_special(PDF pdf, halfword p) int old_setting; /*tex index into |cur_string| */ unsigned k; + halfword h; synch_dvi_with_pos(pdf->posstruct->pos); old_setting = selector; + if (subtype(p) == late_special_node ) { + expand_macros_in_tokenlist(special_tokens(p)); + h = token_link(def_ref); + } else { + h = token_link(special_tokens(p)); + } selector = new_string; - show_token_list(token_link(write_tokens(p)), null, -1); + show_token_list(h, null, -1); selector = old_setting; + if (subtype(p) == late_special_node ) { + flush_list(def_ref); + } if (cur_length < 256) { dvi_out(xxx1); dvi_out(cur_length); diff --git a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c index d0047919c7f..7c81e462e84 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c @@ -124,6 +124,41 @@ lua_token *check_istoken(lua_State * L, int ud) return NULL; } +/* moved here */ + +int token_from_lua(lua_State * L) +{ + int cmd, chr; + int cs = 0; + size_t len; + lua_token *p; + if (lua_type(L, -1) == LUA_TTABLE) { + len = lua_rawlen(L, -1); + if (len == 3 || len == 2) { + lua_rawgeti(L, -1, 1); + cmd = (int) lua_tointeger(L, -1); + lua_rawgeti(L, -2, 2); + chr = (int) lua_tointeger(L, -1); + if (len == 3) { + lua_rawgeti(L, -3, 3); + cs = (int) lua_tointeger(L, -1); + } + lua_pop(L, (int) len); + if (cs == 0) { + return token_val(cmd, chr); + } else { + return cs_token_flag + cs; + } + } + } else { + p = check_istoken(L, -1); + if (p) { + return token_info(p->token); + } + } + return -1; +} + /* token library functions */ static void make_new_token(lua_State * L, int cmd, int chr, int cs) diff --git a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c index 30538d0cf4f..72dbe01b076 100644 --- a/Build/source/texk/web2c/luatexdir/lua/lnodelib.c +++ b/Build/source/texk/web2c/luatexdir/lua/lnodelib.c @@ -150,7 +150,7 @@ #define nodelib_setattr(L, s, n) reassign_attribute(n,nodelib_getlist(L,s)) -#define nodelib_gettoks(L,a) tokenlist_from_lua(L) +#define nodelib_gettoks(L,a) tokenlist_from_lua(L, a) #define nodelib_getspec nodelib_getlist #define nodelib_getaction nodelib_getlist @@ -1584,6 +1584,7 @@ static int lua_nodelib_direct_setleader(lua_State * L) #define set_pdf_literal_direct_token(L,n,i) do { \ pdf_literal_data(n) = nodelib_gettoks(L, i); \ + pdf_literal_type(n) = normal; \ } while (0) #define cleanup_late_lua(n) do { \ @@ -1652,7 +1653,7 @@ static int lua_nodelib_direct_setleader(lua_State * L) #define get_write_direct_value(L,n) do { \ int l; \ char *s; \ - expand_macros_in_tokenlist(n); \ + expand_macros_in_tokenlist(write_tokens(n)); \ s = tokenlist_to_cstring(def_ref, 1, &l); \ lua_pushlstring(L, s, (size_t) l); \ free(s); \ @@ -1689,7 +1690,7 @@ static int lua_nodelib_direct_getdata(lua_State * L) halfword s = subtype(n); if (s == user_defined_node) { get_user_node_direct_value(L, n); - } else if (s == pdf_literal_node) { + } else if (s == pdf_literal_node || s == pdf_late_literal_node) { get_pdf_literal_direct_value(L, n); /*tex A bonus. */ lua_pushinteger(L,pdf_literal_mode(n)); @@ -1698,7 +1699,7 @@ static int lua_nodelib_direct_getdata(lua_State * L) get_late_lua_direct_value(L, n); } else if (s == pdf_setmatrix_node) { get_pdf_setmatrix_direct_value(L, n); - } else if (s == special_node) { + } else if (s == special_node || s == late_special_node) { get_special_direct_value(L, n); } else if (s == write_node) { get_write_direct_value(L, n); @@ -1725,17 +1726,21 @@ static int lua_nodelib_direct_setdata(lua_State * L) /* data and value */ halfword s = subtype(n); if (s == user_defined_node) { set_user_node_direct_value(L, n, 2); - } else if (s == pdf_literal_node) { - set_pdf_literal_direct_normal(L, n, 2); - if (lua_type(L,2) == LUA_TNUMBER) { + } else if (s == pdf_literal_node || s == pdf_late_literal_node) { + if (lua_type(L,2) == LUA_TTABLE) { + set_pdf_literal_direct_token(L, n, 2); + } else { + set_pdf_literal_direct_normal(L, n, 2); + } + if (lua_type(L,3) == LUA_TNUMBER) { /*tex A bonus. */ - pdf_literal_mode(n) = lua_tointeger(L,2); + pdf_literal_mode(n) = lua_tointeger(L,3); } } else if (s == late_lua_node) { set_late_lua_direct_normal(L, n, 2); } else if (s == pdf_setmatrix_node) { set_pdf_setmatrix_direct_value(L, n, 2); - } else if (s == special_node) { + } else if (s == special_node || s == late_special_node) { set_special_direct_value(L, n, 2); } else if (s == write_node) { set_write_direct_value(L,n,2); @@ -3200,7 +3205,8 @@ static int lua_nodelib_subtypes(lua_State * L) else if (t == fence_noad) subtypes = node_subtypes_fence; /* backend */ else if (t == pdf_dest_node) subtypes = node_values_pdf_destination; - else if (t == pdf_literal_node) subtypes = node_values_pdf_literal; + else if((t == pdf_literal_node) + || (t == pdf_late_literal_node)) subtypes = node_values_pdf_literal; } if (subtypes != NULL) { lua_checkstack(L, 2); @@ -4435,7 +4441,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } else { lua_pushnil(L); } - } else if (t == pdf_literal_node) { + } else if (t == pdf_literal_node || t == pdf_late_literal_node) { /*tex The |string| key is obsolete. */ if (lua_key_eq(s, mode)) { lua_pushinteger(L, pdf_literal_mode(n)); @@ -4520,7 +4526,7 @@ static void lua_nodelib_getfield_whatsit(lua_State * L, int n, const char *s) } else { lua_pushnil(L); } - } else if (t == special_node) { + } else if (t == special_node || t == late_special_node) { if (lua_key_eq(s, data)) { get_special_direct_value(L,n); } else { @@ -5215,7 +5221,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } else { lua_pushnil(L); } - } else if (t == pdf_literal_node) { + } else if (t == pdf_literal_node || t == pdf_late_literal_node) { /*tex The |string| key is obsolete. */ if (lua_key_eq(s, mode)) { lua_pushinteger(L, pdf_literal_mode(n)); @@ -5300,7 +5306,7 @@ static void lua_nodelib_direct_getfield_whatsit(lua_State * L, int n, const char } else { lua_pushnil(L); } - } else if (t == special_node) { + } else if (t == special_node || t == late_special_node) { if (lua_key_eq(s, data)) { get_special_direct_value(L,n); } else { @@ -6580,7 +6586,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) { int t = subtype(n); - if (t == pdf_literal_node) { + if (t == pdf_literal_node || t == pdf_late_literal_node) { /*tex The |string| key is obsolete. */ if (lua_key_eq(s, mode)) { pdf_literal_mode(n) = (quarterword) lua_tointeger(L, 3); @@ -6772,7 +6778,7 @@ static int lua_nodelib_setfield_whatsit(lua_State * L, int n, const char *s) } else { return nodelib_cantset(L, n, s); } - } else if (t == special_node) { + } else if (t == special_node || t == late_special_node) { if (lua_key_eq(s, data)) { set_special_direct_value(L,n,3); } else { @@ -7362,7 +7368,7 @@ static int lua_nodelib_setfield(lua_State * L) static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char *s) { int t = subtype(n); - if (t == pdf_literal_node) { + if (t == pdf_literal_node || t == pdf_late_literal_node) { /*tex The |string| key is obsolete. */ if (lua_key_eq(s, mode)) { pdf_literal_mode(n) = (quarterword) lua_tointeger(L, 3); @@ -7527,7 +7533,7 @@ static int lua_nodelib_direct_setfield_whatsit(lua_State * L, int n, const char } else { return nodelib_cantset(L, n, s); } - } else if (t == special_node) { + } else if (t == special_node || t == late_special_node) { if (lua_key_eq(s, data)) { set_special_direct_value(L, n, 3); } else { diff --git a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c index 6e19e0727bc..8962a39f308 100644 --- a/Build/source/texk/web2c/luatexdir/lua/ltexlib.c +++ b/Build/source/texk/web2c/luatexdir/lua/ltexlib.c @@ -1790,13 +1790,12 @@ static int settex(lua_State * L) } } else if (is_toks_assign(cur_cmd1)) { if (lua_type(L,i) == LUA_TSTRING) { - j = tokenlist_from_lua(L); /* uses stack -1 */ + j = tokenlist_from_lua(L, -1); /* uses stack -1 */ assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs1), j); } else { luaL_error(L, "unsupported value type"); } - } else if (lua_istable(L, (i - 2))) { /* people may want to add keys that are also primitives |tex.wd| for example) diff --git a/Build/source/texk/web2c/luatexdir/lua/luanode.c b/Build/source/texk/web2c/luatexdir/lua/luanode.c index 3fd00253f02..275a7686c25 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luanode.c +++ b/Build/source/texk/web2c/luatexdir/lua/luanode.c @@ -418,7 +418,10 @@ void free_user_lua(pointer p) void show_pdf_literal(pointer p) { int t = pdf_literal_type(p); - tprint_esc("pdfliteral"); + if (subtype(p)==pdf_late_literal_node) + tprint_esc("pdflateliteral"); + else + tprint_esc("pdfliteral"); switch (pdf_literal_mode(p)) { case set_origin: tprint(" origin"); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h index c1e618f7a5d..553be2c1827 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/Build/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -162,7 +162,8 @@ extern int characters_from_lua(lua_State * L, int f); /* return is boolean */ extern int luaopen_token(lua_State * L); extern void tokenlist_to_lua(lua_State * L, int p); extern void tokenlist_to_luastring(lua_State * L, int p); -extern int tokenlist_from_lua(lua_State * L); +extern int tokenlist_from_lua(lua_State * L, int i); +extern int token_from_lua(lua_State * L); extern void lua_nodelib_push(lua_State * L); extern int nodelib_getdir(lua_State * L, int n); @@ -1017,6 +1018,7 @@ make_lua_key(pdf_end_thread);\ make_lua_key(pdf_link_data);\ make_lua_key(pdf_link_state);\ make_lua_key(pdf_literal);\ +make_lua_key(pdf_late_literal);\ make_lua_key(pdf_refobj);\ make_lua_key(pdf_restore);\ make_lua_key(pdf_save);\ @@ -1125,6 +1127,7 @@ make_lua_key(spaceskip);\ make_lua_key(span);\ make_lua_key(spec);\ make_lua_key(special);\ +make_lua_key(late_special);\ make_lua_key(split_discards_head);\ make_lua_key(split_insert);\ make_lua_key(split_keep);\ @@ -1721,6 +1724,7 @@ init_lua_key(pdf_end_thread);\ init_lua_key(pdf_link_data);\ init_lua_key(pdf_link_state);\ init_lua_key(pdf_literal);\ +init_lua_key(pdf_late_literal);\ init_lua_key(pdf_refobj);\ init_lua_key(pdf_restore);\ init_lua_key(pdf_save);\ @@ -1825,6 +1829,7 @@ init_lua_key(spaceskip);\ init_lua_key(span);\ init_lua_key(spec);\ init_lua_key(special);\ +init_lua_key(late_special);\ init_lua_key(split_discards_head);\ init_lua_key(split_insert);\ init_lua_key(split_keep);\ @@ -2492,6 +2497,7 @@ use_lua_key(pdf_end_thread); use_lua_key(pdf_link_data); use_lua_key(pdf_link_state); use_lua_key(pdf_literal); +use_lua_key(pdf_late_literal); use_lua_key(pdf_refobj); use_lua_key(pdf_restore); use_lua_key(pdf_save); @@ -2600,6 +2606,7 @@ use_lua_key(spaceskip); use_lua_key(span); use_lua_key(spec); use_lua_key(special); +use_lua_key(late_special); use_lua_key(split_discards_head); use_lua_key(split_insert); use_lua_key(split_keep); diff --git a/Build/source/texk/web2c/luatexdir/lua/luatoken.c b/Build/source/texk/web2c/luatexdir/lua/luatoken.c index dc2c6b8aaa5..2ab3be47cdd 100644 --- a/Build/source/texk/web2c/luatexdir/lua/luatoken.c +++ b/Build/source/texk/web2c/luatexdir/lua/luatoken.c @@ -386,30 +386,6 @@ static int get_cur_cmd(lua_State * L) } */ -static int token_from_lua(lua_State * L) -{ - int cmd, chr; - int cs = 0; - size_t len = lua_rawlen(L, -1); - if (len == 3 || len == 2) { - lua_rawgeti(L, -1, 1); - cmd = (int) lua_tointeger(L, -1); - lua_rawgeti(L, -2, 2); - chr = (int) lua_tointeger(L, -1); - if (len == 3) { - lua_rawgeti(L, -3, 3); - cs = (int) lua_tointeger(L, -1); - } - lua_pop(L, (int) len); - if (cs == 0) { - return token_val(cmd, chr); - } else { - return cs_token_flag + cs; - } - } - return -1; -} - /* static int get_cur_cs(lua_State * L) { @@ -482,7 +458,7 @@ void tokenlist_to_luastring(lua_State * L, int p) free(s); } -int tokenlist_from_lua(lua_State * L) +int tokenlist_from_lua(lua_State * L, int index) { const char *s; int tok, t; @@ -492,12 +468,12 @@ int tokenlist_from_lua(lua_State * L) token_info(r) = 0; token_link(r) = null; p = r; - t = lua_type(L, -1); + t = lua_type(L, index); if (t == LUA_TTABLE) { - j = lua_rawlen(L, -1); + j = lua_rawlen(L, index); if (j > 0) { for (i = 1; i <= j; i++) { - lua_rawgeti(L, -1, (int) i); + lua_rawgeti(L, index, (int) i); tok = token_from_lua(L); if (tok >= 0) { store_new_token(tok); @@ -507,7 +483,7 @@ int tokenlist_from_lua(lua_State * L) } return r; } else if (t == LUA_TSTRING) { - s = lua_tolstring(L, -1, &j); + s = lua_tolstring(L, index, &j); for (i = 0; i < j; i++) { if (s[i] == 32) { tok = token_val(10, s[i]); diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h index c2d11e26c20..a8e86fb4032 100644 --- a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1,4 +1,4 @@ #ifndef luatex_svn_revision_h #define luatex_svn_revision_h -#define luatex_svn_revision 7558 +#define luatex_svn_revision 7559 #endif diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c index 6561626d8ba..29eb883323c 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.c @@ -274,6 +274,7 @@ static void handle_backend_whatsit(PDF pdf, halfword p, halfword parent_box, sca if (output_mode_used == OMODE_PDF) { switch (subtype(p)) { case pdf_literal_node: + case pdf_late_literal_node: case pdf_save_node: case pdf_restore_node: case pdf_setmatrix_node: @@ -730,6 +731,7 @@ void hlist_out(PDF pdf, halfword this_box, int rule_callback_id) wrapup_leader(p); break; case special_node: + case late_special_node: /*tex |pdf_special(pdf, p)| */ case late_lua_node: /*tex |late_lua(pdf, p)| */ @@ -1103,6 +1105,7 @@ void vlist_out(PDF pdf, halfword this_box, int rule_callback_id) wrapup_leader(p); break; case special_node: + case late_special_node: /*tex |pdf_special(pdf, p)|; */ case late_lua_node: /*tex |late_lua(pdf, p)|; */ diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c index e8b00a64ef5..1309eb51b76 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c @@ -21,16 +21,32 @@ with LuaTeX; if not, see . #include "ptexlib.h" +/* + With these (new) late nodes we operate on write_tokens which happens to be + equivalent to pdf_literal_data so it is somewhat confusing but cleaning this + up now is asking for troubles. +*/ + void pdf_special(PDF pdf, halfword p) { int old_setting = selector; str_number s; + halfword h; + if (subtype(p) == late_special_node) { + expand_macros_in_tokenlist(pdf_literal_data(p)); + h = token_link(def_ref); + } else { + h = token_link(pdf_literal_data(p)); + } selector = new_string; - show_token_list(token_link(write_tokens(p)), null, -1); + show_token_list(h, null, -1); selector = old_setting; s = make_string(); pdf_literal(pdf, s, scan_special, true); flush_str(s); + if (subtype(p) == late_special_node) { + flush_list(def_ref); + } } /*tex @@ -47,15 +63,25 @@ void pdf_out_literal(PDF pdf, halfword p) int old_setting; str_number s; int t = pdf_literal_type(p); + halfword h; pdfstructure *ps = pdf->pstruct; if (t == normal) { old_setting = selector; + if (subtype(p) == pdf_late_literal_node) { + expand_macros_in_tokenlist(pdf_literal_data(p)); + h = token_link(def_ref); + } else { + h = token_link(pdf_literal_data(p)); + } selector = new_string; - show_token_list(token_link(pdf_literal_data(p)), null, -1); + show_token_list(h, null, -1); selector = old_setting; s = make_string(); pdf_literal(pdf, s, pdf_literal_mode(p), false); flush_str(s); + if (subtype(p) == pdf_late_literal_node) { + flush_list(def_ref); + } } else if (t == lua_refid_literal) { switch (pdf_literal_mode(p)) { case set_origin: diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c index 66f25ecd7c0..1d76f695121 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdftables.c +++ b/Build/source/texk/web2c/luatexdir/pdf/pdftables.c @@ -231,6 +231,8 @@ void check_obj_type(PDF pdf, int t, int objnum) passed to |set_rect_dimens| and have control per feature, maybe even under parameter control. */ +halfword calculate_width_to_endlink(halfword p, halfword this_box, halfword *leftskip, halfword *rightskip); + void set_rect_dimens(PDF pdf, halfword p, halfword parent_box, scaledpos cur, scaled_whd alt_rule) { /*tex 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) -- cgit v1.2.3