1% extensions.w
2%
3% Copyright 2009-2010 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\def\eTeX{e-\TeX}
21\def\pdfTeX{pdf\TeX}
22
23@ @c
24
25
26#include "ptexlib.h"
27
28@ @c
29#define mode          cur_list.mode_field
30#define tail          cur_list.tail_field
31#define head          cur_list.head_field
32#define prev_graf     cur_list.pg_field
33#define dir_save      cur_list.dirs_field
34
35#define tracing_nesting int_par(tracing_nesting_code)
36#define box(A) eqtb[box_base+(A)].hh.rh
37#define global_defs int_par(global_defs_code)
38#define cat_code_table int_par(cat_code_table_code)
39#define par_direction int_par(par_direction_code)
40#define toks(A) equiv(toks_base+(A))
41
42#define local_inter_line_penalty int_par(local_inter_line_penalty_code)
43#define local_broken_penalty int_par(local_broken_penalty_code)
44#define local_left_box equiv(local_left_box_base)
45#define local_right_box equiv(local_right_box_base)
46
47
48@ The program above includes a bunch of ``hooks'' that allow further
49capabilities to be added without upsetting \TeX's basic structure.
50Most of these hooks are concerned with ``whatsit'' nodes, which are
51intended to be used for special purposes; whenever a new extension to
52\TeX\ involves a new kind of whatsit node, a corresponding change needs
53to be made to the routines below that deal with such nodes,
54but it will usually be unnecessary to make many changes to the
55other parts of this program.
56
57In order to demonstrate how extensions can be made, we shall treat
58`\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
59and `\.{\\special}' as if they were extensions.
60These commands are actually primitives of \TeX, and they should
61appear in all implementations of the system; but let's try to imagine
62that they aren't. Then the program below illustrates how a person
63could add them.
64
65Sometimes, of course, an extension will require changes to \TeX\ itself;
66no system of hooks could be complete enough for all conceivable extensions.
67The features associated with `\.{\\write}' are almost all confined to the
68following paragraphs, but there are small parts of the |print_ln| and
69|print_char| procedures that were introduced specifically to \.{\\write}
70characters. Furthermore one of the token lists recognized by the scanner
71is a |write_text|; and there are a few other miscellaneous places where we
72have already provided for some aspect of \.{\\write}.  The goal of a \TeX\
73extender should be to minimize alterations to the standard parts of the
74program, and to avoid them completely if possible. He or she should also
75be quite sure that there's no easy way to accomplish the desired goals
76with the standard features that \TeX\ already has. ``Think thrice before
77extending,'' because that may save a lot of work, and it will also keep
78incompatible extensions of \TeX\ from proliferating.
79@^system dependencies@>
80@^extensions to \TeX@>
81
82First let's consider the format of whatsit nodes that are used to represent
83the data associated with \.{\\write} and its relatives. Recall that a whatsit
84has |type=whatsit_node|, and the |subtype| is supposed to distinguish
85different kinds of whatsits. Each node occupies two or more words; the
86exact number is immaterial, as long as it is readily determined from the
87|subtype| or other data.
88
89We shall introduce five |subtype| values here, corresponding to the
90control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}.
91The second word of I/O whatsits has a |write_stream| field
92that identifies the write-stream number (0 to 15, or 16 for out-of-range and
93positive, or 17 for out-of-range and negative).
94In the case of \.{\\write} and \.{\\special}, there is also a field that
95points to the reference count of a token list that should be sent. In the
96case of \.{\\openout}, we need three words and three auxiliary subfields
97to hold the string numbers for name, area, and extension.
98
99@ Extensions might introduce new command codes; but it's best to use
100|extension| with a modifier, whenever possible, so that |main_control|
101stays the same.
102
103@ The sixteen possible \.{\\write} streams are represented by the |write_file|
104array. The |j|th file is open if and only if |write_open[j]=true|. The last
105two streams are special; |write_open[16]| represents a stream number
106greater than 15, while |write_open[17]| represents a negative stream number,
107and both of these variables are always |false|.
108
109@c
110alpha_file write_file[16];
111halfword write_file_mode[16];
112halfword write_file_translation[16];
113boolean write_open[18];
114scaled neg_wd;
115scaled pos_wd;
116scaled neg_ht;
117
118
119@ The variable |write_loc| just introduced is used to provide an
120appropriate error message in case of ``runaway'' write texts.
121
122@c
123halfword write_loc;             /* |eqtb| address of \.{\\write} */
124
125
126@ When an |extension| command occurs in |main_control|, in any mode,
127the |do_extension| routine is called.
128
129@c
130void do_extension(PDF pdf)
131{
132    int i, k;                   /* all-purpose integers */
133    halfword p;                 /* all-purpose pointer */
134    switch (cur_chr) {
135    case open_node:
136        /* Implement \.{\\openout} */
137        new_write_whatsit(open_node_size);
138        scan_optional_equals();
139        scan_file_name();
140        open_name(tail) = cur_name;
141        open_area(tail) = cur_area;
142        open_ext(tail) = cur_ext;
143        break;
144    case write_node:
145        /* Implement \.{\\write} */
146        /* When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
147           without expanding its macros; the macros will be expanded later when this
148           token list is rescanned. */
149        k = cur_cs;
150        new_write_whatsit(write_node_size);
151        cur_cs = k;
152        p = scan_toks(false, false);
153        write_tokens(tail) = def_ref;
154        break;
155    case close_node:
156        /* Implement \.{\\closeout} */
157        new_write_whatsit(write_node_size);
158        write_tokens(tail) = null;
159        break;
160    case special_node:
161        /* Implement \.{\\special} */
162        /* When `\.{\\special\{...\}}' appears, we expand the macros in the token
163           list as in \.{\\xdef} and \.{\\mark}. */
164        new_whatsit(special_node);
165        write_stream(tail) = null;
166        p = scan_toks(false, true);
167        write_tokens(tail) = def_ref;
168        break;
169    case immediate_code:
170        /* Implement \.{\\immediate} */
171        /* To write a token list, we must run it through \TeX's scanner, expanding
172           macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
173           if a delimited macro parameter isn't matched, and runaways would be
174           extremely confusing since we are calling on \TeX's scanner in the middle
175           of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
176           a ``stopper,'' right after the token list. This control sequence is
177           artificially defined to be \.{\\outer}.
178
179           The presence of `\.{\\immediate}' causes the |do_extension| procedure
180           to descend to one level of recursion. Nothing happens unless \.{\\immediate}
181           is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
182         */
183        get_x_token();
184        if (cur_cmd == extension_cmd) {
185            if (cur_chr <= close_node) {
186                p = tail;
187                /* |do_extension()| and |out_what()| here can only be open, write, or close */
188                do_extension(pdf);      /* append a whatsit node */
189                out_what(pdf, tail);    /* do the action immediately */
190                flush_node_list(tail);
191                tail = p;
192                vlink(p) = null;
193            } else {
194                switch (cur_chr) {
195                case pdf_obj_code:
196                    check_o_mode(pdf, "\\immediate\\pdfobj", 1 << OMODE_PDF,
197                                 true);
198                    do_extension(pdf);  /* scan object and set |pdf_last_obj| */
199                    if (obj_data_ptr(pdf, pdf_last_obj) == 0)   /* this object has not been initialized yet */
200                        pdf_error("ext1",
201                                  "`\\pdfobj reserveobjnum' cannot be used with \\immediate");
202                    pdf_write_obj(pdf, pdf_last_obj);
203                    break;
204                case pdf_xform_code:
205                    check_o_mode(pdf, "\\immediate\\pdfxform", 1 << OMODE_PDF,
206                                 true);
207                    do_extension(pdf);  /* scan form and set |pdf_last_xform| */
208                    pdf_cur_form = pdf_last_xform;
209                    ship_out(pdf, obj_xform_box(pdf, pdf_last_xform), SHIPPING_FORM);
210                    break;
211                case pdf_ximage_code:
212                    check_o_mode(pdf, "\\immediate\\pdfximage", 1 << OMODE_PDF,
213                                 true);
214                    do_extension(pdf);  /* scan image and set |pdf_last_ximage| */
215                    pdf_write_image(pdf, pdf_last_ximage);
216                    break;
217                default:
218                    back_input();
219                    break;
220                }
221            }
222        } else {
223            back_input();
224        }
225        break;
226    case pdf_annot_node:
227        /* Implement \.{\\pdfannot} */
228        check_o_mode(pdf, "\\pdfannot", 1 << OMODE_PDF, false);
229        scan_annot(pdf);
230        break;
231    case pdf_catalog_code:
232        /* Implement \.{\\pdfcatalog} */
233        check_o_mode(pdf, "\\pdfcatalog", 1 << OMODE_PDF, true);        /* writes an object */
234        scan_pdfcatalog(pdf);
235        break;
236    case pdf_dest_node:
237        /* Implement \.{\\pdfdest} */
238        check_o_mode(pdf, "\\pdfdest", 1 << OMODE_PDF, false);
239        scan_pdfdest(pdf);
240        break;
241    case pdf_end_link_node:
242        /* Implement \.{\\pdfendlink} */
243        check_o_mode(pdf, "\\pdfendlink", 1 << OMODE_PDF, false);
244        if (abs(mode) == vmode)
245            pdf_error("ext1", "\\pdfendlink cannot be used in vertical mode");
246        new_whatsit(pdf_end_link_node);
247        break;
248    case pdf_end_thread_node:
249        /* Implement \.{\\pdfendthread} */
250        check_o_mode(pdf, "\\pdfendthread", 1 << OMODE_PDF, false);
251        new_whatsit(pdf_end_thread_node);
252        break;
253    case pdf_font_attr_code:
254        /* Implement \.{\\pdffontattr} */
255        /* A change from Thanh's original code: the font attributes are simply
256           initialized to zero now, this is easier to deal with from C than an
257           empty \TeX{} string, and surely nobody will want to set
258           \.{\\pdffontattr} to a string containing a single zero, as that
259           would be nonsensical in the PDF output. */
260        check_o_mode(pdf, "\\pdffontattr", 1 << OMODE_PDF, false);
261        scan_font_ident();
262        k = cur_val;
263        if (k == null_font)
264            pdf_error("font", "invalid font identifier");
265        scan_pdf_ext_toks();
266        set_pdf_font_attr(k, tokens_to_string(def_ref));
267        if (str_length(pdf_font_attr(k)) == 0) {
268            flush_str((str_ptr - 1));   /* from |tokens_to_string| */
269            set_pdf_font_attr(k, 0);
270        }
271        break;
272    case pdf_font_expand_code:
273        /* Implement \.{\\pdffontexpand} */
274        read_expand_font();
275        break;
276    case pdf_include_chars_code:
277        /* Implement \.{\\pdfincludechars} */
278        check_o_mode(pdf, "\\pdfincludechars", 1 << OMODE_PDF, false);
279        pdf_include_chars(pdf);
280        break;
281    case pdf_info_code:
282        /* Implement \.{\\pdfinfo} */
283        check_o_mode(pdf, "\\pdfinfo", 1 << OMODE_PDF, false);
284        scan_pdf_ext_toks();
285        pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
286        break;
287    case pdf_literal_node:
288        /* Implement \.{\\pdfliteral} */
289        check_o_mode(pdf, "\\pdfliteral", 1 << OMODE_PDF, false);
290        new_whatsit(pdf_literal_node);
291        if (scan_keyword("direct"))
292            set_pdf_literal_mode(tail, direct_always);
293        else if (scan_keyword("page"))
294            set_pdf_literal_mode(tail, direct_page);
295        else
296            set_pdf_literal_mode(tail, set_origin);
297        scan_pdf_ext_toks();
298        set_pdf_literal_type(tail, normal);
299        set_pdf_literal_data(tail, def_ref);
300        break;
301    case pdf_colorstack_node:
302        /* Implement \.{\\pdfcolorstack} */
303        check_o_mode(pdf, "\\pdfcolorstack", 1 << OMODE_PDF, false);
304        /* Scan and check the stack number and store in |cur_val| */
305        scan_int();
306        if (cur_val >= colorstackused()) {
307            print_err("Unknown color stack number ");
308            print_int(cur_val);
309            help3
310                ("Allocate and initialize a color stack with \\pdfcolorstackinit.",
311                 "I'll use default color stack 0 here.",
312                 "Proceed, with fingers crossed.");
313            error();
314            cur_val = 0;
315        }
316        if (cur_val < 0) {
317            print_err("Invalid negative color stack number");
318            help2("I'll use default color stack 0 here.",
319                  "Proceed, with fingers crossed.");
320            error();
321            cur_val = 0;
322        }
323        if (scan_keyword("set"))
324            i = colorstack_set;
325        else if (scan_keyword("push"))
326            i = colorstack_push;
327        else if (scan_keyword("pop"))
328            i = colorstack_pop;
329        else if (scan_keyword("current"))
330            i = colorstack_current;
331        else
332            i = -1;             /* error */
333
334        if (i >= 0) {
335            new_whatsit(pdf_colorstack_node);
336            set_pdf_colorstack_stack(tail, cur_val);
337            set_pdf_colorstack_cmd(tail, i);
338            set_pdf_colorstack_data(tail, null);
339            if (i <= colorstack_data) {
340                scan_pdf_ext_toks();
341                set_pdf_colorstack_data(tail, def_ref);
342            }
343        } else {
344            print_err("Color stack action is missing");
345            help3("The expected actions for \\pdfcolorstack:",
346                  "    set, push, pop, current",
347                  "I'll ignore the color stack command.");
348            error();
349        }
350        break;
351    case pdf_setmatrix_node:
352        /* Implement \.{\\pdfsetmatrix} */
353        check_o_mode(pdf, "\\pdfsetmatrix", 1 << OMODE_PDF, false);
354        new_whatsit(pdf_setmatrix_node);
355        scan_pdf_ext_toks();
356        set_pdf_setmatrix_data(tail, def_ref);
357        break;
358    case pdf_save_node:
359        /* Implement \.{\\pdfsave} */
360        check_o_mode(pdf, "\\pdfsave", 1 << OMODE_PDF, false);
361        new_whatsit(pdf_save_node);
362        break;
363    case pdf_restore_node:
364        /* Implement \.{\\pdfrestore} */
365        check_o_mode(pdf, "\\pdfrestore", 1 << OMODE_PDF, false);
366        new_whatsit(pdf_restore_node);
367        break;
368    case pdf_map_file_code:
369        /* Implement \.{\\pdfmapfile} */
370        check_o_mode(pdf, "\\pdfmapfile", 1 << OMODE_PDF, false);
371        scan_pdf_ext_toks();
372        pdfmapfile(def_ref);
373        delete_token_ref(def_ref);
374        break;
375    case pdf_map_line_code:
376        /* Implement \.{\\pdfmapline} */
377        check_o_mode(pdf, "\\pdfmapline", 1 << OMODE_PDF, false);
378        scan_pdf_ext_toks();
379        pdfmapline(def_ref);
380        delete_token_ref(def_ref);
381        break;
382    case pdf_names_code:
383        /* Implement \.{\\pdfnames} */
384        check_o_mode(pdf, "\\pdfnames", 1 << OMODE_PDF, false);
385        scan_pdf_ext_toks();
386        pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
387        break;
388    case pdf_obj_code:
389        /* Implement \.{\\pdfobj} */
390        check_o_mode(pdf, "\\pdfobj", 1 << OMODE_PDF, false);
391        scan_obj(pdf);
392        break;
393    case pdf_outline_code:
394        /* Implement \.{\\pdfoutline} */
395        check_o_mode(pdf, "\\pdfoutline", 1 << OMODE_PDF, true);
396        scan_pdfoutline(pdf);
397        break;
398    case pdf_refobj_node:
399        /* Implement \.{\\pdfrefobj} */
400        check_o_mode(pdf, "\\pdfrefobj", 1 << OMODE_PDF, false);
401        scan_refobj(pdf);
402        break;
403    case pdf_refxform_node:
404        /* Implement \.{\\pdfrefxform} */
405        check_o_mode(pdf, "\\pdfrefxform", 1 << OMODE_PDF, false);
406        scan_pdfrefxform(pdf);
407        break;
408    case pdf_refximage_node:
409        /* Implement \.{\\pdfrefximage} */
410        check_o_mode(pdf, "\\pdfrefximage", 1 << OMODE_PDF, false);
411        scan_pdfrefximage(pdf);
412        break;
413    case pdf_save_pos_node:
414        /* Implement \.{\\pdfsavepos} */
415        new_whatsit(pdf_save_pos_node);
416        break;
417    case pdf_start_link_node:
418        /* Implement \.{\\pdfstartlink} */
419        check_o_mode(pdf, "\\pdfstartlink", 1 << OMODE_PDF, false);
420        scan_startlink(pdf);
421        break;
422    case pdf_start_thread_node:
423        /* Implement \.{\\pdfstartthread} */
424        check_o_mode(pdf, "\\pdfstartthread", 1 << OMODE_PDF, false);
425        new_annot_whatsit(pdf_start_thread_node);
426        scan_thread_id();
427        break;
428    case pdf_thread_node:
429        /* Implement \.{\\pdfthread} */
430        check_o_mode(pdf, "\\pdfthread", 1 << OMODE_PDF, false);
431        new_annot_whatsit(pdf_thread_node);
432        scan_thread_id();
433        break;
434    case pdf_trailer_code:
435        /* Implement \.{\\pdftrailer} */
436        check_o_mode(pdf, "\\pdftrailer", 1 << OMODE_PDF, false);
437        scan_pdf_ext_toks();
438        pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
439        break;
440    case pdf_xform_code:
441        /* Implement \.{\\pdfxform} */
442        check_o_mode(pdf, "\\pdfxform", 1 << OMODE_PDF, false);
443        scan_pdfxform(pdf);
444        break;
445    case pdf_ximage_code:
446        /* Implement \.{\\pdfximage} */
447        check_o_mode(pdf, "\\pdfximage", 1 << OMODE_PDF, false);
448        /* png, jpeg, and pdf image handling depends on this done so early: */
449        fix_pdf_minorversion(pdf);
450        scan_pdfximage(pdf);
451        break;
452    case save_cat_code_table_code:
453        /* Implement \.{\\savecatcodetable} */
454        scan_int();
455        if ((cur_val < 0) || (cur_val > 0x7FFF)) {
456            print_err("Invalid \\catcode table");
457            help1("All \\catcode table ids must be between 0 and 0x7FFF");
458            error();
459        } else {
460            if (cur_val == cat_code_table) {
461                print_err("Invalid \\catcode table");
462                help1("You cannot overwrite the current \\catcode table");
463                error();
464            } else {
465                copy_cat_codes(cat_code_table, cur_val);
466            }
467        }
468        break;
469    case init_cat_code_table_code:
470        /* Implement \.{\\initcatcodetable} */
471        scan_int();
472        if ((cur_val < 0) || (cur_val > 0x7FFF)) {
473            print_err("Invalid \\catcode table");
474            help1("All \\catcode table ids must be between 0 and 0x7FFF");
475            error();
476        } else {
477            if (cur_val == cat_code_table) {
478                print_err("Invalid \\catcode table");
479                help1("You cannot overwrite the current \\catcode table");
480                error();
481            } else {
482                initex_cat_codes(cur_val);
483            }
484        }
485        break;
486    case set_random_seed_code:
487        /* Implement \.{\\pdfsetrandomseed} */
488        /*  Negative random seed values are silently converted to positive ones */
489        scan_int();
490        if (cur_val < 0)
491            negate(cur_val);
492        random_seed = cur_val;
493        init_randoms(random_seed);
494        break;
495    case pdf_glyph_to_unicode_code:
496        /* Implement \.{\\pdfglyphtounicode} */
497        glyph_to_unicode();
498        break;
499    case late_lua_node:
500        /* Implement \.{\\latelua} */
501        new_whatsit(late_lua_node); /* type == normal */
502        late_lua_name(tail) = scan_lua_state();
503        (void) scan_toks(false, false);
504        late_lua_data(tail) = def_ref;
505        break;
506    default:
507        confusion("ext1");
508        break;
509    }
510}
511
512
513@ Here is a subroutine that creates a whatsit node having a given |subtype|
514and a given number of words. It initializes only the first word of the whatsit,
515and appends it to the current list.
516
517@c
518void new_whatsit(int s)
519{
520    halfword p;                 /* the new node */
521    p = new_node(whatsit_node, s);
522    couple_nodes(tail, p);
523    tail = p;
524}
525
526
527@ The next subroutine uses |cur_chr| to decide what sort of whatsit is
528involved, and also inserts a |write_stream| number.
529
530@c
531void new_write_whatsit(int w)
532{
533    new_whatsit(cur_chr);
534    if (w != write_node_size) {
535        scan_four_bit_int();
536    } else {
537        scan_int();
538        if (cur_val < 0)
539            cur_val = 17;
540        else if ((cur_val > 15) && (cur_val != 18))
541            cur_val = 16;
542    }
543    write_stream(tail) = cur_val;
544}
545
546
547@ We have to check whether \.{\\pdfoutput} is set for using \pdfTeX{}
548  extensions.
549
550@c
551void scan_pdf_ext_toks(void)
552{
553    (void) scan_toks(false, true);      /* like \.{\\special} */
554}
555
556@  We need to check whether the referenced object exists.
557
558finds the node preceding the rightmost node |e|; |s| is some node before |e|
559@c
560halfword prev_rightmost(halfword s, halfword e)
561{
562    halfword p = s;
563    if (p == null)
564        return null;
565    while (vlink(p) != e) {
566        p = vlink(p);
567        if (p == null)
568            return null;
569    }
570    return p;
571}
572
573@ \.{\\pdfxform} and \.{\\pdfrefxform} are similiar to \.{\\pdfobj} and
574  \.{\\pdfrefobj}
575
576@c
577int pdf_last_xform;
578
579@ \.{\\pdfximage} and \.{\\pdfrefximage} are similiar to \.{\\pdfxform} and
580  \.{\\pdfrefxform}. As we have to scan |<rule spec>| quite often, it is better
581  have a |rule_node| that holds the most recently scanned |<rule spec>|.
582
583@c
584int pdf_last_ximage;
585int pdf_last_ximage_pages;
586int pdf_last_ximage_colordepth;
587int pdf_last_annot;
588
589@ pdflastlink needs an extra global variable
590
591@c
592int pdf_last_link;
593scaledpos pdf_last_pos = { 0, 0 };
594
595
596@ To implement primitives as \.{\\pdfinfo}, \.{\\pdfcatalog} or
597\.{\\pdfnames} we need to concatenate tokens lists.
598
599@c
600halfword concat_tokens(halfword q, halfword r)
601{                               /* concat |q| and |r| and returns the result tokens list */
602    halfword p;
603    if (q == null)
604        return r;
605    p = q;
606    while (token_link(p) != null)
607        p = token_link(p);
608    set_token_link(p, token_link(r));
609    free_avail(r);
610    return q;
611}
612
613@ @c
614int pdf_retval;                 /* global multi-purpose return value */
615
616@ @c
617halfword make_local_par_node(void)
618/* This function creates a |local_paragraph| node */
619{
620    halfword p, q;
621    p = new_node(whatsit_node, local_par_node);
622    local_pen_inter(p) = local_inter_line_penalty;
623    local_pen_broken(p) = local_broken_penalty;
624    if (local_left_box != null) {
625        q = copy_node_list(local_left_box);
626        local_box_left(p) = q;
627        local_box_left_width(p) = width(local_left_box);
628    }
629    if (local_right_box != null) {
630        q = copy_node_list(local_right_box);
631        local_box_right(p) = q;
632        local_box_right_width(p) = width(local_right_box);
633    }
634    local_par_dir(p) = par_direction;
635    return p;
636}
637
638
639
640@ The \eTeX\ features available in extended mode are grouped into two
641categories:  (1)~Some of them are permanently enabled and have no
642semantic effect as long as none of the additional primitives are
643executed.  (2)~The remaining \eTeX\ features are optional and can be
644individually enabled and disabled.  For each optional feature there is
645an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
646resp.\ disabled by assigning a positive, resp.\ non-positive value to
647that integer.
648
649
650@ In order to handle \.{\\everyeof} we need an array |eof_seen| of
651boolean variables.
652
653@c
654boolean *eof_seen;              /* has eof been seen? */
655
656
657@ The |print_group| procedure prints the current level of grouping and
658the name corresponding to |cur_group|.
659
660@c
661void print_group(boolean e)
662{
663    switch (cur_group) {
664    case bottom_level:
665        tprint("bottom level");
666        return;
667        break;
668    case simple_group:
669    case semi_simple_group:
670        if (cur_group == semi_simple_group)
671            tprint("semi ");
672        tprint("simple");
673        break;;
674    case hbox_group:
675    case adjusted_hbox_group:
676        if (cur_group == adjusted_hbox_group)
677            tprint("adjusted ");
678        tprint("hbox");
679        break;
680    case vbox_group:
681        tprint("vbox");
682        break;
683    case vtop_group:
684        tprint("vtop");
685        break;
686    case align_group:
687    case no_align_group:
688        if (cur_group == no_align_group)
689            tprint("no ");
690        tprint("align");
691        break;
692    case output_group:
693        tprint("output");
694        break;
695    case disc_group:
696        tprint("disc");
697        break;
698    case insert_group:
699        tprint("insert");
700        break;
701    case vcenter_group:
702        tprint("vcenter");
703        break;
704    case math_group:
705    case math_choice_group:
706    case math_shift_group:
707    case math_left_group:
708        tprint("math");
709        if (cur_group == math_choice_group)
710            tprint(" choice");
711        else if (cur_group == math_shift_group)
712            tprint(" shift");
713        else if (cur_group == math_left_group)
714            tprint(" left");
715        break;
716    }                           /* there are no other cases */
717    tprint(" group (level ");
718    print_int(cur_level);
719    print_char(')');
720    if (saved_value(-1) != 0) { /* |saved_line| */
721        if (e)
722            tprint(" entered at line ");
723        else
724            tprint(" at line ");
725        print_int(saved_value(-1));     /* |saved_line| */
726    }
727}
728
729
730@ The |group_trace| procedure is called when a new level of grouping
731begins (|e=false|) or ends (|e=true|) with |saved_value(-1)| containing the
732line number.
733
734@c
735void group_trace(boolean e)
736{
737    begin_diagnostic();
738    print_char('{');
739    if (e)
740        tprint("leaving ");
741    else
742        tprint("entering ");
743    print_group(e);
744    print_char('}');
745    end_diagnostic(false);
746}
747
748@ A group entered (or a conditional started) in one file may end in a
749different file.  Such slight anomalies, although perfectly legitimate,
750may cause errors that are difficult to locate.  In order to be able to
751give a warning message when such anomalies occur, \eTeX\ uses the
752|grp_stack| and |if_stack| arrays to record the initial |cur_boundary|
753and |cond_ptr| values for each input file.
754
755@c
756save_pointer *grp_stack;        /* initial |cur_boundary| */
757halfword *if_stack;             /* initial |cond_ptr| */
758
759
760@ When a group ends that was apparently entered in a different input
761file, the |group_warning| procedure is invoked in order to update the
762|grp_stack|.  If moreover \.{\\tracingnesting} is positive we want to
763give a warning message.  The situation is, however, somewhat complicated
764by two facts:  (1)~There may be |grp_stack| elements without a
765corresponding \.{\\input} file or \.{\\scantokens} pseudo file (e.g.,
766error insertions from the terminal); and (2)~the relevant information is
767recorded in the |name_field| of the |input_stack| only loosely
768synchronized with the |in_open| variable indexing |grp_stack|.
769
770@c
771void group_warning(void)
772{
773    int i;                      /* index into |grp_stack| */
774    boolean w;                  /* do we need a warning? */
775    base_ptr = input_ptr;
776    input_stack[base_ptr] = cur_input;  /* store current state */
777    i = in_open;
778    w = false;
779    while ((grp_stack[i] == cur_boundary) && (i > 0)) {
780        /* Set variable |w| to indicate if this case should be reported */
781        /* This code scans the input stack in order to determine the type of the
782           current input file. */
783        if (tracing_nesting > 0) {
784            while ((input_stack[base_ptr].state_field == token_list) ||
785                   (input_stack[base_ptr].index_field > i))
786                decr(base_ptr);
787            if (input_stack[base_ptr].name_field > 17)
788                w = true;
789        }
790
791        grp_stack[i] = save_value(save_ptr);
792        decr(i);
793    }
794    if (w) {
795        tprint_nl("Warning: end of ");
796        print_group(true);
797        tprint(" of a different file");
798        print_ln();
799        if (tracing_nesting > 1)
800            show_context();
801        if (history == spotless)
802            history = warning_issued;
803    }
804}
805
806
807@ When a conditional ends that was apparently started in a different
808input file, the |if_warning| procedure is invoked in order to update the
809|if_stack|.  If moreover \.{\\tracingnesting} is positive we want to
810give a warning message (with the same complications as above).
811
812@c
813void if_warning(void)
814{
815    int i;                      /* index into |if_stack| */
816    boolean w;                  /* do we need a warning? */
817    base_ptr = input_ptr;
818    input_stack[base_ptr] = cur_input;  /* store current state */
819    i = in_open;
820    w = false;
821    while (if_stack[i] == cond_ptr) {
822        /* Set variable |w| to... */
823        if (tracing_nesting > 0) {
824            while ((input_stack[base_ptr].state_field == token_list) ||
825                   (input_stack[base_ptr].index_field > i))
826                decr(base_ptr);
827            if (input_stack[base_ptr].name_field > 17)
828                w = true;
829        }
830
831        if_stack[i] = vlink(cond_ptr);
832        decr(i);
833    }
834    if (w) {
835        tprint_nl("Warning: end of ");
836        print_cmd_chr(if_test_cmd, cur_if);
837        print_if_line(if_line);
838        tprint(" of a different file");
839        print_ln();
840        if (tracing_nesting > 1)
841            show_context();
842        if (history == spotless)
843            history = warning_issued;
844    }
845}
846
847
848@ Conversely, the |file_warning| procedure is invoked when a file ends
849and some groups entered or conditionals started while reading from that
850file are still incomplete.
851
852@c
853void file_warning(void)
854{
855    halfword p;                 /* saved value of |save_ptr| or |cond_ptr| */
856    int l;                      /* saved value of |cur_level| or |if_limit| */
857    int c;                      /* saved value of |cur_group| or |cur_if| */
858    int i;                      /* saved value of |if_line| */
859    p = save_ptr;
860    l = cur_level;
861    c = cur_group;
862    save_ptr = cur_boundary;
863    while (grp_stack[in_open] != save_ptr) {
864        decr(cur_level);
865        tprint_nl("Warning: end of file when ");
866        print_group(true);
867        tprint(" is incomplete");
868        cur_group = save_level(save_ptr);
869        save_ptr = save_value(save_ptr);
870    }
871    save_ptr = p;
872    cur_level = (quarterword) l;
873    cur_group = (group_code) c; /* restore old values */
874    p = cond_ptr;
875    l = if_limit;
876    c = cur_if;
877    i = if_line;
878    while (if_stack[in_open] != cond_ptr) {
879        tprint_nl("Warning: end of file when ");
880        print_cmd_chr(if_test_cmd, cur_if);
881        if (if_limit == fi_code)
882            tprint_esc("else");
883        print_if_line(if_line);
884        tprint(" is incomplete");
885        if_line = if_line_field(cond_ptr);
886        cur_if = if_limit_subtype(cond_ptr);
887        if_limit = if_limit_type(cond_ptr);
888        cond_ptr = vlink(cond_ptr);
889    }
890    cond_ptr = p;
891    if_limit = l;
892    cur_if = c;
893    if_line = i;                /* restore old values */
894    print_ln();
895    if (tracing_nesting > 1)
896        show_context();
897    if (history == spotless)
898        history = warning_issued;
899}
900
901@ @c
902halfword last_line_fill;        /* the |par_fill_skip| glue node of the new paragraph */
903
904
905@ The lua interface needs some extra functions. The functions
906themselves are quite boring, but they are handy because otherwise this
907internal stuff has to be accessed from C directly, where lots of the
908defines are not available.
909
910@c
911#define get_tex_dimen_register(j) dimen(j)
912#define get_tex_skip_register(j) skip(j)
913#define get_tex_count_register(j) count(j)
914#define get_tex_attribute_register(j) attribute(j)
915#define get_tex_box_register(j) box(j)
916
917int set_tex_dimen_register(int j, scaled v)
918{
919    int a;                      /* return non-nil for error */
920    if (global_defs > 0)
921        a = 4;
922    else
923        a = 0;
924    word_define(j + scaled_base, v);
925    return 0;
926}
927
928int set_tex_skip_register(int j, halfword v)
929{
930    int a;                      /* return non-nil for error */
931    if (global_defs > 0)
932        a = 4;
933    else
934        a = 0;
935    if (type(v) != glue_spec_node)
936        return 1;
937    word_define(j + skip_base, v);
938    return 0;
939}
940
941int set_tex_count_register(int j, scaled v)
942{
943    int a;                      /* return non-nil for error */
944    if (global_defs > 0)
945        a = 4;
946    else
947        a = 0;
948    word_define(j + count_base, v);
949    return 0;
950}
951
952int set_tex_box_register(int j, scaled v)
953{
954    int a;                      /* return non-nil for error */
955    if (global_defs > 0)
956        a = 4;
957    else
958        a = 0;
959    define(j + box_base, box_ref_cmd, v);
960    return 0;
961}
962
963int set_tex_attribute_register(int j, scaled v)
964{
965    int a;                      /* return non-nil for error */
966    if (global_defs > 0)
967        a = 4;
968    else
969        a = 0;
970    if (j > max_used_attr)
971        max_used_attr = j;
972    attr_list_cache = cache_disabled;
973    word_define(j + attribute_base, v);
974    return 0;
975}
976
977int get_tex_toks_register(int j)
978{
979    str_number s;
980    s = get_nullstr();
981    if (toks(j) != null) {
982        s = tokens_to_string(toks(j));
983    }
984    return s;
985}
986
987int set_tex_toks_register(int j, lstring s)
988{
989    halfword ref;
990    int a;
991    ref = get_avail();
992    (void) str_toks(s);
993    set_token_ref_count(ref, 0);
994    set_token_link(ref, token_link(temp_token_head));
995    if (global_defs > 0)
996        a = 4;
997    else
998        a = 0;
999    define(j + toks_base, call_cmd, ref);
1000    return 0;
1001}
1002
1003scaled get_tex_box_width(int j)
1004{
1005    halfword q = box(j);
1006    if (q != null)
1007        return width(q);
1008    return 0;
1009}
1010
1011int set_tex_box_width(int j, scaled v)
1012{
1013    halfword q = box(j);
1014    if (q == null)
1015        return 1;
1016    width(q) = v;
1017    return 0;
1018}
1019
1020scaled get_tex_box_height(int j)
1021{
1022    halfword q = box(j);
1023    if (q != null)
1024        return height(q);
1025    return 0;
1026}
1027
1028int set_tex_box_height(int j, scaled v)
1029{
1030    halfword q = box(j);
1031    if (q == null)
1032        return 1;
1033    height(q) = v;
1034    return 0;
1035}
1036
1037
1038scaled get_tex_box_depth(int j)
1039{
1040    halfword q = box(j);
1041    if (q != null)
1042        return depth(q);
1043    return 0;
1044}
1045
1046int set_tex_box_depth(int j, scaled v)
1047{
1048    halfword q = box(j);
1049    if (q == null)
1050        return 1;
1051    depth(q) = v;
1052    return 0;
1053}
1054
1055
1056@ This section is devoted to the {\sl Synchronize \TeX nology}
1057- or simply {\sl Sync\TeX} - used to synchronize between input and output.
1058This section explains how synchronization basics are implemented.
1059Before we enter into more technical details,
1060let us recall in a few words what is synchronization.
1061
1062\TeX\ typesetting system clearly separates the input and the output material,
1063and synchronization will provide a new link between both that can help
1064text editors and viewers to work together.
1065More precisely, forwards synchronization is the ability,
1066given a location in the input source file,
1067to find what is the corresponding place in the output.
1068Backwards synchronization just performs the opposite:
1069given a location in the output,
1070retrieve the corresponding material in the input source file.
1071
1072For better code management and maintainance, we adopt a naming convention.
1073Throughout this program, code related to the {\sl Synchronize \TeX nology} is tagged
1074with the ``{\sl synctex}'' key word. Any code extract where {\sl Sync\TeX} plays
1075its part, either explicitly or implicitly, (should) contain the string ``{\sl synctex}''.
1076This naming convention also holds for external files.
1077Moreover, all the code related to {\sl Sync\TeX} is gathered in this section,
1078except the definitions.
1079
1080Enabling synchronization should be performed from the command line,
1081|synctexoption| is used for that purpose.
1082This global integer variable is declared here but it is not used here.
1083This is just a placeholder where the command line controller will put
1084the {\sl Sync\TeX} related options, and the {\sl Sync\TeX} controller will read them.
1085
1086@c
1087int synctexoption;
1088
1089
1090@ A convenient primitive is provided:
1091\.{\\synctex=1} in the input source file enables synchronization whereas
1092\.{\\synctex=0} disables it.
1093Its memory address is |synctex_code|.
1094It is initialized by the {\sl Sync\TeX} controller to the command-line option if given.
1095The controller may filter some reserved bits.
1096
1097In order to give the {\sl Sync\TeX} controller read and write access to
1098the contents of the \.{\\synctex} primitive, we declare |synctexoffset|,
1099such that |mem[synctexoffset]| and \.{\\synctex} correspond to
1100the same memory storage. |synctexoffset| is initialized to
1101the correct value when quite everything is initialized.
1102
1103@c
1104int synctexoffset;              /* holds the true value of |synctex_code| */
1105
1106
1107@ Synchronization is achieved with the help of an auxiliary file named
1108`\.{{\sl jobname}.synctex}' ({\sl jobname} is the contents of the
1109\.{\\jobname} macro), where a {\sl Sync\TeX} controller implemented
1110in the external |synctex.c| file will store geometrical information.
1111This {\sl Sync\TeX} controller will take care of every technical details
1112concerning the {\sl Sync\TeX} file, we will only focus on the messages
1113the controller will receive from the \TeX\ program.
1114
1115The most accurate synchronization information should allow to map
1116any character of the input source file to the corresponding location
1117in the output, if relevant.
1118Ideally, the synchronization information of the input material consists of
1119the file name, the line and column numbers of every character.
1120The synchronization information in the output is simply the page number and
1121either point coordinates, or box dimensions and position.
1122The problem is that the mapping between these informations is only known at
1123ship out time, which means that we must keep track of the input
1124synchronization information until the pages ship out.
1125
1126As \TeX\ only knows about file names and line numbers,
1127but forgets the column numbers, we only consider a
1128restricted input synchronization information called {\sl Sync\TeX\ information}.
1129It consists of a unique file name identifier, the {\sl Sync\TeX\ file tag},
1130and the line number.
1131
1132Keeping track of such information,
1133should be different whether characters or nodes are involved.
1134Actually, only certain nodes are involved in {\sl Sync\TeX},
1135we call them {\sl synchronized nodes}.
1136Synchronized nodes store the {\sl Sync\TeX} information in their last two words:
1137the first one contains a {\sl Sync\TeX\ file tag} uniquely identifying
1138the input file, and the second one contains the current line number,
1139as returned by the \.{\\inputlineno} primitive.
1140The |synctex_field_size| macro contains the necessary size to store
1141the {\sl Sync\TeX} information in a node.
1142
1143When declaring the size of a new node, it is recommanded to use the following
1144convention: if the node is synchronized, use a definition similar to
1145|my_synchronized_node_size|={\sl xxx}+|synctex_field_size|.
1146Moreover, one should expect that the {\sl Sync\TeX} information is always stored
1147in the last two words of a synchronized node.
1148
1149By default, every node with a sufficiently big size is initialized
1150at creation time in the |get_node| routine with the current
1151{\sl Sync\TeX} information, whether or not the node is synchronized.
1152One purpose is to set this information very early in order to minimize code
1153dependencies, including forthcoming extensions.
1154Another purpose is to avoid the assumption that every node type has a dedicated getter,
1155where initialization should take place. Actually, it appears that some nodes are created
1156using directly the |get_node| routine and not the dedicated constructor.
1157And finally, initializing the node at only one place is less error prone.
1158
1159Instead of storing the input file name, it is better to store just an identifier.
1160Each time \TeX\ opens a new file, it notifies the {\sl Sync\TeX} controller with
1161a |synctex_start_input| message.
1162This controller will create a new {\sl Sync\TeX} file tag and
1163will update the current input state record accordingly.
1164If the input comes from the terminal or a pseudo file, the |synctex_tag| is set to 0.
1165It results in automatically disabling synchronization for material
1166input from the terminal or pseudo files.
1167
1168
1169Synchronized nodes are boxes, math, kern and glue nodes.
1170Other nodes should be synchronized too, in particular math noads.
1171\TeX\ assumes that math, kern and glue nodes have the same size,
1172this is why both are synchronized.
1173{\sl In fine}, only horizontal lists are really used in {\sl Sync\TeX},
1174but all box nodes are considered the same with respect to synchronization,
1175because a box node type is allowed to change at execution time.
1176
1177{\sl Nota Bene:}
1178The {\sl Sync\TeX} code is very close to the memory model.
1179It is not connected to any other part of the code,
1180except for memory management. It is possible to neutralize the {\sl Sync\TeX} code
1181rather simply. The first step is to define a null |synctex_field_size|.
1182The second step is to comment out the code in ``Initialize bigger nodes...'' and every
1183``Copy ... {\sl Sync\TeX} information''.
1184The last step will be to comment out the |synctex_tag_field| related code in the
1185definition of |synctex_tag| and the various ``Prepare ... {\sl Sync\TeX} information''.
1186Then all the remaining code should be just harmless.
1187The resulting program would behave exactly the same as if absolutely no {\sl Sync\TeX}
1188related code was there, including memory management.
1189Of course, all this assumes that {\sl Sync\TeX} is turned off from the command line.
1190@^synctex@>
1191@^synchronization@>
1192
1193
1194@ Here are extra variables for Web2c.  (This numbering of the
1195system-dependent section allows easy integration of Web2c and e-\TeX, etc.)
1196@^<system dependencies@>
1197
1198@c
1199pool_pointer edit_name_start;   /* where the filename to switch to starts */
1200int edit_name_length, edit_line;        /* what line to start editing at */
1201int ipcon;                      /* level of IPC action, 0 for none [default] */
1202boolean stop_at_space;          /* whether |more_name| returns false for space */
1203
1204@ The |edit_name_start| will be set to point into |str_pool| somewhere after
1205its beginning if \TeX\ is supposed to switch to an editor on exit.
1206
1207@c
1208int shellenabledp;
1209int restrictedshell;
1210char *output_comment;
1211
1212@ Are we printing extra info as we read the format file?
1213
1214@c
1215boolean debug_format_file;
1216