new beta-0.90.0
[luatex.git] / source / texk / web2c / luatexdir / tex / extensions.w
bloba6161dcf2435ef9a18f2804dddf9503c419d4614
1 % extensions.w
3 % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
5 % This file is part of LuaTeX.
7 % LuaTeX is free software; you can redistribute it and/or modify it under
8 % the terms of the GNU General Public License as published by the Free
9 % Software Foundation; either version 2 of the License, or (at your
10 % option) any later version.
12 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 % License for more details.
17 % You should have received a copy of the GNU General Public License along
18 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
20 \def\eTeX{e-\TeX}
21 \def\pdfTeX{pdf\TeX}
23 @ @c
24 #include "ptexlib.h"
26 @ @c
27 #define mode cur_list.mode_field
28 #define tail cur_list.tail_field
29 #define head cur_list.head_field
30 #define prev_graf cur_list.pg_field
31 #define dir_save cur_list.dirs_field
33 #define tracing_nesting int_par(tracing_nesting_code)
34 #define tracing_online int_par(tracing_online_code)
35 #define box(A) eqtb[box_base+(A)].hh.rh
36 #define global_defs int_par(global_defs_code)
37 #define cat_code_table int_par(cat_code_table_code)
38 #define toks(A) equiv(toks_base+(A))
40 @ The program above includes a bunch of ``hooks'' that allow further
41 capabilities to be added without upsetting \TeX's basic structure.
42 Most of these hooks are concerned with ``whatsit'' nodes, which are
43 intended to be used for special purposes; whenever a new extension to
44 \TeX\ involves a new kind of whatsit node, a corresponding change needs
45 to be made to the routines below that deal with such nodes,
46 but it will usually be unnecessary to make many changes to the
47 other parts of this program.
49 In order to demonstrate how extensions can be made, we shall treat
50 `\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}',
51 and `\.{\\special}' as if they were extensions.
52 These commands are actually primitives of \TeX, and they should
53 appear in all implementations of the system; but let's try to imagine
54 that they aren't. Then the program below illustrates how a person
55 could add them.
57 Sometimes, of course, an extension will require changes to \TeX\ itself;
58 no system of hooks could be complete enough for all conceivable extensions.
59 The features associated with `\.{\\write}' are almost all confined to the
60 following paragraphs, but there are small parts of the |print_ln| and
61 |print_char| procedures that were introduced specifically to \.{\\write}
62 characters. Furthermore one of the token lists recognized by the scanner
63 is a |write_text|; and there are a few other miscellaneous places where we
64 have already provided for some aspect of \.{\\write}. The goal of a \TeX\
65 extender should be to minimize alterations to the standard parts of the
66 program, and to avoid them completely if possible. He or she should also
67 be quite sure that there's no easy way to accomplish the desired goals
68 with the standard features that \TeX\ already has. ``Think thrice before
69 extending,'' because that may save a lot of work, and it will also keep
70 incompatible extensions of \TeX\ from proliferating.
71 @^system dependencies@>
72 @^extensions to \TeX@>
74 First let's consider the format of whatsit nodes that are used to represent
75 the data associated with \.{\\write} and its relatives. Recall that a whatsit
76 has |type=whatsit_node|, and the |subtype| is supposed to distinguish
77 different kinds of whatsits. Each node occupies two or more words; the
78 exact number is immaterial, as long as it is readily determined from the
79 |subtype| or other data.
81 We shall introduce five |subtype| values here, corresponding to the
82 control sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}.
83 The second word of I/O whatsits has a |write_stream| field
84 that identifies the write-stream number (0 to 15, or 16 for out-of-range and
85 positive, or 17 for out-of-range and negative).
86 In the case of \.{\\write} and \.{\\special}, there is also a field that
87 points to the reference count of a token list that should be sent. In the
88 case of \.{\\openout}, we need three words and three auxiliary subfields
89 to hold the string numbers for name, area, and extension.
91 @ Extensions might introduce new command codes; but it's best to use
92 |extension| with a modifier, whenever possible, so that |main_control|
93 stays the same.
95 @ The sixteen possible \.{\\write} streams are represented by the |write_file|
96 array. The |j|th file is open if and only if |write_open[j]=true|. The last
97 two streams are special; |write_open[16]| represents a stream number
98 greater than 15, while |write_open[17]| represents a negative stream number,
99 and both of these variables are always |false|.
102 alpha_file write_file[last_file_selector+1];
103 halfword write_file_mode[last_file_selector+1];
104 halfword write_file_translation[last_file_selector+1];
105 boolean write_open[last_file_selector+1];
107 scaled neg_wd;
108 scaled pos_wd;
109 scaled neg_ht;
111 @ The variable |write_loc| just introduced is used to provide an
112 appropriate error message in case of ``runaway'' write texts.
115 halfword write_loc; /* |eqtb| address of \.{\\write} */
118 hh: eventually i'll make \pdfextension a lua token parsed function;
119 a complication is that sometimes token lists are delayed
122 @ When an |extension| command occurs in |main_control|, in any mode,
123 the |do_extension| routine is called.
126 int last_saved_image_index ;
127 int last_saved_image_pages ;
128 int last_saved_box_index ;
129 scaledpos last_position = { 0, 0 };
131 static void do_extension_dvi(int immediate)
133 if (scan_keyword("literal")) {
134 new_whatsit(special_node);
135 write_stream(tail) = null;
136 scan_toks(false, true);
137 write_tokens(tail) = def_ref;
138 } else {
139 tex_error("unexpected use of \\dviextension",null);
143 static void do_extension_pdf(int immediate)
145 int i;
147 if (scan_keyword("literal")) {
148 new_whatsit(pdf_literal_node);
149 if (scan_keyword("direct"))
150 set_pdf_literal_mode(tail, direct_always);
151 else if (scan_keyword("page"))
152 set_pdf_literal_mode(tail, direct_page);
153 else
154 set_pdf_literal_mode(tail, set_origin);
155 scan_toks(false, true);
156 set_pdf_literal_type(tail, normal);
157 set_pdf_literal_data(tail, def_ref);
158 } else if (scan_keyword("dest")) {
159 scan_pdfdest(static_pdf);
160 } else if (scan_keyword("annot")) {
161 scan_annot(static_pdf);
162 } else if (scan_keyword("save")) {
163 new_whatsit(pdf_save_node);
164 } else if (scan_keyword("restore")) {
165 new_whatsit(pdf_restore_node);
166 } else if (scan_keyword("setmatrix")) {
167 new_whatsit(pdf_setmatrix_node);
168 scan_toks(false, true);
169 set_pdf_setmatrix_data(tail, def_ref);
170 } else if (scan_keyword("obj")) {
171 scan_obj(static_pdf);
172 if (immediate) {
173 if (obj_data_ptr(static_pdf, pdf_last_obj) == 0) /* this object has not been initialized yet */
174 normal_error("pdf backend","\\pdfextension obj 'reserveobjnum' cannot be used with \\immediate");
175 pdf_write_obj(static_pdf, pdf_last_obj);
177 } else if (scan_keyword("refobj")) {
178 scan_refobj(static_pdf);
179 } else if (scan_keyword("colorstack")) {
180 scan_int();
181 if (cur_val >= colorstackused()) {
182 print_err("Unknown color stack number ");
183 print_int(cur_val);
184 help3
185 ("Allocate and initialize a color stack with \\pdfextension colorstackinit.",
186 "I'll use default color stack 0 here.",
187 "Proceed, with fingers crossed.");
188 error();
189 cur_val = 0;
191 if (cur_val < 0) {
192 print_err("Invalid negative color stack number");
193 help2("I'll use default color stack 0 here.",
194 "Proceed, with fingers crossed.");
195 error();
196 cur_val = 0;
198 if (scan_keyword("set"))
199 i = colorstack_set;
200 else if (scan_keyword("push"))
201 i = colorstack_push;
202 else if (scan_keyword("pop"))
203 i = colorstack_pop;
204 else if (scan_keyword("current"))
205 i = colorstack_current;
206 else
207 i = -1; /* error */
208 if (i >= 0) {
209 new_whatsit(pdf_colorstack_node);
210 set_pdf_colorstack_stack(tail, cur_val);
211 set_pdf_colorstack_cmd(tail, i);
212 set_pdf_colorstack_data(tail, null);
213 if (i <= colorstack_data) {
214 scan_toks(false, true);
215 set_pdf_colorstack_data(tail, def_ref);
217 } else {
218 print_err("Color stack action is missing");
219 help3("The expected actions for \\pdfextension colorstack:",
220 " set, push, pop, current",
221 "I'll ignore the color stack command.");
222 error();
224 } else if (scan_keyword("startlink")) {
225 scan_startlink(static_pdf);
226 } else if (scan_keyword("endlink")) {
227 if (abs(mode) == vmode)
228 normal_error("pdf backend", "\\pdfextension endlink cannot be used in vertical mode");
229 new_whatsit(pdf_end_link_node);
230 } else if (scan_keyword("startthread")) {
231 new_annot_whatsit(pdf_start_thread_node);
232 scan_thread_id();
233 } else if (scan_keyword("endthread")) {
234 new_whatsit(pdf_end_thread_node);
235 } else if (scan_keyword("thread")) {
236 new_annot_whatsit(pdf_thread_node);
237 scan_thread_id();
238 } else if (scan_keyword("outline")) {
239 scan_pdfoutline(static_pdf);
240 } else if (scan_keyword("glyphtounicode")) {
241 glyph_to_unicode();
242 } else if (scan_keyword("catalog")) {
243 scan_pdfcatalog(static_pdf);
244 } else if (scan_keyword("fontattr")) {
246 The font attributes are simply initialized to zero now, this is easier to deal with from C than an
247 empty \TeX{} string, and surely nobody will want to set font attr to a string containing a single zero,
248 as that would be nonsensical in the PDF output.
250 scan_font_ident();
251 i = cur_val;
252 if (i == null_font)
253 normal_error("pdf backend", "invalid font identifier");
254 scan_toks(false, true);
255 set_pdf_font_attr(i, tokens_to_string(def_ref));
256 if (str_length(pdf_font_attr(i)) == 0) {
257 flush_str((str_ptr - 1)); /* from |tokens_to_string| */
258 set_pdf_font_attr(i, 0);
260 } else if (scan_keyword("mapfile")) {
261 scan_toks(false, true);
262 pdfmapfile(def_ref);
263 delete_token_ref(def_ref);
264 } else if (scan_keyword("mapline")) {
265 scan_toks(false, true);
266 pdfmapline(def_ref);
267 delete_token_ref(def_ref);
268 } else if (scan_keyword("includechars")) {
269 pdf_include_chars(static_pdf);
270 } else if (scan_keyword("info")) {
271 scan_toks(false, true);
272 pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
273 } else if (scan_keyword("names")) {
274 scan_toks(false, true);
275 pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
276 } else if (scan_keyword("trailer")) {
277 scan_toks(false, true);
278 pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
279 } else {
280 tex_error("unexpected use of \\pdfextension",null);
284 static void do_resource_dvi(int immediate, int code)
288 static void do_resource_pdf(int immediate, int code)
290 switch (code) {
291 case use_box_resource_code:
292 scan_pdfrefxform(static_pdf);
293 break;
294 case use_image_resource_code:
295 scan_pdfrefximage(static_pdf);
296 break;
297 case save_box_resource_code:
298 scan_pdfxform(static_pdf);
299 if (immediate) {
300 pdf_cur_form = last_saved_box_index;
301 ship_out(static_pdf, obj_xform_box(static_pdf, last_saved_box_index), SHIPPING_FORM);
303 break;
304 case save_image_resource_code:
305 fix_pdf_minorversion(static_pdf);
306 scan_pdfximage(static_pdf);
307 if (immediate) {
308 pdf_write_image(static_pdf, last_saved_image_index);
310 break;
316 Ad immediate:
318 To write a token list, we must run it through \TeX's scanner, expanding
319 macros and \.{\\the} and \.{\\number}, etc. This might cause runaways,
320 if a delimited macro parameter isn't matched, and runaways would be
321 extremely confusing since we are calling on \TeX's scanner in the middle
322 of a \.{\\shipout} command. Therefore we will put a dummy control sequence as
323 a ``stopper,'' right after the token list. This control sequence is
324 artificially defined to be \.{\\outer}.
326 The presence of `\.{\\immediate}' causes the |do_extension| procedure
327 to descend to one level of recursion. Nothing happens unless \.{\\immediate}
328 is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
332 /* extensions are backend related */
334 @ The next subroutine uses |cur_chr| to decide what sort of whatsit is
335 involved, and also inserts a |write_stream| number.
338 static void new_write_whatsit(int w, int check)
340 new_whatsit(cur_chr);
341 if (check) {
342 /* so we check with open and close */
343 scan_limited_int(last_file_selector,NULL);
344 } else {
345 /* but we're tolerant with the rest */
346 scan_int();
347 if (cur_val < 0)
348 cur_val = term_only;
349 else if (cur_val > last_file_selector) {
350 cur_val = term_and_log;
353 write_stream(tail) = cur_val;
356 void do_extension(int immediate)
358 halfword p; /* all-purpose pointer */
359 if (cur_cmd == extension_cmd) {
360 /* these have their own range starting at 0 */
361 switch (cur_chr) {
362 case open_code:
363 p = tail;
364 new_write_whatsit(open_node_size,1);
365 scan_optional_equals();
366 scan_file_name();
367 open_name(tail) = cur_name;
368 open_area(tail) = cur_area;
369 open_ext(tail) = cur_ext;
370 if (immediate) {
371 out_what(static_pdf, tail);
372 flush_node_list(tail);
373 tail = p;
374 vlink(p) = null;
376 break;
377 case write_code:
379 When `\.{\\write 12\{...\}}' appears, we scan the token list `\.{\{...\}}'
380 without expanding its macros; the macros will be expanded later when this
381 token list is rescanned.
383 p = tail;
384 new_write_whatsit(write_node_size,0);
385 cur_cs = write_stream(tail);
386 scan_toks(false, false);
387 write_tokens(tail) = def_ref;
388 if (immediate) {
389 out_what(static_pdf, tail);
390 flush_node_list(tail);
391 tail = p;
392 vlink(p) = null;
394 break;
395 case close_code:
396 p = tail;
397 new_write_whatsit(close_node_size,1);
398 write_tokens(tail) = null;
399 if (immediate) {
400 out_what(static_pdf, tail);
401 flush_node_list(tail);
402 tail = p;
403 vlink(p) = null;
405 break;
406 case special_code:
408 When `\.{\\special\{...\}}' appears, we expand the macros in the token
409 list as in \.{\\xdef} and \.{\\mark}.
411 new_whatsit(special_node);
412 write_stream(tail) = null;
413 p = scan_toks(false, true);
414 write_tokens(tail) = def_ref;
415 break;
416 case immediate_code:
417 get_x_token();
418 do_extension(1);
419 break;
420 case use_box_resource_code:
421 case use_image_resource_code:
422 case save_box_resource_code:
423 case save_image_resource_code:
424 switch (get_o_mode()) {
425 case OMODE_DVI:
426 do_resource_dvi(immediate,cur_chr);
427 break;
428 case OMODE_PDF:
429 do_resource_pdf(immediate,cur_chr);
430 break;
431 default:
432 break;
434 break;
435 /* backend extensions have their own range starting at 32 */
436 case dvi_extension_code:
437 if (get_o_mode() == OMODE_DVI)
438 do_extension_dvi(immediate);
439 break;
440 case pdf_extension_code:
441 if (get_o_mode() == OMODE_PDF)
442 do_extension_pdf(immediate);
443 break;
444 /* done */
445 default:
446 if (immediate) {
447 back_input();
448 } else {
449 confusion("invalid extension");
451 break;
453 } else {
454 /* no extension command, quite certainly following \immediate */
455 back_input();
459 @ Here is a subroutine that creates a whatsit node having a given |subtype|
460 and a given number of words. It initializes only the first word of the whatsit,
461 and appends it to the current list.
464 void new_whatsit(int s)
466 halfword p = new_node(whatsit_node, s);
467 couple_nodes(tail, p);
468 tail = p;
471 @ The final line of this routine is slightly subtle; at least, the author
472 didn't think about it until getting burnt! There is a used-up token list
473 @^Knuth, Donald Ervin@>
474 on the stack, namely the one that contained |end_write_token|. (We
475 insert this artificial `\.{\\endwrite}' to prevent runaways, as explained
476 above.) If it were not removed, and if there were numerous writes on a
477 single page, the stack would overflow.
480 #define end_write_token cs_token_flag+end_write
482 void expand_macros_in_tokenlist(halfword p)
484 int old_mode;
485 pointer q = get_avail();
486 pointer r = get_avail();
487 token_info(q) = right_brace_token + '}';
488 token_link(q) = r;
489 token_info(r) = end_write_token;
490 begin_token_list(q, inserted);
491 begin_token_list(write_tokens(p), write_text);
492 q = get_avail();
493 token_info(q) = left_brace_token + '{';
494 begin_token_list(q, inserted);
495 /* now we're ready to scan
496 `\.\{$\langle\,$token list$\,\rangle$\.{\} \\endwrite}' */
497 old_mode = mode;
498 mode = 0;
499 /* disable \.{\\prevdepth}, \.{\\spacefactor}, \.{\\lastskip}, \.{\\prevgraf} */
500 cur_cs = write_loc;
501 q = scan_toks(false, true); /* expand macros, etc. */
502 get_token();
503 if (cur_tok != end_write_token) {
504 /* Recover from an unbalanced write command */
505 const char *hlp[] = {
506 "On this page there's a \\write with fewer real {'s than }'s.",
507 "I can't handle that very well; good luck.", NULL
509 tex_error("Unbalanced write command", hlp);
510 do {
511 get_token();
512 } while (cur_tok != end_write_token);
514 mode = old_mode;
515 end_token_list(); /* conserve stack space */
518 void write_out(halfword p)
520 int old_setting; /* holds print |selector| */
521 int j; /* write stream number */
522 char *s, *ss; /* line to be written, as a C string */
523 int callback_id;
524 int lua_retval;
525 expand_macros_in_tokenlist(p);
526 old_setting = selector;
527 j = write_stream(p);
528 if (write_open[j]) {
529 selector = j;
530 } else if ((j == term_only) && (selector == term_and_log)) {
531 /* write to the terminal if file isn't open */
532 selector = log_only;
533 tprint_nl("");
534 } else {
535 tprint_nl("");
537 s = tokenlist_to_cstring(def_ref, false, NULL);
538 if (selector < no_print) {
539 /* selector is a file */
540 callback_id = callback_defined(process_output_buffer_callback);
541 if (callback_id > 0) {
542 /* fix up the output buffer using callbacks */
543 lua_retval = run_callback(callback_id, "S->S", s, &ss);
544 if ((lua_retval == true) && (ss != NULL)) {
545 xfree(s);
546 s = ss;
550 tprint(s);
551 xfree(s);
552 print_ln();
553 flush_list(def_ref);
554 selector = old_setting;
557 void finalize_write_files(void) {
558 int k;
559 for (k = 0; k <= last_file_selector; k++) {
560 if (write_open[k]) {
561 lua_a_close_out(write_file[k]);
566 void initialize_write_files(void) {
567 int k;
568 for (k = 0; k <= last_file_selector; k++) {
569 write_open[k] = false;
573 void close_write_file(int id) {
574 if (write_open[id]) {
575 lua_a_close_out(write_file[id]);
576 write_open[id] = false;
580 boolean open_write_file(int id, char *fn) {
581 if (lua_a_open_out(&(write_file[id]), fn, (id + 1))) {
582 write_open[id] = true;
583 return true;
584 } else {
585 return false;
590 @ To implement primitives as \.{\\pdfextension info}, \.{\\pdfextension catalog} or
591 \.{\\pdfextension names} we need to concatenate tokens lists.
594 halfword concat_tokens(halfword q, halfword r)
595 { /* concat |q| and |r| and returns the result tokens list */
596 halfword p;
597 if (q == null)
598 return r;
599 p = q;
600 while (token_link(p) != null)
601 p = token_link(p);
602 set_token_link(p, token_link(r));
603 free_avail(r);
604 return q;
607 @ The \eTeX\ features available in extended mode are grouped into two
608 categories: (1)~Some of them are permanently enabled and have no
609 semantic effect as long as none of the additional primitives are
610 executed. (2)~The remaining \eTeX\ features are optional and can be
611 individually enabled and disabled. For each optional feature there is
612 an \eTeX\ state variable named \.{\\...state}; the feature is enabled,
613 resp.\ disabled by assigning a positive, resp.\ non-positive value to
614 that integer.
616 @ In order to handle \.{\\everyeof} we need an array |eof_seen| of
617 boolean variables.
620 boolean *eof_seen; /* has eof been seen? */
622 @ The |print_group| procedure prints the current level of grouping and
623 the name corresponding to |cur_group|.
626 void print_group(boolean e)
628 switch (cur_group) {
629 case bottom_level:
630 tprint("bottom level");
631 return;
632 break;
633 case simple_group:
634 case semi_simple_group:
635 if (cur_group == semi_simple_group)
636 tprint("semi ");
637 tprint("simple");
638 break;;
639 case hbox_group:
640 case adjusted_hbox_group:
641 if (cur_group == adjusted_hbox_group)
642 tprint("adjusted ");
643 tprint("hbox");
644 break;
645 case vbox_group:
646 tprint("vbox");
647 break;
648 case vtop_group:
649 tprint("vtop");
650 break;
651 case align_group:
652 case no_align_group:
653 if (cur_group == no_align_group)
654 tprint("no ");
655 tprint("align");
656 break;
657 case output_group:
658 tprint("output");
659 break;
660 case disc_group:
661 tprint("disc");
662 break;
663 case insert_group:
664 tprint("insert");
665 break;
666 case vcenter_group:
667 tprint("vcenter");
668 break;
669 case math_group:
670 case math_choice_group:
671 case math_shift_group:
672 case math_left_group:
673 tprint("math");
674 if (cur_group == math_choice_group)
675 tprint(" choice");
676 else if (cur_group == math_shift_group)
677 tprint(" shift");
678 else if (cur_group == math_left_group)
679 tprint(" left");
680 break;
681 } /* there are no other cases */
682 tprint(" group (level ");
683 print_int(cur_level);
684 print_char(')');
685 if (saved_value(-1) != 0) { /* |saved_line| */
686 if (e)
687 tprint(" entered at line ");
688 else
689 tprint(" at line ");
690 print_int(saved_value(-1)); /* |saved_line| */
694 @ The |group_trace| procedure is called when a new level of grouping
695 begins (|e=false|) or ends (|e=true|) with |saved_value(-1)| containing the
696 line number.
699 void group_trace(boolean e)
701 begin_diagnostic();
702 print_char('{');
703 if (e)
704 tprint("leaving ");
705 else
706 tprint("entering ");
707 print_group(e);
708 print_char('}');
709 end_diagnostic(false);
712 @ A group entered (or a conditional started) in one file may end in a
713 different file. Such slight anomalies, although perfectly legitimate,
714 may cause errors that are difficult to locate. In order to be able to
715 give a warning message when such anomalies occur, \eTeX\ uses the
716 |grp_stack| and |if_stack| arrays to record the initial |cur_boundary|
717 and |cond_ptr| values for each input file.
720 save_pointer *grp_stack; /* initial |cur_boundary| */
721 halfword *if_stack; /* initial |cond_ptr| */
723 @ When a group ends that was apparently entered in a different input
724 file, the |group_warning| procedure is invoked in order to update the
725 |grp_stack|. If moreover \.{\\tracingnesting} is positive we want to
726 give a warning message. The situation is, however, somewhat complicated
727 by two facts: (1)~There may be |grp_stack| elements without a
728 corresponding \.{\\input} file or \.{\\scantokens} pseudo file (e.g.,
729 error insertions from the terminal); and (2)~the relevant information is
730 recorded in the |name_field| of the |input_stack| only loosely
731 synchronized with the |in_open| variable indexing |grp_stack|.
734 void group_warning(void)
736 boolean w = false; /* do we need a warning? */
737 int i = in_open; /* index into |grp_stack| */
738 base_ptr = input_ptr;
739 input_stack[base_ptr] = cur_input; /* store current state */
740 while ((grp_stack[i] == cur_boundary) && (i > 0)) {
741 /* Set variable |w| to indicate if this case should be reported */
742 /* This code scans the input stack in order to determine the type of the
743 current input file. */
744 if (tracing_nesting > 0) {
745 while ((input_stack[base_ptr].state_field == token_list) ||
746 (input_stack[base_ptr].index_field > i))
747 decr(base_ptr);
748 if (input_stack[base_ptr].name_field > 17)
749 w = true;
752 grp_stack[i] = save_value(save_ptr);
753 decr(i);
755 if (w) {
756 tprint_nl("Warning: end of ");
757 print_group(true);
758 tprint(" of a different file");
759 print_ln();
760 if (tracing_nesting > 1)
761 show_context();
762 if (history == spotless)
763 history = warning_issued;
767 @ When a conditional ends that was apparently started in a different
768 input file, the |if_warning| procedure is invoked in order to update the
769 |if_stack|. If moreover \.{\\tracingnesting} is positive we want to
770 give a warning message (with the same complications as above).
773 void if_warning(void)
775 boolean w = false; /* do we need a warning? */
776 int i = in_open;
777 base_ptr = input_ptr;
778 input_stack[base_ptr] = cur_input; /* store current state */
779 while (if_stack[i] == cond_ptr) {
780 /* Set variable |w| to... */
781 if (tracing_nesting > 0) {
782 while ((input_stack[base_ptr].state_field == token_list) ||
783 (input_stack[base_ptr].index_field > i))
784 decr(base_ptr);
785 if (input_stack[base_ptr].name_field > 17)
786 w = true;
789 if_stack[i] = vlink(cond_ptr);
790 decr(i);
792 if (w) {
793 tprint_nl("Warning: end of ");
794 print_cmd_chr(if_test_cmd, cur_if);
795 print_if_line(if_line);
796 tprint(" of a different file");
797 print_ln();
798 if (tracing_nesting > 1)
799 show_context();
800 if (history == spotless)
801 history = warning_issued;
806 @ Conversely, the |file_warning| procedure is invoked when a file ends
807 and some groups entered or conditionals started while reading from that
808 file are still incomplete.
811 void file_warning(void)
813 halfword p = save_ptr; /* saved value of |save_ptr| or |cond_ptr| */
814 int l = cur_level; /* saved value of |cur_level| or |if_limit| */
815 int c = cur_group; /* saved value of |cur_group| or |cur_if| */
816 int i; /* saved value of |if_line| */
817 save_ptr = cur_boundary;
818 while (grp_stack[in_open] != save_ptr) {
819 decr(cur_level);
820 tprint_nl("Warning: end of file when ");
821 print_group(true);
822 tprint(" is incomplete");
823 cur_group = save_level(save_ptr);
824 save_ptr = save_value(save_ptr);
826 save_ptr = p;
827 cur_level = (quarterword) l;
828 cur_group = (group_code) c; /* restore old values */
829 p = cond_ptr;
830 l = if_limit;
831 c = cur_if;
832 i = if_line;
833 while (if_stack[in_open] != cond_ptr) {
834 tprint_nl("Warning: end of file when ");
835 print_cmd_chr(if_test_cmd, cur_if);
836 if (if_limit == fi_code)
837 tprint_esc("else");
838 print_if_line(if_line);
839 tprint(" is incomplete");
840 if_line = if_line_field(cond_ptr);
841 cur_if = if_limit_subtype(cond_ptr);
842 if_limit = if_limit_type(cond_ptr);
843 cond_ptr = vlink(cond_ptr);
845 cond_ptr = p;
846 if_limit = l;
847 cur_if = c;
848 if_line = i; /* restore old values */
849 print_ln();
850 if (tracing_nesting > 1)
851 show_context();
852 if (history == spotless)
853 history = warning_issued;
856 @ @c
857 halfword last_line_fill; /* the |par_fill_skip| glue node of the new paragraph */
859 @ The lua interface needs some extra functions. The functions
860 themselves are quite boring, but they are handy because otherwise this
861 internal stuff has to be accessed from C directly, where lots of the
862 defines are not available.
865 #define dimen(A) eqtb[scaled_base+(A)].hh.rh
866 #define count(A) eqtb[count_base+(A)].hh.rh
868 #define get_tex_dimen_register(j) dimen(j)
869 #define get_tex_skip_register(j) skip(j)
870 #define get_tex_mu_skip_register(j) mu_skip(j)
871 #define get_tex_count_register(j) count(j)
872 #define get_tex_attribute_register(j) attribute(j)
873 #define get_tex_box_register(j) box(j)
875 /* these can now be macros (todo) */
877 int get_tex_extension_count_register(int i)
879 return (int) int_par(backend_int_base-int_base+i);
882 void set_tex_extension_count_register(int i, int d)
884 int_par(backend_int_base-int_base+i) = d;
887 int get_tex_extension_dimen_register(int i)
889 return (int) dimen_par(backend_dimen_base-dimen_base+i);
892 void set_tex_extension_dimen_register(int i, int d)
894 dimen_par(backend_dimen_base-dimen_base+i) = d;
897 int get_tex_extension_toks_register(int i)
899 return equiv(backend_toks_base+i);
902 int set_tex_dimen_register(int j, scaled v)
904 int a; /* return non-nil for error */
905 if (global_defs > 0)
906 a = 4;
907 else
908 a = 0;
909 word_define(j + scaled_base, v);
910 return 0;
913 int set_tex_skip_register(int j, halfword v)
915 int a; /* return non-nil for error */
916 if (global_defs > 0)
917 a = 4;
918 else
919 a = 0;
920 if (type(v) != glue_spec_node)
921 return 1;
922 word_define(j + skip_base, v);
923 return 0;
926 int set_tex_mu_skip_register(int j, halfword v)
928 int a; /* return non-nil for error */
929 if (global_defs > 0)
930 a = 4;
931 else
932 a = 0;
933 if (type(v) != glue_spec_node)
934 return 1;
935 word_define(j + mu_skip_base, v);
936 return 0;
939 int set_tex_count_register(int j, scaled v)
941 int a; /* return non-nil for error */
942 if (global_defs > 0)
943 a = 4;
944 else
945 a = 0;
946 word_define(j + count_base, v);
947 return 0;
950 int set_tex_box_register(int j, scaled v)
952 int a; /* return non-nil for error */
953 if (global_defs > 0)
954 a = 4;
955 else
956 a = 0;
957 define(j + box_base, box_ref_cmd, v);
958 return 0;
961 int set_tex_attribute_register(int j, scaled v)
963 int a; /* return non-nil for error */
964 if (global_defs > 0)
965 a = 4;
966 else
967 a = 0;
968 if (j > max_used_attr)
969 max_used_attr = j;
970 attr_list_cache = cache_disabled;
971 word_define(j + attribute_base, v);
972 return 0;
975 int get_tex_toks_register(int j)
977 str_number s = get_nullstr();
978 if (toks(j) != null) {
979 s = tokens_to_string(toks(j));
981 return s;
984 int set_tex_toks_register(int j, lstring s)
986 int a;
987 halfword ref = get_avail();
988 (void) str_toks(s);
989 set_token_ref_count(ref, 0);
990 set_token_link(ref, token_link(temp_token_head));
991 if (global_defs > 0)
992 a = 4;
993 else
994 a = 0;
995 define(j + toks_base, call_cmd, ref);
996 return 0;
999 int scan_tex_toks_register(int j, int c, lstring s)
1001 int a;
1002 halfword ref = get_avail();
1003 (void) str_scan_toks(c,s);
1004 set_token_ref_count(ref, 0);
1005 set_token_link(ref, token_link(temp_token_head));
1006 if (global_defs > 0)
1007 a = 4;
1008 else
1009 a = 0;
1010 define(j + toks_base, call_cmd, ref);
1011 return 0;
1014 scaled get_tex_box_width(int j)
1016 halfword q = box(j);
1017 if (q != null)
1018 return width(q);
1019 return 0;
1022 int set_tex_box_width(int j, scaled v)
1024 halfword q = box(j);
1025 if (q == null)
1026 return 1;
1027 width(q) = v;
1028 return 0;
1031 scaled get_tex_box_height(int j)
1033 halfword q = box(j);
1034 if (q != null)
1035 return height(q);
1036 return 0;
1039 int set_tex_box_height(int j, scaled v)
1041 halfword q = box(j);
1042 if (q == null)
1043 return 1;
1044 height(q) = v;
1045 return 0;
1048 scaled get_tex_box_depth(int j)
1050 halfword q = box(j);
1051 if (q != null)
1052 return depth(q);
1053 return 0;
1056 int set_tex_box_depth(int j, scaled v)
1058 halfword q = box(j);
1059 if (q == null)
1060 return 1;
1061 depth(q) = v;
1062 return 0;
1065 @ This section is devoted to the {\sl Synchronize \TeX nology}
1066 - or simply {\sl Sync\TeX} - used to synchronize between input and output.
1067 This section explains how synchronization basics are implemented.
1068 Before we enter into more technical details,
1069 let us recall in a few words what is synchronization.
1071 \TeX\ typesetting system clearly separates the input and the output material,
1072 and synchronization will provide a new link between both that can help
1073 text editors and viewers to work together.
1074 More precisely, forwards synchronization is the ability,
1075 given a location in the input source file,
1076 to find what is the corresponding place in the output.
1077 Backwards synchronization just performs the opposite:
1078 given a location in the output,
1079 retrieve the corresponding material in the input source file.
1081 For better code management and maintainance, we adopt a naming convention.
1082 Throughout this program, code related to the {\sl Synchronize \TeX nology} is tagged
1083 with the ``{\sl synctex}'' key word. Any code extract where {\sl Sync\TeX} plays
1084 its part, either explicitly or implicitly, (should) contain the string ``{\sl synctex}''.
1085 This naming convention also holds for external files.
1086 Moreover, all the code related to {\sl Sync\TeX} is gathered in this section,
1087 except the definitions.
1089 Enabling synchronization should be performed from the command line,
1090 |synctexoption| is used for that purpose.
1091 This global integer variable is declared here but it is not used here.
1092 This is just a placeholder where the command line controller will put
1093 the {\sl Sync\TeX} related options, and the {\sl Sync\TeX} controller will read them.
1096 int synctexoption;
1098 @ A convenient primitive is provided:
1099 \.{\\synctex=1} in the input source file enables synchronization whereas
1100 \.{\\synctex=0} disables it.
1101 Its memory address is |synctex_code|.
1102 It is initialized by the {\sl Sync\TeX} controller to the command-line option if given.
1103 The controller may filter some reserved bits.
1105 In order to give the {\sl Sync\TeX} controller read and write access to
1106 the contents of the \.{\\synctex} primitive, we declare |synctexoffset|,
1107 such that |mem[synctexoffset]| and \.{\\synctex} correspond to
1108 the same memory storage. |synctexoffset| is initialized to
1109 the correct value when quite everything is initialized.
1112 int synctexoffset; /* holds the true value of |synctex_code| */
1114 @ Synchronization is achieved with the help of an auxiliary file named
1115 `\.{{\sl jobname}.synctex}' ({\sl jobname} is the contents of the
1116 \.{\\jobname} macro), where a {\sl Sync\TeX} controller implemented
1117 in the external |synctex.c| file will store geometrical information.
1118 This {\sl Sync\TeX} controller will take care of every technical details
1119 concerning the {\sl Sync\TeX} file, we will only focus on the messages
1120 the controller will receive from the \TeX\ program.
1122 The most accurate synchronization information should allow to map
1123 any character of the input source file to the corresponding location
1124 in the output, if relevant.
1125 Ideally, the synchronization information of the input material consists of
1126 the file name, the line and column numbers of every character.
1127 The synchronization information in the output is simply the page number and
1128 either point coordinates, or box dimensions and position.
1129 The problem is that the mapping between these informations is only known at
1130 ship out time, which means that we must keep track of the input
1131 synchronization information until the pages ship out.
1133 As \TeX\ only knows about file names and line numbers,
1134 but forgets the column numbers, we only consider a
1135 restricted input synchronization information called {\sl Sync\TeX\ information}.
1136 It consists of a unique file name identifier, the {\sl Sync\TeX\ file tag},
1137 and the line number.
1139 Keeping track of such information,
1140 should be different whether characters or nodes are involved.
1141 Actually, only certain nodes are involved in {\sl Sync\TeX},
1142 we call them {\sl synchronized nodes}.
1143 Synchronized nodes store the {\sl Sync\TeX} information in their last two words:
1144 the first one contains a {\sl Sync\TeX\ file tag} uniquely identifying
1145 the input file, and the second one contains the current line number,
1146 as returned by the \.{\\inputlineno} primitive.
1147 The |synctex_field_size| macro contains the necessary size to store
1148 the {\sl Sync\TeX} information in a node.
1150 When declaring the size of a new node, it is recommanded to use the following
1151 convention: if the node is synchronized, use a definition similar to
1152 |my_synchronized_node_size|={\sl xxx}+|synctex_field_size|.
1153 Moreover, one should expect that the {\sl Sync\TeX} information is always stored
1154 in the last two words of a synchronized node.
1156 By default, every node with a sufficiently big size is initialized
1157 at creation time in the |get_node| routine with the current
1158 {\sl Sync\TeX} information, whether or not the node is synchronized.
1159 One purpose is to set this information very early in order to minimize code
1160 dependencies, including forthcoming extensions.
1161 Another purpose is to avoid the assumption that every node type has a dedicated getter,
1162 where initialization should take place. Actually, it appears that some nodes are created
1163 using directly the |get_node| routine and not the dedicated constructor.
1164 And finally, initializing the node at only one place is less error prone.
1166 Instead of storing the input file name, it is better to store just an identifier.
1167 Each time \TeX\ opens a new file, it notifies the {\sl Sync\TeX} controller with
1168 a |synctex_start_input| message.
1169 This controller will create a new {\sl Sync\TeX} file tag and
1170 will update the current input state record accordingly.
1171 If the input comes from the terminal or a pseudo file, the |synctex_tag| is set to 0.
1172 It results in automatically disabling synchronization for material
1173 input from the terminal or pseudo files.
1175 Synchronized nodes are boxes, math, kern and glue nodes.
1176 Other nodes should be synchronized too, in particular math noads.
1177 \TeX\ assumes that math, kern and glue nodes have the same size,
1178 this is why both are synchronized.
1179 {\sl In fine}, only horizontal lists are really used in {\sl Sync\TeX},
1180 but all box nodes are considered the same with respect to synchronization,
1181 because a box node type is allowed to change at execution time.
1183 {\sl Nota Bene:}
1184 The {\sl Sync\TeX} code is very close to the memory model.
1185 It is not connected to any other part of the code,
1186 except for memory management. It is possible to neutralize the {\sl Sync\TeX} code
1187 rather simply. The first step is to define a null |synctex_field_size|.
1188 The second step is to comment out the code in ``Initialize bigger nodes...'' and every
1189 ``Copy ... {\sl Sync\TeX} information''.
1190 The last step will be to comment out the |synctex_tag_field| related code in the
1191 definition of |synctex_tag| and the various ``Prepare ... {\sl Sync\TeX} information''.
1192 Then all the remaining code should be just harmless.
1193 The resulting program would behave exactly the same as if absolutely no {\sl Sync\TeX}
1194 related code was there, including memory management.
1195 Of course, all this assumes that {\sl Sync\TeX} is turned off from the command line.
1196 @^synctex@>
1197 @^synchronization@>
1199 @ Here are extra variables for Web2c. (This numbering of the
1200 system-dependent section allows easy integration of Web2c and e-\TeX, etc.)
1201 @^<system dependencies@>
1204 pool_pointer edit_name_start; /* where the filename to switch to starts */
1205 int edit_name_length, edit_line; /* what line to start editing at */
1206 int ipcon; /* level of IPC action, 0 for none [default] */
1207 boolean stop_at_space; /* whether |more_name| returns false for space */
1209 @ The |edit_name_start| will be set to point into |str_pool| somewhere after
1210 its beginning if \TeX\ is supposed to switch to an editor on exit.
1213 int shellenabledp;
1214 int restrictedshell;
1215 char *output_comment;
1217 @ Are we printing extra info as we read the format file?
1220 boolean debug_format_file;