~ubuntu-branches/ubuntu/wily/luatex/wily

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/tex/extensions.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2010-04-29 00:47:19 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100429004719-o42etkqe90n97b9e
Tags: 0.60.1-1
* new upstream release, adapt build-script patch
* disable patch: upstream-epstopdf_cc_no_xpdf_patching, included upstream
* disable patch: libpoppler-0.12, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* extensions.c
2
 
 
3
 
   Copyright 2009 Taco Hoekwater <taco@luatex.org>
4
 
 
5
 
   This file is part of LuaTeX.
6
 
 
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.
11
 
 
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.
16
 
 
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/>. */
19
 
 
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 $";
23
 
 
24
 
#include <ptexlib.h>
25
 
 
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
31
 
 
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))
38
 
 
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)
43
 
 
44
 
/*
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.
53
 
 
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
60
 
could add them.
61
 
 
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@>
78
 
 
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.
85
 
 
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.
95
 
*/
96
 
 
97
 
/*
98
 
Extensions might introduce new command codes; but it's best to use
99
 
|extension| with a modifier, whenever possible, so that |main_control|
100
 
stays the same.
101
 
*/
102
 
 
103
 
 
104
 
/*
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|.
110
 
*/
111
 
 
112
 
alpha_file write_file[16];
113
 
halfword write_file_mode[16];
114
 
halfword write_file_translation[16];
115
 
boolean write_open[18];
116
 
scaled neg_wd;
117
 
scaled pos_wd;
118
 
scaled neg_ht;
119
 
 
120
 
/*
121
 
The variable |write_loc| just introduced is used to provide an
122
 
appropriate error message in case of ``runaway'' write texts.
123
 
*/
124
 
 
125
 
halfword write_loc;             /* |eqtb| address of \.{\\write} */
126
 
 
127
 
/*
128
 
When an |extension| command occurs in |main_control|, in any mode,
129
 
the |do_extension| routine is called.
130
 
*/
131
 
 
132
 
void do_extension(PDF pdf)
133
 
{
134
 
    int i, k;                   /* all-purpose integers */
135
 
    halfword p;                 /* all-purpose pointer */
136
 
    switch (cur_chr) {
137
 
    case open_node:
138
 
        /* Implement \.{\\openout} */
139
 
        new_write_whatsit(open_node_size);
140
 
        scan_optional_equals();
141
 
        scan_file_name();
142
 
        open_name(tail) = cur_name;
143
 
        open_area(tail) = cur_area;
144
 
        open_ext(tail) = cur_ext;
145
 
        break;
146
 
    case write_node:
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. */
151
 
        k = cur_cs;
152
 
        new_write_whatsit(write_node_size);
153
 
        cur_cs = k;
154
 
        p = scan_toks(false, false);
155
 
        write_tokens(tail) = def_ref;
156
 
        break;
157
 
    case close_node:
158
 
        /* Implement \.{\\closeout} */
159
 
        new_write_whatsit(write_node_size);
160
 
        write_tokens(tail) = null;
161
 
        break;
162
 
    case special_node:
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;
170
 
        break;
171
 
    case immediate_code:
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}@>
181
 
 
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}'.
185
 
           @^recursion@>
186
 
         */
187
 
        get_x_token();
188
 
        if (cur_cmd == extension_cmd) {
189
 
            if (cur_chr <= close_node) {
190
 
                p = tail;
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);
195
 
                tail = p;
196
 
                vlink(p) = null;
197
 
            } else {
198
 
                switch (cur_chr) {
199
 
                case pdf_obj_code:
200
 
                    check_o_mode(pdf, "\\immediate\\pdfobj", 1 << OMODE_PDF,
201
 
                                 true);
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 */
204
 
                        pdf_error("ext1",
205
 
                                  "`\\pdfobj reserveobjnum' cannot be used with \\immediate");
206
 
                    pdf_write_obj(pdf, pdf_last_obj);
207
 
                    break;
208
 
                case pdf_xform_code:
209
 
                    check_o_mode(pdf, "\\immediate\\pdfxform", 1 << OMODE_PDF,
210
 
                                 true);
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);
214
 
                    break;
215
 
                case pdf_ximage_code:
216
 
                    check_o_mode(pdf, "\\immediate\\pdfximage", 1 << OMODE_PDF,
217
 
                                 true);
218
 
                    do_extension(pdf);  /* scan image and set |pdf_last_ximage| */
219
 
                    pdf_write_image(pdf, pdf_last_ximage);
220
 
                    break;
221
 
                default:
222
 
                    back_input();
223
 
                    break;
224
 
                }
225
 
            }
226
 
        } else {
227
 
            back_input();
228
 
        }
229
 
        break;
230
 
    case pdf_annot_node:
231
 
        /* Implement \.{\\pdfannot} */
232
 
        check_o_mode(pdf, "\\pdfannot", 1 << OMODE_PDF, false);
233
 
        scan_annot(pdf);
234
 
        break;
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);
239
 
        break;
240
 
    case pdf_dest_node:
241
 
        /* Implement \.{\\pdfdest} */
242
 
        check_o_mode(pdf, "\\pdfdest", 1 << OMODE_PDF, false);
243
 
        scan_pdfdest(pdf);
244
 
        break;
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);
251
 
        break;
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);
256
 
        break;
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);
265
 
        scan_font_ident();
266
 
        k = cur_val;
267
 
        if (k == null_font)
268
 
            pdf_error("font", "invalid font identifier");
269
 
        scan_pdf_ext_toks();
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);
274
 
        }
275
 
        break;
276
 
    case pdf_font_expand_code:
277
 
        /* Implement \.{\\pdffontexpand} */
278
 
        read_expand_font();
279
 
        break;
280
 
    case pdf_include_chars_code:
281
 
        /* Implement \.{\\pdfincludechars} */
282
 
        check_o_mode(pdf, "\\pdfincludechars", 1 << OMODE_PDF, false);
283
 
        pdf_include_chars(pdf);
284
 
        break;
285
 
    case pdf_info_code:
286
 
        /* Implement \.{\\pdfinfo} */
287
 
        check_o_mode(pdf, "\\pdfinfo", 1 << OMODE_PDF, false);
288
 
        scan_pdf_ext_toks();
289
 
        pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
290
 
        break;
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);
299
 
        else
300
 
            set_pdf_literal_mode(tail, set_origin);
301
 
        scan_pdf_ext_toks();
302
 
        set_pdf_literal_type(tail, normal);
303
 
        set_pdf_literal_data(tail, def_ref);
304
 
        break;
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| */
309
 
        scan_int();
310
 
        if (cur_val >= colorstackused()) {
311
 
            print_err("Unknown color stack number ");
312
 
            print_int(cur_val);
313
 
            help3
314
 
                ("Allocate and initialize a color stack with \\pdfcolorstackinit.",
315
 
                 "I'll use default color stack 0 here.",
316
 
                 "Proceed, with fingers crossed.");
317
 
            error();
318
 
            cur_val = 0;
319
 
        }
320
 
        if (cur_val < 0) {
321
 
            print_err("Invalid negative color stack number");
322
 
            help2("I'll use default color stack 0 here.",
323
 
                  "Proceed, with fingers crossed.");
324
 
            error();
325
 
            cur_val = 0;
326
 
        }
327
 
        if (scan_keyword("set"))
328
 
            i = colorstack_set;
329
 
        else if (scan_keyword("push"))
330
 
            i = colorstack_push;
331
 
        else if (scan_keyword("pop"))
332
 
            i = colorstack_pop;
333
 
        else if (scan_keyword("current"))
334
 
            i = colorstack_current;
335
 
        else
336
 
            i = -1;             /* error */
337
 
 
338
 
        if (i >= 0) {
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) {
344
 
                scan_pdf_ext_toks();
345
 
                set_pdf_colorstack_data(tail, def_ref);
346
 
            }
347
 
        } else {
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.");
352
 
            error();
353
 
        }
354
 
        break;
355
 
    case pdf_setmatrix_node:
356
 
        /* Implement \.{\\pdfsetmatrix} */
357
 
        check_o_mode(pdf, "\\pdfsetmatrix", 1 << OMODE_PDF, false);
358
 
        new_whatsit(pdf_setmatrix_node);
359
 
        scan_pdf_ext_toks();
360
 
        set_pdf_setmatrix_data(tail, def_ref);
361
 
        break;
362
 
    case pdf_save_node:
363
 
        /* Implement \.{\\pdfsave} */
364
 
        check_o_mode(pdf, "\\pdfsave", 1 << OMODE_PDF, false);
365
 
        new_whatsit(pdf_save_node);
366
 
        break;
367
 
    case pdf_restore_node:
368
 
        /* Implement \.{\\pdfrestore} */
369
 
        check_o_mode(pdf, "\\pdfrestore", 1 << OMODE_PDF, false);
370
 
        new_whatsit(pdf_restore_node);
371
 
        break;
372
 
    case pdf_map_file_code:
373
 
        /* Implement \.{\\pdfmapfile} */
374
 
        check_o_mode(pdf, "\\pdfmapfile", 1 << OMODE_PDF, false);
375
 
        scan_pdf_ext_toks();
376
 
        pdfmapfile(def_ref);
377
 
        delete_token_ref(def_ref);
378
 
        break;
379
 
    case pdf_map_line_code:
380
 
        /* Implement \.{\\pdfmapline} */
381
 
        check_o_mode(pdf, "\\pdfmapline", 1 << OMODE_PDF, false);
382
 
        scan_pdf_ext_toks();
383
 
        pdfmapline(def_ref);
384
 
        delete_token_ref(def_ref);
385
 
        break;
386
 
    case pdf_names_code:
387
 
        /* Implement \.{\\pdfnames} */
388
 
        check_o_mode(pdf, "\\pdfnames", 1 << OMODE_PDF, false);
389
 
        scan_pdf_ext_toks();
390
 
        pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
391
 
        break;
392
 
    case pdf_obj_code:
393
 
        /* Implement \.{\\pdfobj} */
394
 
        check_o_mode(pdf, "\\pdfobj", 1 << OMODE_PDF, false);
395
 
        scan_obj(pdf);
396
 
        break;
397
 
    case pdf_outline_code:
398
 
        /* Implement \.{\\pdfoutline} */
399
 
        check_o_mode(pdf, "\\pdfoutline", 1 << OMODE_PDF, true);
400
 
        scan_pdfoutline(pdf);
401
 
        break;
402
 
    case pdf_refobj_node:
403
 
        /* Implement \.{\\pdfrefobj} */
404
 
        check_o_mode(pdf, "\\pdfrefobj", 1 << OMODE_PDF, false);
405
 
        scan_refobj(pdf);
406
 
        break;
407
 
    case pdf_refxform_node:
408
 
        /* Implement \.{\\pdfrefxform} */
409
 
        check_o_mode(pdf, "\\pdfrefxform", 1 << OMODE_PDF, false);
410
 
        scan_pdfrefxform(pdf);
411
 
        break;
412
 
    case pdf_refximage_node:
413
 
        /* Implement \.{\\pdfrefximage} */
414
 
        check_o_mode(pdf, "\\pdfrefximage", 1 << OMODE_PDF, false);
415
 
        scan_pdfrefximage(pdf);
416
 
        break;
417
 
    case pdf_save_pos_node:
418
 
        /* Implement \.{\\pdfsavepos} */
419
 
        new_whatsit(pdf_save_pos_node);
420
 
        break;
421
 
    case pdf_start_link_node:
422
 
        /* Implement \.{\\pdfstartlink} */
423
 
        check_o_mode(pdf, "\\pdfstartlink", 1 << OMODE_PDF, false);
424
 
        scan_startlink(pdf);
425
 
        break;
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);
430
 
        scan_thread_id();
431
 
        break;
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);
436
 
        scan_thread_id();
437
 
        break;
438
 
    case pdf_trailer_code:
439
 
        /* Implement \.{\\pdftrailer} */
440
 
        check_o_mode(pdf, "\\pdftrailer", 1 << OMODE_PDF, false);
441
 
        scan_pdf_ext_toks();
442
 
        pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
443
 
        break;
444
 
    case pdf_xform_code:
445
 
        /* Implement \.{\\pdfxform} */
446
 
        check_o_mode(pdf, "\\pdfxform", 1 << OMODE_PDF, false);
447
 
        scan_pdfxform(pdf);
448
 
        break;
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);
454
 
        scan_pdfximage(pdf);
455
 
        break;
456
 
    case save_cat_code_table_code:
457
 
        /* Implement \.{\\savecatcodetable} */
458
 
        scan_int();
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");
462
 
            error();
463
 
        } else {
464
 
            if (cur_val == cat_code_table) {
465
 
                print_err("Invalid \\catcode table");
466
 
                help1("You cannot overwrite the current \\catcode table");
467
 
                error();
468
 
            } else {
469
 
                copy_cat_codes(cat_code_table, cur_val);
470
 
            }
471
 
        }
472
 
        break;
473
 
    case init_cat_code_table_code:
474
 
        /* Implement \.{\\initcatcodetable} */
475
 
        scan_int();
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");
479
 
            error();
480
 
        } else {
481
 
            if (cur_val == cat_code_table) {
482
 
                print_err("Invalid \\catcode table");
483
 
                help1("You cannot overwrite the current \\catcode table");
484
 
                error();
485
 
            } else {
486
 
                initex_cat_codes(cur_val);
487
 
            }
488
 
        }
489
 
        break;
490
 
    case set_random_seed_code:
491
 
        /* Implement \.{\\pdfsetrandomseed} */
492
 
        /*  Negative random seed values are silently converted to positive ones */
493
 
        scan_int();
494
 
        if (cur_val < 0)
495
 
            negate(cur_val);
496
 
        random_seed = cur_val;
497
 
        init_randoms(random_seed);
498
 
        break;
499
 
    case pdf_glyph_to_unicode_code:
500
 
        /* Implement \.{\\pdfglyphtounicode} */
501
 
        glyph_to_unicode();
502
 
        break;
503
 
    case late_lua_node:
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;
509
 
        break;
510
 
    default:
511
 
        confusion("ext1");
512
 
        break;
513
 
    }
514
 
}
515
 
 
516
 
/*
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.
520
 
*/
521
 
 
522
 
void new_whatsit(int s)
523
 
{
524
 
    halfword p;                 /* the new node */
525
 
    p = new_node(whatsit_node, s);
526
 
    couple_nodes(tail, p);
527
 
    tail = p;
528
 
}
529
 
 
530
 
/*
531
 
The next subroutine uses |cur_chr| to decide what sort of whatsit is
532
 
involved, and also inserts a |write_stream| number.
533
 
*/
534
 
 
535
 
void new_write_whatsit(int w)
536
 
{
537
 
    new_whatsit(cur_chr);
538
 
    if (w != write_node_size) {
539
 
        scan_four_bit_int();
540
 
    } else {
541
 
        scan_int();
542
 
        if (cur_val < 0)
543
 
            cur_val = 17;
544
 
        else if ((cur_val > 15) && (cur_val != 18))
545
 
            cur_val = 16;
546
 
    }
547
 
    write_stream(tail) = cur_val;
548
 
}
549
 
 
550
 
/*
551
 
  We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
552
 
  extensions.
553
 
*/
554
 
 
555
 
void scan_pdf_ext_toks(void)
556
 
{
557
 
    (void) scan_toks(false, true);      /* like \.{\\special} */
558
 
}
559
 
 
560
 
/*  We need to check whether the referenced object exists. */
561
 
 
562
 
/* finds the node preceding the rightmost node |e|; |s| is some node before |e| */
563
 
halfword prev_rightmost(halfword s, halfword e)
564
 
{
565
 
    halfword p = s;
566
 
    if (p == null)
567
 
        return null;
568
 
    while (vlink(p) != e) {
569
 
        p = vlink(p);
570
 
        if (p == null)
571
 
            return null;
572
 
    }
573
 
    return p;
574
 
}
575
 
 
576
 
/* \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
577
 
  \.{\\pdfrefobj}
578
 
*/
579
 
 
580
 
int pdf_last_xform;
581
 
 
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>|.
585
 
*/
586
 
 
587
 
int pdf_last_ximage;
588
 
int pdf_last_ximage_pages;
589
 
int pdf_last_ximage_colordepth;
590
 
int pdf_last_annot;
591
 
 
592
 
/* pdflastlink needs an extra global variable */
593
 
 
594
 
int pdf_last_link;
595
 
scaledpos pdf_last_pos = { 0, 0 };
596
 
 
597
 
/*
598
 
To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
599
 
\.{\\pdfnames} we need to concatenate tokens lists.
600
 
*/
601
 
 
602
 
halfword concat_tokens(halfword q, halfword r)
603
 
{                               /* concat |q| and |r| and returns the result tokens list */
604
 
    halfword p;
605
 
    if (q == null)
606
 
        return r;
607
 
    p = q;
608
 
    while (token_link(p) != null)
609
 
        p = token_link(p);
610
 
    set_token_link(p, token_link(r));
611
 
    free_avail(r);
612
 
    return q;
613
 
}
614
 
 
615
 
int pdf_retval;                 /* global multi-purpose return value */
616
 
 
617
 
 
618
 
halfword make_local_par_node(void)
619
 
/* This function creates a |local_paragraph| node */
620
 
{
621
 
    halfword p, q;
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);
629
 
    }
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);
634
 
    }
635
 
    local_par_dir(p) = par_direction;
636
 
    return p;
637
 
}
638
 
 
639
 
 
640
 
/*
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
648
 
that integer.
649
 
*/
650
 
 
651
 
/*
652
 
In order to handle \.{\\everyeof} we need an array |eof_seen| of
653
 
boolean variables.
654
 
*/
655
 
 
656
 
boolean *eof_seen;              /* has eof been seen? */
657
 
 
658
 
/*
659
 
The |print_group| procedure prints the current level of grouping and
660
 
the name corresponding to |cur_group|.
661
 
*/
662
 
 
663
 
void print_group(boolean e)
664
 
{
665
 
    switch (cur_group) {
666
 
    case bottom_level:
667
 
        tprint("bottom level");
668
 
        return;
669
 
        break;
670
 
    case simple_group:
671
 
    case semi_simple_group:
672
 
        if (cur_group == semi_simple_group)
673
 
            tprint("semi ");
674
 
        tprint("simple");
675
 
        break;;
676
 
    case hbox_group:
677
 
    case adjusted_hbox_group:
678
 
        if (cur_group == adjusted_hbox_group)
679
 
            tprint("adjusted ");
680
 
        tprint("hbox");
681
 
        break;
682
 
    case vbox_group:
683
 
        tprint("vbox");
684
 
        break;
685
 
    case vtop_group:
686
 
        tprint("vtop");
687
 
        break;
688
 
    case align_group:
689
 
    case no_align_group:
690
 
        if (cur_group == no_align_group)
691
 
            tprint("no ");
692
 
        tprint("align");
693
 
        break;
694
 
    case output_group:
695
 
        tprint("output");
696
 
        break;
697
 
    case disc_group:
698
 
        tprint("disc");
699
 
        break;
700
 
    case insert_group:
701
 
        tprint("insert");
702
 
        break;
703
 
    case vcenter_group:
704
 
        tprint("vcenter");
705
 
        break;
706
 
    case math_group:
707
 
    case math_choice_group:
708
 
    case math_shift_group:
709
 
    case math_left_group:
710
 
        tprint("math");
711
 
        if (cur_group == math_choice_group)
712
 
            tprint(" choice");
713
 
        else if (cur_group == math_shift_group)
714
 
            tprint(" shift");
715
 
        else if (cur_group == math_left_group)
716
 
            tprint(" left");
717
 
        break;
718
 
    }                           /* there are no other cases */
719
 
    tprint(" group (level ");
720
 
    print_int(cur_level);
721
 
    print_char(')');
722
 
    if (saved_value(-1) != 0) { /* saved_line */
723
 
        if (e)
724
 
            tprint(" entered at line ");
725
 
        else
726
 
            tprint(" at line ");
727
 
        print_int(saved_value(-1));     /* saved_line */
728
 
    }
729
 
}
730
 
 
731
 
/*
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
734
 
line number.
735
 
*/
736
 
 
737
 
void group_trace(boolean e)
738
 
{
739
 
    begin_diagnostic();
740
 
    print_char('{');
741
 
    if (e)
742
 
        tprint("leaving ");
743
 
    else
744
 
        tprint("entering ");
745
 
    print_group(e);
746
 
    print_char('}');
747
 
    end_diagnostic(false);
748
 
}
749
 
 
750
 
/*
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.
757
 
*/
758
 
 
759
 
save_pointer *grp_stack;        /* initial |cur_boundary| */
760
 
halfword *if_stack;             /* initial |cond_ptr| */
761
 
 
762
 
/*
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|.
772
 
*/
773
 
 
774
 
void group_warning(void)
775
 
{
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 */
780
 
    i = in_open;
781
 
    w = false;
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))
789
 
                decr(base_ptr);
790
 
            if (input_stack[base_ptr].name_field > 17)
791
 
                w = true;
792
 
        }
793
 
 
794
 
        grp_stack[i] = save_value(save_ptr);
795
 
        decr(i);
796
 
    }
797
 
    if (w) {
798
 
        tprint_nl("Warning: end of ");
799
 
        print_group(true);
800
 
        tprint(" of a different file");
801
 
        print_ln();
802
 
        if (tracing_nesting > 1)
803
 
            show_context();
804
 
        if (history == spotless)
805
 
            history = warning_issued;
806
 
    }
807
 
}
808
 
 
809
 
/*
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).
814
 
*/
815
 
 
816
 
void if_warning(void)
817
 
{
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 */
822
 
    i = in_open;
823
 
    w = false;
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))
829
 
                decr(base_ptr);
830
 
            if (input_stack[base_ptr].name_field > 17)
831
 
                w = true;
832
 
        }
833
 
 
834
 
        if_stack[i] = vlink(cond_ptr);
835
 
        decr(i);
836
 
    }
837
 
    if (w) {
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");
842
 
        print_ln();
843
 
        if (tracing_nesting > 1)
844
 
            show_context();
845
 
        if (history == spotless)
846
 
            history = warning_issued;
847
 
    }
848
 
}
849
 
 
850
 
/*
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.
854
 
*/
855
 
 
856
 
void file_warning(void)
857
 
{
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| */
862
 
    p = save_ptr;
863
 
    l = cur_level;
864
 
    c = cur_group;
865
 
    save_ptr = cur_boundary;
866
 
    while (grp_stack[in_open] != save_ptr) {
867
 
        decr(cur_level);
868
 
        tprint_nl("Warning: end of file when ");
869
 
        print_group(true);
870
 
        tprint(" is incomplete");
871
 
        cur_group = save_level(save_ptr);
872
 
        save_ptr = save_value(save_ptr);
873
 
    }
874
 
    save_ptr = p;
875
 
    cur_level = l;
876
 
    cur_group = c;              /* restore old values */
877
 
    p = cond_ptr;
878
 
    l = if_limit;
879
 
    c = cur_if;
880
 
    i = if_line;
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)
885
 
            tprint_esc("else");
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);
892
 
    }
893
 
    cond_ptr = p;
894
 
    if_limit = l;
895
 
    cur_if = c;
896
 
    if_line = i;                /* restore old values */
897
 
    print_ln();
898
 
    if (tracing_nesting > 1)
899
 
        show_context();
900
 
    if (history == spotless)
901
 
        history = warning_issued;
902
 
}
903
 
 
904
 
halfword last_line_fill;        /* the |par_fill_skip| glue node of the new paragraph */
905
 
 
906
 
/*
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.
911
 
*/
912
 
 
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)
918
 
 
919
 
int set_tex_dimen_register(int j, scaled v)
920
 
{
921
 
    int a;                      /* return non-nil for error */
922
 
    if (global_defs > 0)
923
 
        a = 4;
924
 
    else
925
 
        a = 0;
926
 
    word_define(j + scaled_base, v);
927
 
    return 0;
928
 
}
929
 
 
930
 
int set_tex_skip_register(int j, halfword v)
931
 
{
932
 
    int a;                      /* return non-nil for error */
933
 
    if (global_defs > 0)
934
 
        a = 4;
935
 
    else
936
 
        a = 0;
937
 
    if (type(v) != glue_spec_node)
938
 
        return 1;
939
 
    word_define(j + skip_base, v);
940
 
    return 0;
941
 
}
942
 
 
943
 
int set_tex_count_register(int j, scaled v)
944
 
{
945
 
    int a;                      /* return non-nil for error */
946
 
    if (global_defs > 0)
947
 
        a = 4;
948
 
    else
949
 
        a = 0;
950
 
    word_define(j + count_base, v);
951
 
    return 0;
952
 
}
953
 
 
954
 
int set_tex_box_register(int j, scaled v)
955
 
{
956
 
    int a;                      /* return non-nil for error */
957
 
    if (global_defs > 0)
958
 
        a = 4;
959
 
    else
960
 
        a = 0;
961
 
    define(j + box_base, box_ref_cmd, v);
962
 
    return 0;
963
 
}
964
 
 
965
 
int set_tex_attribute_register(int j, scaled v)
966
 
{
967
 
    int a;                      /* return non-nil for error */
968
 
    if (global_defs > 0)
969
 
        a = 4;
970
 
    else
971
 
        a = 0;
972
 
    if (j > max_used_attr)
973
 
        max_used_attr = j;
974
 
    attr_list_cache = cache_disabled;
975
 
    word_define(j + attribute_base, v);
976
 
    return 0;
977
 
}
978
 
 
979
 
int get_tex_toks_register(int j)
980
 
{
981
 
    str_number s;
982
 
    s = get_nullstr();
983
 
    if (toks(j) != null) {
984
 
        s = tokens_to_string(toks(j));
985
 
    }
986
 
    return s;
987
 
}
988
 
 
989
 
int set_tex_toks_register(int j, lstring s)
990
 
{
991
 
    halfword ref;
992
 
    int a;
993
 
    ref = get_avail();
994
 
    (void) str_toks(s);
995
 
    set_token_ref_count(ref, 0);
996
 
    set_token_link(ref, token_link(temp_token_head));
997
 
    if (global_defs > 0)
998
 
        a = 4;
999
 
    else
1000
 
        a = 0;
1001
 
    define(j + toks_base, call_cmd, ref);
1002
 
    return 0;
1003
 
}
1004
 
 
1005
 
scaled get_tex_box_width(int j)
1006
 
{
1007
 
    halfword q = box(j);
1008
 
    if (q != null)
1009
 
        return width(q);
1010
 
    return 0;
1011
 
}
1012
 
 
1013
 
int set_tex_box_width(int j, scaled v)
1014
 
{
1015
 
    halfword q = box(j);
1016
 
    if (q == null)
1017
 
        return 1;
1018
 
    width(q) = v;
1019
 
    return 0;
1020
 
}
1021
 
 
1022
 
scaled get_tex_box_height(int j)
1023
 
{
1024
 
    halfword q = box(j);
1025
 
    if (q != null)
1026
 
        return height(q);
1027
 
    return 0;
1028
 
}
1029
 
 
1030
 
int set_tex_box_height(int j, scaled v)
1031
 
{
1032
 
    halfword q = box(j);
1033
 
    if (q == null)
1034
 
        return 1;
1035
 
    height(q) = v;
1036
 
    return 0;
1037
 
}
1038
 
 
1039
 
 
1040
 
scaled get_tex_box_depth(int j)
1041
 
{
1042
 
    halfword q = box(j);
1043
 
    if (q != null)
1044
 
        return depth(q);
1045
 
    return 0;
1046
 
}
1047
 
 
1048
 
int set_tex_box_depth(int j, scaled v)
1049
 
{
1050
 
    halfword q = box(j);
1051
 
    if (q == null)
1052
 
        return 1;
1053
 
    depth(q) = v;
1054
 
    return 0;
1055
 
}
1056
 
 
1057
 
/*
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.
1063
 
 
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.
1073
 
 
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.
1081
 
 
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.
1087
 
*/
1088
 
 
1089
 
int synctexoption;
1090
 
 
1091
 
/*
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.
1098
 
 
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.
1104
 
*/
1105
 
 
1106
 
int synctexoffset;              /* holds the true value of |synctex_code| */
1107
 
 
1108
 
/*
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.
1116
 
 
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.
1127
 
 
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.
1133
 
 
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.
1144
 
 
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.
1150
 
 
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.
1160
 
 
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.
1169
 
 
1170
 
 
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.
1178
 
 
1179
 
@ {\sl Nota Bene:}
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.
1192
 
@^synctex@>
1193
 
@^synchronization@>
1194
 
*/
1195
 
 
1196
 
/*
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@>
1200
 
*/
1201
 
 
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 */
1206
 
 
1207
 
/*
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.
1210
 
*/
1211
 
 
1212
 
int shellenabledp;
1213
 
int restrictedshell;
1214
 
char *output_comment;
1215
 
 
1216
 
/* Are we printing extra info as we read the format file? */
1217
 
 
1218
 
boolean debug_format_file;