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