3
Copyright 2009 Taco Hoekwater <taco@luatex.org>
5
This file is part of LuaTeX.
7
LuaTeX is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2 of the License, or (at your
10
option) any later version.
12
LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU General Public License along
18
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
20
static const char _svn_version[] =
21
"$Id: extensions.c 3261 2009-12-18 11:38:21Z taco $"
22
"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/tex/extensions.c $";
26
#define mode cur_list.mode_field
27
#define tail cur_list.tail_field
28
#define head cur_list.head_field
29
#define prev_graf cur_list.pg_field
30
#define dir_save cur_list.dirs_field
32
#define tracing_nesting int_par(tracing_nesting_code)
33
#define box(A) eqtb[box_base+(A)].hh.rh
34
#define global_defs int_par(global_defs_code)
35
#define cat_code_table int_par(cat_code_table_code)
36
#define par_direction int_par(par_direction_code)
37
#define toks(A) equiv(toks_base+(A))
39
#define local_inter_line_penalty int_par(local_inter_line_penalty_code)
40
#define local_broken_penalty int_par(local_broken_penalty_code)
41
#define local_left_box equiv(local_left_box_base)
42
#define local_right_box equiv(local_right_box_base)
45
The program above includes a bunch of ``hooks'' that allow further
46
capabilities to be added without upsetting \TeX's basic structure.
47
Most of these hooks are concerned with ``whatsit'' nodes, which are
48
intended to be used for special purposes; whenever a new extension to
49
\TeX\ involves a new kind of whatsit node, a corresponding change needs
50
to be made to the routines below that deal with such nodes,
51
but it will usually be unnecessary to make many changes to the
52
other parts of this program.
54
In order to demonstrate how extensions can be made, we shall treat
55
`\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
56
and `\.{\\special}' as if they were extensions.
57
These commands are actually primitives of \TeX, and they should
58
appear in all implementations of the system; but let's try to imagine
59
that they aren't. Then the program below illustrates how a person
62
Sometimes, of course, an extension will require changes to \TeX\ itself;
63
no system of hooks could be complete enough for all conceivable extensions.
64
The features associated with `\.{\\write}' are almost all confined to the
65
following paragraphs, but there are small parts of the |print_ln| and
66
|print_char| procedures that were introduced specifically to \.{\\write}
67
characters. Furthermore one of the token lists recognized by the scanner
68
is a |write_text|; and there are a few other miscellaneous places where we
69
have already provided for some aspect of \.{\\write}. The goal of a \TeX\
70
extender should be to minimize alterations to the standard parts of the
71
program, and to avoid them completely if possible. He or she should also
72
be quite sure that there's no easy way to accomplish the desired goals
73
with the standard features that \TeX\ already has. ``Think thrice before
74
extending,'' because that may save a lot of work, and it will also keep
75
incompatible extensions of \TeX\ from proliferating.
76
@^system dependencies@>
77
@^extensions to \TeX@>
79
@ First let's consider the format of whatsit nodes that are used to represent
80
the data associated with \.{\\write} and its relatives. Recall that a whatsit
81
has |type=whatsit_node|, and the |subtype| is supposed to distinguish
82
different kinds of whatsits. Each node occupies two or more words; the
83
exact number is immaterial, as long as it is readily determined from the
84
|subtype| or other data.
86
We shall introduce five |subtype| values here, corresponding to the
87
control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}.
88
The second word of I/O whatsits has a |write_stream| field
89
that identifies the write-stream number (0 to 15, or 16 for out-of-range and
90
positive, or 17 for out-of-range and negative).
91
In the case of \.{\\write} and \.{\\special}, there is also a field that
92
points to the reference count of a token list that should be sent. In the
93
case of \.{\\openout}, we need three words and three auxiliary subfields
94
to hold the string numbers for name, area, and extension.
98
Extensions might introduce new command codes; but it's best to use
99
|extension| with a modifier, whenever possible, so that |main_control|
105
The sixteen possible \.{\\write} streams are represented by the |write_file|
106
array. The |j|th file is open if and only if |write_open[j]=true|. The last
107
two streams are special; |write_open[16]| represents a stream number
108
greater than 15, while |write_open[17]| represents a negative stream number,
109
and both of these variables are always |false|.
112
alpha_file write_file[16];
113
halfword write_file_mode[16];
114
halfword write_file_translation[16];
115
boolean write_open[18];
121
The variable |write_loc| just introduced is used to provide an
122
appropriate error message in case of ``runaway'' write texts.
125
halfword write_loc; /* |eqtb| address of \.{\\write} */
128
When an |extension| command occurs in |main_control|, in any mode,
129
the |do_extension| routine is called.
132
void do_extension(PDF pdf)
134
int i, k; /* all-purpose integers */
135
halfword p; /* all-purpose pointer */
138
/* Implement \.{\\openout} */
139
new_write_whatsit(open_node_size);
140
scan_optional_equals();
142
open_name(tail) = cur_name;
143
open_area(tail) = cur_area;
144
open_ext(tail) = cur_ext;
147
/* Implement \.{\\write} */
148
/* When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
149
without expanding its macros; the macros will be expanded later when this
150
token list is rescanned. */
152
new_write_whatsit(write_node_size);
154
p = scan_toks(false, false);
155
write_tokens(tail) = def_ref;
158
/* Implement \.{\\closeout} */
159
new_write_whatsit(write_node_size);
160
write_tokens(tail) = null;
163
/* Implement \.{\\special} */
164
/* When `\.{\\special\{...\}}' appears, we expand the macros in the token
165
list as in \.{\\xdef} and \.{\\mark}. */
166
new_whatsit(special_node);
167
write_stream(tail) = null;
168
p = scan_toks(false, true);
169
write_tokens(tail) = def_ref;
172
/* Implement \.{\\immediate} */
173
/* To write a token list, we must run it through \TeX's scanner, expanding
174
macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
175
if a delimited macro parameter isn't matched, and runaways would be
176
extremely confusing since we are calling on \TeX's scanner in the middle
177
of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
178
a ``stopper,'' right after the token list. This control sequence is
179
artificially defined to be \.{\\outer}.
180
@:end_write_}{\.{\\endwrite}@>
182
The presence of `\.{\\immediate}' causes the |do_extension| procedure
183
to descend to one level of recursion. Nothing happens unless \.{\\immediate}
184
is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
188
if (cur_cmd == extension_cmd) {
189
if (cur_chr <= close_node) {
191
/* do_extension() and out_what() here can only be open, write, or close */
192
do_extension(pdf); /* append a whatsit node */
193
out_what(pdf, tail); /* do the action immediately */
194
flush_node_list(tail);
200
check_o_mode(pdf, "\\immediate\\pdfobj", 1 << OMODE_PDF,
202
do_extension(pdf); /* scan object and set |pdf_last_obj| */
203
if (obj_data_ptr(pdf, pdf_last_obj) == 0) /* this object has not been initialized yet */
205
"`\\pdfobj reserveobjnum' cannot be used with \\immediate");
206
pdf_write_obj(pdf, pdf_last_obj);
209
check_o_mode(pdf, "\\immediate\\pdfxform", 1 << OMODE_PDF,
211
do_extension(pdf); /* scan form and set |pdf_last_xform| */
212
pdf_cur_form = pdf_last_xform;
213
ship_out(pdf, obj_xform_box(pdf, pdf_last_xform), false);
215
case pdf_ximage_code:
216
check_o_mode(pdf, "\\immediate\\pdfximage", 1 << OMODE_PDF,
218
do_extension(pdf); /* scan image and set |pdf_last_ximage| */
219
pdf_write_image(pdf, pdf_last_ximage);
231
/* Implement \.{\\pdfannot} */
232
check_o_mode(pdf, "\\pdfannot", 1 << OMODE_PDF, false);
235
case pdf_catalog_code:
236
/* Implement \.{\\pdfcatalog} */
237
check_o_mode(pdf, "\\pdfcatalog", 1 << OMODE_PDF, true); /* writes an object */
238
scan_pdfcatalog(pdf);
241
/* Implement \.{\\pdfdest} */
242
check_o_mode(pdf, "\\pdfdest", 1 << OMODE_PDF, false);
245
case pdf_end_link_node:
246
/* Implement \.{\\pdfendlink} */
247
check_o_mode(pdf, "\\pdfendlink", 1 << OMODE_PDF, false);
248
if (abs(mode) == vmode)
249
pdf_error("ext1", "\\pdfendlink cannot be used in vertical mode");
250
new_whatsit(pdf_end_link_node);
252
case pdf_end_thread_node:
253
/* Implement \.{\\pdfendthread} */
254
check_o_mode(pdf, "\\pdfendthread", 1 << OMODE_PDF, false);
255
new_whatsit(pdf_end_thread_node);
257
case pdf_font_attr_code:
258
/* Implement \.{\\pdffontattr} */
259
/* A change from \THANH's original code: the font attributes are simply
260
initialized to zero now, this is easier to deal with from C than an
261
empty \TeX{} string, and surely nobody will want to set
262
\.{\\pdffontattr} to a string containing a single zero, as that
263
would be nonsensical in the PDF output. */
264
check_o_mode(pdf, "\\pdffontattr", 1 << OMODE_PDF, false);
268
pdf_error("font", "invalid font identifier");
270
set_pdf_font_attr(k, tokens_to_string(def_ref));
271
if (str_length(pdf_font_attr(k)) == 0) {
272
flush_str((str_ptr - 1)); /* from tokens_to_string */
273
set_pdf_font_attr(k, 0);
276
case pdf_font_expand_code:
277
/* Implement \.{\\pdffontexpand} */
280
case pdf_include_chars_code:
281
/* Implement \.{\\pdfincludechars} */
282
check_o_mode(pdf, "\\pdfincludechars", 1 << OMODE_PDF, false);
283
pdf_include_chars(pdf);
286
/* Implement \.{\\pdfinfo} */
287
check_o_mode(pdf, "\\pdfinfo", 1 << OMODE_PDF, false);
289
pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
291
case pdf_literal_node:
292
/* Implement \.{\\pdfliteral} */
293
check_o_mode(pdf, "\\pdfliteral", 1 << OMODE_PDF, false);
294
new_whatsit(pdf_literal_node);
295
if (scan_keyword("direct"))
296
set_pdf_literal_mode(tail, direct_always);
297
else if (scan_keyword("page"))
298
set_pdf_literal_mode(tail, direct_page);
300
set_pdf_literal_mode(tail, set_origin);
302
set_pdf_literal_type(tail, normal);
303
set_pdf_literal_data(tail, def_ref);
305
case pdf_colorstack_node:
306
/* Implement \.{\\pdfcolorstack} */
307
check_o_mode(pdf, "\\pdfcolorstack", 1 << OMODE_PDF, false);
308
/* Scan and check the stack number and store in |cur_val| */
310
if (cur_val >= colorstackused()) {
311
print_err("Unknown color stack number ");
314
("Allocate and initialize a color stack with \\pdfcolorstackinit.",
315
"I'll use default color stack 0 here.",
316
"Proceed, with fingers crossed.");
321
print_err("Invalid negative color stack number");
322
help2("I'll use default color stack 0 here.",
323
"Proceed, with fingers crossed.");
327
if (scan_keyword("set"))
329
else if (scan_keyword("push"))
331
else if (scan_keyword("pop"))
333
else if (scan_keyword("current"))
334
i = colorstack_current;
339
new_whatsit(pdf_colorstack_node);
340
set_pdf_colorstack_stack(tail, cur_val);
341
set_pdf_colorstack_cmd(tail, i);
342
set_pdf_colorstack_data(tail, null);
343
if (i <= colorstack_data) {
345
set_pdf_colorstack_data(tail, def_ref);
348
print_err("Color stack action is missing");
349
help3("The expected actions for \\pdfcolorstack:",
350
" set, push, pop, current",
351
"I'll ignore the color stack command.");
355
case pdf_setmatrix_node:
356
/* Implement \.{\\pdfsetmatrix} */
357
check_o_mode(pdf, "\\pdfsetmatrix", 1 << OMODE_PDF, false);
358
new_whatsit(pdf_setmatrix_node);
360
set_pdf_setmatrix_data(tail, def_ref);
363
/* Implement \.{\\pdfsave} */
364
check_o_mode(pdf, "\\pdfsave", 1 << OMODE_PDF, false);
365
new_whatsit(pdf_save_node);
367
case pdf_restore_node:
368
/* Implement \.{\\pdfrestore} */
369
check_o_mode(pdf, "\\pdfrestore", 1 << OMODE_PDF, false);
370
new_whatsit(pdf_restore_node);
372
case pdf_map_file_code:
373
/* Implement \.{\\pdfmapfile} */
374
check_o_mode(pdf, "\\pdfmapfile", 1 << OMODE_PDF, false);
377
delete_token_ref(def_ref);
379
case pdf_map_line_code:
380
/* Implement \.{\\pdfmapline} */
381
check_o_mode(pdf, "\\pdfmapline", 1 << OMODE_PDF, false);
384
delete_token_ref(def_ref);
387
/* Implement \.{\\pdfnames} */
388
check_o_mode(pdf, "\\pdfnames", 1 << OMODE_PDF, false);
390
pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
393
/* Implement \.{\\pdfobj} */
394
check_o_mode(pdf, "\\pdfobj", 1 << OMODE_PDF, false);
397
case pdf_outline_code:
398
/* Implement \.{\\pdfoutline} */
399
check_o_mode(pdf, "\\pdfoutline", 1 << OMODE_PDF, true);
400
scan_pdfoutline(pdf);
402
case pdf_refobj_node:
403
/* Implement \.{\\pdfrefobj} */
404
check_o_mode(pdf, "\\pdfrefobj", 1 << OMODE_PDF, false);
407
case pdf_refxform_node:
408
/* Implement \.{\\pdfrefxform} */
409
check_o_mode(pdf, "\\pdfrefxform", 1 << OMODE_PDF, false);
410
scan_pdfrefxform(pdf);
412
case pdf_refximage_node:
413
/* Implement \.{\\pdfrefximage} */
414
check_o_mode(pdf, "\\pdfrefximage", 1 << OMODE_PDF, false);
415
scan_pdfrefximage(pdf);
417
case pdf_save_pos_node:
418
/* Implement \.{\\pdfsavepos} */
419
new_whatsit(pdf_save_pos_node);
421
case pdf_start_link_node:
422
/* Implement \.{\\pdfstartlink} */
423
check_o_mode(pdf, "\\pdfstartlink", 1 << OMODE_PDF, false);
426
case pdf_start_thread_node:
427
/* Implement \.{\\pdfstartthread} */
428
check_o_mode(pdf, "\\pdfstartthread", 1 << OMODE_PDF, false);
429
new_annot_whatsit(pdf_start_thread_node);
432
case pdf_thread_node:
433
/* Implement \.{\\pdfthread} */
434
check_o_mode(pdf, "\\pdfthread", 1 << OMODE_PDF, false);
435
new_annot_whatsit(pdf_thread_node);
438
case pdf_trailer_code:
439
/* Implement \.{\\pdftrailer} */
440
check_o_mode(pdf, "\\pdftrailer", 1 << OMODE_PDF, false);
442
pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
445
/* Implement \.{\\pdfxform} */
446
check_o_mode(pdf, "\\pdfxform", 1 << OMODE_PDF, false);
449
case pdf_ximage_code:
450
/* Implement \.{\\pdfximage} */
451
check_o_mode(pdf, "\\pdfximage", 1 << OMODE_PDF, false);
452
/* png, jpeg, and pdf image handling depends on this done so early: */
453
fix_pdf_minorversion(pdf);
456
case save_cat_code_table_code:
457
/* Implement \.{\\savecatcodetable} */
459
if ((cur_val < 0) || (cur_val > 0xFFFF)) {
460
print_err("Invalid \\catcode table");
461
help1("All \\catcode table ids must be between 0 and 0xFFFF");
464
if (cur_val == cat_code_table) {
465
print_err("Invalid \\catcode table");
466
help1("You cannot overwrite the current \\catcode table");
469
copy_cat_codes(cat_code_table, cur_val);
473
case init_cat_code_table_code:
474
/* Implement \.{\\initcatcodetable} */
476
if ((cur_val < 0) || (cur_val > 0xFFFF)) {
477
print_err("Invalid \\catcode table");
478
help1("All \\catcode table ids must be between 0 and 0xFFFF");
481
if (cur_val == cat_code_table) {
482
print_err("Invalid \\catcode table");
483
help1("You cannot overwrite the current \\catcode table");
486
initex_cat_codes(cur_val);
490
case set_random_seed_code:
491
/* Implement \.{\\pdfsetrandomseed} */
492
/* Negative random seed values are silently converted to positive ones */
496
random_seed = cur_val;
497
init_randoms(random_seed);
499
case pdf_glyph_to_unicode_code:
500
/* Implement \.{\\pdfglyphtounicode} */
504
/* Implement \.{\\latelua} */
505
new_whatsit(late_lua_node);
506
late_lua_name(tail) = scan_lua_state();
507
(void) scan_toks(false, false);
508
late_lua_data(tail) = def_ref;
517
Here is a subroutine that creates a whatsit node having a given |subtype|
518
and a given number of words. It initializes only the first word of the whatsit,
519
and appends it to the current list.
522
void new_whatsit(int s)
524
halfword p; /* the new node */
525
p = new_node(whatsit_node, s);
526
couple_nodes(tail, p);
531
The next subroutine uses |cur_chr| to decide what sort of whatsit is
532
involved, and also inserts a |write_stream| number.
535
void new_write_whatsit(int w)
537
new_whatsit(cur_chr);
538
if (w != write_node_size) {
544
else if ((cur_val > 15) && (cur_val != 18))
547
write_stream(tail) = cur_val;
551
We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
555
void scan_pdf_ext_toks(void)
557
(void) scan_toks(false, true); /* like \.{\\special} */
560
/* We need to check whether the referenced object exists. */
562
/* finds the node preceding the rightmost node |e|; |s| is some node before |e| */
563
halfword prev_rightmost(halfword s, halfword e)
568
while (vlink(p) != e) {
576
/* \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
582
/* \.{\\pdfximage} and \.{\\pdfrefximage} are similiar to \.{\\pdfxform} and
583
\.{\\pdfrefxform}. As we have to scan |<rule spec>| quite often, it is better
584
have a |rule_node| that holds the most recently scanned |<rule spec>|.
588
int pdf_last_ximage_pages;
589
int pdf_last_ximage_colordepth;
592
/* pdflastlink needs an extra global variable */
595
scaledpos pdf_last_pos = { 0, 0 };
598
To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
599
\.{\\pdfnames} we need to concatenate tokens lists.
602
halfword concat_tokens(halfword q, halfword r)
603
{ /* concat |q| and |r| and returns the result tokens list */
608
while (token_link(p) != null)
610
set_token_link(p, token_link(r));
615
int pdf_retval; /* global multi-purpose return value */
618
halfword make_local_par_node(void)
619
/* This function creates a |local_paragraph| node */
622
p = new_node(whatsit_node, local_par_node);
623
local_pen_inter(p) = local_inter_line_penalty;
624
local_pen_broken(p) = local_broken_penalty;
625
if (local_left_box != null) {
626
q = copy_node_list(local_left_box);
627
local_box_left(p) = q;
628
local_box_left_width(p) = width(local_left_box);
630
if (local_right_box != null) {
631
q = copy_node_list(local_right_box);
632
local_box_right(p) = q;
633
local_box_right_width(p) = width(local_right_box);
635
local_par_dir(p) = par_direction;
641
The \eTeX\ features available in extended mode are grouped into two
642
categories: (1)~Some of them are permanently enabled and have no
643
semantic effect as long as none of the additional primitives are
644
executed. (2)~The remaining \eTeX\ features are optional and can be
645
individually enabled and disabled. For each optional feature there is
646
an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
647
resp.\ disabled by assigning a positive, resp.\ non-positive value to
652
In order to handle \.{\\everyeof} we need an array |eof_seen| of
656
boolean *eof_seen; /* has eof been seen? */
659
The |print_group| procedure prints the current level of grouping and
660
the name corresponding to |cur_group|.
663
void print_group(boolean e)
667
tprint("bottom level");
671
case semi_simple_group:
672
if (cur_group == semi_simple_group)
677
case adjusted_hbox_group:
678
if (cur_group == adjusted_hbox_group)
690
if (cur_group == no_align_group)
707
case math_choice_group:
708
case math_shift_group:
709
case math_left_group:
711
if (cur_group == math_choice_group)
713
else if (cur_group == math_shift_group)
715
else if (cur_group == math_left_group)
718
} /* there are no other cases */
719
tprint(" group (level ");
720
print_int(cur_level);
722
if (saved_value(-1) != 0) { /* saved_line */
724
tprint(" entered at line ");
727
print_int(saved_value(-1)); /* saved_line */
732
The |group_trace| procedure is called when a new level of grouping
733
begins (|e=false|) or ends (|e=true|) with |saved_value(-1)| containing the
737
void group_trace(boolean e)
747
end_diagnostic(false);
751
A group entered (or a conditional started) in one file may end in a
752
different file. Such slight anomalies, although perfectly legitimate,
753
may cause errors that are difficult to locate. In order to be able to
754
give a warning message when such anomalies occur, \eTeX\ uses the
755
|grp_stack| and |if_stack| arrays to record the initial |cur_boundary|
756
and |cond_ptr| values for each input file.
759
save_pointer *grp_stack; /* initial |cur_boundary| */
760
halfword *if_stack; /* initial |cond_ptr| */
763
When a group ends that was apparently entered in a different input
764
file, the |group_warning| procedure is invoked in order to update the
765
|grp_stack|. If moreover \.{\\tracingnesting} is positive we want to
766
give a warning message. The situation is, however, somewhat complicated
767
by two facts: (1)~There may be |grp_stack| elements without a
768
corresponding \.{\\input} file or \.{\\scantokens} pseudo file (e.g.,
769
error insertions from the terminal); and (2)~the relevant information is
770
recorded in the |name_field| of the |input_stack| only loosely
771
synchronized with the |in_open| variable indexing |grp_stack|.
774
void group_warning(void)
776
int i; /* index into |grp_stack| */
777
boolean w; /* do we need a warning? */
778
base_ptr = input_ptr;
779
input_stack[base_ptr] = cur_input; /* store current state */
782
while ((grp_stack[i] == cur_boundary) && (i > 0)) {
783
/* Set variable |w| to indicate if this case should be reported */
784
/* This code scans the input stack in order to determine the type of the
785
current input file. */
786
if (tracing_nesting > 0) {
787
while ((input_stack[base_ptr].state_field == token_list) ||
788
(input_stack[base_ptr].index_field > i))
790
if (input_stack[base_ptr].name_field > 17)
794
grp_stack[i] = save_value(save_ptr);
798
tprint_nl("Warning: end of ");
800
tprint(" of a different file");
802
if (tracing_nesting > 1)
804
if (history == spotless)
805
history = warning_issued;
810
When a conditional ends that was apparently started in a different
811
input file, the |if_warning| procedure is invoked in order to update the
812
|if_stack|. If moreover \.{\\tracingnesting} is positive we want to
813
give a warning message (with the same complications as above).
816
void if_warning(void)
818
int i; /* index into |if_stack| */
819
boolean w; /* do we need a warning? */
820
base_ptr = input_ptr;
821
input_stack[base_ptr] = cur_input; /* store current state */
824
while (if_stack[i] == cond_ptr) {
825
/* Set variable |w| to... */
826
if (tracing_nesting > 0) {
827
while ((input_stack[base_ptr].state_field == token_list) ||
828
(input_stack[base_ptr].index_field > i))
830
if (input_stack[base_ptr].name_field > 17)
834
if_stack[i] = vlink(cond_ptr);
838
tprint_nl("Warning: end of ");
839
print_cmd_chr(if_test_cmd, cur_if);
840
print_if_line(if_line);
841
tprint(" of a different file");
843
if (tracing_nesting > 1)
845
if (history == spotless)
846
history = warning_issued;
851
Conversely, the |file_warning| procedure is invoked when a file ends
852
and some groups entered or conditionals started while reading from that
853
file are still incomplete.
856
void file_warning(void)
858
halfword p; /* saved value of |save_ptr| or |cond_ptr| */
859
quarterword l; /* saved value of |cur_level| or |if_limit| */
860
quarterword c; /* saved value of |cur_group| or |cur_if| */
861
int i; /* saved value of |if_line| */
865
save_ptr = cur_boundary;
866
while (grp_stack[in_open] != save_ptr) {
868
tprint_nl("Warning: end of file when ");
870
tprint(" is incomplete");
871
cur_group = save_level(save_ptr);
872
save_ptr = save_value(save_ptr);
876
cur_group = c; /* restore old values */
881
while (if_stack[in_open] != cond_ptr) {
882
tprint_nl("Warning: end of file when ");
883
print_cmd_chr(if_test_cmd, cur_if);
884
if (if_limit == fi_code)
886
print_if_line(if_line);
887
tprint(" is incomplete");
888
if_line = if_line_field(cond_ptr);
889
cur_if = if_limit_subtype(cond_ptr);
890
if_limit = if_limit_type(cond_ptr);
891
cond_ptr = vlink(cond_ptr);
896
if_line = i; /* restore old values */
898
if (tracing_nesting > 1)
900
if (history == spotless)
901
history = warning_issued;
904
halfword last_line_fill; /* the |par_fill_skip| glue node of the new paragraph */
907
The lua interface needs some extra pascal functions. The functions
908
themselves are quite boring, but they are handy because otherwise this
909
internal stuff has to be accessed from C directly, where lots of the
910
pascal defines are not available.
913
#define get_tex_dimen_register(j) dimen(j)
914
#define get_tex_skip_register(j) skip(j)
915
#define get_tex_count_register(j) count(j)
916
#define get_tex_attribute_register(j) attribute(j)
917
#define get_tex_box_register(j) box(j)
919
int set_tex_dimen_register(int j, scaled v)
921
int a; /* return non-nil for error */
926
word_define(j + scaled_base, v);
930
int set_tex_skip_register(int j, halfword v)
932
int a; /* return non-nil for error */
937
if (type(v) != glue_spec_node)
939
word_define(j + skip_base, v);
943
int set_tex_count_register(int j, scaled v)
945
int a; /* return non-nil for error */
950
word_define(j + count_base, v);
954
int set_tex_box_register(int j, scaled v)
956
int a; /* return non-nil for error */
961
define(j + box_base, box_ref_cmd, v);
965
int set_tex_attribute_register(int j, scaled v)
967
int a; /* return non-nil for error */
972
if (j > max_used_attr)
974
attr_list_cache = cache_disabled;
975
word_define(j + attribute_base, v);
979
int get_tex_toks_register(int j)
983
if (toks(j) != null) {
984
s = tokens_to_string(toks(j));
989
int set_tex_toks_register(int j, lstring s)
995
set_token_ref_count(ref, 0);
996
set_token_link(ref, token_link(temp_token_head));
1001
define(j + toks_base, call_cmd, ref);
1005
scaled get_tex_box_width(int j)
1007
halfword q = box(j);
1013
int set_tex_box_width(int j, scaled v)
1015
halfword q = box(j);
1022
scaled get_tex_box_height(int j)
1024
halfword q = box(j);
1030
int set_tex_box_height(int j, scaled v)
1032
halfword q = box(j);
1040
scaled get_tex_box_depth(int j)
1042
halfword q = box(j);
1048
int set_tex_box_depth(int j, scaled v)
1050
halfword q = box(j);
1058
This section is devoted to the {\sl Synchronize \TeX nology}
1059
- or simply {\sl Sync\TeX} - used to synchronize between input and output.
1060
This section explains how synchronization basics are implemented.
1061
Before we enter into more technical details,
1062
let us recall in a few words what is synchronization.
1064
\TeX\ typesetting system clearly separates the input and the output material,
1065
and synchronization will provide a new link between both that can help
1066
text editors and viewers to work together.
1067
More precisely, forwards synchronization is the ability,
1068
given a location in the input source file,
1069
to find what is the corresponding place in the output.
1070
Backwards synchronization just performs the opposite:
1071
given a location in the output,
1072
retrieve the corresponding material in the input source file.
1074
For better code management and maintainance, we adopt a naming convention.
1075
Throughout this program, code related to the {\sl Synchronize \TeX nology} is tagged
1076
with the ``{\sl synctex}'' key word. Any code extract where {\sl Sync\TeX} plays
1077
its part, either explicitly or implicitly, (should) contain the string ``{\sl synctex}''.
1078
This naming convention also holds for external files.
1079
Moreover, all the code related to {\sl Sync\TeX} is gathered in this section,
1080
except the definitions.
1082
@ Enabling synchronization should be performed from the command line,
1083
|synctexoption| is used for that purpose.
1084
This global integer variable is declared here but it is not used here.
1085
This is just a placeholder where the command line controller will put
1086
the {\sl Sync\TeX} related options, and the {\sl Sync\TeX} controller will read them.
1092
@ A convenient primitive is provided:
1093
\.{\\synctex=1} in the input source file enables synchronization whereas
1094
\.{\\synctex=0} disables it.
1095
Its memory address is |synctex_code|.
1096
It is initialized by the {\sl Sync\TeX} controller to the command-line option if given.
1097
The controller may filter some reserved bits.
1099
@ In order to give the {\sl Sync\TeX} controller read and write access to
1100
the contents of the \.{\\synctex} primitive, we declare |synctexoffset|,
1101
such that |mem[synctexoffset]| and \.{\\synctex} correspond to
1102
the same memory storage. |synctexoffset| is initialized to
1103
the correct value when quite everything is initialized.
1106
int synctexoffset; /* holds the true value of |synctex_code| */
1109
Synchronization is achieved with the help of an auxiliary file named
1110
`\.{{\sl jobname}.synctex}' ({\sl jobname} is the contents of the
1111
\.{\\jobname} macro), where a {\sl Sync\TeX} controller implemented
1112
in the external |synctex.c| file will store geometrical information.
1113
This {\sl Sync\TeX} controller will take care of every technical details
1114
concerning the {\sl Sync\TeX} file, we will only focus on the messages
1115
the controller will receive from the \TeX\ program.
1117
The most accurate synchronization information should allow to map
1118
any character of the input source file to the corresponding location
1119
in the output, if relevant.
1120
Ideally, the synchronization information of the input material consists of
1121
the file name, the line and column numbers of every character.
1122
The synchronization information in the output is simply the page number and
1123
either point coordinates, or box dimensions and position.
1124
The problem is that the mapping between these informations is only known at
1125
ship out time, which means that we must keep track of the input
1126
synchronization information until the pages ship out.
1128
As \TeX\ only knows about file names and line numbers,
1129
but forgets the column numbers, we only consider a
1130
restricted input synchronization information called {\sl Sync\TeX\ information}.
1131
It consists of a unique file name identifier, the {\sl Sync\TeX\ file tag},
1132
and the line number.
1134
Keeping track of such information,
1135
should be different whether characters or nodes are involved.
1136
Actually, only certain nodes are involved in {\sl Sync\TeX},
1137
we call them {\sl synchronized nodes}.
1138
Synchronized nodes store the {\sl Sync\TeX} information in their last two words:
1139
the first one contains a {\sl Sync\TeX\ file tag} uniquely identifying
1140
the input file, and the second one contains the current line number,
1141
as returned by the \.{\\inputlineno} primitive.
1142
The |synctex_field_size| macro contains the necessary size to store
1143
the {\sl Sync\TeX} information in a node.
1145
When declaring the size of a new node, it is recommanded to use the following
1146
convention: if the node is synchronized, use a definition similar to
1147
|my_synchronized_node_size|={\sl xxx}+|synctex_field_size|.
1148
Moreover, one should expect that the {\sl Sync\TeX} information is always stored
1149
in the last two words of a synchronized node.
1151
@ By default, every node with a sufficiently big size is initialized
1152
at creation time in the |get_node| routine with the current
1153
{\sl Sync\TeX} information, whether or not the node is synchronized.
1154
One purpose is to set this information very early in order to minimize code
1155
dependencies, including forthcoming extensions.
1156
Another purpose is to avoid the assumption that every node type has a dedicated getter,
1157
where initialization should take place. Actually, it appears that some nodes are created
1158
using directly the |get_node| routine and not the dedicated constructor.
1159
And finally, initializing the node at only one place is less error prone.
1161
@ Instead of storing the input file name, it is better to store just an identifier.
1162
Each time \TeX\ opens a new file, it notifies the {\sl Sync\TeX} controller with
1163
a |synctex_start_input| message.
1164
This controller will create a new {\sl Sync\TeX} file tag and
1165
will update the current input state record accordingly.
1166
If the input comes from the terminal or a pseudo file, the |synctex_tag| is set to 0.
1167
It results in automatically disabling synchronization for material
1168
input from the terminal or pseudo files.
1171
@ Synchronized nodes are boxes, math, kern and glue nodes.
1172
Other nodes should be synchronized too, in particular math noads.
1173
\TeX\ assumes that math, kern and glue nodes have the same size,
1174
this is why both are synchronized.
1175
{\sl In fine}, only horizontal lists are really used in {\sl Sync\TeX},
1176
but all box nodes are considered the same with respect to synchronization,
1177
because a box node type is allowed to change at execution time.
1180
The {\sl Sync\TeX} code is very close to the memory model.
1181
It is not connected to any other part of the code,
1182
except for memory management. It is possible to neutralize the {\sl Sync\TeX} code
1183
rather simply. The first step is to define a null |synctex_field_size|.
1184
The second step is to comment out the code in ``Initialize bigger nodes...'' and every
1185
``Copy ... {\sl Sync\TeX} information''.
1186
The last step will be to comment out the |synctex_tag_field| related code in the
1187
definition of |synctex_tag| and the various ``Prepare ... {\sl Sync\TeX} information''.
1188
Then all the remaining code should be just harmless.
1189
The resulting program would behave exactly the same as if absolutely no {\sl Sync\TeX}
1190
related code was there, including memory management.
1191
Of course, all this assumes that {\sl Sync\TeX} is turned off from the command line.
1197
Here are extra variables for Web2c. (This numbering of the
1198
system-dependent section allows easy integration of Web2c and e-\TeX, etc.)
1199
@^<system dependencies@>
1202
pool_pointer edit_name_start; /* where the filename to switch to starts */
1203
int edit_name_length, edit_line; /* what line to start editing at */
1204
int ipcon; /* level of IPC action, 0 for none [default] */
1205
boolean stop_at_space; /* whether |more_name| returns false for space */
1208
The |edit_name_start| will be set to point into |str_pool| somewhere after
1209
its beginning if \TeX\ is supposed to switch to an editor on exit.
1213
int restrictedshell;
1214
char *output_comment;
1216
/* Are we printing extra info as we read the format file? */
1218
boolean debug_format_file;