summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorLuigi Scarso <luigi.scarso@gmail.com>2023-02-17 23:30:17 +0000
committerLuigi Scarso <luigi.scarso@gmail.com>2023-02-17 23:30:17 +0000
commit40f7db304a155502cef39ce83478a33907e97030 (patch)
treec6fd1beabff67716c5bc08204ed3877608d236c2 /Build
parent35c8bd5c065403e14361f540d6633de184ea2c89 (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')
-rw-r--r--Build/source/texk/web2c/luatexdir/ChangeLog5
-rw-r--r--Build/source/texk/web2c/luatexdir/dvi/dvigen.c12
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lnewtokenlib.c35
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/lnodelib.c42
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/ltexlib.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luanode.c5
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatex-api.h9
-rw-r--r--Build/source/texk/web2c/luatexdir/lua/luatoken.c34
-rw-r--r--Build/source/texk/web2c/luatexdir/luatex_svnversion.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdflistout.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfliteral.c30
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdftables.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/backend.c5
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.h3
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.c105
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.h3
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.c2
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.c18
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h27
20 files changed, 242 insertions, 106 deletions
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 <luigi.scarso@gmail.com>
+ * new "late special" feature by Phelype Oleinik,
+ heavily adapted by H.Hagen.
+
+
2023-02-05 Luigi Scarso <luigi.scarso@gmail.com>
* 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 <http://www.gnu.org/licenses/>.
#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)