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