summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/tex
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/web2c/luatexdir/tex
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/tex')
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.c1299
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/align.h54
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/arithmetic.c815
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/arithmetic.h80
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/backend.c124
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/backend.h54
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/buildpage.c1164
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/buildpage.h74
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.c936
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/commands.h359
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/conditional.c568
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/conditional.h78
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.c196
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/directions.h168
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/dumpdata.c539
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/dumpdata.h114
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/equivalents.c1220
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/equivalents.h916
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/errors.c1055
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/errors.h116
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/expand.c967
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/expand.h102
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.c1344
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/extensions.h147
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/filename.c383
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/filename.h33
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/inputstack.c960
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/inputstack.h344
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.c2537
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/linebreak.h98
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mainbody.c780
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mainbody.h246
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.c4245
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/maincontrol.h217
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mathcodes.c360
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mathcodes.h67
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/memoryword.c29
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/memoryword.h128
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.c4830
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/mlist.h41
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/nesting.c429
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/nesting.h70
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.c2145
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/packaging.h156
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.c603
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/postlinebreak.h50
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/primitive.c785
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/primitive.h89
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/printing.c1350
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/printing.h133
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/scanning.c2751
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/scanning.h109
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/stringpool.c375
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/stringpool.h142
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texdeffont.c247
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texdeffont.h30
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texfileio.c1509
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texfileio.h145
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.c2727
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texmath.h306
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.c4840
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/texnodes.h1188
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textcodes.c530
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textcodes.h54
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.c3920
-rw-r--r--Build/source/texk/web2c/luatexdir/tex/textoken.h189
66 files changed, 0 insertions, 52659 deletions
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.c b/Build/source/texk/web2c/luatexdir/tex/align.c
deleted file mode 100644
index bb721856fac..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/align.c
+++ /dev/null
@@ -1,1299 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-void fin_align(void);
-void init_row(void);
-void init_col(void);
-
-#define noDEBUG
-
-/*tex
-
- It's sort of a miracle whenever \.{\\halign} and \.{\\valign} work, because
- they cut across so many of the control structures of \TeX. Therefore the
- present page is probably not the best place for a beginner to start reading
- this program; it is better to master everything else first.
-
- Let us focus our thoughts on an example of what the input might be, in order
- to get some idea about how the alignment miracle happens. The example doesn't
- do anything useful, but it is sufficiently general to indicate all of the
- special cases that must be dealt with; please do not be disturbed by its
- apparent complexity and meaninglessness.
-
- \starttyping
- \tabskip 2pt plus 3pt
- \halign to 300pt{u1#v1&
- \hskip 50pt \tabskip 1pt plus 1fil u2#v2&
- \hskip 50pt u3#v3\cr
- \hskip 25pt a1&\omit a2&\vrule\cr
- \hskip 25pt \noalign\{\vskip 3pt}
- \hskip 25pt b1\span b2\cr
- \hskip 25pt \omit&c2\span\omit\cr}
- \stoptyping
-
- Here's what happens:
-
- \startitemize
-
- \startitem
- When `\.{\\halign to 300pt\{}' is scanned, the |scan_spec| routine
- places the 300pt dimension onto the |save_stack|, and an
- |align_group| code is placed above it. This will make it possible to
- complete the alignment when the matching `\.\}' is found.
- \stopitem
-
- \startitem
- The preamble is scanned next. Macros in the preamble are not
- expanded, except as part of a tabskip specification. For example, if
- \.{u2} had been a macro in the preamble above, it would have been
- expanded, since \TeX\ must look for `\.{minus...}' as part of the
- tabskip glue. A ``preamble list'' is constructed based on the user's
- preamble; in our case it contains the following seven items:
-
- \starttabulate
- \NC \type{\glue 2pt plus 3pt} \NC the tabskip preceding column 1 \NC \NR
- \NC \type{\alignrecord} of width $-\infty$ \NC preamble info for column 1 \NC \NR
- \NC \type{\glue 2pt plus 3pt} \NC the tabskip between columns 1 and 2 \NC \NR
- \NC \type{\alignrecord} of width $-\infty$ \NC preamble info for column 2 \NC \NR
- \NC \type{\glue 1pt plus 1fil} \NC the tabskip between columns 2 and 3 \NC \NR
- \NC \type{\alignrecord} of width $-\infty$ \NC preamble info for column 3 \NC \NR
- \NC \type{\glue 1pt plus 1fil} \NC the tabskip following column 3 \NC \NR
- \stoptabulate
-
- These ``alignrecord'' entries have the same size as an |unset_node|,
- since they will later be converted into such nodes. These alignrecord
- nodes have no |depth| field; this is split into |u_part| and
- |v_part|, and they point to token lists for the templates of the
- alignment. For example, the |u_part| field in the first alignrecord
- points to the token list `\.{u1}', i.e., the template preceding the
- `\.\#' for column~1. Furthermore, They have a |span_ptr| instead of a
- |node_attr| field, and these |span_ptr| fields are initially set to
- the value |end_span|, for reasons explained below.
- \stopitem
-
- \startitem
- \TeX\ now looks at what follows the \.{\\cr} that ended the preamble.
- It is not `\.{\\noalign}' or `\.{\\omit}', so this input is put back
- to be read again, and the template `\.{u1}' is fed to the scanner.
- Just before reading `\.{u1}', \TeX\ goes into restricted horizontal
- mode. Just after reading `\.{u1}', \TeX\ will see `\.{a1}', and then
- (when the {\.\&} is sensed) \TeX\ will see `\.{v1}'. Then \TeX\ scans
- an |endv| token, indicating the end of a column. At this point an
- |unset_node| is created, containing the contents of the current hlist
- (i.e., `\.{u1a1v1}'). The natural width of this unset node replaces
- the |width| field of the alignrecord for column~1; in general, the
- alignrecords will record the maximum natural width that has occurred
- so far in a given column.
- \stopitem
-
- \startitem
- Since `\.{\\omit}' follows the `\.\&', the templates for column~2 are
- now bypassed. Again \TeX\ goes into restricted horizontal mode and
- makes an |unset_node| from the resulting hlist; but this time the
- hlist contains simply `\.{a2}'. The natural width of the new unset
- box is remembered in the |width| field of the alignrecord for
- column~2.
- \stopitem
-
- \startitem
- A third |unset_node| is created for column 3, using essentially the
- mechanism that worked for column~1; this unset box contains
- `\.{u3\\vrule v3}'. The vertical rule in this case has running
- dimensions that will later extend to the height and depth of the
- whole first row, since each |unset_node| in a row will eventually
- inherit the height and depth of its enclosing box.
- \stopitem
-
- \startitem
- The first row has now ended; it is made into a single unset box
- comprising the following seven items:
-
- \starttyping
- \glue 2pt plus 3pt
- \unsetbox for 1 column: u1a1v1
- \glue 2pt plus 3pt
- \unsetbox for 1 column: a2
- \glue 1pt plus 1fil
- \unsetbox for 1 column: u3\vrule v3
- \glue 1pt plus 1fil
- \stoptyping
-
- The width of this unset row is unimportant, but it has the correct
- height and depth, so the correct baselineskip glue will be computed
- as the row is inserted into a vertical list.
- \stopitem
-
- \startitem
- Since `\.{\\noalign}' follows the current \.{\\cr}, \TeX\ appends
- additional material (in this case \.{\\vskip 3pt}) to the vertical
- list. While processing this material, \TeX\ will be in internal
- vertical mode, and |no_align_group| will be on |save_stack|.
- \stopitem
-
- \startitem
- The next row produces an unset box that looks like this:
-
- \starttyping
- \glue 2pt plus 3pt
- \unsetbox for 2 columns: u1b1v1u2b2v2
- \glue 1pt plus 1fil
- \unsetbox for 1 column: {(empty)}
- \glue 1pt plus 1fil
- \stoptyping
-
- The natural width of the unset box that spans columns 1~and~2 is
- stored in a ``span node,'' which we will explain later; the
- |span_ptr| field of the alignrecord for column~1 now points to the
- new span node, and the |span_ptr| of the span node points to
- |end_span|.
- \stopitem
-
- \startitem
-
- The final row produces the unset box
-
- \starttyping
- \glue 2pt plus 3pt\cr
- \unsetbox for 1 column: {(empty)}
- \glue 2pt plus 3pt\cr
- \unsetbox for 2 columns: u2c2v2
- \glue 1pt plus 1fil
- \stoptyping
-
- A new span node is attached to the alignrecord for column 2.
- \stopitem
-
- \startitem
- The last step is to compute the true column widths and to change all
- the unset boxes to hboxes, appending the whole works to the vertical
- list that encloses the \.{\\halign}. The rules for deciding on the
- final widths of each unset column box will be explained below.
- \stopitem
-
- \stopitemize
-
- Note that as \.{\\halign} is being processed, we fearlessly give up control
- to the rest of \TeX. At critical junctures, an alignment routine is called
- upon to step in and do some little action, but most of the time these
- routines just lurk in the background. It's something like post-hypnotic
- suggestion.
-
- We have mentioned that alignrecords contain no |height| or |depth| fields.
- Their |glue_sign| and |glue_order| are pre-empted as well, since it is
- necessary to store information about what to do when a template ends. This
- information is called the |extra_info| field.
-
-*/
-
-/*tex The pointer to \<u_j> token list: */
-
-#define u_part(A) vlink((A)+depth_offset)
-
-/*tex The pointer to \<v_j> token list */
-
-#define v_part(A) vinfo((A)+depth_offset)
-
-/*tex A column spanning list */
-
-#define span_ptr(A) vinfo((A)+1)
-
-/*tex Info to remember during template */
-
-#define extra_info(A) vinfo((A)+list_offset)
-
-/*tex
-
- Alignments can occur within alignments, so a small stack is used to access
- the alignrecord information. At each level we have a |preamble| pointer,
- indicating the beginning of the preamble list; a |cur_align| pointer,
- indicating the current position in the preamble list; a |cur_span| pointer,
- indicating the value of |cur_align| at the beginning of a sequence of spanned
- columns; a |cur_loop| pointer, indicating the tabskip glue before an
- alignrecord that should be copied next if the current list is extended; and
- the |align_state| variable, which indicates the nesting of braces so that
- \.{\\cr} and \.{\\span} and tab marks are properly intercepted. There also
- are pointers |cur_head| and |cur_tail| to the head and tail of a list of
- adjustments being moved out from horizontal mode to vertical~mode, and alike
- |cur_pre_head| and |cur_pre_tail| for pre-adjust lists.
-
- The current values of these nine quantities appear in global variables; when
- they have to be pushed down, they are stored in 6-word nodes, and |align_ptr|
- points to the topmost such node.
-
-*/
-
-/*tex This could be in |texnodes.h| but it's documented here. */
-
-/*tex The current preamble list: */
-
-#define preamble vlink(align_head)
-
-/*tex The current position in the preamble list: */
-
-pointer cur_align = null;
-
-/*tex The start of the currently spanned columns in the preamble list: */
-
-pointer cur_span = null;
-
-/*tex A place to copy when extending a periodic preamble: */
-
-pointer cur_loop = null;
-
-/*tex The most recently pushed-down alignment stack node: */
-
-pointer align_ptr = null;
-
-/*tex Adjustment list pointers: */
-
-pointer cur_head = null, cur_tail = null;
-
-/*tex Pre-adjustment list pointers: */
-
-pointer cur_pre_head = null, cur_pre_tail = null;
-
-/*tex
-
- The |align_state| and |preamble| variables are initialized elsewhere.
-
- Alignment stack maintenance is handled by a pair of trivial routines called
- |push_alignment| and |pop_alignment|.
-
- (HH:) It makes not much sense to add support for an \.{attr} keyword to
- \.{\\halign} and \.{\\valign} because then we need to decide if we tag rows
- or cells or both or come up with \.{cellattr} and \.{rowattr} and such. But
- then it even makes sense to have explicit commands (in addition to the
- seperator) to tags individual cells. Too muss hassle for now and the
- advantages are not that large.
-
-*/
-
-static void push_alignment(void)
-{
- /*tex The new alignment stack node: */
- pointer p;
- p = new_node(align_stack_node, 0);
- vinfo(p + 1) = align_ptr;
- vlink(p + 1) = cur_align;
- vinfo(p + 2) = preamble;
- vlink(p + 2) = cur_span;
- vinfo(p + 3) = cur_loop;
- vlink(p + 3) = align_state;
- vinfo(p + 4) = cur_head;
- vlink(p + 4) = cur_tail;
- vinfo(p + 5) = cur_pre_head;
- vlink(p + 5) = cur_pre_tail;
- align_ptr = p;
- cur_head = new_node(temp_node, 0);
- cur_pre_head = new_node(temp_node, 0);
-}
-
-static void pop_alignment(void)
-{
- /*tex The top alignment stack node: */
- pointer p;
- flush_node(cur_head);
- flush_node(cur_pre_head);
- p = align_ptr;
- cur_pre_tail = vlink(p + 5);
- cur_pre_head = vinfo(p + 5);
- cur_tail = vlink(p + 4);
- cur_head = vinfo(p + 4);
- align_state = vlink(p + 3);
- cur_loop = vinfo(p + 3);
- cur_span = vlink(p + 2);
- preamble = vinfo(p + 2);
- cur_align = vlink(p + 1);
- align_ptr = vinfo(p + 1);
- flush_node(p);
-}
-
-/*tex
-
- \TeX\ has eight procedures that govern alignments: |init_align| and
- |fin_align| are used at the very beginning and the very end; |init_row| and
- |fin_row| are used at the beginning and end of individual rows; |init_span|
- is used at the beginning of a sequence of spanned columns (possibly involving
- only one column); |init_col| and |fin_col| are used at the beginning and end
- of individual columns; and |align_peek| is used after \.{\\cr} to see whether
- the next item is \.{\\noalign}.
-
- We shall consider these routines in the order they are first used during the
- course of a complete \.{\\halign}, namely |init_align|, |align_peek|,
- |init_row|, |init_span|, |init_col|, |fin_col|, |fin_row|, |fin_align|.
-
- The preamble is copied directly, except that \.{\\tabskip} causes a change to
- the tabskip glue, thereby possibly expanding macros that immediately follow
- it. An appearance of \.{\\span} also causes such an expansion.
-
- Note that if the preamble contains `\.{\\global\\tabskip}', the
- `\.{\\global}' token survives in the preamble and the `\.{\\tabskip}' defines
- new tabskip glue (locally).
-
-*/
-
-static void get_preamble_token(void)
-{
- RESTART:
- get_token();
- while ((cur_chr == span_code) && (cur_cmd == tab_mark_cmd)) {
- /*tex This token will be expanded once. */
- get_token();
- if (cur_cmd > max_command_cmd) {
- expand();
- get_token();
- }
- }
- if (cur_cmd == endv_cmd)
- fatal_error("(interwoven alignment preambles are not allowed)");
- if ((cur_cmd == assign_glue_cmd)
- && (cur_chr == glue_base + tab_skip_code)) {
- scan_optional_equals();
- scan_glue(glue_val_level);
- if (global_defs_par > 0)
- geq_define(glue_base + tab_skip_code, glue_ref_cmd, cur_val);
- else
- eq_define(glue_base + tab_skip_code, glue_ref_cmd, cur_val);
- goto RESTART;
- }
-}
-
-/*tex
-
- When \.{\\halign} or \.{\\valign} has been scanned in an appropriate mode,
- \TeX\ calls |init_align|, whose task is to get everything off to a good
- start. This mostly involves scanning the preamble and putting its information
- into the preamble list.
-
-*/
-
-void init_align(void)
-{
- /*tex |warning_index| value for error messages */
- pointer save_cs_ptr;
- /*tex for short-term temporary use */
- pointer p, r;
- /*tex \.{\\halign} or \.{\\valign}, usually */
- save_cs_ptr = cur_cs;
- push_alignment();
- /*tex enter a new alignment level */
- align_state = -1000000;
- /*tex
-
- When \.{\\halign} is used as a displayed formula, there should be no
- other pieces of mlists present.
-
- */
- if ((cur_list.mode_field == mmode) && ((cur_list.tail_field != cur_list.head_field) || (incompleat_noad_par != null))) {
- const char *hlp[] = {
- "Displays can use special alignments (like \\eqalignno)",
- "only if nothing but the alignment itself is between $$'s.",
- "So I've deleted the formulas that preceded this alignment.",
- NULL
- };
- tex_error("Improper \\halign inside $$'s", hlp);
- flush_math();
- }
- /*tex Enter a new semantic level. */
- push_nest();
- /*tex
-
- In vertical modes, |prev_depth| already has the correct value. But if we
- are in |mmode| (displayed formula mode), we reach out to the enclosing
- vertical mode for the |prev_depth| value that produces the correct
- baseline calculations.
- */
- if (cur_list.mode_field == mmode) {
- cur_list.mode_field = -vmode;
- prev_depth_par = nest[nest_ptr - 2].prev_depth_field;
- } else if (cur_list.mode_field > 0) {
- cur_list.mode_field = -(cur_list.mode_field);
- }
- scan_spec(align_group);
- /*tex Scan the preamble. */
- preamble = null;
- cur_align = align_head;
- cur_loop = null;
- scanner_status = aligning;
- warning_index = save_cs_ptr;
- align_state = -1000000;
- /*tex At this point, |cur_cmd=left_brace|. */
- while (true) {
- /*tex Append the current tabskip glue to the preamble list. */
- r = new_param_glue(tab_skip_code);
- vlink(cur_align) = r;
- cur_align = vlink(cur_align);
- if (cur_cmd == car_ret_cmd) {
- /*tex \.{\\cr} ends the preamble. */
- break;
- }
- /*tex
-
- Scan preamble text until |cur_cmd| is |tab_mark| or |car_ret| and
- then scan the template \<u_j>, putting the resulting token list in
- |hold_token_head|. Spaces are eliminated from the beginning of a
- template.
-
- */
- p = hold_token_head;
- token_link(p) = null;
- while (1) {
- get_preamble_token();
- if (cur_cmd == mac_param_cmd)
- break;
- if ((cur_cmd <= car_ret_cmd) && (cur_cmd >= tab_mark_cmd)
- && (align_state == -1000000)) {
- if ((p == hold_token_head) && (cur_loop == null) && (cur_cmd == tab_mark_cmd)) {
- cur_loop = cur_align;
- } else {
- const char *hlp[] = {
- "There should be exactly one # between &'s, when an",
- "\\halign or \\valign is being set up. In this case you had",
- "none, so I've put one in; maybe that will work.",
- NULL
- };
- back_input();
- tex_error("Missing # inserted in alignment preamble", hlp);
- break;
- }
- } else if ((cur_cmd != spacer_cmd) || (p != hold_token_head)) {
- r = get_avail();
- token_link(p) = r;
- p = token_link(p);
- token_info(p) = cur_tok;
- }
- }
- r = new_node(align_record_node, 0);
- vlink(cur_align) = r;
- /*tex A new align record: */
- cur_align = vlink(cur_align);
- span_ptr(cur_align) = end_span;
- width(cur_align) = null_flag;
- u_part(cur_align) = token_link(hold_token_head);
- /*tex
-
- Scan the template \<v_j>, putting the resulting token list in
- |hold_token_head|.
-
- */
- p = hold_token_head;
- token_link(p) = null;
- while (1) {
- CONTINUE:
- get_preamble_token();
- if ((cur_cmd <= car_ret_cmd) && (cur_cmd >= tab_mark_cmd) && (align_state == -1000000))
- break;
- if (cur_cmd == mac_param_cmd) {
- const char *hlp[] = {
- "There should be exactly one # between &'s, when an",
- "\\halign or \\valign is being set up. In this case you had",
- "more than one, so I'm ignoring all but the first.",
- NULL
- };
- tex_error("Only one # is allowed per tab", hlp);
- goto CONTINUE;
- }
- r = get_avail();
- token_link(p) = r;
- p = token_link(p);
- token_info(p) = cur_tok;
- }
- r = get_avail();
- token_link(p) = r;
- p = token_link(p);
- /*tex Put \.{\\endtemplate} at the end: */
- token_info(p) = end_template_token;
- v_part(cur_align) = token_link(hold_token_head);
- }
- scanner_status = normal;
- new_save_level(align_group);
- if (every_cr_par != null)
- begin_token_list(every_cr_par, every_cr_text);
- /*tex Look for \.{\\noalign} or \.{\\omit}. */
- align_peek();
-}
-
-/*tex
-
- The tricky part about alignments is getting the templates into the scanner at
- the right time, and recovering control when a row or column is finished.
-
- We usually begin a row after each \.{\\cr} has been sensed, unless that
- \.{\\cr} is followed by \.{\\noalign} or by the right brace that terminates
- the alignment. The |align_peek| routine is used to look ahead and do the
- right thing; it either gets a new row started, or gets a \.{\\noalign}
- started, or finishes off the alignment.
-
-*/
-
-void align_peek(void)
-{
- RESTART:
- align_state = 1000000;
- do {
- get_x_or_protected();
- } while (cur_cmd == spacer_cmd);
- if (cur_cmd == no_align_cmd) {
- scan_left_brace();
- new_save_level(no_align_group);
- if (cur_list.mode_field == -vmode)
- normal_paragraph();
- } else if (cur_cmd == right_brace_cmd) {
- fin_align();
- } else if ((cur_cmd == car_ret_cmd) && (cur_chr == cr_cr_code)) {
- /*tex Ignore \.{\\crcr}. */
- goto RESTART;
- } else {
- /*tex Start a new row. */
- init_row();
- /*tex Start a new column and replace what we peeked at. */
- init_col();
- }
-}
-
-
-/*tex
-
- The parameter to |init_span| is a pointer to the alignrecord where the next
- column or group of columns will begin. A new semantic level is entered, so
- that the columns will generate a list for subsequent packaging.
-
-*/
-
-static void init_span(pointer p)
-{
- push_nest();
- if (cur_list.mode_field == -hmode) {
- space_factor_par = 1000;
- } else {
- prev_depth_par = ignore_depth;
- normal_paragraph();
- }
- cur_span = p;
-}
-
-/*tex
-
- To start a row (i.e., a `row' that rhymes with `dough' but not with `bough'),
- we enter a new semantic level, copy the first tabskip glue, and change from
- internal vertical mode to restricted horizontal mode or vice versa. The
- |space_factor| and |prev_depth| are not used on this semantic level, but we
- clear them to zero just to be tidy.
-
-*/
-
-void init_row(void)
-{
- push_nest();
- cur_list.mode_field = (-hmode - vmode) - cur_list.mode_field;
- if (cur_list.mode_field == -hmode)
- space_factor_par = 0;
- else
- prev_depth_par = 0;
- tail_append(new_glue(preamble));
- subtype(cur_list.tail_field) = tab_skip_code + 1;
- cur_align = vlink(preamble);
- cur_tail = cur_head;
- cur_pre_tail = cur_pre_head;
- init_span(cur_align);
-}
-
-/*tex
-
- When a column begins, we assume that |cur_cmd| is either |omit| or else the
- current token should be put back into the input until the \<u_j> template has
- been scanned. (Note that |cur_cmd| might be |tab_mark| or |car_ret|.) We also
- assume that |align_state| is approximately 1000000 at this time. We remain in
- the same mode, and start the template if it is called for.
-
-*/
-
-void init_col(void)
-{
- extra_info(cur_align) = cur_cmd;
- if (cur_cmd == omit_cmd)
- align_state = 0;
- else {
- back_input();
- begin_token_list(u_part(cur_align), u_template);
- }
- /*tex now |align_state=1000000| */
-}
-
-
-/*tex
-
- The scanner sets |align_state| to zero when the \<u_j> template ends. When a
- subsequent \.{\\cr} or \.{\\span} or tab mark occurs with |align_state=0|,
- the scanner activates the following code, which fires up the \<v_j> template.
- We need to remember the |cur_chr|, which is either |cr_cr_code|, |cr_code|,
- |span_code|, or a character code, depending on how the column text has ended.
-
- This part of the program had better not be activated when the preamble to
- another alignment is being scanned, or when no alignment preamble is active.
-
-*/
-
-void insert_vj_template(void)
-{
- if ((scanner_status == aligning) || (cur_align == null))
- fatal_error("(interwoven alignment preambles are not allowed)");
- cur_cmd = extra_info(cur_align);
- extra_info(cur_align) = cur_chr;
- if (cur_cmd == omit_cmd)
- begin_token_list(omit_template, v_template);
- else
- begin_token_list(v_part(cur_align), v_template);
- align_state = 1000000;
-}
-
-/*tex Determine the stretch order */
-
-#define determine_stretch_order() do { \
- if (total_stretch[filll]!= 0) o = filll; \
- else if (total_stretch[fill] != 0) o = fill; \
- else if (total_stretch[fil] != 0) o = fil; \
- else if (total_stretch[sfi] != 0) o = sfi; \
- else o=normal; \
-} while (0)
-
-/*tex Determine the shrink order */
-
-#define determine_shrink_order() do { \
- if (total_shrink[filll] != 0) o = filll; \
- else if (total_shrink[fill] != 0) o = fill; \
- else if (total_shrink[fil] != 0) o = fil; \
- else if (total_shrink[sfi] != 0) o = sfi; \
- else o=normal; \
-} while (0)
-
-/*tex
-
- When the |endv| command at the end of a \<v_j> template comes through the
- scanner, things really start to happen; and it is the |fin_col| routine that
- makes them happen. This routine returns |true| if a row as well as a column
- has been finished.
-
-*/
-
-boolean fin_col(void)
-{
- /*tex the alignrecord after the current one */
- pointer p;
- /*tex temporary pointers for list manipulation */
- pointer q, r;
- /*tex a new span node */
- pointer s;
- /*tex a new unset box */
- pointer u;
- /*tex natural width */
- scaled w;
- /*tex order of infinity */
- unsigned char o;
- /*tex span counter */
- halfword n;
- if (cur_align == null)
- confusion("endv");
- q = vlink(cur_align);
- if (q == null)
- confusion("endv");
- if (align_state < 500000)
- fatal_error("(interwoven alignment preambles are not allowed)");
- p = vlink(q);
- /*tex If the preamble list has been traversed, check that the row has ended. */
- if ((p == null) && (extra_info(cur_align) < cr_code)) {
- if (cur_loop != null) {
- /*tex Lengthen the preamble periodically: */
- r = new_node(align_record_node, 0);
- vlink(q) = r;
- /*tex A new align record: */
- p = vlink(q);
- span_ptr(p) = end_span;
- width(p) = null_flag;
- cur_loop = vlink(cur_loop);
- /*tex Copy the templates from node |cur_loop| into node |p|. */
- q = hold_token_head;
- r = u_part(cur_loop);
- while (r != null) {
- s = get_avail();
- token_link(q) = s;
- q = token_link(q);
- token_info(q) = token_info(r);
- r = token_link(r);
- }
- token_link(q) = null;
- u_part(p) = token_link(hold_token_head);
- q = hold_token_head;
- r = v_part(cur_loop);
- while (r != null) {
- s = get_avail();
- token_link(q) = s;
- q = token_link(q);
- token_info(q) = token_info(r);
- r = token_link(r);
- }
- token_link(q) = null;
- v_part(p) = token_link(hold_token_head);
- cur_loop = vlink(cur_loop);
- r = new_glue(cur_loop);
- vlink(p) = r;
- } else {
- const char *hlp[] = {
- "You have given more \\span or & marks than there were",
- "in the preamble to the \\halign or \\valign now in progress.",
- "So I'll assume that you meant to type \\cr instead.",
- NULL
- };
- extra_info(cur_align) = cr_code;
- tex_error("Extra alignment tab has been changed to \\cr", hlp);
- }
- }
- if (extra_info(cur_align) != span_code) {
- unsave();
- new_save_level(align_group);
- /*tex Package an unset box for the current column and record its width. */
- if (cur_list.mode_field == -hmode) {
- adjust_tail = cur_tail;
- pre_adjust_tail = cur_pre_tail;
- u = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0, additional, align_set_group, -1, 0, 0);
- w = width(u);
- cur_tail = adjust_tail;
- adjust_tail = null;
- cur_pre_tail = pre_adjust_tail;
- pre_adjust_tail = null;
- } else {
- u = filtered_vpackage(vlink(cur_list.head_field), 0, additional, 0, align_set_group, -1, 0, 0);
- w = height(u);
- }
- /*tex This represents a span count of 1: */
- n = min_quarterword;
- if (cur_span != cur_align) {
- /*tex Update width entry for spanned columns. */
- q = cur_span;
- do {
- incr(n);
- q = vlink(vlink(q));
- } while (q != cur_align);
- if (n > max_quarterword) {
- /*tex This can happen, but won't. */
- confusion("too many spans");
- }
- q = cur_span;
- while (span_span(span_ptr(q)) < n) {
- q = span_ptr(q);
- }
- if (span_span(span_ptr(q)) > n) {
- s = new_span_node(span_ptr(q), n, w);
- span_ptr(q) = s;
- } else if (width(span_ptr(q)) < w) {
- width(span_ptr(q)) = w;
- }
- } else if (w > width(cur_align)) {
- width(cur_align) = w;
- }
- type(u) = unset_node;
- span_count(u) = (quarterword) n;
- determine_stretch_order();
- glue_order(u) = o;
- glue_stretch(u) = total_stretch[o];
- determine_shrink_order();
- glue_sign(u) = o;
- glue_shrink(u) = total_shrink[o];
- pop_nest();
- vlink(cur_list.tail_field) = u;
- cur_list.tail_field = u;
- /*tex Copy the tabskip glue between columns. */
- tail_append(new_glue(vlink(cur_align)));
- subtype(cur_list.tail_field) = tab_skip_code + 1;
- if (extra_info(cur_align) >= cr_code) {
- return true;
- }
- init_span(p);
- }
- align_state = 1000000;
- do {
- get_x_or_protected();
- } while (cur_cmd == spacer_cmd);
- cur_align = p;
- init_col();
- return false;
-}
-
-/*tex
-
- A span node is a 3-word record containing |width|, |span_span|, and
- |span_ptr| fields. The |span_span| field indicates the number of spanned
- columns; the |span_ptr| field points to a span node for the same starting
- column, having a greater extent of spanning, or to |end_span|, which has the
- largest possible |span_span| field; the |width| field holds the largest
- natural width corresponding to a particular set of spanned columns.
-
- A list of the maximum widths so far, for spanned columns starting at a given
- column, begins with the |span_ptr| field of the alignrecord for that column.
- The code has to make sure that there is room for |span_ptr| in both the
- alignrecord and the span nodes, which is why |span_ptr| replaces |node_attr|.
-
- The |new_span_node| function is defined in |texnodes.c|.
-
-*/
-
-/*tex This is normally |alink|: */
-
-#ifndef span_span
-# define span_span(A) vlink((A)+1)
-#endif
-
-/*tex
-
- At the end of a row, we append an unset box to the current vlist (for
- \.{\\halign}) or the current hlist (for \.{\\valign}). This unset box
- contains the unset boxes for the columns, separated by the tabskip glue.
- Everything will be set later.
-
-*/
-
-void fin_row(void)
-{
- /*tex The new unset box: */
- pointer p;
- if (cur_list.mode_field == -hmode) {
- p = filtered_hpack(cur_list.head_field, cur_list.tail_field, 0,
- additional, fin_row_group, -1, 0, 0);
- pop_nest();
- if (cur_pre_head != cur_pre_tail)
- append_list(cur_pre_head, cur_pre_tail);
- append_to_vlist(p,lua_key_index(alignment));
- if (cur_head != cur_tail)
- append_list(cur_head, cur_tail);
- } else {
- p = filtered_vpackage(vlink(cur_list.head_field),
- 0, additional, max_depth_par, fin_row_group, -1, 0, 0);
- pop_nest();
- vlink(cur_list.tail_field) = p;
- cur_list.tail_field = p;
- space_factor_par = 1000;
- }
- type(p) = unset_node;
- glue_stretch(p) = 0;
- if (every_cr_par != null)
- begin_token_list(every_cr_par, every_cr_text);
- align_peek();
- /*tex Note that |glue_shrink(p)=0| since |glue_shrink==shift_amount|. */
-}
-
-/*tex
-
- Finally, we will reach the end of the alignment, and we can breathe a sigh of
- relief that memory hasn't overflowed. All the unset boxes will now be set so
- that the columns line up, taking due account of spanned columns.
-
-*/
-
-void fin_align(void)
-{
- /*tex registers for the list operations */
- pointer p, q, r, s, u, rr;
- /*tex width of column */
- scaled t, w;
- /*tex shift offset for unset boxes */
- scaled o;
- /*tex matching span amount */
- halfword n;
- /*tex temporary storage for |overfull_rule| */
- scaled rule_save;
- /*tex temporary storage for |prev_depth| */
- halfword pd;
- /*tex temporary storage for |new_glue| */
- halfword ng;
- /*tex The |align_group| was for individual entries: */
- if (cur_group != align_group)
- confusion("align1");
- unsave();
- /*tex The |align_group| was for the whole alignment: */
- if (cur_group != align_group)
- confusion("align0");
- unsave();
- if (nest[nest_ptr - 1].mode_field == mmode) {
- o = display_indent_par;
- } else {
- o = 0;
- }
- /*tex
-
- Go through the preamble list, determining the column widths and
- changing the alignrecords to dummy unset boxes.
-
- It's time now to dismantle the preamble list and to compute the
- column widths. Let $w_{ij}$ be the maximum of the natural widths of
- all entries that span columns $i$ through $j$, inclusive. The
- alignrecord for column~$i$ contains $w_{ii}$ in its |width| field,
- and there is also a linked list of the nonzero $w_{ij}$ for
- increasing $j$, accessible via the |info| field; these span nodes
- contain the value $j-i+|min_quarterword|$ in their |link| fields. The
- values of $w_{ii}$ were initialized to |null_flag|, which we regard
- as $-\infty$.
-
- The final column widths are defined by the formula $$w_j=\max_{1\L
- i\L j}\biggl( w_{ij}-\sum_{i\L k<j}(t_k+w_k)\biggr),$$ where $t_k$ is
- the natural width of the tabskip glue between columns $k$ and~$k+1$.
- However, if $w_{ij}=-\infty$ for all |i| in the range |1<=i<=j|
- (i.e., if every entry that involved column~|j| also involved
- column~|j+1|), we let $w_j=0$, and we zero out the tabskip glue after
- column~|j|.
-
- \TeX\ computes these values by using the following scheme: First
- $w_1=w_{11}$. Then replace $w_{2j}$ by $\max(w_{2j},w_{1j}-t_1-w_1)$,
- for all $j>1$. Then $w_2=w_{22}$. Then replace $w_{3j}$ by
- $\max(w_{3j},w_{2j}-t_2-w_2)$ for all $j>2$; and so on. If any $w_j$
- turns out to be $-\infty$, its value is changed to zero and so is the
- next tabskip.
-
- */
- q = vlink(preamble);
- do {
- flush_list(u_part(q));
- flush_list(v_part(q));
- p = vlink(vlink(q));
- if (width(q) == null_flag) {
- /*tex Nullify |width(q)| and the tabskip glue following this column. */
- width(q) = 0;
- r = vlink(q);
- reset_glue_to_zero(r);
- }
- if (span_ptr(q) != end_span) {
- /*tex
-
- Merge the widths in the span nodes of |q| with those of |p|,
- destroying the span nodes of |q|.
-
- Merging of two span-node lists is a typical exercise in the
- manipulation of linearly linked data structures. The essential
- invariant in the following |repeat| loop is that we want to
- dispense with node |r|, in |q|'s list, and |u| is its successor;
- all nodes of |p|'s list up to and including |s| have been
- processed, and the successor of |s| matches |r| or precedes |r|
- or follows |r|, according as |link(r)=n| or |link(r)>n| or
- |link(r)<n|.
-
- */
- t = width(q) + width(vlink(q));
- r = span_ptr(q);
- s = end_span;
- span_ptr(s) = p;
- n = min_quarterword + 1;
- do {
- width(r) = width(r) - t;
- u = span_ptr(r);
- while (span_span(r) > n) {
- s = span_ptr(s);
- n = span_span(span_ptr(s)) + 1;
- }
- if (span_span(r) < n) {
- span_ptr(r) = span_ptr(s);
- span_ptr(s) = r;
- decr(span_span(r));
- s = r;
- } else {
- if (width(r) > width(span_ptr(s)))
- width(span_ptr(s)) = width(r);
- flush_node(r);
- }
- r = u;
- } while (r != end_span);
- }
- type(q) = unset_node;
- span_count(q) = min_quarterword;
- height(q) = 0;
- depth(q) = 0;
- glue_order(q) = normal;
- glue_sign(q) = normal;
- glue_stretch(q) = 0;
- glue_shrink(q) = 0;
- q = p;
- } while (q != null);
- /*tex
-
- Package the preamble list, to determine the actual tabskip glue amounts,
- and let |p| point to this prototype box.
-
- Now the preamble list has been converted to a list of alternating unset
- boxes and tabskip glue, where the box widths are equal to the final
- column sizes. In case of \.{\\valign}, we change the widths to heights,
- so that a correct error message will be produced if the alignment is
- overfull or underfull.
-
- */
- decr(save_ptr);
- pack_begin_line = -cur_list.ml_field;
- if (cur_list.mode_field == -vmode) {
- rule_save = overfull_rule_par;
- /*tex Prevent the rule from being packaged. */
- overfull_rule_par = 0;
- p = hpack(preamble, saved_value(0), saved_level(0), -1);
- overfull_rule_par = rule_save;
- } else {
- q = vlink(preamble);
- do {
- height(q) = width(q);
- width(q) = 0;
- q = vlink(vlink(q));
- } while (q != null);
- p = filtered_vpackage(preamble,
- saved_value(0), saved_level(0), max_depth_par, preamble_group, -1, 0, 0);
- q = vlink(preamble);
- do {
- width(q) = height(q);
- height(q) = 0;
- q = vlink(vlink(q));
- } while (q != null);
- }
- pack_begin_line = 0;
- /*tex Set the glue in all the unset boxes of the current list. */
- q = vlink(cur_list.head_field);
- s = cur_list.head_field;
- while (q != null) {
- if (!is_char_node(q)) {
- if (type(q) == unset_node) {
- /*tex
-
- We set the unset box |q| and the unset boxes in it. The unset
- box |q| represents a row that contains one or more unset
- boxes, depending on how soon \.{\\cr} occurred in that row.
-
- */
- if (cur_list.mode_field == -vmode) {
- type(q) = hlist_node;
- subtype(q) = align_row_list;
- width(q) = width(p);
- } else {
- type(q) = vlist_node;
- subtype(q) = align_row_list;
- height(q) = height(p);
- }
- glue_order(q) = glue_order(p);
- glue_sign(q) = glue_sign(p);
- glue_set(q) = glue_set(p);
- shift_amount(q) = o;
- r = vlink(list_ptr(q));
- if (type(r) != unset_node) {
- formatted_error("alignment","bad box");
- }
- s = vlink(list_ptr(p));
- do {
- /*tex
-
- We set the glue in node |r| and change it from an unset
- node. A box made from spanned columns will be followed by
- tabskip glue nodes and by empty boxes as if there were no
- spanning. This permits perfect alignment of subsequent
- entries, and it prevents values that depend on floating
- point arithmetic from entering into the dimensions of any
- boxes.
-
- */
- n = span_count(r);
- t = width(s);
- w = t;
- u = hold_head;
- while (n > min_quarterword) {
- decr(n);
- /*tex
-
- Append tabskip glue and an empty box to list |u|, and
- update |s| and |t| as the prototype nodes are passed.
-
- */
- s = vlink(s);
- ng = new_glue(s);
- vlink(u) = ng;
- u = vlink(u);
- subtype(u) = tab_skip_code + 1;
- t = t + width(s);
- if (glue_sign(p) == stretching) {
- if (stretch_order(s) == glue_order(p))
- t = t + round(float_cast(glue_set(p)) * float_cast(stretch(s)));
- } else if (glue_sign(p) == shrinking) {
- if (shrink_order(s) == glue_order(p))
- t = t - round(float_cast(glue_set(p)) * float_cast(shrink(s)));
- }
- s = vlink(s);
- rr = new_null_box();
- vlink(u) = rr;
- u = vlink(u);
- t = t + width(s);
- subtype(u) = align_cell_list;
- if (cur_list.mode_field == -vmode) {
- width(u) = width(s);
- } else {
- type(u) = vlist_node;
- height(u) = width(s);
- }
- }
- if (cur_list.mode_field == -vmode) {
- /*tex
-
- Make the unset node |r| into an |hlist_node| of width
- |w|, setting the glue as if the width were |t|.
-
- */
- height(r) = height(q);
- depth(r) = depth(q);
- if (t == width(r)) {
- glue_sign(r) = normal;
- glue_order(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- } else if (t > width(r)) {
- glue_sign(r) = stretching;
- if (glue_stretch(r) == 0)
- set_glue_ratio_zero(glue_set(r));
- else
- glue_set(r) = unfloat((double) (t - width(r)) / glue_stretch(r));
- } else {
- glue_order(r) = glue_sign(r);
- glue_sign(r) = shrinking;
- if (glue_shrink(r) == 0)
- set_glue_ratio_zero(glue_set(r));
- else if ((glue_order(r) == normal) && (width(r) - t > glue_shrink(r)))
- set_glue_ratio_one(glue_set(r));
- else
- glue_set(r) = unfloat((double) (width(r) - t) / glue_shrink(r));
- }
- width(r) = w;
- type(r) = hlist_node;
- subtype(r) = align_cell_list;
-
- } else {
- /*tex
-
- Make the unset node |r| into a |vlist_node| of height
- |w|, setting the glue as if the height were |t|.
-
- */
- width(r) = width(q);
- if (t == height(r)) {
- glue_sign(r) = normal;
- glue_order(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- } else if (t > height(r)) {
- glue_sign(r) = stretching;
- if (glue_stretch(r) == 0)
- set_glue_ratio_zero(glue_set(r));
- else
- glue_set(r) = unfloat((t - height(r)) / glue_stretch(r));
- } else {
- glue_order(r) = glue_sign(r);
- glue_sign(r) = shrinking;
- if (glue_shrink(r) == 0)
- set_glue_ratio_zero(glue_set(r));
- else if ((glue_order(r) == normal) && (height(r) - t > glue_shrink(r)))
- set_glue_ratio_one(glue_set(r));
- else
- glue_set(r) = unfloat((height(r) - t) / glue_shrink(r));
- }
- height(r) = w;
- type(r) = vlist_node;
- subtype(r) = align_cell_list;
- }
- shift_amount(r) = 0;
- if (u != hold_head) {
- /*tex Append blank boxes to account for spanned nodes. */
- vlink(u) = vlink(r);
- vlink(r) = vlink(hold_head);
- r = u;
- }
-
- r = vlink(vlink(r));
- s = vlink(vlink(s));
- } while (r != null);
-
- } else if (type(q) == rule_node) {
- /*tex
-
- Make the running dimensions in rule |q| extend to the
- boundaries of the alignment.
-
- */
- if (is_running(width(q)))
- width(q) = width(p);
- if (is_running(height(q)))
- height(q) = height(p);
- if (is_running(depth(q)))
- depth(q) = depth(p);
- if (o != 0) {
- r = vlink(q);
- vlink(q) = null;
- q = hpack(q, 0, additional, -1);
- shift_amount(q) = o;
- subtype(q) = align_cell_list;
- vlink(q) = r;
- vlink(s) = q;
- }
- }
- }
- s = q;
- q = vlink(q);
- }
- flush_node_list(p);
- pop_alignment();
- /*tex
-
- We now have a completed alignment, in the list that starts at
- |cur_list.head_field| and ends at |cur_list.tail_field|. This list will
- be merged with the one that encloses it. (In case the enclosing mode is
- |mmode|, for displayed formulas, we will need to insert glue before and
- after the display; that part of the program will be deferred until we're
- more familiar with such operations.)
-
- */
- pd = prev_depth_par;
- p = vlink(cur_list.head_field);
- q = cur_list.tail_field;
- pop_nest();
- if (cur_list.mode_field == mmode) {
- finish_display_alignment(p, q, pd);
- } else {
- prev_depth_par = pd;
- vlink(cur_list.tail_field) = p;
- if (p != null)
- cur_list.tail_field = q;
- if (cur_list.mode_field == vmode) {
- if (!output_active)
- lua_node_filter_s(buildpage_filter_callback,lua_key_index(alignment));
- build_page();
- }
- }
-}
-
-/*tex
-
- The token list |omit_template| just referred to is a constant token list that
- contains the special control sequence \.{\\endtemplate} only.
-
-*/
-
-void initialize_alignments(void)
-{
- token_info(omit_template) = end_template_token;
- span_span(end_span) = max_quarterword + 1;
- span_ptr(end_span) = null;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/align.h b/Build/source/texk/web2c/luatexdir/tex/align.h
deleted file mode 100644
index a93539f0dc5..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/align.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* align.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef ALIGN_H
-# define ALIGN_H 1
-
-/* We enter `\.{\\span}' into |eqtb| with |tab_mark| as its command code,
-and with |span_code| as the command modifier. This makes \TeX\ interpret it
-essentially the same as an alignment delimiter like `\.\&', yet it is
-recognizably different when we need to distinguish it from a normal delimiter.
-It also turns out to be useful to give a special |cr_code| to `\.{\\cr}',
-and an even larger |cr_cr_code| to `\.{\\crcr}'.
-
-The end of a template is represented by two ``frozen'' control sequences
-called \.{\\endtemplate}. The first has the command code |end_template|, which
-is |>outer_call|, so it will not easily disappear in the presence of errors.
-The |get_x_token| routine converts the first into the second, which has |endv|
-as its command code.
-*/
-
-# define tab_mark_cmd_code 1114113 /* {|biggest_char+2|} */
-# define span_code 1114114 /* {|biggest_char+3|} */
-# define cr_code (span_code+1) /* distinct from |span_code| and from any character */
-# define cr_cr_code (cr_code+1) /* this distinguishes \.{\\crcr} from \.{\\cr} */
-
-
-extern void init_align(void);
-extern void initialize_alignments(void);
-
-extern boolean fin_col(void);
-extern void fin_row(void);
-
-extern void align_peek(void);
-extern void insert_vj_template(void);
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/arithmetic.c b/Build/source/texk/web2c/luatexdir/tex/arithmetic.c
deleted file mode 100644
index 2782c253400..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/arithmetic.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
-
-arithmetic.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-The principal computations performed by \TeX\ are done entirely in terms of
-integers less than $2^{31}$ in magnitude; and divisions are done only when both
-dividend and divisor are nonnegative. Thus, the arithmetic specified in this
-program can be carried out in exactly the same way on a wide variety of
-computers, including some small ones. Why? Because the arithmetic calculations
-need to be spelled out precisely in order to guarantee that \TeX\ will produce
-identical output on different machines. If some quantities were rounded
-differently in different implementations, we would find that line breaks and even
-page breaks might occur in different places. Hence the arithmetic of \TeX\ has
-been designed with care, and systems that claim to be implementations of \TeX82
-should follow precisely the @:TeX82}{\TeX82@> calculations as they appear in the
-present program.
-
-Actually there are three places where \TeX\ uses |div| with a possibly negative
-numerator. These are harmless; see |div| in the index. Also if the user sets the
-\.{\\time} or the \.{\\year} to a negative value, some diagnostic information
-will involve negative-numerator division. The same remarks apply for |mod| as
-well as for |div|.
-
-Here is a routine that calculates half of an integer, using an unambiguous
-convention with respect to signed odd numbers.
-
-*/
-
-int half(int x)
-{
- if (odd(x))
- return ((x + 1) / 2);
- else
- return (x / 2);
-}
-
-/*tex
-
-The following function is used to create a scaled integer from a given decimal
-fraction $(.d_0d_1\ldots d_{k-1})$, where |0<=k<=17|. The digit $d_i$ is
-given in |dig[i]|, and the calculation produces a correctly rounded result.
-
-*/
-
-scaled round_decimals(int k)
-{
- int a = 0;
- while (k-- > 0) {
- a = (a + dig[k] * two) / 10;
- }
- return ((a + 1) / 2);
-}
-
-/*tex
-
-Conversely, here is a procedure analogous to |print_int|. If the output of this
-procedure is subsequently read by \TeX\ and converted by the |round_decimals|
-routine above, it turns out that the original value will be reproduced exactly;
-the ``simplest'' such decimal number is output, but there is always at least one
-digit following the decimal point.
-
-The invariant relation in the \&{repeat} loop is that a sequence of decimal
-digits yet to be printed will yield the original number if and only if they form
-a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$. We can stop if and only
-if $f=0$ satisfies this condition; the loop will terminate before $s$ can
-possibly become zero.
-
-The next one prints a scaled real, rounded to five digits.
-
-*/
-
-void print_scaled(scaled s)
-{
- /*tex The amount of allowable inaccuracy: */
- scaled delta;
- char buffer[20];
- int i = 0;
- if (s < 0) {
- /*tex Print the sign, if negative. */
- print_char('-');
- negate(s);
- }
- /*tex Print the integer part. */
- print_int(s / unity);
- buffer[i++] = '.';
- s = 10 * (s % unity) + 5;
- delta = 10;
- do {
- if (delta > unity) {
- /*tex Round the last digit. */
- s = s + 0100000 - 50000;
- }
- buffer[i++] = '0' + (s / unity);
- s = 10 * (s % unity);
- delta = delta * 10;
- } while (s > delta);
- buffer[i++] = '\0';
- tprint(buffer);
-}
-
-/*tex
-
-Physical sizes that a \TeX\ user specifies for portions of documents are
-represented internally as scaled points. Thus, if we define an `sp' (scaled
-@^sp@> point) as a unit equal to $2^{-16}$ printer's points, every dimension
-inside of \TeX\ is an integer number of sp. There are exactly 4,736,286.72 sp per
-inch. Users are not allowed to specify dimensions larger than $2^{30}-1$ sp,
-which is a distance of about 18.892 feet (5.7583 meters); two such quantities can
-be added without overflow on a 32-bit computer.
-
-The present implementation of \TeX\ does not check for overflow when @^overflow
-in arithmetic@> dimensions are added or subtracted. This could be done by
-inserting a few dozen tests of the form `\ignorespaces|if x>=010000000000 then
-@t\\{report\_overflow}@>|', but the chance of overflow is so remote that such
-tests do not seem worthwhile.
-
-\TeX\ needs to do only a few arithmetic operations on scaled quantities, other
-than addition and subtraction, and the following subroutines do most of the work.
-A single computation might use several subroutine calls, and it is desirable to
-avoid producing multiple error messages in case of arithmetic overflow; so the
-routines set the global variable |arith_error| to |true| instead of reporting
-errors directly to the user. Another global variable, |tex_remainder|, holds the
-remainder after a division.
-
-*/
-
-/*tex Has arithmetic overflow occurred recently? */
-
-boolean arith_error;
-
-/*tex The amount subtracted to get an exact division. */
-
-scaled tex_remainder;
-
-/*tex
-
- The first arithmetical subroutine we need computes $nx+y$, where |x|
-and~|y| are |scaled| and |n| is an integer. We will also use it to
-multiply integers.
-
-*/
-
-scaled mult_and_add(int n, scaled x, scaled y, scaled max_answer)
-{
- if (n == 0)
- return y;
- if (n < 0) {
- negate(x);
- negate(n);
- }
- if (((x <= (max_answer - y) / n) && (-x <= (max_answer + y) / n))) {
- return (n * x + y);
- } else {
- arith_error = true;
- return 0;
- }
-}
-
-/*tex
-
-We also need to divide scaled dimensions by integers.
-
-*/
-
-scaled x_over_n(scaled x, int n)
-{
- /*tex Should |tex_remainder| be negated? */
- boolean negative = false;
- if (n == 0) {
- arith_error = true;
- tex_remainder = x;
- return 0;
- } else {
- if (n < 0) {
- negate(x);
- negate(n);
- negative = true;
- }
- if (x >= 0) {
- tex_remainder = x % n;
- if (negative)
- negate(tex_remainder);
- return (x / n);
- } else {
- tex_remainder = -((-x) % n);
- if (negative)
- negate(tex_remainder);
- return (-((-x) / n));
- }
- }
-}
-
-/*tex
-
-Then comes the multiplication of a scaled number by a fraction |n/d|, where |n|
-and |d| are nonnegative integers |<=@t$2^{16}$@>| and |d| is positive. It would
-be too dangerous to multiply by~|n| and then divide by~|d|, in separate
-operations, since overflow might well occur; and it would be too inaccurate to
-divide by |d| and then multiply by |n|. Hence this subroutine simulates
-1.5-precision arithmetic.
-
-*/
-
-scaled xn_over_d(scaled x, int n, int d)
-{
- nonnegative_integer t, u, v, xx, dd;
- boolean positive = true;
- if (x < 0) {
- negate(x);
- positive = false;
- }
- xx = (nonnegative_integer) x;
- dd = (nonnegative_integer) d;
- t = ((xx % 0100000) * (nonnegative_integer) n);
- u = ((xx / 0100000) * (nonnegative_integer) n + (t / 0100000));
- v = (u % dd) * 0100000 + (t % 0100000);
- if (u / dd >= 0100000)
- arith_error = true;
- else
- u = 0100000 * (u / dd) + (v / dd);
- if (positive) {
- tex_remainder = (int) (v % dd);
- return (scaled) u;
- } else {
- /*tex The casts are for ms cl. */
- tex_remainder = -(int) (v % dd);
- return -(scaled) (u);
- }
-}
-
-/*tex
-
-The next subroutine is used to compute the ``badness'' of glue, when a total~|t|
-is supposed to be made from amounts that sum to~|s|. According to {\sl The \TeX
-book}, the badness of this situation is $100(t/s)^3$; however, badness is simply
-a heuristic, so we need not squeeze out the last drop of accuracy when computing
-it. All we really want is an approximation that has similar properties.
-@:TeXbook}{\sl The \TeX book@>
-
-The actual method used to compute the badness is easier to read from the program
-than to describe in words. It produces an integer value that is a reasonably
-close approximation to $100(t/s)^3$, and all implementations of \TeX\ should use
-precisely this method. Any badness of $2^{13}$ or more is treated as infinitely
-bad, and represented by 10000.
-
-It is not difficult to prove that $$\hbox{|badness(t+1,s)>=badness(t,s)
->= badness(t,s+1)|}.$$ The badness function defined here is capable of computing
-at most 1095 distinct values, but that is plenty.
-
-*/
-
-halfword badness(scaled t, scaled s)
-{
- /*tex Approximation to $\alpha t/s$, where $\alpha^3\approx 100\cdot2^{18}$ */
- int r;
- if (t == 0) {
- return 0;
- } else if (s <= 0) {
- return inf_bad;
- } else {
- /*tex $297^3=99.94\times2^{18}$ */
- if (t <= 7230584) {
- r = (t * 297) / s;
- } else if (s >= 1663497) {
- r = t / (s / 297);
- } else {
- r = t;
- }
- if (r > 1290) {
- /*tex $1290^3<2^{31}<1291^3$ */
- return inf_bad;
- } else {
- /*tex This is $r^3/2^{18}$, rounded to the nearest integer. */
- return ((r * r * r + 0400000) / 01000000);
- }
- }
-}
-
-/*tex
-
-When \TeX\ ``packages'' a list into a box, it needs to calculate the
-proportionality ratio by which the glue inside the box should stretch or shrink.
-This calculation does not affect \TeX's decision making, so the precise details
-of rounding, etc., in the glue calculation are not of critical importance for the
-consistency of results on different computers.
-
-We shall use the type |glue_ratio| for such proportionality ratios. A glue ratio
-should take the same amount of memory as an |integer| (usually 32 bits) if it is
-to blend smoothly with \TeX's other data structures. Thus |glue_ratio| should be
-equivalent to |short_real| in some implementations of PASCAL. Alternatively, it
-is possible to deal with glue ratios using nothing but fixed-point arithmetic;
-see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the routines cited there must
-be modified to allow negative glue ratios.) @^system dependencies@>
-
-*/
-
-/*
-
-This section is (almost) straight from MetaPost. I (Taco) had to change the types
-(use |integer| instead of |fraction|), but that should not have any influence on
-the actual calculations (the original comments refer to quantities like
-|fraction_four| ($2^{30}$), and that is the same as the numeric representation of
-|max_dimen|).
-
-I've copied the low-level variables and routines that are needed, but only those
-(e.g. |m_log|), not the accompanying ones like |m_exp|. Most of the following
-low-level numeric routines are only needed within the calculation of |norm_rand|.
-I've been forced to rename |make_fraction| to |make_frac| because TeX already has
-a routine by that name with a wholly different function (it creates a
-|fraction_noad| for math typesetting)
-
-And now let's complete our collection of numeric utility routines by considering
-random number generation. \MP{} generates pseudo-random numbers with the additive
-scheme recommended in Section 3.6 of {\sl The Art of Computer Programming};
-however, the results are random fractions between 0 and |fraction_one-1|,
-inclusive.
-
-There's an auxiliary array |randoms| that contains 55 pseudo-random fractions.
-Using the recurrence $x_n=(x_{n-55}-x_{n-31})\bmod 2^{28}$, we generate batches
-of 55 new $x_n$'s at a time by calling |new_randoms|. The global variable
-|j_random| tells which element has most recently been consumed.
-
-*/
-
-/*tex The last 55 random values generated: */
-
-static int randoms[55];
-
-/*tex The number of unused |randoms|: */
-
-static int j_random;
-
-/*tex The default random seed: */
-
-scaled random_seed;
-
-/*tex A small bit of \METAPOST\ is needed. */
-
-#define fraction_half 01000000000 /* $2^{27} $, represents 0.50000000 */
-#define fraction_one 02000000000 /* $2^{28} $, represents 1.00000000 */
-#define fraction_four 010000000000 /* $2^{30} $, represents 4.00000000 */
-#define el_gordo 017777777777 /* $2^{31}-1$, the largest value that \MP\ likes */
-
-/*tex
-
-The |make_frac| routine produces the |fraction| equivalent of |p/q|, given
-integers |p| and~|q|; it computes the integer
-$f=\lfloor2^{28}p/q+{1\over2}\rfloor$, when $p$ and $q$ are positive. If |p| and
-|q| are both of the same scaled type |t|, the ``type relation''
-|make_frac(t,t)=fraction| is valid; and it's also possible to use the subroutine
-``backwards,'' using the relation |make_frac(t,fraction)=t| between scaled types.
-
-If the result would have magnitude $2^{31}$ or more, |make_frac| sets
-|arith_error:=true|. Most of \MP's internal computations have been designed to
-avoid this sort of error.
-
-If this subroutine were programmed in assembly language on a typical machine, we
-could simply compute |(@t$2^{28}$@>*p)div q|, since a double-precision product
-can often be input to a fixed-point division instruction. But when we are
-restricted to PASCAL arithmetic it is necessary either to resort to
-multiple-precision maneuvering or to use a simple but slow iteration. The
-multiple-precision technique would be about three times faster than the code
-adopted here, but it would be comparatively long and tricky, involving about
-sixteen additional multiplications and divisions.
-
-This operation is part of \MP's ``inner loop''; indeed, it will consume nearly
-10\%! of the running time (exclusive of input and output) if the code below is
-left unchanged. A machine-dependent recoding will therefore make \MP\ run faster.
-The present implementation is highly portable, but slow; it avoids multiplication
-and division except in the initial stage. System wizards should be careful to
-replace it with a routine that is guaranteed to produce identical results in all
-cases. @^system dependencies@>
-
-As noted below, a few more routines should also be replaced by machine-dependent
-code, for efficiency. But when a procedure is not part of the ``inner loop,''
-such changes aren't advisable; simplicity and robustness are preferable to
-trickery, unless the cost is too high.
-
-*/
-
-static int make_frac(int p, int q)
-{
- /*tex The fraction bits, with a leading 1 bit: */
- int f;
- /*tex The integer part of $\vert p/q\vert$: */
- int n;
- /*tex Disables certain compiler optimizations: */
- register int be_careful;
- /*tex Should the result be negated? */
- boolean negative = false;
- if (p < 0) {
- negate(p);
- negative = true;
- }
- if (q <= 0) {
- negate(q);
- negative = !negative;
- }
- n = p / q;
- p = p % q;
- if (n >= 8) {
- arith_error = true;
- if (negative)
- return (-el_gordo);
- else
- return el_gordo;
- } else {
- n = (n - 1) * fraction_one;
- /*tex_remainder
-
- Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$. The |repeat| loop
- here preserves the following invariant relations between |f|, |p|,
- and~|q|: (i)~|0<=p<q|; (ii)~$fq+p=2^k(q+p_0)$, where $k$ is an
- integer and $p_0$ is the original value of~$p$.
-
- Notice that the computation specifies |(p-q)+p| instead of |(p+p)-q|,
- because the latter could overflow. Let us hope that optimizing
- compilers do not miss this point; a special variable |be_careful| is
- used to emphasize the necessary order of computation. Optimizing
- compilers should keep |be_careful| in a register, not store it in
- memory.
-
- */
- f = 1;
- do {
- be_careful = p - q;
- p = be_careful + p;
- if (p >= 0)
- f = f + f + 1;
- else {
- f += f;
- p = p + q;
- }
- } while (f < fraction_one);
- be_careful = p - q;
- if (be_careful + p >= 0)
- incr(f);
-
- if (negative)
- return (-(f + n));
- else
- return (f + n);
- }
-}
-
-static int take_frac(int q, int f)
-{
- /*tex The fraction so far: */
- int p;
- /*tex Additional multiple of $q$: */
- int n;
- /*tex Disables certain compiler optimizations. */
- register int be_careful;
- /*tex Should the result be negated? */
- boolean negative = false;
- /*tex Reduce to the case that |f>=0| and |q>0|. */
- if (f < 0) {
- negate(f);
- negative = true;
- }
- if (q < 0) {
- negate(q);
- negative = !negative;
- }
- if (f < fraction_one) {
- n = 0;
- } else {
- n = f / fraction_one;
- f = f % fraction_one;
- if (q <= el_gordo / n) {
- n = n * q;
- } else {
- arith_error = true;
- n = el_gordo;
- }
- }
- f = f + fraction_one;
- /*tex
-
- Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$. The invariant relations
- in this case are (i)~$\lfloor(qf+p)/2^k\rfloor =\lfloor
- qf_0/2^{28}+{1\over2}\rfloor$, where $k$ is an integer and $f_0$ is the
- original value of~$f$; (ii)~$2^k\L f<2^{k+1}$.
-
- Here |p| becomes $2^{27}$; the invariants hold now with $k=28$:
-
- */
- p = fraction_half;
- if (q < fraction_four) {
- do {
- if (odd(f))
- p = halfp(p + q);
- else
- p = halfp(p);
- f = halfp(f);
- } while (f != 1);
- } else {
- do {
- if (odd(f))
- p = p + halfp(q - p);
- else
- p = halfp(p);
- f = halfp(f);
- } while (f != 1);
- }
- be_careful = n - el_gordo;
- if (be_careful + p > 0) {
- arith_error = true;
- n = el_gordo - p;
- }
- if (negative)
- return (-(n + p));
- else
- return (n + p);
-}
-
-/*tex
-
-The subroutines for logarithm and exponential involve two tables. The first is
-simple: |two_to_the[k]| equals $2^k$. The second involves a bit more calculation,
-which the author claims to have done correctly: |spec_log[k]| is $2^{27}$ times
-$\ln\bigl(1/(1-2^{-k})\bigr)= 2^{-k}+{1\over2}2^{-2k}+{1\over3}2^{-3k}+\cdots\,$,
-rounded to the nearest integer.
-
-*/
-
-/*tex The powers of two: */
-
-static int two_to_the[31];
-
-/*tex Special logarithms: */
-
-static int spec_log[29];
-
-void initialize_arithmetic(void)
-{
- int k;
- two_to_the[0] = 1;
- for (k = 1; k <= 30; k++) {
- two_to_the[k] = 2 * two_to_the[k - 1];
- }
- spec_log [1] = 93032640;
- spec_log [2] = 38612034;
- spec_log [3] = 17922280;
- spec_log [4] = 8662214;
- spec_log [5] = 4261238;
- spec_log [6] = 2113709;
- spec_log [7] = 1052693;
- spec_log [8] = 525315;
- spec_log [9] = 262400;
- spec_log[10] = 131136;
- spec_log[11] = 65552;
- spec_log[12] = 32772;
- spec_log[13] = 16385;
- for (k = 14; k <= 27; k++) {
- spec_log[k] = two_to_the[27 - k];
- }
- spec_log[28] = 1;
-}
-
-static int m_log(int x)
-{
- /*tex Auxiliary registers: */
- int y, z;
- /*tex Iteration counter: */
- int k;
- if (x <= 0) {
- /*tex Handle non-positive logarithm. */
- print_err("Logarithm of ");
- print_scaled(x);
- tprint(" has been replaced by 0");
- help2(
- "Since I don't take logs of non-positive numbers,",
- "I'm zeroing this one. Proceed, with fingers crossed."
- );
- error();
- return 0;
- } else {
- /*tex $14\times2^{27}\ln2\approx1302456956.421063$ */
- y = 1302456956 + 4 - 100;
- /*tex $2^{16}\times .421063\approx 27595$ */
- z = 27595 + 6553600;
- while (x < fraction_four) {
- x += x;
- /*tex $2^{27}\ln2\approx 93032639.74436163$ */
- y = y - 93032639;
- /*tex $2^{16}\times.74436163\approx 48782$ */
- z = z - 48782;
- }
-
- y = y + (z / unity);
- k = 2;
- while (x > fraction_four + 4) {
- /*tex
- Increase |k| until |x| can be multiplied by a factor of $2^{-k}$,
- and adjust $y$ accordingly. Here $z=\lceil x/2^k\rceil$.
- */
- z = ((x - 1) / two_to_the[k]) + 1;
- while (x < fraction_four + z) {
- z = halfp(z + 1);
- k = k + 1;
- }
- y = y + spec_log[k];
- x = x - z;
- }
- return (y / 8);
- }
-}
-
-/*tex
-
-The following somewhat different subroutine tests rigorously if $ab$ is greater
-than, equal to, or less than~$cd$, given integers $(a,b,c,d)$. In most cases a
-quick decision is reached. The result is $+1$, 0, or~$-1$ in the three respective
-cases.
-
-*/
-
-static int ab_vs_cd(int a, int b, int c, int d)
-{
- int q, r;
- /*tex Reduce to the case that |a,c>=0| and |b,d>0|. */
- if (a < 0) {
- negate(a);
- negate(b);
- }
- if (c < 0) {
- negate(c);
- negate(d);
- }
- if (d <= 0) {
- if (b >= 0)
- return (((a == 0 || b == 0) && (c == 0 || d == 0)) ? 0 : 1);
- if (d == 0)
- return (a == 0 ? 0 : -1);
- q = a;
- a = c;
- c = q;
- q = -b;
- b = -d;
- d = q;
- } else if (b <= 0) {
- if (b < 0 && a > 0)
- return -1;
- return (c == 0 ? 0 : -1);
- }
- while (1) {
- q = a / d;
- r = c / b;
- if (q != r)
- return (q > r ? 1 : -1);
- q = a % d;
- r = c % b;
- if (r == 0)
- return (q == 0 ? 0 : 1);
- if (q == 0)
- return -1;
- a = b;
- b = q;
- c = d;
- d = r;
- /*tex Now |a>d>0| and |c>b>0|. */
- }
-}
-
-/*tex
-
-To consume a random integer, the program below will say `|next_random|' and then
-it will fetch |randoms[j_random]|.
-
-*/
-
-#define next_random() do { \
- if (j_random==0) \
- new_randoms(); \
- else \
- decr(j_random); \
-} while (0)
-
-static void new_randoms(void)
-{
- /*tex The index into |randoms|. */
- int k;
- /*tex The accumulator. */
- int x;
- for (k = 0; k <= 23; k++) {
- x = randoms[k] - randoms[k + 31];
- if (x < 0)
- x = x + fraction_one;
- randoms[k] = x;
- }
- for (k = 24; k <= 54; k++) {
- x = randoms[k] - randoms[k - 24];
- if (x < 0)
- x = x + fraction_one;
- randoms[k] = x;
- }
- j_random = 54;
-}
-
-/*tex
-
-To initialize the |randoms| table, we call the following routine.
-
-*/
-
-void init_randoms(int seed)
-{
- /*tex Three more or less random integers. */
- int j, jj, k;
- /*tex The index into |randoms|. */
- int i;
- j = abs(seed);
- while (j >= fraction_one)
- j = halfp(j);
- k = 1;
- for (i = 0; i <= 54; i++) {
- jj = k;
- k = j - k;
- j = jj;
- if (k < 0)
- k = k + fraction_one;
- randoms[(i * 21) % 55] = j;
- }
- /*tex We ``warm up'' the array. */
- new_randoms();
- new_randoms();
- new_randoms();
-}
-
-/*tex
-
-To produce a uniform random number in the range |0<=u<x| or |0>=u>x| or |0=u=x|,
-given a |scaled| value~|x|, we proceed as shown here.
-
-Note that the call of |take_frac| will produce the values 0 and~|x| with about
-half the probability that it will produce any other particular values between 0
-and~|x|, because it rounds its answers.
-
-*/
-
-int unif_rand(int x)
-{
- int y;
- next_random();
- y = take_frac(abs(x), randoms[j_random]);
- if (y == abs(x))
- return 0;
- else if (x > 0)
- return y;
- else
- return -y;
-}
-
-/*tex
-
-Finally, a normal deviate with mean zero and unit standard deviation can readily
-be obtained with the ratio method (Algorithm 3.4.1R in {\sl The Art of Computer
-Programming\/}.
-
-*/
-
-int norm_rand(void)
-{
- /*tex What the book would call $2^{16}X$, $2^{28}U$, and $-2^{24}\ln U$. */
- int x, u, l;
- do {
- do {
- next_random();
- x = take_frac(112429, randoms[j_random] - fraction_half);
- /*tex Which is $2^{16}\sqrt{8/e}\approx 112428.82793$. */
- next_random();
- u = randoms[j_random];
- } while (abs(x) >= u);
- x = make_frac(x, u);
- /*tex More fuzzyness: $2^{24}\cdot12\ln2\approx139548959.6165$. */
- l = 139548960 - m_log(u);
- } while (ab_vs_cd(1024, l, x, x) < 0);
- return x;
-}
-
-/*tex
-
-This function could also be expressed as a macro, but it is a useful breakpoint
-for debugging.
-
-*/
-
-int fix_int(int val, int min, int max)
-{
- return (val < min ? min : (val > max ? max : val));
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/arithmetic.h b/Build/source/texk/web2c/luatexdir/tex/arithmetic.h
deleted file mode 100644
index e5638990e0c..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/arithmetic.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* arithmetic.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef ARITHMETIC_H
-# define ARITHMETIC_H
-
-/* |incr| and |decr| are in texmfmp.h */
-
- /* #define incr(A) (A)++ *//* increase a variable by unity */
- /* #define decr(A) (A)-- *//* decrease a variable by unity */
-
-# define negate(A) (A)=-(A) /* change the sign of a variable */
-
-# undef half
-extern int half(int x);
-
-/*
-Fixed-point arithmetic is done on {\sl scaled integers\/} that are multiples
-of $2^{-16}$. In other words, a binary point is assumed to be sixteen bit
-positions from the right end of a binary computer word.
-*/
-
-# define unity 0200000 /* $2^{16}$, represents 1.00000 */
-# define two 0400000 /* $2^{17}$, represents 2.00000 */
-
-typedef unsigned int nonnegative_integer; /* $0\L x<2^{31}$ */
-
-extern scaled round_decimals(int k);
-extern void print_scaled(scaled s);
-
-extern boolean arith_error;
-extern scaled tex_remainder;
-
-extern scaled mult_and_add(int n, scaled x, scaled y, scaled max_answer);
-
-# define nx_plus_y(A,B,C) mult_and_add((A),(B),(C),07777777777)
-# define mult_integers(A,B) mult_and_add((A),(B),0,017777777777)
-
-extern scaled x_over_n(scaled x, int n);
-extern scaled xn_over_d(scaled x, int n, int d);
-
-# define inf_bad 10000 /* infinitely bad value */
-
-extern halfword badness(scaled t, scaled s);
-
-# define set_glue_ratio_zero(A) (A)=0.0 /* store the representation of zero ratio */
-# define set_glue_ratio_one(A) (A)=1.0 /* store the representation of unit ratio */
-# define float_cast(A) (float)(A) /* convert from |glue_ratio| to type |real| */
-# define unfloat(A) (glue_ratio)(A) /* convert from |real| to type |glue_ratio| */
-# define float_constant(A) (float)A /* convert |integer| constant to |real| */
-# define float_round round
-
-extern void initialize_arithmetic(void);
-
-extern scaled random_seed; /* the default random seed */
-
-extern void init_randoms(int seed);
-extern int unif_rand(int x);
-extern int norm_rand(void);
-
-extern int fix_int(int val, int min, int max);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/backend.c b/Build/source/texk/web2c/luatexdir/tex/backend.c
deleted file mode 100644
index 3115a88a7e3..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/backend.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* to fill */
-
-#include "ptexlib.h"
-
-scaled max_v = 0; /* maximum height-plus-depth of pages shipped so far */
-scaled max_h = 0; /* maximum width of pages shipped so far */
-boolean doing_leaders = false; /* are we inside a leader box? */
-int cur_s = -1; /* current depth of output box nesting, initially $-1$ */
-
-static backend_struct *backend = NULL;
-backend_function *backend_out, *backend_out_whatsit, *backend_out_control;
-
-static void missing_backend_function(PDF pdf, halfword p)
-{
- const char *n = get_node_name(type(p), subtype(p));
- if (type(p) == whatsit_node)
- formatted_error("pdf backend","no output function for whatsit %s",n);
- else
- formatted_error("pdf backend","no output function for node %s",n);
-}
-
-static void init_none_backend_functions(void)
-{
- backend_struct *p = &backend[OMODE_NONE];
- p->name = strdup("NONE");
-}
-
-static void init_pdf_backend_functions(void)
-{
- backend_struct *p = &backend[OMODE_PDF];
- p->name = strdup("PDF");
- p->node_fu[rule_node] = &pdf_place_rule;
- p->node_fu[glyph_node] = &pdf_place_glyph;
- p->whatsit_fu[special_node] = &pdf_special;
- p->whatsit_fu[pdf_literal_node] = &pdf_out_literal;
- p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj;
- p->whatsit_fu[pdf_annot_node] = &do_annot;
- p->whatsit_fu[pdf_start_link_node] = &do_link;
- p->whatsit_fu[pdf_end_link_node] = &end_link;
- p->whatsit_fu[pdf_dest_node] = &do_dest;
- p->whatsit_fu[pdf_thread_node] = &do_thread;
- p->whatsit_fu[pdf_end_thread_node] = &end_thread;
- p->whatsit_fu[late_lua_node] = &late_lua;
- p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack;
- p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix;
- p->whatsit_fu[pdf_save_node] = &pdf_out_save;
- p->whatsit_fu[pdf_restore_node] = &pdf_out_restore;
- p->whatsit_fu[pdf_link_state_node] = &pdf_out_link_state;
- p->control_fu[backend_control_push_list] = &pdf_push_list;
- p->control_fu[backend_control_pop_list] = &pdf_pop_list;
- p->control_fu[backend_control_begin_page] = &pdf_begin_page;
- p->control_fu[backend_control_end_page] = &pdf_end_page;
- p->control_fu[backend_control_open_file] = &pdf_open_file;
- p->control_fu[backend_control_write_header] = &pdf_write_header;
- p->control_fu[backend_control_finish_file] = &pdf_finish_file;
- p->control_fu[backend_control_set_reference_point] = &pdf_set_reference_point;
-}
-
-static void init_dvi_backend_functions(void)
-{
- backend_struct *p = &backend[OMODE_DVI];
- p->name = strdup("DVI");
- p->node_fu[rule_node] = &dvi_place_rule;
- p->node_fu[glyph_node] = &dvi_place_glyph;
- p->whatsit_fu[special_node] = &dvi_special;
- p->whatsit_fu[late_lua_node] = &late_lua;
- p->control_fu[backend_control_push_list] = &dvi_push_list;
- p->control_fu[backend_control_pop_list] = &dvi_pop_list;
- p->control_fu[backend_control_begin_page] = &dvi_begin_page;
- p->control_fu[backend_control_end_page] = &dvi_end_page;
- p->control_fu[backend_control_open_file] = &dvi_open_file;
- p->control_fu[backend_control_write_header] = &dvi_write_header;
- p->control_fu[backend_control_finish_file] = &dvi_finish_file;
- p->control_fu[backend_control_set_reference_point] = &dvi_set_reference_point;
-}
-
-
-void init_backend_functionpointers(output_mode o_mode)
-{
- int i, j;
- if (backend == NULL) {
- backend = xmalloc((MAX_OMODE + 1) * sizeof(backend_struct));
- for (i = 0; i <= MAX_OMODE; i++) {
- backend[i].node_fu = xmalloc((MAX_NODE_TYPE + 1) * sizeof(backend_function));
- backend[i].whatsit_fu = xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(backend_function));
- backend[i].control_fu = xmalloc((MAX_CONTROL_TYPE + 1) * sizeof(backend_function));
- for (j = 0; j < MAX_NODE_TYPE + 1; j++)
- backend[i].node_fu[j] = &missing_backend_function;
- for (j = 0; j < MAX_WHATSIT_TYPE + 1; j++)
- backend[i].whatsit_fu[j] = &missing_backend_function;
- for (j = 0; j < MAX_CONTROL_TYPE + 1; j++)
- backend[i].control_fu[j] = &missing_backend_function;
- }
- init_none_backend_functions();
- init_dvi_backend_functions();
- init_pdf_backend_functions();
- }
- backend_out = backend[o_mode].node_fu;
- backend_out_whatsit = backend[o_mode].whatsit_fu;
- backend_out_control = backend[o_mode].control_fu;
-}
-
-output_mode get_o_mode(void)
-{
- output_mode o_mode;
- if (output_mode_par > 0) {
- o_mode = OMODE_PDF;
- } else
- o_mode = OMODE_DVI;
- return o_mode;
-}
-
-void fix_o_mode(void)
-{
- output_mode o_mode = get_o_mode();
- if (output_mode_used == OMODE_NONE) {
- output_mode_used = o_mode;
- /*tex Used by synctex, we need to use output_mode_used there: */
- static_pdf->o_mode = output_mode_used;
- } else if (output_mode_used != o_mode) {
- normal_error("pdf backend", "\\outputmode can only be changed before anything is written to the output");
- }
- init_backend_functionpointers(output_mode_used);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/backend.h b/Build/source/texk/web2c/luatexdir/tex/backend.h
deleted file mode 100644
index 5cfbd06fb90..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/backend.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* to fill */
-
-#ifndef BACKEND_H
-# define BACKEND_H
-
-#include "ptexlib.h"
-
-extern scaled max_v;
-extern scaled max_h;
-extern boolean doing_leaders;
-extern int cur_s;
-
-# define MAX_CONTROL_TYPE 7
-
-typedef enum {
- backend_control_push_list = 0,
- backend_control_pop_list,
- backend_control_begin_page,
- backend_control_end_page,
- backend_control_open_file,
- backend_control_write_header,
- backend_control_finish_file,
- backend_control_set_reference_point
-} backend_control_types ;
-
-typedef void (*backend_function) (); /* variadic arguments */
-
-typedef struct {
- char *name; /* name of the backend */
- backend_function *node_fu; /* array of node output functions */
- backend_function *whatsit_fu; /* array of whatsit output functions */
- backend_function *control_fu; /* array of whatsit output functions */
-} backend_struct;
-
-/* extern pos_info_structure pos_info; */
-
-extern backend_function *backend_out;
-extern backend_function *backend_out_whatsit;
-extern backend_function *backend_out_control;
-
-/* get_o_mode translates from output_mode to output_mode_used */
-/* fix_o_mode freezes output_mode as soon as anything goes through the backend */
-
-/*
- extern void check_o_mode(PDF pdf, const char *s, int o_mode, boolean errorflag);
- extern void ensure_output_file_open(PDF pdf, const char *ext);
-*/
-
-extern void fix_o_mode(void);
-extern output_mode get_o_mode(void);
-
-extern void init_backend_functionpointers(output_mode o_mode);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.c b/Build/source/texk/web2c/luatexdir/tex/buildpage.c
deleted file mode 100644
index 81e69dc3b2a..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/buildpage.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-
-#define mode mode_par
-#define head head_par
-#define tail tail_par
-
-/*tex
-
- When \TeX\ appends new material to its main vlist in vertical mode, it uses a
- method something like |vsplit| to decide where a page ends, except that the
- calculations are done ``on line'' as new items come in. The main complication
- in this process is that insertions must be put into their boxes and removed
- from the vlist, in a more-or-less optimum manner.
-
- We shall use the term ``current page'' for that part of the main vlist that
- is being considered as a candidate for being broken off and sent to the
- user's output routine. The current page starts at |vlink(page_head)|, and it
- ends at |page_tail|. We have |page_head=page_tail| if this list is empty.
-
- Utter chaos would reign if the user kept changing page specifications while a
- page is being constructed, so the page builder keeps the pertinent
- specifications frozen as soon as the page receives its first box or
- insertion. The global variable |page_contents| is |empty| when the current
- page contains only mark nodes and content-less whatsit nodes; it is
- |inserts_only| if the page contains only insertion nodes in addition to marks
- and whatsits. Glue nodes, kern nodes, and penalty nodes are discarded until a
- box or rule node appears, at which time |page_contents| changes to
- |box_there|. As soon as |page_contents| becomes non-|empty|, the current
- |vsize| and |max_depth| are squirreled away into |page_goal| and
- |page_max_depth|; the latter values will be used until the page has been
- forwarded to the user's output routine. The \.{\\topskip} adjustment is made
- when |page_contents| changes to |box_there|.
-
- Although |page_goal| starts out equal to |vsize|, it is decreased by the
- scaled natural height-plus-depth of the insertions considered so far, and by
- the \.{\\skip} corrections for those insertions. Therefore it represents the
- size into which the non-inserted material should fit, assuming that all
- insertions in the current page have been made.
-
- The global variables |best_page_break| and |least_page_cost| correspond
- respectively to the local variables |best_place| and |least_cost| in the
- |vert_break| routine that we have already studied; i.e., they record the
- location and value of the best place currently known for breaking the current
- page. The value of |page_goal| at the time of the best break is stored in
- |best_size|.
-
-*/
-
-/*tex the final node on the current page */
-
-halfword page_tail;
-
-/*tex what is on the current page so far? */
-
-int page_contents;
-
-/*tex maximum box depth on page being built */
-
-scaled page_max_depth;
-
-/*tex break here to get the best page known so far */
-
-halfword best_page_break;
-
-/*tex the score for this currently best page */
-
-int least_page_cost;
-
-/*tex its |page_goal| */
-
-scaled best_size;
-
-/*tex
-
- The page builder has another data structure to keep track of insertions. This
- is a list of four-word nodes, starting and ending at |page_ins_head|. That
- is, the first element of the list is node |t$_1$=vlink(page_ins_head)|;
- node $r_j$ is followed by |t$_{j+1}$=vlink(t$_j$)|; and if there are
- |n| items we have |$_{n+1}$>=page_ins_head|. The |subtype| field of each
- node in this list refers to an insertion number; for example, `\.{\\insert
- 250}' would correspond to a node whose |subtype| is |qi(250)| (the same as
- the |subtype| field of the relevant |ins_node|). These |subtype| fields are
- in increasing order, and |subtype(page_ins_head)=65535|, so |page_ins_head|
- serves as a convenient sentinel at the end of the list. A record is present
- for each insertion number that appears in the current page.
-
- The |type| field in these nodes distinguishes two possibilities that might
- occur as we look ahead before deciding on the optimum page break. If
- |type(r)=inserting_node|, then |height(r)| contains the total of the
- height-plus-depth dimensions of the box and all its inserts seen so far.
- |type(r)=split_up_node|, then no more insertions will be made into this box,
- because at least one previous insertion was too big to fit on the current
- page; |broken_ptr(r)| points to the node where that insertion will be split,
- if \TeX\ decides to split it, |broken_ins(r)| points to the insertion node
- that was tentatively split, and |height(r)| includes also the natural height
- plus depth of the part that would be split off.
-
- In both cases, |last_ins_ptr(r)| points to the last |ins_node| encountered
- for box |qo(subtype(r))| that would be at least partially inserted on the
- next page; and |best_ins_ptr(r)| points to the last such |ins_node| that
- should actually be inserted, to get the page with minimum badness among all
- page breaks considered so far. We have |best_ins_ptr(r)=null| if and only if
- no insertion for this box should be made to produce this optimum page.
-
- Pages are built by appending nodes to the current list in \TeX's vertical
- mode, which is at the outermost level of the semantic nest. This vlist is
- split into two parts; the ``current page'' that we have been talking so much
- about already, and the ``contribution list'' that receives new nodes as they
- are created. The current page contains everything that the page builder has
- accounted for in its data structures, as described above, while the
- contribution list contains other things that have been generated by other
- parts of \TeX\ but have not yet been seen by the page builder. The
- contribution list starts at |vlink(contrib_head)|, and it ends at the current
- node in \TeX's vertical mode.
-
- When \TeX\ has appended new material in vertical mode, it calls the procedure
- |build_page|, which tries to catch up by moving nodes from the contribution
- list to the current page. This procedure will succeed in its goal of emptying
- the contribution list, unless a page break is discovered, i.e., unless the
- current page has grown to the point where the optimum next page break has
- been determined. In the latter case, the nodes after the optimum break will
- go back onto the contribution list, and control will effectively pass to the
- user's output routine.
-
- We make |type(page_head)=glue_node|, so that an initial glue node on the
- current page will not be considered a valid breakpoint.
-
-*/
-
-void initialize_buildpage(void)
-{
- subtype(page_ins_head) = 65535;
- type(page_ins_head) = split_up_node;
- vlink(page_ins_head) = page_ins_head;
-
- type(page_head) = glue_node;
- subtype(page_head) = normal;
-}
-
-/*tex
-
- An array |page_so_far| records the heights and depths of everything on the
- current page. This array contains six |scaled| numbers, like the similar
- arrays already considered in |line_break| and |vert_break|; and it also
- contains |page_goal| and |page_depth|, since these values are all accessible
- to the user via |set_page_dimen| commands. The value of |page_so_far[1]| is
- also called |page_total|. The stretch and shrink components of the \.{\\skip}
- corrections for each insertion are included in |page_so_far|, but the natural
- space components of these corrections are not, since they have been
- subtracted from |page_goal|.
-
- The variable |page_depth| records the depth of the current page; it has been
- adjusted so that it is at most |page_max_depth|. The variable |last_glue|
- points to the glue specification of the most recent node contributed from the
- contribution list, if this was a glue node; otherwise
- |last_glue=max_halfword|. (If the contribution list is nonempty, however, the
- value of |last_glue| is not necessarily accurate.) The variables
- |last_penalty|, |last_kern|, and |last_node_type| are similar. And finally,
- |insert_penalties| holds the sum of the penalties associated with all split
- and floating insertions.
-
-*/
-
-/*tex height and glue of the current page */
-
-scaled page_so_far[8];
-
-/*tex used to implement \.{\\lastskip} */
-
-halfword last_glue;
-
-/*tex used to implement \.{\\lastpenalty} */
-
-int last_penalty;
-
-/*tex used to implement \.{\\lastkern} */
-
-scaled last_kern;
-
-/*tex used to implement \.{\\lastnodetype} */
-
-int last_node_type;
-
-/*tex sum of the penalties for held-over insertions */
-
-int insert_penalties;
-
-#define print_plus(A,B) do { \
- if (page_so_far[(A)]!=0) { \
- tprint(" plus "); \
- print_scaled(page_so_far[(A)]); \
- tprint((B)); \
- } \
-} while (0)
-
-void print_totals(void)
-{
- print_scaled(page_total);
- print_plus(2, "");
- print_plus(3, "fil");
- print_plus(4, "fill");
- print_plus(5, "filll");
- if (page_shrink != 0) {
- tprint(" minus ");
- print_scaled(page_shrink);
- }
-}
-
-/*tex
-
- Here is a procedure that is called when the |page_contents| is changing from
- |empty| to |inserts_only| or |box_there|.
-
-*/
-
-#define do_all_six(A) A(1);A(2);A(3);A(4);A(5);A(6);A(7)
-#define set_page_so_far_zero(A) page_so_far[(A)]=0
-
-void freeze_page_specs(int s)
-{
- page_contents = s;
- page_goal = vsize_par;
- page_max_depth = max_depth_par;
- page_depth = 0;
- do_all_six(set_page_so_far_zero);
- least_page_cost = awful_bad;
- if (tracing_pages_par > 0) {
- begin_diagnostic();
- tprint_nl("%% goal height=");
- print_scaled(page_goal);
- tprint(", max depth=");
- print_scaled(page_max_depth);
- end_diagnostic(false);
- }
-}
-
-/*tex
-
- The global variable |output_active| is true during the time the user's output
- routine is driving \TeX.
-
-*/
-
-/*tex Are we in the midst of an output routine? */
-
-boolean output_active;
-
-/*tex
-
- The page builder is ready to start a fresh page if we initialize the
- following state variables. (However, the page insertion list is initialized
- elsewhere.)
-
-*/
-
-void start_new_page(void)
-{
- page_contents = empty;
- page_tail = page_head;
- vlink(page_head) = null;
- last_glue = max_halfword;
- last_penalty = 0;
- last_kern = 0;
- last_node_type = -1;
- page_depth = 0;
- page_max_depth = 0;
-}
-
-/*tex
-
- At certain times box \.{\\outputbox} is supposed to be void (i.e., |null|),
- or an insertion box is supposed to be ready to accept a vertical list. If
- not, an error message is printed, and the following subroutine flushes the
- unwanted contents, reporting them to the user.
-
-*/
-
-static void box_error(int n)
-{
- error();
- begin_diagnostic();
- tprint_nl("The following box has been deleted:");
- show_box(box(n));
- end_diagnostic(true);
- flush_node_list(box(n));
- box(n) = null;
-}
-
-/*tex
-
- The following procedure guarantees that a given box register does not contain
- an \.{\\hbox}.
-
-*/
-
-static void ensure_vbox(int n)
-{
- halfword p = box(n);
- if (p != null && type(p) == hlist_node) {
- print_err("Insertions can only be added to a vbox");
- help3(
- "Tut tut: You're trying to \\insert into a",
- "\\box register that now contains an \\hbox.",
- "Proceed, and I'll discard its present contents."
- );
- box_error(n);
- }
-}
-
-/*tex
-
- \TeX\ is not always in vertical mode at the time |build_page| is called; the
- current mode reflects what \TeX\ should return to, after the contribution
- list has been emptied. A call on |build_page| should be immediately followed
- by `|goto big_switch|', which is \TeX's central control point.
-
-*/
-
-/*tex Append contributions to the current page. */
-
-void build_page(void)
-{
- /*tex the node being appended */
- halfword p;
- /*tex nodes being examined */
- halfword q, r;
- /*tex badness and cost of current page */
- int b, c;
- /*tex penalty to be added to the badness */
- int pi = 0;
- /*tex insertion box number */
- int n;
- /*tex sizes used for insertion calculations */
- scaled delta, h, w;
- int id, sk, i;
- if ((vlink(contrib_head) == null) || output_active)
- return;
- do {
- CONTINUE:
- p = vlink(contrib_head);
- /*tex Update the values of |last_glue|, |last_penalty|, and |last_kern|. */
- if (last_glue != max_halfword) {
- flush_node(last_glue);
- last_glue = max_halfword;
- }
- last_penalty = 0;
- last_kern = 0;
- last_node_type = type(p) + 1;
- if (type(p) == glue_node) {
- last_glue = new_glue(p);
- } else if (type(p) == penalty_node) {
- last_penalty = penalty(p);
- } else if (type(p) == kern_node) {
- last_kern = width(p);
- }
- /*tex
-
- Move node |p| to the current page; if it is time for a page break,
- put the nodes following the break back onto the contribution list,
- and |return| to the users output routine if there is one.
-
- The code here is an example of a many-way switch into routines that
- merge together in different places. Some people call this
- unstructured programming, but the author doesn't see much wrong with
- it, as long as the various labels have a well-understood meaning.
-
- If the current page is empty and node |p| is to be deleted, |goto
- done1|; otherwise use node |p| to update the state of the current
- page; if this node is an insertion, |goto contribute|; otherwise if
- this node is not a legal breakpoint, |goto contribute| or
- |update_heights|; otherwise set |pi| to the penalty associated with
- this breakpoint.
-
- The title of this section is already so long, it seems best to avoid
- making it more accurate but still longer, by mentioning the fact that
- a kern node at the end of the contribution list will not be
- contributed until we know its successor.
-
- */
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case rule_node:
- if (page_contents < box_there) {
- /*tex
-
- Initialize the current page, insert the \.{\\topskip}
- glue ahead of |p|, and |goto continue|.
-
- */
- if (page_contents == empty)
- freeze_page_specs(box_there);
- else
- page_contents = box_there;
- q = new_skip_param(top_skip_code);
- if ((type(p) == hlist_node) && is_mirrored(body_direction_par)) {
- if (width(q) > depth(p))
- width(q) = width(q) - depth(p);
- else
- width(q) = 0;
- } else {
- if (width(q) > height(p))
- width(q) = width(q) - height(p);
- else
- width(q) = 0;
- }
- couple_nodes(q, p);
- couple_nodes(contrib_head, q);
- goto CONTINUE;
- } else {
- /*tex
-
- Prepare to move a box or rule node to the current page,
- then |goto contribute|.
-
- */
- if ((type(p) == hlist_node) && is_mirrored(body_direction_par)) {
- page_total = page_total + page_depth + depth(p);
- page_depth = height(p);
- } else {
- page_total = page_total + page_depth + height(p);
- page_depth = depth(p);
- }
- goto CONTRIBUTE;
-
- }
- break;
- case boundary_node:
- case whatsit_node:
- goto CONTRIBUTE;
- break;
- case glue_node:
- if (page_contents < box_there)
- goto DONE1;
- else if (precedes_break(page_tail))
- pi = 0;
- else
- goto UPDATE_HEIGHTS;
- break;
- case kern_node:
- if (page_contents < box_there)
- goto DONE1;
- else if (vlink(p) == null)
- goto EXIT;
- else if (type(vlink(p)) == glue_node)
- pi = 0;
- else
- goto UPDATE_HEIGHTS;
- break;
- case penalty_node:
- if (page_contents < box_there)
- goto DONE1;
- else
- pi = penalty(p);
- break;
- case mark_node:
- goto CONTRIBUTE;
- break;
- case ins_node:
- /*tex Append an insertion to the current page and |goto contribute|. */
- if (page_contents == empty)
- freeze_page_specs(inserts_only);
- n = subtype(p);
- r = page_ins_head;
- i = 1 ;
- while (n >= subtype(vlink(r))) {
- r = vlink(r);
- i = i + 1 ;
- }
- if (subtype(r) != n) {
- /*tex
-
- Create a page insertion node with |subtype(r)=qi(n)|, and
- include the glue correction for box |n| in the current
- page state.
-
- We take note of the value of \.{\\skip} |n| and the
- height plus depth of \.{\\box}~|n| only when the first
- \.{\\insert}~|n| node is encountered for a new page. A
- user who changes the contents of \.{\\box}~|n| after that
- first \.{\\insert}~|n| had better be either extremely
- careful or extremely lucky, or both.
-
- */
- id = callback_defined(build_page_insert_callback);
- if (id != 0) {
- run_callback(id, "dd->d",n,i,&sk);
- } else {
- sk = n;
- }
- q = new_node(inserting_node, n);
- try_couple_nodes(q, vlink(r));
- couple_nodes(r, q);
- r = q;
- ensure_vbox(n);
- if (box(n) == null)
- height(r) = 0;
- else
- height(r) = height(box(n)) + depth(box(n));
- best_ins_ptr(r) = null;
- q = skip(sk);
- if (count(n) == 1000)
- h = height(r);
- else
- h = x_over_n(height(r), 1000) * count(n);
- page_goal = page_goal - h - width(q);
- if (stretch_order(q) > 1)
- page_so_far[1 + stretch_order(q)] = page_so_far[1 + stretch_order(q)] + stretch(q);
- else
- page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
- page_shrink = page_shrink + shrink(q);
- if ((shrink_order(q) != normal) && (shrink(q) != 0)) {
- print_err("Infinite glue shrinkage inserted from \\skip");
- print_int(n);
- help3(
- "The correction glue for page breaking with insertions",
- "must have finite shrinkability. But you may proceed,",
- "since the offensive shrinkability has been made finite."
- );
- error();
- }
-
- }
- if (type(r) == split_up_node) {
- insert_penalties = insert_penalties + float_cost(p);
- } else {
- last_ins_ptr(r) = p;
- delta = page_goal - page_total - page_depth + page_shrink;
- /*tex This much room is left if we shrink the maximum. */
- if (count(n) == 1000) {
- h = height(p);
- } else {
- /*tex This much room is needed. */
- h = x_over_n(height(p), 1000) * count(n);
- }
- if (((h <= 0) || (h <= delta))
- && (height(p) + height(r) <= dimen(n))) {
- page_goal = page_goal - h;
- height(r) = height(r) + height(p);
- } else {
- /*tex
-
- Find the best way to split the insertion, and change
- |type(r)| to |split_up_node|.
-
- Here is the code that will split a long footnote
- between pages, in an emergency. The current situation
- deserves to be recapitulated: Node |p| is an
- insertion into box |n|; the insertion will not fit,
- in its entirety, either because it would make the
- total contents of box |n| greater than \.{\\dimen}
- |n|, or because it would make the incremental amount
- of growth |h| greater than the available space
- |delta|, or both. (This amount |h| has been weighted
- by the insertion scaling factor, i.e., by \.{\\count}
- |n| over 1000.) Now we will choose the best way to
- break the vlist of the insertion, using the same
- criteria as in the \.{\\vsplit} operation.
-
- */
- if (count(n) <= 0) {
- w = max_dimen;
- } else {
- w = page_goal - page_total - page_depth;
- if (count(n) != 1000)
- w = x_over_n(w, count(n)) * 1000;
- }
- if (w > dimen(n) - height(r))
- w = dimen(n) - height(r);
- q = vert_break(ins_ptr(p), w, depth(p));
- height(r) = height(r) + best_height_plus_depth;
- if (tracing_pages_par > 0) {
- /*tex Display the insertion split cost. */
- begin_diagnostic();
- tprint_nl("% split");
- print_int(n);
- tprint(" to ");
- print_scaled(w);
- print_char(',');
- print_scaled(best_height_plus_depth);
- tprint(" p=");
- if (q == null)
- print_int(eject_penalty);
- else if (type(q) == penalty_node)
- print_int(penalty(q));
- else
- print_char('0');
- end_diagnostic(false);
- }
- if (count(n) != 1000)
- best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n);
- page_goal = page_goal - best_height_plus_depth;
- type(r) = split_up_node;
- broken_ptr(r) = q;
- broken_ins(r) = p;
- if (q == null)
- insert_penalties = insert_penalties + eject_penalty;
- else if (type(q) == penalty_node)
- insert_penalties = insert_penalties + penalty(q);
- }
- }
- goto CONTRIBUTE;
-
- break;
- default:
- formatted_error("pagebuilder","invalid node of type %d in vertical mode", type(p));
- break;
- }
- /*tex
-
- Check if node |p| is a new champion breakpoint; then if it is time
- for a page break, prepare for output, and either fire up the users
- output routine and |return| or ship out the page and |goto done|.
-
- */
- if (pi < inf_penalty) {
- /*tex
-
- Compute the badness, |b|, of the current page, using |awful_bad|
- if the box is too full.
-
- */
- if (page_total < page_goal) {
- if ((page_so_far[3] != 0) || (page_so_far[4] != 0) ||
- (page_so_far[5] != 0))
- b = 0;
- else
- b = badness(page_goal - page_total, page_so_far[2]);
- } else if (page_total - page_goal > page_shrink) {
- b = awful_bad;
- } else {
- b = badness(page_total - page_goal, page_shrink);
- }
- if (b < awful_bad) {
- if (pi <= eject_penalty)
- c = pi;
- else if (b < inf_bad)
- c = b + pi + insert_penalties;
- else
- c = deplorable;
- } else {
- c = b;
- }
- if (insert_penalties >= 10000)
- c = awful_bad;
- if (tracing_pages_par > 0) {
- /*tex Display the page break cost. */
- begin_diagnostic();
- tprint_nl("%");
- tprint(" t=");
- print_totals();
- tprint(" g=");
- print_scaled(page_goal);
- tprint(" b=");
- if (b == awful_bad)
- print_char('*');
- else
- print_int(b);
- tprint(" p=");
- print_int(pi);
- tprint(" c=");
- if (c == awful_bad)
- print_char('*');
- else
- print_int(c);
- if (c <= least_page_cost)
- print_char('#');
- end_diagnostic(false);
- }
- if (c <= least_page_cost) {
- best_page_break = p;
- best_size = page_goal;
- least_page_cost = c;
- r = vlink(page_ins_head);
- while (r != page_ins_head) {
- best_ins_ptr(r) = last_ins_ptr(r);
- r = vlink(r);
- }
- }
- if ((c == awful_bad) || (pi <= eject_penalty)) {
- /*tex Output the current page at the best place. */
- fire_up(p);
- if (output_active) {
- /*tex User's output routine will act. */
- goto EXIT;
- }
- /*tex The page has been shipped out by default output routine. */
- goto DONE;
- }
- }
- if ((type(p) < glue_node) || (type(p) > kern_node))
- goto CONTRIBUTE;
- UPDATE_HEIGHTS:
- /*tex
-
- Go here to record glue in the |active_height| table. Update the
- current page measurements with respect to the glue or kern specified
- by node~|p|.
-
- */
- if (type(p) != kern_node) {
- if (stretch_order(p) > 1)
- page_so_far[1 + stretch_order(p)] = page_so_far[1 + stretch_order(p)] + stretch(p);
- else
- page_so_far[2 + stretch_order(p)] = page_so_far[2 + stretch_order(p)] + stretch(p);
- page_shrink = page_shrink + shrink(p);
- if ((shrink_order(p) != normal) && (shrink(p) != 0)) {
- print_err("Infinite glue shrinkage found on current page");
- help4(
- "The page about to be output contains some infinitely",
- "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
- "Such glue doesn't belong there; but you can safely proceed,",
- "since the offensive shrinkability has been made finite."
- );
- error();
- reset_glue_to_zero(p);
- shrink_order(p) = normal;
- }
- }
- page_total = page_total + page_depth + width(p);
- page_depth = 0;
- CONTRIBUTE:
- /*tex
-
- Go here to link a node into the current page. Make sure that
- |page_max_depth| is not exceeded.
-
- */
- if (page_depth > page_max_depth) {
- page_total = page_total + page_depth - page_max_depth;
- page_depth = page_max_depth;
- }
- /*tex Link node |p| into the current page and |goto done|. */
- couple_nodes(page_tail, p);
- page_tail = p;
- try_couple_nodes(contrib_head,vlink(p));
- vlink(p) = null;
- goto DONE;
- DONE1:
- /*tex Recycle node |p|. */
- try_couple_nodes(contrib_head,vlink(p));
- vlink(p) = null;
- if (saving_vdiscards_par > 0) {
- if (page_disc == null) {
- page_disc = p;
- } else {
- couple_nodes(tail_page_disc, p);
- }
- tail_page_disc = p;
- } else {
- flush_node_list(p);
- }
- DONE:
- ;
- } while (vlink(contrib_head) != null);
- /*tex Make the contribution list empty by setting its tail to |contrib_head|. */
- contrib_tail = contrib_head;
- EXIT:
- ;
-}
-
-/*tex
-
- When the page builder has looked at as much material as could appear before
- the next page break, it makes its decision. The break that gave minimum
- badness will be used to put a completed ``page'' into box \.{\\outputbox},
- with insertions appended to their other boxes.
-
- We also set the values of |top_mark|, |first_mark|, and |bot_mark|. The
- program uses the fact that |bot_mark(x)<>null| implies |first_mark(x)<>null|;
- it also knows that |bot_mark(x)=null| implies
- |top_mark(x)=first_mark(x)=null|.
-
- The |fire_up| subroutine prepares to output the current page at the best
- place; then it fires up the user's output routine, if there is one, or it
- simply ships out the page. There is one parameter, |c|, which represents the
- node that was being contributed to the page when the decision to force an
- output was made.
-
-*/
-
-void fire_up(halfword c)
-{
- /*tex nodes being examined and/or changed */
- halfword p, q, r, s;
- /*tex predecessor of |p| */
- halfword prev_p;
- /*tex insertion box number */
- int n;
- /*tex should the present insertion be held over? */
- boolean wait;
- /*tex saved value of |vbadness| */
- int save_vbadness;
- /*tex saved value of |vfuzz| */
- scaled save_vfuzz;
- /*tex saved value of |split_top_skip| */
- halfword save_split_top_skip;
- /*tex for looping through the marks */
- halfword i;
- /*tex Set the value of |output_penalty|. */
- if (type(best_page_break) == penalty_node) {
- geq_word_define(int_base + output_penalty_code,
- penalty(best_page_break));
- penalty(best_page_break) = inf_penalty;
- } else {
- geq_word_define(int_base + output_penalty_code, inf_penalty);
- }
-
- for (i = 0; i <= biggest_used_mark; i++) {
- if (bot_mark(i) != null) {
- if (top_mark(i) != null)
- delete_token_ref(top_mark(i));
- set_top_mark(i, bot_mark(i));
- add_token_ref(top_mark(i));
- delete_first_mark(i);
- }
- }
- /*tex
-
- Put the optimal current page into box |output_box|, update |first_mark|
- and |bot_mark|, append insertions to their boxes, and put the remaining
- nodes back on the contribution list.
-
- As the page is finally being prepared for output, pointer |p| runs
- through the vlist, with |prev_p| trailing behind; pointer |q| is the tail
- of a list of insertions that are being held over for a subsequent page.
-
- */
- if (c == best_page_break) {
- /*tex |c| not yet linked in */
- best_page_break = null;
- }
- /*tex Ensure that box |output_box| is empty before output. */
- if (box(output_box_par) != null) {
- print_err("\\box");
- print_int(output_box_par);
- tprint(" is not void");
- help2(
- "You shouldn't use \\box\\outputbox except in \\output routines.",
- "Proceed, and I'll discard its present contents."
- );
- box_error(output_box_par);
- }
- /*tex This will count the number of insertions held over. */
- insert_penalties = 0;
- save_split_top_skip = split_top_skip_par;
- if (holding_inserts_par <= 0) {
- /*tex
-
- Prepare all the boxes involved in insertions to act as queues. If
- many insertions are supposed to go into the same box, we want to know
- the position of the last node in that box, so that we don't need to
- waste time when linking further information into it. The
- |last_ins_ptr| fields of the page insertion nodes are therefore used
- for this purpose during the packaging phase.
-
- */
- r = vlink(page_ins_head);
- while (r != page_ins_head) {
- if (best_ins_ptr(r) != null) {
- n = subtype(r);
- ensure_vbox(n);
- if (box(n) == null)
- box(n) = new_null_box();
- p = box(n) + list_offset;
- while (vlink(p) != null)
- p = vlink(p);
- last_ins_ptr(r) = p;
- }
- r = vlink(r);
- }
-
- }
- q = hold_head;
- vlink(q) = null;
- prev_p = page_head;
- p = vlink(prev_p);
- while (p != best_page_break) {
- if (type(p) == ins_node) {
- if (holding_inserts_par <= 0) {
- /*tex
-
- Either insert the material specified by node |p| into the
- appropriate box, or hold it for the next page; also delete
- node |p| from the current page.
-
- We will set |best_ins_ptr:=null| and package the box
- corresponding to insertion node~|r|, just after making the
- final insertion into that box. If this final insertion is
- `|split_up_node|', the remainder after splitting and pruning
- (if any) will be carried over to the next page.
-
- */
- r = vlink(page_ins_head);
- while (subtype(r) != subtype(p))
- r = vlink(r);
- if (best_ins_ptr(r) == null) {
- wait = true;
- } else {
- wait = false;
- s = last_ins_ptr(r);
- vlink(s) = ins_ptr(p);
- if (best_ins_ptr(r) == p) {
- halfword t;
- /*tex
-
- Wrap up the box specified by node |r|, splitting node
- |p| if called for; set |wait:=true| if node |p| holds
- a remainder after splitting.
-
- */
- if (type(r) == split_up_node) {
- if ((broken_ins(r) == p) && (broken_ptr(r) != null)) {
- while (vlink(s) != broken_ptr(r))
- s = vlink(s);
- vlink(s) = null;
- split_top_skip_par = split_top_ptr(p);
- ins_ptr(p) =
- prune_page_top(broken_ptr(r), false);
- if (ins_ptr(p) != null) {
- t = vpack(ins_ptr(p), 0, additional, -1);
- height(p) = height(t) + depth(t);
- list_ptr(t) = null;
- flush_node(t);
- wait = true;
- }
- }
- }
- best_ins_ptr(r) = null;
- n = subtype(r);
- t = list_ptr(box(n));
- list_ptr(box(n)) = null;
- flush_node(box(n));
- box(n) = vpack(t, 0, additional, body_direction_par);
-
- } else {
- while (vlink(s) != null)
- s = vlink(s);
- last_ins_ptr(r) = s;
- }
- }
- /*tex
-
- Either append the insertion node |p| after node |q|, and
- remove it from the current page, or delete |node(p)|.
-
- */
- try_couple_nodes(prev_p, vlink(p));
- vlink(p) = null;
- if (wait) {
- couple_nodes(q, p);
- q = p;
- incr(insert_penalties);
- } else {
- ins_ptr(p) = null;
- flush_node(p);
- }
- p = prev_p;
-
- }
- } else if (type(p) == mark_node) {
- /*tex Update the values of |first_mark| and |bot_mark|. */
- if (first_mark(mark_class(p)) == null) {
- set_first_mark(mark_class(p), mark_ptr(p));
- add_token_ref(first_mark(mark_class(p)));
- }
- if (bot_mark(mark_class(p)) != null)
- delete_token_ref(bot_mark(mark_class(p)));
- set_bot_mark(mark_class(p), mark_ptr(p));
- add_token_ref(bot_mark(mark_class(p)));
-
- }
- prev_p = p;
- p = vlink(prev_p);
- }
- split_top_skip_par = save_split_top_skip;
- /*tex
-
- Break the current page at node |p|, put it in box~|output_box|, and put
- the remaining nodes on the contribution list.
-
- When the following code is executed, the current page runs from node
- |vlink(page_head)| to node |prev_p|, and the nodes from |p| to
- |page_tail| are to be placed back at the front of the contribution list.
- Furthermore the heldover insertions appear in a list from
- |vlink(hold_head)| to |q|; we will put them into the current page list
- for safekeeping while the user's output routine is active. We might have
- |q=hold_head|; and |p=null| if and only if |prev_p=page_tail|. Error
- messages are suppressed within |vpackage|, since the box might appear to
- be overfull or underfull simply because the stretch and shrink from the
- \.{\\skip} registers for inserts are not actually present in the box.
-
- */
- if (p != null) {
- if (vlink(contrib_head) == null) {
- contrib_tail = page_tail;
- }
- couple_nodes(page_tail,vlink(contrib_head));
- couple_nodes(contrib_head, p);
- vlink(prev_p) = null;
- }
- save_vbadness = vbadness_par;
- vbadness_par = inf_bad;
- save_vfuzz = vfuzz_par;
- /*tex Inhibit error messages. */
- vfuzz_par = max_dimen;
- box(output_box_par) = filtered_vpackage(vlink(page_head),
- best_size, exactly, page_max_depth, output_group, body_direction_par, 0, 0);
- vbadness_par = save_vbadness;
- vfuzz_par = save_vfuzz;
- if (last_glue != max_halfword)
- flush_node(last_glue);
- /*tex Start a new current page. This sets |last_glue:=max_halfword|. */
- start_new_page();
- if (q != hold_head) {
- vlink(page_head) = vlink(hold_head);
- page_tail = q;
- }
- /*tex Delete the page-insertion nodes. */
- r = vlink(page_ins_head);
- while (r != page_ins_head) {
- /*tex Todo: couple. */
- q = vlink(r);
- flush_node(r);
- r = q;
- }
- vlink(page_ins_head) = page_ins_head;
- for (i = 0; i <= biggest_used_mark; i++) {
- if ((top_mark(i) != null) && (first_mark(i) == null)) {
- set_first_mark(i, top_mark(i));
- add_token_ref(top_mark(i));
- }
- }
- if (output_routine_par != null) {
- if (dead_cycles >= max_dead_cycles_par) {
- /*tex Explain that too many dead cycles have occurred in a row. */
- print_err("Output loop---");
- print_int(dead_cycles);
- tprint(" consecutive dead cycles");
- help3(
- "I've concluded that your \\output is awry; it never does a",
- "\\shipout, so I'm shipping \\box\\outputbox out myself. Next time",
- "increase \\maxdeadcycles if you want me to be more patient!"
- );
- error();
- } else {
- /*tex Fire up the users output routine and |return|. */
- output_active = true;
- incr(dead_cycles);
- push_nest();
- mode = -vmode;
- prev_depth_par = ignore_depth;
- mode_line_par = -line;
- begin_token_list(output_routine_par, output_text);
- new_save_level(output_group);
- normal_paragraph();
- scan_left_brace();
- return;
- }
- }
- /*tex
-
- Perform the default output routine. The list of heldover insertions,
- running from |vlink(page_head)| to |page_tail|, must be moved to the
- contribution list when the user has specified no output routine.
-
- */
- if (vlink(page_head) != null) {
- if (vlink(contrib_head) == null) {
- contrib_tail = page_tail;
- } else {
- vlink(page_tail) = vlink(contrib_head);
- }
- vlink(contrib_head) = vlink(page_head);
- vlink(page_head) = null;
- page_tail = page_head;
- }
- flush_node_list(page_disc);
- page_disc = null;
- ship_out(static_pdf, box(output_box_par), SHIPPING_PAGE);
- box(output_box_par) = null;
-}
-
-/*tex
-
- When the user's output routine finishes, it has constructed a vlist in
- internal vertical mode, and \TeX\ will do the following:
-
-*/
-
-void resume_after_output(void)
-{
- if ((iloc != null) || ((token_type != output_text) && (token_type != backed_up))) {
- /*tex Recover from an unbalanced output routine */
- print_err("Unbalanced output routine");
- help2(
- "Your sneaky output routine has problematic {'s and/or }'s.",
- "I can't handle that very well; good luck."
- );
- error();
- /*tex Loops forever if reading from a file, since |null=min_halfword<=0|. */
- do {
- get_token();
- } while (iloc != null);
- }
- /*tex Conserve stack space in case more outputs are triggered. */
- end_token_list();
- end_graf(bottom_level);
- unsave();
- output_active = false;
- insert_penalties = 0;
- /*tex Ensure that box |output_box| is empty after output. */
- if (box(output_box_par) != null) {
- print_err("Output routine didn't use all of \\box");
- print_int(output_box_par);
- help3(
- "Your \\output commands should empty \\box\\outputbox,",
- "e.g., by saying `\\shipout\\box\\outputbox'.",
- "Proceed; I'll discard its present contents."
- );
- box_error(output_box_par);
- }
- if (tail != head) {
- /*tex Current list goes after heldover insertions. */
- try_couple_nodes(page_tail, vlink(head));
- page_tail = tail;
- }
- if (vlink(page_head) != null) {
- /* Both go before heldover contributions. */
- if (vlink(contrib_head) == null)
- contrib_tail = page_tail;
- try_couple_nodes(page_tail, vlink(contrib_head));
- try_couple_nodes(contrib_head, vlink(page_head));
- vlink(page_head) = null;
- page_tail = page_head;
- }
- flush_node_list(page_disc);
- page_disc = null;
- pop_nest();
- normal_page_filter(after_output);
- build_page();
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/buildpage.h b/Build/source/texk/web2c/luatexdir/tex/buildpage.h
deleted file mode 100644
index 9c013514efa..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/buildpage.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* buildpage.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef BUILDPAGE_H
-# define BUILDPAGE_H
-
-/* empty = 0 */
-# define inserts_only 1 /* |page_contents| when an insert node has been contributed, but no boxes */
-# define box_there 2 /* |page_contents| when a box or rule has been contributed */
-
-extern halfword page_tail; /* the final node on the current page */
-extern int page_contents; /* what is on the current page so far? */
-extern scaled page_max_depth; /* maximum box depth on page being built */
-extern halfword best_page_break; /* break here to get the best page known so far */
-extern int least_page_cost; /* the score for this currently best page */
-extern scaled best_size; /* its |page_goal| */
-
-/*
-The data structure definitions here use the fact that the |@!height| field
-appears in the fourth word of a box node.
-@^data structure assumptions@>
-*/
-
-# define broken_ptr(A) vlink((A)+2) /* an insertion for this class will break here if anywhere */
-# define broken_ins(A) vinfo((A)+2) /* this insertion might break at |broken_ptr| */
-# define last_ins_ptr(A) vlink((A)+3) /* the most recent insertion for this |subtype| */
-# define best_ins_ptr(A) vinfo((A)+3) /* the optimum most recent insertion */
-
-extern void initialize_buildpage(void);
-
-# define page_goal page_so_far[0] /* desired height of information on page being built */
-# define page_total page_so_far[1] /* height of the current page */
-# define page_shrink page_so_far[6] /* shrinkability of the current page */
-# define page_depth page_so_far[7] /* depth of the current page */
-
-extern scaled page_so_far[8]; /* height and glue of the current page */
-extern halfword last_glue; /* used to implement \.{\\lastskip */
-extern int last_penalty; /* used to implement \.{\\lastpenalty} */
-extern scaled last_kern; /* used to implement \.{\\lastkern} */
-extern int last_node_type; /* used to implement \.{\\lastnodetype} */
-extern int insert_penalties; /* sum of the penalties for held-over insertions */
-
-extern void print_totals(void);
-extern void freeze_page_specs(int s);
-
-extern boolean output_active;
-
-extern void start_new_page(void);
-
-# define contrib_tail nest[0].tail_field
- /* tail of the contribution list */
-
-extern void build_page(void); /* append contributions to the current page */
-extern void fire_up(halfword c);
-extern void resume_after_output(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.c b/Build/source/texk/web2c/luatexdir/tex/commands.c
deleted file mode 100644
index 261f23f4a83..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/commands.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
-
-commands.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-The symbolic names for glue parameters are put into \TeX's hash table by using
-the routine called |primitive|, defined below. Let us enter them now, so that we
-don't have to list all those parameter names anywhere else.
-
-*/
-
-void initialize_commands(void)
-{
-
- primitive_tex("lineskip", assign_glue_cmd, glue_base + line_skip_code, glue_base);
- primitive_tex("baselineskip", assign_glue_cmd, glue_base + baseline_skip_code, glue_base);
- primitive_tex("parskip", assign_glue_cmd, glue_base + par_skip_code, glue_base);
- primitive_tex("abovedisplayskip", assign_glue_cmd, glue_base + above_display_skip_code, glue_base);
- primitive_tex("belowdisplayskip", assign_glue_cmd, glue_base + below_display_skip_code, glue_base);
- primitive_tex("abovedisplayshortskip", assign_glue_cmd, glue_base + above_display_short_skip_code, glue_base);
- primitive_tex("belowdisplayshortskip", assign_glue_cmd, glue_base + below_display_short_skip_code, glue_base);
- primitive_tex("leftskip", assign_glue_cmd, glue_base + left_skip_code, glue_base);
- primitive_tex("rightskip", assign_glue_cmd, glue_base + right_skip_code, glue_base);
- primitive_tex("topskip", assign_glue_cmd, glue_base + top_skip_code, glue_base);
- primitive_tex("splittopskip", assign_glue_cmd, glue_base + split_top_skip_code, glue_base);
- primitive_tex("tabskip", assign_glue_cmd, glue_base + tab_skip_code, glue_base);
- primitive_tex("spaceskip", assign_glue_cmd, glue_base + space_skip_code, glue_base);
- primitive_tex("xspaceskip", assign_glue_cmd, glue_base + xspace_skip_code, glue_base);
- primitive_tex("parfillskip", assign_glue_cmd, glue_base + par_fill_skip_code, glue_base);
- primitive_tex("thinmuskip", assign_mu_glue_cmd, glue_base + thin_mu_skip_code, glue_base + thin_mu_skip_code);
- primitive_tex("medmuskip", assign_mu_glue_cmd, glue_base + med_mu_skip_code, glue_base + thin_mu_skip_code);
- primitive_tex("thickmuskip", assign_mu_glue_cmd, glue_base + thick_mu_skip_code, glue_base + thin_mu_skip_code);
- primitive_luatex("mathsurroundskip", assign_glue_cmd, glue_base + math_skip_code, glue_base);
- primitive_luatex("mathsurroundmode", assign_int_cmd, int_base + math_skip_mode_code, int_base);
- primitive_luatex("mathscriptboxmode", assign_int_cmd, int_base + math_script_box_mode_code, int_base);
- primitive_luatex("mathscriptcharmode", assign_int_cmd, int_base + math_script_char_mode_code, int_base);
- primitive_luatex("mathrulethicknessmode", assign_int_cmd, int_base + math_rule_thickness_mode_code, int_base);
- primitive_luatex("mathflattenmode", assign_int_cmd, int_base + math_flatten_mode_code, int_base);
- primitive_tex("output", assign_toks_cmd, output_routine_loc, local_base);
- primitive_tex("everypar", assign_toks_cmd, every_par_loc, local_base);
- primitive_tex("everymath", assign_toks_cmd, every_math_loc, local_base);
- primitive_tex("everydisplay", assign_toks_cmd, every_display_loc, local_base);
- primitive_tex("everyhbox", assign_toks_cmd, every_hbox_loc, local_base);
- primitive_tex("everyvbox", assign_toks_cmd, every_vbox_loc, local_base);
- primitive_tex("everyjob", assign_toks_cmd, every_job_loc, local_base);
- primitive_tex("everycr", assign_toks_cmd, every_cr_loc, local_base);
- primitive_tex("errhelp", assign_toks_cmd, err_help_loc, local_base);
-
- /*tex The integer parameter names must be entered into the hash table */
-
- primitive_tex("pretolerance", assign_int_cmd, int_base + pretolerance_code, int_base);
- primitive_tex("tolerance", assign_int_cmd, int_base + tolerance_code, int_base);
- primitive_tex("linepenalty", assign_int_cmd, int_base + line_penalty_code, int_base);
- primitive_tex("hyphenpenalty", assign_int_cmd, int_base + hyphen_penalty_code, int_base);
- primitive_tex("exhyphenpenalty", assign_int_cmd, int_base + ex_hyphen_penalty_code, int_base);
- primitive_tex("clubpenalty", assign_int_cmd, int_base + club_penalty_code, int_base);
- primitive_tex("widowpenalty", assign_int_cmd, int_base + widow_penalty_code, int_base);
- primitive_tex("displaywidowpenalty", assign_int_cmd, int_base + display_widow_penalty_code, int_base);
- primitive_tex("brokenpenalty", assign_int_cmd, int_base + broken_penalty_code, int_base);
- primitive_tex("binoppenalty", assign_int_cmd, int_base + bin_op_penalty_code, int_base);
- primitive_luatex("prerelpenalty", assign_int_cmd, int_base + pre_rel_penalty_code, int_base);
- primitive_luatex("prebinoppenalty", assign_int_cmd, int_base + pre_bin_op_penalty_code, int_base);
- primitive_tex("relpenalty", assign_int_cmd, int_base + rel_penalty_code, int_base);
- primitive_tex("predisplaypenalty", assign_int_cmd, int_base + pre_display_penalty_code, int_base);
- primitive_tex("postdisplaypenalty", assign_int_cmd, int_base + post_display_penalty_code, int_base);
- primitive_luatex("mathpenaltiesmode", assign_int_cmd, int_base + math_penalties_mode_code, int_base);
- primitive_luatex("mathdelimitersmode", assign_int_cmd, int_base + math_delimiters_mode_code, int_base);
- primitive_tex("interlinepenalty", assign_int_cmd, int_base + inter_line_penalty_code, int_base);
- primitive_tex("doublehyphendemerits", assign_int_cmd, int_base + double_hyphen_demerits_code, int_base);
- primitive_tex("finalhyphendemerits", assign_int_cmd, int_base + final_hyphen_demerits_code, int_base);
- primitive_tex("adjdemerits", assign_int_cmd, int_base + adj_demerits_code, int_base);
- primitive_tex("mag", assign_int_cmd, int_base + mag_code, int_base);
- primitive_tex("delimiterfactor", assign_int_cmd, int_base + delimiter_factor_code, int_base);
- primitive_tex("looseness", assign_int_cmd, int_base + looseness_code, int_base);
- primitive_tex("time", assign_int_cmd, int_base + time_code, int_base);
- primitive_tex("day", assign_int_cmd, int_base + day_code, int_base);
- primitive_tex("month", assign_int_cmd, int_base + month_code, int_base);
- primitive_tex("year", assign_int_cmd, int_base + year_code, int_base);
- primitive_tex("showboxbreadth", assign_int_cmd, int_base + show_box_breadth_code, int_base);
- primitive_tex("showboxdepth", assign_int_cmd, int_base + show_box_depth_code, int_base);
- primitive_tex("hbadness", assign_int_cmd, int_base + hbadness_code, int_base);
- primitive_tex("vbadness", assign_int_cmd, int_base + vbadness_code, int_base);
- primitive_tex("pausing", assign_int_cmd, int_base + pausing_code, int_base);
- primitive_tex("tracingonline", assign_int_cmd, int_base + tracing_online_code, int_base);
- primitive_tex("tracingmacros", assign_int_cmd, int_base + tracing_macros_code, int_base);
- primitive_tex("tracingstats", assign_int_cmd, int_base + tracing_stats_code, int_base);
- primitive_tex("tracingparagraphs", assign_int_cmd, int_base + tracing_paragraphs_code, int_base);
- primitive_tex("tracingpages", assign_int_cmd, int_base + tracing_pages_code, int_base);
- primitive_tex("tracingoutput", assign_int_cmd, int_base + tracing_output_code, int_base);
- primitive_tex("tracinglostchars", assign_int_cmd, int_base + tracing_lost_chars_code, int_base);
- primitive_tex("tracingcommands", assign_int_cmd, int_base + tracing_commands_code, int_base);
- primitive_tex("tracingrestores", assign_int_cmd, int_base + tracing_restores_code, int_base);
- primitive_tex("uchyph", assign_int_cmd, int_base + uc_hyph_code, int_base);
- primitive_tex("outputpenalty", assign_int_cmd, int_base + output_penalty_code, int_base);
- primitive_tex("maxdeadcycles", assign_int_cmd, int_base + max_dead_cycles_code, int_base);
- primitive_tex("hangafter", assign_int_cmd, int_base + hang_after_code, int_base);
- primitive_tex("floatingpenalty", assign_int_cmd, int_base + floating_penalty_code, int_base);
- primitive_tex("globaldefs", assign_int_cmd, int_base + global_defs_code, int_base);
- primitive_tex("fam", assign_int_cmd, int_base + cur_fam_code, int_base);
- primitive_tex("escapechar", assign_int_cmd, int_base + escape_char_code, int_base);
- primitive_tex("defaulthyphenchar", assign_int_cmd, int_base + default_hyphen_char_code, int_base);
- primitive_tex("defaultskewchar", assign_int_cmd, int_base + default_skew_char_code, int_base);
- primitive_tex("endlinechar", assign_int_cmd, int_base + end_line_char_code, int_base);
- primitive_tex("newlinechar", assign_int_cmd, int_base + new_line_char_code, int_base);
- primitive_tex("language", assign_int_cmd, int_base + language_code, int_base);
- primitive_tex("setlanguage", assign_int_cmd, int_base + cur_lang_code, int_base);
- primitive_tex("firstvalidlanguage", assign_int_cmd, int_base + first_valid_language_code, int_base);
- primitive_tex("exhyphenchar", assign_int_cmd, int_base + ex_hyphen_char_code, int_base);
- primitive_tex("lefthyphenmin", assign_int_cmd, int_base + left_hyphen_min_code, int_base);
- primitive_tex("righthyphenmin", assign_int_cmd, int_base + right_hyphen_min_code, int_base);
- primitive_tex("holdinginserts", assign_int_cmd, int_base + holding_inserts_code, int_base);
- primitive_tex("errorcontextlines", assign_int_cmd, int_base + error_context_lines_code, int_base);
- primitive_luatex("nokerns", assign_int_cmd, int_base + disable_kern_code, int_base);
- primitive_luatex("noligs", assign_int_cmd, int_base + disable_lig_code, int_base);
- primitive_luatex("nospaces", assign_int_cmd, int_base + disable_space_code, int_base);
- primitive_luatex("catcodetable", assign_int_cmd, int_base + cat_code_table_code, int_base);
- primitive_luatex("outputbox", assign_int_cmd, int_base + output_box_code, int_base);
- primitive_luatex("outputmode", assign_int_cmd, int_base + output_mode_code, int_base);
- primitive_luatex("adjustspacing", assign_int_cmd, int_base + adjust_spacing_code, int_base);
- primitive_luatex("protrudechars", assign_int_cmd, int_base + protrude_chars_code, int_base);
- primitive_luatex("tracingfonts", assign_int_cmd, int_base + tracing_fonts_code, int_base);
- primitive_luatex("draftmode", assign_int_cmd, int_base + draft_mode_code, int_base);
- primitive_tex("parindent", assign_dimen_cmd, dimen_base + par_indent_code, dimen_base);
- primitive_tex("mathsurround", assign_dimen_cmd, dimen_base + math_surround_code, dimen_base);
- primitive_tex("lineskiplimit", assign_dimen_cmd, dimen_base + line_skip_limit_code, dimen_base);
- primitive_tex("hsize", assign_dimen_cmd, dimen_base + hsize_code, dimen_base);
- primitive_tex("vsize", assign_dimen_cmd, dimen_base + vsize_code, dimen_base);
- primitive_tex("maxdepth", assign_dimen_cmd, dimen_base + max_depth_code, dimen_base);
- primitive_tex("splitmaxdepth", assign_dimen_cmd, dimen_base + split_max_depth_code, dimen_base);
- primitive_tex("boxmaxdepth", assign_dimen_cmd, dimen_base + box_max_depth_code, dimen_base);
- primitive_tex("hfuzz", assign_dimen_cmd, dimen_base + hfuzz_code, dimen_base);
- primitive_tex("vfuzz", assign_dimen_cmd, dimen_base + vfuzz_code, dimen_base);
- primitive_tex("delimitershortfall", assign_dimen_cmd, dimen_base + delimiter_shortfall_code, dimen_base);
- primitive_tex("nulldelimiterspace", assign_dimen_cmd, dimen_base + null_delimiter_space_code, dimen_base);
- primitive_tex("scriptspace", assign_dimen_cmd, dimen_base + script_space_code, dimen_base);
- primitive_tex("predisplaysize", assign_dimen_cmd, dimen_base + pre_display_size_code, dimen_base);
- primitive_tex("displaywidth", assign_dimen_cmd, dimen_base + display_width_code, dimen_base);
- primitive_tex("displayindent", assign_dimen_cmd, dimen_base + display_indent_code, dimen_base);
- primitive_tex("overfullrule", assign_dimen_cmd, dimen_base + overfull_rule_code, dimen_base);
- primitive_tex("hangindent", assign_dimen_cmd, dimen_base + hang_indent_code, dimen_base);
- primitive_tex("hoffset", assign_dimen_cmd, dimen_base + h_offset_code, dimen_base);
- primitive_tex("voffset", assign_dimen_cmd, dimen_base + v_offset_code, dimen_base);
- primitive_tex("emergencystretch", assign_dimen_cmd, dimen_base + emergency_stretch_code, dimen_base);
- primitive_luatex("pagewidth", assign_dimen_cmd, dimen_base + page_width_code, dimen_base);
- primitive_luatex("pageheight", assign_dimen_cmd, dimen_base + page_height_code, dimen_base);
- primitive_luatex("pxdimen", assign_dimen_cmd, dimen_base + px_dimen_code, dimen_base);
- primitive_luatex("predisplaygapfactor", assign_int_cmd, int_base + math_pre_display_gap_factor_code, int_base);
- primitive_luatex("hyphenpenaltymode", assign_int_cmd, int_base + hyphen_penalty_mode_code, int_base);
- primitive_luatex("automatichyphenpenalty", assign_int_cmd, int_base + automatic_hyphen_penalty_code, int_base);
- primitive_luatex("explicithyphenpenalty", assign_int_cmd, int_base + explicit_hyphen_penalty_code, int_base);
- primitive_luatex("automatichyphenmode", assign_int_cmd, int_base + automatic_hyphen_mode_code, int_base);
- primitive_luatex("compoundhyphenmode", assign_int_cmd, int_base + compound_hyphen_mode_code, int_base);
- primitive_luatex("breakafterdirmode", assign_int_cmd, int_base + break_after_dir_mode_code, int_base);
- primitive_luatex("exceptionpenalty", assign_int_cmd, int_base + exception_penalty_code, int_base);
- primitive_luatex("fixupboxesmode", assign_int_cmd, int_base + fixup_boxes_code, int_base);
- primitive_luatex("glyphdimensionsmode", assign_int_cmd, int_base + glyph_dimensions_code, int_base);
-
- /*tex
-
- Many of \TeX's primitives need no |equiv|, since they are identifiable by
- their |eq_type| alone. These primitives are loaded into the hash table as
- follows:
-
- */
-
- primitive_tex(" ", ex_space_cmd, 0, 0);
- primitive_tex("/", ital_corr_cmd, 0, 0);
- primitive_tex("accent", accent_cmd, 0, 0);
- primitive_tex("advance", advance_cmd, 0, 0);
- primitive_tex("afterassignment", after_assignment_cmd, 0, 0);
- primitive_tex("aftergroup", after_group_cmd, 0, 0);
- primitive_tex("begingroup", begin_group_cmd, 0, 0);
- primitive_tex("char", char_num_cmd, 0, 0);
- primitive_tex("csname", cs_name_cmd, 0, 0);
- primitive_luatex("lastnamedcs", cs_name_cmd, 1, 0);
- primitive_luatex("begincsname", cs_name_cmd, 2, 0);
- primitive_tex("delimiter", delim_num_cmd, 0, 0);
- primitive_luatex("Udelimiter", delim_num_cmd, 1, 0);
- primitive_tex("divide", divide_cmd, 0, 0);
- primitive_tex("endcsname", end_cs_name_cmd, 0, 0);
- primitive_tex("endgroup", end_group_cmd, 0, 0);
- cs_text(frozen_end_group) = maketexstring("endgroup");
- eqtb[frozen_end_group] = eqtb[cur_val];
- primitive_tex("expandafter", expand_after_cmd, 0, 0);
- primitive_tex("font", def_font_cmd, 0, 0);
- primitive_luatex("letterspacefont", letterspace_font_cmd, 0, 0);
- primitive_luatex("expandglyphsinfont", normal_cmd, expand_font_code, 0);
- primitive_luatex("copyfont", copy_font_cmd, 0, 0);
- primitive_luatex("setfontid", set_font_id_cmd, 0, 0);
- primitive_tex("fontdimen", assign_font_dimen_cmd, 0, 0);
- primitive_tex("halign", halign_cmd, 0, 0);
- primitive_tex("hrule", hrule_cmd, 0, 0);
- primitive_luatex("nohrule", no_hrule_cmd, 0, 0);
- primitive_tex("ignorespaces", ignore_spaces_cmd, 0, 0);
- primitive_tex("insert", insert_cmd, 0, 0);
- primitive_luatex("leftghost", char_ghost_cmd, 0, 0);
- primitive_tex("mark", mark_cmd, 0, 0);
- primitive_tex("mathaccent", math_accent_cmd, 0, 0);
- primitive_luatex("Umathaccent", math_accent_cmd, 1, 0);
- primitive_tex("mathchar", math_char_num_cmd, 0, 0);
- primitive_luatex("Umathchar", math_char_num_cmd, 1, 0);
- primitive_luatex("Umathcharnum", math_char_num_cmd, 2, 0);
- primitive_tex("mathchoice", math_choice_cmd, 0, 0);
- primitive_luatex("Ustack", math_choice_cmd, 1, 0);
- primitive_tex("multiply", multiply_cmd, 0, 0);
- primitive_tex("noalign", no_align_cmd, 0, 0);
- primitive_tex("noboundary", boundary_cmd, 0, 0);
- primitive_tex("boundary", boundary_cmd, 1, 0);
- primitive_tex("protrusionboundary", boundary_cmd, 2, 0);
- primitive_tex("wordboundary", boundary_cmd, 3, 0);
- primitive_tex("noexpand", no_expand_cmd, 0, 0);
- primitive_luatex("primitive", no_expand_cmd, 1, 0);
- primitive_tex("nonscript", non_script_cmd, 0, 0);
- primitive_tex("omit", omit_cmd, 0, 0);
- primitive_tex("parshape", set_tex_shape_cmd, par_shape_loc, par_shape_loc);
- primitive_tex("penalty", break_penalty_cmd, 0, 0);
- primitive_tex("prevgraf", set_prev_graf_cmd, 0, 0);
- primitive_tex("radical", radical_cmd, 0, 0);
- primitive_luatex("Uradical", radical_cmd, 1, 0);
- primitive_luatex("Uroot", radical_cmd, 2, 0);
- primitive_luatex("Uunderdelimiter", radical_cmd, 3, 0);
- primitive_luatex("Uoverdelimiter", radical_cmd, 4, 0);
- primitive_luatex("Udelimiterunder", radical_cmd, 5, 0);
- primitive_luatex("Udelimiterover", radical_cmd, 6, 0);
- primitive_luatex("Uhextensible", radical_cmd, 7, 0);
- primitive_tex("read", read_to_cs_cmd, 0, 0);
- primitive_tex("relax", relax_cmd, too_big_char, too_big_char);
- cs_text(frozen_relax) = maketexstring("relax");
- eqtb[frozen_relax] = eqtb[cur_val];
- primitive_luatex("rightghost", char_ghost_cmd, 1, 0);
- primitive_tex("setbox", set_box_cmd, 0, 0);
- primitive_tex("the", the_cmd, 0, 0);
- primitive_luatex("toksapp", combine_toks_cmd, 0, 0);
- primitive_luatex("etoksapp", combine_toks_cmd, 1, 0);
- primitive_luatex("tokspre", combine_toks_cmd, 2, 0);
- primitive_luatex("etokspre", combine_toks_cmd, 3, 0);
- primitive_luatex("gtoksapp", combine_toks_cmd, 4, 0);
- primitive_luatex("xtoksapp", combine_toks_cmd, 5, 0);
- primitive_luatex("gtokspre", combine_toks_cmd, 6, 0);
- primitive_luatex("xtokspre", combine_toks_cmd, 7, 0);
- primitive_tex("toks", toks_register_cmd, 0, 0);
- primitive_tex("vadjust", vadjust_cmd, 0, 0);
- primitive_tex("valign", valign_cmd, 0, 0);
- primitive_tex("vcenter", vcenter_cmd, 0, 0);
- primitive_tex("vrule", vrule_cmd, 0, 0);
- primitive_luatex("novrule", no_vrule_cmd, 0, 0);
- primitive_luatex("luafunctioncall", lua_function_call_cmd, 0, 0);
- primitive_luatex("luabytecodecall", lua_bytecode_call_cmd, 0, 0);
- primitive_luatex("luadef", def_lua_call_cmd, 0, 0);
- primitive_tex("par", par_end_cmd, too_big_char, too_big_char);
- par_loc = cur_val;
- par_token = cs_token_flag + par_loc;
-
- /*tex
- The processing of \.{\\input} involves the |start_input| subroutine,
- which will be declared later; the processing of \.{\\endinput} is trivial.
- */
-
- primitive_tex("input", input_cmd, 0, 0);
- primitive_tex("endinput", input_cmd, 1, 0);
- primitive_tex("topmark", top_bot_mark_cmd, top_mark_code, 0);
- primitive_tex("firstmark", top_bot_mark_cmd, first_mark_code, 0);
- primitive_tex("botmark", top_bot_mark_cmd, bot_mark_code, 0);
- primitive_tex("splitfirstmark", top_bot_mark_cmd, split_first_mark_code, 0);
- primitive_tex("splitbotmark", top_bot_mark_cmd, split_bot_mark_code, 0);
- primitive_luatex("clearmarks", mark_cmd, clear_marks_code, 0);
- primitive_etex("marks", mark_cmd, marks_code, 0);
- primitive_etex("topmarks", top_bot_mark_cmd, top_mark_code + marks_code, 0);
- primitive_etex("firstmarks", top_bot_mark_cmd, first_mark_code + marks_code, 0);
- primitive_etex("botmarks", top_bot_mark_cmd, bot_mark_code + marks_code, 0);
- primitive_etex("splitfirstmarks", top_bot_mark_cmd, split_first_mark_code + marks_code, 0);
- primitive_etex("splitbotmarks", top_bot_mark_cmd, split_bot_mark_code + marks_code, 0);
-
- /*
- The hash table is initialized with `\.{\\count}', `\.{\\attribute}',
- `\.{\\dimen}', `\.{\\skip}', and `\.{\\muskip}' all having |register|
- as their command code; they are distinguished by the |chr_code|, which
- is either |int_val|, |attr_val|, |dimen_val|, |glue_val|, or |mu_val|.
- */
-
- primitive_tex("count", register_cmd, int_val_level, 0);
- primitive_luatex("attribute", register_cmd, attr_val_level, 0);
- primitive_tex("dimen", register_cmd, dimen_val_level, 0);
- primitive_tex("skip", register_cmd, glue_val_level, 0);
- primitive_tex("muskip", register_cmd, mu_val_level, 0);
-
- primitive_tex("spacefactor", set_aux_cmd, hmode, 0);
- primitive_tex("prevdepth", set_aux_cmd, vmode, 0);
- primitive_tex("deadcycles", set_page_int_cmd, 0, 0);
- primitive_tex("insertpenalties", set_page_int_cmd, 1, 0);
- primitive_tex("wd", set_box_dimen_cmd, width_offset, 0);
- primitive_tex("ht", set_box_dimen_cmd, height_offset, 0);
- primitive_tex("dp", set_box_dimen_cmd, depth_offset, 0);
- primitive_tex("lastpenalty", last_item_cmd, lastpenalty_code, 0);
- primitive_tex("lastkern", last_item_cmd, lastkern_code, 0);
- primitive_tex("lastskip", last_item_cmd, lastskip_code, 0);
- primitive_tex("inputlineno", last_item_cmd, input_line_no_code, 0);
- primitive_tex("badness", last_item_cmd, badness_code, 0);
- primitive_luatex("luatexversion", last_item_cmd, luatex_version_code, 0);
- primitive_luatex("lastsavedboxresourceindex", last_item_cmd, last_saved_box_resource_index_code, 0);
- primitive_luatex("lastsavedimageresourceindex", last_item_cmd, last_saved_image_resource_index_code, 0);
- primitive_luatex("lastsavedimageresourcepages", last_item_cmd, last_saved_image_resource_pages_code, 0);
- primitive_luatex("lastxpos", last_item_cmd, last_x_pos_code, 0);
- primitive_luatex("lastypos", last_item_cmd, last_y_pos_code, 0);
- primitive_luatex("randomseed", last_item_cmd, random_seed_code, 0);
-
- primitive_tex("number", convert_cmd, number_code, 0);
- primitive_tex("romannumeral", convert_cmd, roman_numeral_code, 0);
- primitive_tex("string", convert_cmd, string_code, 0);
- primitive_luatex("csstring", convert_cmd, cs_string_code, 0);
- primitive_tex("meaning", convert_cmd, meaning_code, 0);
- primitive_etex("eTeXVersion", convert_cmd, etex_code, 0);
- primitive_tex("fontname", convert_cmd, font_name_code, 0);
- primitive_luatex("fontid", convert_cmd, font_id_code, 0);
- primitive_luatex("luatexrevision", convert_cmd, luatex_revision_code, 0);
- primitive_luatex("luatexbanner", convert_cmd, luatex_banner_code, 0);
- primitive_luatex("leftmarginkern", convert_cmd, left_margin_kern_code, 0);
- primitive_luatex("rightmarginkern", convert_cmd, right_margin_kern_code, 0);
- primitive_luatex("uniformdeviate", convert_cmd, uniform_deviate_code, 0);
- primitive_luatex("normaldeviate", convert_cmd, normal_deviate_code, 0);
- primitive_core("directlua", convert_cmd, lua_code, 0);
- primitive_luatex("luafunction", convert_cmd, lua_function_code, 0);
- primitive_luatex("luabytecode", convert_cmd, lua_bytecode_code, 0);
- primitive_luatex("luaescapestring", convert_cmd, lua_escape_string_code, 0);
- primitive_luatex("mathstyle", convert_cmd, math_style_code, 0);
- primitive_luatex("expanded", convert_cmd, expanded_code, 0);
- primitive_luatex("immediateassignment", convert_cmd, immediate_assignment_code, 0);
- primitive_luatex("immediateassigned", convert_cmd, immediate_assigned_code, 0);
- primitive_tex("jobname", convert_cmd, job_name_code, 0);
- primitive_luatex("formatname", convert_cmd, format_name_code, 0);
- primitive_luatex("Uchar", convert_cmd, uchar_code, 0);
-
- primitive_luatex("Umathcharclass", convert_cmd, math_char_class_code, 0);
- primitive_luatex("Umathcharfam", convert_cmd, math_char_fam_code, 0);
- primitive_luatex("Umathcharslot", convert_cmd, math_char_slot_code, 0);
-
- primitive_tex("if", if_test_cmd, if_char_code, 0);
- primitive_tex("ifcat", if_test_cmd, if_cat_code, 0);
- primitive_tex("ifnum", if_test_cmd, if_int_code, 0);
- primitive_tex("ifdim", if_test_cmd, if_dim_code, 0);
- primitive_tex("ifodd", if_test_cmd, if_odd_code, 0);
- primitive_tex("ifvmode", if_test_cmd, if_vmode_code, 0);
- primitive_tex("ifhmode", if_test_cmd, if_hmode_code, 0);
- primitive_tex("ifmmode", if_test_cmd, if_mmode_code, 0);
- primitive_tex("ifinner", if_test_cmd, if_inner_code, 0);
- primitive_tex("ifvoid", if_test_cmd, if_void_code, 0);
- primitive_tex("ifhbox", if_test_cmd, if_hbox_code, 0);
- primitive_tex("ifvbox", if_test_cmd, if_vbox_code, 0);
- primitive_tex("ifx", if_test_cmd, if_x_code, 0);
- primitive_tex("ifeof", if_test_cmd, if_eof_code, 0);
- primitive_tex("iftrue", if_test_cmd, if_true_code, 0);
- primitive_tex("iffalse", if_test_cmd, if_false_code, 0);
- primitive_tex("ifcase", if_test_cmd, if_case_code, 0);
- primitive_luatex("ifprimitive", if_test_cmd, if_primitive_code, 0);
- primitive_luatex("ifcondition", if_test_cmd, if_condition_code, 0);
- primitive_tex("fi", fi_or_else_cmd, fi_code, 0);
- cs_text(frozen_fi) = maketexstring("fi");
- eqtb[frozen_fi] = eqtb[cur_val];
- primitive_tex("or", fi_or_else_cmd, or_code, 0);
- primitive_tex("else", fi_or_else_cmd, else_code, 0);
-
- /*
- \TeX\ always knows at least one font, namely the null font. It has no
- characters, and its seven parameters are all equal to zero.
- */
-
- primitive_tex("nullfont", set_font_cmd, null_font, 0);
- cs_text(frozen_null_font) = maketexstring("nullfont");
- eqtb[frozen_null_font] = eqtb[cur_val];
-
- primitive_tex("span", tab_mark_cmd, span_code, tab_mark_cmd_code);
- primitive_luatex("aligntab", tab_mark_cmd, tab_mark_cmd_code, tab_mark_cmd_code);
- primitive_luatex("alignmark", mac_param_cmd, tab_mark_cmd_code, tab_mark_cmd_code);
- primitive_tex("cr", car_ret_cmd, cr_code, cr_code);
- cs_text(frozen_cr) = maketexstring("cr");
- eqtb[frozen_cr] = eqtb[cur_val];
- primitive_tex("crcr", car_ret_cmd, cr_cr_code, cr_code);
- cs_text(frozen_end_template) = maketexstring("endtemplate");
- cs_text(frozen_endv) = maketexstring("endtemplate");
- set_eq_type(frozen_endv, endv_cmd);
- set_equiv(frozen_endv, null_list);
- set_eq_level(frozen_endv, level_one);
- eqtb[frozen_end_template] = eqtb[frozen_endv];
- set_eq_type(frozen_end_template, end_template_cmd);
-
- primitive_tex("pagegoal", set_page_dimen_cmd, 0, 0);
- primitive_tex("pagetotal", set_page_dimen_cmd, 1, 0);
- primitive_tex("pagestretch", set_page_dimen_cmd, 2, 0);
- primitive_tex("pagefilstretch", set_page_dimen_cmd, 3, 0);
- primitive_tex("pagefillstretch", set_page_dimen_cmd, 4, 0);
- primitive_tex("pagefilllstretch", set_page_dimen_cmd, 5, 0);
- primitive_tex("pageshrink", set_page_dimen_cmd, 6, 0);
- primitive_tex("pagedepth", set_page_dimen_cmd, 7, 0);
-
- /*
- Either \.{\\dump} or \.{\\end} will cause |main_control| to enter the
- endgame, since both of them have `|stop|' as their command code.
- */
-
- primitive_tex("end", stop_cmd, 0, 0);
- primitive_tex("dump", stop_cmd, 1, 0);
-
- primitive_tex("hskip", hskip_cmd, skip_code, 0);
- primitive_tex("hfil", hskip_cmd, fil_code, 0);
- primitive_tex("hfill", hskip_cmd, fill_code, 0);
- primitive_tex("hss", hskip_cmd, ss_code, 0);
- primitive_tex("hfilneg", hskip_cmd, fil_neg_code, 0);
- primitive_tex("vskip", vskip_cmd, skip_code, 0);
- primitive_tex("vfil", vskip_cmd, fil_code, 0);
- primitive_tex("vfill", vskip_cmd, fill_code, 0);
- primitive_tex("vss", vskip_cmd, ss_code, 0);
- primitive_tex("vfilneg", vskip_cmd, fil_neg_code, 0);
- primitive_tex("mskip", mskip_cmd, mskip_code, 0);
- primitive_tex("kern", kern_cmd, explicit_kern, 0);
- primitive_tex("mkern", mkern_cmd, mu_glue, 0);
- primitive_tex("moveleft", hmove_cmd, 1, 0);
- primitive_tex("moveright", hmove_cmd, 0, 0);
- primitive_tex("raise", vmove_cmd, 1, 0);
- primitive_tex("lower", vmove_cmd, 0, 0);
- primitive_tex("box", make_box_cmd, box_code, 0);
- primitive_tex("copy", make_box_cmd, copy_code, 0);
- primitive_tex("lastbox", make_box_cmd, last_box_code, 0);
- primitive_tex("vsplit", make_box_cmd, vsplit_code, 0);
- primitive_tex("tpack", make_box_cmd, tpack_code, 0);
- primitive_tex("vpack", make_box_cmd, vpack_code, 0);
- primitive_tex("hpack", make_box_cmd, hpack_code, 0);
- primitive_tex("vtop", make_box_cmd, vtop_code, 0);
- primitive_tex("vbox", make_box_cmd, vtop_code + vmode, 0);
- primitive_tex("hbox", make_box_cmd, vtop_code + hmode, 0);
- primitive_tex("shipout", leader_ship_cmd, a_leaders - 2, 0); /* |ship_out_flag=leader_flag-2| */
- primitive_tex("leaders", leader_ship_cmd, a_leaders, 0);
- primitive_tex("cleaders", leader_ship_cmd, c_leaders, 0);
- primitive_tex("xleaders", leader_ship_cmd, x_leaders, 0);
- primitive_luatex("gleaders", leader_ship_cmd, g_leaders, 0);
- primitive_luatex("boxdir", assign_box_dir_cmd, 0, 0);
- primitive_luatex("boxdirection", assign_box_direction_cmd, 0, 0);
- primitive_tex("indent", start_par_cmd, 1, 0);
- primitive_tex("noindent", start_par_cmd, 0, 0);
- primitive_luatex("quitvmode", start_par_cmd, 2, 0);
- primitive_tex("unpenalty", remove_item_cmd, penalty_node, 0);
- primitive_tex("unkern", remove_item_cmd, kern_node, 0);
- primitive_tex("unskip", remove_item_cmd, glue_node, 0);
- primitive_tex("unhbox", un_hbox_cmd, box_code, 0);
- primitive_tex("unhcopy", un_hbox_cmd, copy_code, 0);
- primitive_tex("unvbox", un_vbox_cmd, box_code, 0);
- primitive_tex("unvcopy", un_vbox_cmd, copy_code, 0);
- primitive_tex("-", discretionary_cmd, explicit_disc, 0); /* good old tex */
- primitive_tex("discretionary", discretionary_cmd, discretionary_disc, 0);
- primitive_luatex("explicitdiscretionary", discretionary_cmd, explicit_disc, 0);
- primitive_luatex("automaticdiscretionary", discretionary_cmd, automatic_disc, 0);
- primitive_luatex("localleftbox", assign_local_box_cmd, 0, 0);
- primitive_luatex("localrightbox", assign_local_box_cmd, 1, 0);
-
- primitive_luatex("Ustartmath", math_shift_cs_cmd, text_style, 0);
- primitive_luatex("Ustopmath", math_shift_cs_cmd, cramped_text_style, 0);
- primitive_luatex("Ustartdisplaymath", math_shift_cs_cmd, display_style, 0);
- primitive_luatex("Ustopdisplaymath", math_shift_cs_cmd, cramped_display_style, 0);
- primitive_tex("eqno", eq_no_cmd, 0, 0);
- primitive_tex("leqno", eq_no_cmd, 1, 0);
- primitive_tex("mathord", math_comp_cmd, ord_noad_type, 0);
- primitive_tex("mathop", math_comp_cmd, op_noad_type_normal, 0);
- primitive_tex("mathbin", math_comp_cmd, bin_noad_type, 0);
- primitive_tex("mathrel", math_comp_cmd, rel_noad_type, 0);
- primitive_tex("mathopen", math_comp_cmd, open_noad_type, 0);
- primitive_tex("mathclose", math_comp_cmd, close_noad_type, 0);
- primitive_tex("mathpunct", math_comp_cmd, punct_noad_type, 0);
- primitive_tex("mathinner", math_comp_cmd, inner_noad_type, 0);
- primitive_tex("underline", math_comp_cmd, under_noad_type, 0);
- primitive_tex("overline", math_comp_cmd, over_noad_type, 0);
- primitive_tex("displaylimits", limit_switch_cmd, op_noad_type_normal, 0);
- primitive_tex("limits", limit_switch_cmd, op_noad_type_limits, 0);
- primitive_tex("nolimits", limit_switch_cmd, op_noad_type_no_limits, 0);
- primitive_tex("displaystyle", math_style_cmd, display_style, 0);
- primitive_tex("textstyle", math_style_cmd, text_style, 0);
- primitive_tex("scriptstyle", math_style_cmd, script_style, 0);
- primitive_tex("scriptscriptstyle", math_style_cmd, script_script_style, 0);
- primitive_luatex("crampeddisplaystyle", math_style_cmd, cramped_display_style, 0);
- primitive_luatex("crampedtextstyle", math_style_cmd, cramped_text_style, 0);
- primitive_luatex("crampedscriptstyle", math_style_cmd, cramped_script_style, 0);
- primitive_luatex("crampedscriptscriptstyle", math_style_cmd, cramped_script_script_style, 0);
- primitive_luatex("Usuperscript", super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd);
- primitive_luatex("Usubscript", super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd);
- primitive_luatex("Unosuperscript", no_super_sub_script_cmd, sup_mark_cmd, sup_mark_cmd);
- primitive_luatex("Unosubscript", no_super_sub_script_cmd, sub_mark_cmd, sup_mark_cmd);
- primitive_tex("above", above_cmd, above_code, 0);
- primitive_tex("over", above_cmd, over_code, 0);
- primitive_tex("atop", above_cmd, atop_code, 0);
- primitive_luatex("Uskewed", above_cmd, skewed_code, 0);
- primitive_tex("abovewithdelims", above_cmd, delimited_code + above_code, 0);
- primitive_tex("overwithdelims", above_cmd, delimited_code + over_code, 0);
- primitive_tex("atopwithdelims", above_cmd, delimited_code + atop_code, 0);
- primitive_luatex("Uskewedwithdelims", above_cmd, delimited_code + skewed_code, 0);
- primitive_tex("left", left_right_cmd, left_noad_side, 0);
- primitive_tex("right", left_right_cmd, right_noad_side, 0);
- primitive_tex("middle", left_right_cmd, middle_noad_side, 0);
- primitive_tex("Uleft", left_right_cmd, 10+left_noad_side, 0);
- primitive_tex("Uright", left_right_cmd, 10+right_noad_side, 0);
- primitive_tex("Umiddle", left_right_cmd, 10+middle_noad_side, 0);
- primitive_luatex("Uvextensible", left_right_cmd, 10+no_noad_side, 0);
- cs_text(frozen_right) = maketexstring("right");
- eqtb[frozen_right] = eqtb[cur_val];
-
- primitive_tex("long", prefix_cmd, 1, 0);
- primitive_tex("outer", prefix_cmd, 2, 0);
- primitive_tex("global", prefix_cmd, 4, 0);
- primitive_tex("def", def_cmd, 0, 0);
- primitive_tex("gdef", def_cmd, 1, 0);
- primitive_tex("edef", def_cmd, 2, 0);
- primitive_tex("xdef", def_cmd, 3, 0);
- primitive_tex("glet", let_cmd, 0, 0);
- primitive_tex("let", let_cmd, 1, 0);
- primitive_tex("futurelet", let_cmd, 2, 0);
- primitive_luatex("letcharcode", let_cmd, 3, 0);
- primitive_tex("chardef", shorthand_def_cmd, char_def_code, 0);
- primitive_tex("mathchardef", shorthand_def_cmd, math_char_def_code, 0);
- primitive_luatex("Umathchardef", shorthand_def_cmd, xmath_char_def_code, 0);
- primitive_luatex("Umathcharnumdef", shorthand_def_cmd, umath_char_def_code, 0);
- primitive_tex("countdef", shorthand_def_cmd, count_def_code, 0);
- primitive_luatex("attributedef", shorthand_def_cmd, attribute_def_code, 0);
- primitive_tex("dimendef", shorthand_def_cmd, dimen_def_code, 0);
- primitive_tex("skipdef", shorthand_def_cmd, skip_def_code, 0);
- primitive_tex("muskipdef", shorthand_def_cmd, mu_skip_def_code, 0);
- primitive_tex("toksdef", shorthand_def_cmd, toks_def_code, 0);
- primitive_tex("catcode", def_char_code_cmd, cat_code_base, cat_code_base);
- primitive_tex("mathcode", def_char_code_cmd, math_code_base, cat_code_base);
- primitive_tex("lccode", def_char_code_cmd, lc_code_base, cat_code_base);
- primitive_tex("uccode", def_char_code_cmd, uc_code_base, cat_code_base);
- primitive_tex("sfcode", def_char_code_cmd, sf_code_base, cat_code_base);
- primitive_tex("delcode", def_del_code_cmd, del_code_base, del_code_base);
- primitive_tex("textfont", def_family_cmd, text_size, 0);
- primitive_tex("scriptfont", def_family_cmd, script_size, 0);
- primitive_tex("scriptscriptfont", def_family_cmd, script_script_size, 0);
- primitive_luatex("Umathquad", set_math_param_cmd, math_param_quad, 0);
- primitive_luatex("Umathaxis", set_math_param_cmd, math_param_axis, 0);
-
- primitive_luatex("Umathoperatorsize", set_math_param_cmd, math_param_operator_size, 0);
- primitive_luatex("Umathoverbarkern", set_math_param_cmd, math_param_overbar_kern, 0);
- primitive_luatex("Umathoverbarrule", set_math_param_cmd, math_param_overbar_rule, 0);
- primitive_luatex("Umathoverbarvgap", set_math_param_cmd, math_param_overbar_vgap, 0);
- primitive_luatex("Umathunderbarkern", set_math_param_cmd, math_param_underbar_kern, 0);
- primitive_luatex("Umathunderbarrule", set_math_param_cmd, math_param_underbar_rule, 0);
- primitive_luatex("Umathunderbarvgap", set_math_param_cmd, math_param_underbar_vgap, 0);
- primitive_luatex("Umathradicalkern", set_math_param_cmd, math_param_radical_kern, 0);
- primitive_luatex("Umathradicalrule", set_math_param_cmd, math_param_radical_rule, 0);
- primitive_luatex("Umathradicalvgap", set_math_param_cmd, math_param_radical_vgap, 0);
- primitive_luatex("Umathradicaldegreebefore", set_math_param_cmd, math_param_radical_degree_before, 0);
- primitive_luatex("Umathradicaldegreeafter", set_math_param_cmd, math_param_radical_degree_after, 0);
- primitive_luatex("Umathradicaldegreeraise", set_math_param_cmd, math_param_radical_degree_raise, 0);
- primitive_luatex("Umathstackvgap", set_math_param_cmd, math_param_stack_vgap, 0);
- primitive_luatex("Umathstacknumup", set_math_param_cmd, math_param_stack_num_up, 0);
- primitive_luatex("Umathstackdenomdown", set_math_param_cmd, math_param_stack_denom_down, 0);
- primitive_luatex("Umathfractionrule", set_math_param_cmd, math_param_fraction_rule, 0);
- primitive_luatex("Umathfractionnumvgap", set_math_param_cmd, math_param_fraction_num_vgap, 0);
- primitive_luatex("Umathfractionnumup", set_math_param_cmd, math_param_fraction_num_up, 0);
- primitive_luatex("Umathfractiondenomvgap", set_math_param_cmd, math_param_fraction_denom_vgap, 0);
- primitive_luatex("Umathfractiondenomdown", set_math_param_cmd, math_param_fraction_denom_down, 0);
- primitive_luatex("Umathfractiondelsize", set_math_param_cmd, math_param_fraction_del_size, 0);
- primitive_luatex("Umathskewedfractionvgap", set_math_param_cmd, math_param_skewed_fraction_vgap, 0);
- primitive_luatex("Umathskewedfractionhgap", set_math_param_cmd, math_param_skewed_fraction_hgap, 0);
- primitive_luatex("Umathlimitabovevgap", set_math_param_cmd, math_param_limit_above_vgap, 0);
- primitive_luatex("Umathlimitabovebgap", set_math_param_cmd, math_param_limit_above_bgap, 0);
- primitive_luatex("Umathlimitabovekern", set_math_param_cmd, math_param_limit_above_kern, 0);
- primitive_luatex("Umathlimitbelowvgap", set_math_param_cmd, math_param_limit_below_vgap, 0);
- primitive_luatex("Umathlimitbelowbgap", set_math_param_cmd, math_param_limit_below_bgap, 0);
- primitive_luatex("Umathlimitbelowkern", set_math_param_cmd, math_param_limit_below_kern, 0);
- primitive_luatex("Umathnolimitsubfactor", set_math_param_cmd, math_param_nolimit_sub_factor, 0); /* bonus */
- primitive_luatex("Umathnolimitsupfactor", set_math_param_cmd, math_param_nolimit_sup_factor, 0); /* bonus */
- primitive_luatex("Umathunderdelimitervgap", set_math_param_cmd, math_param_under_delimiter_vgap, 0);
- primitive_luatex("Umathunderdelimiterbgap", set_math_param_cmd, math_param_under_delimiter_bgap, 0);
- primitive_luatex("Umathoverdelimitervgap", set_math_param_cmd, math_param_over_delimiter_vgap, 0);
- primitive_luatex("Umathoverdelimiterbgap", set_math_param_cmd, math_param_over_delimiter_bgap, 0);
- primitive_luatex("Umathsubshiftdrop", set_math_param_cmd, math_param_sub_shift_drop, 0);
- primitive_luatex("Umathsupshiftdrop", set_math_param_cmd, math_param_sup_shift_drop, 0);
- primitive_luatex("Umathsubshiftdown", set_math_param_cmd, math_param_sub_shift_down, 0);
- primitive_luatex("Umathsubsupshiftdown", set_math_param_cmd, math_param_sub_sup_shift_down, 0);
- primitive_luatex("Umathsubtopmax", set_math_param_cmd, math_param_sub_top_max, 0);
- primitive_luatex("Umathsupshiftup", set_math_param_cmd, math_param_sup_shift_up, 0);
- primitive_luatex("Umathsupbottommin", set_math_param_cmd, math_param_sup_bottom_min, 0);
- primitive_luatex("Umathsupsubbottommax", set_math_param_cmd, math_param_sup_sub_bottom_max, 0);
- primitive_luatex("Umathsubsupvgap", set_math_param_cmd, math_param_subsup_vgap, 0);
- primitive_luatex("Umathspaceafterscript", set_math_param_cmd, math_param_space_after_script, 0);
- primitive_luatex("Umathconnectoroverlapmin", set_math_param_cmd, math_param_connector_overlap_min, 0);
- primitive_luatex("Umathordordspacing", set_math_param_cmd, math_param_ord_ord_spacing, 0);
- primitive_luatex("Umathordopspacing", set_math_param_cmd, math_param_ord_op_spacing, 0);
- primitive_luatex("Umathordbinspacing", set_math_param_cmd, math_param_ord_bin_spacing, 0);
- primitive_luatex("Umathordrelspacing", set_math_param_cmd, math_param_ord_rel_spacing, 0);
- primitive_luatex("Umathordopenspacing", set_math_param_cmd, math_param_ord_open_spacing, 0);
- primitive_luatex("Umathordclosespacing", set_math_param_cmd, math_param_ord_close_spacing, 0);
- primitive_luatex("Umathordpunctspacing", set_math_param_cmd, math_param_ord_punct_spacing, 0);
- primitive_luatex("Umathordinnerspacing", set_math_param_cmd, math_param_ord_inner_spacing, 0);
- primitive_luatex("Umathopordspacing", set_math_param_cmd, math_param_op_ord_spacing, 0);
- primitive_luatex("Umathopopspacing", set_math_param_cmd, math_param_op_op_spacing, 0);
- primitive_luatex("Umathopbinspacing", set_math_param_cmd, math_param_op_bin_spacing, 0);
- primitive_luatex("Umathoprelspacing", set_math_param_cmd, math_param_op_rel_spacing, 0);
- primitive_luatex("Umathopopenspacing", set_math_param_cmd, math_param_op_open_spacing, 0);
- primitive_luatex("Umathopclosespacing", set_math_param_cmd, math_param_op_close_spacing, 0);
- primitive_luatex("Umathoppunctspacing", set_math_param_cmd, math_param_op_punct_spacing, 0);
- primitive_luatex("Umathopinnerspacing", set_math_param_cmd, math_param_op_inner_spacing, 0);
- primitive_luatex("Umathbinordspacing", set_math_param_cmd, math_param_bin_ord_spacing, 0);
- primitive_luatex("Umathbinopspacing", set_math_param_cmd, math_param_bin_op_spacing, 0);
- primitive_luatex("Umathbinbinspacing", set_math_param_cmd, math_param_bin_bin_spacing, 0);
- primitive_luatex("Umathbinrelspacing", set_math_param_cmd, math_param_bin_rel_spacing, 0);
- primitive_luatex("Umathbinopenspacing", set_math_param_cmd, math_param_bin_open_spacing, 0);
- primitive_luatex("Umathbinclosespacing", set_math_param_cmd, math_param_bin_close_spacing, 0);
- primitive_luatex("Umathbinpunctspacing", set_math_param_cmd, math_param_bin_punct_spacing, 0);
- primitive_luatex("Umathbininnerspacing", set_math_param_cmd, math_param_bin_inner_spacing, 0);
- primitive_luatex("Umathrelordspacing", set_math_param_cmd, math_param_rel_ord_spacing, 0);
- primitive_luatex("Umathrelopspacing", set_math_param_cmd, math_param_rel_op_spacing, 0);
- primitive_luatex("Umathrelbinspacing", set_math_param_cmd, math_param_rel_bin_spacing, 0);
- primitive_luatex("Umathrelrelspacing", set_math_param_cmd, math_param_rel_rel_spacing, 0);
- primitive_luatex("Umathrelopenspacing", set_math_param_cmd, math_param_rel_open_spacing, 0);
- primitive_luatex("Umathrelclosespacing", set_math_param_cmd, math_param_rel_close_spacing, 0);
- primitive_luatex("Umathrelpunctspacing", set_math_param_cmd, math_param_rel_punct_spacing, 0);
- primitive_luatex("Umathrelinnerspacing", set_math_param_cmd, math_param_rel_inner_spacing, 0);
- primitive_luatex("Umathopenordspacing", set_math_param_cmd, math_param_open_ord_spacing, 0);
- primitive_luatex("Umathopenopspacing", set_math_param_cmd, math_param_open_op_spacing, 0);
- primitive_luatex("Umathopenbinspacing", set_math_param_cmd, math_param_open_bin_spacing, 0);
- primitive_luatex("Umathopenrelspacing", set_math_param_cmd, math_param_open_rel_spacing, 0);
- primitive_luatex("Umathopenopenspacing", set_math_param_cmd, math_param_open_open_spacing, 0);
- primitive_luatex("Umathopenclosespacing", set_math_param_cmd, math_param_open_close_spacing, 0);
- primitive_luatex("Umathopenpunctspacing", set_math_param_cmd, math_param_open_punct_spacing, 0);
- primitive_luatex("Umathopeninnerspacing", set_math_param_cmd, math_param_open_inner_spacing, 0);
- primitive_luatex("Umathcloseordspacing", set_math_param_cmd, math_param_close_ord_spacing, 0);
- primitive_luatex("Umathcloseopspacing", set_math_param_cmd, math_param_close_op_spacing, 0);
- primitive_luatex("Umathclosebinspacing", set_math_param_cmd, math_param_close_bin_spacing, 0);
- primitive_luatex("Umathcloserelspacing", set_math_param_cmd, math_param_close_rel_spacing, 0);
- primitive_luatex("Umathcloseopenspacing", set_math_param_cmd, math_param_close_open_spacing, 0);
- primitive_luatex("Umathcloseclosespacing", set_math_param_cmd, math_param_close_close_spacing, 0);
- primitive_luatex("Umathclosepunctspacing", set_math_param_cmd, math_param_close_punct_spacing, 0);
- primitive_luatex("Umathcloseinnerspacing", set_math_param_cmd, math_param_close_inner_spacing, 0);
- primitive_luatex("Umathpunctordspacing", set_math_param_cmd, math_param_punct_ord_spacing, 0);
- primitive_luatex("Umathpunctopspacing", set_math_param_cmd, math_param_punct_op_spacing, 0);
- primitive_luatex("Umathpunctbinspacing", set_math_param_cmd, math_param_punct_bin_spacing, 0);
- primitive_luatex("Umathpunctrelspacing", set_math_param_cmd, math_param_punct_rel_spacing, 0);
- primitive_luatex("Umathpunctopenspacing", set_math_param_cmd, math_param_punct_open_spacing, 0);
- primitive_luatex("Umathpunctclosespacing", set_math_param_cmd, math_param_punct_close_spacing, 0);
- primitive_luatex("Umathpunctpunctspacing", set_math_param_cmd, math_param_punct_punct_spacing, 0);
- primitive_luatex("Umathpunctinnerspacing", set_math_param_cmd, math_param_punct_inner_spacing, 0);
- primitive_luatex("Umathinnerordspacing", set_math_param_cmd, math_param_inner_ord_spacing, 0);
- primitive_luatex("Umathinneropspacing", set_math_param_cmd, math_param_inner_op_spacing, 0);
- primitive_luatex("Umathinnerbinspacing", set_math_param_cmd, math_param_inner_bin_spacing, 0);
- primitive_luatex("Umathinnerrelspacing", set_math_param_cmd, math_param_inner_rel_spacing, 0);
- primitive_luatex("Umathinneropenspacing", set_math_param_cmd, math_param_inner_open_spacing, 0);
- primitive_luatex("Umathinnerclosespacing", set_math_param_cmd, math_param_inner_close_spacing, 0);
- primitive_luatex("Umathinnerpunctspacing", set_math_param_cmd, math_param_inner_punct_spacing, 0);
- primitive_luatex("Umathinnerinnerspacing", set_math_param_cmd, math_param_inner_inner_spacing, 0);
-
- primitive_luatex("Umathcode", extdef_math_code_cmd, math_code_base, math_code_base);
- primitive_luatex("Udelcode", extdef_del_code_cmd, del_code_base, del_code_base);
- primitive_luatex("Umathcodenum", extdef_math_code_cmd, math_code_base + 1, math_code_base);
- primitive_luatex("Udelcodenum", extdef_del_code_cmd, del_code_base + 1, del_code_base);
- primitive_tex("hyphenation", hyph_data_cmd, 0, 0);
- primitive_tex("patterns", hyph_data_cmd, 1, 0);
- primitive_luatex("prehyphenchar", hyph_data_cmd, 2, 0);
- primitive_luatex("posthyphenchar", hyph_data_cmd, 3, 0);
- primitive_luatex("preexhyphenchar", hyph_data_cmd, 4, 0);
- primitive_luatex("postexhyphenchar", hyph_data_cmd, 5, 0);
- primitive_luatex("hyphenationmin", hyph_data_cmd, 6, 0);
- primitive_luatex("hjcode", hyph_data_cmd, 7, 0);
- primitive_tex("hyphenchar", assign_font_int_cmd, 0, 0);
- primitive_tex("skewchar", assign_font_int_cmd, 1, 0);
- primitive_luatex("lpcode", assign_font_int_cmd, lp_code_base, 0);
- primitive_luatex("rpcode", assign_font_int_cmd, rp_code_base, 0);
- primitive_luatex("efcode", assign_font_int_cmd, ef_code_base, 0);
- primitive_luatex("tagcode", assign_font_int_cmd, tag_code, 0);
- primitive_luatex("ignoreligaturesinfont", assign_font_int_cmd, no_lig_code, 0);
- primitive_tex("batchmode", set_interaction_cmd, batch_mode, 0);
- primitive_tex("nonstopmode", set_interaction_cmd, nonstop_mode, 0);
- primitive_tex("scrollmode", set_interaction_cmd, scroll_mode, 0);
- primitive_tex("errorstopmode", set_interaction_cmd, error_stop_mode, 0);
- primitive_tex("openin", in_stream_cmd, 1, 0);
- primitive_tex("closein", in_stream_cmd, 0, 0);
- primitive_tex("message", message_cmd, 0, 0);
- primitive_tex("errmessage", message_cmd, 1, 0);
- primitive_tex("lowercase", case_shift_cmd, lc_code_base, lc_code_base);
- primitive_tex("uppercase", case_shift_cmd, uc_code_base, lc_code_base);
- primitive_tex("show", xray_cmd, show_code, 0);
- primitive_tex("showbox", xray_cmd, show_box_code, 0);
- primitive_tex("showthe", xray_cmd, show_the_code, 0);
- primitive_tex("showlists", xray_cmd, show_lists, 0);
-
- primitive_tex("openout", extension_cmd, open_code, 0);
- primitive_tex("write", extension_cmd, write_code, 0);
- write_loc = cur_val;
- primitive_tex("closeout", extension_cmd, close_code, 0);
- primitive_luatex("endlocalcontrol", extension_cmd, end_local_code, 0);
- primitive_tex("special", extension_cmd, special_code, 0);
- cs_text(frozen_special) = maketexstring("special");
- eqtb[frozen_special] = eqtb[cur_val];
- primitive_tex("immediate", extension_cmd, immediate_code, 0);
- primitive_luatex("localinterlinepenalty", assign_int_cmd, int_base + local_inter_line_penalty_code, int_base);
- primitive_luatex("localbrokenpenalty", assign_int_cmd, int_base + local_broken_penalty_code, int_base);
- primitive_luatex("pagedir", assign_dir_cmd, int_base + page_direction_code, dir_base);
- primitive_luatex("bodydir", assign_dir_cmd, int_base + body_direction_code, dir_base);
- primitive_luatex("pardir", assign_dir_cmd, int_base + par_direction_code, dir_base);
- primitive_luatex("textdir", assign_dir_cmd, int_base + text_direction_code, dir_base);
- primitive_luatex("mathdir", assign_dir_cmd, int_base + math_direction_code, dir_base);
- primitive_luatex("linedir", assign_dir_cmd, int_base + line_direction_code, dir_base);
- primitive_luatex("pageleftoffset", assign_dimen_cmd, dimen_base + page_left_offset_code, dimen_base);
- primitive_luatex("pagetopoffset", assign_dimen_cmd, dimen_base + page_top_offset_code, dimen_base);
- primitive_luatex("pagerightoffset", assign_dimen_cmd, dimen_base + page_right_offset_code, dimen_base);
- primitive_luatex("pagebottomoffset", assign_dimen_cmd, dimen_base + page_bottom_offset_code, dimen_base);
- primitive_luatex("saveboxresource", extension_cmd, save_box_resource_code, 0);
- primitive_luatex("useboxresource", extension_cmd, use_box_resource_code, 0);
- primitive_luatex("saveimageresource", extension_cmd, save_image_resource_code, 0);
- primitive_luatex("useimageresource", extension_cmd, use_image_resource_code, 0);
- primitive_luatex("savepos", normal_cmd, save_pos_code, 0);
- primitive_luatex("savecatcodetable", normal_cmd, save_cat_code_table_code, 0);
- primitive_luatex("initcatcodetable", normal_cmd, init_cat_code_table_code, 0);
- primitive_luatex("setrandomseed", normal_cmd, set_random_seed_code, 0);
- primitive_luatex("latelua", normal_cmd, late_lua_code, 0);
- primitive_luatex("lateluafunction", normal_cmd, late_lua_call_code, 0);
- primitive_luatex("insertht", convert_cmd, insert_ht_code, 0);
- primitive_luatex("dviextension", extension_cmd, dvi_extension_code, 0);
- primitive_luatex("dvifeedback", feedback_cmd, dvi_feedback_code, 0);
- primitive_luatex("dvivariable", variable_cmd, dvi_variable_code, 0);
- primitive_luatex("pdfextension", extension_cmd, pdf_extension_code, 0);
- primitive_luatex("pdffeedback", feedback_cmd, pdf_feedback_code, 0);
- primitive_luatex("pdfvariable", variable_cmd, pdf_variable_code, 0);
- primitive_luatex("mathoption", option_cmd, math_option_code, 0);
-
- primitive_luatex("luacopyinputnodes", assign_int_cmd, int_base + copy_lua_input_nodes_code, int_base);
-
- primitive_luatex("pagedirection", assign_direction_cmd, int_base + page_direction_code, dir_base);
- primitive_luatex("bodydirection", assign_direction_cmd, int_base + body_direction_code, dir_base);
- primitive_luatex("pardirection", assign_direction_cmd, int_base + par_direction_code, dir_base);
- primitive_luatex("textdirection", assign_direction_cmd, int_base + text_direction_code, dir_base);
- primitive_luatex("mathdirection", assign_direction_cmd, int_base + math_direction_code, dir_base);
- primitive_luatex("linedirection", assign_direction_cmd, int_base + line_direction_code, dir_base);
-
- /*
- some of the internal integer parameters are not associated with actual
- primitives at all.
- */
-
- primitive_no("nolocalwhatsits", assign_int_cmd, int_base + no_local_whatsits_code, int_base);
- primitive_no("nolocaldirs", assign_int_cmd, int_base + no_local_dirs_code, int_base);
-
-}
-
-void initialize_etex_commands(void)
-{
- primitive_etex("lastnodetype", last_item_cmd, last_node_type_code, 0);
- primitive_etex("eTeXversion", last_item_cmd, eTeX_version_code, 0);
- primitive_etex("eTeXminorversion", last_item_cmd, eTeX_minor_version_code, 0);
- primitive_etex("eTeXrevision", convert_cmd, eTeX_revision_code, 0);
-
- /*tex
-
- First we implement the additional \eTeX\ parameters in the table of
- equivalents.
- */
-
- primitive_etex("everyeof", assign_toks_cmd, every_eof_loc, local_base);
- primitive_etex("tracingassigns", assign_int_cmd, int_base + tracing_assigns_code, int_base);
- primitive_etex("tracinggroups", assign_int_cmd, int_base + tracing_groups_code, int_base);
- primitive_etex("tracingifs", assign_int_cmd, int_base + tracing_ifs_code, int_base);
- primitive_etex("tracingscantokens", assign_int_cmd, int_base + tracing_scan_tokens_code, int_base);
- primitive_etex("tracingnesting", assign_int_cmd, int_base + tracing_nesting_code, int_base);
- primitive_etex("predisplaydirection", assign_int_cmd, int_base + pre_display_direction_code, int_base);
- primitive_etex("lastlinefit", assign_int_cmd, int_base + last_line_fit_code, int_base);
- primitive_etex("savingvdiscards", assign_int_cmd, int_base + saving_vdiscards_code, int_base);
- primitive_etex("savinghyphcodes", assign_int_cmd, int_base + saving_hyph_codes_code, int_base);
- primitive_luatex("suppressfontnotfounderror", assign_int_cmd, int_base + suppress_fontnotfound_error_code, int_base);
- primitive_luatex("suppresslongerror", assign_int_cmd, int_base + suppress_long_error_code, int_base);
- primitive_luatex("suppressprimitiveerror", assign_int_cmd, int_base + suppress_primitive_error_code, int_base);
- primitive_luatex("suppressmathparerror", assign_int_cmd, int_base + suppress_mathpar_error_code, int_base);
- primitive_luatex("suppressifcsnameerror", assign_int_cmd, int_base + suppress_ifcsname_error_code, int_base);
- primitive_luatex("suppressoutererror", assign_int_cmd, int_base + suppress_outer_error_code, int_base);
- primitive_luatex("matheqnogapstep", assign_int_cmd, int_base + math_eqno_gap_step_code, int_base);
- primitive_luatex("mathdisplayskipmode", assign_int_cmd, int_base + math_display_skip_mode_code, int_base);
- primitive_luatex("mathscriptsmode", assign_int_cmd, int_base + math_scripts_mode_code, int_base);
- primitive_luatex("mathnolimitsmode", assign_int_cmd, int_base + math_nolimits_mode_code, int_base);
- primitive_luatex("mathitalicsmode", assign_int_cmd, int_base + math_italics_mode_code, int_base);
- primitive_luatex("mathrulesmode", assign_int_cmd, int_base + math_rules_mode_code, int_base);
- primitive_luatex("mathrulesfam", assign_int_cmd, int_base + math_rules_fam_code, int_base);
- primitive_luatex("synctex", assign_int_cmd, int_base + synctex_code, int_base);
-
- primitive_etex("currentgrouplevel", last_item_cmd, current_group_level_code, 0);
- primitive_etex("currentgrouptype", last_item_cmd, current_group_type_code, 0);
-
- primitive_etex("currentiflevel", last_item_cmd, current_if_level_code, 0);
- primitive_etex("currentiftype", last_item_cmd, current_if_type_code, 0);
- primitive_etex("currentifbranch", last_item_cmd, current_if_branch_code, 0);
- primitive_etex("fontcharwd", last_item_cmd, font_char_wd_code, 0);
- primitive_etex("fontcharht", last_item_cmd, font_char_ht_code, 0);
- primitive_etex("fontchardp", last_item_cmd, font_char_dp_code, 0);
- primitive_etex("fontcharic", last_item_cmd, font_char_ic_code, 0);
-
- primitive_etex("parshapelength", last_item_cmd, par_shape_length_code, 0);
- primitive_etex("parshapeindent", last_item_cmd, par_shape_indent_code, 0);
- primitive_etex("parshapedimen", last_item_cmd, par_shape_dimen_code, 0);
-
- primitive_luatex("shapemode", assign_int_cmd, int_base + shape_mode_code, int_base);
- primitive_luatex("hyphenationbounds", assign_int_cmd, int_base + hyphenation_bounds_code, int_base);
-
- primitive_etex("showgroups", xray_cmd, show_groups, 0);
-
- /*tex
-
- The \.{\\showtokens} command displays a token list.
-
- */
-
- primitive_etex("showtokens", xray_cmd, show_tokens, 0);
-
- /*tex
-
- The \.{\\unexpanded} primitive prevents expansion of tokens much as the
- result from \.{\\the} applied to a token variable. The \.{\\detokenize}
- primitive converts a token list into a list of character tokens much as
- if the token list were written to a file. We use the fact that the
- command modifiers for \.{\\unexpanded} and \.{\\detokenize} are odd
- whereas those for \.{\\the} and \.{\\showthe} are even.
-
- */
-
- primitive_etex("unexpanded", the_cmd, 1, 0);
- primitive_etex("detokenize", the_cmd, show_tokens, 0);
-
- /*tex
-
- The \.{\\showifs} command displays all currently active conditionals.
-
- */
-
- primitive_etex("showifs", xray_cmd, show_ifs, 0);
-
- /*tex
-
- The \.{\\interactionmode} primitive allows to query and set the interaction mode.
-
- */
-
- primitive_etex("interactionmode", set_page_int_cmd, 2, 0);
-
- /*tex
-
- The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens} primitive.
-
- */
-
- primitive_etex("scantokens", input_cmd, 2, 0);
- primitive_luatex("scantextokens", input_cmd, 3, 0);
-
- primitive_etex("readline", read_to_cs_cmd, 1, 0);
-
- primitive_etex("unless", expand_after_cmd, 1, 0);
- primitive_etex("ifdefined", if_test_cmd, if_def_code, 0);
- primitive_etex("ifcsname", if_test_cmd, if_cs_code, 0);
- primitive_etex("iffontchar", if_test_cmd, if_font_char_code, 0);
- primitive_luatex("ifincsname", if_test_cmd, if_in_csname_code, 0);
- primitive_luatex("ifabsnum", if_test_cmd, if_abs_num_code, 0);
- primitive_luatex("ifabsdim", if_test_cmd, if_abs_dim_code, 0);
-
- /*tex
-
- The |protected| feature of \eTeX\ defines the \.{\\protected} prefix
- command for macro definitions. Such macros are protected against
- expansions when lists of expanded tokens are built, e.g., for \.{\\edef}
- or during \.{\\write}.
- */
-
- primitive_etex("protected", prefix_cmd, 8, 0);
-
- /*tex
-
- Here are the additional \eTeX\ primitives for expressions.
-
- */
-
- primitive_etex("numexpr", last_item_cmd, eTeX_expr - int_val_level + int_val_level, 0);
- primitive_etex("dimexpr", last_item_cmd, eTeX_expr - int_val_level + dimen_val_level, 0);
- primitive_etex("glueexpr", last_item_cmd, eTeX_expr - int_val_level + glue_val_level, 0);
- primitive_etex("muexpr", last_item_cmd, eTeX_expr - int_val_level + mu_val_level, 0);
-
- primitive_etex("gluestretchorder", last_item_cmd, glue_stretch_order_code, 0);
- primitive_etex("glueshrinkorder", last_item_cmd, glue_shrink_order_code, 0);
- primitive_etex("gluestretch", last_item_cmd, glue_stretch_code, 0);
- primitive_etex("glueshrink", last_item_cmd, glue_shrink_code, 0);
-
- primitive_luatex("eTeXgluestretchorder", last_item_cmd, eTeX_glue_stretch_order_code, 0);
- primitive_luatex("eTeXglueshrinkorder", last_item_cmd, eTeX_glue_shrink_order_code, 0);
-
- primitive_etex("mutoglue", last_item_cmd, mu_to_glue_code, 0);
- primitive_etex("gluetomu", last_item_cmd, glue_to_mu_code, 0);
-
- /*tex
-
- The \.{\\pagediscards} and \.{\\splitdiscards} commands share the command
- code |un_vbox| with \.{\\unvbox} and \.{\\unvcopy}, they are
- distinguished by their |chr_code| values |last_box_code| and
- |vsplit_code|. These |chr_code| values are larger than |box_code| and
- |copy_code|.
-
- */
-
- primitive_etex("pagediscards", un_vbox_cmd, last_box_code, 0);
- primitive_etex("splitdiscards", un_vbox_cmd, vsplit_code, 0);
-
- /*tex
-
- The \.{\\interlinepenalties}, \.{\\clubpenalties}, \.{\\widowpenalties},
- and \.{\\displaywidowpenalties} commands allow to define arrays of
- penalty values to be used instead of the corresponding single values.
-
- */
-
- primitive_etex("interlinepenalties", set_etex_shape_cmd, inter_line_penalties_loc, etex_pen_base);
- primitive_etex("clubpenalties", set_etex_shape_cmd, club_penalties_loc, etex_pen_base);
- primitive_etex("widowpenalties", set_etex_shape_cmd, widow_penalties_loc, etex_pen_base);
- primitive_etex("displaywidowpenalties", set_etex_shape_cmd, display_widow_penalties_loc, etex_pen_base);
-
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.h b/Build/source/texk/web2c/luatexdir/tex/commands.h
deleted file mode 100644
index 7d7a7056564..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/commands.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/* commands.h
-
- Copyright 2008 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef COMMANDS_H
-# define COMMANDS_H
-
-/*
-Before we can go any further, we need to define symbolic names for the internal
-code numbers that represent the various commands obeyed by \TeX. These codes
-are somewhat arbitrary, but not completely so. For example, the command
-codes for character types are fixed by the language, since a user says,
-e.g., `\.{\\catcode \`\\\${} = 3}' to make \.{\char'44} a math delimiter,
-and the command code |math_shift| is equal to~3. Some other codes have
-been made adjacent so that |case| statements in the program need not consider
-cases that are widely spaced, or so that |case| statements can be replaced
-by |if| statements.
-
-At any rate, here is the list, for future reference. First come the
-``catcode'' commands, several of which share their numeric codes with
-ordinary commands when the catcode cannot emerge from \TeX's scanning routine.
-
-@ Next are the ordinary run-of-the-mill command codes. Codes that are
-|min_internal| or more represent internal quantities that might be
-expanded by `\.{\\the}'.
-
-
-@ The next codes are special; they all relate to mode-independent
-assignment of values to \TeX's internal registers or tables.
-Codes that are |max_internal| or less represent internal quantities
-that might be expanded by `\.{\\the}'.
-
-There is no matching primitive to go with |assign_attr|, but even if
-there was no \.{\\attributedef}, a reserved number would still be
-needed because there is an implied correspondence between the
-|assign_xxx| commands and |xxx_val| expression values. That would
-break down otherwise.
-
-@ The remaining command codes are extra special, since they cannot get through
-\TeX's scanner to the main control routine. They have been given values higher
-than |max_command| so that their special nature is easily discernible.
-The ``expandable'' commands come first.
-
-
-*/
-
-typedef enum {
- relax_cmd = 0, /* do nothing ( \.{\\relax} ) */
-# define escape_cmd relax_cmd /* escape delimiter (called \.\\ in {\sl The \TeX book\/}) */
- left_brace_cmd, /* beginning of a group ( \.\{ ) */
- right_brace_cmd, /* ending of a group ( \.\} ) */
- math_shift_cmd, /* mathematics shift character ( \.\$ ) */
- tab_mark_cmd, /* alignment delimiter ( \.\&, \.{\\span} ) */
- car_ret_cmd, /* end of line ( |carriage_return|, \.{\\cr}, \.{\\crcr} ) */
-# define out_param_cmd car_ret_cmd /* output a macro parameter */
- mac_param_cmd, /* macro parameter symbol ( \.\# ) */
- sup_mark_cmd, /* superscript ( \.{\char'136} ) */
- sub_mark_cmd, /* subscript ( \.{\char'137} ) */
- endv_cmd, /* end of \<v_j> list in alignment template */
-# define ignore_cmd endv_cmd /* characters to ignore ( \.{\^\^@@} ) */
- spacer_cmd, /* characters equivalent to blank space ( \.{\ } ) */
- letter_cmd, /* characters regarded as letters ( \.{A..Z}, \.{a..z} ) */
- other_char_cmd, /* none of the special character types */
- par_end_cmd, /* end of paragraph ( \.{\\par} ) */
-# define active_char_cmd par_end_cmd /* characters that invoke macros ( \.{\char`\~} ) */
-# define match_cmd par_end_cmd /* match a macro parameter */
- stop_cmd, /* end of job ( \.{\\end}, \.{\\dump} ) */
-# define comment_cmd stop_cmd /* characters that introduce comments ( \.\% ) */
-# define end_match_cmd stop_cmd /* end of parameters to macro */
- delim_num_cmd, /* specify delimiter numerically ( \.{\\delimiter} ) */
-# define invalid_char_cmd delim_num_cmd /* characters that shouldn't appear ( \.{\^\^?} ) */
-# define max_char_code_cmd delim_num_cmd /* largest catcode for individual characters */
- char_num_cmd, /* character specified numerically ( \.{\\char} ) */
- math_char_num_cmd, /* explicit math code ( \.{\\mathchar} ) */
- mark_cmd, /* mark definition ( \.{\\mark} ) */
- node_cmd,
- xray_cmd, /* peek inside of \TeX\ ( \.{\\show}, \.{\\showbox}, etc.~) */
- make_box_cmd, /* make a box ( \.{\\box}, \.{\\copy}, \.{\\hbox}, etc.~) */
- hmove_cmd, /* horizontal motion ( \.{\\moveleft}, \.{\\moveright} ) */
- vmove_cmd, /* vertical motion ( \.{\\raise}, \.{\\lower} ) */
- un_hbox_cmd, /* unglue a box ( \.{\\unhbox}, \.{\\unhcopy} ) */
- un_vbox_cmd, /* unglue a box ( \.{\\unvbox}, \.{\\unvcopy} or \.{\\pagediscards}, \.{\\splitdiscards} ) */
- remove_item_cmd, /* nullify last item ( \.{\\unpenalty}, \.{\\unkern}, \.{\\unskip} ) */
- hskip_cmd, /* horizontal glue ( \.{\\hskip}, \.{\\hfil}, etc.~) */
- vskip_cmd, /* vertical glue ( \.{\\vskip}, \.{\\vfil}, etc.~) */
- mskip_cmd, /* math glue ( \.{\\mskip} ) */
- kern_cmd, /* fixed space ( \.{\\kern}) */
- mkern_cmd, /* math kern ( \.{\\mkern} ) */
- leader_ship_cmd, /* use a box ( \.{\\shipout}, \.{\\leaders}, etc.~) */
- halign_cmd, /* horizontal table alignment ( \.{\\halign} ) */
- valign_cmd, /* vertical table alignment ( \.{\\valign} ) */
- no_align_cmd, /* temporary escape from alignment ( \.{\\noalign} ) */
- vrule_cmd, /* vertical rule ( \.{\\vrule} ) */
- hrule_cmd, /* horizontal rule ( \.{\\hrule} ) */
- no_vrule_cmd, /* no rule, just reserve space ( \.{\\novrule} )*/
- no_hrule_cmd, /* no rule, just reserve space ( \.{\\nohrule} )*/
- insert_cmd, /* vlist inserted in box ( \.{\\insert} ) */
- vadjust_cmd, /* vlist inserted in enclosing paragraph ( \.{\\vadjust} ) */
- ignore_spaces_cmd, /* gobble |spacer| tokens ( \.{\\ignorespaces} ) */
- after_assignment_cmd, /* save till assignment is done ( \.{\\afterassignment} ) */
- after_group_cmd, /* save till group is done ( \.{\\aftergroup} ) */
- break_penalty_cmd, /* additional badness ( \.{\\penalty} ) */
- start_par_cmd, /* begin paragraph ( \.{\\indent}, \.{\\noindent} ) */
- ital_corr_cmd, /* italic correction ( \.{\\/} ) */
- accent_cmd, /* attach accent in text ( \.{\\accent} ) */
- math_accent_cmd, /* attach accent in math ( \.{\\mathaccent} ) */
- discretionary_cmd, /* discretionary texts ( \.{\\-}, \.{\\discretionary} ) */
- eq_no_cmd, /* equation number ( \.{\\eqno}, \.{\\leqno} ) */
- left_right_cmd, /* variable delimiter ( \.{\\left}, \.{\\right} or \.{\\middle} ) */
- math_comp_cmd, /* component of formula ( \.{\\mathbin}, etc.~) */
- limit_switch_cmd, /* diddle limit conventions ( \.{\\displaylimits}, etc.~) */
- above_cmd, /* generalized fraction ( \.{\\above}, \.{\\atop}, etc.~) */
- math_style_cmd, /* style specification ( \.{\\displaystyle}, etc.~) */
- math_choice_cmd, /* choice specification ( \.{\\mathchoice} ) */
- non_script_cmd, /* conditional math glue ( \.{\\nonscript} ) */
- vcenter_cmd, /* vertically center a vbox ( \.{\\vcenter} ) */
- case_shift_cmd, /* force specific case ( \.{\\lowercase}, \.{\\uppercase}~) */
- message_cmd, /* send to user ( \.{\\message}, \.{\\errmessage} ) */
- normal_cmd, /* general extensions to \TeX\ that don't fit into a category */
- extension_cmd, /* extensions to \TeX\ ( \.{\\write}, \.{\\special}, etc.~) */
- option_cmd,
- lua_function_call_cmd,
- lua_bytecode_call_cmd,
- lua_call_cmd,
- in_stream_cmd, /* files for reading ( \.{\\openin}, \.{\\closein} ) */
- begin_group_cmd, /* begin local grouping ( \.{\\begingroup} ) */
- end_group_cmd, /* end local grouping ( \.{\\endgroup} ) */
- omit_cmd, /* omit alignment template ( \.{\\omit} ) */
- ex_space_cmd, /* explicit space ( \.{\\\ } ) */
- boundary_cmd, /* insert boundry node with value ( \.{\\*boundary} ) */
- radical_cmd, /* square root and similar signs ( \.{\\radical} ) */
- super_sub_script_cmd, /* explicit super- or subscript */
- no_super_sub_script_cmd, /* explicit no super- or subscript */
- math_shift_cs_cmd, /* start- and endmath */
- end_cs_name_cmd, /* end control sequence ( \.{\\endcsname} ) */
- char_ghost_cmd, /* \.{\\leftghost}, \.{\\rightghost} character for kerning */
- assign_local_box_cmd, /* box for guillemets \.{\\localleftbox} or \.{\\localrightbox} */
- char_given_cmd, /* character code defined by \.{\\chardef} */
-# define min_internal_cmd char_given_cmd /* the smallest code that can follow \.{\\the} */
- math_given_cmd, /* math code defined by \.{\\mathchardef} */
- xmath_given_cmd, /* math code defined by \.{\\Umathchardef} or \.{\\Umathcharnumdef} */
- last_item_cmd, /* most recent item ( \.{\\lastpenalty}, \.{\\lastkern}, \.{\\lastskip} ) */
-# define max_non_prefixed_command_cmd last_item_cmd /* largest command code that can't be \.{\\global} */
- toks_register_cmd, /* token list register ( \.{\\toks} ) */
- assign_toks_cmd, /* special token list ( \.{\\output}, \.{\\everypar}, etc.~) */
- assign_int_cmd, /* user-defined integer ( \.{\\tolerance}, \.{\\day}, etc.~) */
- assign_attr_cmd, /* user-defined attributes */
- assign_dimen_cmd, /* user-defined length ( \.{\\hsize}, etc.~) */
- assign_glue_cmd, /* user-defined glue ( \.{\\baselineskip}, etc.~) */
- assign_mu_glue_cmd, /* user-defined muglue ( \.{\\thinmuskip}, etc.~) */
- assign_font_dimen_cmd, /* user-defined font dimension ( \.{\\fontdimen} ) */
- assign_font_int_cmd, /* user-defined font integer ( \.{\\hyphenchar}, \.{\\skewchar} ) */
- assign_hang_indent_cmd,
- set_aux_cmd, /* specify state info ( \.{\\spacefactor}, \.{\\prevdepth} ) */
- set_prev_graf_cmd, /* specify state info ( \.{\\prevgraf} ) */
- set_page_dimen_cmd, /* specify state info ( \.{\\pagegoal}, etc.~) */
- set_page_int_cmd, /* specify state info ( \.{\\deadcycles}, \.{\\insertpenalties} ) */
- set_box_dimen_cmd, /* change dimension of box ( \.{\\wd}, \.{\\ht}, \.{\\dp} ) */
- set_tex_shape_cmd, /* specify fancy paragraph shape ( \.{\\parshape} ) */
- set_etex_shape_cmd, /* specify etex extended list ( \.{\\interlinepenalties}, etc.~) */
- def_char_code_cmd, /* define a character code ( \.{\\catcode}, etc.~) */
- def_del_code_cmd, /* define a delimiter code ( \.{\\delcode}) */
- extdef_math_code_cmd, /* define an extended character code ( \.{\\Umathcode}, etc.~) */
- extdef_del_code_cmd, /* define an extended delimiter code ( \.{\\Udelcode}, etc.~) */
- def_family_cmd, /* declare math fonts ( \.{\\textfont}, etc.~) */
- set_math_param_cmd, /* set math parameters ( \.{\\mathquad}, etc.~) */
- set_font_cmd, /* set current font ( font identifiers ) */
- def_font_cmd, /* define a font file ( \.{\\font} ) */
- register_cmd, /* internal register ( \.{\\count}, \.{\\dimen}, etc.~) */
- assign_box_direction_cmd, /* (\.{\\boxdirection}) */
- assign_box_dir_cmd, /* (\.{\\boxdir}) */
- assign_direction_cmd, /* (\.{\\pagedirection}, \.{\\textdirection}) */
- assign_dir_cmd, /* (\.{\\pagedir}, \.{\\textdir}) */
- combine_toks_cmd,
-# define max_internal_cmd assign_dir_cmd /* the largest code that can follow \.{\\the} */
- advance_cmd, /* advance a register or parameter ( \.{\\advance} ) */
- multiply_cmd, /* multiply a register or parameter ( \.{\\multiply} ) */
- divide_cmd, /* divide a register or parameter ( \.{\\divide} ) */
- prefix_cmd, /* qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} ) */
- let_cmd, /* assign a command code ( \.{\\let}, \.{\\futurelet} ) */
- shorthand_def_cmd, /* code definition ( \.{\\chardef}, \.{\\countdef}, etc.~) */
- def_lua_call_cmd,
- read_to_cs_cmd, /* read into a control sequence ( \.{\\read} ) */
- def_cmd, /* macro definition ( \.{\\def}, \.{\\gdef}, \.{\\xdef}, \.{\\edef} ) */
- set_box_cmd, /* set a box ( \.{\\setbox} ) */
- hyph_data_cmd, /* hyphenation data ( \.{\\hyphenation}, \.{\\patterns} ) */
- set_interaction_cmd, /* define level of interaction ( \.{\\batchmode}, etc.~) */
- letterspace_font_cmd, /* letterspace a font ( \.{\\letterspacefont} ) */
- expand_font_cmd, /* expand glyphs ( \.{\\expandglyphsinfont} ) */
- copy_font_cmd, /* create a new font instance ( \.{\\copyfont} ) */
- set_font_id_cmd,
- undefined_cs_cmd, /* initial state of most |eq_type| fields */
- expand_after_cmd, /* special expansion ( \.{\\expandafter} ) */
- no_expand_cmd, /* special nonexpansion ( \.{\\noexpand} ) */
- input_cmd, /* input a source file ( \.{\\input}, \.{\\endinput} or \.{\\scantokens} or \.{\\scantextokens} ) */
- lua_expandable_call_cmd,
- lua_local_call_cmd,
- if_test_cmd, /* conditional text ( \.{\\if}, \.{\\ifcase}, etc.~) */
- fi_or_else_cmd, /* delimiters for conditionals ( \.{\\else}, etc.~) */
- cs_name_cmd, /* make a control sequence from tokens ( \.{\\csname} ) */
- convert_cmd, /* convert to text ( \.{\\number}, \.{\\string}, etc.~) */
- variable_cmd,
- feedback_cmd,
- the_cmd, /* expand an internal quantity ( \.{\\the} or \.{\\unexpanded}, \.{\\detokenize} ) */
- top_bot_mark_cmd, /* inserted mark ( \.{\\topmark}, etc.~) */
- call_cmd, /* non-long, non-outer control sequence */
- long_call_cmd, /* long, non-outer control sequence */
- outer_call_cmd, /* non-long, outer control sequence */
- long_outer_call_cmd, /* long, outer control sequence */
- end_template_cmd, /* end of an alignment template */
- dont_expand_cmd, /* the following token was marked by \.{\\noexpand} */
- glue_ref_cmd, /* the equivalent points to a glue specification */
- shape_ref_cmd, /* the equivalent points to a parshape specification */
- box_ref_cmd, /* the equivalent points to a box node, or is |null| */
- data_cmd, /* the equivalent is simply a halfword number */
-} tex_command_code;
-
-# define max_command_cmd set_font_id_cmd /* the largest command code seen at |big_switch| */
-# define last_cmd data_cmd
-# define max_non_prefixed_command last_item_cmd
-
-typedef enum {
- above_code = 0,
- over_code = 1,
- atop_code = 2,
- skewed_code = 3,
- delimited_code = 4,
-} fraction_codes;
-
-typedef enum {
- number_code = 0, /* command code for \.{\\number} */
- lua_code, /* command code for \.{\\directlua} */
- lua_function_code, /* command code for \.{\\luafunction} */
- lua_bytecode_code, /* command code for \.{\\luabytecode} */
- expanded_code, /* command code for \.{\\expanded} */
- immediate_assignment_code, /* command code for \.{\\immediateassignment} */
- immediate_assigned_code, /* command code for \.{\\assigned} */
- math_style_code, /* command code for \.{\\mathstyle} */
- string_code, /* command code for \.{\\string} */
- cs_string_code, /* command code for \.{\\csstring} */
- roman_numeral_code, /* command code for \.{\\romannumeral} */
- meaning_code, /* command code for \.{\\meaning} */
- uchar_code, /* command code for \.{\\Uchar} */
- lua_escape_string_code, /* command code for \.{\\luaescapestring} */
- font_id_code, /* command code for \.{\\fontid} */
- font_name_code, /* command code for \.{\\fontname} */
- left_margin_kern_code, /* command code for \.{\\leftmarginkern} */
- right_margin_kern_code, /* command code for \.{\\rightmarginkern} */
- uniform_deviate_code, /* command code for \.{\\uniformdeviate} */
- normal_deviate_code, /* command code for \.{\\normaldeviate} */
- math_char_class_code,
- math_char_fam_code,
- math_char_slot_code,
- insert_ht_code, /* command code for \.{\\insertht} */
- job_name_code, /* command code for \.{\\jobname} */
- format_name_code, /* command code for \.{\\AlephVersion} */
- luatex_banner_code, /* command code for \.{\\luatexbanner}: */
- luatex_revision_code, /* command code for \.{\\luatexrevision} */
- etex_code, /* command code for \.{\\eTeXVersion} */
- eTeX_revision_code, /* command code for \.{\\eTeXrevision} */
- font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */
- /* backend */
- dvi_feedback_code,
- pdf_feedback_code,
- dvi_variable_code,
- pdf_variable_code,
-} convert_codes;
-
-typedef enum {
- lastpenalty_code = 0, /* code for \.{\\lastpenalty} */
- lastattr_code, /* not used */
- lastkern_code, /* code for \.{\\lastkern} */
- lastskip_code, /* code for \.{\\lastskip} */
- last_node_type_code, /* code for \.{\\lastnodetype} */
- input_line_no_code, /* code for \.{\\inputlineno} */
- badness_code, /* code for \.{\\badness} */
- last_saved_box_resource_index_code, /* code for \.{\\lastsavedboxresourceindex} */
- last_saved_image_resource_index_code, /* code for \.{\\lastsavedimageresourceindex} */
- last_saved_image_resource_pages_code, /* code for \.{\\lastsavedimageresourcepages} */
- last_x_pos_code, /* code for \.{\\lastxpos} */
- last_y_pos_code, /* code for \.{\\lastypos} */
- random_seed_code, /* code for \.{\\randomseed} */
- luatex_version_code, /* code for \.{\\luatexversion} */
- eTeX_minor_version_code, /* code for \.{\\eTeXminorversion} */
- eTeX_version_code, /* code for \.{\\eTeXversion} */
-# define eTeX_int eTeX_version_code /* first of \eTeX\ codes for integers */
- current_group_level_code, /* code for \.{\\currentgrouplevel} */
- current_group_type_code, /* code for \.{\\currentgrouptype} */
- current_if_level_code, /* code for \.{\\currentiflevel} */
- current_if_type_code, /* code for \.{\\currentiftype} */
- current_if_branch_code, /* code for \.{\\currentifbranch} */
- glue_stretch_order_code, /* code for \.{\\gluestretchorder} */
- glue_shrink_order_code, /* code for \.{\\glueshrinkorder} */
- eTeX_glue_stretch_order_code, /* code for \.{\\eTeXgluestretchorder} */
- eTeX_glue_shrink_order_code, /* code for \.{\\eTeXglueshrinkorder} */
- font_char_wd_code, /* code for \.{\\fontcharwd} */
-# define eTeX_dim font_char_wd_code /* first of \eTeX\ codes for dimensions */
- font_char_ht_code, /* code for \.{\\fontcharht} */
- font_char_dp_code, /* code for \.{\\fontchardp} */
- font_char_ic_code, /* code for \.{\\fontcharic} */
- par_shape_length_code, /* code for \.{\\parshapelength} */
- par_shape_indent_code, /* code for \.{\\parshapeindent} */
- par_shape_dimen_code, /* code for \.{\\parshapedimen} */
- glue_stretch_code, /* code for \.{\\gluestretch} */
- glue_shrink_code, /* code for \.{\\glueshrink} */
- mu_to_glue_code, /* code for \.{\\mutoglue} */
-# define eTeX_glue mu_to_glue_code /* first of \eTeX\ codes for glue */
- glue_to_mu_code, /* code for \.{\\gluetomu} */
-# define eTeX_mu glue_to_mu_code /* first of \eTeX\ codes for muglue */
- numexpr_code, /* code for \.{\\numexpr} */
-# define eTeX_expr numexpr_code /* first of \eTeX\ codes for expressions */
- attrexpr_code, /* not used */
- dimexpr_code, /* code for \.{\\dimexpr} */
- glueexpr_code, /* code for \.{\\glueexpr} */
- muexpr_code, /* code for \.{\\muexpr} */
-} last_item_codes;
-
-
-typedef enum {
- save_cat_code_table_code=0,
- init_cat_code_table_code,
- set_random_seed_code,
- save_pos_code,
- late_lua_code,
- late_lua_call_code,
- expand_font_code,
-} normal_codes;
-
-typedef enum {
- lp_code_base = 2,
- rp_code_base = 3,
- ef_code_base = 4,
- tag_code = 5,
- no_lig_code = 6,
- gp_code_base = 7
-} font_codes ;
-
-# define immediate_code 4 /* command modifier for \.{\\immediate} */
-
-extern void initialize_commands(void);
-extern void initialize_etex_commands(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.c b/Build/source/texk/web2c/luatexdir/tex/conditional.c
deleted file mode 100644
index 948db580340..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/conditional.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
-
-conditional.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-@* We consider now the way \TeX\ handles various kinds of \.{\\if} commands.
-
-Conditions can be inside conditions, and this nesting has a stack that is
-independent of the |save_stack|.
-
-Four global variables represent the top of the condition stack: |cond_ptr| points
-to pushed-down entries, if any; |if_limit| specifies the largest code of a
-|fi_or_else| command that is syntactically legal; |cur_if| is the name of the
-current type of conditional; and |if_line| is the line number at which it began.
-
-If no conditions are currently in progress, the condition stack has the special
-state |cond_ptr=null|, |if_limit=normal|, |cur_if=0|, |if_line=0|. Otherwise
-|cond_ptr| points to a two-word node; the |type|, |subtype|, and |link| fields of
-the first word contain |if_limit|, |cur_if|, and |cond_ptr| at the next level,
-and the second word contains the corresponding |if_line|.
-
-In |cond_ptr| we keep track of the top of the condition stack while |if_limit|
-holds the upper bound on |fi_or_else| codes. The type of conditional being worked
-on is stored in cur_if and |if_line| keeps track of the line where that
-conditional began. When we skip conditional text, |skip_line| keeps track of the
-line number where skipping began, for use in error messages.
-
-*/
-
-halfword cond_ptr;
-int if_limit, cur_if, if_line, skip_line;
-
-/*tex
-
-Here is a procedure that ignores text until coming to an \.{\\or}, \.{\\else}, or
-\.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$ nesting. After it has acted,
-|cur_chr| will indicate the token that was found, but |cur_tok| will not be set
-(because this makes the procedure run faster).
-
-With |l| we keep track of the level of $\.{\\if}\ldots\.{\\fi}$ nesting and
-|scanner_status| let us return to the entry status.
-
-*/
-
-void pass_text(void)
-{
- int l = 0;
- int save_scanner_status = scanner_status;
- scanner_status = skipping;
- skip_line = line;
- while (1) {
- get_next();
- if (cur_cmd == fi_or_else_cmd) {
- if (l == 0)
- break;
- if (cur_chr == fi_code)
- decr(l);
- } else if (cur_cmd == if_test_cmd) {
- incr(l);
- }
- }
- scanner_status = save_scanner_status;
- if (tracing_ifs_par > 0)
- show_cur_cmd_chr();
-}
-
-/*tex
-
-When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then if\/
-\.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if} condition
-has been evaluated, \.{\\relax} will be inserted. For example, a sequence of
-commands like `\.{\\ifvoid1\\else...\\fi}' would otherwise require something
-after the `\.1'.
-
-*/
-
-void push_condition_stack(void)
-{
- halfword p = new_node(if_node, 0);
- vlink(p) = cond_ptr;
- if_limit_type(p) = (quarterword) if_limit;
- if_limit_subtype(p) = (quarterword) cur_if;
- if_line_field(p) = if_line;
- cond_ptr = p;
- cur_if = cur_chr;
- if_limit = if_code;
- if_line = line;
-}
-
-void pop_condition_stack(void)
-{
- halfword p;
- if (if_stack[in_open] == cond_ptr) {
- /*tex Conditionals are possibly not properly nested with files. */
- if_warning();
- }
- p = cond_ptr;
- if_line = if_line_field(p);
- cur_if = if_limit_subtype(p);
- if_limit = if_limit_type(p);
- cond_ptr = vlink(p);
- flush_node(p);
-}
-
-/*tex
-
-Here's a procedure that changes the |if_limit| code corresponding to a given
-value of |cond_ptr|.
-
-*/
-
-void change_if_limit(int l, halfword p)
-{
- if (p == cond_ptr) {
- if_limit = l;
- } else {
- halfword q = cond_ptr;
- while (1) {
- if (q == null)
- confusion("if");
- if (vlink(q) == p) {
- if_limit_type(q) = (quarterword) l;
- return;
- }
- q = vlink(q);
- }
- }
-}
-
-/*tex
-
-The conditional \.{\\ifcsname} is equivalent to \.{\\expandafter}
-\.{\\expandafter} \.{\\ifdefined} \.{\\csname}, except that no new control
-sequence will be entered into the hash table (once all tokens preceding the
-mandatory \.{\\endcsname} have been expanded).
-
-*/
-
-static halfword last_tested_cs ;
-
-static boolean test_for_cs(void)
-{
- /*tex Is the condition true? */
- boolean b = false;
- /*tex To be tested against the second operand: */
- int m, s;
- /*tex For traversing token lists in \.{\\ifx} tests: */
- halfword q;
- halfword n = get_avail();
- /*tex Head of the list of characters: */
- halfword p = n;
- is_in_csname += 1;
- while (1) {
- get_x_token();
- if (cur_cs != 0)
- break;
- store_new_token(cur_tok);
- }
- if (cur_cmd != end_cs_name_cmd) {
- last_tested_cs = null_cs;
- if (suppress_ifcsname_error_par) {
- do {
- get_x_token();
- } while (cur_cmd != end_cs_name_cmd);
- flush_list(n);
- is_in_csname -= 1;
- return b;
- } else {
- complain_missing_csname();
- }
- }
- /*tex Look up the characters of list |n| in the hash table, and set |cur_cs|. */
- m = first;
- p = token_link(n);
- while (p != null) {
- if (m >= max_buf_stack) {
- max_buf_stack = m + 4;
- if (max_buf_stack >= buf_size)
- check_buffer_overflow(max_buf_stack);
- }
- s = token_chr(token_info(p));
- if (s <= 0x7F) {
- buffer[m++] = (packed_ASCII_code) s;
- } else if (s <= 0x7FF) {
- buffer[m++] = (packed_ASCII_code) (0xC0 + s / 0x40);
- buffer[m++] = (packed_ASCII_code) (0x80 + s % 0x40);
- } else if (s <= 0xFFFF) {
- buffer[m++] = (packed_ASCII_code) (0xE0 + s / 0x1000);
- buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x1000) / 0x40);
- buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x1000) % 0x40);
- } else {
- buffer[m++] = (packed_ASCII_code) (0xF0 + s / 0x40000);
- buffer[m++] = (packed_ASCII_code) (0x80 + (s % 0x40000) / 0x1000);
- buffer[m++] = (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) / 0x40);
- buffer[m++] = (packed_ASCII_code) (0x80 + ((s % 0x40000) % 0x1000) % 0x40);
- }
- p = token_link(p);
- }
- if (m > first) {
- /*tex |no_new_control_sequence| is |true| */
- cur_cs = id_lookup(first, m - first);
- } else if (m == first) {
- /*tex the list is empty */
- cur_cs = null_cs;
- }
- b = (eq_type(cur_cs) != undefined_cs_cmd);
- flush_list(n);
- last_cs_name = cur_cs;
- is_in_csname -= 1;
- return b;
-}
-
-/*tex
-
-An active character will be treated as category 13 following \.{\\if\\noexpand}
-or following \.{\\ifcat\\noexpand}.
-
-*/
-
-#define get_x_token_or_active_char() do { \
- get_x_token(); \
- if (cur_cmd==relax_cmd && cur_chr==no_expand_flag) { \
- if (is_active_cs(cs_text(cur_cs))) { \
- cur_cmd=active_char_cmd; \
- cur_chr=active_cs_value(cs_text(cur_tok-cs_token_flag)); \
- } \
- } \
-} while (0)
-
-/*tex
-
-A condition is started when the |expand| procedure encounters an |if_test|
-command; in that case |expand| reduces to |conditional|, which is a recursive
-procedure. @^recursion@>
-
-*/
-
-void conditional(void)
-{
- /*tex Is the condition true? */
- boolean b = false;
- /*tex The relation to be evaluated: */
- int r;
- /*tex To be tested against the second operand: */
- int m, n;
- /*tex For traversing token lists in \.{\\ifx} tests: */
- halfword p, q;
- /*tex The |scanner_status| upon entry: */
- int save_scanner_status;
- /*tex The |cond_ptr| corresponding to this conditional: */
- halfword save_cond_ptr;
- /*tex The type of this conditional: */
- int this_if;
- /*tex Was this \.{\\if} preceded by \.{\\unless}? */
- boolean is_unless;
- if ((tracing_ifs_par > 0) && (tracing_commands_par <= 1)) {
- show_cur_cmd_chr();
- }
- push_condition_stack();
- save_cond_ptr = cond_ptr;
- is_unless = (cur_chr >= unless_code);
- this_if = cur_chr % unless_code;
- /*tex Either process \.{\\ifcase} or set |b| to the value of a boolean condition. */
- switch (this_if) {
- case if_char_code:
- case if_cat_code:
- /*tex Test if two characters match. */
- get_x_token_or_active_char();
- if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) {
- /*tex It's not a character. */
- m = relax_cmd;
- n = too_big_char;
- } else {
- m = cur_cmd;
- n = cur_chr;
- }
- get_x_token_or_active_char();
- if ((cur_cmd > active_char_cmd) || (cur_chr > biggest_char)) {
- cur_cmd = relax_cmd;
- cur_chr = too_big_char;
- }
- if (this_if == if_char_code)
- b = (n == cur_chr);
- else
- b = (m == cur_cmd);
- break;
- case if_int_code:
- case if_dim_code:
- case if_abs_dim_code:
- case if_abs_num_code:
- /*tex
- Test the relation between integers or dimensions. Here we use the fact
- that |<|, |=|, and |>| are consecutive ASCII codes.
- */
- if (this_if == if_int_code || this_if == if_abs_num_code)
- scan_int();
- else
- scan_normal_dimen();
- n = cur_val;
- if ((n < 0) && (this_if == if_abs_dim_code || this_if == if_abs_num_code))
- negate(n);
- /*tex Get the next non-blank non-call... */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- r = cur_tok - other_token;
- if ((r < '<') || (r > '>')) {
- print_err("Missing = inserted for ");
- print_cmd_chr(if_test_cmd, this_if);
- help1("I was expecting to see `<', `=', or `>'. Didn't.");
- back_error();
- r = '=';
- }
- if (this_if == if_int_code || this_if == if_abs_num_code)
- scan_int();
- else
- scan_normal_dimen();
- if ((cur_val < 0) && (this_if == if_abs_dim_code || this_if == if_abs_num_code))
- negate(cur_val);
- switch (r) {
- case '<':
- b = (n < cur_val);
- break;
- case '=':
- b = (n == cur_val);
- break;
- case '>':
- b = (n > cur_val);
- break;
- default:
- /*tex This can't happen. */
- b = false;
- break;
- }
- break;
- case if_odd_code:
- /*tex Test if an integer is odd. */
- scan_int();
- b = odd(cur_val);
- break;
- case if_vmode_code:
- b = (abs(cur_list.mode_field) == vmode);
- break;
- case if_hmode_code:
- b = (abs(cur_list.mode_field) == hmode);
- break;
- case if_mmode_code:
- b = (abs(cur_list.mode_field) == mmode);
- break;
- case if_inner_code:
- b = (cur_list.mode_field < 0);
- break;
- case if_void_code:
- scan_register_num();
- p = box(cur_val);
- b = (p == null);
- break;
- case if_hbox_code:
- scan_register_num();
- p = box(cur_val);
- b = (p != null) && (type(p) == hlist_node);
- break;
- case if_vbox_code:
- scan_register_num();
- p = box(cur_val);
- b = (p != null) && (type(p) == vlist_node);
- break;
- case if_x_code:
- /*tex
- Test if two tokens match. Note that `\.{\\ifx}' will declare two
- macros different if one is \\{long} or \\{outer} and the other
- isn't, even though the texts of the macros are the same.
-
- We need to reset |scanner_status|, since \.{\\outer} control
- sequences are allowed, but we might be scanning a macro
- definition or preamble.
- */
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_next();
- n = cur_cs;
- p = cur_cmd;
- q = cur_chr;
- get_next();
- if (cur_cmd != p) {
- b = false;
- } else if (cur_cmd < call_cmd) {
- b = (cur_chr == q);
- } else {
- /*tex
- Test if two macro texts match. Note also that `\.{\\ifx}'
- decides that macros \.{\\a} and \.{\\b} are different in
- examples like this:
-
- $$\vbox{\halign{\.{#}\hfil&\qquad\.{#}\hfil\cr
- {}\\def\\a\{\\c\}&
- {}\\def\\c\{\}\cr
- {}\\def\\b\{\\d\}&
- {}\\def\\d\{\}\cr}}$$
- */
- p = token_link(cur_chr);
- /*tex Omit reference counts. */
- q = token_link(equiv(n));
- if (p == q) {
- b = true;
- } else {
- while ((p != null) && (q != null)) {
- if (token_info(p) != token_info(q)) {
- p = null;
- break;
- } else {
- p = token_link(p);
- q = token_link(q);
- }
- }
- b = ((p == null) && (q == null));
- }
- }
- scanner_status = save_scanner_status;
- break;
- case if_eof_code:
- scan_four_bit_int();
- b = (read_open[cur_val] == closed);
- break;
- case if_true_code:
- b = true;
- break;
- case if_false_code:
- b = false;
- break;
- case if_case_code:
- /*tex Select the appropriate case and |return| or |goto common_ending|. */
- scan_int();
- /*tex |n| is the number of cases to pass. */
- n = cur_val;
- if (tracing_commands_par > 1) {
- begin_diagnostic();
- tprint("{case ");
- print_int(n);
- print_char('}');
- end_diagnostic(false);
- }
- while (n != 0) {
- pass_text();
- if (cond_ptr == save_cond_ptr) {
- if (cur_chr == or_code)
- decr(n);
- else
- goto COMMON_ENDING;
- } else if (cur_chr == fi_code) {
- pop_condition_stack();
- }
- }
- change_if_limit(or_code, save_cond_ptr);
- /*tex Wait for \.{\\or}, \.{\\else}, or \.{\\fi}. */
- return;
- break;
- case if_primitive_code:
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_next();
- scanner_status = save_scanner_status;
- m = prim_lookup(cs_text(cur_cs));
- b = ((cur_cmd != undefined_cs_cmd) &&
- (m != undefined_primitive) &&
- (cur_cmd == get_prim_eq_type(m)) &&
- (cur_chr == get_prim_equiv(m)));
- break;
- case if_def_code:
- /*tex
- The conditional \.{\\ifdefined} tests if a control sequence is
- defined. We need to reset |scanner_status|, since \.{\\outer}
- control sequences are allowed, but we might be scanning a macro
- definition or preamble.
- */
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_next();
- b = (cur_cmd != undefined_cs_cmd);
- scanner_status = save_scanner_status;
- break;
- case if_cs_code:
- b = test_for_cs();
- break;
- case if_in_csname_code:
- b = is_in_csname;
- break;
- case if_font_char_code:
- /*tex
- The conditional \.{\\iffontchar} tests the existence of a
- character in a font.
- */
- scan_font_ident();
- n = cur_val;
- scan_char_num();
- b = char_exists(n, cur_val);
- break;
- default:
- /*tex there are no other cases, but we need to please |-Wall|. */
- b = false;
- }
- if (is_unless)
- b = !b;
- if (tracing_commands_par > 1) {
- /*tex Display the value of |b|. */
- begin_diagnostic();
- if (b)
- tprint("{true}");
- else
- tprint("{false}");
- end_diagnostic(false);
- }
- if (b) {
- change_if_limit(else_code, save_cond_ptr);
- /*tex Wait for \.{\\else} or \.{\\fi}. */
- return;
- }
- /*tex
- Skip to \.{\\else} or \.{\\fi}, then |goto common_ending|. In a
- construction like `\.{\\if\\iftrue abc\\else d\\fi}', the first
- \.{\\else} that we come to after learning that the \.{\\if} is false is
- not the \.{\\else} we're looking for. Hence the following curious logic
- is needed.
- */
- while (1) {
- pass_text();
- if (cond_ptr == save_cond_ptr) {
- if (cur_chr != or_code)
- goto COMMON_ENDING;
- print_err("Extra \\or");
- help1(
- "I'm ignoring this; it doesn't match any \\if."
- );
- error();
- } else if (cur_chr == fi_code) {
- pop_condition_stack();
- }
- }
- COMMON_ENDING:
- if (cur_chr == fi_code) {
- pop_condition_stack();
- } else {
- /*tex Wait for \.{\\fi}. */
- if_limit = fi_code;
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/conditional.h b/Build/source/texk/web2c/luatexdir/tex/conditional.h
deleted file mode 100644
index 483496eece2..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/conditional.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* conditional.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef CONDITIONAL_H
-# define CONDITIONAL_H
-
-# define unless_code 32 /* amount added for `\.{\\unless}' prefix */
-
-typedef enum {
- if_char_code = 0, /* \.{\\if} */
- if_cat_code = 1, /* \.{\\ifcat} */
- if_int_code = 2, /* \.{\\ifnum} */
- if_dim_code = 3, /* \.{\\ifdim} */
- if_odd_code = 4, /* \.{\\ifodd} */
- if_vmode_code = 5, /* \.{\\ifvmode} */
- if_hmode_code = 6, /* \.{\\ifhmode} */
- if_mmode_code = 7, /* \.{\\ifmmode} */
- if_inner_code = 8, /* \.{\\ifinner} */
- if_void_code = 9, /* \.{\\ifvoid} */
- if_hbox_code = 10, /* \.{\\ifhbox} */
- if_vbox_code = 11, /* \.{\\ifvbox} */
- if_x_code = 12, /* \.{\\ifx} */
- if_eof_code = 13, /* \.{\\ifeof} */
- if_true_code = 14, /* \.{\\iftrue} */
- if_false_code = 15, /* \.{\\iffalse} */
- if_case_code = 16, /* \.{\\ifcase} */
- if_def_code = 17, /* \.{\\ifdefined} */
- if_cs_code = 18, /* \.{\\ifcsname} */
- if_font_char_code = 19, /* \.{\\iffontchar} */
- if_in_csname_code = 20, /* \.{\\ifincsname} */
- if_primitive_code = 21, /* \.{\\ifprimitive} */
- if_abs_num_code = 22, /* \.{\\ifabsnum} */
- if_abs_dim_code = 23, /* \.{\\ifabsdim} */
- if_condition_code = 24, /* \.{\\ifcondition} */
-} if_type_codes;
-
-# define if_limit_subtype(A) subtype((A)+1)
-# define if_limit_type(A) type((A)+1)
-# define if_line_field(A) vlink((A)+1)
-
-typedef enum {
- if_code = 1, /* \.{\\if...} */
- fi_code = 2, /* \.{\\fi} */
- else_code = 3, /* \.{\\else} */
- or_code = 4, /* \.{\\or} */
-} else_type_codes;
-
-extern halfword cond_ptr; /* top of the condition stack */
-extern int if_limit; /* upper bound on |fi_or_else| codes */
-extern int cur_if; /* type of conditional being worked on */
-extern int if_line; /* line where that conditional began */
-extern int skip_line; /* skipping began here */
-
-extern void pass_text(void);
-extern void push_condition_stack(void);
-extern void pop_condition_stack(void);
-extern void change_if_limit(int l, halfword p);
-
-extern void conditional(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.c b/Build/source/texk/web2c/luatexdir/tex/directions.c
deleted file mode 100644
index 59b2f7dcd85..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/directions.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-
-directions.w
-
-Copyright 2009-2014 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-void scan_direction(void)
-{
- int save_cur_cmd = cur_cmd;
- int save_cur_chr = cur_chr;
- get_x_token();
- if (cur_cmd == assign_dir_cmd) {
- cur_val = eqtb[cur_chr].cint;
- goto EXIT;
- } else {
- back_input();
- }
- if (scan_keyword("tlt")) {
- cur_val = dir_TLT;
- } else if (scan_keyword("trt")) {
- cur_val = dir_TRT;
- } else if (scan_keyword("ltl")) {
- cur_val = dir_LTL;
- } else if (scan_keyword("rtt")) {
- cur_val = dir_RTT;
- } else {
- tex_error("Bad direction", NULL);
- cur_val = 0;
- }
- get_x_token();
- if (cur_cmd != spacer_cmd)
- back_input();
- EXIT:
- cur_cmd = save_cur_cmd;
- cur_chr = save_cur_chr;
-}
-
-/*tex
-
- The next two are used by |postlinebreak.c|:
-
-*/
-
-halfword do_push_dir_node(halfword p, halfword a)
-{
- halfword n = copy_node(a);
- vlink(n) = p;
- return n;
-}
-
-halfword do_pop_dir_node(halfword p)
-{
- halfword n = vlink(p);
- flush_node(p);
- return n;
-}
-
-halfword dir_ptr;
-halfword text_dir_ptr;
-
-void initialize_directions(void)
-{
- /*tex There is no need to do anything here at the moment. */
-}
-
-halfword new_dir(int s)
-{
- halfword p = new_node(dir_node, 0);
- dir_dir(p) = s;
- dir_level(p) = cur_level;
- return p;
-}
-
-const char *dir_strings_par[4] = { [0] =
- "TLT","TRT","LTL","RTT",
-};
-
-const char *dir_strings_text_normal[4] = { [0] =
- "+TLT","+TRT","+LTL","+RTT",
-};
-
-const char *dir_strings_text_cancel[4] = { [0] =
- "-TLT","-TRT","-LTL","-RTT",
-};
-
-void print_dir_par(int d)
-{
- tprint(dir_strings_par[d]);
-}
-
-void print_dir_text(halfword d)
-{
- if (subtype(d) == cancel_dir) {
- tprint(dir_strings_text_cancel[dir_dir(d)]);
- } else {
- tprint(dir_strings_text_normal[dir_dir(d)]);
- }
-}
-
-scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph)
-{
- scaled wd = 0;
- if (isglyph) {
- if (textdir_parallel(curdir, pdir) == textglyphdir_orthogonal(pdir)) {
- wd = glyph_width(p);
- if (ex_glyph(p) != 0) {
- /* wd = round_xn_over_d(wd, 1000 + ex_glyph(p)/1000, 1000); */
- wd = ext_xn_over_d(wd, 1000000+ex_glyph(p), 1000000);
-
- }
- } else {
- wd = glyph_depth(p) + glyph_height(p);
- }
- } else {
- if (textdir_parallel(pdir, curdir))
- wd = width(p);
- else
- wd = depth(p) + height(p);
- }
- return wd;
-}
-
-scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p, boolean isglyph)
-{
- scaled_whd whd = { 0, 0, 0 };
- whd.wd = pack_width(curdir, pdir, p, isglyph);
- if (isglyph) {
- if (is_rotated(curdir)) {
- if (textdir_parallel(curdir, pdir))
- whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2;
- else
- whd.ht = whd.dp = glyph_width(p) / 2;
- } else if (is_rotated(pdir)) {
- if (textdir_parallel(curdir, pdir))
- whd.ht = whd.dp = (glyph_height(p) + glyph_depth(p)) / 2;
- else
- whd.ht = glyph_width(p);
- } else {
- if (glyphdir_eq(curdir, pdir)) {
- whd.ht = glyph_height(p);
- whd.dp = glyph_depth(p);
- } else if (glyphdir_opposite(curdir, pdir)) {
- whd.ht = glyph_depth(p);
- whd.dp = glyph_height(p);
- } else
- whd.ht = glyph_width(p);
- }
- } else {
- if (is_rotated(curdir)) {
- if (textdir_parallel(curdir, pdir))
- whd.ht = whd.dp = (height(p) + depth(p)) / 2;
- else
- whd.ht = whd.dp = width(p) / 2;
- } else if (pardir_eq(curdir, pdir)) {
- whd.ht = height(p);
- whd.dp = depth(p);
- } else if (pardir_opposite(curdir, pdir)) {
- whd.ht = depth(p);
- whd.dp = height(p);
- } else
- whd.ht = width(p);
- }
- return whd;
-}
-
-void update_text_dir_ptr(int val)
-{
- if (dir_level(text_dir_ptr) == cur_level) {
- /* update */
- dir_dir(text_dir_ptr) = val;
- } else {
- /* addition */
- halfword text_dir_tmp = new_dir(val);
- vlink(text_dir_tmp) = text_dir_ptr;
- text_dir_ptr = text_dir_tmp;
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/directions.h b/Build/source/texk/web2c/luatexdir/tex/directions.h
deleted file mode 100644
index 92d6cc18f12..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/directions.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* directions.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef DIRECTIONS_H
-# define DIRECTIONS_H
-
-/*
-#define dir_swap 4
-*/
-
-#define dir_min_value 0
-#define dir_max_value 3
-
-#define check_dir_value(d) \
- if ((d < dir_min_value) || (d > dir_max_value)) \
- d = dir_min_value;
-
-#define is_mirrored(a) 0
-
-#define is_rotated(a) (a == dir_RTT)
-
-/*
-
- # define textdir_parallel(a,b) ( \
- ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \
- ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \
- )
-
- # define pardir_parallel(a,b) ( \
- ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \
- ((a == dir_LTL || a == dir_RTT) && (b == dir_LTL || b == dir_RTT)) \
- )
-
- # define pardir_eq(a,b) ( \
- ((a == dir_TLT || a == dir_TRT) && (b == dir_TLT || b == dir_TRT)) || \
- (a == dir_LTL && b == dir_LTL) || \
- (a == dir_RTT && b == dir_RTT) \
- )
-
- # define textdir_eq(a,b) ( \
- (a == dir_TLT && b == dir_TLT) || \
- (a == dir_TRT && b == dir_TRT) || \
- (a == dir_LTL && (b == dir_LTL || b == dir_RTT)) || \
- (a == dir_RTT && (b == dir_LTL || b == dir_RTT))
-
- # define partextdir_eq(a,b) ( \
- ((a == dir_TLT || a == dir_TRT) && (b == dir_LTL || b == dir_RTT)) || \
- (a == dir_LTL && b == dir_TLT) || \
- (a == dir_RTT && b == dir_TRT) \
- )
-
- # define dir_TLT_or_TRT(a) (a == dir_TLT || a == dir_TRT)
- # define dir_LTL_or_RTT(a) (a == dir_LTL || a == dir_RTT)
-
-*/
-
-/* TLT TRT LTL RTT */
-
-# define dir_TLT_or_TRT(a) (a < 2)
-# define dir_LTL_or_RTT(a) (a > 1)
-
-# define textdir_parallel(a,b) ( \
- (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \
- (dir_LTL_or_RTT(a) && dir_LTL_or_RTT(b)) \
-)
-
-# define pardir_parallel(a,b) ( \
- (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \
- (dir_LTL_or_RTT(a) && dir_LTL_or_RTT(b)) \
-)
-
-# define pardir_opposite(a,b) ( \
- (a == dir_LTL && b == dir_RTT) || \
- (a == dir_RTT && b == dir_LTL) \
-)
-
-# define textdir_opposite(a,b) ( \
- (a == dir_TLT && b == dir_TRT) || \
- (a == dir_TRT && b == dir_TLT) \
-)
-
-# define glyphdir_opposite(a,b) 0
-
-# define pardir_eq(a,b) ( \
- (dir_TLT_or_TRT(a) && dir_TLT_or_TRT(b)) || \
- (a == dir_LTL && b == dir_LTL) || \
- (a == dir_RTT && b == dir_RTT) \
-)
-
-# define textdir_eq(a,b) ( \
- (a == dir_TLT && b == dir_TLT) || \
- (a == dir_TRT && b == dir_TRT) || \
- (a == dir_LTL && dir_LTL_or_RTT(b)) || \
- (a == dir_RTT && dir_LTL_or_RTT(b)) \
-)
-
-# define glyphdir_eq(a,b) ( \
- (a != dir_LTL && b != dir_LTL) || \
- (a == dir_LTL && b == dir_LTL) \
-)
-
-# define partextdir_eq(a,b) ( \
- (dir_TLT_or_TRT(a) && dir_LTL_or_RTT(b)) || \
- (a == dir_LTL && b == dir_TLT) || \
- (a == dir_RTT && b == dir_TRT) \
-)
-
-# define textglyphdir_orthogonal(a) (a != dir_RTT)
-
-# define textdir_is_L(a) (a == dir_TLT)
-
-# define push_dir(p,a) { \
- halfword dir_tmp=new_dir((a)); \
- vlink(dir_tmp)=p; \
- p=dir_tmp; \
-}
-
-# define push_dir_node(p,a) { \
- halfword dir_tmp=copy_node((a)); \
- vlink(dir_tmp)=p; \
- p=dir_tmp; \
-}
-
-# define pop_dir_node(p) { \
- halfword dir_tmp=p; \
- p=vlink(dir_tmp); \
- flush_node(dir_tmp); \
-}
-
-extern halfword dir_ptr;
-
-extern halfword text_dir_ptr;
-
-extern void initialize_directions(void);
-extern halfword new_dir(int s);
-
-extern const char *string_dir(int d);
-extern void print_dir_par(int d);
-extern void print_dir_text(halfword d);
-
-extern void scan_direction(void);
-
-extern halfword do_push_dir_node(halfword p, halfword a);
-extern halfword do_pop_dir_node(halfword p);
-
-scaled pack_width(int curdir, int pdir, halfword p, boolean isglyph);
-scaled_whd pack_width_height_depth(int curdir, int pdir, halfword p, boolean isglyph);
-
-void update_text_dir_ptr(int val);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c b/Build/source/texk/web2c/luatexdir/tex/dumpdata.c
deleted file mode 100644
index e7d53050b29..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
-
-dumpdata.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
- We use a magic number to register the version of the format. Normally this
- number only increments when we add a new primitive of change command codes.
- We start with 907 which is the sum of the values of the bytes of \quote
- {don knuth}.
-
-*/
-
-#define FORMAT_ID (907+54)
-#if ((FORMAT_ID>=0) && (FORMAT_ID<=256))
-#error Wrong value for FORMAT_ID.
-#endif
-
-/*tex
-
-After \.{INITEX} has seen a collection of fonts and macros, it can write all the
-necessary information on an auxiliary file so that production versions of \TeX\
-are able to initialize their memory at high speed. The present section of the
-program takes care of such output and input. We shall consider simultaneously the
-processes of storing and restoring, so that the inverse relation between them is
-clear. @.INITEX@>
-
-The global variable |format_ident| is a string that is printed right after the
-|banner| line when \TeX\ is ready to start. For \.{INITEX} this string says
-simply `\.{(INITEX)}'; for other versions of \TeX\ it says, for example,
-`\.{(preloaded format=plain 1982.11.19)}', showing the year, month, and day that
-the format file was created. We have |format_ident=0| before \TeX's tables are
-loaded. |FORMAT_ID| is a new field of type int suitable for the identification of
-a format: values between 0 and 256 (included) can not be used because in the
-previous format they are used for the length of the name of the engine.
-
-*/
-
-str_number format_ident;
-str_number format_name;
-
-
-/*tex
-
-Format files consist of |memory_word| items, and we use the following macros to
-dump words of different types:
-
-*/
-
-FILE *fmt_file;
-
-void store_fmt_file(void)
-{
- int j, k, l, x;
- halfword p;
- char *format_engine;
- int callback_id;
- char *fmtname = NULL;
- /*tex
- If dumping is not allowed, abort. The user is not allowed to dump a
- format file unless |save_ptr=0|. This condition implies that
- |cur_level=level_one|, hence the |xeq_level| array is constant and it
- need not be dumped.
- */
- if (save_ptr != 0) {
- print_err("You can't dump inside a group");
- help1("`{...\\dump}' is a no-no.");
- succumb();
- }
- /*tex
- Create the |format_ident|, open the format file, and inform the user that
- dumping has begun.
- */
- callback_id = callback_defined(pre_dump_callback);
- if (callback_id > 0) {
- (void) run_callback(callback_id, "->");
- }
- selector = new_string;
- tprint(" (format=");
- print(job_name);
- print_char(' ');
- print_int(year_par);
- print_char('.');
- print_int(month_par);
- print_char('.');
- print_int(day_par);
- print_char(')');
- str_room(2);
- format_ident = make_string();
- print(job_name);
- format_name = make_string();
- if (interaction == batch_mode) {
- selector = log_only;
- } else {
- selector = term_and_log;
- }
- fmtname = pack_job_name(format_extension);
- while (!zopen_w_output(&fmt_file, fmtname, FOPEN_WBIN_MODE)) {
- fmtname = prompt_file_name("format file name", format_extension);
- }
- tprint_nl("Beginning to dump on file ");
- tprint(fmtname);
- free(fmtname);
- tprint_nl("");
- print(format_ident);
- /*tex
- Dump constants for consistency check. The next few sections of the
- program should make it clear how we use the dump/undump macros. First
- comes Web2C \TeX's magic constant: "W2TX"
- */
- dump_int(0x57325458);
- dump_int(FORMAT_ID);
- /*tex
- We align |engine_name| to 4 bytes with one or more trailing |NUL|.
- */
- x = (int) strlen(engine_name);
- format_engine = xmalloc((unsigned) (x + 4));
- strcpy(format_engine, engine_name);
- for (k = x; k <= x + 3; k++)
- format_engine[k] = 0;
- x = x + 4 - (x % 4);
- dump_int(x);
- dump_things(format_engine[0], x);
- xfree(format_engine);
- dump_int(0x57325458);
- dump_int(max_halfword);
- dump_int(hash_high);
- dump_int(eqtb_size);
- dump_int(hash_prime);
- /*tex Dump the string pool. */
- k = dump_string_pool();
- print_ln();
- print_int(k);
- tprint(" strings using ");
- print_int((longinteger) pool_size);
- tprint(" bytes");
- /*tex
- Dump the dynamic memory. By sorting the list of available spaces in the
- variable-size portion of |mem|, we are usually able to get by without
- having to dump very much of the dynamic memory.
-
- We recompute |var_used| and |dyn_used|, so that \.{INITEX} dumps valid
- information even when it has not been gathering statistics.
- */
- dump_node_mem();
- dump_int(temp_token_head);
- dump_int(hold_token_head);
- dump_int(omit_template);
- dump_int(null_list);
- dump_int(backup_head);
- dump_int(garbage);
- x = (int) fix_mem_min;
- dump_int(x);
- x = (int) fix_mem_max;
- dump_int(x);
- x = (int) fix_mem_end;
- dump_int(x);
- dump_int(avail);
- dyn_used = (int) fix_mem_end + 1;
- dump_things(fixmem[fix_mem_min], fix_mem_end - fix_mem_min + 1);
- x = x + (int) (fix_mem_end + 1 - fix_mem_min);
- p = avail;
- while (p != null) {
- decr(dyn_used);
- p = token_link(p);
- }
- dump_int(dyn_used);
- print_ln();
- print_int(x);
- tprint(" memory locations dumped; current usage is ");
- print_int(var_used);
- print_char('&');
- print_int(dyn_used);
- /*tex
- Dump regions 1 to 4 of |eqtb|, the table of equivalents. The table of
- equivalents usually contains repeated information, so we dump it in
- compressed form: The sequence of $n+2$ values $(n,x_1,\ldots,x_n,m)$ in
- the format file represents $n+m$ consecutive entries of |eqtb|, with |m|
- extra copies of $x_n$, namely $(x_1,\ldots,x_n,x_n,\ldots,x_n)$.
- */
- k = null_cs;
- do {
- j = k;
- while (j < int_base - 1) {
- if ((equiv(j) == equiv(j + 1)) && (eq_type(j) == eq_type(j + 1)) &&
- (eq_level(j) == eq_level(j + 1)))
- goto FOUND1;
- incr(j);
- }
- l = int_base;
- /*tex |j=int_base-1| */
- goto DONE1;
- FOUND1:
- incr(j);
- l = j;
- while (j < int_base - 1) {
- if ((equiv(j) != equiv(j + 1)) || (eq_type(j) != eq_type(j + 1)) ||
- (eq_level(j) != eq_level(j + 1)))
- goto DONE1;
- incr(j);
- }
- DONE1:
- dump_int(l - k);
- dump_things(eqtb[k], l - k);
- k = j + 1;
- dump_int(k - l);
- } while (k != int_base);
- /*tex Dump regions 5 and 6 of |eqtb|. */
- do {
- j = k;
- while (j < eqtb_size) {
- if (eqtb[j].cint == eqtb[j + 1].cint)
- goto FOUND2;
- incr(j);
- }
- l = eqtb_size + 1;
- /*tex |j=eqtb_size| */
- goto DONE2;
- FOUND2:
- incr(j);
- l = j;
- while (j < eqtb_size) {
- if (eqtb[j].cint != eqtb[j + 1].cint)
- goto DONE2;
- incr(j);
- }
- DONE2:
- dump_int(l - k);
- dump_things(eqtb[k], l - k);
- k = j + 1;
- dump_int(k - l);
- } while (k <= eqtb_size);
- if (hash_high > 0) {
- /*tex Dump the |hash_extra| part: */
- dump_things(eqtb[eqtb_size + 1], hash_high);
- }
- dump_int(par_loc);
- dump_int(write_loc);
- dump_math_codes();
- dump_text_codes();
- /*tex
- Dump the hash table, A different scheme is used to compress the hash
- table, since its lower region is usually sparse. When |text(p)<>0| for
- |p<=hash_used|, we output two words, |p| and |hash[p]|. The hash table
- is, of course, densely packed for |p>=hash_used|, so the remaining
- entries are output in a~block.
- */
- dump_primitives();
- dump_int(hash_used);
- cs_count = frozen_control_sequence - 1 - hash_used + hash_high;
- for (p = hash_base; p <= hash_used; p++) {
- if (cs_text(p) != 0) {
- dump_int(p);
- dump_hh(hash[p]);
- incr(cs_count);
- }
- }
- dump_things(hash[hash_used + 1],undefined_control_sequence - 1 - hash_used);
- if (hash_high > 0) {
- dump_things(hash[eqtb_size + 1], hash_high);
- }
- dump_int(cs_count);
- print_ln();
- print_int(cs_count);
- tprint(" multiletter control sequences");
- /*tex Dump the font information. */
- dump_int(max_font_id());
- for (k = 0; k <= max_font_id(); k++) {
- /*tex Dump the array info for internal font number |k|. */
- dump_font(k);
- tprint_nl("\\font");
- print_esc(font_id_text(k));
- print_char('=');
- tprint_file_name((unsigned char *) font_name(k),
- (unsigned char *) font_area(k), NULL);
- if (font_size(k) != font_dsize(k)) {
- tprint(" at ");
- print_scaled(font_size(k));
- tprint("pt");
- }
- }
- print_ln();
- print_int(max_font_id());
- tprint(" preloaded font");
- if (max_font_id() != 1)
- print_char('s');
- dump_math_data();
- /*tex Dump the hyphenation tables. */
- dump_language_data();
- /*tex Dump a couple more things and the closing check word. */
- dump_int(interaction);
- dump_int(format_ident);
- dump_int(format_name);
- dump_int(69069);
- /*tex
- We have already printed a lot of statistics, so we set |tracing_stats:=0|
- to prevent them from appearing again.
- */
- tracing_stats_par = 0;
- /*tex Dump the \LUA\ bytecodes. */
- dump_luac_registers();
- /*tex Close the format file. */
- zwclose(fmt_file);
-}
-
-/*tex
-
-Corresponding to the procedure that dumps a format file, we have a function that
-reads one in. The function returns |false| if the dumped format is incompatible
-with the present \TeX\ table sizes, etc.
-
-*/
-
-#define too_small(A) do { \
- wake_up_terminal(); \
- wterm_cr(); \
- fprintf(term_out,"---! Must increase the %s",(A)); \
- goto BAD_FMT; \
-} while (0)
-
-/*tex
-
- The inverse macros are slightly more complicated, since we need to check the
- range of the values we are reading in. We say `|undump(a)(b)(x)|' to read an
- integer value |x| that is supposed to be in the range |a<=x<=b|.
-
-*/
-
-#define undump(A,B,C) do { \
- undump_int(x); \
- if (x<(A) || x>(B)) \
- goto BAD_FMT; \
- else \
- (C) = x; \
-} while (0)
-
-#define format_debug(A,B) do { \
- if (debug_format_file) { \
- fprintf (stderr, "fmtdebug: %s=%d", (A), (int)(B)); \
- } \
-} while (0)
-
-#define undump_size(A,B,C,D) do { \
- undump_int(x); \
- if (x<(A)) \
- goto BAD_FMT; \
- if (x>(B)) \
- too_small(C); \
- else \
- format_debug (C,x); \
- (D) = x; \
-} while (0)
-
-boolean load_fmt_file(const char *fmtname)
-{
- int j, k, x;
- halfword p;
- char *format_engine;
- /*tex Undump constants for consistency check .*/
- if (ini_version) {
- libcfree(hash);
- libcfree(eqtb);
- libcfree(fixmem);
- libcfree(varmem);
- }
- undump_int(x);
- format_debug("format magic number", x);
- if (x != 0x57325458) {
- /*tex it's not a format file. */
- goto BAD_FMT;
- }
- undump_int(x);
- format_debug("format id", x);
- if (x != FORMAT_ID) {
- /*tex We have a |FORMAT_ID| mismatch. */
- goto BAD_FMT;
- }
- undump_int(x);
- format_debug("engine name size", x);
- if ((x < 0) || (x > 256)) {
- /*tex The format file is corrupt. */
- goto BAD_FMT;
- }
- format_engine = xmalloc((unsigned) x);
- undump_things(format_engine[0], x);
- format_engine[x - 1] = 0;
- if (strcmp(engine_name, format_engine)) {
- wake_up_terminal();
- wterm_cr();
- fprintf(term_out, "---! %s was written by %s", fmtname, format_engine);
- xfree(format_engine);
- goto BAD_FMT;
- }
- xfree(format_engine);
- undump_int(x);
- format_debug("string pool checksum", x);
- if (x != 0x57325458) {
- wake_up_terminal();
- wterm_cr();
- fprintf(term_out, "---! %s was written by a different version",
- fmtname);
- goto BAD_FMT;
- }
- undump_int(x);
- if (x != max_halfword)
- goto BAD_FMT;
- undump_int(hash_high);
- if ((hash_high < 0) || (hash_high > sup_hash_extra))
- goto BAD_FMT;
- if (hash_extra < hash_high)
- hash_extra = hash_high;
- eqtb_top = eqtb_size + hash_extra;
- if (hash_extra == 0)
- hash_top = undefined_control_sequence;
- else
- hash_top = eqtb_top;
- hash = xmallocarray(two_halves, (unsigned) (1 + hash_top));
- memset(hash, 0, sizeof(two_halves) * (unsigned) (hash_top + 1));
- eqtb = xmallocarray(memory_word, (unsigned) (eqtb_top + 1));
- set_eq_type(undefined_control_sequence, undefined_cs_cmd);
- set_equiv(undefined_control_sequence, null);
- set_eq_level(undefined_control_sequence, level_zero);
- for (x = eqtb_size + 1; x <= eqtb_top; x++)
- eqtb[x] = eqtb[undefined_control_sequence];
- undump_int(x);
- if (x != eqtb_size)
- goto BAD_FMT;
- undump_int(x);
- if (x != hash_prime)
- goto BAD_FMT;
- /*tex Undump the string pool */
- str_ptr = undump_string_pool();
- /*tex Undump the dynamic memory */
- undump_node_mem();
- undump_int(temp_token_head);
- undump_int(hold_token_head);
- undump_int(omit_template);
- undump_int(null_list);
- undump_int(backup_head);
- undump_int(garbage);
- undump_int(fix_mem_min);
- undump_int(fix_mem_max);
- fixmem = xmallocarray(smemory_word, fix_mem_max + 1);
- memset(voidcast(fixmem), 0, (fix_mem_max + 1) * sizeof(smemory_word));
- undump_int(fix_mem_end);
- undump_int(avail);
- undump_things(fixmem[fix_mem_min], fix_mem_end - fix_mem_min + 1);
- undump_int(dyn_used);
- /*tex Undump regions 1 to 6 of the table of equivalents |eqtb|. */
- k = null_cs;
- do {
- undump_int(x);
- if ((x < 1) || (k + x > eqtb_size + 1))
- goto BAD_FMT;
- undump_things(eqtb[k], x);
- k = k + x;
- undump_int(x);
- if ((x < 0) || (k + x > eqtb_size + 1))
- goto BAD_FMT;
- for (j = k; j <= k + x - 1; j++)
- eqtb[j] = eqtb[k - 1];
- k = k + x;
- } while (k <= eqtb_size);
- if (hash_high > 0) {
- /*tex undump |hash_extra| part */
- undump_things(eqtb[eqtb_size + 1], hash_high);
- }
- undump(hash_base, hash_top, par_loc);
- par_token = cs_token_flag + par_loc;
- undump(hash_base, hash_top, write_loc);
- undump_math_codes();
- undump_text_codes();
- /*tex Undump the hash table */
- undump_primitives();
- undump(hash_base, frozen_control_sequence, hash_used);
- p = hash_base - 1;
- do {
- undump(p + 1, hash_used, p);
- undump_hh(hash[p]);
- } while (p != hash_used);
- undump_things(hash[hash_used + 1], undefined_control_sequence - 1 - hash_used);
- if (debug_format_file)
- print_csnames(hash_base, undefined_control_sequence - 1);
- if (hash_high > 0) {
- undump_things(hash[eqtb_size + 1], hash_high);
- if (debug_format_file)
- print_csnames(eqtb_size + 1, hash_high - (eqtb_size + 1));
- }
- undump_int(cs_count);
- /*tex Undump the font information */
- undump_int(x);
- set_max_font_id(x);
- for (k = 0; k <= max_font_id(); k++) {
- /*tex Undump the array info for internal font number |k| */
- undump_font(k);
- }
- undump_math_data();
- /*tex Undump the hyphenation tables */
- undump_language_data();
- /*tex Undump a couple more things and the closing check word */
- undump(batch_mode, error_stop_mode, interaction);
- if (interactionoption != unspecified_mode)
- interaction = interactionoption;
- undump(0, str_ptr, format_ident);
- undump(0, str_ptr, format_name);
- undump_int(x);
- if (x != 69069)
- goto BAD_FMT;
- /*tex Undump the lua bytecodes. */
- undump_luac_registers();
- prev_depth_par = ignore_depth;
- return true;
- BAD_FMT:
- wake_up_terminal();
- wterm_cr();
- fprintf(term_out, "(Fatal format file error; I'm stymied)");
- return false;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.h b/Build/source/texk/web2c/luatexdir/tex/dumpdata.h
deleted file mode 100644
index 933dcfa1f0d..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* dumpdata.h
-
- Copyright 2009, 2012 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef DUMPDATA_H
-# define DUMPDATA_H
-
-extern str_number format_ident;
-extern str_number format_name; /* principal file name */
-extern FILE *fmt_file; /* for input or output of format information */
-
-extern void store_fmt_file(void);
-extern boolean load_fmt_file(const char *);
-
-/* (Un)dumping. These are called from the change file. */
-# define dump_things(base, len) \
- do_zdump ((char *) &(base), sizeof (base), (int) (len), DUMP_FILE)
-# define undump_things(base, len) \
- do_zundump ((char *) &(base), sizeof (base), (int) (len), DUMP_FILE)
-
-extern void do_zdump(char *, int, int, FILE *);
-extern void do_zundump(char *, int, int, FILE *);
-
-/* Like do_undump, but check each value against LOW and HIGH. The
- slowdown isn't significant, and this improves the chances of
- detecting incompatible format files. In fact, Knuth himself noted
- this problem with Web2c some years ago, so it seems worth fixing. We
- can't make this a subroutine because then we lose the type of BASE. */
-# define undump_checked_things(low, high, base, len) \
- do { \
- unsigned i; \
- undump_things (base, len); \
- for (i = 0; i < (len); i++) { \
- if ((&(base))[i] < (low) || (&(base))[i] > (high)) { \
- FATAL5 ("Item %u (=%ld) of .fmt array at %lx <%ld or >%ld", \
- i, (unsigned long) (&(base))[i], (unsigned long) &(base), \
- (unsigned long) low, (unsigned long) high); \
- } \
- } \
- } while (0)
-
-/* Like undump_checked_things, but only check the upper value. We use
- this when the base type is unsigned, and thus all the values will be
- greater than zero by definition. */
-# define undump_upper_check_things(high, base, len) \
- do { \
- unsigned i; \
- undump_things (base, len); \
- for (i = 0; i < (len); i++) { \
- if ((&(base))[i] > (high)) { \
- FATAL4 ("Item %u (=%ld) of .fmt array at %lx >%ld", \
- i, (unsigned long) (&(base))[i], (unsigned long) &(base), \
- (unsigned long) high); \
- } \
- } \
- } while (0)
-
-/* Use the above for all the other dumping and undumping. */
-# define generic_dump(x) dump_things (x, 1)
-# define generic_undump(x) undump_things (x, 1)
-
-# define dump_wd generic_dump
-# define dump_hh generic_dump
-# define dump_qqqq generic_dump
-# define undump_wd generic_undump
-# define undump_hh generic_undump
-# define undump_qqqq generic_undump
-
-/* `dump_int' is called with constant integers, so we put them into a
- variable first. */
-# define dump_int(x) \
- do \
- { \
- int x_val = (x); \
- generic_dump (x_val); \
- } \
- while (0)
-
-/* web2c/regfix puts variables in the format file loading into
- registers. Some compilers aren't willing to take addresses of such
- variables. So we must kludge. */
-# if defined(REGFIX) || defined(WIN32)
-# define undump_int(x) \
- do \
- { \
- int x_val; \
- generic_undump (x_val); \
- x = x_val; \
- } \
- while (0)
-# else
-# define undump_int generic_undump
-# endif /* not (REGFIX || WIN32) */
-
-
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.c b/Build/source/texk/web2c/luatexdir/tex/equivalents.c
deleted file mode 100644
index 3d260d5c5ee..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/equivalents.c
+++ /dev/null
@@ -1,1220 +0,0 @@
-/*
-
-equivalents.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-halfword last_cs_name = null_cs;
-
-/*tex |eqtb[p]| has just been restored or retained. */
-
-static void diagnostic_trace(halfword p, const char *s)
-{
- begin_diagnostic();
- print_char('{');
- tprint(s);
- print_char(' ');
- show_eqtb(p);
- print_char('}');
- end_diagnostic(false);
-}
-
-void show_eqtb_meaning(halfword n);
-
-/*tex
-
-Now that we have studied the data structures for \TeX's semantic routines, we
-ought to consider the data structures used by its syntactic routines. In other
-words, our next concern will be the tables that \TeX\ looks at when it is
-scanning what the user has written.
-
-The biggest and most important such table is called |eqtb|. It holds the current
-``equivalents'' of things; i.e., it explains what things mean or what their
-current values are, for all quantities that are subject to the nesting structure
-provided by \TeX's grouping mechanism. There are six parts to |eqtb|:
-
-1) |eqtb[null_cs]| holds the current equivalent of the zero-length control
-sequence.
-
-2) |eqtb[hash_base..(glue_base-1)]| holds the current equivalents of single- and
-multiletter control sequences.
-
-3) |eqtb[glue_base..(local_base-1)]| holds the current equivalents of glue
-parameters like the current baselineskip.
-
-4) |eqtb[local_base..(int_base-1)]| holds the current equivalents of local
-halfword quantities like the current box registers, the current ``catcodes,'' the
-current font, and a pointer to the current paragraph shape.
-
-5) |eqtb[int_base..(dimen_base-1)]| holds the current equivalents of fullword
-integer parameters like the current hyphenation penalty.
-
-6) |eqtb[dimen_base..eqtb_size]| holds the current equivalents of fullword
-dimension parameters like the current hsize or amount of hanging indentation.
-
-Note that, for example, the current amount of baselineskip glue is determined by
-the setting of a particular location in region~3 of |eqtb|, while the current
-meaning of the control sequence `\.{\\baselineskip}' (which might have been
-changed by \.{\\def} or \.{\\let}) appears in region~2.
-
-The last two regions of |eqtb| have fullword values instead of the three fields
-|eq_level|, |eq_type|, and |equiv|. An |eq_type| is unnecessary, but \TeX\ needs
-to store the |eq_level| information in another array called |xeq_level|.
-
-*/
-
-memory_word *eqtb;
-halfword eqtb_top;
-quarterword xeq_level[(eqtb_size + 1)];
-
-void initialize_equivalents(void)
-{
- int k;
- for (k = int_base; k <= eqtb_size; k++)
- xeq_level[k] = level_one;
-}
-
-/*tex
-
-The nested structure provided by `$\.{\char'173}\ldots\.{\char'175}$' groups in
-\TeX\ means that |eqtb| entries valid in outer groups should be saved and
-restored later if they are overridden inside the braces. When a new |eqtb| value
-is being assigned, the program therefore checks to see if the previous entry
-belongs to an outer level. In such a case, the old value is placed on the
-|save_stack| just before the new value enters |eqtb|. At the end of a grouping
-level, i.e., when the right brace is sensed, the |save_stack| is used to restore
-the outer values, and the inner ones are destroyed.
-
-Entries on the |save_stack| are of type |save_record|. The top item on this stack
-is |save_stack[p]|, where |p=save_ptr-1|; it contains three fields called
-|save_type|, |save_level|, and |save_value|, and it is interpreted in one of four
-ways:
-
-1) If |save_type(p)=restore_old_value|, then |save_value(p)| is a location in
-|eqtb| whose current value should be destroyed at the end of the current group
-and replaced by |save_word(p-1)| (|save_type(p-1)==saved_eqtb|). Furthermore if
-|save_value(p)>=int_base|, then |save_level(p)| should replace the corresponding
-entry in |xeq_level| (if |save_value(p)<int_base|, then the level is part of
-|save_word(p-1)|).
-
-2) If |save_type(p)=restore_zero|, then |save_value(p)| is a location in |eqtb|
-whose current value should be destroyed at the end of the current group, when it
-should be replaced by the current value of |eqtb[undefined_control_sequence]|.
-
-3) If |save_type(p)=insert_token|, then |save_value(p)| is a token that should be
-inserted into \TeX's input when the current group ends.
-
-4) If |save_type(p)=level_boundary|, then |save_level(p)| is a code explaining
-what kind of group we were previously in, and |save_value(p)| points to the level
-boundary word at the bottom of the entries for that group. Furthermore,
-|save_value(p-1)| contains the source line number at which the current level of
-grouping was entered, this field has itself a type: |save_type(p-1)==saved_line|.
-
-Besides this `official' use, various subroutines push temporary variables on the
-save stack when it is handy to do so. These all have an explicit |save_type|, and
-they are:
-
-|saved_adjust| signifies an adjustment is beging scanned,
-|saved_insert| an insertion is being scanned,
-|saved_disc| the \.{\\discretionary} sublist we are working on right now,
-|saved_boxtype| whether a \.{\\localbox} is \.{\\left} or \.{\\right},
-|saved_textdir| a text direction to be restored,
-|saved_eqno| diffentiates between \.{\\eqno} and \.{\\leqno},
-|saved_choices| the \.{\\mathchoices} sublist we are working on right now,
-|saved_math| and interrupted math list,
-|saved_boxcontext| the box context value,
-|saved_boxspec| the box \.{to} or \.{spread} specification,
-|saved_boxdir| the box \.{dir} specification,
-|saved_boxattr| the box \.{attr} specification,
-|saved_boxpack| the box \.{pack} specification.
-
-The global variable |cur_group| keeps track of what sort of group we are
-currently in. Another global variable, |cur_boundary|, points to the topmost
-|level_boundary| word. And |cur_level| is the current depth of nesting. The
-routines are designed to preserve the condition that no entry in the |save_stack|
-or in |eqtb| ever has a level greater than |cur_level|.
-
-*/
-
-save_record *save_stack;
-int save_ptr; /* first unused entry on the save stack */
-int max_save_stack; /* maximum usage of save stack */
-quarterword cur_level = level_one; /* current nesting level for groups */
-group_code cur_group = bottom_level; /* current group type */
-int cur_boundary; /* where the current level begins */
-
-/*tex
-
-At this time it might be a good idea for the reader to review the introduction to
-|eqtb| that was given above just before the long lists of parameter names. Recall
-that the ``outer level'' of the program is |level_one|, since undefined control
-sequences are assumed to be ``defined'' at |level_zero|.
-
-The following macro is used to test if there is room for up to eight more entries
-on |save_stack|. By making a conservative test like this, we can get by with
-testing for overflow in only a few places.
-
-*/
-
-#define check_full_save_stack() do { \
- if (save_ptr>max_save_stack) { \
- max_save_stack=save_ptr; \
- if (max_save_stack>save_size-8) \
- overflow("save size",(unsigned)save_size); \
- } \
-} while (0)
-
-/*tex
-
-Procedure |new_save_level| is called when a group begins. The argument is a group
-identification code like `|hbox_group|'. After calling this routine, it is safe
-to put six more entries on |save_stack|.
-
-In some cases integer-valued items are placed onto the |save_stack| just below a
-|level_boundary| word, because this is a convenient place to keep information
-that is supposed to ``pop up'' just when the group has finished. For example,
-when `\.{\\hbox to 100pt}' is being treated, the 100pt dimension is stored on
-|save_stack| just before |new_save_level| is called.
-
-*/
-
-void new_save_level(group_code c)
-{ /*tex We begin a new level of grouping. */
- check_full_save_stack();
- set_saved_record(0, saved_line, 0, line);
- incr(save_ptr);
- save_type(save_ptr) = level_boundary;
- save_level(save_ptr) = cur_group;
- save_value(save_ptr) = cur_boundary;
- if (cur_level == max_quarterword) {
- overflow("grouping levels", max_quarterword - min_quarterword);
- }
- /*tex We quit if |(cur_level+1)| is too big to be stored in |eqtb|. */
- cur_boundary = save_ptr;
- cur_group = c;
- if (tracing_groups_par > 0)
- group_trace(false);
- incr(cur_level);
- incr(save_ptr);
-}
-
-static const char *save_stack_type(int v)
-{
- const char *s = "";
- switch (save_type(v)) {
- case restore_old_value: s = "restore_old_value"; break;
- case restore_zero: s = "restore_zero"; break;
- case insert_token: s = "insert_token"; break;
- case level_boundary: s = "level_boundary"; break;
- case saved_line: s = "saved_line"; break;
- case saved_adjust: s = "saved_adjust"; break;
- case saved_insert: s = "saved_insert"; break;
- case saved_disc: s = "saved_disc"; break;
- case saved_boxtype: s = "saved_boxtype"; break;
- case saved_textdir: s = "saved_textdir"; break;
- case saved_eqno: s = "saved_eqno"; break;
- case saved_choices: s = "saved_choices"; break;
- case saved_math: s = "saved_math"; break;
- case saved_boxcontext: s = "saved_boxcontext"; break;
- case saved_boxspec: s = "saved_boxspec"; break;
- case saved_boxdir: s = "saved_boxdir"; break;
- case saved_boxattr: s = "saved_boxattr"; break;
- case saved_boxpack: s = "saved_boxpack"; break;
- case saved_attrlist: s = "saved_attrlist"; break;
- case saved_eqtb: s = "saved_eqtb"; break;
- default: break;
- }
- return s;
-}
-
-void print_save_stack(void)
-{
- int i;
- begin_diagnostic();
- selector = term_and_log;
- print_ln();
- for (i = (save_ptr - 1); i >= 0; i--) {
- tprint("save_stack[");
- if (i < 100)
- print_char(' ');
- if (i < 10)
- print_char(' ');
- print_int(i);
- tprint("]: ");
- tprint(save_stack_type(i));
- switch (save_type(i)) {
- case restore_old_value:
- tprint(", ");
- show_eqtb_meaning(save_value(i));
- tprint("=");
- if (save_value(i) >= int_base) {
- print_int(save_word(i - 1).cint);
- } else {
- print_int(eq_type_field(save_word(i - 1)));
- print_char(',');
- print_int(equiv_field(save_word(i - 1)));
- }
- i--;
- break;
- case restore_zero:
- tprint(", ");
- show_eqtb_meaning(save_value(i));
- break;
- case insert_token:
- tprint(", ");
- {
- halfword p = get_avail();
- set_token_info(p, save_value(i));
- show_token_list(p, null, 1);
- free_avail(p);
- }
- break;
- case level_boundary:
- tprint(", old group=");
- print_int(save_level(i));
- tprint(", boundary = ");
- print_int(save_value(i));
- tprint(", line = ");
- print_int(save_value(i - 1));
- i--;
- break;
- case saved_adjust:
- tprint(", ");
- /*tex vadjust vs vadjust pre */
- print_int(save_level(i));
- break;
- case saved_insert:
- tprint(", ");
- /*tex insert number */
- print_int(save_value(i));
- break;
- case saved_boxtype:
- /*tex \.{\\localleftbox} vs \.{\\localrightbox} */
- tprint(", ");
- print_int(save_value(i));
- break;
- case saved_eqno:
- /*tex \.{\\eqno} vs \.{\\leqno} */
- tprint(", ");
- print_int(save_value(i));
- break;
- case saved_disc:
- case saved_choices:
- tprint(", ");
- print_int(save_value(i));
- break;
- case saved_math:
- tprint(", listptr=");
- print_int(save_value(i));
- break;
- case saved_boxcontext:
- tprint(", ");
- print_int(save_value(i));
- break;
- case saved_boxspec:
- tprint(", spec=");
- print_int(save_level(i));
- tprint(", dimen=");
- print_int(save_value(i));
- break;
- case saved_textdir:
- case saved_boxdir:
- tprint(", ");
- print_dir_text(save_value(i));
- break;
- case saved_boxattr:
- case saved_boxpack:
- case saved_attrlist:
- tprint(", ");
- print_int(save_value(i));
- break;
- case saved_line:
- case saved_eqtb:
- break;
- default:
- break;
- }
- print_ln();
- }
- end_diagnostic(true);
-}
-
-/*tex
-
-The \.{\\showgroups} command displays all currently active grouping levels.
-
-The modifications of \TeX\ required for the display produced by the
-|show_save_groups| procedure were first discussed by Donald~E. Knuth in {\sl
-TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990. @^Knuth, Donald Ervin@>
-
-In order to understand a group type we also have to know its mode. Since
-unrestricted horizontal modes are not associated with grouping, they are skipped
-when traversing the semantic nest.
-
-*/
-
-void show_save_groups(void)
-{
- int p = nest_ptr;
- int m;
- save_pointer v = save_ptr;
- quarterword l = cur_level;
- group_code c = cur_group;
- int a = 1; /* to keep track of alignments */
- int i;
- quarterword j;
- const char *s = NULL;
- save_ptr = cur_boundary;
- decr(cur_level);
- tprint_nl("");
- print_ln();
- while (1) {
- tprint_nl("### ");
- print_group(true);
- if (cur_group == bottom_level)
- goto DONE;
- do {
- m = nest[p].mode_field;
- if (p > 0)
- decr(p);
- else
- m = vmode;
- } while (m == hmode);
- tprint(" (");
- switch (cur_group) {
- case simple_group:
- incr(p);
- goto FOUND2;
- break;
- case hbox_group:
- case adjusted_hbox_group:
- s = "hbox";
- break;
- case vbox_group:
- s = "vbox";
- break;
- case vtop_group:
- s = "vtop";
- break;
- case align_group:
- if (a == 0) {
- if (m == -vmode)
- s = "halign";
- else
- s = "valign";
- a = 1;
- goto FOUND1;
- } else {
- if (a == 1)
- tprint("align entry");
- else
- tprint_esc("cr");
- if (p >= a)
- p = p - a;
- a = 0;
- goto FOUND;
- }
- break;
- case no_align_group:
- incr(p);
- a = -1;
- tprint_esc("noalign");
- goto FOUND2;
- break;
- case output_group:
- tprint_esc("output");
- goto FOUND;
- break;
- case math_group:
- goto FOUND2;
- break;
- case disc_group:
- tprint_esc("discretionary");
- for (i = 1; i < 3; i++) {
- if (i <= saved_value(-2)) {
- tprint("{}");
- }
- }
- goto FOUND2;
- break;
- case math_choice_group:
- tprint_esc("mathchoice");
- for (i = 1; i < 4; i++) {
- /*tex A different offset because |-2==saved_textdir|: */
- if (i <= saved_value(-3)) {
- tprint("{}");
- }
- }
- goto FOUND2;
- break;
- case insert_group:
- if (saved_type(-1) == saved_adjust) {
- tprint_esc("vadjust");
- if (saved_level(-1) != 0)
- tprint(" pre");
- } else {
- tprint_esc("insert");
- print_int(saved_value(-1));
- }
- goto FOUND2;
- break;
- case vcenter_group:
- s = "vcenter";
- goto FOUND1;
- break;
- case semi_simple_group:
- incr(p);
- tprint_esc("begingroup");
- goto FOUND;
- break;
- case math_shift_group:
- if (m == mmode) {
- print_char('$');
- } else if (nest[p].mode_field == mmode) {
- print_cmd_chr(eq_no_cmd, saved_value(-2));
- goto FOUND;
- }
- print_char('$');
- goto FOUND;
- break;
- case math_left_group:
- if (subtype(nest[p + 1].eTeX_aux_field) == left_noad_side)
- tprint_esc("left");
- else
- tprint_esc("middle");
- goto FOUND;
- break;
- default:
- confusion("showgroups");
- break;
- }
- /*tex Show the box context */
- i = saved_value(-5);
- if (i != 0) {
- if (i < box_flag) {
- if (abs(nest[p].mode_field) == vmode)
- j = hmove_cmd;
- else
- j = vmove_cmd;
- if (i > 0)
- print_cmd_chr(j, 0);
- else
- print_cmd_chr(j, 1);
- print_scaled(abs(i));
- tprint("pt");
- } else if (i < ship_out_flag) {
- if (i >= global_box_flag) {
- tprint_esc("global");
- i = i - (global_box_flag - box_flag);
- }
- tprint_esc("setbox");
- print_int(i - box_flag);
- print_char('=');
- } else {
- print_cmd_chr(leader_ship_cmd, i - (leader_flag - a_leaders));
- }
- }
- FOUND1:
- tprint_esc(s);
- /*tex Show the box packaging info. The offsets may vary. */
- {
- int ii = -1;
- while (saved_type(ii) != saved_boxspec)
- ii--;
- if (saved_value(ii) != 0) {
- print_char(' ');
- if (saved_level(ii) == exactly)
- tprint("to");
- else
- tprint("spread");
- print_scaled(saved_value(ii));
- tprint("pt");
- }
- }
- FOUND2:
- print_char('{');
- FOUND:
- print_char(')');
- decr(cur_level);
- cur_group = save_level(save_ptr);
- save_ptr = save_value(save_ptr);
- }
- DONE:
- save_ptr = v;
- cur_level = l;
- cur_group = c;
-}
-
-/*tex
-
-Just before an entry of |eqtb| is changed, the following procedure should be
-called to update the other data structures properly. It is important to keep in
-mind that reference counts in |mem| include references from within |save_stack|,
-so these counts must be handled carefully. @^reference counts@>
-
-We don't need to destroy when an assignment has the same node:
-
-*/
-
-void eq_destroy(memory_word w)
-{
- halfword q;
- switch (eq_type_field(w)) {
- case call_cmd:
- case long_call_cmd:
- case outer_call_cmd:
- case long_outer_call_cmd:
- delete_token_ref(equiv_field(w));
- break;
- case glue_ref_cmd:
- flush_node(equiv_field(w));
- break;
- case shape_ref_cmd:
- q = equiv_field(w);
- if (q != null) {
- /*tex
- We need to free a \.{\\parshape} block. Such a block is
- |2n+1| words long, where |n=vinfo(q)|. It happens in the
- flush function.
- */
- flush_node(q);
- }
- break;
- case box_ref_cmd:
- flush_node_list(equiv_field(w));
- break;
- default:
- break;
- }
-}
-
-/*tex
-
-To save a value of |eqtb[p]| that was established at level |l|, we can use the
-following subroutine.
-
-*/
-void eq_save(halfword p, quarterword l)
-{
- check_full_save_stack();
- if (l == level_zero) {
- save_type(save_ptr) = restore_zero;
- } else {
- save_word(save_ptr) = eqtb[p];
- save_type(save_ptr) = saved_eqtb;
- incr(save_ptr);
- save_type(save_ptr) = restore_old_value;
- }
- save_level(save_ptr) = l;
- save_value(save_ptr) = p;
- incr(save_ptr);
-}
-
-/*tex
-
-The procedure |eq_define| defines an |eqtb| entry having specified |eq_type| and
-|equiv| fields, and saves the former value if appropriate. This procedure is used
-only for entries in the first four regions of |eqtb|, i.e., only for entries that
-have |eq_type| and |equiv| fields. After calling this routine, it is safe to put
-four more entries on |save_stack|, provided that there was room for four more
-entries before the call, since |eq_save| makes the necessary test.
-
-*/
-
-void eq_define(halfword p, quarterword t, halfword e)
-{
- boolean trace = tracing_assigns_par > 0;
- if ((eq_type(p) == t) && (equiv(p) == e)) {
- if (trace)
- diagnostic_trace(p, "reassigning");
- eq_destroy(eqtb[p]);
- return;
- }
- if (trace)
- diagnostic_trace(p, "changing");
- if (eq_level(p) == cur_level)
- eq_destroy(eqtb[p]);
- else if (cur_level > level_one)
- eq_save(p, eq_level(p));
- set_eq_level(p, cur_level);
- set_eq_type(p, t);
- set_equiv(p, e);
- if (trace)
- diagnostic_trace(p, "into");
-}
-
-/*tex
-
-The counterpart of |eq_define| for the remaining (fullword) positions in |eqtb|
-is called |eq_word_define|. Since |xeq_level[p]>=level_one| for all |p|, a
-`|restore_zero|' will never be used in this case.
-
-*/
-
-void eq_word_define(halfword p, int w)
-{
- boolean trace = tracing_assigns_par > 0;
- if (eqtb[p].cint == w) {
- if (trace)
- diagnostic_trace(p, "reassigning");
- return;
- }
- if (trace)
- diagnostic_trace(p, "changing");
- if (xeq_level[p] != cur_level) {
- eq_save(p, xeq_level[p]);
- xeq_level[p] = cur_level;
- }
- eqtb[p].cint = w;
- if (trace)
- diagnostic_trace(p, "into");
-}
-
-/*tex
-
-The |eq_define| and |eq_word_define| routines take care of local definitions.
-@^global definitions@> Global definitions are done in almost the same way, but
-there is no need to save old values, and the new value is associated with
-|level_one|.
-
-*/
-
-void geq_define(halfword p, quarterword t, halfword e)
-{
- boolean trace = tracing_assigns_par > 0;
- if (trace)
- diagnostic_trace(p, "globally changing");
- eq_destroy(eqtb[p]);
- set_eq_level(p, level_one);
- set_eq_type(p, t);
- set_equiv(p, e);
- if (trace)
- diagnostic_trace(p, "into");
-}
-
-void geq_word_define(halfword p, int w)
-{
- boolean trace = tracing_assigns_par > 0;
- if (trace)
- diagnostic_trace(p, "globally changing");
- eqtb[p].cint = w;
- xeq_level[p] = level_one;
- if (trace)
- diagnostic_trace(p, "into");
-}
-
-/*tex
-
-Subroutine |save_for_after| puts a token on the stack for save-keeping.
-
-*/
-
-void save_for_after(halfword t)
-{
- if (cur_level > level_one) {
- check_full_save_stack();
- save_type(save_ptr) = insert_token;
- save_level(save_ptr) = level_zero;
- save_value(save_ptr) = t;
- incr(save_ptr);
- }
-}
-
-/*tex
-
-The |unsave| routine goes the other way, taking items off of |save_stack|. This
-routine takes care of restoration when a level ends; everything belonging to the
-topmost group is cleared off of the save stack.
-
-*/
-
-void unsave(void)
-{
- halfword p;
- quarterword l = level_one;
- /*tex Variable |a| registers if we already have processed an \.{\\aftergroup}. */
- boolean a = false;
- unsave_math_codes(cur_level);
- unsave_cat_codes(cat_code_table_par, cur_level);
- unsave_text_codes(cur_level);
- unsave_math_data(cur_level);
- if (cur_level > level_one) {
- boolean trace = tracing_restores_par > 0;
- decr(cur_level);
- /*tex Clear off top level from |save_stack|. */
- while (true) {
- decr(save_ptr);
- if (save_type(save_ptr) == level_boundary)
- break;
- p = save_value(save_ptr);
- if (save_type(save_ptr) == insert_token) {
- reinsert_token(a, p);
- /*tex always |true| as we are always in \ETEX\ now. */
- a = true;
- } else {
- if (save_type(save_ptr) == restore_old_value) {
- l = save_level(save_ptr);
- decr(save_ptr);
- } else {
- save_word(save_ptr) = eqtb[undefined_control_sequence];
- }
- /*tex
- Store |save_stack[save_ptr]| in |eqtb[p]|, unless |eqtb[p]|
- holds a global value A global definition, which sets the
- level to |level_one|, will not be undone by |unsave|. If at
- least one global definition of |eqtb[p]| has been carried out
- within the group that just ended, the last such definition
- will therefore survive.
- */
- if (p < int_base || p > eqtb_size) {
- if (eq_level(p) == level_one) {
- /*tex Destroy the saved value: */
- eq_destroy(save_word(save_ptr));
- if (trace)
- diagnostic_trace(p, "retaining");
- } else {
- /*tex Destroy the current value: */
- eq_destroy(eqtb[p]);
- /*tex Restore the saved value: */
- eqtb[p] = save_word(save_ptr);
- if (trace)
- diagnostic_trace(p, "restoring");
- }
- } else if (xeq_level[p] != level_one) {
- eqtb[p] = save_word(save_ptr);
- xeq_level[p] = l;
- if (trace)
- diagnostic_trace(p, "restoring");
- } else {
- if (trace)
- diagnostic_trace(p, "retaining");
- }
- }
- }
-
- if (tracing_groups_par > 0) {
- group_trace(true);
- }
- if (grp_stack[in_open] == cur_boundary) {
- /*tex Groups are possibly not properly nested with files. */
- group_warning();
- }
- cur_group = save_level(save_ptr);
- cur_boundary = save_value(save_ptr);
- decr(save_ptr);
- } else {
- /*tex |unsave| is not used when |cur_group=bottom_level| */
- confusion("curlevel");
- }
- attr_list_cache = cache_disabled;
-}
-
-/*tex
-
-Most of the parameters kept in |eqtb| can be changed freely, but there's an
-exception: The magnification should not be used with two different values during
-any \TeX\ job, since a single magnification is applied to an entire run. The
-global variable |mag_set| is set to the current magnification whenever it becomes
-necessary to ``freeze'' it at a particular value.
-
-The |prepare_mag| subroutine is called whenever \TeX\ wants to use |mag| for
-magnification. If nonzero, this magnification should be used henceforth. We might
-drop magnifaction at some point.
-
-*/
-
-int mag_set = 0;
-
-void prepare_mag(void)
-{
- if ((mag_set > 0) && (mag_par != mag_set)) {
- print_err("Incompatible magnification (");
- print_int(mag_par);
- tprint(");");
- tprint_nl(" the previous value will be retained");
- help2(
- "I can handle only one magnification ratio per job. So I've",
- "reverted to the magnification you used earlier on this run."
- );
- int_error(mag_set);
- geq_word_define(int_base + mag_code, mag_set); /* |mag:=mag_set| */
- }
- if ((mag_par <= 0) || (mag_par > 32768)) {
- print_err("Illegal magnification has been changed to 1000");
- help1(
- "The magnification ratio must be between 1 and 32768."
- );
- int_error(mag_par);
- geq_word_define(int_base + mag_code, 1000);
- }
- if ((mag_set == 0) && (mag_par != mag_set)) {
- if (mag_par != 1000)
- one_true_inch = xn_over_d(one_hundred_inch, 10, mag_par);
- else
- one_true_inch = one_inch;
- }
- mag_set = mag_par;
-}
-
-/*tex
-
-Let's pause a moment now and try to look at the Big Picture. The \TeX\ program
-consists of three main parts: syntactic routines, semantic routines, and output
-routines. The chief purpose of the syntactic routines is to deliver the user's
-input to the semantic routines, one token at a time. The semantic routines act as
-an interpreter responding to these tokens, which may be regarded as commands. And
-the output routines are periodically called on to convert box-and-glue lists into
-a compact set of instructions that will be sent to a typesetter. We have
-discussed the basic data structures and utility routines of \TeX, so we are good
-and ready to plunge into the real activity by considering the syntactic routines.
-
-Our current goal is to come to grips with the |get_next| procedure, which is the
-keystone of \TeX's input mechanism. Each call of |get_next| sets the value of
-three variables |cur_cmd|, |cur_chr|, and |cur_cs|, representing the next input
-token.
-
-$$
- \vbox{\halign{#\hfil\cr
- \hbox{|cur_cmd| denotes a command code from the long list of codes given above;}\cr
- \hbox{|cur_chr| denotes a character code or other modifier of the command code;}\cr
- \hbox{|cur_cs| is the |eqtb| location of the current control sequence,}\cr
- \hbox{\qquad if the current token was a control sequence, otherwise it's zero.}\cr}}
-$$
-
-Underlying this external behavior of |get_next| is all the machinery necessary to
-convert from character files to tokens. At a given time we may be only partially
-finished with the reading of several files (for which \.{\\input} was specified),
-and partially finished with the expansion of some user-defined macros and/or some
-macro parameters, and partially finished with the generation of some text in a
-template for \.{\\halign}, and so on. When reading a character file, special
-characters must be classified as math delimiters, etc.; comments and extra blank
-spaces must be removed, paragraphs must be recognized, and control sequences must
-be found in the hash table. Furthermore there are occasions in which the scanning
-routines have looked ahead for a word like `\.{plus}' but only part of that word
-was found, hence a few characters must be put back into the input and scanned
-again.
-
-To handle these situations, which might all be present simultaneously, \TeX\ uses
-various stacks that hold information about the incomplete activities, and there
-is a finite state control for each level of the input mechanism. These stacks
-record the current state of an implicitly recursive process, but the |get_next|
-procedure is not recursive. Therefore it will not be difficult to translate these
-algorithms into low-level languages that do not support recursion.
-
-In general, |cur_cmd| is the current command as set by |get_next|, while
-|cur_chr| is the operand of the current command. The control sequence found here
-is registsred in |cur_cs| and is zero if none found. The |cur_tok| variable
-contains the packed representative of |cur_cmd| and |cur_chr| and like the other
-ones is global.
-
-*/
-
-int cur_cmd;
-halfword cur_chr;
-halfword cur_cs;
-halfword cur_tok;
-
-/*tex
-
-Here is a procedure that displays the current command. The variable |n| holds the
-level of \.{\\if...\\fi} nesting and |l| the line where \.{\\if} started.
-
-*/
-
-void show_cur_cmd_chr(void)
-{
- int n, l;
- halfword p;
- begin_diagnostic();
- tprint_nl("{");
- if (mode_par != shown_mode) {
- print_mode(mode_par);
- tprint(": ");
- shown_mode = mode_par;
- }
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- if (tracing_ifs_par > 0) {
- if (cur_cmd >= if_test_cmd) {
- if (cur_cmd <= fi_or_else_cmd) {
- tprint(": ");
- if (cur_cmd == fi_or_else_cmd) {
- print_cmd_chr(if_test_cmd, cur_if);
- print_char(' ');
- n = 0;
- l = if_line;
- } else {
- n = 1;
- l = line;
- }
- p = cond_ptr;
- while (p != null) {
- incr(n);
- p = vlink(p);
- }
- tprint("(level ");
- print_int(n);
- print_char(')');
- print_if_line(l);
- }
- }
- }
- print_char('}');
- end_diagnostic(false);
-}
-
-/*tex
-
-Here is a procedure that displays the contents of |eqtb[n]| symbolically.
-
-*/
-
-void show_eqtb(halfword n)
-{
- if (n < null_cs) {
- /*tex
- This can't happen in a pure \TEX\ run, but careless usage of tokens
- at the \LUA\ end can make you end up here.
- */
- tprint("? bad token, case 1: ");
- print_int(n);
- } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) {
- /*tex
- This routine show the current meaning of |eqtb| entry |n| in region 1 or 2.
- Similar routines for the other regions will appear below.
- */
- sprint_cs(n);
- print_char('=');
- print_cmd_chr(eq_type(n), equiv(n));
- if (eq_type(n) >= call_cmd) {
- print_char(':');
- show_token_list(token_link(equiv(n)), null, 32);
- }
- } else if (n < local_base) {
- /*tex
- Here we show equivalent |n| in region 3. All glue parameters and registers
- are initially `\.{0pt plus0pt minus0pt}'.
- */
- if (n < skip_base) {
- if (n < glue_base + thin_mu_skip_code)
- print_cmd_chr(assign_glue_cmd, n);
- else
- print_cmd_chr(assign_mu_glue_cmd, n);
- print_char('=');
- if (n < glue_base + thin_mu_skip_code)
- print_spec(equiv(n), "pt");
- else
- print_spec(equiv(n), "mu");
- } else if (n < mu_skip_base) {
- tprint_esc("skip");
- print_int(n - skip_base);
- print_char('=');
- print_spec(equiv(n), "pt");
- } else {
- tprint_esc("muskip");
- print_int(n - mu_skip_base);
- print_char('=');
- print_spec(equiv(n), "mu");
- }
-
- } else if (n < int_base) {
- /*tex
- We're now at equivalent |n| in region 4. First we initialize most
- things to null or undefined values. An undefined font is represented
- by the internal code |font_base|.
-
- However, the character code tables are given initial values based on
- the conventional interpretation of ASCII code. These initial values
- should not be changed when \TeX\ is adapted for use with non-English
- languages; all changes to the initialization conventions should be
- made in format packages, not in \TeX\ itself, so that global
- interchange of formats is possible.
- */
- if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) {
- if (n == par_shape_loc)
- print_cmd_chr(set_tex_shape_cmd, n);
- else
- print_cmd_chr(set_etex_shape_cmd, n);
- print_char('=');
- if (equiv(n) == null) {
- print_char('0');
- } else if (n > par_shape_loc) {
- print_int(penalty(equiv(n)));
- print_char(' ');
- print_int(penalty(equiv(n) + 1));
- if (penalty(equiv(n)) > 1)
- tprint_esc("ETC.");
- } else {
- print_int(vinfo(par_shape_par_ptr + 1));
- }
- } else if (n < toks_base) {
- print_cmd_chr(assign_toks_cmd, n);
- print_char('=');
- if (equiv(n) != null)
- show_token_list(token_link(equiv(n)), null, 32);
- } else if (n < box_base) {
- tprint_esc("toks");
- print_int(n - toks_base);
- print_char('=');
- if (equiv(n) != null)
- show_token_list(token_link(equiv(n)), null, 32);
- } else if (n < cur_font_loc) {
- tprint_esc("box");
- print_int(n - box_base);
- print_char('=');
- if (equiv(n) == null) {
- tprint("void");
- } else {
- depth_threshold = 0;
- breadth_max = 1;
- show_node_list(equiv(n));
- }
- } else if (n == cur_font_loc) {
- /*tex
- Let's show the font identifier in |eqtb[n]|, that's
- |font_id_text(equiv(n))|
- */
- tprint("current font");
- print_char('=');
- print_esc(hash[font_id_base + equiv(n)].rh);
- }
- } else if (n < dimen_base) {
- /*tex Show equivalent |n| in region 5: */
- if (n < dir_base) {
- print_cmd_chr(assign_int_cmd, n);
- print_char('=');
- print_int(eqtb[n].cint);
- } else if (n < count_base) {
- print_cmd_chr(assign_dir_cmd, n);
- print_char(' ');
- print_dir_par(eqtb[n].cint);
- } else if (n < attribute_base) {
- tprint_esc("count");
- print_int(n - count_base);
- print_char('=');
- print_int(eqtb[n].cint);
- } else if (n < del_code_base) {
- tprint_esc("attribute");
- print_int(n - attribute_base);
- print_char('=');
- print_int(eqtb[n].cint);
- }
- } else if (n <= eqtb_size) {
- /*tex Show equivalent |n| in region 6: */
- if (n < scaled_base) {
- print_cmd_chr(assign_dimen_cmd, n);
- } else {
- tprint_esc("dimen");
- print_int(n - scaled_base);
- }
- print_char('=');
- print_scaled(eqtb[n].cint);
- tprint("pt");
- } else {
- /*tex This can't happen unless you messed up at the \LUA\ end. */
- tprint("? bad token, case 2: ");
- print_int(n);
- }
-}
-
-void show_eqtb_meaning(halfword n)
-{
- if (n < null_cs) {
- /*tex This can't happen. */
- print_char('?');
- } else if ((n < glue_base) || ((n > eqtb_size) && (n <= eqtb_top))) {
- /*tex
- Here is a routine that displays the current meaning of an |eqtb|
- entry in region 1 or~2. Similar routines for the other regions will
- appear below.
- */
- sprint_cs(n);
- } else if (n < local_base) {
- /*
- Show equivalent |n| in region 3. All glue parameters and registers
- are initially `\.{0pt plus0pt minus0pt}'.
- */
- if (n < skip_base) {
- if (n < glue_base + thin_mu_skip_code)
- print_cmd_chr(assign_glue_cmd, n);
- else
- print_cmd_chr(assign_mu_glue_cmd, n);
- } else if (n < mu_skip_base) {
- tprint_esc("skip");
- print_int(n - skip_base);
- } else {
- tprint_esc("muskip");
- print_int(n - mu_skip_base);
- }
- } else if (n < int_base) {
- /*tex
- Show equivalent |n| in region 4. We initialize most things to null or
- undefined values. An undefined font is represented by the internal
- code |font_base|. However, the character code tables are given
- initial values based on the conventional interpretation of ASCII
- code. These initial values should not be changed when \TeX\ is
- adapted for use with non-English languages; all changes to the
- initialization conventions should be made in format packages, not in
- \TeX\ itself, so that global interchange of formats is possible.
- */
- if ((n == par_shape_loc) || ((n >= etex_pen_base) && (n < etex_pens))) {
- if (n == par_shape_loc)
- print_cmd_chr(set_tex_shape_cmd, n);
- else
- print_cmd_chr(set_etex_shape_cmd, n);
- } else if (n < toks_base) {
- print_cmd_chr(assign_toks_cmd, n);
- } else if (n < box_base) {
- tprint_esc("toks");
- print_int(n - toks_base);
- } else if (n < cur_font_loc) {
- tprint_esc("box");
- print_int(n - box_base);
- } else if (n == cur_font_loc) {
- /*tex Show the font identifier in |eqtb[n]|. */
- tprint("current font");
- }
- } else if (n < dimen_base) {
- /*tex Show equivalent |n| in region 5. */
- if (n < dir_base) {
- print_cmd_chr(assign_int_cmd, n);
- } else if (n < count_base) {
- print_cmd_chr(assign_dir_cmd, n);
- } else if (n < attribute_base) {
- tprint_esc("count");
- print_int(n - count_base);
- } else if (n < del_code_base) {
- tprint_esc("attribute");
- print_int(n - attribute_base);
- }
- } else if (n <= eqtb_size) {
- /*tex Show equivalent |n| in region 6. */
- if (n < scaled_base) {
- print_cmd_chr(assign_dimen_cmd, n);
- } else {
- tprint_esc("dimen");
- print_int(n - scaled_base);
- }
- } else {
- /*tex This can't happen either. */
- print_char('?');
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h
deleted file mode 100644
index 83117c64fa1..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h
+++ /dev/null
@@ -1,916 +0,0 @@
-/* equivalents.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef EQUIVALENTS_H
-# define EQUIVALENTS_H
-
-/*
-
-Like the preceding parameters, the following quantities can be changed at compile
-time to extend or reduce \TeX's capacity. But if they are changed, it is
-necessary to rerun the initialization program \.{INITEX} @.INITEX@> to generate
-new tables for the production \TeX\ program. One can't simply make helter-skelter
-changes to the following constants, since certain rather complex initialization
-numbers are computed from them. They are defined here using \.{WEB} macros,
-instead of being put into \PASCAL's |const| list, in order to emphasize this
-distinction.
-
-*/
-
-# define font_base 0 /* smallest internal font number; must not be less than |min_quarterword| */
-# define biggest_reg 65535 /* the largest allowed register number; must be |< max_quarterword| */
-# define number_regs 65536 /* |biggest_reg+1| */
-# define number_attrs 65536 /* total numbeer of attributes */
-# define biggest_char 1114111 /* 0x10FFFF, the largest allowed character number; must be |< max_halfword| */
-# define too_big_char (biggest_char+1) /* 1114112, |biggest_char+1| */
-# define special_char (biggest_char+2) /* 1114113, |biggest_char+2| */
-# define number_chars (biggest_char+3) /* 1114112, |biggest_char+1| */
-# define number_fonts (5535-font_base+1)
-# define biggest_lang 32767
-# define too_big_lang 32768
-# define text_size 0 /* size code for the largest size in a family */
-# define script_size 1 /* size code for the medium size in a family */
-# define script_script_size 2 /* size code for the smallest size in a family */
-
-/*
-
-Each entry in |eqtb| is a |memory_word|. Most of these words are of type
-|two_halves|, and subdivided into three fields:
-
-\yskip\hangg 1) The |eq_level| (a quarterword) is the level of grouping at which
-this equivalent was defined. If the level is |level_zero|, the equivalent has
-never been defined; |level_one| refers to the outer level (outside of all
-groups), and this level is also used for global definitions that never go away.
-Higher levels are for equivalents that will disappear at the end of their group.
-@^global definitions@>
-
-\yskip\hangg 2) The |eq_type| (another quarterword) specifies what kind of entry
-this is. There are many types, since each \TeX\ primitive like \.{\\hbox},
-\.{\\def}, etc., has its own special code. The list of command codes above
-includes all possible settings of the |eq_type| field.
-
-\yskip\hangg 3) The |equiv| (a halfword) is the current equivalent value. This
-may be a font number, a pointer into |mem|, or a variety of other things.
-
-Many locations in |eqtb| have symbolic names. The purpose of the next paragraphs
-is to define these names, and to set up the initial values of the equivalents.
-
-In the first region we have a single entry for the `null csname' of length zero.
-In luatex, the active characters and and single-letter control sequence names are
-part of the next region.
-
-Then comes region~2, which corresponds to the hash table that we will define
-later. The maximum address in this region is used for a dummy control sequence
-that is perpetually undefined. There also are several locations for control
-sequences that are perpetually defined (since they are used in error recovery).
-
-@ Region 3 of |eqtb| contains the |number_regs| \.{\\skip} registers, as well as
-the glue parameters defined here. It is important that the ``muskip'' parameters
-have larger numbers than the others.
-
-@ Region 4 of |eqtb| contains the local quantities defined here. The bulk of this
-region is taken up by five tables that are indexed by eight-bit characters; these
-tables are important to both the syntactic and semantic portions of \TeX. There
-are also a bunch of special things like font and token parameters, as well as the
-tables of \.{\\toks} and \.{\\box} registers.
-
-@ Region 5 of |eqtb| contains the integer parameters and registers defined here,
-as well as the |del_code| table. The latter table differs from the
-|cat_code..math_code| tables that precede it, since delimiter codes are fullword
-integers while the other kinds of codes occupy at most a halfword. This is what
-makes region~5 different from region~4. We will store the |eq_level| information
-in an auxiliary array of quarterwords that will be defined later.
-
-@ The integer parameters should really be initialized by a macro package; the
-following initialization does the minimum to keep \TeX\ from complete failure.
-
-@^null delimiter@>
-
-@ The final region of |eqtb| contains the dimension parameters defined here, and
-the |number_regs| \.{\\dimen} registers.
-
-*/
-
-# define null_cs 1 /* equivalent of \.{\\csname\\endcsname} */
-# define hash_base (null_cs+1) /* beginning of region 2, for the hash table */
-# define frozen_control_sequence (hash_base+hash_size) /* for error recovery */
-# define frozen_protection (frozen_control_sequence) /* inaccessible but definable */
-# define frozen_cr (frozen_control_sequence+1) /* permanent `\.{\\cr}' */
-# define frozen_end_group (frozen_control_sequence+2) /* permanent `\.{\\endgroup}' */
-# define frozen_right (frozen_control_sequence+3) /* permanent `\.{\\right}' */
-# define frozen_fi (frozen_control_sequence+4) /* permanent `\.{\\fi}' */
-# define frozen_end_template (frozen_control_sequence+5) /* permanent `\.{\\endtemplate}' */
-# define frozen_endv (frozen_control_sequence+6) /* second permanent `\.{\\endtemplate}' */
-# define frozen_relax (frozen_control_sequence+7) /* permanent `\.{\\relax}' */
-# define end_write (frozen_control_sequence+8) /* permanent `\.{\\endwrite}' */
-# define frozen_dont_expand (frozen_control_sequence+9 ) /* permanent `\.{\\notexpanded:}' */
-# define frozen_primitive (frozen_control_sequence+11 ) /* permanent `\.{\\primitive}' */
-# define frozen_special (frozen_control_sequence+12 ) /* permanent `\.{\\special}' */
-# define frozen_null_font (frozen_control_sequence+13 ) /* permanent `\.{\\nullfont}' */
-# define font_id_base (frozen_null_font-font_base ) /* begins table of |number_fonts| permanent font identifiers */
-# define undefined_control_sequence (frozen_null_font+number_fonts)
-# define glue_base (undefined_control_sequence+1) /* beginning of region 3 */
-
-# define line_skip_code 0 /* interline glue if |baseline_skip| is infeasible */
-# define baseline_skip_code 1 /* desired glue between baselines */
-# define par_skip_code 2 /* extra glue just above a paragraph */
-# define above_display_skip_code 3 /* extra glue just above displayed math */
-# define below_display_skip_code 4 /* extra glue just below displayed math */
-# define above_display_short_skip_code 5 /* glue above displayed math following short lines */
-# define below_display_short_skip_code 6 /* glue below displayed math following short lines */
-# define left_skip_code 7 /* glue at left of justified lines */
-# define right_skip_code 8 /* glue at right of justified lines */
-# define top_skip_code 9 /* glue at top of main pages */
-# define split_top_skip_code 10 /* glue at top of split pages */
-# define tab_skip_code 11 /* glue between aligned entries */
-# define space_skip_code 12 /* glue between words (if not |zero_glue|) */
-# define xspace_skip_code 13 /* glue after sentences (if not |zero_glue|) */
-# define par_fill_skip_code 14 /* glue on last line of paragraph */
-# define math_skip_code 15
-# define thin_mu_skip_code 16 /* thin space in math formula */
-# define med_mu_skip_code 17 /* medium space in math formula */
-# define thick_mu_skip_code 18 /* thick space in math formula */
-# define glue_pars 19 /* total number of glue parameters */
-
-# define skip_base (glue_base+glue_pars) /* table of |number_regs| ``skip'' registers */
-# define mu_skip_base (skip_base+number_regs) /* table of |number_regs| ``muskip'' registers */
-# define local_base (mu_skip_base+number_regs) /* beginning of region 4 */
-
-# define par_shape_loc (local_base) /* specifies paragraph shape */
-# define output_routine_loc (local_base+1) /* points to token list for \.{\\output} */
-# define every_par_loc (local_base+2) /* points to token list for \.{\\everypar} */
-# define every_math_loc (local_base+3) /* points to token list for \.{\\everymath} */
-# define every_display_loc (local_base+4) /* points to token list for \.{\\everydisplay} */
-# define every_hbox_loc (local_base+5) /* points to token list for \.{\\everyhbox} */
-# define every_vbox_loc (local_base+6) /* points to token list for \.{\\everyvbox} */
-# define every_job_loc (local_base+7) /* points to token list for \.{\\everyjob} */
-# define every_cr_loc (local_base+8) /* points to token list for \.{\\everycr} */
-# define err_help_loc (local_base+9) /* points to token list for \.{\\errhelp} */
-# define every_eof_loc (local_base+10) /* points to token list for \.{\\everyeof} */
-
-# define backend_toks_base (local_base+11)
-# define backend_toks_last (local_base+20)
-
-# define toks_base (local_base+21) /* table of |number_regs| token list registers */
-
-# define etex_pen_base (toks_base+number_regs) /* start of table of \eTeX's penalties */
-# define inter_line_penalties_loc (etex_pen_base) /* additional penalties between lines */
-# define club_penalties_loc (etex_pen_base+1) /* penalties for creating club lines */
-# define widow_penalties_loc (etex_pen_base+2) /* penalties for creating widow lines */
-# define display_widow_penalties_loc (etex_pen_base+3) /* ditto, just before a display */
-# define etex_pens (etex_pen_base+4) /* end of table of \eTeX's penalties */
-# define local_left_box_base (etex_pens)
-# define local_right_box_base (local_left_box_base+1)
-# define box_base (local_right_box_base+1) /* table of |number_regs| box registers */
-# define cur_font_loc (box_base+number_regs) /* internal font number outside math mode */
-# define internal_math_param_base (cur_font_loc+1 ) /* current math parameter data index */
-# define cat_code_base (internal_math_param_base+1) /* current category code data index */
-# define lc_code_base (cat_code_base+1) /* table of |number_chars| lowercase mappings */
-# define uc_code_base (lc_code_base+1) /* table of |number_chars| uppercase mappings */
-# define sf_code_base (uc_code_base+1) /* table of |number_chars| spacefactor mappings */
-# define math_code_base (sf_code_base+1) /* table of |number_chars| math mode mappings */
-# define int_base (math_code_base+1) /* beginning of region 5 */
-
-# define pretolerance_code 0 /* badness tolerance before hyphenation */
-# define tolerance_code 1 /* badness tolerance after hyphenation */
-# define line_penalty_code 2 /* added to the badness of every line */
-# define hyphen_penalty_code 3 /* penalty for break after discretionary hyphen */
-# define ex_hyphen_penalty_code 4 /* penalty for break after explicit hyphen */
-# define club_penalty_code 5 /* penalty for creating a club line */
-# define widow_penalty_code 6 /* penalty for creating a widow line */
-# define display_widow_penalty_code 7 /* ditto, just before a display */
-# define broken_penalty_code 8 /* penalty for breaking a page at a broken line */
-# define bin_op_penalty_code 9 /* penalty for breaking after a binary operation */
-# define rel_penalty_code 10 /* penalty for breaking after a relation */
-# define pre_display_penalty_code 11 /* penalty for breaking just before a displayed formula */
-# define post_display_penalty_code 12 /* penalty for breaking just after a displayed formula */
-# define inter_line_penalty_code 13 /* additional penalty between lines */
-# define double_hyphen_demerits_code 14 /* demerits for double hyphen break */
-# define final_hyphen_demerits_code 15 /* demerits for final hyphen break */
-# define adj_demerits_code 16 /* demerits for adjacent incompatible lines */
-# define mag_code 17 /* magnification ratio */
-# define delimiter_factor_code 18 /* ratio for variable-size delimiters */
-# define looseness_code 19 /* change in number of lines for a paragraph */
-# define time_code 20 /* current time of day */
-# define day_code 21 /* current day of the month */
-# define month_code 22 /* current month of the year */
-# define year_code 23 /* current year of our Lord */
-# define show_box_breadth_code 24 /* nodes per level in |show_box| */
-# define show_box_depth_code 25 /* maximum level in |show_box| */
-# define hbadness_code 26 /* hboxes exceeding this badness will be shown by |hpack| */
-# define vbadness_code 27 /* vboxes exceeding this badness will be shown by |vpack| */
-# define pausing_code 28 /* pause after each line is read from a file */
-# define tracing_online_code 29 /* show diagnostic output on terminal */
-# define tracing_macros_code 30 /* show macros as they are being expanded */
-# define tracing_stats_code 31 /* show memory usage if \TeX\ knows it */
-# define tracing_paragraphs_code 32 /* show line-break calculations */
-# define tracing_pages_code 33 /* show page-break calculations */
-# define tracing_output_code 34 /* show boxes when they are shipped out */
-# define tracing_lost_chars_code 35 /* show characters that aren't in the font */
-# define tracing_commands_code 36 /* show command codes at |big_switch| */
-# define tracing_restores_code 37 /* show equivalents when they are restored */
-# define uc_hyph_code 38 /* hyphenate words beginning with a capital letter */
-# define output_penalty_code 39 /* penalty found at current page break */
-# define max_dead_cycles_code 40 /* bound on consecutive dead cycles of output */
-# define hang_after_code 41 /* hanging indentation changes after this many lines */
-# define floating_penalty_code 42 /* penalty for insertions heldover after a split */
-# define global_defs_code 43 /* override \.{\\global} specifications */
-# define cur_fam_code 44 /* current family */
-# define escape_char_code 45 /* escape character for token output */
-# define default_hyphen_char_code 46 /* value of \.{\\hyphenchar} when a font is loaded */
-# define default_skew_char_code 47 /* value of \.{\\skewchar} when a font is loaded */
-# define end_line_char_code 48 /* character placed at the right end of the buffer */
-# define new_line_char_code 49 /* character that prints as |print_ln| */
-# define language_code 50 /* current hyphenation table */
-# define left_hyphen_min_code 51 /* minimum left hyphenation fragment size */
-# define right_hyphen_min_code 52 /* minimum right hyphenation fragment size */
-# define holding_inserts_code 53 /* do not remove insertion nodes from \.{\\box255} */
-# define error_context_lines_code 54 /* maximum intermediate line pairs shown */
-# define local_inter_line_penalty_code 55 /* local \.{\\interlinepenalty} */
-# define local_broken_penalty_code 56 /* local \.{\\brokenpenalty} */
-# define no_local_whatsits_code 57 /* counts local whatsits */
-# define no_local_dirs_code 58
-
-# define disable_lig_code 60
-# define disable_kern_code 61
-# define disable_space_code 62
-# define cat_code_table_code 63
-# define output_box_code 64
-# define cur_lang_code 65 /* current language id */
-# define ex_hyphen_char_code 66
-# define hyphenation_min_code 67 /* minimum word length */
-# define adjust_spacing_code 68 /* level of spacing adjusting */
-# define protrude_chars_code 69 /* protrude chars at left/right edge of paragraphs */
-# define output_mode_code 70 /* switch on PDF output if positive */
-# define draft_mode_code 71
-# define tracing_fonts_code 72
-# define tracing_assigns_code 73 /* show assignments */
-# define tracing_groups_code 74 /* show save/restore groups */
-# define tracing_ifs_code 75 /* show conditionals */
-# define tracing_scan_tokens_code 76 /* show pseudo file open and close */
-# define tracing_nesting_code 77 /* show incomplete groups and ifs within files */
-# define pre_display_direction_code 78 /* text direction preceding a display */
-# define last_line_fit_code 79 /* adjustment for last line of paragraph */
-# define saving_vdiscards_code 80 /* save items discarded from vlists */
-# define saving_hyph_codes_code 81 /* save hyphenation codes for languages */
-# define suppress_fontnotfound_error_code 82 /* suppress errors for missing fonts */
-# define suppress_long_error_code 83 /* suppress errors for missing fonts */
-# define suppress_ifcsname_error_code 84 /* suppress errors for failed \.{\\ifcsname} */
-# define suppress_outer_error_code 85 /* suppress errors for \.{\\outer} */
-# define suppress_mathpar_error_code 86 /* suppress errors for \.{\\par}} in math */
-# define math_eqno_gap_step_code 87 /* factor/1000 used for distance between eq and eqno */
-# define math_display_skip_mode_code 88
-# define math_scripts_mode_code 89
-# define math_nolimits_mode_code 90
-# define math_rules_mode_code 91
-# define math_rules_fam_code 92
-# define math_italics_mode_code 93
-# define synctex_code 94 /* is synctex file generation enabled ? */
-# define shape_mode_code 95
-# define first_valid_language_code 96
-# define hyphenation_bounds_code 97
-# define math_skip_mode_code 98
-# define math_pre_display_gap_factor_code 99
-# define hyphen_penalty_mode_code 100
-# define automatic_hyphen_penalty_code 101
-# define explicit_hyphen_penalty_code 102
-# define automatic_hyphen_mode_code 103
-# define compound_hyphen_mode_code 104
-# define break_after_dir_mode_code 105
-# define exception_penalty_code 106
-
-# define pre_bin_op_penalty_code 107
-# define pre_rel_penalty_code 108
-# define math_penalties_mode_code 109
-# define math_delimiters_mode_code 110
-# define math_script_box_mode_code 111
-# define math_script_char_mode_code 112
-# define math_rule_thickness_mode_code 113
-# define math_flatten_mode_code 114
-
-# define copy_lua_input_nodes_code 115
-# define suppress_primitive_error_code 116
-# define fixup_boxes_code 117
-# define glyph_dimensions_code 118
-
-# define math_option_code 119
-
-# define mathoption_int_base_code (math_option_code+1) /* one reserve */
-# define mathoption_int_last_code (mathoption_int_base_code+8)
-
-# define backend_int_base_code (mathoption_int_last_code+1)
-# define backend_int_last_code (backend_int_base_code+32) /* we need some 25 but take some slack */
-
-# define tex_int_pars (backend_int_last_code+1) /* total number of integer parameters */
-
-# define mathoption_int_base (int_base+mathoption_int_base_code)
-# define mathoption_int_last (int_base+mathoption_int_last_code)
-
-# define backend_int_base (int_base+backend_int_base_code)
-# define backend_int_last (int_base+backend_int_last_code)
-
-# define page_direction_code (tex_int_pars)
-# define body_direction_code (tex_int_pars+1)
-# define par_direction_code (tex_int_pars+2)
-# define text_direction_code (tex_int_pars+3)
-# define math_direction_code (tex_int_pars+4)
-# define line_direction_code (tex_int_pars+5) /* gets remapped so is no real register */
-
-# define int_pars (tex_int_pars+5) /* total number of integer parameters */
-
-# define dir_base (int_base+tex_int_pars)
-# define count_base (int_base+int_pars) /* |number_regs| user \.{\\count} registers */
-# define attribute_base (count_base+number_regs) /* |number_attrs| user \.{\\attribute} registers */
-# define del_code_base (attribute_base+number_attrs) /* |number_chars| delimiter code mappings */
-# define dimen_base (del_code_base+1) /* beginning of region 6 */
-
-# define par_indent_code 0 /* indentation of paragraphs */
-# define math_surround_code 1 /* space around math in text */
-# define line_skip_limit_code 2 /* threshold for |line_skip| instead of |baseline_skip| */
-# define hsize_code 3 /* line width in horizontal mode */
-# define vsize_code 4 /* page height in vertical mode */
-# define max_depth_code 5 /* maximum depth of boxes on main pages */
-# define split_max_depth_code 6 /* maximum depth of boxes on split pages */
-# define box_max_depth_code 7 /* maximum depth of explicit vboxes */
-# define hfuzz_code 8 /* tolerance for overfull hbox messages */
-# define vfuzz_code 9 /* tolerance for overfull vbox messages */
-# define delimiter_shortfall_code 10 /* maximum amount uncovered by variable delimiters */
-# define null_delimiter_space_code 11 /* blank space in null delimiters */
-# define script_space_code 12 /* extra space after subscript or superscript */
-# define pre_display_size_code 13 /* length of text preceding a display */
-# define display_width_code 14 /* length of line for displayed equation */
-# define display_indent_code 15 /* indentation of line for displayed equation */
-# define overfull_rule_code 16 /* width of rule that identifies overfull hboxes */
-# define hang_indent_code 17 /* amount of hanging indentation */
-# define h_offset_code 18 /* amount of horizontal offset when shipping pages out */
-# define v_offset_code 19 /* amount of vertical offset when shipping pages out */
-# define emergency_stretch_code 20 /* reduces badnesses on final pass of line-breaking */
-# define page_left_offset_code 21
-# define page_top_offset_code 22
-# define page_right_offset_code 23
-# define page_bottom_offset_code 24
-# define px_dimen_code 25
-# define page_width_code 26 /* page width of the output */
-# define page_height_code 27 /* page height of the output */
-
-# define backend_dimen_base (dimen_base+28)
-# define backend_dimen_last (dimen_base+37)
-
-# define dimen_pars (38) /* total number of dimension parameters */
-
-# define scaled_base (dimen_base+dimen_pars) /* table of |number_regs| user-defined \.{\\dimen} registers */
-# define eqtb_size (scaled_base+biggest_reg) /* largest subscript of |eqtb| */
-
-extern memory_word *eqtb;
-
-extern halfword eqtb_top; /* maximum of the |eqtb| */
-
-extern quarterword xeq_level[(eqtb_size + 1)];
-extern void initialize_equivalents(void);
-
-# define eq_level_field(A) (A).hh.b1
-# define eq_type_field(A) (A).hh.b0
-# define equiv_field(A) (A).hh.rh
-
-# define eq_level(A) eq_level_field(eqtb[(A)]) /* level of definition */
-# define eq_type(A) eq_type_field(eqtb[(A)]) /* command code for equivalent */
-# define equiv(A) equiv_field(eqtb[(A)]) /* equivalent value */
-
-# define set_eq_level(A,B) eq_level((A)) = (B)
-# define set_eq_type(A,B) eq_type((A)) = (B)
-# define set_equiv(A,B) equiv((A)) = (B)
-
-typedef struct save_record_ {
- quarterword type_;
- quarterword level_;
- memory_word word_;
-} save_record;
-
-extern save_record *save_stack;
-extern int save_ptr; /* first unused entry on |save_stack| */
-extern int max_save_stack; /* maximum usage of save stack */
-extern quarterword cur_level; /* current nesting level for groups */
-extern group_code cur_group; /* current group type */
-extern int cur_boundary; /* where the current level begins */
-
-# define save_type(A) save_stack[(A)].type_ /* classifies a |save_stack| entry */
-# define save_level(A) save_stack[(A)].level_ /* saved level for regions 5 and 6, or group code */
-# define save_value(A) save_stack[(A)].word_.cint /* |eqtb| location or token or |save_stack| location */
-# define save_word(A) save_stack[(A)].word_ /* |eqtb| entry */
-
-/*
-
-We use the notation |saved(k)| to stand for an item that appears in location
-|save_ptr+k| of the save stack.
-
-*/
-
-# define saved_type(A) save_stack[save_ptr+(A)].type_
-# define saved_level(A) save_stack[save_ptr+(A)].level_
-# define saved_value(A) save_stack[save_ptr+(A)].word_.cint
-
-# define set_saved_record(A,B,C,D) do { \
- saved_type(A) = (quarterword)(B); \
- saved_level(A) = (quarterword)(C); \
- saved_value(A) = (D); \
- } while (0)
-
-# define restore_old_value 0 /* |save_type| when a value should be restored later */
-# define restore_zero 1 /* |save_type| when an undefined entry should be restored */
-# define insert_token 2 /* |save_type| when a token is being saved for later use */
-# define level_boundary 3 /* |save_type| corresponding to beginning of group */
-# define saved_line 4
-# define saved_adjust 5
-# define saved_insert 6
-# define saved_disc 7
-# define saved_boxtype 8
-# define saved_textdir 9
-# define saved_eqno 10
-# define saved_choices 11
-# define saved_math 12
-# define saved_boxcontext 13
-# define saved_boxspec 14
-# define saved_boxdir 15
-# define saved_boxattr 16
-# define saved_boxpack 17
-# define saved_attrlist 18
-# define saved_eqtb 19
-
-extern void print_save_stack(void);
-
-# define int_par(A) eqtb[int_base+(A)].cint
-# define dimen_par(A) eqtb[dimen_base+(A)].cint
-# define loc_par(A) equiv(local_base+(A))
-# define glue_par(A) equiv(glue_base+(A))
-
-typedef enum {
- c_mathoption_old_code = 0, /* this one is stable */
- /*
- c_mathoption_umathcode_meaning_code,
- */
-} math_option_codes ;
-
-# define mathoption_int_par(A) eqtb[mathoption_int_base+(A)].cint
-
-/* if nonzero, this magnification should be used henceforth */
-
-extern int mag_set;
-extern void prepare_mag(void);
-
-/*
-
-@ Here are the group codes that are used to discriminate between different kinds
-of groups. They allow \TeX\ to decide what special actions, if any, should be
-performed when a group ends. \def\grp{\.{\char'173...\char'175}}
-
-Some groups are not supposed to be ended by right braces. For example, the `\.\$'
-that begins a math formula causes a |math_shift_group| to be started, and this
-should be terminated by a matching `\.\$'. Similarly, a group that starts with
-\.{\\left} should end with \.{\\right}, and one that starts with \.{\\begingroup}
-should end with \.{\\endgroup}.
-
-*/
-
-typedef enum {
- bottom_level = 0, /* group code for the outside world */
- simple_group, /* group code for local structure only */
- hbox_group, /* code for `\.{\\hbox}\grp' */
- adjusted_hbox_group, /* code for `\.{\\hbox}\grp' in vertical mode */
- vbox_group, /* code for `\.{\\vbox}\grp' */
- vtop_group, /* code for `\.{\\vtop}\grp' */
- align_group, /* code for `\.{\\halign}\grp', `\.{\\valign}\grp' */
- no_align_group, /* code for `\.{\\noalign}\grp' */
- output_group, /* code for output routine */
- math_group, /* code for, e.g., `\.{\char'136}\grp' */
- disc_group, /* code for `\.{\\discretionary}\grp\grp\grp' */
- insert_group, /* code for `\.{\\insert}\grp', `\.{\\vadjust}\grp' */
- vcenter_group, /* code for `\.{\\vcenter}\grp' */
- math_choice_group, /* code for `\.{\\mathchoice}\grp\grp\grp\grp' */
- semi_simple_group, /* code for `\.{\\begingroup...\\endgroup}' */
- math_shift_group, /* code for `\.{\$...\$}' */
- math_left_group, /* code for `\.{\\left...\\right}' */
- local_box_group, /* code for `\.{\\localleftbox...\\localrightbox}' */
- split_off_group, /* box code for the top part of a \.{\\vsplit} */
- split_keep_group, /* box code for the bottom part of a \.{\\vsplit} */
- preamble_group, /* box code for the preamble processing in an alignment */
- align_set_group, /* box code for the final item pass in an alignment */
- fin_row_group /* box code for a provisory line in an alignment */
-} tex_group_codes;
-
-typedef enum {
- new_graf_par_code = 0,
- local_box_par_code,
- hmode_par_par_code,
- penalty_par_code,
- math_par_code,
-} tex_par_codes ;
-
-typedef enum {
- display_style = 0, /* |subtype| for \.{\\displaystyle} */
- cramped_display_style, /* |subtype| for \.{\\crampeddisplaystyle} */
- text_style, /* |subtype| for \.{\\textstyle} */
- cramped_text_style, /* |subtype| for \.{\\crampedtextstyle} */
- script_style, /* |subtype| for \.{\\scriptstyle} */
- cramped_script_style, /* |subtype| for \.{\\crampedscriptstyle} */
- script_script_style, /* |subtype| for \.{\\scriptscriptstyle} */
- cramped_script_script_style, /* |subtype| for \.{\\crampedscriptscriptstyle} */
-} math_style_subtypes;
-
-typedef enum { /* this could move to directions.h */
- dir_TLT = 0,
- dir_TRT,
- dir_LTL,
- dir_RTT,
-} dir_codes;
-
-# define max_group_code local_box_group /* which is wrong, but is what the web says */
-
-extern int cur_cmd; /* current command set by |get_next| */
-extern halfword cur_chr; /* operand of current command */
-extern halfword cur_cs; /* control sequence found here, zero if none found */
-extern halfword cur_tok; /* packed representative of |cur_cmd| and |cur_chr| */
-
-extern void show_cur_cmd_chr(void);
-
-extern void new_save_level(group_code c); /* begin a new level of grouping */
-extern void eq_destroy(memory_word w); /* gets ready to forget |w| */
-extern void eq_save(halfword p, quarterword l); /* saves |eqtb[p]| */
-extern void eq_define(halfword p, quarterword t, halfword e); /* new data for |eqtb| */
-extern void eq_word_define(halfword p, int w);
-extern void geq_define(halfword p, quarterword t, halfword e); /* global |eq_define| */
-extern void geq_word_define(halfword p, int w); /* global |eq_word_define| */
-extern void save_for_after(halfword t);
-extern void unsave(void); /* pops the top level off the save stack */
-extern void show_save_groups(void);
-
-# define level_zero 0 /* level for undefined quantities */
-# define level_one 1 /* outermost level for defined quantities */
-
-extern void show_eqtb(halfword n);
-
-/* \csname \ifcsname */
-
-extern halfword last_cs_name;
-
-/*
- The *_par macros expand to the variables that are (in most cases) also accessible
- at the users end. Most are registers but some are in the (stack) lists.
-
- More *_par will move here : there is no real need for thse macros but because there
- were already a bunch and because they were defined all over the place we moved them
- here.
-
-*/
-
-#define space_skip_par glue_par(space_skip_code)
-#define xspace_skip_par glue_par(xspace_skip_code)
-#define math_skip_par glue_par(math_skip_code)
-#define math_skip_mode int_par(math_skip_mode_code)
-
-#define pre_display_size_par dimen_par(pre_display_size_code)
-#define display_width_par dimen_par(display_width_code)
-#define display_indent_par dimen_par(display_indent_code)
-#define math_surround_par dimen_par(math_surround_code)
-
-#define display_skip_mode_par int_par(math_display_skip_mode_code)
-#define math_eqno_gap_step_par int_par(math_eqno_gap_step_code)
-
-#define body_direction_par int_par(body_direction_code)
-#define page_direction_par int_par(page_direction_code)
-#define par_direction_par int_par(par_direction_code)
-#define text_direction_par int_par(text_direction_code)
-#define math_direction_par int_par(math_direction_code)
-
-#define shape_mode_par int_par(shape_mode_code)
-#define hyphenation_bounds_par int_par(hyphenation_bounds_code)
-#define first_valid_language_par int_par(first_valid_language_code)
-
-#define hsize_par dimen_par(hsize_code)
-#define vsize_par dimen_par(vsize_code)
-#define hfuzz_par dimen_par(hfuzz_code)
-#define vfuzz_par dimen_par(vfuzz_code)
-#define hbadness_par int_par(hbadness_code)
-#define vbadness_par int_par(vbadness_code)
-
-#define baseline_skip_par glue_par(baseline_skip_code)
-#define par_indent_par dimen_par(par_indent_code)
-#define hang_indent_par dimen_par(hang_indent_code)
-#define hang_after_par int_par(hang_after_code)
-#define left_skip_par glue_par(left_skip_code)
-#define right_skip_par glue_par(right_skip_code)
-
-#define emergency_stretch_par dimen_par(emergency_stretch_code)
-#define pretolerance_par int_par(pretolerance_code)
-#define tolerance_par int_par(tolerance_code)
-#define looseness_par int_par(looseness_code)
-#define adjust_spacing_par int_par(adjust_spacing_code)
-#define adj_demerits_par int_par(adj_demerits_code)
-#define protrude_chars_par int_par(protrude_chars_code)
-#define line_penalty_par int_par(line_penalty_code)
-#define last_line_fit_par int_par(last_line_fit_code)
-#define double_hyphen_demerits_par int_par(double_hyphen_demerits_code)
-#define final_hyphen_demerits_par int_par(final_hyphen_demerits_code)
-#define inter_line_penalty_par int_par(inter_line_penalty_code)
-#define club_penalty_par int_par(club_penalty_code)
-#define broken_penalty_par int_par(broken_penalty_code)
-#define display_widow_penalty_par int_par(display_widow_penalty_code)
-#define widow_penalty_par int_par(widow_penalty_code)
-#define line_skip_limit_par dimen_par(line_skip_limit_code)
-
-#define delimiter_shortfall_par dimen_par(delimiter_shortfall_code)
-#define null_delimiter_space_par dimen_par(null_delimiter_space_code)
-#define script_space_par dimen_par(script_space_code)
-#define max_depth_par dimen_par(max_depth_code)
-#define box_max_depth_par dimen_par(box_max_depth_code)
-#define split_max_depth_par dimen_par(split_max_depth_code)
-#define overfull_rule_par dimen_par(overfull_rule_code)
-#define box_max_depth_par dimen_par(box_max_depth_code)
-#define top_skip_par glue_par(top_skip_code)
-#define split_top_skip_par glue_par(split_top_skip_code)
-
-#define cur_fam_par int_par(cur_fam_code)
-#define pre_display_direction_par int_par(pre_display_direction_code)
-#define pre_display_penalty_par int_par(pre_display_penalty_code)
-#define post_display_penalty_par int_par(post_display_penalty_code)
-
-#define cur_fam_par_in_range ((cur_fam_par>=0)&&(cur_fam_par<256))
-
-#define local_inter_line_penalty_par int_par(local_inter_line_penalty_code)
-#define local_broken_penalty_par int_par(local_broken_penalty_code)
-#define local_left_box_par equiv(local_left_box_base)
-#define local_right_box_par equiv(local_right_box_base)
-
-#define end_line_char_par int_par(end_line_char_code)
-#define new_line_char_par int_par(new_line_char_code)
-#define escape_char_par int_par(escape_char_code)
-
-#define end_line_char_inactive ((end_line_char_par < 0) || (end_line_char_par > 127))
-
-#define delimiter_factor_par int_par(delimiter_factor_code)
-#define bin_op_penalty_par int_par(bin_op_penalty_code)
-#define rel_penalty_par int_par(rel_penalty_code)
-#define pre_bin_op_penalty_par int_par(pre_bin_op_penalty_code)
-#define pre_rel_penalty_par int_par(pre_rel_penalty_code)
-#define math_penalties_mode_par int_par(math_penalties_mode_code)
-#define math_delimiters_mode_par int_par(math_delimiters_mode_code)
-#define math_script_box_mode_par int_par(math_script_box_mode_code)
-#define math_script_char_mode_par int_par(math_script_char_mode_code)
-#define math_rule_thickness_mode_par int_par(math_rule_thickness_mode_code)
-#define math_flatten_mode_par int_par(math_flatten_mode_code)
-#define null_delimiter_space_par dimen_par(null_delimiter_space_code)
-#define disable_lig_par int_par(disable_lig_code)
-#define disable_kern_par int_par(disable_kern_code)
-#define disable_space_par int_par(disable_space_code)
-#define math_scripts_mode_par int_par(math_scripts_mode_code)
-#define math_nolimits_mode_par int_par(math_nolimits_mode_code)
-#define math_italics_mode_par int_par(math_italics_mode_code)
-#define math_rules_mode_par int_par(math_rules_mode_code)
-#define math_rules_fam_par int_par(math_rules_fam_code)
-
-#define thin_mu_skip_par glue_par(thin_mu_skip_code)
-#define med_mu_skip_par glue_par(med_mu_skip_code)
-#define thick_mu_skip_par glue_par(thick_mu_skip_code)
-
-#define every_math_par equiv(every_math_loc)
-#define every_display_par equiv(every_display_loc)
-#define every_cr_par equiv(every_cr_loc)
-#define every_hbox_par equiv(every_hbox_loc)
-#define every_vbox_par equiv(every_vbox_loc)
-#define every_eof_par equiv(every_eof_loc)
-#define every_par_par equiv(every_par_loc)
-#define err_help_par equiv(err_help_loc)
-
-#define no_local_whatsits_par int_par(no_local_whatsits_code)
-#define no_local_dirs_par int_par(no_local_dirs_code)
-
-#define prev_depth_par cur_list.prev_depth_field
-#define prev_graf_par cur_list.pg_field
-#define tail_par cur_list.tail_field
-#define head_par cur_list.head_field
-#define mode_par cur_list.mode_field
-#define dirs_par cur_list.dirs_field
-#define space_factor_par cur_list.space_factor_field
-#define incompleat_noad_par cur_list.incompleat_noad_field
-#define mode_line_par cur_list.ml_field
-#define aux_par cur_list.eTeX_aux_field
-#define delim_par aux_par
-
-#define par_shape_par_ptr equiv(par_shape_loc)
-#define inter_line_penalties_par_ptr equiv(inter_line_penalties_loc)
-#define club_penalties_par_ptr equiv(club_penalties_loc)
-#define widow_penalties_par_ptr equiv(widow_penalties_loc)
-#define display_widow_penalties_par_ptr equiv(display_widow_penalties_loc)
-
-#define page_width_par dimen_par(page_width_code)
-#define page_height_par dimen_par(page_height_code)
-#define h_offset_par dimen_par(h_offset_code)
-#define v_offset_par dimen_par(v_offset_code)
-#define page_left_offset_par dimen_par(page_left_offset_code)
-#define page_top_offset_par dimen_par(page_top_offset_code)
-#define page_right_offset_par dimen_par(page_right_offset_code)
-#define page_bottom_offset_par dimen_par(page_bottom_offset_code)
-#define px_dimen_par dimen_par(px_dimen_code)
-
-#define max_dead_cycles_par int_par(max_dead_cycles_code)
-#define output_box_par int_par(output_box_code)
-#define holding_inserts_par int_par(holding_inserts_code)
-#define output_routine_par equiv(output_routine_loc)
-#define floating_penalty_par int_par(floating_penalty_code)
-
-#define mag_par int_par(mag_code)
-
-#define global_defs_par int_par(global_defs_code)
-#define cat_code_table_par int_par(cat_code_table_code)
-#define saving_vdiscards_par int_par(saving_vdiscards_code)
-
-#define tracing_output_par int_par(tracing_output_code)
-#define tracing_stats_par int_par(tracing_stats_code)
-#define tracing_online_par int_par(tracing_online_code)
-#define tracing_paragraphs_par int_par(tracing_paragraphs_code)
-#define tracing_nesting_par int_par(tracing_nesting_code)
-#define tracing_lost_chars_par int_par(tracing_lost_chars_code)
-#define tracing_scan_tokens_par int_par(tracing_scan_tokens_code)
-#define tracing_ifs_par int_par(tracing_ifs_code)
-#define tracing_commands_par int_par(tracing_commands_code)
-#define tracing_macros_par int_par(tracing_macros_code)
-#define tracing_assigns_par int_par(tracing_assigns_code)
-#define tracing_fonts_par int_par(tracing_fonts_code)
-#define tracing_pages_par int_par(tracing_pages_code)
-#define tracing_restores_par int_par(tracing_restores_code)
-#define tracing_groups_par int_par(tracing_groups_code)
-
-#define show_box_depth_par int_par(show_box_depth_code)
-#define show_box_breadth_par int_par(show_box_breadth_code)
-
-#define pausing_par int_par(pausing_code)
-
-#define suppress_outer_error_par int_par(suppress_outer_error_code)
-#define suppress_long_error_par int_par(suppress_long_error_code)
-#define suppress_mathpar_error_par int_par(suppress_mathpar_error_code)
-#define suppress_fontnotfound_error_par int_par(suppress_fontnotfound_error_code)
-#define suppress_ifcsname_error_par int_par(suppress_ifcsname_error_code)
-#define suppress_primitive_error_par int_par(suppress_primitive_error_code)
-#define error_context_lines_par int_par(error_context_lines_code)
-#define copy_lua_input_nodes_par int_par(copy_lua_input_nodes_code)
-
-#define math_old_par mathoption_int_par(c_mathoption_old_code)
-
-/*
-#define math_umathcode_meaning_par mathoption_int_par(c_mathoption_umathcode_meaning_code)
-*/
-
-#define math_pre_display_gap_factor_par int_par(math_pre_display_gap_factor_code)
-
-#define time_par int_par(time_code)
-#define day_par int_par(day_code)
-#define month_par int_par(month_code)
-#define year_par int_par(year_code)
-
-#define output_mode_par int_par(output_mode_code)
-#define draft_mode_par int_par(draft_mode_code)
-#define synctex_par int_par(synctex_code)
-
-#define language_par int_par(language_code)
-#define uc_hyph_par int_par(uc_hyph_code)
-#define left_hyphen_min_par int_par(left_hyphen_min_code)
-#define right_hyphen_min_par int_par(right_hyphen_min_code)
-#define ex_hyphen_char_par int_par(ex_hyphen_char_code)
-#define hyphen_penalty_par int_par(hyphen_penalty_code)
-#define ex_hyphen_penalty_par int_par(ex_hyphen_penalty_code)
-#define default_hyphen_char_par int_par(default_hyphen_char_code)
-#define default_skew_char_par int_par(default_skew_char_code)
-#define saving_hyph_codes_par int_par(saving_hyph_codes_code)
-
-#define hyphen_penalty_mode_par int_par(hyphen_penalty_mode_code)
-#define automatic_hyphen_penalty_par int_par(automatic_hyphen_penalty_code)
-#define explicit_hyphen_penalty_par int_par(explicit_hyphen_penalty_code)
-#define automatic_hyphen_mode_par int_par(automatic_hyphen_mode_code)
-#define compound_hyphen_mode_par int_par(compound_hyphen_mode_code)
-#define break_after_dir_mode_par int_par(break_after_dir_mode_code)
-#define exception_penalty_par int_par(exception_penalty_code)
-
-#define cur_lang_par int_par(cur_lang_code)
-#define cur_font_par equiv(cur_font_loc)
-
-#define fixup_boxes_par int_par(fixup_boxes_code)
-#define glyph_dimensions_par int_par(glyph_dimensions_code)
-
-/* */
-
-#define math_use_current_family_code 7
-
-/*
- #define box(A) equiv(box_base+(A))
- #define box(A) eqtb[box_base+(A)].hh.rh
-*/
-
-#define attribute(A) equiv(attribute_base+(A))
-#define box(A) equiv(box_base+(A))
-#define count(A) equiv(count_base+(A))
-#define dimen(A) equiv(scaled_base+(A))
-#define mu_skip(A) equiv(mu_skip_base+(A))
-#define skip(A) equiv(skip_base+(A))
-#define toks(A) equiv(toks_base+(A))
-
-#define get_tex_attribute_register(j) attribute(j)
-#define get_tex_box_register(j) box(j)
-#define get_tex_count_register(j) count(j)
-#define get_tex_dimen_register(j) dimen(j)
-#define get_tex_mu_skip_register(j) mu_skip(j)
-#define get_tex_skip_register(j) skip(j)
-
-#define font_id_text(A) cs_text(font_id_base+(A))
-
-#define end_template_token (cs_token_flag+frozen_end_template)
-#define end_write_token (cs_token_flag+end_write)
-
-/* for now here */
-
-#define xspace_skip_subtype (xspace_skip_code + 1)
-#define space_skip_subtype (space_skip_code + 1)
-
-/*
-
-hyphen_penalty_mode_par automatic_disc (-) explicit_disc (\-)
----------------------------------------------------------------------------------
-0 (default) ex_hyphen_penalty_par ex_hyphen_penalty_par
-1 hyphen_penalty_par hyphen_penalty_par
-2 ex_hyphen_penalty_par hyphen_penalty_par
-3 hyphen_penalty_par ex_hyphen_penalty_par
-4 automatic_hyphen_penalty_par explicit_disc_penalty_par
-5 ex_hyphen_penalty_par explicit_disc_penalty_par
-6 hyphen_penalty_par explicit_disc_penalty_par
-7 automatic_hyphen_penalty_par ex_hyphen_penalty_par
-8 automatic_hyphen_penalty_par hyphen_penalty_par
-*/
-
-#define set_automatic_disc_penalty(n) \
- switch (hyphen_penalty_mode_par) { \
- case 0: \
- case 2: \
- case 5: \
- /* we take ex_hyphen_penalty */ \
- disc_penalty(n) = ex_hyphen_penalty_par; \
- break; \
- case 1: \
- case 3: \
- case 6: \
- /* we take hyphen_penalty */ \
- disc_penalty(n) = hyphen_penalty_par; \
- break; \
- case 4: \
- case 7: \
- case 8: \
- /* we take automatic_hyphen_penalty */ \
- disc_penalty(n) = automatic_hyphen_penalty_par; \
- break; \
- default: \
- /* what we've done since the beginning */ \
- disc_penalty(n) = ex_hyphen_penalty_par; \
- break; \
- }
-
-#define set_explicit_disc_penalty(n) \
- switch (hyphen_penalty_mode_par) { \
- case 0: \
- case 3: \
- case 7: \
- /* we take ex_hyphen_penalty */ \
- disc_penalty(n) = ex_hyphen_penalty_par; \
- break; \
- case 1: \
- case 2: \
- case 8: \
- /* we take hyphen_penalty */ \
- disc_penalty(n) = hyphen_penalty_par; \
- break; \
- case 4: \
- case 5: \
- case 6: \
- /* we take automatic_hyphen_penalty */ \
- disc_penalty(n) = explicit_hyphen_penalty_par; \
- break; \
- default: \
- /* what we've done since the beginning */ \
- disc_penalty(n) = ex_hyphen_penalty_par; \
- break; \
- }
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.c b/Build/source/texk/web2c/luatexdir/tex/errors.c
deleted file mode 100644
index ce80df99e7e..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/errors.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/*
-
-errors.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-#define edit_var "TEXEDIT"
-
-/*tex
-
-When something anomalous is detected, \TeX\ typically does something like this:
-$$\vbox{\halign{#\hfil\cr |print_err("Something anomalous has been
-detected");|\cr |help3("This is the first line of my offer to help.")|\cr |("This
-is the second line. I'm trying to")|\cr |("explain the best way for you to
-proceed.");|\cr |error;|\cr}}$$ A two-line help message would be given using
-|help2|, etc.; these informal helps should use simple vocabulary that complements
-the words used in the official error message that was printed. (Outside the
-U.S.A., the help messages should preferably be translated into the local
-vernacular. Each line of help is at most 60 characters long, in the present
-implementation, so that |max_print_line| will not be exceeded.)
-
-The |print_err| procedure supplies a `\.!' before the official message, and makes
-sure that the terminal is awake if a stop is going to occur. The |error|
-procedure supplies a `\..' after the official message, then it shows the location
-of the error; and if |interaction=error_stop_mode|, it also enters into a dialog
-with the user, during which time the help message may be printed. @^system
-dependencies@>
-
-*/
-
-/*tex The current level of interaction: */
-
-int interaction;
-
-/*tex Set from the command line: */
-
-int interactionoption;
-
-char *last_error = NULL;
-char *last_lua_error = NULL;
-char *last_warning_tag = NULL;
-char *last_warning_str = NULL;
-char *last_error_context = NULL;
-
-int err_old_setting = 0 ;
-int in_error = 0 ;
-
-void set_last_error_context(void)
-{
- str_number str;
- int sel = selector;
- int saved_new_line_char;
- int saved_new_string_line;
- selector = new_string;
- saved_new_line_char = new_line_char_par;
- saved_new_string_line = new_string_line;
- new_line_char_par = 10;
- new_string_line = 10;
- show_context();
- xfree(last_error_context);
- str = make_string();
- last_error_context = makecstring(str);
- flush_str(str);
- selector = sel;
- new_line_char_par = saved_new_line_char;
- new_string_line = saved_new_string_line;
- return;
-}
-
-void flush_err(void)
-{
- str_number s_error;
- char *s = NULL;
- int callback_id ;
- if (in_error) {
- selector = err_old_setting;
- str_room(1);
- s_error = make_string();
- s = makecstring(s_error);
- flush_str(s_error);
- if (interaction == error_stop_mode) {
- wake_up_terminal();
- }
- xfree(last_error);
- last_error = (string) xmalloc((unsigned) (strlen(s) + 1));
- strcpy(last_error,s);
- callback_id = callback_defined(show_error_message_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "->");
- } else {
- tprint(s);
- }
- in_error = 0 ;
- }
-}
-
-void print_err(const char *s)
-{
- int callback_id = callback_defined(show_error_message_callback);
- if (interaction == error_stop_mode) {
- wake_up_terminal();
- }
- if (callback_id > 0) {
- err_old_setting = selector;
- selector = new_string;
- in_error = 1 ;
- }
- if (filelineerrorstylep) {
- print_file_line();
- } else {
- tprint_nl("! ");
- }
- tprint(s);
- if (callback_id <= 0) {
- xfree(last_error);
- last_error = (string) xmalloc((unsigned) (strlen(s) + 1));
- strcpy(last_error,s);
- }
-}
-
-/*tex
-
-\TeX\ is careful not to call |error| when the print |selector| setting might be
-unusual. The only possible values of |selector| at the time of error messages are
-
-|no_print| (when |interaction=batch_mode| and |log_file| not yet open);
-
-|term_only| (when |interaction>batch_mode| and |log_file| not yet open);
-
-|log_only| (when |interaction=batch_mode| and |log_file| is open);
-
-|term_and_log| (when |interaction>batch_mode| and |log_file| is open).
-
-*/
-
-void fixup_selector(boolean logopened)
-{
- if (interaction == batch_mode)
- selector = no_print;
- else
- selector = term_only;
- if (logopened)
- selector = selector + 2;
-}
-
-/*tex
-
-A global variable |deletions_allowed| is set |false| if the |get_next| routine is
-active when |error| is called; this ensures that |get_next| and related routines
-like |get_token| will never be called recursively. A similar interlock is
-provided by |set_box_allowed|. @^recursion@>
-
-The global variable |history| records the worst level of error that has been
-detected. It has four possible values: |spotless|, |warning_issued|,
-|error_message_issued|, and |fatal_error_stop|.
-
-Another global variable, |error_count|, is increased by one when an |error|
-occurs without an interactive dialog, and it is reset to zero at the end of every
-paragraph. If |error_count| reaches 100, \TeX\ decides that there is no point in
-continuing further.
-
-*/
-
-/*tex Is it safe for |error| to call |get_token|? */
-
-boolean deletions_allowed;
-
-/*tex Is it safe to do a \.{\\setbox} assignment? */
-
-boolean set_box_allowed;
-/*tex Has the source input been clean so far? */
-
-int history;
-
-/*tex The number of scrolled errors since the last paragraph ended. */
-
-int error_count;
-
-/*tex Should \TeX\ pause for instructions? */
-
-int interrupt;
-
-/*tex Should interrupts be observed? */
-
-boolean OK_to_interrupt;
-
-/*tex
-
-The value of |history| is initially |fatal_error_stop|, but it will be changed to
-|spotless| if \TeX\ survives the initialization process.
-
-*/
-
-void initialize_errors(void)
-{
- if (interactionoption == unspecified_mode)
- interaction = error_stop_mode;
- else
- interaction = interactionoption;
- deletions_allowed = true;
- set_box_allowed = true;
- OK_to_interrupt = true;
-}
-
-/*tex
-
-It is possible for |error| to be called recursively if some error arises when
-|get_token| is being used to delete a token, and/or if some fatal error occurs
-while \TeX\ is trying to fix a non-fatal one. But such recursion @^recursion@> is
-never more than two levels deep.
-
-Individual lines of help are recorded in the array |help_line|.
-
-*/
-
-const char *help_line[7];
-
-/*tex
- Should the |err_help| list be shown?
-*/
-
-boolean use_err_help;
-
-/*tex
-
-The |jump_out| procedure just cuts across all active procedure levels and exits
-the program. It is used when there is no recovery from a particular error. The
-exit code can be overloaded.
-
-*/
-
-int defaultexitcode = 0;
-
-__attribute__ ((noreturn))
-void do_final_end(void)
-{
- update_terminal();
- ready_already = 0;
- lua_close(Luas);
- if ((history != spotless) && (history != warning_issued))
- uexit(1);
- else
- uexit(defaultexitcode);
-}
-
-__attribute__ ((noreturn))
-void jump_out(void)
-{
- close_files_and_terminate();
- do_final_end();
-}
-
-/*tex
-
-Here is the function that calls the editor, if one is defined. This is loosely
-based on a similar function in kpathsea, but the calling convention is quite
-different.
-
-*/
-
-static const_string edit_value = EDITOR;
-
-#if defined(WIN32)
-
-static int Isspace (char c)
-{
- return (c == ' ' || c == '\t');
-}
-
-#endif /* WIN32 */
-
-__attribute__ ((noreturn))
-static void luatex_calledit (int baseptr, int linenumber)
-{
- char *temp, *command;
- char *fullcmd = NULL; /* avoid compiler warning */
- char c;
- int sdone, ddone, i;
- char *filename = makecstring(input_stack[base_ptr].name_field);
- int fnlength = strlen(filename);
-#ifdef WIN32
- char *fp, *ffp, *env, editorname[256], buffer[256];
- int cnt = 0;
- int dontchange = 0;
-#endif
- sdone = ddone = 0;
- /*tex
- Close any open input files, since we're going to kill the job.
- */
- close_files_and_terminate();
- /*tex
- Replace the default with the value of the appropriate environment
- variable or config file value, if it's set.
- */
- temp = kpse_var_value (edit_var);
- if (temp != NULL)
- edit_value = temp;
- /*tex
- Construct the command string. The `11' is the maximum length an
- integer might be.
- */
- command = xmalloc (strlen (edit_value) + fnlength + 11);
- /*tex
- So we can construct it as we go.
- */
- temp = command;
-#ifdef WIN32
- fp = editorname;
- if ((isalpha(*edit_value) && *(edit_value + 1) == ':' && IS_DIR_SEP (*(edit_value + 2)))
- || (*edit_value == '"' && isalpha(*(edit_value + 1))
- && *(edit_value + 2) == ':' && IS_DIR_SEP (*(edit_value + 3)))) {
- dontchange = 1;
- }
-#endif
- while ((c = *edit_value++) != 0) {
- if (c == '%') {
- switch (c = *edit_value++) {
- case 'd':
- if (ddone)
- FATAL1 ("call_edit: `%%d' appears twice in editor command: `%s'", edit_value);
- sprintf (temp, "%ld", (long int)linenumber);
- while (*temp != '\0')
- temp++;
- ddone = 1;
- break;
- case 's':
- if (sdone)
- FATAL1 ("call_edit: `%%s' appears twice in editor command: `%s'", edit_value);
- for (i =0; i < fnlength; i++)
- *temp++ = filename[i];
- sdone = 1;
- break;
- case '\0':
- *temp++ = '%';
- /*tex
- Back up to the null to force termination.
- */
- edit_value--;
- break;
- default:
- *temp++ = '%';
- *temp++ = c;
- break;
- }
- } else {
-#ifdef WIN32
- if (dontchange) {
- *temp++ = c;
- } else if(Isspace(c) && cnt == 0) {
- cnt++;
- temp = command;
- *temp++ = c;
- *fp = '\0';
- } else if(!Isspace(c) && cnt == 0) {
- *fp++ = c;
- } else {
- *temp++ = c;
- }
-#else
- *temp++ = c;
-#endif
- }
- }
- *temp = 0;
-#ifdef WIN32
- if (dontchange == 0) {
- if(editorname[0] == '.' || editorname[0] == '/' || editorname[0] == '\\') {
- fprintf(stderr, "%s is not allowed to execute.\n", editorname);
- do_final_end();
- }
- env = (char *)getenv("PATH");
- if(SearchPath(env, editorname, ".exe", 256, buffer, &ffp)==0) {
- if(SearchPath(env, editorname, ".bat", 256, buffer, &ffp)==0) {
- fprintf(stderr, "I cannot find %s in the PATH.\n", editorname);
- do_final_end();
- }
- }
- fullcmd = (char *)xmalloc(strlen(buffer)+strlen(command)+5);
- strcpy(fullcmd, "\"");
- strcat(fullcmd, buffer);
- strcat(fullcmd, "\"");
- strcat(fullcmd, command);
- }
-#else
- fullcmd = command;
-#endif
- /*tex Execute the command. */
- if (system (fullcmd) != 0) {
- fprintf (stderr, "! Trouble executing `%s'.\n", command);
- }
- /*tex Quit, since we found an error. */
- do_final_end ();
-}
-
-/*tex
-
- This completes the job of error reporting.
-
-*/
-
-void error(void)
-{
- /*tex What the user types :*/
- ASCII_code c;
- int callback_id;
- /*tex Used to save global variables when deleting tokens: */
- int s1, s2, s3, s4;
- int i;
- flush_err();
- if (history < error_message_issued)
- history = error_message_issued;
- callback_id = callback_defined(show_error_hook_callback);
- if (callback_id > 0) {
- set_last_error_context();
- run_callback(callback_id, "->");
- } else {
- print_char('.');
- show_context();
- }
- if (haltonerrorp) {
- history = fatal_error_stop;
- jump_out();
- }
- if (interaction == error_stop_mode) {
- /*tex Get user's advice and |return|. */
- while (1) {
- CONTINUE:
- /*tex
- Original reports:
-
- https://tex.stackexchange.com/questions/551313/
- https://tug.org/pipermail/tex-live/2020-June/045876.html
-
- This will probably be fixed by DEK in the 2021 tuneup in a different
- way (so we'll have to remove or alter this change), but the interaction
- sequence in the reports above causes a segmentation fault in web2c -
- writing to the closed \write15 stream because we wrongly decrement
- selector from 16 to 15 in term_input, due to the lack of this check in
- recursive error() call.
- */
- if (interaction !=error_stop_mode)
- return;
- clear_for_error_prompt();
- prompt_input("? ");
- if (last == first)
- return;
- c = buffer[first];
- if (c >= 'a')
- c = c + 'A' - 'a';
- /*tex
- Interpret code |c| and |return| if done. It is desirable to
- provide an `\.E' option here that gives the user an easy way
- to return from \TeX\ to the system editor, with the offending
- line ready to be edited. But such an extension requires some
- system wizardry, so the present implementation simply types
- out the name of the file that should be edited and the
- relevant line number.
- */
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (deletions_allowed) {
- /*tex
- Delete |c-"0"| tokens and |goto continue|. We allow
- deletion of up to 99 tokens at a time.
- */
- s1 = cur_tok;
- s2 = cur_cmd;
- s3 = cur_chr;
- s4 = align_state;
- align_state = 1000000;
- OK_to_interrupt = false;
- if ((last > first + 1) && (buffer[first + 1] >= '0')
- && (buffer[first + 1] <= '9'))
- c = c * 10 + buffer[first + 1] - '0' * 11;
- else
- c = c - '0';
- while (c > 0) {
- /*tex One-level recursive call of |error| is possible. */
- get_token();
- decr(c);
- }
- cur_tok = s1;
- cur_cmd = s2;
- cur_chr = s3;
- align_state = s4;
- OK_to_interrupt = true;
- help2(
- "I have just deleted some text, as you asked.",
- "You can now delete more, or insert, or whatever."
- );
- show_context();
- goto CONTINUE;
- }
- break;
- case 'E':
- if (base_ptr > 0) {
- int callback_id = callback_defined(call_edit_callback);
- if (callback_id>0) {
- (void)run_callback(callback_id, "Sd->", makecstring(input_stack[base_ptr].name_field), line);
- /*tex This should not be reached. */
- jump_out();
- } else {
- tprint_nl("You want to edit file ");
- print(input_stack[base_ptr].name_field);
- tprint(" at line ");
- print_int(line);
- interaction = scroll_mode;
- if (kpse_init) {
- luatex_calledit(base_ptr, line);
- } else {
- /*tex This should not be reached. */
- tprint_nl("There is no valid callback defined.");
- jump_out();
- }
- }
- }
- break;
- case 'H':
- /*tex Print the help information and |goto continue| */
- if (use_err_help) {
- give_err_help();
- } else {
- if (help_line[0] == NULL) {
- help2(
- "Sorry, I don't know how to help in this situation.",
- "Maybe you should try asking a human?"
- );
- }
- i = 0;
- while (help_line[i] != NULL)
- tprint_nl(help_line[i++]);
- help4(
- "Sorry, I already gave what help I could...",
- "Maybe you should try asking a human?",
- "An error might have occurred before I noticed any problems.",
- "``If all else fails, read the instructions.''"
- );
- goto CONTINUE;
- }
- break;
- case 'I':
- /*tex
-
- Introduce new material from the terminal and |return|. When
- the following code is executed, |buffer[(first+1)..(last-1)]|
- may contain the material inserted by the user; otherwise
- another prompt will be given. In order to understand this
- part of the program fully, you need to be familiar with
- \TeX's input stacks.
-
- We enter a new syntactic level for terminal input:
-
- */
- begin_file_reading();
- /*tex
- Now |state=mid_line|, so an initial blank space will count as
- a blank.
- */
- if (last > first + 1) {
- iloc = first + 1;
- buffer[first] = ' ';
- } else {
- prompt_input("insert>");
- iloc = first;
- }
- first = last;
- /*tex No |end_line_char| ends this line. */
- ilimit = last - 1;
- return;
- break;
- case 'Q':
- case 'R':
- case 'S':
- /*tex
-
- Change the interaction level and |return|. Here the author of
- \TeX\ apologizes for making use of the numerical relation
- between |"Q"|, |"R"|, |"S"|, and the desired interaction
- settings |batch_mode|, |nonstop_mode|, |scroll_mode|.
-
- */
- error_count = 0;
- interaction = batch_mode + c - 'Q';
- tprint("OK, entering ");
- switch (c) {
- case 'Q':
- tprint_esc("batchmode");
- decr(selector);
- break;
- case 'R':
- tprint_esc("nonstopmode");
- break;
- case 'S':
- tprint_esc("scrollmode");
- break;
- }
- tprint("...");
- print_ln();
- update_terminal();
- return;
- break;
- case 'X':
- interaction = scroll_mode;
- jump_out();
- break;
- default:
- break;
- }
- if (!use_err_help) {
- /* Print the menu of available options */
- tprint("Type <return> to proceed, S to scroll future error messages,");
- tprint_nl("R to run without stopping, Q to run quietly,");
- tprint_nl("I to insert something, ");
- if (base_ptr > 0)
- tprint("E to edit your file,");
- if (deletions_allowed)
- tprint_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
- tprint_nl("H for help, X to quit.");
- }
- use_err_help = false;
- }
-
- }
- incr(error_count);
- if (error_count == 100) {
- tprint_nl("(That makes 100 errors; please try again.)");
- history = fatal_error_stop;
- jump_out();
- }
- /*tex Put help message on the transcript file. */
- if (interaction > batch_mode) {
- /*tex Avoid terminal output: */
- decr(selector);
- }
- if (use_err_help) {
- print_ln();
- give_err_help();
- } else {
- int i1 = 0;
- while (help_line[i1] != NULL)
- tprint_nl(help_line[i1++]);
- }
- print_ln();
- if (interaction > batch_mode) {
- /*tex Re-enable terminal output: */
- incr(selector);
- }
- print_ln();
-}
-
-/*tex
-
-A dozen or so error messages end with a parenthesized integer, so we save a teeny
-bit of program space by declaring the following procedure:
-
-*/
-
-void int_error(int n)
-{
- tprint(" (");
- print_int(n);
- print_char(')');
- error();
-}
-
-/*tex
-
-In anomalous cases, the print selector might be in an unknown state; the
-following subroutine is called to fix things just enough to keep running a bit
-longer.
-
-*/
-
-void normalize_selector(void)
-{
- if (log_opened_global)
- selector = term_and_log;
- else
- selector = term_only;
- if (job_name == 0)
- open_log_file();
- if (interaction == batch_mode)
- decr(selector);
-}
-
-/*tex
-
-The following procedure prints \TeX's last words before dying.
-
-*/
-
-void succumb(void)
-{
- if (interaction == error_stop_mode) {
- /*tex No more interaction: */
- interaction = scroll_mode;
- }
- if (log_opened_global) {
- error();
- }
- history = fatal_error_stop;
- /*tex Irrecoverable error: */
- jump_out();
-}
-
-/*tex
-
-This prints |s|, and that's it.
-
-*/
-
-void fatal_error(const char *s)
-{
- normalize_selector();
- print_err("Emergency stop");
- help1(s);
- succumb();
-}
-
-/*tex
-
-Here is the most dreaded error message. We stop due to finiteness.
-
-*/
-
-void overflow(const char *s, unsigned int n)
-{
- normalize_selector();
- print_err("TeX capacity exceeded, sorry [");
- tprint(s);
- print_char('=');
- print_int((int) n);
- print_char(']');
- if (varmem == NULL) {
- print_err("Sorry, I ran out of memory.");
- print_ln();
- exit(EXIT_FAILURE);
- }
- help2(
- "If you really absolutely need more capacity,",
- "you can ask a wizard to enlarge me."
- );
- succumb();
-}
-
-/*tex
-
-The program might sometime run completely amok, at which point there is no choice
-but to stop. If no previous error has been detected, that's bad news; a message
-is printed that is really intended for the \TeX\ maintenance person instead of
-the user (unless the user has been particularly diabolical). The index entries
-for `this can't happen' may help to pinpoint the problem. @^dry rot@>
-
-*/
-
-void confusion(const char *s)
-{ /* consistency check violated; |s| tells where */
- normalize_selector();
- if (history < error_message_issued) {
- print_err("This can't happen (");
- tprint(s);
- print_char(')');
- help1(
- "I'm broken. Please show this to someone who can fix"
- );
- } else {
- print_err("I can't go on meeting you like this");
- help2(
- "One of your faux pas seems to have wounded me deeply...",
- "in fact, I'm barely conscious. Please fix it and try again."
- );
- }
- succumb();
-}
-
-/*tex
-
-Users occasionally want to interrupt \TeX\ while it's running. If the runtime
-system allows this, one can implement a routine that sets the global variable
-|interrupt| to some nonzero value when such an interrupt is signalled. Otherwise
-there is probably at least a way to make |interrupt| nonzero using the debugger.
-@^system dependencies@> @^debugging@>
-
-*/
-
-void check_interrupt(void)
-{
- if (interrupt != 0)
- pause_for_instructions();
-}
-
-/*tex
-
-When an interrupt has been detected, the program goes into its highest
-interaction level and lets the user have nearly the full flexibility of the
-|error| routine. \TeX\ checks for interrupts only at times when it is safe to do
-this.
-
-*/
-
-void pause_for_instructions(void)
-{
- if (OK_to_interrupt) {
- interaction = error_stop_mode;
- if ((selector == log_only) || (selector == no_print))
- incr(selector);
- print_err("Interruption");
- help3(
- "You rang?",
- "Try to insert some instructions for me (e.g.,`I\\showlists'),",
- "unless you just want to quit by typing `X'."
- );
- deletions_allowed = false;
- error();
- deletions_allowed = true;
- interrupt = 0;
- }
-}
-
-void tex_error(const char *msg, const char **hlp)
-{
- print_err(msg);
- if (hlp != NULL) {
- int i;
- for (i = 0; (hlp[i] != NULL && i <= 5); i++) {
- help_line[i] = hlp[i];
- }
- help_line[i] = NULL;
- } else {
- help_line[0] = NULL;
- }
- error();
-}
-
-/*tex
-
-The |back_error| routine is used when we want to replace an offending token just
-before issuing an error message. This routine, like |back_input|, requires that
-|cur_tok| has been set. We disable interrupts during the call of |back_input| so
-that the help message won't be lost.
-
-*/
-
-void back_error(void)
-{
- OK_to_interrupt = false;
- back_input();
- OK_to_interrupt = true;
- error();
-}
-
-/*tex
-
- Back up one inserted token and call |error|.
-*/
-
-void ins_error(void)
-{
- OK_to_interrupt = false;
- back_input();
- token_type = inserted;
- OK_to_interrupt = true;
- error();
-}
-
-/*tex
-
-When \TeX\ wants to typeset a character that doesn't exist, the character node is
-not created; thus the output routine can assume that characters exist when it
-sees them. The following procedure prints a warning message unless the user has
-suppressed it.
-If |tracing_lost_chars_par| (i.e. \.{\\tracinglostchar}) is greater than 2,
-it's considered as an error.
-
-*/
-
-void char_warning(internal_font_number f, int c)
-{
- /*tex saved value of |tracing_online| */
- int old_setting;
- /* index to current digit; we assume that $0\L n<16^{22}$ */
- int k;
- if (tracing_lost_chars_par > 0) {
- old_setting = tracing_online_par;
- if (tracing_lost_chars_par > 1)
- tracing_online_par = 1;
- begin_diagnostic();
- tprint_nl("Missing character: There is no ");
- print(c);
- tprint(" (U+");
- k = 0;
- if (c < 16)
- print_char('0');
- if (c < 256)
- print_char('0');
- if (c < 4096)
- print_char('0');
- do {
- dig[k] = c % 16;
- c = c / 16;
- incr(k);
- } while (c != 0);
- print_the_digs((eight_bits) k);
- tprint(") in font ");
- print_font_name(f);
- print_char('!');
- end_diagnostic(false);
- tracing_online_par = old_setting;
- }
- if (tracing_lost_chars_par > 2) {
- error();
- }
-}
-
-void wrapup_backend(void) {
- ensure_output_state(static_pdf, ST_OMODE_FIX);
- if (output_mode_used == OMODE_NONE) {
- print_err(" ==> Fatal error occurred, no FMT file produced!");
- } else {
- backend_out_control[backend_control_finish_file](static_pdf,history == fatal_error_stop);
- }
-}
-
-void normal_error(const char *t, const char *p)
-{
- normalize_selector();
- if (interaction == error_stop_mode) {
- wake_up_terminal();
- }
- if (filelineerrorstylep) {
- print_file_line();
- } else {
- tprint_nl("! ");
- }
- tprint("error: ");
- if (cur_file_name) {
- tprint(" (file ");
- tprint(cur_file_name);
- tprint(")");
- }
- if (t != NULL) {
- tprint(" (");
- tprint(t);
- tprint(")");
- }
- tprint(": ");
- if (p != NULL)
- tprint(p);
- history = fatal_error_stop;
- wrapup_backend();
- exit(EXIT_FAILURE);
-}
-
-void normal_warning(const char *t, const char *p)
-{
- int report_id ;
- if (strcmp(t,"lua") == 0) {
- int saved_new_line_char;
- saved_new_line_char = new_line_char_par;
- new_line_char_par = 10;
- report_id = callback_defined(show_lua_error_hook_callback);
- if (report_id == 0) {
- if (p != NULL)
- tprint(p);
- help2(
- "The lua interpreter ran into a problem, so the",
- "remainder of this lua chunk will be ignored."
- );
- } else {
- (void) run_callback(report_id, "->");
- }
- error();
- new_line_char_par = saved_new_line_char;
- } else {
- report_id = callback_defined(show_warning_message_callback);
- if (report_id > 0) {
- /*tex Free the last ones, */
- xfree(last_warning_str);
- xfree(last_warning_tag);
- last_warning_str = (string) xmalloc(strlen(p) + 1);
- last_warning_tag = (string) xmalloc(strlen(t) + 1);
- strcpy(last_warning_str,p);
- strcpy(last_warning_tag,t);
- run_callback(report_id, "->");
- } else {
- print_ln();
- tprint("warning ");
- if (cur_file_name) {
- tprint(" (file ");
- tprint(cur_file_name);
- tprint(")");
- }
- if (t != NULL) {
- tprint(" (");
- tprint(t);
- tprint(")");
- }
- tprint(": ");
- if (p != NULL)
- tprint(p);
- print_ln();
- }
- if (history == spotless)
- history = warning_issued;
- }
-}
-
-static char print_buf[PRINTF_BUF_SIZE];
-
-__attribute__ ((format(printf, 2,3)))
-void formatted_error(const char *t, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- normal_error(t,print_buf);
- va_end(args);
-}
-
-__attribute__ ((format(printf, 2,3)))
-void formatted_warning(const char *t, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vsnprintf(print_buf, PRINTF_BUF_SIZE, fmt, args);
- normal_warning(t,print_buf);
- va_end(args);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/errors.h b/Build/source/texk/web2c/luatexdir/tex/errors.h
deleted file mode 100644
index 39fdf6b46e2..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/errors.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* errors.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef ERRORS_H
-# define ERRORS_H
-
-/*
-The global variable |interaction| has four settings, representing increasing
-amounts of user interaction:
-*/
-
-typedef enum {
- batch_mode = 0, /* omits all stops and omits terminal output */
- nonstop_mode = 1, /* omits all stops */
- scroll_mode = 2, /* omits error stops */
- error_stop_mode = 3, /* stops at every opportunity to interact */
- unspecified_mode = 4, /* extra value for command-line switch */
-} interaction_settings;
-
-extern int interaction; /* current level of interaction */
-extern int interactionoption; /* set from command line */
-
-extern int defaultexitcode; /* the exit code can be overloaded */
-
-extern void initialize_errors(void);
-
-extern char *last_error;
-extern char *last_lua_error;
-extern char *last_warning_tag;
-extern char *last_warning_str;
-extern char *last_error_context;
-
-extern void set_last_error_context(void);
-
-extern void print_err(const char *s);
-
-extern void fixup_selector(boolean log_opened);
-
-extern boolean deletions_allowed;
-extern boolean set_box_allowed;
-extern int history;
-extern int error_count;
-extern int interrupt;
-extern boolean OK_to_interrupt;
-
-typedef enum {
- spotless = 0, /* |history| value when nothing has been amiss yet */
- warning_issued = 1, /* |history| value when |begin_diagnostic| has been called */
- error_message_issued = 2, /* |history| value when |error| has been called */
- fatal_error_stop = 3, /* |history| value when termination was premature */
-} error_states;
-
-extern const char *help_line[7]; /* helps for the next |error| */
-extern boolean use_err_help; /* should the |err_help| list be shown? */
-
-/* these macros are just temporary, until everything is in C */
-
-# define hlp1(A) help_line[0]=A
-# define hlp2(A,B) help_line[1]=A; hlp1(B)
-# define hlp3(A,B,C) help_line[2]=A; hlp2(B,C)
-# define hlp4(A,B,C,D) help_line[3]=A; hlp3(B,C,D)
-# define hlp5(A,B,C,D,E) help_line[4]=A; hlp4(B,C,D,E)
-# define hlp6(A,B,C,D,E,F) help_line[5]=A; hlp5(B,C,D,E,F)
-
-# define help0() help_line[0]=NULL /* sometimes there might be no help */
-# define help1(A) do { help_line[1]=NULL; hlp1(A); } while (0)
-# define help2(A,B) do { help_line[2]=NULL; hlp2(B,A); } while (0)
-# define help3(A,B,C) do { help_line[3]=NULL; hlp3(C,B,A); } while (0)
-# define help4(A,B,C,D) do { help_line[4]=NULL; hlp4(D,C,B,A); } while (0)
-# define help5(A,B,C,D,E) do { help_line[5]=NULL; hlp5(E,D,C,B,A); } while (0)
-# define help6(A,B,C,D,E,F) do { help_line[6]=NULL; hlp6(F,E,D,C,B,A); } while (0)
-
-extern void do_final_end(void);
-extern void jump_out(void);
-extern void error(void);
-extern void int_error(int n);
-extern void normalize_selector(void);
-extern void succumb(void);
-extern void fatal_error(const char *s);
-extern void overflow(const char *s, unsigned int n);
-extern void confusion(const char *s);
-extern void check_interrupt(void);
-extern void pause_for_instructions(void);
-
-extern void tex_error(const char *msg, const char **hlp);
-extern void normal_error(const char *t, const char *p);
-extern void normal_warning(const char *t, const char *p);
-extern void formatted_error(const char *t, const char *fmt, ...);
-extern void formatted_warning(const char *t, const char *fmt, ...);
-
-extern void back_error(void);
-extern void ins_error(void);
-extern void flush_err(void);
-
-extern void char_warning(internal_font_number f, int c);
-
-extern void wrapup_backend(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.c b/Build/source/texk/web2c/luatexdir/tex/expand.c
deleted file mode 100644
index e85c8f3bdb6..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/expand.c
+++ /dev/null
@@ -1,967 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
- Only a dozen or so command codes |>max_command| can possibly be returned by
- |get_next|; in increasing order, they are |undefined_cs|, |expand_after|,
- |no_expand|, |input|, |if_test|, |fi_or_else|, |cs_name|, |convert|, |the|,
- |top_bot_mark|, |call|, |long_call|, |outer_call|, |long_outer_call|, and
- |end_template|.
-
- Sometimes, recursive calls to the following |expand| routine may cause
- exhaustion of the run-time calling stack, resulting in forced execution stops
- by the operating system. To diminish the chance of this happening, a counter
- is used to keep track of the recursion depth, in conjunction with a constant
- called |expand_depth|.
-
- Note that this does not catch all possible infinite recursion loops, just the
- ones that exhaust the application calling stack. The actual maximum value of
- |expand_depth| is outside of our control, but the initial setting of |100|
- should be enough to prevent problems.
-
-*/
-
-static int expand_depth_count = 0;
-
-/*tex
-
- The |expand| subroutine is used when |cur_cmd>max_command|. It removes a
- ``call'' or a conditional or one of the other special operations just listed.
- It follows that |expand| might invoke itself recursively. In all cases,
- |expand| destroys the current token, but it sets things up so that the next
- |get_next| will deliver the appropriate next token. The value of |cur_tok|
- need not be known when |expand| is called.
-
- Since several of the basic scanning routines communicate via global
- variables, their values are saved as local variables of |expand| so that
- recursive calls don't invalidate them.
-
-*/
-
-int is_in_csname = 0;
-
-void expand(void)
-{
- /*tex token that is being ``expanded after'' */
- halfword t;
- /*tex for list manipulation */
- halfword p;
- /*tex for a local token list pointer */
- halfword cur_ptr;
- /*tex to save the global quantity |cur_val| */
- int cv_backup;
- /*tex to save |cur_val_level|, etc. */
- int cvl_backup, radix_backup, co_backup;
- /*tex to save |link(backup_head)| */
- halfword backup_backup;
- /*tex temporary storage of |scanner_status| */
- int save_scanner_status;
- incr(expand_depth_count);
- if (expand_depth_count >= expand_depth)
- overflow("expansion depth", (unsigned) expand_depth);
- cv_backup = cur_val;
- cvl_backup = cur_val_level;
- radix_backup = radix;
- co_backup = cur_order;
- backup_backup = token_link(backup_head);
- RESWITCH:
- if (cur_cmd < call_cmd) {
- /*tex Expand a nonmacro. */
- if (tracing_commands_par > 1)
- show_cur_cmd_chr();
- switch (cur_cmd) {
- case top_bot_mark_cmd:
- /*tex Insert the appropriate mark text into the scanner. */
- t = cur_chr % marks_code;
- if (cur_chr >= marks_code)
- scan_mark_num();
- else
- cur_val = 0;
- switch (t) {
- case first_mark_code:
- cur_ptr = first_mark(cur_val);
- break;
- case bot_mark_code:
- cur_ptr = bot_mark(cur_val);
- break;
- case split_first_mark_code:
- cur_ptr = split_first_mark(cur_val);
- break;
- case split_bot_mark_code:
- cur_ptr = split_bot_mark(cur_val);
- break;
- default:
- cur_ptr = top_mark(cur_val);
- break;
- }
- if (cur_ptr != null)
- begin_token_list(cur_ptr, mark_text);
- break;
- case expand_after_cmd:
- if (cur_chr == 0) {
- /*tex
-
- Expand the token after the next token. It takes only a
- little shuffling to do what \TeX\ calls
- \.{\\expandafter}.
-
- */
- get_token();
- t = cur_tok;
- get_token();
- if (cur_cmd > max_command_cmd)
- expand();
- else
- back_input();
- cur_tok = t;
- back_input();
- } else {
- /*tex
-
- Negate a boolean conditional and |goto reswitch|. The
- result of a boolean condition is reversed when the
- conditional is preceded by \.{\\unless}.
-
- */
- get_token();
- if ((cur_cmd == if_test_cmd) && (cur_chr != if_case_code)) {
- cur_chr = cur_chr + unless_code;
- goto RESWITCH;
- }
- print_err("You can't use `\\unless' before `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- print_char('\'');
- help1("Continue, and I'll forget that it ever happened.");
- back_error();
- }
- break;
- case no_expand_cmd:
- if (cur_chr == 0) {
- /*tex
-
- Suppress expansion of the next token. The implementation
- of \.{\\noexpand} is a bit trickier, because it is
- necessary to insert a special `|dont_expand|' marker into
- \TeX's reading mechanism. This special marker is
- processed by |get_next|, but it does not slow down the
- inner loop.
-
- Since \.{\\outer} macros might arise here, we must also
- clear the |scanner_status| temporarily.
-
- */
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- t = cur_tok;
- back_input();
- /*tex Now |start| and |loc| point to the backed-up token |t|. */
- if (t >= cs_token_flag) {
- p = get_avail();
- set_token_info(p, cs_token_flag + frozen_dont_expand);
- set_token_link(p, iloc);
- istart = p;
- iloc = p;
- }
-
- } else {
- /*tex
-
- The \.{\\primitive} handling. If the primitive meaning of
- the next token is an expandable command, it suffices to
- replace the current token with the primitive one and
- restart |expand|.
-
- Otherwise, the token we just read has to be pushed back,
- as well as a token matching the internal form of
- \.{\\primitive}, that is sneaked in as an alternate form
- of |ignore_spaces|.
-
- An implementation problem surfaces: There really is no
- |cur_cs| attached to the inserted primitive command, so
- it is safer to set |cur_cs| to zero. |cur_tok| has a
- similar problem. And for the non-expanded branch, simply
- pushing back a token that matches the correct internal
- command does not work, because that approach would not
- survive roundtripping to a temporary file or even a token
- list.
-
- It would be smart to create |frozen_| versions of all the
- primitives. Then, this problem would not happen, at the
- expense of a few hundred extra control sequences.
-
- */
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- cur_cs = prim_lookup(cs_text(cur_cs));
- if (cur_cs != undefined_primitive) {
- t = get_prim_eq_type(cur_cs);
- if (t > max_command_cmd) {
- cur_cmd = t;
- cur_chr = get_prim_equiv(cur_cs);
- cur_tok = token_val(cur_cmd, cur_chr);
- cur_cs = 0;
- goto RESWITCH;
- } else {
- back_input();
- /*tex Now |loc| and |start| point to a one-item list. */
- p = get_avail();
- set_token_info(p, cs_token_flag + frozen_primitive);
- set_token_link(p, iloc);
- iloc = p;
- istart = p;
- }
- } else if (suppress_primitive_error_par == 0) {
- print_err("Missing primitive name");
- help2(
- "The control sequence marked <to be read again> does not",
- "represent any known primitive."
- );
- back_error();
- }
- }
- break;
- case cs_name_cmd:
- /*tex Manufacture a control sequence name. */
- if (cur_chr == 0) {
- manufacture_csname(0);
- } else if (cur_chr == 1) {
- inject_last_tested_cs();
- } else {
- manufacture_csname(1);
- }
- break;
- case convert_cmd:
- conv_toks();
- break;
- case the_cmd:
- ins_the_toks();
- break;
- case if_test_cmd:
- /*tex An experiment. */
- if (cur_chr == if_condition_code) {
- break;
- }
- /*tex End of experiment. */
- conditional();
- break;
- case fi_or_else_cmd:
- /*tex
-
- Terminate the current conditional and skip to \.{\\fi} The
- processing of conditionals is complete except for the
- following code, which is actually part of |expand|. It comes
- into play when \.{\\or}, \.{\\else}, or \.{\\fi} is scanned.
-
- */
- if (tracing_ifs_par > 0)
- if (tracing_commands_par <= 1)
- show_cur_cmd_chr();
- if (cur_chr > if_limit) {
- if (if_limit == if_code) {
- /*tex Condition is not yet evaluated. */
- insert_relax();
- } else {
- print_err("Extra ");
- print_cmd_chr(fi_or_else_cmd, cur_chr);
- help1("I'm ignoring this; it doesn't match any \\if.");
- error();
- }
- } else {
- while (cur_chr != fi_code) {
- /*tex Skip to \.{\\fi}. */
- pass_text();
- }
- pop_condition_stack();
- }
- break;
- case input_cmd:
- /*tex Initiate or terminate input from a file */
- if (cur_chr == 1)
- force_eof = true;
- else if (cur_chr == 2)
- pseudo_start();
- else if (cur_chr == 3) {
- pseudo_start();
- iname = 19;
- } else if (name_in_progress)
- insert_relax();
- else
- start_input();
- break;
- case lua_expandable_call_cmd:
- if (cur_chr <= 0) {
- normal_error("luacall", "invalid number");
- } else {
- str_number u = save_cur_string();
- luacstrings = 0;
- luafunctioncall(cur_chr);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
- break;
- case lua_local_call_cmd:
- if (cur_chr <= 0) {
- normal_error("luacall", "invalid number");
- } else {
- str_number u = save_cur_string();
- luacstrings = 0;
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, cur_chr);
- lua_call(Luas,0,0);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
- break;
- case variable_cmd:
- do_variable();
- break;
- case feedback_cmd:
- do_feedback();
- break;
- default:
- /*tex Complain about an undefined macro */
- print_err("Undefined control sequence");
- help5(
- "The control sequence at the end of the top line",
- "of your error message was never \\def'ed. If you have",
- "misspelled it (e.g., `\\hobx'), type `I' and the correct",
- "spelling (e.g., `I\\hbox'). Otherwise just continue,",
- "and I'll forget about whatever was undefined."
- );
- error();
- break;
- }
- } else if (cur_cmd < end_template_cmd) {
- macro_call();
- } else {
- /*tex
-
- Insert a token containing |frozen_endv|. An |end_template| command is
- effectively changed to an |endv| command by the following code. (The
- reason for this is discussed below; the |frozen_end_template| at the
- end of the template has passed the |check_outer_validity| test, so
- its mission of error detection has been accomplished.)
-
- */
- cur_tok = cs_token_flag + frozen_endv;
- back_input();
- }
- cur_val = cv_backup;
- cur_val_level = cvl_backup;
- radix = radix_backup;
- cur_order = co_backup;
- set_token_link(backup_head, backup_backup);
- decr(expand_depth_count);
-}
-
-void complain_missing_csname(void)
-{
- print_err("Missing \\endcsname inserted");
- help2(
- "The control sequence marked <to be read again> should",
- "not appear between \\csname and \\endcsname."
- );
- back_error();
-}
-
-void manufacture_csname(boolean use)
-{
- halfword p, q, r;
- lstring *ss;
- r = get_avail();
- p = r;
- is_in_csname += 1;
- do {
- get_x_token();
- if (cur_cs == 0)
- store_new_token(cur_tok);
- } while (cur_cs == 0);
- if (cur_cmd != end_cs_name_cmd) {
- /*tex Complain about missing \.{\\endcsname}. */
- complain_missing_csname();
- }
- /*tex Look up the characters of list |r| in the hash table, and set |cur_cs|. */
- ss = tokenlist_to_lstring(r, true);
- is_in_csname -= 1;
- if (use) {
- if (ss->l > 0) {
- cur_cs = string_lookup((char *) ss->s, ss->l);
- } else {
- cur_cs = null_cs;
- }
- last_cs_name = cur_cs ;
- free_lstring(ss);
- flush_list(r);
- if (cur_cs == null_cs) {
- /*tex skip */
- } else if (eq_type(cur_cs) == undefined_cs_cmd) {
- /*tex skip */
- } else {
- cur_tok = cur_cs + cs_token_flag;
- back_input();
- }
- } else {
- if (ss->l > 0) {
- no_new_control_sequence = false;
- cur_cs = string_lookup((char *) ss->s, ss->l);
- no_new_control_sequence = true;
- } else {
- /*tex the list is empty */
- cur_cs = null_cs;
- }
- last_cs_name = cur_cs ;
- free_lstring(ss);
- flush_list(r);
- if (eq_type(cur_cs) == undefined_cs_cmd) {
- /*tex The |save_stack| might change! */
- eq_define(cur_cs, relax_cmd, too_big_char);
- };
- /*tex The control sequence will now match \.{\\relax} */
- cur_tok = cur_cs + cs_token_flag;
- back_input();
- }
-}
-
-void inject_last_tested_cs(void)
-{
- if (last_cs_name != null_cs) {
- cur_cs = last_cs_name;
- cur_tok = last_cs_name + cs_token_flag;
- back_input();
- }
-}
-
-/*tex
-
- Sometimes the expansion looks too far ahead, so we want to insert a harmless
- \.{\\relax} into the user's input.
-
-*/
-
-void insert_relax(void)
-{
- cur_tok = cs_token_flag + cur_cs;
- back_input();
- cur_tok = cs_token_flag + frozen_relax;
- back_input();
- token_type = inserted;
-}
-
-
-/*tex
-
- Here is a recursive procedure that is \TeX's usual way to get the next token
- of input. It has been slightly optimized to take account of common cases.
-
-*/
-
-void get_x_token(void)
-{
- /*tex This code sets |cur_cmd|, |cur_chr|, |cur_tok|, and expands macros. */
- RESTART:
- get_next();
- if (cur_cmd <= max_command_cmd)
- goto DONE;
- if (cur_cmd >= call_cmd) {
- if (cur_cmd < end_template_cmd) {
- macro_call();
- } else {
- cur_cs = frozen_endv;
- cur_cmd = endv_cmd;
- /*tex Now |cur_chr=null_list|. */
- goto DONE;
- }
- } else {
- expand();
- }
- goto RESTART;
- DONE:
- if (cur_cs == 0)
- cur_tok = token_val(cur_cmd, cur_chr);
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-
-/*tex
-
- The |get_x_token| procedure is equivalent to two consecutive procedure calls:
- |get_next; x_token|. It's |get_x_token| without the initial |get_next|.
-
-*/
-
-void x_token(void)
-{
- while (cur_cmd > max_command_cmd) {
- expand();
- get_next();
- }
- if (cur_cs == 0)
- cur_tok = token_val(cur_cmd, cur_chr);
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-
-/*tex
-
- A control sequence that has been \.{\\def}'ed by the user is expanded by
- \TeX's |macro_call| procedure.
-
- Before we get into the details of |macro_call|, however, let's consider the
- treatment of primitives like \.{\\topmark}, since they are essentially macros
- without parameters. The token lists for such marks are kept in five global
- arrays of pointers; we refer to the individual entries of these arrays by
- symbolic macros |top_mark|, etc. The value of |top_mark(x)|, etc. is either
- |null| or a pointer to the reference count of a token list.
-
- The variable |biggest_used_mark| is an aid to try and keep the code somehwat
- efficient without too much extra work: it registers the highest mark class
- ever instantiated by the user, so the loops in |fire_up| and |vsplit| do not
- have to traverse the full range |0..biggest_mark|.
-
-*/
-
-halfword top_marks_array[(biggest_mark + 1)];
-halfword first_marks_array[(biggest_mark + 1)];
-halfword bot_marks_array[(biggest_mark + 1)];
-halfword split_first_marks_array[(biggest_mark + 1)];
-halfword split_bot_marks_array[(biggest_mark + 1)];
-halfword biggest_used_mark;
-
-void initialize_marks(void)
-{
- int i;
- biggest_used_mark = 0;
- for (i = 0; i <= biggest_mark; i++) {
- top_mark(i) = null;
- first_mark(i) = null;
- bot_mark(i) = null;
- split_first_mark(i) = null;
- split_bot_mark(i) = null;
- }
-}
-
-/*tex
-
- Now let's consider |macro_call| itself, which is invoked when \TeX\ is
- scanning a control sequence whose |cur_cmd| is either |call|, |long_call|,
- |outer_call|, or |long_outer_call|. The control sequence definition appears
- in the token list whose reference count is in location |cur_chr| of |mem|.
-
- The global variable |long_state| will be set to |call| or to |long_call|,
- depending on whether or not the control sequence disallows \.{\\par} in its
- parameters. The |get_next| routine will set |long_state| to |outer_call| and
- emit \.{\\par}, if a file ends or if an \.{\\outer} control sequence occurs
- in the midst of an argument.
-
-*/
-
-/*tex Governs the acceptance of \.{\\par}: */
-
-int long_state;
-
-/*tex
-
- The parameters, if any, must be scanned before the macro is expanded.
- Parameters are token lists without reference counts. They are placed on an
- auxiliary stack called |pstack| while they are being scanned, since the
- |param_stack| may be losing entries during the matching process. (Note that
- |param_stack| can't be gaining entries, since |macro_call| is the only
- routine that puts anything onto |param_stack|, and it is not recursive.)
-
-*/
-
-/*tex The arguments supplied to a macro: */
-
-halfword pstack[9];
-
-/*tex
-
- After parameter scanning is complete, the parameters are moved to the
- |param_stack|. Then the macro body is fed to the scanner; in other words,
- |macro_call| places the defined text of the control sequence at the top of\/
- \TeX's input stack, so that |get_next| will proceed to read it next.
-
- The global variable |cur_cs| contains the |eqtb| address of the control
- sequence being expanded, when |macro_call| begins. If this control sequence
- has not been declared \.{\\long}, i.e., if its command code in the |eq_type|
- field is not |long_call| or |long_outer_call|, its parameters are not allowed
- to contain the control sequence \.{\\par}. If an illegal \.{\\par} appears,
- the macro call is aborted, and the \.{\\par} will be rescanned.
-
-*/
-
-/*tex This invokes a user-defined control sequence. */
-
-void macro_call(void)
-{
- /*tex current node in the macro's token list */
- halfword r;
- /*tex current node in parameter token list being built */
- halfword p = null;
- /*tex new node being put into the token list */
- halfword q;
- /*tex backup pointer for parameter matching */
- halfword s;
- /*tex cycle pointer for backup recovery */
- halfword t;
- /*tex auxiliary pointers for backup recovery */
- halfword u, v;
- /*tex one step before the last |right_brace| token */
- halfword rbrace_ptr = null;
- /*tex the number of parameters scanned */
- int n = 0;
- /*tex unmatched left braces in current parameter */
- halfword unbalance;
- /*tex the number of tokens or groups (usually) */
- halfword m = 0;
- /*tex start of the token list */
- halfword ref_count;
- /*tex |scanner_status| upon entry */
- int save_scanner_status = scanner_status;
- /*tex |warning_index| upon entry */
- halfword save_warning_index = warning_index;
- /*tex character used in parameter */
- int match_chr = 0;
- warning_index = cur_cs;
- ref_count = cur_chr;
- r = token_link(ref_count);
- if (tracing_macros_par > 0) {
- /*tex Show the text of the macro being expanded. */
- begin_diagnostic();
- print_input_level();
- // print_ln();
- print_cs(warning_index);
- token_show(ref_count);
- end_diagnostic(false);
- }
- if (token_info(r) == protected_token)
- r = token_link(r);
- if (token_info(r) != end_match_token) {
- /*tex
-
- Scan the parameters and make |link(r)| point to the macro body; but
- |return| if an illegal \.{\\par} is detected.
-
- At this point, the reader will find it advisable to review the
- explanation of token list format that was presented earlier, since
- many aspects of that format are of importance chiefly in the
- |macro_call| routine.
-
- The token list might begin with a string of compulsory tokens before
- the first |match| or |end_match|. In that case the macro name is
- supposed to be followed by those tokens; the following program will
- set |s=null| to represent this restriction. Otherwise |s| will be set
- to the first token of a string that will delimit the next parameter.
-
- */
- scanner_status = matching;
- unbalance = 0;
- long_state = eq_type(cur_cs);
- if (long_state >= outer_call_cmd)
- long_state = long_state - 2;
- do {
- set_token_link(temp_token_head, null);
- if ((token_info(r) >= end_match_token)
- || (token_info(r) < match_token)) {
- s = null;
- } else {
- match_chr = token_info(r) - match_token;
- s = token_link(r);
- r = s;
- p = temp_token_head;
- m = 0;
- }
- /*tex
-
- Scan a parameter until its delimiter string has been found; or,
- if |s=null|, simply scan the delimiter string.
-
- If |info(r)| is a |match| or |end_match| command, it cannot be
- equal to any token found by |get_token|. Therefore an undelimited
- parameter---i.e., a |match| that is immediately followed by
- |match| or |end_match|---will always fail the test
- `|cur_tok=info(r)|' in the following algorithm.
-
- */
- CONTINUE:
- /*tex Set |cur_tok| to the next token of input: */
- get_token();
- if (cur_tok == token_info(r)) {
- /*tex
-
- Advance |r|; |goto found| if the parameter delimiter has been
- fully matched, otherwise |goto continue|.
-
- A slightly subtle point arises here: When the parameter
- delimiter ends with `\.{\#\{}', the token list will have a
- left brace both before and after the |end_match|\kern-.4pt.
- Only one of these should affect the |align_state|, but both
- will be scanned, so we must make a correction.
-
- */
- r = token_link(r);
- if ((token_info(r) >= match_token)
- && (token_info(r) <= end_match_token)) {
- if (cur_tok < left_brace_limit)
- decr(align_state);
- goto FOUND;
- } else {
- goto CONTINUE;
- }
-
- }
- /*tex
-
- Contribute the recently matched tokens to the current parameter,
- and |goto continue| if a partial match is still in effect; but
- abort if |s=null|.
-
- When the following code becomes active, we have matched tokens
- from |s| to the predecessor of |r|, and we have found that
- |cur_tok<>info(r)|. An interesting situation now presents itself:
- If the parameter is to be delimited by a string such as `\.{ab}',
- and if we have scanned `\.{aa}', we want to contribute one `\.a'
- to the current parameter and resume looking for a `\.b'. The
- program must account for such partial matches and for others that
- can be quite complex. But most of the time we have |s=r| and
- nothing needs to be done.
-
- Incidentally, it is possible for \.{\\par} tokens to sneak in to
- certain parameters of non-\.{\\long} macros. For example,
- consider a case like `\.{\\def\\a\#1\\par!\{...\}}' where the
- first \.{\\par} is not followed by an exclamation point. In such
- situations it does not seem appropriate to prohibit the
- \.{\\par}, so \TeX\ keeps quiet about this bending of the rules.
-
- */
- if (s != r) {
- if (s == null) {
- /*tex Report an improper use of the macro and abort. */
- print_err("Use of ");
- sprint_cs(warning_index);
- tprint(" doesn't match its definition");
- help4(
- "If you say, e.g., `\\def\\a1{...}', then you must always",
- "put `1' after `\\a', since control sequence names are",
- "made up of letters only. The macro here has not been",
- "followed by the required stuff, so I'm ignoring it."
- );
- error();
- goto EXIT;
-
- } else {
- t = s;
- do {
- store_new_token(token_info(t));
- incr(m);
- u = token_link(t);
- v = s;
- while (1) {
- if (u == r) {
- if (cur_tok != token_info(v)) {
- goto DONE;
- } else {
- r = token_link(v);
- goto CONTINUE;
- }
- }
- if (token_info(u) != token_info(v))
- goto DONE;
- u = token_link(u);
- v = token_link(v);
- }
- DONE:
- t = token_link(t);
- } while (t != r);
- r = s;
- /*tex At this point, no tokens are recently matched. */
- }
- }
- if (cur_tok == par_token)
- if (long_state != long_call_cmd)
- if (!suppress_long_error_par) {
- goto RUNAWAY;
- }
- if (cur_tok < right_brace_limit) {
- if (cur_tok < left_brace_limit) {
- /*tex Contribute an entire group to the current parameter. */
- unbalance = 1;
- while (1) {
- fast_store_new_token(cur_tok);
- get_token();
- if (cur_tok == par_token) {
- if (long_state != long_call_cmd) {
- if (!suppress_long_error_par) {
- goto RUNAWAY;
-
- }
- }
- }
- if (cur_tok < right_brace_limit) {
- if (cur_tok < left_brace_limit) {
- incr(unbalance);
- } else {
- decr(unbalance);
- if (unbalance == 0)
- break;
- }
- }
- }
- rbrace_ptr = p;
- store_new_token(cur_tok);
- } else {
- /*tex Report an extra right brace and |goto continue|. */
- back_input();
- print_err("Argument of ");
- sprint_cs(warning_index);
- tprint(" has an extra }");
- help6(
- "I've run across a `}' that doesn't seem to match anything.",
- "For example, `\\def\\a#1{...}' and `\\a}' would produce",
- "this error. If you simply proceed now, the `\\par' that",
- "I've just inserted will cause me to report a runaway",
- "argument that might be the root of the problem. But if",
- "your `}' was spurious, just type `2' and it will go away."
- );
- incr(align_state);
- long_state = call_cmd;
- cur_tok = par_token;
- ins_error();
- goto CONTINUE;
- /*tex A white lie; the \.{\\par} won't always trigger a runaway. */
- }
- } else {
- /*tex
-
- Store the current token, but |goto continue| if it is a blank
- space that would become an undelimited parameter.
-
- */
- if (cur_tok == space_token && token_info(r) <= end_match_token && token_info(r) >= match_token)
- goto CONTINUE;
- store_new_token(cur_tok);
- }
- incr(m);
- if (token_info(r) > end_match_token)
- goto CONTINUE;
- if (token_info(r) < match_token)
- goto CONTINUE;
- FOUND:
- if (s != null) {
- /*
-
- Tidy up the parameter just scanned, and tuck it away. If the
- parameter consists of a single group enclosed in braces, we
- must strip off the enclosing braces. That's why |rbrace_ptr|
- was introduced.
-
- */
- if ((m == 1) && (token_info(p) < right_brace_limit)
- && (p != temp_token_head)) {
- set_token_link(rbrace_ptr, null);
- free_avail(p);
- p = token_link(temp_token_head);
- pstack[n] = token_link(p);
- free_avail(p);
- } else {
- pstack[n] = token_link(temp_token_head);
- }
- incr(n);
- if (tracing_macros_par > 0) {
- begin_diagnostic();
- print_input_level();
- // print_nl(match_chr);
- print(match_chr);
- print_int(n);
- tprint("<-");
- show_token_list(pstack[n - 1], null, 1000);
- end_diagnostic(false);
- }
- }
- /*tex
-
- Now |info(r)| is a token whose command code is either |match| or
- |end_match|.
-
- */
- } while (token_info(r) != end_match_token);
- }
- /*tex
-
- Feed the macro body and its parameters to the scanner Before we put a new
- token list on the input stack, it is wise to clean off all token lists
- that have recently been depleted. Then a user macro that ends with a call
- to itself will not require unbounded stack space.
-
- */
- while ((istate == token_list) && (iloc == null) && (token_type != v_template)) {
- /*tex Conserve stack space. */
- end_token_list();
- }
- begin_token_list(ref_count, macro);
- iname = warning_index;
- iloc = token_link(r);
- if (n > 0) {
- if (param_ptr + n > max_param_stack) {
- max_param_stack = param_ptr + n;
- if (max_param_stack > param_size)
- overflow("parameter stack size", (unsigned) param_size);
- }
- for (m = 0; m <= n - 1; m++)
- param_stack[param_ptr + m] = pstack[m];
- param_ptr = param_ptr + n;
- }
- goto EXIT;
- RUNAWAY:
- /*tex
-
- Report a runaway argument and abort. If |long_state=outer_call|, a
- runaway argument has already been reported.
-
- */
- if (long_state == call_cmd) {
- runaway();
- print_err("Paragraph ended before ");
- sprint_cs(warning_index);
- tprint(" was complete");
- help3(
- "I suspect you've forgotten a `}', causing me to apply this",
- "control sequence to too much text. How can we recover?",
- "My plan is to forget the whole thing and hope for the best."
- );
- back_error();
- }
- pstack[n] = token_link(temp_token_head);
- align_state = align_state - unbalance;
- for (m = 0; m <= n; m++)
- flush_list(pstack[m]);
- EXIT:
- scanner_status = save_scanner_status;
- warning_index = save_warning_index;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/expand.h b/Build/source/texk/web2c/luatexdir/tex/expand.h
deleted file mode 100644
index 18c0514e317..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/expand.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* expand.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef EXPAND_H
-# define EXPAND_H
-
-extern boolean is_in_csname;
-extern void expand(void);
-extern void complain_missing_csname(void);
-extern void manufacture_csname(boolean use);
-extern void inject_last_tested_cs(void);
-extern void insert_relax(void);
-extern void get_x_token(void);
-extern void x_token(void);
-
-# define top_mark_code 0 /* the mark in effect at the previous page break */
-# define first_mark_code 1 /* the first mark between |top_mark| and |bot_mark| */
-# define bot_mark_code 2 /* the mark in effect at the current page break */
-# define split_first_mark_code 3
- /* the first mark found by \.{\\vsplit} */
-# define split_bot_mark_code 4 /* the last mark found by \.{\\vsplit} */
-# define marks_code 5
-
-# define top_mark(A) top_marks_array[(A)]
-# define first_mark(A) first_marks_array[(A)]
-# define bot_mark(A) bot_marks_array[(A)]
-# define split_first_mark(A) split_first_marks_array[(A)]
-# define split_bot_mark(A) split_bot_marks_array[(A)]
-
-# define set_top_mark(A,B) top_mark(A)=(B)
-# define set_first_mark(A,B) first_mark(A)=(B)
-# define set_bot_mark(A,B) bot_mark(A)=(B)
-# define set_split_first_mark(A,B) split_first_mark(A)=(B)
-# define set_split_bot_mark(A,B) split_bot_mark(A)=(B)
-
-# define delete_top_mark(A) do { \
- if (top_mark(A)!=null) \
- delete_token_ref(top_mark(A)); \
- top_mark(A)=null; \
- } while (0)
-
-# define delete_bot_mark(A) do { \
- if (bot_mark(A)!=null) \
- delete_token_ref(bot_mark(A)); \
- bot_mark(A)=null; \
- } while (0)
-
-# define delete_first_mark(A) do { \
- if (first_mark(A)!=null) \
- delete_token_ref(first_mark(A)); \
- first_mark(A)=null; \
- } while (0)
-
-# define delete_split_first_mark(A) do { \
- if (split_first_mark(A)!=null) \
- delete_token_ref(split_first_mark(A)); \
- split_first_mark(A)=null; \
- } while (0)
-
-# define delete_split_bot_mark(A) do { \
- if (split_bot_mark(A)!=null) \
- delete_token_ref(split_bot_mark(A)); \
- split_bot_mark(A)=null; \
-} while (0)
-
-# define clear_marks_code 1
-
-# define biggest_mark 65535
-
-extern halfword top_marks_array[(biggest_mark + 1)];
-extern halfword first_marks_array[(biggest_mark + 1)];
-extern halfword bot_marks_array[(biggest_mark + 1)];
-extern halfword split_first_marks_array[(biggest_mark + 1)];
-extern halfword split_bot_marks_array[(biggest_mark + 1)];
-extern halfword biggest_used_mark;
-
-
-extern void initialize_marks(void);
-
-extern int long_state;
-extern halfword pstack[9];
-extern void macro_call(void);
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.c b/Build/source/texk/web2c/luatexdir/tex/extensions.c
deleted file mode 100644
index 19d4e444173..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/extensions.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-#define mode mode_par
-#define tail tail_par
-#define head head_par
-#define dir_save dirs_par
-
-/*tex
-
- The program above includes a bunch of ``hooks'' that allow further
- capabilities to be added without upsetting \TeX's basic structure. Most of
- these hooks are concerned with ``whatsit'' nodes, which are intended to be
- used for special purposes; whenever a new extension to \TeX\ involves a new
- kind of whatsit node, a corresponding change needs to be made to the routines
- below that deal with such nodes, but it will usually be unnecessary to make
- many changes to the other parts of this program.
-
- In order to demonstrate how extensions can be made, we shall treat
- `\.{\\write}', `\.{\\openout}', `\.{\\closeout}', `\.{\\immediate}', and
- `\.{\\special}' as if they were extensions. These commands are actually
- primitives of \TeX, and they should appear in all implementations of the
- system; but let's try to imagine that they aren't. Then the program below
- illustrates how a person could add them.
-
- Sometimes, of course, an extension will require changes to \TeX\ itself; no
- system of hooks could be complete enough for all conceivable extensions. The
- features associated with `\.{\\write}' are almost all confined to the
- following paragraphs, but there are small parts of the |print_ln| and
- |print_char| procedures that were introduced specifically to \.{\\write}
- characters. Furthermore one of the token lists recognized by the scanner is a
- |write_text|; and there are a few other miscellaneous places where we have
- already provided for some aspect of \.{\\write}. The goal of a \TeX\ extender
- should be to minimize alterations to the standard parts of the program, and
- to avoid them completely if possible. He or she should also be quite sure
- that there's no easy way to accomplish the desired goals with the standard
- features that \TeX\ already has. ``Think thrice before extending,'' because
- that may save a lot of work, and it will also keep incompatible extensions of
- \TeX\ from proliferating.
-
- First let's consider the format of whatsit nodes that are used to represent
- the data associated with \.{\\write} and its relatives. Recall that a whatsit
- has |type=whatsit_node|, and the |subtype| is supposed to distinguish
- different kinds of whatsits. Each node occupies two or more words; the exact
- number is immaterial, as long as it is readily determined from the |subtype|
- or other data.
-
- We shall introduce five |subtype| values here, corresponding to the control
- sequences \.{\\openout}, \.{\\write}, \.{\\closeout}, and \.{\\special}. The
- second word of I/O whatsits has a |write_stream| field that identifies the
- write-stream number (0 to 15, or 16 for out-of-range and positive, or 17 for
- out-of-range and negative). In the case of \.{\\write} and \.{\\special},
- there is also a field that points to the reference count of a token list that
- should be sent. In the case of \.{\\openout}, we need three words and three
- auxiliary subfields to hold the string numbers for name, area, and extension.
-
- Extensions might introduce new command codes; but it's best to use
- |extension| with a modifier, whenever possible, so that |main_control| stays
- the same.
-
- The sixteen possible \.{\\write} streams are represented by the |write_file|
- array. The |j|th file is open if and only if |write_open[j]=true|. The last
- two streams are special; |write_open[16]| represents a stream number greater
- than 15, while |write_open[17]| represents a negative stream number, and both
- of these variables are always |false|.
-
-*/
-
-alpha_file write_file[last_file_selector+1];
-halfword write_file_mode[last_file_selector+1];
-halfword write_file_translation[last_file_selector+1];
-boolean write_open[last_file_selector+1];
-
-scaled neg_wd;
-scaled pos_wd;
-scaled neg_ht;
-
-/*tex
-
- The variable |write_loc| just introduced is used to provide an appropriate
- error message in case of ``runaway'' write texts.
-
-*/
-
-/*tex The |eqtb| address of \.{\\write}: */
-
-halfword write_loc;
-
-/*tex
-
- When an |extension| command occurs in |main_control|, in any mode, the
- |do_extension| routine is called.
-
-*/
-
-int last_saved_image_index ;
-int last_saved_image_pages ;
-int last_saved_box_index ;
-scaledpos last_position = { 0, 0 };
-
-static void do_extension_dvi(int immediate)
-{
- if (scan_keyword("literal")) {
- new_whatsit(special_node);
- write_stream(tail) = null;
- scan_toks(false, true);
- write_tokens(tail) = def_ref;
- } else {
- tex_error("unexpected use of \\dviextension",null);
- }
-}
-
-static void do_extension_pdf(int immediate)
-{
- int i;
- if (scan_keyword("literal")) {
- new_whatsit(pdf_literal_node);
- if (scan_keyword("direct"))
- set_pdf_literal_mode(tail, direct_always);
- else if (scan_keyword("page"))
- set_pdf_literal_mode(tail, direct_page);
- else if (scan_keyword("text"))
- set_pdf_literal_mode(tail, direct_text);
- else if (scan_keyword("raw"))
- set_pdf_literal_mode(tail, direct_raw);
- else if (scan_keyword("origin"))
- set_pdf_literal_mode(tail, set_origin);
- else
- set_pdf_literal_mode(tail, set_origin);
- scan_toks(false, true);
- set_pdf_literal_type(tail, normal);
- set_pdf_literal_data(tail, def_ref);
- } else if (scan_keyword("dest")) {
- scan_pdfdest(static_pdf);
- } else if (scan_keyword("annot")) {
- scan_annot(static_pdf);
- } else if (scan_keyword("save")) {
- new_whatsit(pdf_save_node);
- } else if (scan_keyword("restore")) {
- new_whatsit(pdf_restore_node);
- } else if (scan_keyword("linkstate")) {
- new_whatsit(pdf_link_state_node);
- scan_int();
- pdf_link_state(tail) = cur_val;
- } else if (scan_keyword("setmatrix")) {
- new_whatsit(pdf_setmatrix_node);
- scan_toks(false, true);
- set_pdf_setmatrix_data(tail, def_ref);
- } else if (scan_keyword("obj")) {
- scan_obj(static_pdf);
- if (immediate) {
- if (obj_data_ptr(static_pdf, pdf_last_obj) == 0) {
- /*tex This object has not been initialized yet. */
- normal_error("pdf backend","\\pdfextension obj 'reserveobjnum' cannot be used with \\immediate");
- }
- pdf_write_obj(static_pdf, pdf_last_obj);
- }
- } else if (scan_keyword("refobj")) {
- scan_refobj(static_pdf);
- } else if (scan_keyword("colorstack")) {
- scan_int();
- if (cur_val >= colorstackused()) {
- print_err("Unknown color stack number ");
- print_int(cur_val);
- help3(
- "Allocate and initialize a color stack with \\pdfextension colorstackinit.",
- "I'll use default color stack 0 here.",
- "Proceed, with fingers crossed."
- );
- error();
- cur_val = 0;
- }
- if (cur_val < 0) {
- print_err("Invalid negative color stack number");
- help2(
- "I'll use default color stack 0 here.",
- "Proceed, with fingers crossed."
- );
- error();
- cur_val = 0;
- }
- if (scan_keyword("set"))
- i = colorstack_set;
- else if (scan_keyword("push"))
- i = colorstack_push;
- else if (scan_keyword("pop"))
- i = colorstack_pop;
- else if (scan_keyword("current"))
- i = colorstack_current;
- else
- i = -1;
- if (i >= 0) {
- new_whatsit(pdf_colorstack_node);
- set_pdf_colorstack_stack(tail, cur_val);
- set_pdf_colorstack_cmd(tail, i);
- set_pdf_colorstack_data(tail, null);
- if (i <= colorstack_data) {
- scan_toks(false, true);
- set_pdf_colorstack_data(tail, def_ref);
- }
- } else {
- print_err("Color stack action is missing");
- help3(
- "The expected actions for \\pdfextension colorstack:",
- " set, push, pop, current",
- "I'll ignore the color stack command."
- );
- error();
- }
- } else if (scan_keyword("startlink")) {
- scan_startlink(static_pdf);
- } else if (scan_keyword("endlink")) {
- if (abs(mode) == vmode)
- normal_error("pdf backend", "\\pdfextension endlink cannot be used in vertical mode");
- new_whatsit(pdf_end_link_node);
- } else if (scan_keyword("startthread")) {
- new_annot_whatsit(pdf_start_thread_node);
- scan_thread_id();
- } else if (scan_keyword("endthread")) {
- new_whatsit(pdf_end_thread_node);
- } else if (scan_keyword("thread")) {
- new_annot_whatsit(pdf_thread_node);
- scan_thread_id();
- } else if (scan_keyword("outline")) {
- scan_pdfoutline(static_pdf);
- } else if (scan_keyword("glyphtounicode")) {
- glyph_to_unicode();
- } else if (scan_keyword("catalog")) {
- scan_pdfcatalog(static_pdf);
- } else if (scan_keyword("fontattr")) {
- /*tex
-
- The font attributes are simply initialized to zero now, this is
- easier to deal with from C than an empty \TeX{} string, and surely
- nobody will want to set font attr to a string containing a single
- zero, as that would be nonsensical in the PDF output.
-
- */
- scan_font_ident();
- i = cur_val;
- if (i == null_font)
- normal_error("pdf backend", "invalid font identifier");
- scan_toks(false, true);
- set_pdf_font_attr(i, tokens_to_string(def_ref));
- if (str_length(pdf_font_attr(i)) == 0) {
- /*tex From |tokens_to_string|. */
- flush_str((str_ptr - 1));
- set_pdf_font_attr(i, 0);
- }
- } else if (scan_keyword("mapfile")) {
- scan_toks(false, true);
- pdfmapfile(def_ref);
- delete_token_ref(def_ref);
- } else if (scan_keyword("mapline")) {
- scan_toks(false, true);
- pdfmapline(def_ref);
- delete_token_ref(def_ref);
- } else if (scan_keyword("includechars")) {
- pdf_include_chars(static_pdf);
- } else if (scan_keyword("info")) {
- scan_toks(false, true);
- pdf_info_toks = concat_tokens(pdf_info_toks, def_ref);
- } else if (scan_keyword("names")) {
- scan_toks(false, true);
- pdf_names_toks = concat_tokens(pdf_names_toks, def_ref);
- } else if (scan_keyword("trailer")) {
- scan_toks(false, true);
- pdf_trailer_toks = concat_tokens(pdf_trailer_toks, def_ref);
- } else {
- tex_error("unexpected use of \\pdfextension",null);
- }
-}
-
-static void do_resource_dvi(int immediate, int code)
-{
- /*tex Nothing is done here. */
-}
-
-static void do_resource_pdf(int immediate, int code)
-{
- switch (code) {
- case use_box_resource_code:
- scan_pdfrefxform(static_pdf);
- break;
- case use_image_resource_code:
- scan_pdfrefximage(static_pdf);
- break;
- case save_box_resource_code:
- scan_pdfxform(static_pdf);
- if (immediate) {
- pdf_cur_form = last_saved_box_index;
- ship_out(static_pdf, obj_xform_box(static_pdf, last_saved_box_index), SHIPPING_FORM);
- }
- break;
- case save_image_resource_code:
- scan_pdfximage(static_pdf);
- if (immediate) {
- pdf_write_image(static_pdf, last_saved_image_index);
- }
- break;
- }
-}
-
-/*tex
-
- Ad immediate:
-
- To write a token list, we must run it through \TeX's scanner, expanding
- macros and \.{\\the} and \.{\\number}, etc. This might cause runaways, if a
- delimited macro parameter isn't matched, and runaways would be extremely
- confusing since we are calling on \TeX's scanner in the middle of a
- \.{\\shipout} command. Therefore we will put a dummy control sequence as a
- ``stopper,'' right after the token list. This control sequence is
- artificially defined to be \.{\\outer}.
-
- The presence of `\.{\\immediate}' causes the |do_extension| procedure to
- descend to one level of recursion. Nothing happens unless \.{\\immediate} is
- followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
-
-*/
-
-/*tex
-
- The extensions are backend related. The next subroutine uses |cur_chr| to
- decide what sort of whatsit is involved, and also inserts a |write_stream|
- number.
-
-*/
-
-static void new_write_whatsit(int w, int check)
-{
- new_whatsit(cur_chr);
- if (check) {
- /*tex So we check with open and close. */
- scan_limited_int(last_file_selector,NULL);
- } else {
- /*tex But we're tolerant with the rest. */
- scan_int();
- if (cur_val < 0)
- cur_val = term_only;
- else if (cur_val > last_file_selector) {
- cur_val = term_and_log;
- }
- }
- write_stream(tail) = cur_val;
-}
-
-void do_extension(int immediate)
-{
- /*tex An all-purpose pointer. */
- halfword p;
- if (cur_cmd == extension_cmd) {
- /*tex These have their own range starting at 0. */
- switch (cur_chr) {
- case open_code:
- p = tail;
- new_write_whatsit(open_node_size,1);
- scan_optional_equals();
- /* scan_file_name(); */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- back_input();
- if (cur_cmd != left_brace_cmd) {
- scan_file_name();
- } else {
- scan_file_name_toks();
- }
- /* */
- open_name(tail) = cur_name;
- open_area(tail) = cur_area;
- open_ext(tail) = cur_ext;
- if (immediate) {
- wrapup_leader(tail);
- flush_node_list(tail);
- tail = p;
- vlink(p) = null;
- }
- break;
- case write_code:
- /*tex
-
- When `\.{\\write 12\{...\}}' appears, we scan the token list
- `\.{\{...\}}' without expanding its macros; the macros will
- be expanded later when this token list is rescanned.
-
- */
- p = tail;
- new_write_whatsit(write_node_size,0);
- cur_cs = write_stream(tail);
- scan_toks(false, false);
- write_tokens(tail) = def_ref;
- if (immediate) {
- wrapup_leader(tail);
- flush_node_list(tail);
- tail = p;
- vlink(p) = null;
- }
- break;
- case close_code:
- p = tail;
- new_write_whatsit(close_node_size,1);
- write_tokens(tail) = null;
- if (immediate) {
- wrapup_leader(tail);
- flush_node_list(tail);
- tail = p;
- vlink(p) = null;
- }
- break;
- case special_code:
- /*tex
-
- When `\.{\\special\{...\}}' appears, we expand the macros in
- the token list as in \.{\\xdef} and \.{\\mark}.
-
- */
- new_whatsit(special_node);
- write_stream(tail) = null;
- p = scan_toks(false, true);
- write_tokens(tail) = def_ref;
- break;
- case immediate_code:
- get_x_token();
- do_extension(1);
- break;
- case end_local_code:
- if (tracing_nesting_par > 2) {
- local_control_message("leaving token scanner");
- }
- end_local_control();
- break;
- case use_box_resource_code:
- case use_image_resource_code:
- case save_box_resource_code:
- case save_image_resource_code:
- switch (get_o_mode()) {
- case OMODE_DVI:
- do_resource_dvi(immediate,cur_chr);
- break;
- case OMODE_PDF:
- do_resource_pdf(immediate,cur_chr);
- break;
- default:
- break;
- }
- break;
- /*tex Backend extensions have their own range starting at 32. */
- case dvi_extension_code:
- if (get_o_mode() == OMODE_DVI)
- do_extension_dvi(immediate);
- break;
- case pdf_extension_code:
- if (get_o_mode() == OMODE_PDF)
- do_extension_pdf(immediate);
- break;
- /*tex Done. */
- default:
- if (immediate) {
- back_input();
- } else {
- confusion("invalid extension");
- }
- break;
- }
- } else {
- /*tex No extension command, quite certainly following |\immediate|. */
- back_input();
- }
-}
-
-/*tex
-
- Here is a subroutine that creates a whatsit node having a given |subtype| and
- a given number of words. It initializes only the first word of the whatsit,
- and appends it to the current list.
-
-*/
-
-void new_whatsit(int s)
-{
- halfword p = new_node(whatsit_node, s);
- couple_nodes(tail, p);
- tail = p;
-}
-
-/*tex
-
- The final line of this routine is slightly subtle; at least, the author
- didn't think about it until getting burnt! There is a used-up token list on
- the stack, namely the one that contained |end_write_token|. (We insert this
- artificial `\.{\\endwrite}' to prevent runaways, as explained above.) If it
- were not removed, and if there were numerous writes on a single page, the
- stack would overflow.
-
-*/
-
-void expand_macros_in_tokenlist(halfword p)
-{
- int old_mode;
- pointer q = get_avail();
- pointer r = get_avail();
- token_info(q) = right_brace_token + '}';
- token_link(q) = r;
- token_info(r) = end_write_token;
- begin_token_list(q, inserted);
- begin_token_list(write_tokens(p), write_text);
- q = get_avail();
- token_info(q) = left_brace_token + '{';
- begin_token_list(q, inserted);
- /*tex
-
- Now we're ready to scan `\.\{$\langle\,$token list$\,\rangle$\.{\}
- \\endwrite}'.
-
- */
- old_mode = mode;
- mode = 0;
- /*tex
-
- Disable \.{\\prevdepth}, \.{\\spacefactor}, \.{\\lastskip},
- \.{\\prevgraf}.
-
- */
- cur_cs = write_loc;
- /*tex Expand macros, etc. */
- q = scan_toks(false, true);
- get_token();
- if (cur_tok != end_write_token) {
- /*tex Recover from an unbalanced write command */
- const char *hlp[] = {
- "On this page there's a \\write with fewer real {'s than }'s.",
- "I can't handle that very well; good luck.",
- NULL
- };
- tex_error("Unbalanced write command", hlp);
- do {
- get_token();
- } while (cur_tok != end_write_token);
- }
- mode = old_mode;
- /*tex Conserve stack space. */
- end_token_list();
-}
-
-void write_out(halfword p)
-{
- /*tex holds print |selector| */
- int old_setting;
- /*tex write stream number */
- int j;
- /*tex line to be written, as a Lua string */
- lstring *ss = NULL;
- lstring *s = NULL;
- int callback_id;
- int lua_retval;
- expand_macros_in_tokenlist(p);
- old_setting = selector;
- j = write_stream(p);
- if (file_can_be_written(j)) {
- selector = j;
- } else if ((j == term_only) && (selector == term_and_log)) {
- /*tex write to the terminal if file isn't open */
- selector = log_only;
- tprint_nl("");
- } else {
- tprint_nl("");
- }
- s = tokenlist_to_lstring(def_ref, false);
- if (selector < no_print) {
- /*tex selector is a file */
- callback_id = callback_defined(process_output_buffer_callback);
- if (callback_id > 0) {
- /*tex fix up the output buffer using callbacks */
- lua_retval = run_callback(callback_id, "L->L", s, &ss);
- if ((lua_retval == true) && (ss != NULL)) {
- free_lstring(s);
- s = ss;
- }
- }
- }
- lprint(s);
- free_lstring(s);
- print_ln();
- flush_list(def_ref);
- selector = old_setting;
-}
-
-void finalize_write_files(void) {
- int k;
- for (k = 0; k <= last_file_selector; k++) {
- if (write_open[k]) {
- lua_a_close_out(write_file[k]);
- }
- }
-}
-
-void initialize_write_files(void) {
- int k;
- for (k = 0; k <= last_file_selector; k++) {
- write_open[k] = false;
- }
-}
-
-void close_write_file(int id) {
- if (write_open[id]) {
- lua_a_close_out(write_file[id]);
- write_open[id] = false;
- }
-}
-
-boolean open_write_file(int id, char *fn) {
- if (lua_a_open_out(&(write_file[id]), fn, (id + 1))) {
- write_open[id] = true;
- return true;
- } else {
- return false;
- }
-}
-
-/*tex
-
- To implement primitives as \.{\\pdfextension info}, \.{\\pdfextension
- catalog} or \.{\\pdfextension names} we need to concatenate tokens lists.
-
-*/
-
-halfword concat_tokens(halfword q, halfword r)
-{
- /*tex concat |q| and |r| and returns the result tokens list */
- halfword p;
- if (q == null)
- return r;
- p = q;
- while (token_link(p) != null)
- p = token_link(p);
- set_token_link(p, token_link(r));
- free_avail(r);
- return q;
-}
-
-/*tex
-
- The \eTeX\ features available in extended mode are grouped into two
- categories: (1)~Some of them are permanently enabled and have no semantic
- effect as long as none of the additional primitives are executed. (2)~The
- remaining \eTeX\ features are optional and can be individually enabled and
- disabled. For each optional feature there is an \eTeX\ state variable named
- \.{\\...state}; the feature is enabled, resp.\ disabled by assigning a
- positive, resp.\ non-positive value to that integer.
-
- In order to handle \.{\\everyeof} we need an array |eof_seen| of boolean
- variables.
-
-*/
-
-boolean *eof_seen;
-
-/*tex
-
- The |print_group| procedure prints the current level of grouping and the name
- corresponding to |cur_group|.
-
-*/
-
-void print_group(boolean e)
-{
- switch (cur_group) {
- case bottom_level:
- tprint("bottom level");
- return;
- break;
- case simple_group:
- case semi_simple_group:
- if (cur_group == semi_simple_group)
- tprint("semi ");
- tprint("simple");
- break;;
- case hbox_group:
- case adjusted_hbox_group:
- if (cur_group == adjusted_hbox_group)
- tprint("adjusted ");
- tprint("hbox");
- break;
- case vbox_group:
- tprint("vbox");
- break;
- case vtop_group:
- tprint("vtop");
- break;
- case align_group:
- case no_align_group:
- if (cur_group == no_align_group)
- tprint("no ");
- tprint("align");
- break;
- case output_group:
- tprint("output");
- break;
- case disc_group:
- tprint("disc");
- break;
- case insert_group:
- tprint("insert");
- break;
- case vcenter_group:
- tprint("vcenter");
- break;
- case math_group:
- case math_choice_group:
- case math_shift_group:
- case math_left_group:
- tprint("math");
- if (cur_group == math_choice_group)
- tprint(" choice");
- else if (cur_group == math_shift_group)
- tprint(" shift");
- else if (cur_group == math_left_group)
- tprint(" left");
- break;
- }
- tprint(" group (level ");
- print_int(cur_level);
- print_char(')');
- if (saved_value(-1) != 0) {
- /*tex |saved_line| */
- if (e)
- tprint(" entered at line ");
- else
- tprint(" at line ");
- print_int(saved_value(-1));
- }
-}
-
-/*tex
-
- The |group_trace| procedure is called when a new level of grouping begins
- (|e=false|) or ends (|e=true|) with |saved_value(-1)| containing the line
- number.
-
-*/
-
-void group_trace(boolean e)
-{
- begin_diagnostic();
- print_char('{');
- if (e)
- tprint("leaving ");
- else
- tprint("entering ");
- print_group(e);
- print_char('}');
- end_diagnostic(false);
-}
-
-/*tex
-
- A group entered (or a conditional started) in one file may end in a different
- file. Such slight anomalies, although perfectly legitimate, may cause errors
- that are difficult to locate. In order to be able to give a warning message
- when such anomalies occur, \eTeX\ uses the |grp_stack| and |if_stack| arrays
- to record the initial |cur_boundary| and |cond_ptr| values for each input
- file.
-
-*/
-
-/*tex initial |cur_boundary| */
-
-save_pointer *grp_stack;
-
-/*tex initial |cond_ptr| */
-
-halfword *if_stack;
-
-/*tex
-
- When a group ends that was apparently entered in a different input file, the
- |group_warning| procedure is invoked in order to update the |grp_stack|. If
- moreover \.{\\tracingnesting} is positive we want to give a warning message.
- The situation is, however, somewhat complicated by two facts: (1)~There may
- be |grp_stack| elements without a corresponding \.{\\input} file or
- \.{\\scantokens} pseudo file (e.g., error insertions from the terminal); and
- (2)~the relevant information is recorded in the |name_field| of the
- |input_stack| only loosely synchronized with the |in_open| variable indexing
- |grp_stack|.
-
-*/
-
-void group_warning(void)
-{
- /*tex do we need a warning? */
- boolean w = false;
- /*tex index into |grp_stack| */
- int i = in_open;
- base_ptr = input_ptr;
- /*tex store current state */
- input_stack[base_ptr] = cur_input;
- while ((grp_stack[i] == cur_boundary) && (i > 0)) {
- /*tex
-
- Set variable |w| to indicate if this case should be reported. This
- code scans the input stack in order to determine the type of the
- current input file.
-
- */
- if (tracing_nesting_par > 0) {
- while ((input_stack[base_ptr].state_field == token_list) || (input_stack[base_ptr].index_field > i))
- decr(base_ptr);
- if (input_stack[base_ptr].name_field > 17)
- w = true;
- }
- grp_stack[i] = save_value(save_ptr);
- decr(i);
- }
- if (w) {
- tprint_nl("Warning: end of ");
- print_group(true);
- tprint(" of a different file");
- print_ln();
- if (tracing_nesting_par > 1)
- show_context();
- if (history == spotless)
- history = warning_issued;
- }
-}
-
-/*tex
-
- When a conditional ends that was apparently started in a different input
- file, the |if_warning| procedure is invoked in order to update the
- |if_stack|. If moreover \.{\\tracingnesting} is positive we want to give a
- warning message (with the same complications as above).
-
-*/
-
-void if_warning(void)
-{
- /*tex Do we need a warning? */
- boolean w = false;
- int i = in_open;
- base_ptr = input_ptr;
- /*tex Store current state. */
- input_stack[base_ptr] = cur_input;
- while (if_stack[i] == cond_ptr) {
- /*tex Set variable |w| to. */
- if (tracing_nesting_par > 0) {
- while ((input_stack[base_ptr].state_field == token_list) || (input_stack[base_ptr].index_field > i))
- decr(base_ptr);
- if (input_stack[base_ptr].name_field > 17)
- w = true;
- }
- if_stack[i] = vlink(cond_ptr);
- decr(i);
- }
- if (w) {
- tprint_nl("Warning: end of ");
- print_cmd_chr(if_test_cmd, cur_if);
- print_if_line(if_line);
- tprint(" of a different file");
- print_ln();
- if (tracing_nesting_par > 1)
- show_context();
- if (history == spotless)
- history = warning_issued;
- }
-}
-
-/*tex
-
- Conversely, the |file_warning| procedure is invoked when a file ends and some
- groups entered or conditionals started while reading from that file are still
- incomplete.
-
-*/
-
-void file_warning(void)
-{
- /*tex saved value of |save_ptr| or |cond_ptr| */
- halfword p = save_ptr;
- /*tex saved value of |cur_level| or |if_limit| */
- int l = cur_level;
- /*tex saved value of |cur_group| or |cur_if| */
- int c = cur_group;
- /*tex saved value of |if_line| */
- int i;
- save_ptr = cur_boundary;
- while (grp_stack[in_open] != save_ptr) {
- decr(cur_level);
- tprint_nl("Warning: end of file when ");
- print_group(true);
- tprint(" is incomplete");
- cur_group = save_level(save_ptr);
- save_ptr = save_value(save_ptr);
- }
- save_ptr = p;
- cur_level = (quarterword) l;
- /*tex Restore old values. */
- cur_group = (group_code) c;
- p = cond_ptr;
- l = if_limit;
- c = cur_if;
- i = if_line;
- while (if_stack[in_open] != cond_ptr) {
- tprint_nl("Warning: end of file when ");
- print_cmd_chr(if_test_cmd, cur_if);
- if (if_limit == fi_code)
- tprint_esc("else");
- print_if_line(if_line);
- tprint(" is incomplete");
- if_line = if_line_field(cond_ptr);
- cur_if = if_limit_subtype(cond_ptr);
- if_limit = if_limit_type(cond_ptr);
- cond_ptr = vlink(cond_ptr);
- }
- /*tex restore old values */
- cond_ptr = p;
- if_limit = l;
- cur_if = c;
- if_line = i;
- print_ln();
- if (tracing_nesting_par > 1)
- show_context();
- if (history == spotless)
- history = warning_issued;
-}
-
-/*tex The |par_fill_skip| glue node of the new paragraph. */
-
-halfword last_line_fill;
-
-/*tex
-
- The lua interface needs some extra functions. The functions themselves are
- quite boring, but they are handy because otherwise this internal stuff has to
- be accessed from C directly, where lots of the defines are not available.
-
-*/
-
-#define get_tex_dimen_register(j) dimen(j)
-#define get_tex_skip_register(j) skip(j)
-#define get_tex_mu_skip_register(j) mu_skip(j)
-#define get_tex_count_register(j) count(j)
-#define get_tex_attribute_register(j) attribute(j)
-#define get_tex_box_register(j) box(j)
-
-/*tex These can now be macros (todo). */
-
-int get_tex_extension_count_register(int i)
-{
- return (int) int_par(backend_int_base-int_base+i);
-}
-
-void set_tex_extension_count_register(int i, int d)
-{
- int_par(backend_int_base-int_base+i) = d;
-}
-
-int get_tex_extension_dimen_register(int i)
-{
- return (int) dimen_par(backend_dimen_base-dimen_base+i);
-}
-
-void set_tex_extension_dimen_register(int i, int d)
-{
- dimen_par(backend_dimen_base-dimen_base+i) = d;
-}
-
-int get_tex_extension_toks_register(int i)
-{
- return equiv(backend_toks_base+i);
-}
-
-int set_tex_dimen_register(int j, scaled v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- word_define(j + scaled_base, v);
- return 0;
-}
-
-int set_tex_skip_register(int j, halfword v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- if (type(v) != glue_spec_node)
- return 1;
- word_define(j + skip_base, v);
- return 0;
-}
-
-int set_tex_mu_skip_register(int j, halfword v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- if (type(v) != glue_spec_node)
- return 1;
- word_define(j + mu_skip_base, v);
- return 0;
-}
-
-int set_tex_count_register(int j, scaled v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- word_define(j + count_base, v);
- return 0;
-}
-
-int set_tex_box_register(int j, scaled v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- define(j + box_base, box_ref_cmd, v);
- return 0;
-}
-
-int set_tex_attribute_register(int j, scaled v)
-{
- int a;
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- if (j > max_used_attr)
- max_used_attr = j;
- attr_list_cache = cache_disabled;
- word_define(j + attribute_base, v);
- return 0;
-}
-
-int get_tex_toks_register(int j)
-{
- str_number s = get_nullstr();
- if (toks(j) != null) {
- s = tokens_to_string(toks(j));
- }
- return s;
-}
-
-int set_tex_toks_register(int j, lstring s)
-{
- int a;
- halfword ref = get_avail();
- (void) str_toks(s);
- set_token_ref_count(ref, 0);
- set_token_link(ref, token_link(temp_token_head));
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- define(j + toks_base, call_cmd, ref);
- return 0;
-}
-
-int scan_tex_toks_register(int j, int c, lstring s)
-{
- int a;
- halfword ref = get_avail();
- (void) str_scan_toks(c,s);
- set_token_ref_count(ref, 0);
- set_token_link(ref, token_link(temp_token_head));
- if (global_defs_par > 0)
- a = 4;
- else
- a = 0;
- define(j + toks_base, call_cmd, ref);
- return 0;
-}
-
-scaled get_tex_box_width(int j)
-{
- halfword q = box(j);
- if (q != null)
- return width(q);
- return 0;
-}
-
-int set_tex_box_width(int j, scaled v)
-{
- halfword q = box(j);
- if (q == null)
- return 1;
- width(q) = v;
- return 0;
-}
-
-scaled get_tex_box_height(int j)
-{
- halfword q = box(j);
- if (q != null)
- return height(q);
- return 0;
-}
-
-int set_tex_box_height(int j, scaled v)
-{
- halfword q = box(j);
- if (q == null)
- return 1;
- height(q) = v;
- return 0;
-}
-
-scaled get_tex_box_depth(int j)
-{
- halfword q = box(j);
- if (q != null)
- return depth(q);
- return 0;
-}
-
-int set_tex_box_depth(int j, scaled v)
-{
- halfword q = box(j);
- if (q == null)
- return 1;
- depth(q) = v;
- return 0;
-}
-
-/*tex
-
- This section is devoted to the {\sl Synchronize \TeX nology} - or simply {\sl
- Sync\TeX} - used to synchronize between input and output. This section
- explains how synchronization basics are implemented. Before we enter into
- more technical details, let us recall in a few words what is synchronization.
-
- \TeX\ typesetting system clearly separates the input and the output material,
- and synchronization will provide a new link between both that can help text
- editors and viewers to work together. More precisely, forwards
- synchronization is the ability, given a location in the input source file, to
- find what is the corresponding place in the output. Backwards synchronization
- just performs the opposite: given a location in the output, retrieve the
- corresponding material in the input source file.
-
- For better code management and maintainance, we adopt a naming convention.
- Throughout this program, code related to the {\sl Synchronize \TeX nology} is
- tagged with the ``{\sl synctex}'' key word. Any code extract where {\sl
- Sync\TeX} plays its part, either explicitly or implicitly, (should) contain
- the string ``{\sl synctex}''. This naming convention also holds for external
- files. Moreover, all the code related to {\sl Sync\TeX} is gathered in this
- section, except the definitions.
-
- Enabling synchronization should be performed from the command line,
- |synctexoption| is used for that purpose. This global integer variable is
- declared here but it is not used here. This is just a placeholder where the
- command line controller will put the {\sl Sync\TeX} related options, and the
- {\sl Sync\TeX} controller will read them.
-
-*/
-
-int synctexoption;
-
-/*tex
-
- A convenient primitive is provided: \.{\\synctex=1} in the input source file
- enables synchronization whereas \.{\\synctex=0} disables it. Its memory
- address is |synctex_code|. It is initialized by the {\sl Sync\TeX} controller
- to the command-line option if given. The controller may filter some reserved
- bits.
-
- In order to give the {\sl Sync\TeX} controller read and write access to the
- contents of the \.{\\synctex} primitive, we declare |synctexoffset|, such
- that |mem[synctexoffset]| and \.{\\synctex} correspond to the same memory
- storage. |synctexoffset| is initialized to the correct value when quite
- everything is initialized.
-
-*/
-
-/*tex Holds the true value of |synctex_code|: */
-
-int synctexoffset;
-
-/*tex
-
- Synchronization is achieved with the help of an auxiliary file named `\.{{\sl
- jobname}.synctex}' ({\sl jobname} is the contents of the \.{\\jobname}
- macro), where a {\sl Sync\TeX} controller implemented in the external
- |synctex.c| file will store geometrical information. This {\sl Sync\TeX}
- controller will take care of every technical details concerning the {\sl
- Sync\TeX} file, we will only focus on the messages the controller will
- receive from the \TeX\ program.
-
- The most accurate synchronization information should allow to map any
- character of the input source file to the corresponding location in the
- output, if relevant. Ideally, the synchronization information of the input
- material consists of the file name, the line and column numbers of every
- character. The synchronization information in the output is simply the page
- number and either point coordinates, or box dimensions and position. The
- problem is that the mapping between these informations is only known at ship
- out time, which means that we must keep track of the input synchronization
- information until the pages ship out.
-
- As \TeX\ only knows about file names and line numbers, but forgets the column
- numbers, we only consider a restricted input synchronization information
- called {\sl Sync\TeX\ information}. It consists of a unique file name
- identifier, the {\sl Sync\TeX\ file tag}, and the line number.
-
- Keeping track of such information, should be different whether characters or
- nodes are involved. Actually, only certain nodes are involved in {\sl
- Sync\TeX}, we call them {\sl synchronized nodes}. Synchronized nodes store
- the {\sl Sync\TeX} information in their last two words: the first one
- contains a {\sl Sync\TeX\ file tag} uniquely identifying the input file, and
- the second one contains the current line number, as returned by the
- \.{\\inputlineno} primitive. The |synctex_field_size| macro contains the
- necessary size to store the {\sl Sync\TeX} information in a node.
-
- When declaring the size of a new node, it is recommanded to use the following
- convention: if the node is synchronized, use a definition similar to
- |my_synchronized_node_size|={\sl xxx}+|synctex_field_size|. Moreover, one
- should expect that the {\sl Sync\TeX} information is always stored in the
- last two words of a synchronized node.
-
- By default, every node with a sufficiently big size is initialized at
- creation time in the |get_node| routine with the current {\sl Sync\TeX}
- information, whether or not the node is synchronized. One purpose is to set
- this information very early in order to minimize code dependencies, including
- forthcoming extensions. Another purpose is to avoid the assumption that every
- node type has a dedicated getter, where initialization should take place.
- Actually, it appears that some nodes are created using directly the
- |get_node| routine and not the dedicated constructor. And finally,
- initializing the node at only one place is less error prone.
-
- Instead of storing the input file name, it is better to store just an
- identifier. Each time \TeX\ opens a new file, it notifies the {\sl Sync\TeX}
- controller with a |synctex_start_input| message. This controller will create
- a new {\sl Sync\TeX} file tag and will update the current input state record
- accordingly. If the input comes from the terminal or a pseudo file, the
- |synctex_tag| is set to 0. It results in automatically disabling
- synchronization for material input from the terminal or pseudo files.
-
- Synchronized nodes are boxes, math, kern and glue nodes. Other nodes should
- be synchronized too, in particular math noads. \TeX\ assumes that math, kern
- and glue nodes have the same size, this is why both are synchronized. {\sl In
- fine}, only horizontal lists are really used in {\sl Sync\TeX}, but all box
- nodes are considered the same with respect to synchronization, because a box
- node type is allowed to change at execution time.
-
- {\em Nota Bene:} The {\sl Sync\TeX} code is very close to the memory model.
- It is not connected to any other part of the code, except for memory
- management. It is possible to neutralize the {\sl Sync\TeX} code rather
- simply. The first step is to define a null |synctex_field_size|. The second
- step is to comment out the code in ``Initialize bigger nodes...'' and every
- ``Copy ... {\sl Sync\TeX} information''. The last step will be to comment out
- the |synctex_tag_field| related code in the definition of |synctex_tag| and
- the various ``Prepare ... {\sl Sync\TeX} information''. Then all the
- remaining code should be just harmless. The resulting program would behave
- exactly the same as if absolutely no {\sl Sync\TeX} related code was there,
- including memory management. Of course, all this assumes that {\sl Sync\TeX}
- is turned off from the command line.
-
- Here are extra variables for Web2c. (This numbering of the system-dependent
- section allows easy integration of Web2c and e-\TeX, etc.)
-
-*/
-
-/*tex where the filename to switch to starts */
-
-pool_pointer edit_name_start;
-
-/*tex what line to start editing at */
-
-int edit_name_length, edit_line;
-
-/*tex whether |more_name| returns false for space */
-
-boolean stop_at_space;
-
-/*tex
-
- The |edit_name_start| will be set to point into |str_pool| somewhere after
- its beginning if \TeX\ is supposed to switch to an editor on exit.
-
-*/
-
-int shellenabledp;
-int restrictedshell;
-char *output_comment;
-
-/*tex
-
- Are we printing extra info as we read the format file?
-
-*/
-
-boolean debug_format_file;
-
-void wrapup_leader(halfword p)
-{
- /*tex Do some work that has been queued up for \.{\\write}. */
- if (!doing_leaders) {
- int j = write_stream(p);
- if (subtype(p) == write_node) {
- write_out(p);
- } else if (subtype(p) == close_node) {
- close_write_file(j);
- } else if (valid_write_file(j)) {
- char *fn;
- close_write_file(j);
- cur_name = open_name(p);
- cur_area = open_area(p);
- cur_ext = open_ext(p);
- if (cur_ext == get_nullstr())
- cur_ext = maketexstring(".tex");
- fn = pack_file_name(cur_name, cur_area, cur_ext);
- while (! open_write_file(j,fn)) {
- fn = prompt_file_name("output file name", ".tex");
- }
- }
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/extensions.h b/Build/source/texk/web2c/luatexdir/tex/extensions.h
deleted file mode 100644
index 5e22ddf26c3..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/extensions.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* extensions.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef EXTENSIONS_H
-# define EXTENSIONS_H
-
-extern alpha_file write_file[last_file_selector+1];
-extern halfword write_file_mode[last_file_selector+1];
-extern halfword write_file_translation[last_file_selector+1];
-extern boolean write_open[last_file_selector+1];
-
-# define valid_write_file(n) ((n>=0) && (n<=last_file_selector))
-# define file_can_be_written(n) (valid_write_file(n) && write_open[n])
-
-extern void expand_macros_in_tokenlist(halfword p);
-extern void write_out(halfword p);
-extern void finalize_write_files(void);
-extern void initialize_write_files(void);
-extern void close_write_file(int id);
-extern boolean open_write_file(int id, char *fn);
-
-extern scaled neg_wd;
-extern scaled pos_wd;
-extern scaled neg_ht;
-
-extern halfword write_loc;
-
-extern void do_extension(int immediate);
-
-/*
-User defined whatsits can be inserted into node lists to pass data
-along from one lua call to another without interference from the
-typesetting engine itself. Each has an id, a type, and a value. The
-type of the value depends on the |user_node_type| field.
-*/
-
-extern void new_whatsit(int s);
-
-extern halfword concat_tokens(halfword q, halfword r);
-
-/*
-The \.{\\pagediscards} and \.{\\splitdiscards} commands share the
-command code |un_vbox| with \.{\\unvbox} and \.{\\unvcopy}, they are
-distinguished by their |chr_code| values |last_box_code| and
-|vsplit_code|. These |chr_code| values are larger than |box_code| and
-|copy_code|.
-*/
-
-extern boolean *eof_seen; /* has eof been seen? */
-extern void print_group(boolean e);
-extern void group_trace(boolean e);
-extern save_pointer *grp_stack; /* initial |cur_boundary| */
-extern halfword *if_stack; /* initial |cond_ptr| */
-extern void group_warning(void);
-extern void if_warning(void);
-extern void file_warning(void);
-
-extern halfword last_line_fill; /* the |par_fill_skip| glue node of the new paragraph */
-
-# define get_tex_dimen_register(j) dimen(j)
-# define get_tex_skip_register(j) skip(j)
-# define get_tex_mu_skip_register(j) mu_skip(j)
-# define get_tex_count_register(j) count(j)
-# define get_tex_attribute_register(j) attribute(j)
-# define get_tex_box_register(j) box(j)
-
-extern int get_tex_extension_count_register(int i);
-extern void set_tex_extension_count_register(int i, int d);
-extern int get_tex_extension_dimen_register(int i);
-extern void set_tex_extension_dimen_register(int i, int d);
-extern int get_tex_extension_toks_register (int i);
-
-extern int set_tex_dimen_register(int j, scaled v);
-extern int set_tex_skip_register(int j, halfword v);
-extern int set_tex_mu_skip_register(int j, halfword v);
-extern int set_tex_count_register(int j, scaled v);
-extern int set_tex_box_register(int j, scaled v);
-extern int set_tex_attribute_register(int j, scaled v);
-extern int get_tex_toks_register(int l);
-extern int set_tex_toks_register(int j, lstring s);
-extern int scan_tex_toks_register(int j, int c, lstring s);
-extern scaled get_tex_box_width(int j);
-extern int set_tex_box_width(int j, scaled v);
-extern scaled get_tex_box_height(int j);
-extern int set_tex_box_height(int j, scaled v);
-extern scaled get_tex_box_depth(int j);
-extern int set_tex_box_depth(int j, scaled v);
-
-/* Synctex variables */
-
-extern int synctexoption;
-extern int synctexoffset;
-
-/* Here are extra variables for Web2c. */
-
-extern pool_pointer edit_name_start;
-extern int edit_name_length, edit_line;
-extern boolean stop_at_space;
-extern int shellenabledp;
-extern int restrictedshell;
-extern char *output_comment;
-extern boolean debug_format_file;
-
-extern int last_saved_box_index ;
-extern int last_saved_image_index ;
-extern int last_saved_image_pages ;
-extern scaledpos last_position ;
-
-typedef enum {
- /* traditional extensions */
- open_code = 0,
- write_code,
- close_code,
- reserved_extension_code, // 3: we moved special below immediate //
- reserved_immediate_code, // 4: same number as main codes, expected value //
- /* backend specific implementations */
- special_code,
- save_box_resource_code,
- use_box_resource_code,
- save_image_resource_code,
- use_image_resource_code,
- end_local_code,
- /* backend */
- dvi_extension_code,
- pdf_extension_code,
-} extension_codes ;
-
-extern void wrapup_leader(halfword p);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.c b/Build/source/texk/web2c/luatexdir/tex/filename.c
deleted file mode 100644
index 1e06e877ae8..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/filename.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
-
-filename.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-
-/*tex
-
- In order to isolate the system-dependent aspects of file names, the @^system
- dependencies@> system-independent parts of \TeX\ are expressed in terms of
- three system-dependent procedures called |begin_name|, |more_name|, and
- |end_name|. In essence, if the user-specified characters of the file name are
- $c_1\ldots c_n$, the system-independent driver program does the operations
- $$|begin_name|;\,|more_name|(c_1);\,\ldots\,;\,|more_name|(c_n);
- \,|end_name|.$$
-
- These three procedures communicate with each other via global variables.
- Afterwards the file name will appear in the string pool as three strings
- called |cur_name|\penalty10000\hskip-.05em, |cur_area|, and |cur_ext|; the
- latter two are null (i.e., |""|), unless they were explicitly specified by
- the user.
-
- Actually the situation is slightly more complicated, because \TeX\ needs to
- know when the file name ends. The |more_name| routine is a function (with
- side effects) that returns |true| on the calls |more_name|$(c_1)$, \dots,
- |more_name|$(c_{n-1})$. The final call |more_name|$(c_n)$ returns |false|;
- or, it returns |true| and the token following $c_n$ is something like
- `\.{\\hbox}' (i.e., not a character). In other words, |more_name| is supposed
- to return |true| unless it is sure that the file name has been completely
- scanned; and |end_name| is supposed to be able to finish the assembly of
- |cur_name|, |cur_area|, and |cur_ext| regardless of whether
- $|more_name|(c_n)$ returned |true| or |false|.
-
-
- Here now is the first of the system-dependent routines for file name
- scanning. @^system dependencies@>
-
-*/
-
-static void begin_name(void)
-{
- area_delimiter = 0;
- ext_delimiter = 0;
- quoted_filename = false;
-}
-
-/*tex
-
- And here's the second. The string pool might change as the file name is being
- scanned, since a new \.{\\csname} might be entered; therefore we keep
- |area_delimiter| and |ext_delimiter| relative to the beginning of the current
- string, instead of assigning an absolute address like |pool_ptr| to them.
- @^system dependencies@>
-
-*/
-
-static boolean more_name(ASCII_code c)
-{
- if (c == ' ' && stop_at_space && (!quoted_filename)) {
- return false;
- } else if (c == '"') {
- quoted_filename = !quoted_filename;
- return true;
- } else {
- str_room(1);
- append_char(c);
- if (IS_DIR_SEP(c)) {
- area_delimiter = (pool_pointer) cur_length;
- ext_delimiter = 0;
- } else if (c == '.')
- ext_delimiter = (pool_pointer) cur_length;
- return true;
- }
-}
-
-/*tex
-
- The third. @^system dependencies@>
-
-*/
-
-static void end_name(void)
-{
- unsigned char *s;
- if (str_ptr + 3 > (max_strings + STRING_OFFSET))
- overflow(
- "number of strings",
- (unsigned) (max_strings - init_str_ptr + STRING_OFFSET)
- );
- /*tex At this point, the full string lives in |cur_string|. */
- if (area_delimiter == 0) {
- cur_area = get_nullstr();
- } else {
- s = (unsigned char *) xstrdup((char *) (cur_string + area_delimiter));
- cur_string[area_delimiter] = '\0';
- cur_length = (unsigned) strlen((char *) cur_string);
- cur_area = make_string();
- xfree(cur_string);
- cur_length = (unsigned) strlen((char *) s);
- cur_string = s;
- }
- if (ext_delimiter == 0) {
- cur_name = make_string();
- cur_ext = get_nullstr();
- } else {
- int l = (ext_delimiter - area_delimiter - 1);
- s = (unsigned char *) xstrdup((char *) (cur_string + l));
- cur_string[l] = '\0';
- cur_length = (unsigned) strlen((char *) cur_string);
- cur_name = make_string();
- xfree(cur_string);
- cur_length = (unsigned) strlen((char *) s);
- cur_string = s;
- cur_ext = make_string();
- }
-}
-
-/*tex
-
- Now let's consider the ``driver'' routines by which \TeX\ deals with file
- names in a system-independent manner. First comes a procedure that looks for a
- file name in the input by calling |get_x_token| for the information.
-
-*/
-
-void scan_file_name(void)
-{
- str_number u = 0;
- name_in_progress = true;
- begin_name();
- /*tex Get the next non-blank non-call token: */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- while (true) {
- if ((cur_cmd > other_char_cmd) || (cur_chr > biggest_char)) { /* not a character */
- back_input();
- break;
- }
- /*tex
- If |cur_chr| is a space and we're not scanning a token list, check
- whether we're at the end of the buffer. Otherwise we end up adding
- spurious spaces to file names in some cases.
- */
- if ((cur_chr == ' ') && (istate != token_list) && (iloc > ilimit)
- && !quoted_filename)
- break;
- if (cur_chr > 127) {
- unsigned char *bytes;
- unsigned char *thebytes;
- thebytes = uni2str((unsigned) cur_chr);
- bytes = thebytes;
- while (*bytes) {
- if (!more_name(*bytes))
- break;
- bytes++;
- }
- xfree(thebytes);
- } else {
- if (!more_name(cur_chr))
- break;
- }
- u = save_cur_string();
- get_x_token();
- restore_cur_string(u);
- }
- end_name();
- name_in_progress = false;
-}
-
-/*
- This function constructs a the three file name strings from a token list.
-*/
-
-void scan_file_name_toks(void)
-{
- char *a, *n, *e, *s = NULL;
- int i, l = 0;
- int save_scanner_status = scanner_status;
- halfword save_def_ref = def_ref;
- (void) scan_toks(false, true);
- s = tokenlist_to_cstring(def_ref, true, &l);
- a = n = s;
- e = NULL;
- for (i = 0; i < l; i++) {
- if (IS_DIR_SEP(s[i])) {
- n = s + i + 1;
- e = NULL;
- } else if (s[i] == '.') {
- e = s + i;
- }
- }
- if (n != s) {
- /*tex explicit area */
- cur_area = maketexlstring(a, (size_t) (n - a));
- } else {
- cur_area = get_nullstr();
- }
- if (e != NULL) {
- /*tex explicit extension */
- cur_name = maketexlstring(n, (size_t) (e - n));
- cur_ext = maketexstring(e);
- } else {
- cur_name = maketexstring(n);
- cur_ext = get_nullstr();
- }
- flush_list(def_ref);
- scanner_status = save_scanner_status;
- def_ref = save_def_ref;
- xfree(s);
-}
-
-/*tex
-
- Here is a routine that manufactures the output file names, assuming that
- |job_name<>0|. It ignores and changes the current settings of |cur_area| and
- |cur_ext|; |s = ".log"|, |".dvi"|, or |format_extension|
-*/
-
-char *pack_job_name(const char *s)
-{
- cur_area = get_nullstr();
- cur_ext = maketexstring(s);
- cur_name = job_name;
- return pack_file_name(cur_name, cur_area, cur_ext);
-}
-
-/*tex
-
- If some trouble arises when \TeX\ tries to open a file, the following routine
- calls upon the user to supply another file name. Parameter~|s| is used in the
- error message to identify the type of file; parameter~|e| is the default
- extension if none is given. Upon exit from the routine, variables |cur_name|,
- |cur_area|, and |cur_ext| are ready for another attempt at file opening.
-
-*/
-
-char *prompt_file_name(const char *s, const char *e)
-{
- int k; /* index into |buffer| */
- str_number saved_cur_name; /* to catch empty terminal input */
- int callback_id ;
- char prompt[256];
- char *ar, *na, *ex;
- saved_cur_name = cur_name;
- if (interaction == scroll_mode) {
- wake_up_terminal();
- }
- ar = makecstring(cur_area);
- na = makecstring(cur_name);
- ex = makecstring(cur_ext);
- if (strcmp(s, "input file name") == 0) {
- snprintf(prompt, 255, "I can't find file `%s%s%s'.", ar, na, ex);
- } else {
- snprintf(prompt, 255, "I can't write on file `%s%s%s'.", ar, na, ex);
- }
- free(ar);
- free(na);
- free(ex);
- print_err(prompt);
- callback_id = callback_defined(show_error_hook_callback);
- if (callback_id > 0) {
- flush_err();
- run_callback(callback_id, "->");
- } else {
- if ((strcmp(e, ".tex") == 0) || (strcmp(e, "") == 0))
- show_context();
- if (strcmp(s, "input file name") == 0)
- tprint_nl(promptfilenamehelpmsg ")");
- }
- tprint_nl("Please type another ");
- tprint(s);
- if (interaction < scroll_mode)
- fatal_error("*** (job aborted, file error in nonstop mode)");
- clear_terminal();
- prompt_input(": ");
- begin_name();
- k = first;
- while ((buffer[k] == ' ') && (k < last))
- k++;
- while (true) {
- if (k == last)
- break;
- if (!more_name(buffer[k]))
- break;
- k++;
- }
- end_name();
- if (cur_ext == get_nullstr())
- cur_ext = maketexstring(e);
- if (str_length(cur_name) == 0)
- cur_name = saved_cur_name;
- return pack_file_name(cur_name, cur_area, cur_ext);
-}
-
-void tprint_file_name(unsigned char *n, unsigned char *a, unsigned char *e)
-{
- boolean must_quote; /* whether to quote the filename */
- unsigned char *j; /* index into string */
- must_quote = false;
- if (a != NULL) {
- j = a;
- while ((!must_quote) && (*j)) {
- must_quote = (*j == ' ');
- j++;
- }
- }
- if (n != NULL) {
- j = n;
- while ((!must_quote) && (*j)) {
- must_quote = (*j == ' ');
- j++;
- }
- }
- if (e != NULL) {
- j = e;
- while ((!must_quote) && (*j)) {
- must_quote = (*j == ' ');
- j++;
- }
- }
- /*tex
- Alternative is to assume that any filename that has to be quoted has at
- least one quoted component...if we pick this, a number of insertions of
- |print_file_name| should go away.
- */
- if (must_quote)
- print_char('"');
- if (a != NULL) {
- for (j = a; *j; j++)
- if (*j != '"')
- print_char(*j);
- }
- if (n != NULL) {
- for (j = n; *j; j++)
- if (*j != '"')
- print_char(*j);
- }
- if (e != NULL) {
- for (j = e; *j; j++)
- if (*j != '"')
- print_char(*j);
- }
- if (must_quote)
- print_char('"');
-}
-
-void print_file_name(str_number n, str_number a, str_number e)
-{
- char *nam, *are, *ext;
- nam = makecstring(n);
- are = makecstring(a);
- ext = makecstring(e);
- tprint_file_name(
- (unsigned char *) nam,
- (unsigned char *) are,
- (unsigned char *) ext
- );
- free(nam);
- free(are);
- free(ext);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/filename.h b/Build/source/texk/web2c/luatexdir/tex/filename.h
deleted file mode 100644
index cb3d060fd83..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/filename.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* filename.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef FILENAME_H
-# define FILENAME_H
-
-extern void scan_file_name(void);
-extern void scan_file_name_toks(void);
-extern char *pack_job_name(const char *s);
-extern char *prompt_file_name(const char *s, const char *e);
-extern void tprint_file_name(unsigned char *n, unsigned char *a,
- unsigned char *e);
-extern void print_file_name(str_number, str_number, str_number);
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.c b/Build/source/texk/web2c/luatexdir/tex/inputstack.c
deleted file mode 100644
index 6b0e1a055eb..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/inputstack.c
+++ /dev/null
@@ -1,960 +0,0 @@
-/*
-
-inputstack.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-in_state_record *input_stack = NULL;
-
-/*tex First unused location of |input_stack|: */
-
-int input_ptr = 0;
-
-/*tex Largest value of |input_ptr| when pushing: */
-
-int max_in_stack = 0;
-
-/*tex The `top' input state: */
-
-in_state_record cur_input;
-
-/*tex The number of lines in the buffer, less one: */
-
-int in_open = 0;
-
-/*tex The number of open text files: */
-
-int open_parens = 0;
-
-alpha_file *input_file = NULL;
-
-/*tex The current line number in the current source file: */
-
-int line = 0;
-
-int *line_stack = NULL;
-
-str_number *source_filename_stack = NULL;
-
-char **full_source_filename_stack = NULL;
-
-/*tex Can a subfile end now? */
-
-int scanner_status = 0;
-
-/*tex Identifier relevant to non-|normal| scanner status: */
-
-pointer warning_index = null;
-
-/*tex Reference count of token list being defined: */
-
-pointer def_ref = null;
-
-/*tex
-
-Here is a procedure that uses |scanner_status| to print a warning message when a
-subfile has ended, and at certain other crucial times:
-
-*/
-
-void runaway(void)
-{
- /*tex The head of the runaway list: */
- pointer p = null;
- if (scanner_status > skipping) {
- switch (scanner_status) {
- case defining:
- tprint_nl("Runaway definition");
- p = def_ref;
- break;
- case matching:
- tprint_nl("Runaway argument");
- p = temp_token_head;
- break;
- case aligning:
- tprint_nl("Runaway preamble");
- p = hold_token_head;
- break;
- case absorbing:
- tprint_nl("Runaway text");
- p = def_ref;
- break;
- default:
- /*tex There are no other cases. */
- break;
- }
- print_char('?');
- print_ln();
- show_token_list(token_link(p), null, error_line - 10);
- }
-}
-
-/*tex
-
-The |param_stack| is an auxiliary array used to hold pointers to the token lists
-for parameters at the current level and subsidiary levels of input. This stack is
-maintained with convention (2), and it grows at a different rate from the others.
-
-*/
-
-/*tex Token list pointers for parameters: */
-
-pointer *param_stack = NULL;
-
-/*tex First unused entry in |param_stack|: */
-
-int param_ptr = 0;
-
-/*tex Largest value of |param_ptr|, will be |<=param_size+9|: */
-
-int max_param_stack = 0;
-
-/*tex
-
-The input routines must also interact with the processing of \.{\\halign} and
-\.{\\valign}, since the appearance of tab marks and \.{\\cr} in certain places is
-supposed to trigger the beginning of special $v_j$ template text in the scanner.
-This magic is accomplished by an |align_state| variable that is increased by~1
-when a `\.{\char'173}' is scanned and decreased by~1 when a `\.{\char'175}' is
-scanned. The |align_state| is nonzero during the $u_j$ template, after which it
-is set to zero; the $v_j$ template begins when a tab mark or \.{\\cr} occurs at a
-time that |align_state=0|.
-
-*/
-
-/*tex The group level with respect to current alignment: */
-
-int align_state = 0;
-
-/*tex
-
-Thus, the ``current input state'' can be very complicated indeed; there can be
-many levels and each level can arise in a variety of ways. The |show_context|
-procedure, which is used by \TeX's error-reporting routine to print out the
-current input state on all levels down to the most recent line of characters from
-an input file, illustrates most of these conventions. The global variable
-|base_ptr| contains the lowest level that was displayed by this procedure.
-
-*/
-
-/*tex The shallowest level shown by |show_context|: */
-
-int base_ptr = 0;
-
-/*tex
-
-The status at each level is indicated by printing two lines, where the first line
-indicates what was read so far and the second line shows what remains to be read.
-The context is cropped, if necessary, so that the first line contains at most
-|half_error_line| characters, and the second contains at most |error_line|.
-Non-current input levels whose |token_type| is `|backed_up|' are shown only if
-they have not been fully read.
-
-*/
-
-static void print_token_list_type(int t)
-{
- switch (t) {
- case parameter:
- tprint_nl("<argument> ");
- break;
- case u_template:
- case v_template:
- tprint_nl("<template> ");
- break;
- case backed_up:
- if (iloc == null)
- tprint_nl("<recently read> ");
- else
- tprint_nl("<to be read again> ");
- break;
- case inserted:
- tprint_nl("<inserted text> ");
- break;
- case macro:
- print_ln();
- print_cs(iname);
- break;
- case output_text:
- tprint_nl("<output> ");
- break;
- case every_par_text:
- tprint_nl("<everypar> ");
- break;
- case every_math_text:
- tprint_nl("<everymath> ");
- break;
- case every_display_text:
- tprint_nl("<everydisplay> ");
- break;
- case every_hbox_text:
- tprint_nl("<everyhbox> ");
- break;
- case every_vbox_text:
- tprint_nl("<everyvbox> ");
- break;
- case every_job_text:
- tprint_nl("<everyjob> ");
- break;
- case every_cr_text:
- tprint_nl("<everycr> ");
- break;
- case mark_text:
- tprint_nl("<mark> ");
- break;
- case every_eof_text:
- tprint_nl("<everyeof> ");
- break;
- case write_text:
- tprint_nl("<write> ");
- break;
- case local_text:
- tprint_nl("<local> ");
- break;
- default:
- tprint_nl("?");
- /*tex This should never happen. */
- break;
- }
-}
-
-/*tex
-
-Here it is necessary to explain a little trick. We don't want to store a long
-string that corresponds to a token list, because that string might take up lots
-of memory; and we are printing during a time when an error message is being
-given, so we dare not do anything that might overflow one of \TeX's tables. So
-`pseudoprinting' is the answer: We enter a mode of printing that stores
-characters into a buffer of length |error_line|, where character $k+1$ is placed
-into \hbox{|trick_buf[k mod error_line]|} if |k<trick_count|, otherwise character
-|k| is dropped. Initially we set |tally:=0| and |trick_count:=1000000|; then when
-we reach the point where transition from line 1 to line 2 should occur, we set
-|first_count:=tally| and |trick_count:=@tmax@>(error_line,
-tally+1+error_line-half_error_line)|. At the end of the pseudoprinting, the
-values of |first_count|, |tally|, and |trick_count| give us all the information
-we need to print the two lines, and all of the necessary text is in |trick_buf|.
-
-Namely, let |l| be the length of the descriptive information that appears on the
-first line. The length of the context information gathered for that line is
-|k=first_count|, and the length of the context information gathered for line~2 is
-$m=\min(|tally|, |trick_count|)-k$. If |l+k<=h|, where |h=half_error_line|, we
-print |trick_buf[0..k-1]| after the descriptive information on line~1, and set
-|n:=l+k|; here |n| is the length of line~1. If $l+k>h$, some cropping is
-necessary, so we set |n:=h| and print `\.{...}' followed by
-$$\hbox{|trick_buf[(l+k-h+3)..k-1]|,}$$ where subscripts of |trick_buf| are
-circular modulo |error_line|. The second line consists of |n|~spaces followed by
-|trick_buf[k..(k+m-1)]|, unless |n+m>error_line|; in the latter case, further
-cropping is done. This is easier to program than to explain.
-
-The following code sets up the print routines so that they will gather the
-desired information.
-
-*/
-
-void set_trick_count(void)
-{
- first_count = tally;
- trick_count = tally + 1 + error_line - half_error_line;
- if (trick_count < error_line)
- trick_count = error_line;
-}
-
-#define begin_pseudoprint() do { \
- l=tally; \
- tally=0; \
- selector=pseudo; \
- trick_count=1000000; \
- } while (0)
-
-#define PSEUDO_PRINT_THE_LINE() do { \
- begin_pseudoprint(); \
- if (buffer[ilimit]==end_line_char_par) { \
- j=ilimit; \
- } else { \
- /*tex Determine the effective end of the line. */ \
- j=ilimit+1; \
- } \
- if (j>0) { \
- for (i=istart;i<=j-1;i++) { \
- if (i==iloc) \
- set_trick_count(); \
- print_char(buffer[i]); \
- } \
- } \
-} while (0)
-
-/*tex
-
-We don't care too much if we stay a bit too much below the max error_line even if
-we have more room on the line. If length is really an issue then any length is.
-After all one can set the length larger.
-
-*/
-
-#define print_valid_utf8(q) do { \
- c = (int)trick_buf[q % error_line]; \
- if (c < 128) { \
- print_char(c); \
- } else if (c < 194) { \
- /* invalid */ \
- } else if (c < 224) { \
- print_char(c); \
- print_char(trick_buf[(q+1) % error_line]); \
- } else if (c < 240) { \
- print_char(c); \
- print_char(trick_buf[(q+1) % error_line]); \
- print_char(trick_buf[(q+2) % error_line]); \
- } else if (c < 245) { \
- print_char(c); \
- print_char(trick_buf[(q+1) % error_line]); \
- print_char(trick_buf[(q+2) % error_line]); \
- print_char(trick_buf[(q+3) % error_line]); \
- } else { \
- /*tex Invalid character! */ \
- } \
-} while (0)
-
-/*tex
-
-This one prints where the scanner is.
-
-*/
-
-void show_context(void)
-{
- /*tex Saved |selector| setting: */
- int old_setting;
- /*tex Number of contexts shown so far, less one: */
- int nn = -1;
- /*tex Have we reached the final context to be shown? */
- boolean bottom_line = false;
- /*tex Index into |buffer|: */
- int i;
- /*tex End of current line in |buffer|: */
- int j;
- /*tex Length of descriptive information on line 1: */
- int l;
- /*tex Context information gathered for line 2: */
- int m;
- /*tex Length of line 1: */
- int n;
- /*tex Starting or ending place in |trick_buf|: */
- int p;
- /*tex Temporary index: */
- int q;
- /*tex Used in sanitizer: */
- int c;
- base_ptr = input_ptr;
- input_stack[base_ptr] = cur_input;
- /*tex Store the current state. */
- while (true) {
- /*tex Enter into the context. */
- cur_input = input_stack[base_ptr];
- if (istate != token_list) {
- if ((iname > 21) || (base_ptr == 0))
- bottom_line = true;
- }
- if ((base_ptr == input_ptr) || bottom_line || (nn < error_context_lines_par)) {
- /*tex Display the current context. */
- if ((base_ptr == input_ptr) || (istate != token_list) || (token_type != backed_up) || (iloc != null)) {
- /*tex
- We omit backed-up token lists that have already been read.
- Get ready to count characters.
- */
- tally = 0;
- old_setting = selector;
- if (istate != token_list) {
- /*tex
- Print the location of the current line. This routine
- should be changed, if necessary, to give the best
- possible indication of where the current line resides in
- the input file. For example, on some systems it is best
- to print both a page and line number.
- */
- if (iname <= 17) {
- if (terminal_input) {
- if (base_ptr == 0)
- tprint_nl("<*>");
- else
- tprint_nl("<insert> ");
- } else {
- tprint_nl("<read ");
- if (iname == 17)
- print_char('*');
- else
- print_int(iname - 1);
- print_char('>');
- };
- } else {
- tprint_nl("l.");
- if (iindex == in_open) {
- print_int(line);
- } else {
- /*tex Input from a pseudo file. */
- print_int(line_stack[iindex + 1]);
- }
- }
- print_char(' ');
- PSEUDO_PRINT_THE_LINE();
- } else {
- print_token_list_type(token_type);
-
- begin_pseudoprint();
- if (token_type < macro) {
- show_token_list(istart, iloc, 100000);
- } else {
- /*tex Avoid reference count. */
- show_token_list(token_link(istart), iloc, 100000);
- }
- }
- /*tex Stop pseudoprinting. */
- selector = old_setting;
- /*tex Print two lines using the tricky pseudoprinted information. */
- if (trick_count == 1000000) {
- set_trick_count();
- }
- /*tex The |set_trick_count| must be performed. */
- if (tally < trick_count) {
- m = tally - first_count;
- } else {
- /* The context on line 2: */
- m = trick_count - first_count;
- }
- if (l + first_count <= half_error_line) {
- p = 0;
- n = l + first_count;
- } else {
- tprint("...");
- p = l + first_count - half_error_line + 3;
- n = half_error_line;
- }
- for (q = p; q <= first_count - 1; q++) {
- print_valid_utf8(q);
- }
- print_ln();
- /*tex Print |n| spaces to begin line 2. */
- for (q = 1; q <= n; q++) {
- print_char(' ');
- }
- if (m + n <= error_line)
- p = first_count + m;
- else
- p = first_count + (error_line - n - 3);
- for (q = first_count; q <= p - 1; q++)
- print_valid_utf8(q);
- if (m + n > error_line)
- tprint("...");
- incr(nn);
- }
- } else if (nn == error_context_lines_par) {
- tprint_nl("...");
- incr(nn);
- /*tex Omitted if |error_context_lines_par<0|. */
- }
- if (bottom_line)
- break;
- decr(base_ptr);
- }
- /*tex Restore the original state. */
- cur_input = input_stack[input_ptr];
-}
-
-/*tex
-
-The following subroutines change the input status in commonly needed ways.
-
-First comes |push_input|, which stores the current state and creates a
-new level (having, initially, the same properties as the old).
-
-Enter a new input level, save the old:
-
-*/
-
-# define pop_input() \
- cur_input=input_stack[--input_ptr]
-
-# define push_input() \
- if (input_ptr > max_in_stack) { \
- max_in_stack = input_ptr; \
- if (input_ptr == stack_size) \
- overflow("input stack size", (unsigned) stack_size); \
- } \
- input_stack[input_ptr] = cur_input; \
- nofilter = false; \
- incr(input_ptr);
-
-/*tex
-
-Here is a procedure that starts a new level of token-list input, given a token
-list |p| and its type |t|. If |t=macro|, the calling routine should set |name|
-and |loc|.
-
-*/
-
-void begin_token_list(halfword p, quarterword t)
-{
- push_input();
- istate = token_list;
- istart = p;
- token_type = (unsigned char) t;
- if (t >= macro) {
- /*tex The token list starts with a reference count. */
- add_token_ref(p);
- if (t == macro) {
- param_start = param_ptr;
- } else {
- iloc = token_link(p);
- if (tracing_macros_par > 1) {
- begin_diagnostic();
- // tprint_nl("");
- print_input_level();
- if (t == mark_text)
- tprint_esc("mark");
- else if (t == write_text)
- tprint_esc("write");
- else
- print_cmd_chr(assign_toks_cmd, t - output_text + output_routine_loc);
- tprint("->");
- token_show(p);
- end_diagnostic(false);
- }
- }
- } else {
- iloc = p;
- }
-}
-
-/*tex
-
-When a token list has been fully scanned, the following computations should be
-done as we leave that level of input. The |token_type| tends to be equal to
-either |backed_up| or |inserted| about 2/3 of the time. @^inner loop@>
-
-*/
-
-void end_token_list(void)
-{
- /*tex Leave a token-list input level: */
- if (token_type >= backed_up) {
- /*tex The token list to be deleted: */
- if (token_type <= inserted) {
- flush_list(istart);
- } else {
- /*tex Update the reference count: */
- delete_token_ref(istart);
- if (token_type == macro) {
- /*tex Parameters must be flushed: */
- while (param_ptr > param_start) {
- decr(param_ptr);
- flush_list(param_stack[param_ptr]);
- }
- }
- }
- } else if (token_type == u_template) {
- if (align_state > 500000)
- align_state = 0;
- else
- fatal_error("(interwoven alignment preambles are not allowed)");
- }
- pop_input();
- check_interrupt();
-}
-
-/*tex
-
-Sometimes \TeX\ has read too far and wants to ``unscan'' what it has seen. The
-|back_input| procedure takes care of this by putting the token just scanned back
-into the input stream, ready to be read again. This procedure can be used only if
-|cur_tok| represents the token to be replaced. Some applications of \TeX\ use
-this procedure a lot, so it has been slightly optimized for speed. @^inner loop@>
-
-*/
-
-/* undoes one token of input */
-
-void back_input(void)
-{
- /*tex A token list of length one: */
- halfword p;
- while ((istate == token_list) && (iloc == null) && (token_type != v_template)) {
- /*tex Conserve stack space. */
- end_token_list();
- }
- p = get_avail();
- set_token_info(p, cur_tok);
- if (cur_tok < right_brace_limit) {
- if (cur_tok < left_brace_limit)
- decr(align_state);
- else
- incr(align_state);
- }
- push_input();
- /*tex This is |back_list(p)|, without procedure overhead: */
- istate = token_list;
- istart = p;
- token_type = backed_up;
- iloc = p;
-}
-
-/*tex
-
-Insert token |p| into \TeX's input
-
-*/
-
-void reinsert_token(boolean a, halfword pp)
-{
- halfword t;
- t = cur_tok;
- cur_tok = pp;
- if (a) {
- halfword p;
- p = get_avail();
- set_token_info(p, cur_tok);
- set_token_link(p, iloc);
- iloc = p;
- istart = p;
- if (cur_tok < right_brace_limit) {
- if (cur_tok < left_brace_limit)
- decr(align_state);
- else
- incr(align_state);
- }
- } else {
- back_input();
- }
- cur_tok = t;
-}
-
-/*tex
-
-The |begin_file_reading| procedure starts a new level of input for lines of
-characters to be read from a file, or as an insertion from the terminal. It does
-not take care of opening the file, nor does it set |loc| or |limit| or |line|.
-@^system dependencies@>
-
-*/
-
-void begin_file_reading(void)
-{
- if (in_open == max_in_open)
- overflow("text input levels", (unsigned) max_in_open);
- if (first == buf_size)
- check_buffer_overflow(first);
- incr(in_open);
- push_input();
- iindex = (unsigned short)(in_open);
- source_filename_stack[iindex] = 0;
- full_source_filename_stack[iindex] = NULL;
- eof_seen[iindex] = false;
- grp_stack[iindex] = cur_boundary;
- if_stack[iindex] = cond_ptr;
- line_stack[iindex] = line;
- istart = first;
- istate = mid_line;
- iname = 0;
- /*tex Variable |terminal_input| is now |true|. */
- line_catcode_table = DEFAULT_CAT_TABLE;
- line_partial = false;
- /*tex Prepare terminal input \SYNCTEX\ information. */
- synctex_tag = 0;
-}
-
-/*tex
-
-Conversely, the variables must be downdated when such a level of input is
-finished:
-
-*/
-
-void end_file_reading(void)
-{
- first = istart;
- line = line_stack[iindex];
- if ((iname >= 18) && (iname <= 20)) {
- pseudo_close();
- } else if (iname == 21) {
- luacstring_close(iindex);
- } else if (iname > 17) {
- /*tex Forget it. */
- lua_a_close_in(cur_file, 0);
- source_filename_stack[iindex] = 0;
- if (full_source_filename_stack[iindex] != NULL) {
- free(full_source_filename_stack[iindex]);
- full_source_filename_stack[iindex] = NULL;
- }
- }
- pop_input();
- decr(in_open);
-}
-
-/*tex
-
-In order to keep the stack from overflowing during a long sequence of
-inserted `\.{\\show}' commands, the following routine removes completed
-error-inserted lines from memory.
-
-*/
-void clear_for_error_prompt(void)
-{
- while ((istate != token_list) && terminal_input && (input_ptr > 0) && (iloc > ilimit)) {
- end_file_reading();
- }
- print_ln();
- clear_terminal();
-}
-
-/*tex
-
-To get \TeX's whole input mechanism going, we perform the following actions.
-
-*/
-
-void initialize_inputstack(void)
-{
- input_ptr = 0;
- max_in_stack = 0;
- source_filename_stack[0] = 0;
-
- full_source_filename_stack[0] = NULL;
- in_open = 0;
- open_parens = 0;
- max_buf_stack = 0;
-
- grp_stack[0] = 0;
- if_stack[0] = null;
- param_ptr = 0;
- max_param_stack = 0;
- first = buf_size;
- do {
- buffer[first] = 0;
- decr(first);
- } while (first != 0);
- scanner_status = normal;
- warning_index = null;
- first = 1;
- istate = new_line;
- istart = 1;
- iindex = 0;
- line = 0;
- iname = 0;
- nofilter = false;
- force_eof = false;
- luacstrings = 0;
- line_catcode_table = DEFAULT_CAT_TABLE;
- line_partial = false;
- align_state = 1000000;
- if (!init_terminal()) {
- /*tex |goto final_end|; */
- exit(EXIT_FAILURE);
- }
- /* |init_terminal| has set |loc| and |last| */
- ilimit = last;
- first = last + 1;
-}
-
-/*tex
-
-The global variable |pseudo_files| is used to maintain a stack of pseudo files.
-The |pseudo_lines| field of each pseudo file points to a linked list of variable
-size nodes representing lines not yet processed: the |subtype| field contains the
-size of this node, all the following words contain ASCII codes.
-
-If this is really critical code (which it isn't) then we can consider a c stack
-and store a pointer to a line in the line node instead which saves splitting here
-and reconstructing later.
-
-*/
-
-halfword pseudo_files;
-
-static halfword string_to_pseudo(str_number str, int nl)
-{
- halfword i, r, q = null;
- unsigned l, len;
- four_quarters w;
- int sz;
- halfword h = new_node(pseudo_file_node, 0);
- unsigned char *s = str_string(str);
- len = (unsigned) str_length(str);
- l = 0;
- while (l < len) {
- /*tex start of current line */
- unsigned m = l;
- while ((l < len) && (s[l] != nl))
- l++;
- sz = (int) (l - m + 7) / 4;
- if (sz == 1)
- sz = 2;
- r = new_node(pseudo_line_node, sz);
- i = r;
- while (--sz > 1) {
- w.b0 = s[m++];
- w.b1 = s[m++];
- w.b2 = s[m++];
- w.b3 = s[m++];
- varmem[++i].qqqq = w;
- }
- w.b0 = (quarterword) (l > m ? s[m++] : ' ');
- w.b1 = (quarterword) (l > m ? s[m++] : ' ');
- w.b2 = (quarterword) (l > m ? s[m++] : ' ');
- w.b3 = (quarterword) (l > m ? s[m] : ' ');
- varmem[++i].qqqq = w;
- if (q == null) {
- pseudo_lines(h) = r;
- } else {
- /*tex There is no |prev| node here so no need to couple_nodes! */
- vlink(q) = r ;
- }
- q = r ;
- if (s[l] == nl)
- l++;
- }
- return h;
-}
-
-/*tex
-
-The |pseudo_start| procedure initiates reading from a pseudo file.
-
-*/
-
-void pseudo_from_string(void)
-{
- /*tex The string to be converted into a pseudo file: */
- str_number s;
- /*tex A helper for list construction: */
- halfword p;
- s = make_string();
- /*tex Convert string |s| into a new pseudo file */
- p = string_to_pseudo(s, new_line_char_par);
- vlink(p) = pseudo_files;
- pseudo_files = p;
- flush_str(s);
- /*tex
- Initiate input from new pseudo file. It sets up |cur_file| and a new level
- of input
- */
- begin_file_reading();
- line = 0;
- ilimit = istart;
- /*tex force line read */
- iloc = ilimit + 1;
- if (tracing_scan_tokens_par > 0) {
- if (term_offset > max_print_line - 3)
- print_ln();
- else if ((term_offset > 0) || (file_offset > 0))
- print_char(' ');
- iname = 20;
- tprint("( ");
- incr(open_parens);
- update_terminal();
- } else {
- iname = 18;
- }
- /*tex Prepare pseudo file \SYNCTEX\ information. */
- synctex_tag = 0;
-}
-
-void pseudo_start(void)
-{
- int old_setting;
- scan_general_text();
- old_setting = selector;
- selector = new_string;
- token_show(temp_token_head);
- selector = old_setting;
- flush_list(token_link(temp_token_head));
- str_room(1);
- pseudo_from_string();
-}
-
-void lua_string_start(void)
-{
- /*tex Set up |cur_file| and a new level of input: */
- begin_file_reading();
- line = 0;
- ilimit = istart;
- /*tex Force line read: */
- iloc = ilimit + 1;
- iname = 21;
- luacstring_start(iindex);
-}
-
-/*tex
-
-Here we read a line from the current pseudo file into |buffer|.
-It inputs the next line or returns |false|.
-
-*/
-
-boolean pseudo_input(void)
-{
- /*tex The current line from pseudo file: */
- halfword p;
- /*tex The size of node |p|: */
- int sz;
- /*tex Four ASCII codes: */
- four_quarters w;
- /*tex The loop index: */
- halfword r;
- /*tex cf.\ Matthew 19\thinspace:\thinspace30 */
- last = first;
- p = pseudo_lines(pseudo_files);
- if (p == null) {
- return false;
- } else {
- pseudo_lines(pseudo_files) = vlink(p);
- sz = subtype(p);
- if (4 * sz - 3 >= buf_size - last)
- check_buffer_overflow(last + 4 * sz);
- last = first;
- for (r = p + 1; r <= p + sz - 1; r++) {
- w = varmem[r].qqqq;
- buffer[last] = (packed_ASCII_code) w.b0;
- buffer[last + 1] = (packed_ASCII_code) w.b1;
- buffer[last + 2] = (packed_ASCII_code) w.b2;
- buffer[last + 3] = (packed_ASCII_code) w.b3;
- last += 4;
- }
- if (last >= max_buf_stack)
- max_buf_stack = last + 1;
- while ((last > first) && (buffer[last - 1] == ' '))
- decr(last);
- flush_node(p);
- }
- return true;
-}
-
-/*tex
-
-When we are done with a pseudo file we `close' it.
-
-*/
-
-void pseudo_close(void)
-{
- halfword p;
- p = vlink(pseudo_files);
- flush_node(pseudo_files);
- pseudo_files = p;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/inputstack.h b/Build/source/texk/web2c/luatexdir/tex/inputstack.h
deleted file mode 100644
index 0c7669ff3c8..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/inputstack.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* inputstack.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef INPUTSTACK_H
-# define INPUTSTACK_H 1
-
-/*
- The state of \TeX's input mechanism appears in the input stack, whose
- entries are records with six fields, called |state|, |index|, |start|, |loc|,
- |limit|, and |name|.
-*/
-
-typedef struct in_state_record {
- halfword start_field;
- halfword loc_field;
- halfword limit_field;
- halfword name_field;
- int synctex_tag_field; /* stack the tag of the current file */
- unsigned short state_field:16;
- unsigned short index_field:16;
- signed short cattable_field:16; /* category table used by the current line (see textoken.c) */
- boolean partial_field:8; /* is the current line partial? (see textoken.c) */
- boolean nofilter_field:8; /* used by token filtering */
-} in_state_record;
-
-extern in_state_record *input_stack;
-extern int input_ptr;
-extern int max_in_stack;
-extern in_state_record cur_input; /* the ``top'' input state */
-
-# define iloc cur_input.loc_field /* location of first unread character in |buffer| */
-# define istate cur_input.state_field /* current scanner state */
-# define iindex cur_input.index_field /* reference for buffer information */
-# define istart cur_input.start_field /* starting position in |buffer| */
-# define ilimit cur_input.limit_field /* end of current line in |buffer| */
-# define iname cur_input.name_field /* name of the current file */
-# define nofilter cur_input.nofilter_field /* is token filtering explicitly disallowed? */
-# define synctex_tag cur_input.synctex_tag_field /* tag of the current file */
-# define line_catcode_table cur_input.cattable_field
-# define line_partial cur_input.partial_field
-
-/*
-Let's look more closely now at the control variables
-(|state|,~|index|,~|start|,~|loc|,~|limit|,~|name|),
-assuming that \TeX\ is reading a line of characters that have been input
-from some file or from the user's terminal. There is an array called
-|buffer| that acts as a stack of all lines of characters that are
-currently being read from files, including all lines on subsidiary
-levels of the input stack that are not yet completed. \TeX\ will return to
-the other lines when it is finished with the present input file.
-
-(Incidentally, on a machine with byte-oriented addressing, it might be
-appropriate to combine |buffer| with the |str_pool| array,
-letting the buffer entries grow downward from the top of the string pool
-and checking that these two tables don't bump into each other.)
-
-The line we are currently working on begins in position |start| of the
-buffer; the next character we are about to read is |buffer[loc]|; and
-|limit| is the location of the last character present. If |loc>limit|,
-the line has been completely read. Usually |buffer[limit]| is the
-|end_line_char|, denoting the end of a line, but this is not
-true if the current line is an insertion that was entered on the user's
-terminal in response to an error message.
-
-The |name| variable is a string number that designates the name of
-the current file, if we are reading a text file. It is zero if we
-are reading from the terminal; it is |n+1| if we are reading from
-input stream |n|, where |0<=n<=16|. (Input stream 16 stands for
-an invalid stream number; in such cases the input is actually from
-the terminal, under control of the procedure |read_toks|.)
-Finally |18<=name<=20| indicates that we are reading a pseudo file
-created by the \.{\\scantokens} or \.{\\scantextokens} command.
-
-The |state| variable has one of three values, when we are scanning such
-files:
-$$\baselineskip 15pt\vbox{\halign{#\hfil\cr
-1) |state=mid_line| is the normal state.\cr
-2) |state=skip_blanks| is like |mid_line|, but blanks are ignored.\cr
-3) |state=new_line| is the state at the beginning of a line.\cr}}$$
-These state values are assigned numeric codes so that if we add the state
-code to the next character's command code, we get distinct values. For
-example, `|mid_line+spacer|' stands for the case that a blank
-space character occurs in the middle of a line when it is not being
-ignored; after this case is processed, the next value of |state| will
-be |skip_blanks|.
-*/
-
-# define max_char_code 15 /* largest catcode for individual characters */
-
-typedef enum {
- mid_line = 1, /* |state| code when scanning a line of characters */
- skip_blanks = 2 + max_char_code, /* |state| code when ignoring blanks */
- new_line = 3 + max_char_code + max_char_code, /* |state| code at start of line */
-} state_codes;
-
-/*
-Additional information about the current line is available via the
-|index| variable, which counts how many lines of characters are present
-in the buffer below the current level. We have |index=0| when reading
-from the terminal and prompting the user for each line; then if the user types,
-e.g., `\.{\\input paper}', we will have |index=1| while reading
-the file \.{paper.tex}. However, it does not follow that |index| is the
-same as the input stack pointer, since many of the levels on the input
-stack may come from token lists. For example, the instruction `\.{\\input
-paper}' might occur in a token list.
-
-The global variable |in_open| is equal to the |index|
-value of the highest non-token-list level. Thus, the number of partially read
-lines in the buffer is |in_open+1|, and we have |in_open=index|
-when we are not reading a token list.
-
-If we are not currently reading from the terminal, or from an input
-stream, we are reading from the file variable |input_file[index]|. We use
-the notation |terminal_input| as a convenient abbreviation for |name=0|,
-and |cur_file| as an abbreviation for |input_file[index]|.
-
-The global variable |line| contains the line number in the topmost
-open file, for use in error messages. If we are not reading from
-the terminal, |line_stack[index]| holds the line number for the
-enclosing level, so that |line| can be restored when the current
-file has been read. Line numbers should never be negative, since the
-negative of the current line number is used to identify the user's output
-routine in the |mode_line| field of the semantic nest entries.
-
-If more information about the input state is needed, it can be
-included in small arrays like those shown here. For example,
-the current page or segment number in the input file might be
-put into a variable |@!page|, maintained for enclosing levels in
-`\ignorespaces|@!page_stack:array[1..max_in_open] of integer|\unskip'
-by analogy with |line_stack|.
-@^system dependencies@>
-*/
-
-# define terminal_input (iname==0) /* are we reading from the terminal? */
-# define cur_file input_file[iindex] /* the current |alpha_file| variable */
-
-extern int in_open;
-extern int open_parens;
-extern alpha_file *input_file;
-extern int line;
-extern int *line_stack;
-extern str_number *source_filename_stack;
-extern char **full_source_filename_stack;
-
-/*
-Users of \TeX\ sometimes forget to balance left and right braces properly,
-and one of the ways \TeX\ tries to spot such errors is by considering an
-input file as broken into subfiles by control sequences that
-are declared to be \.{\\outer}.
-
-A variable called |scanner_status| tells \TeX\ whether or not to complain
-when a subfile ends. This variable has six possible values:
-
-\yskip\hang|normal|, means that a subfile can safely end here without incident.
-
-\yskip\hang|skipping|, means that a subfile can safely end here, but not a file,
-because we're reading past some conditional text that was not selected.
-
-\yskip\hang|defining|, means that a subfile shouldn't end now because a
-macro is being defined.
-
-\yskip\hang|matching|, means that a subfile shouldn't end now because a
-macro is being used and we are searching for the end of its arguments.
-
-\yskip\hang|aligning|, means that a subfile shouldn't end now because we are
-not finished with the preamble of an \.{\\halign} or \.{\\valign}.
-
-\yskip\hang|absorbing|, means that a subfile shouldn't end now because we are
-reading a balanced token list for \.{\\message}, \.{\\write}, etc.
-
-\yskip\noindent
-If the |scanner_status| is not |normal|, the variable |warning_index| points
-to the |eqtb| location for the relevant control sequence name to print
-in an error message.
-*/
-
-typedef enum {
- skipping = 1, /* |scanner_status| when passing conditional text */
- defining = 2, /* |scanner_status| when reading a macro definition */
- matching = 3, /* |scanner_status| when reading macro arguments */
- aligning = 4, /* |scanner_status| when reading an alignment preamble */
- absorbing = 5, /* |scanner_status| when reading a balanced text */
-} scanner_states;
-
-extern int scanner_status;
-extern pointer warning_index;
-extern pointer def_ref;
-
-extern void runaway(void);
-
-/*
-However, the discussion about input state really applies only to the
-case that we are inputting from a file. There is another important case,
-namely when we are currently getting input from a token list. In this case
-|state=token_list|, and the conventions about the other state variables
-are different:
-
-\yskip\hang|loc| is a pointer to the current node in the token list, i.e.,
-the node that will be read next. If |loc=null|, the token list has been
-fully read.
-
-\yskip\hang|start| points to the first node of the token list; this node
-may or may not contain a reference count, depending on the type of token
-list involved.
-
-\yskip\hang|token_type|, which takes the place of |index| in the
-discussion above, is a code number that explains what kind of token list
-is being scanned.
-
-\yskip\hang|name| points to the |eqtb| address of the control sequence
-being expanded, if the current token list is a macro.
-
-\yskip\hang|param_start|, which takes the place of |limit|, tells where
-the parameters of the current macro begin in the |param_stack|, if the
-current token list is a macro.
-
-\yskip\noindent The |token_type| can take several values, depending on
-where the current token list came from:
-
-\yskip\hang|parameter|, if a parameter is being scanned;
-
-\hang|u_template|, if the \<u_j> part of an alignment
-template is being scanned;
-
-\hang|v_template|, if the \<v_j> part of an alignment
-template is being scanned;
-
-\hang|backed_up|, if the token list being scanned has been inserted as
-`to be read again'.
-
-\hang|inserted|, if the token list being scanned has been inserted as
-the text expansion of a \.{\\count} or similar variable;
-
-\hang|macro|, if a user-defined control sequence is being scanned;
-
-\hang|output_text|, if an \.{\\output} routine is being scanned;
-
-\hang|every_par_text|, if the text of \.{\\everypar} is being scanned;
-
-\hang|every_math_text|, if the text of \.{\\everymath} is being scanned;
-
-\hang|every_display_text|, if the text of \.{\\everydisplay} is being scanned;
-
-\hang|every_hbox_text|, if the text of \.{\\everyhbox} is being scanned;
-
-\hang|every_vbox_text|, if the text of \.{\\everyvbox} is being scanned;
-
-\hang|every_job_text|, if the text of \.{\\everyjob} is being scanned;
-
-\hang|every_cr_text|, if the text of \.{\\everycr} is being scanned;
-
-\hang|mark_text|, if the text of a \.{\\mark} is being scanned;
-
-\hang|write_text|, if the text of a \.{\\write} is being scanned.
-
-\yskip\noindent
-The codes for |output_text|, |every_par_text|, etc., are equal to a constant
-plus the corresponding codes for token list parameters |output_routine_loc|,
-|every_par_loc|, etc.
-
-The token list begins with a reference count if and
-only if |token_type>=macro|.
-@^reference counts@>
-
-Since \eTeX's additional token list parameters precede |toks_base|, the
-corresponding token types must precede |write_text|.
-*/
-
-# define token_list 0 /* |state| code when scanning a token list */
-# define token_type iindex /* type of current token list */
-# define param_start ilimit /* base of macro parameters in |param_stack| */
-
-
-typedef enum {
- parameter = 0, /* |token_type| code for parameter */
- u_template = 1, /* |token_type| code for \<u_j> template */
- v_template = 2, /* |token_type| code for \<v_j> template */
- backed_up = 3, /* |token_type| code for text to be reread */
- inserted = 4, /* |token_type| code for inserted texts */
- macro = 5, /* |token_type| code for defined control sequences */
- output_text = 6, /* |token_type| code for output routines */
- every_par_text = 7, /* |token_type| code for \.{\\everypar} */
- every_math_text = 8, /* |token_type| code for \.{\\everymath} */
- every_display_text = 9, /* |token_type| code for \.{\\everydisplay} */
- every_hbox_text = 10, /* |token_type| code for \.{\\everyhbox} */
- every_vbox_text = 11, /* |token_type| code for \.{\\everyvbox} */
- every_job_text = 12, /* |token_type| code for \.{\\everyjob} */
- every_cr_text = 13, /* |token_type| code for \.{\\everycr} */
- mark_text = 14, /* |token_type| code for \.{\\topmark}, etc. */
- every_eof_text = 15, /* |token_type| code for \.{\\everyeof} */
- write_text = 16, /* |token_type| code for \.{\\write} */
- local_text = 17, /* |token_type| code for special purposed */
-} token_types;
-
-extern pointer *param_stack;
-extern int param_ptr;
-extern int max_param_stack;
-
-extern int align_state;
-
-extern int base_ptr;
-
-extern void show_context(void);
-extern void set_trick_count(void);
-
-# define back_list(A) begin_token_list(A,backed_up) /* backs up a simple token list */
-# define ins_list(A) begin_token_list(A,inserted) /* inserts a simple token list */
-
-extern void begin_token_list(halfword p, quarterword t);
-extern void end_token_list(void);
-extern void back_input(void);
-extern void reinsert_token(boolean a, halfword pp);
-extern void begin_file_reading(void);
-extern void end_file_reading(void);
-extern void clear_for_error_prompt(void);
-
-extern void initialize_inputstack(void);
-
-extern halfword pseudo_files;
-extern void pseudo_from_string(void);
-extern void pseudo_start(void);
-extern void lua_string_start(void);
-extern boolean pseudo_input(void);
-extern void pseudo_close(void);
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.c b/Build/source/texk/web2c/luatexdir/tex/linebreak.c
deleted file mode 100644
index 646a5a771f7..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.c
+++ /dev/null
@@ -1,2537 +0,0 @@
-/*
-
-Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
- We come now to what is probably the most interesting algorithm of \TeX: the
- mechanism for choosing the ``best possible'' breakpoints that yield the
- individual lines of a paragraph. \TeX's line-breaking algorithm takes a given
- horizontal list and converts it to a sequence of boxes that are appended to
- the current vertical list. In the course of doing this, it creates a special
- data structure containing three kinds of records that are not used elsewhere
- in \TeX. Such nodes are created while a paragraph is being processed, and
- they are destroyed afterwards; thus, the other parts of \TeX\ do not need to
- know anything about how line-breaking is done.
-
- The method used here is based on an approach devised by Michael F. Plass and
- the author in 1977, subsequently generalized and improved by the same two
- people in 1980. A detailed discussion appears in {\sl SOFTWARE---Practice
- \AM\ Experience \bf11} (1981), 1119--1184, where it is shown that the
- line-breaking problem can be regarded as a special case of the problem of
- computing the shortest path in an acyclic network. The cited paper includes
- numerous examples and describes the history of line breaking as it has been
- practiced by printers through the ages. The present implementation adds two
- new ideas to the algorithm of 1980: Memory space requirements are
- considerably reduced by using smaller records for inactive nodes than for
- active ones, and arithmetic overflow is avoided by using ``delta distances''
- instead of keeping track of the total distance from the beginning of the
- paragraph to the current point.
-
- The |line_break| procedure should be invoked only in horizontal mode; it
- leaves that mode and places its output into the current vlist of the
- enclosing vertical mode (or internal vertical mode). There is one explicit
- parameter: |d| is true for partial paragraphs preceding display math mode; in
- this case the amount of additional penalty inserted before the final line is
- |display_widow_penalty| instead of |widow_penalty|.
-
- There are also a number of implicit parameters: The hlist to be broken starts
- at |vlink(head)|, and it is nonempty. The value of |prev_graf| in the
- enclosing semantic level tells where the paragraph should begin in the
- sequence of line numbers, in case hanging indentation or \.{\\parshape} are
- in use; |prev_graf| is zero unless this paragraph is being continued after a
- displayed formula. Other implicit parameters, such as the |par_shape_ptr| and
- various penalties to use for hyphenation, etc., appear in |eqtb|.
-
- After |line_break| has acted, it will have updated the current vlist and the
- value of |prev_graf|. Furthermore, the global variable |just_box| will point
- to the final box created by |line_break|, so that the width of this line can
- be ascertained when it is necessary to decide whether to use
- |above_display_skip| or |above_display_short_skip| before a displayed
- formula.
-
-*/
-
-/*tex The |hlist_node| for the last line of the new paragraph: */
-
-halfword just_box;
-
-/*tex
-
- In it's complete form, |line_break| is a rather lengthy procedure---sort of a
- small world unto itself---we must build it up little by little. Below you see
- only the general outline.
-
- The main task performed here is to move the list from |head| to |temp_head|
- and go into the enclosing semantic level. We also append the
- \.{\\parfillskip} glue to the end of the paragraph, removing a space (or
- other glue node) if it was there, since spaces usually precede blank lines
- and instances of `\.{\$\$}'. The |par_fill_skip| is preceded by an infinite
- penalty, so it will never be considered as a potential breakpoint.
-
- That code assumes that a |glue_node| and a |penalty_node| occupy the same
- number of |mem|~words.
-
- Most other processing is delegated to external functions.
-
-*/
-
-void line_break(boolean d, int line_break_context)
-{
- /*tex Main direction of paragraph: */
- int paragraph_dir = 0;
- halfword final_par_glue;
- halfword start_of_par;
- int callback_id;
- /*tex this is for over/underfull box messages */
- pack_begin_line = cur_list.ml_field;
- alink(temp_head) = null;
- vlink(temp_head) = vlink(cur_list.head_field);
- new_hyphenation(temp_head, cur_list.tail_field);
- cur_list.tail_field = new_ligkern(temp_head, cur_list.tail_field);
- if (is_char_node(cur_list.tail_field)) {
- tail_append(new_penalty(inf_penalty,line_penalty));
- } else if (type(cur_list.tail_field) != glue_node) {
- tail_append(new_penalty(inf_penalty,line_penalty));
- } else {
- halfword t = alink(cur_list.tail_field);
- flush_node(cur_list.tail_field);
- cur_list.tail_field = t;
- tail_append(new_penalty(inf_penalty,line_penalty));
- }
- final_par_glue = new_param_glue(par_fill_skip_code);
- couple_nodes(cur_list.tail_field, final_par_glue);
- cur_list.tail_field = vlink(cur_list.tail_field);
- lua_node_filter(pre_linebreak_filter_callback, line_break_context, temp_head, addressof(cur_list.tail_field));
- last_line_fill = cur_list.tail_field;
- pop_nest();
- start_of_par = cur_list.tail_field;
- callback_id = callback_defined(linebreak_filter_callback);
- if (callback_id > 0) {
- callback_id = lua_linebreak_callback(d, temp_head, addressof(cur_list.tail_field));
- if (callback_id > 0) {
- /*tex find the correct value for the |just_box| */
- halfword box_search = cur_list.tail_field;
- just_box = null;
- if (box_search != null) {
- do {
- if (type(box_search) == hlist_node) {
- just_box = box_search;
- }
- box_search = vlink(box_search);
- } while (box_search != null);
- }
- if (just_box == null) {
- help3(
- "A linebreaking routine should return a non-empty list of nodes",
- "and at least one of those has to be a \\hbox.",
- "Sorry, I cannot recover from this."
- );
- print_err("Invalid linebreak_filter");
- succumb();
- }
- } else {
- if (tracing_paragraphs_par > 0) {
- begin_diagnostic();
- print_int(line);
- end_diagnostic(true);
- }
- }
- }
- if (callback_id == 0) {
- if ((!is_char_node(vlink(temp_head))) && ((type(vlink(temp_head)) == local_par_node))) {
- paragraph_dir = local_par_dir(vlink(temp_head));
- } else {
- confusion("weird par dir");
- }
- ext_do_line_break(
- paragraph_dir,
- pretolerance_par,
- tracing_paragraphs_par,
- tolerance_par,
- emergency_stretch_par,
- looseness_par,
- adjust_spacing_par,
- par_shape_par_ptr,
- adj_demerits_par,
- protrude_chars_par,
- line_penalty_par,
- last_line_fit_par,
- double_hyphen_demerits_par,
- final_hyphen_demerits_par,
- hang_indent_par,
- hsize_par,
- hang_after_par,
- left_skip_par,
- right_skip_par,
- inter_line_penalties_par_ptr,
- inter_line_penalty_par,
- club_penalty_par,
- club_penalties_par_ptr,
- (d ? display_widow_penalties_par_ptr : widow_penalties_par_ptr),
- (d ? display_widow_penalty_par : widow_penalty_par),
- broken_penalty_par,
- final_par_glue
- );
- }
- lua_node_filter(post_linebreak_filter_callback, line_break_context, start_of_par, addressof(cur_list.tail_field));
- pack_begin_line = 0;
-}
-
-/*tex
-
- Glue nodes in a horizontal list that is being paragraphed are not supposed to
- include ``infinite'' shrinkability; that is why the algorithm maintains four
- registers for stretching but only one for shrinking. If the user tries to
- introduce infinite shrinkability, the shrinkability will be reset to finite
- and an error message will be issued. A boolean variable |no_shrink_error_yet|
- prevents this error message from appearing more than once per paragraph.
-
-*/
-
-#define check_shrinkage(a) \
- if ((shrink_order((a))!=normal)&&(shrink((a))!=0)) \
- a=finite_shrink((a))
-
-/*tex Have we complained about infinite shrinkage? */
-
-static boolean no_shrink_error_yet;
-
-/*tex Recovers from infinite shrinkage. */
-
-static halfword finite_shrink(halfword p)
-{
- const char *hlp[] = {
- "The paragraph just ended includes some glue that has",
- "infinite shrinkability, e.g., `\\hskip 0pt minus 1fil'.",
- "Such glue doesn't belong there---it allows a paragraph",
- "of any length to fit on one line. But it's safe to proceed,",
- "since the offensive shrinkability has been made finite.",
- NULL
- };
- if (no_shrink_error_yet) {
- no_shrink_error_yet = false;
- tex_error("Infinite glue shrinkage found in a paragraph", hlp);
- }
- shrink_order(p) = normal;
- return p;
-}
-
-/*tex
-
- A pointer variable |cur_p| runs through the given horizontal list as we look
- for breakpoints. This variable is global, since it is used both by
- |line_break| and by its subprocedure |try_break|.
-
- Another global variable called |threshold| is used to determine the
- feasibility of individual lines: breakpoints are feasible if there is a way
- to reach them without creating lines whose badness exceeds |threshold|. (The
- badness is compared to |threshold| before penalties are added, so that
- penalty values do not affect the feasibility of breakpoints, except that no
- break is allowed when the penalty is 10000 or more.) If |threshold| is 10000
- or more, all legal breaks are considered feasible, since the |badness|
- function specified above never returns a value greater than~10000.
-
- Up to three passes might be made through the paragraph in an attempt to find
- at least one set of feasible breakpoints. On the first pass, we have
- |threshold=pretolerance| and |second_pass=final_pass=false|. If this pass
- fails to find a feasible solution, |threshold| is set to |tolerance|,
- |second_pass| is set |true|, and an attempt is made to hyphenate as many
- words as possible. If that fails too, we add |emergency_stretch| to the
- background stretchability and set |final_pass=true|.
-
-*/
-
-/*tex is this our second attempt to break this paragraph? */
-
-static boolean second_pass;
-
-/*tex is this our final attempt to break this paragraph? */
-
-static boolean final_pass;
-
-/*tex maximum badness on feasible lines */
-
-static int threshold;
-
-/*tex
-
- The maximum fill level for |hlist_stack|. Maybe good if larger than |2 *
- max_quarterword|, so that box nesting level would overflow first.
-
-*/
-
-#define max_hlist_stack 512
-
-/*tex stack for |find_protchar_left()| and |find_protchar_right()| */
-
-static halfword hlist_stack[max_hlist_stack];
-
-/*tex fill level for |hlist_stack| */
-
-static short hlist_stack_level = 0;
-
-static void push_node(halfword p)
-{
- if (hlist_stack_level >= max_hlist_stack)
- normal_error("push_node","stack overflow");
- hlist_stack[hlist_stack_level++] = p;
-}
-
-static halfword pop_node(void)
-{
- if (hlist_stack_level <= 0) {
- /*tex This can point to some bug. */
- normal_error("pop_node","stack underflow (internal error)");
- }
- return hlist_stack[--hlist_stack_level];
-}
-
-/*tex maximal stretch ratio of expanded fonts */
-
-static int max_stretch_ratio = 0;
-
-/*tex maximal shrink ratio of expanded fonts */
-
-static int max_shrink_ratio = 0;
-
-/*tex the current step of expanded fonts */
-
-static int cur_font_step = 0;
-
-static boolean check_expand_pars(internal_font_number f)
-{
- int m;
- if ((font_step(f) == 0) || ((font_max_stretch(f) == 0) && (font_max_shrink(f) == 0)))
- return false;
- if (cur_font_step < 0)
- cur_font_step = font_step(f);
- else if (cur_font_step != font_step(f))
- normal_error("font expansion","using fonts with different step of expansion in one paragraph is not allowed");
- m = font_max_stretch(f);
- if (m != 0) {
- if (max_stretch_ratio < 0)
- max_stretch_ratio = m;
- else if (max_stretch_ratio != m)
- normal_error("font expansion","using fonts with different limit of expansion in one paragraph is not allowed");
- }
- m = font_max_shrink(f);
- if (m != 0) {
- if (max_shrink_ratio < 0)
- max_shrink_ratio = -m;
- else if (max_shrink_ratio != -m)
- normal_error("font expansion","using fonts with different limit of expansion in one paragraph is not allowed");
- }
- return true;
-}
-
-/*tex Search left to right from list head |l|, returns 1st non-skipable item */
-
-halfword find_protchar_left(halfword l, boolean d)
-{
- halfword t;
- boolean run;
- boolean done = false ;
- while ((vlink(l) != null) && (type(l) == hlist_node) && zero_dimensions(l) && (list_ptr(l) == null)) {
- /*tex For paragraph start with \.{\\parindent} = 0pt or any empty hbox. */
- l = vlink(l);
- done = true ;
- }
- if ((!done) && (type(l) == local_par_node)) {
- l = vlink(l);
- done = true ;
- }
- if ((!done) && d) {
- while ((vlink(l) != null) && (!(is_char_node(l) || non_discardable(l)))) {
- /*tex standard discardables at line break, \TeX book, p 95 */
- l = vlink(l);
- }
- }
- if (type(l) != glyph_node) {
- hlist_stack_level = 0;
- run = true;
- do {
- t = l;
- while (run && (type(l) == hlist_node) && (list_ptr(l) != null)) {
- push_node(l);
- l = list_ptr(l);
- }
- while (run && cp_skipable(l)) {
- while ((vlink(l) == null) && (hlist_stack_level > 0)) {
- /*tex Don't visit this node again. */
- l = pop_node();
- run = false;
- }
- if ((vlink(l) != null) && (type(l) == boundary_node) && (subtype(l) == protrusion_boundary) &&
- ((boundary_value(l) == 1) || (boundary_value(l) == 3))) {
- /*tex Skip next node. */
- l = vlink(l);
- }
- if (vlink(l) != null) {
- l = vlink(l);
- } else if (hlist_stack_level == 0) {
- run = false;
- }
- }
- } while (t != l);
- }
- return l;
-}
-
-/*tex
-
- Search right to left from list tail |r| to head |l|, returns 1st non-skipable
- item.
-
-*/
-
-halfword find_protchar_right(halfword l, halfword r)
-{
- halfword t;
- boolean run = true;
- if (r == null)
- return null;
- hlist_stack_level = 0;
- do {
- t = r;
- while (run && (type(r) == hlist_node) && (list_ptr(r) != null)) {
- push_node(l);
- push_node(r);
- l = list_ptr(r);
- r = l;
- while (vlink(r) != null) {
- halfword s = r;
- r = vlink(r);
- alink(r) = s;
- }
- }
- while (run && cp_skipable(r)) {
- while ((r == l) && (hlist_stack_level > 0)) {
- /*tex Don't visit this node again. */
- r = pop_node();
- l = pop_node();
- }
- if ((r != l) && (r != null)) {
- if ((alink(r) != null) && (type(r) == boundary_node) && (subtype(r) == protrusion_boundary) &&
- ((boundary_value(r) == 2) || (boundary_value(r) == 3))) {
- /*tex Skip next node. */
- r = alink(r);
- }
- if (alink(r) != null) {
- r = alink(r);
- } else {
- /*tex This is the input: \.{\\leavevmode\\penalty-10000\\penalty-10000} (bug \#268). */
- run = false;
- }
- } else if ((r == l) && (hlist_stack_level == 0))
- run = false;
- }
- } while (t != r);
- return r;
-}
-
-#define left_pw(a) char_pw((a), left_side)
-#define right_pw(a) char_pw((a), right_side)
-
-/*tex
-
- When looking for optimal line breaks, \TeX\ creates a ``break node'' for each
- break that is {\sl feasible}, in the sense that there is a way to end a line
- at the given place without requiring any line to stretch more than a given
- tolerance. A break node is characterized by three things: the position of the
- break (which is a pointer to a |glue_node|, |math_node|, |penalty_node|, or
- |disc_node|); the ordinal number of the line that will follow this
- breakpoint; and the fitness classification of the line that has just ended,
- i.e., |tight_fit|, |decent_fit|, |loose_fit|, or |very_loose_fit|.
-
-*/
-
-typedef enum {
- /*tex fitness classification for lines stretching more than their stretchability */
- very_loose_fit = 0,
- /*tex fitness classification for lines stretching 0.5 to 1.0 of their stretchability */
- loose_fit,
- /*tex fitness classification for all other lines */
- decent_fit,
- /*tex fitness classification for lines shrinking 0.5 to 1.0 of their shrinkability */
- tight_fit
-} fitness_value;
-
-/*tex
-
- The algorithm essentially determines the best possible way to achieve each
- feasible combination of position, line, and fitness. Thus, it answers
- questions like, ``What is the best way to break the opening part of the
- paragraph so that the fourth line is a tight line ending at such-and-such a
- place?'' However, the fact that all lines are to be the same length after a
- certain point makes it possible to regard all sufficiently large line numbers
- as equivalent, when the looseness parameter is zero, and this makes it
- possible for the algorithm to save space and time.
-
- An ``active node'' and a ``passive node'' are created in |mem| for each
- feasible breakpoint that needs to be considered. Active nodes are three words
- long and passive nodes are two words long. We need active nodes only for
- breakpoints near the place in the paragraph that is currently being examined,
- so they are recycled within a comparatively short time after they are
- created.
-
- An active node for a given breakpoint contains six fields:
-
- \startitemize[n]
-
- \startitem
- |vlink| points to the next node in the list of active nodes; the last
- active node has |vlink=active|.
- \stopitem
-
- \startitem
- |break_node| points to the passive node associated with this
- breakpoint.
- \stopitem
-
- \startitem
- |line_number| is the number of the line that follows this breakpoint.
- \stopitem
-
- \startitem
- |fitness| is the fitness classification of the line ending at this
- breakpoint.
- \stopitem
-
- \startitem
- |type| is either |hyphenated_node| or |unhyphenated_node|, depending
- on whether this breakpoint is a |disc_node|.
- \stopitem
-
- \startitem
- |total_demerits| is the minimum possible sum of demerits over all
- lines leading from the beginning of the paragraph to this breakpoint.
- \stopitem
-
- \stopitemize
-
- The value of |vlink(active)| points to the first active node on a vlinked
- list of all currently active nodes. This list is in order by |line_number|,
- except that nodes with |line_number>easy_line| may be in any order relative
- to each other.
-
-*/
-
-void initialize_active(void)
-{
- type(active) = hyphenated_node;
- line_number(active) = max_halfword;
- /*tex The |subtype| is never examined. */
- subtype(active) = 0;
-}
-
-/*tex
-
- The passive node for a given breakpoint contains eight fields:
-
- \startitemize
-
- \startitem
- |vlink| points to the passive node created just before this one, if
- any, otherwise it is |null|.
- \stopitem
-
- \startitem
- |cur_break| points to the position of this breakpoint in the
- horizontal list for the paragraph being broken.
- \stopitem
-
- \startitem
- |prev_break| points to the passive node that should precede this one
- in an optimal path to this breakpoint.
- \stopitem
-
- \startitem
- |serial| is equal to |n| if this passive node is the |n|th one
- created during the current pass. (This field is used only when
- printing out detailed statistics about the line-breaking
- calculations.)
- \stopitem
-
- \startitem
- |passive_pen_inter| holds the current \.{\\localinterlinepenalty}
- \stopitem
-
- \startitem
- |passive_pen_broken| holds the current \.{\\localbrokenpenalty}
- \stopitem
-
- \stopitemize
-
- There is a global variable called |passive| that points to the most recently
- created passive node. Another global variable, |printed_node|, is used to
- help print out the paragraph when detailed information about the
- line-breaking computation is being displayed.
-
-*/
-
-/*tex most recent node on passive list */
-
-static halfword passive;
-
-/*tex most recent node that has been printed */
-
-static halfword printed_node;
-
-/*tex the number of passive nodes allocated on this pass */
-
-static halfword pass_number;
-
-/*tex
-
- The active list also contains ``delta'' nodes that help the algorithm compute
- the badness of individual lines. Such nodes appear only between two active
- nodes, and they have |type=delta_node|. If |p| and |r| are active nodes and
- if |q| is a delta node between them, so that |vlink(p)=q| and |vlink(q)=r|,
- then |q| tells the space difference between lines in the horizontal list that
- start after breakpoint |p| and lines that start after breakpoint |r|. In
- other words, if we know the length of the line that starts after |p| and ends
- at our current position, then the corresponding length of the line that
- starts after |r| is obtained by adding the amounts in node~|q|. A delta node
- contains seven scaled numbers, since it must record the net change in glue
- stretchability with respect to all orders of infinity. The natural width
- difference appears in |mem[q+1].sc|; the stretch differences in units of pt,
- sfi, fil, fill, and filll appear in |mem[q+2..q+6].sc|; and the shrink
- difference appears in |mem[q+7].sc|. The |subtype| field of a delta node is
- not used.
-
- Actually, we have two more fields that are used by |pdftex|.
-
- As the algorithm runs, it maintains a set of seven delta-like registers for
- the length of the line following the first active breakpoint to the current
- position in the given hlist. When it makes a pass through the active list, it
- also maintains a similar set of seven registers for the length following the
- active breakpoint of current interest. A third set holds the length of an
- empty line (namely, the sum of \.{\\leftskip} and \.{\\rightskip}); and a
- fourth set is used to create new delta nodes.
-
- When we pass a delta node we want to do operations like:
-
- \starttyping
- for k := 1 to 7 do
- cur_active_width[k] := cur_active_width[k] + mem[q+k].sc|};
- \stoptyping
-
- and we want to do this without the overhead of |for| loops. The |do_all_six|
- macro makes such six-tuples convenient.
-
-*/
-
-/*tex distance from first active node to~|cur_p| */
-
-static scaled active_width[10] = { 0 };
-
-/*tex length of an ``empty'' line */
-
-static scaled background[10] = { 0 };
-
-/*tex length being computed after current break */
-
-static scaled break_width[10] = { 0 };
-
-/*tex Make |auto_breaking| accessible out of |line_break|: */
-
-static boolean auto_breaking;
-
-/*tex
-
- Let's state the principles of the delta nodes more precisely and concisely,
- so that the following programs will be less obscure. For each legal
- breakpoint~|p| in the paragraph, we define two quantities $\alpha(p)$ and
- $\beta(p)$ such that the length of material in a line from breakpoint~|p| to
- breakpoint~|q| is $\gamma+\beta(q)-\alpha(p)$, for some fixed $\gamma$.
- Intuitively, $\alpha(p)$ and $\beta(q)$ are the total length of material from
- the beginning of the paragraph to a point ``after'' a break at |p| and to a
- point ``before'' a break at |q|; and $\gamma$ is the width of an empty line,
- namely the length contributed by \.{\\leftskip} and \.{\\rightskip}.
-
- Suppose, for example, that the paragraph consists entirely of alternating
- boxes and glue skips; let the boxes have widths $x_1\ldots x_n$ and let the
- skips have widths $y_1\ldots y_n$, so that the paragraph can be represented
- by $x_1y_1\ldots x_ny_n$. Let $p_i$ be the legal breakpoint at $y_i$; then
- $\alpha(p_i)=x_1+y_1+\cdots+x_i+y_i$, and $\beta(p_i)= x_1+y_1+\cdots+x_i$.
- To check this, note that the length of material from $p_2$ to $p_5$, say, is
- $\gamma+x_3+y_3+x_4+y_4+x_5=\gamma+\beta(p_5) -\alpha(p_2)$.
-
- The quantities $\alpha$, $\beta$, $\gamma$ involve glue stretchability and
- shrinkability as well as a natural width. If we were to compute $\alpha(p)$
- and $\beta(p)$ for each |p|, we would need multiple precision arithmetic, and
- the multiprecise numbers would have to be kept in the active nodes. \TeX\
- avoids this problem by working entirely with relative differences or
- ``deltas.'' Suppose, for example, that the active list contains
- $a_1\,\delta_1\,a_2\,\delta_2\,a_3$, where the |a|'s are active breakpoints
- and the $\delta$'s are delta nodes. Then $\delta_1=\alpha(a_1)-\alpha(a_2)$
- and $\delta_2=\alpha(a_2)-\alpha(a_3)$. If the line breaking algorithm is
- currently positioned at some other breakpoint |p|, the |active_width| array
- contains the value $\gamma+\beta(p)-\alpha(a_1)$. If we are scanning through
- the list of active nodes and considering a tentative line that runs from
- $a_2$ to~|p|, say, the |cur_active_width| array will contain the value
- $\gamma+\beta(p)-\alpha(a_2)$. Thus, when we move from $a_2$ to $a_3$, we
- want to add $\alpha(a_2)-\alpha(a_3)$ to |cur_active_width|; and this is just
- $\delta_2$, which appears in the active list between $a_2$ and $a_3$. The
- |background| array contains $\gamma$. The |break_width| array will be used to
- calculate values of new delta nodes when the active list is being updated.
-
- The heart of the line-breaking procedure is `|try_break|', a subroutine that
- tests if the current breakpoint |cur_p| is feasible, by running through the
- active list to see what lines of text can be made from active nodes
- to~|cur_p|. If feasible breaks are possible, new break nodes are created. If
- |cur_p| is too far from an active node, that node is deactivated.
-
- The parameter |pi| to |try_break| is the penalty associated with a break at
- |cur_p|; we have |pi=eject_penalty| if the break is forced, and
- |pi=inf_penalty| if the break is illegal.
-
- The other parameter, |break_type|, is set to |hyphenated_node| or
- |unhyphenated_node|, depending on whether or not the current break is at a
- |disc_node|. The end of a paragraph is also regarded as `|hyphenated_node|';
- this case is distinguishable by the condition |cur_p=null|.
-
-*/
-
-/*tex running \.{\\localinterlinepenalty} */
-
-static int internal_pen_inter;
-
-/*tex running \.{\\localbrokenpenalty} */
-
-static int internal_pen_broken;
-
-/*tex running \.{\\localleftbox} */
-
-static halfword internal_left_box;
-
-/*tex running \.{\\localleftbox} width */
-
-static int internal_left_box_width;
-
-/*tex running \.{\\localleftbox} */
-
-static halfword init_internal_left_box;
-
-/*tex running \.{\\localleftbox} width */
-
-static int init_internal_left_box_width;
-
-/*tex running \.{\\localrightbox} */
-
-static halfword internal_right_box;
-
-/*tex running \.{\\localrightbox} width */
-
-static int internal_right_box_width;
-
-/*tex the length of discretionary material preceding a break */
-
-static scaled disc_width[10] = { 0 };
-
-/*tex
-
- As we consider various ways to end a line at |cur_p|, in a given line number
- class, we keep track of the best total demerits known, in an array with one
- entry for each of the fitness classifications. For example,
- |minimal_demerits[tight_fit]| contains the fewest total demerits of feasible
- line breaks ending at |cur_p| with a |tight_fit| line;
- |best_place[tight_fit]| points to the passive node for the break
- before~|cur_p| that achieves such an optimum; and |best_pl_line[tight_fit]|
- is the |line_number| field in the active node corresponding to
- |best_place[tight_fit]|. When no feasible break sequence is known, the
- |minimal_demerits| entries will be equal to |awful_bad|, which is $2^{30}-1$.
- Another variable, |minimum_demerits|, keeps track of the smallest value in
- the |minimal_demerits| array.
-
-*/
-
-/*tex best total demerits known for current line class and position, given the fitness */
-
-static int minimal_demerits[4];
-
-/*tex best total demerits known for current line class and position */
-
-static int minimum_demerits;
-
-/*tex how to achieve |minimal_demerits| */
-
-static halfword best_place[4];
-
-/*tex corresponding line number */
-
-static halfword best_pl_line[4];
-
-/*tex
-
- The length of lines depends on whether the user has specified \.{\\parshape}
- or \.{\\hangindent}. If |par_shape_ptr| is not null, it points to a
- $(2n+1)$-word record in |mem|, where the |vinfo| in the first word contains
- the value of |n|, and the other $2n$ words contain the left margins and line
- lengths for the first |n| lines of the paragraph; the specifications for line
- |n| apply to all subsequent lines. If |par_shape_ptr=null|, the shape of the
- paragraph depends on the value of |n=hang_after|; if |n>=0|, hanging
- indentation takes place on lines |n+1|, |n+2|, \dots, otherwise it takes
- place on lines 1, \dots, $\vert n\vert$. When hanging indentation is active,
- the left margin is |hang_indent|, if |hang_indent>=0|, else it is 0; the line
- length is $|hsize|-\vert|hang_indent|\vert$. The normal setting is
- |par_shape_ptr=null|, |hang_after=1|, and |hang_indent=0|. Note that if
- |hang_indent=0|, the value of |hang_after| is irrelevant.
-
-*/
-
-/*tex line numbers |>easy_line| are equivalent in break nodes */
-
-static halfword easy_line;
-
-/*tex line numbers |>last_special_line| all have the same width */
-
-static halfword last_special_line;
-
-/*tex the width of all lines |<=last_special_line|, if no \.{\\parshape} has been specified */
-
-static scaled first_width;
-
-/*tex the width of all lines |>last_special_line| */
-
-static scaled second_width;
-
-/*tex left margin to go with |first_width| */
-
-static scaled first_indent;
-
-/*tex left margin to go with |second_width| */
-
-static scaled second_indent;
-
-/*tex use this passive node and its predecessors */
-
-static halfword best_bet;
-
-/*tex the demerits associated with |best_bet| */
-
-static int fewest_demerits;
-
-/*tex line number following the last line of the new paragraph */
-
-static halfword best_line;
-
-/*tex the difference between |line_number(best_bet)| and the optimum |best_line| */
-
-static int actual_looseness;
-
-/*tex the difference between the current line number and the optimum |best_line| */
-
-static int line_diff;
-
-/*tex
-
- \TeX\ makes use of the fact that |hlist_node|, |vlist_node|, |rule_node|,
- |ins_node|, |mark_node|, |adjust_node|, |disc_node|, |whatsit_node|, and
- |math_node| are at the low end of the type codes, by permitting a break at
- glue in a list if and only if the |type| of the previous node is less than
- |math_node|. Furthermore, a node is discarded after a break if its type is
- |math_node| or~more.
-
-*/
-
-#define do_all_six(a) a(1);a(2);a(3);a(4);a(5);a(6);a(7)
-#define do_seven_eight(a) if (adjust_spacing > 1) { a(8);a(9); }
-#define do_all_eight(a) do_all_six(a); do_seven_eight(a)
-#define do_one_seven_eight(a) a(1); do_seven_eight(a)
-
-#define store_background(a) {active_width[a]=background[a];}
-
-#define kern_break() { \
- if ((!is_char_node(vlink(cur_p))) && auto_breaking) \
- if (type(vlink(cur_p))==glue_node) \
- ext_try_break(\
- 0, \
- unhyphenated_node, \
- line_break_dir, \
- adjust_spacing, \
- par_shape_ptr, \
- adj_demerits, \
- tracing_paragraphs, \
- protrude_chars, \
- line_penalty, \
- last_line_fit, \
- double_hyphen_demerits, \
- final_hyphen_demerits, \
- first_p, \
- cur_p \
- ); \
- if (type(cur_p)!=math_node) \
- active_width[1] += width(cur_p); \
- else \
- active_width[1] += surround(cur_p); \
-}
-
-#define clean_up_the_memory() { \
- q=vlink(active); \
- while (q!=active) { \
- cur_p = vlink(q); \
- if (type(q)==delta_node) \
- flush_node(q); \
- else \
- flush_node(q); \
- q = cur_p; \
- } \
- q = passive; \
- while (q!=null) { \
- cur_p = vlink(q); \
- flush_node(q); \
- q = cur_p; \
- } \
-}
-
-/*tex special algorithm for last line of paragraph? */
-
-static boolean do_last_line_fit;
-
-/*tex infinite stretch components of |par_fill_skip| */
-
-static scaled fill_width[4];
-
-/*tex |shortfall| corresponding to |minimal_demerits| */
-
-static scaled best_pl_short[4];
-
-/*tex corresponding glue stretch or shrink */
-
-static scaled best_pl_glue[4];
-
-#define reset_disc_width(a) disc_width[(a)] = 0
-
-#define add_disc_width_to_break_width(a) break_width[(a)] += disc_width[(a)]
-#define sub_disc_width_from_active_width(a) active_width[(a)] -= disc_width[(a)]
-
-#define add_char_shrink(a,b) a += char_shrink((b))
-#define add_char_stretch(a,b) a += char_stretch((b))
-#define sub_char_shrink(a,b) a -= char_shrink((b))
-#define sub_char_stretch(a,b) a -= char_stretch((b))
-
-#define add_kern_shrink(a,b) a += kern_shrink((b))
-#define add_kern_stretch(a,b) a += kern_stretch((b))
-#define sub_kern_shrink(a,b) a -= kern_shrink((b))
-#define sub_kern_stretch(a,b) a -= kern_stretch((b))
-
-/*tex
-
- This function is used to add the width of a list of nodes (from a
- discretionary) to one of the width arrays.
-
- Replacement texts and discretionary texts are supposed to contain only
- character nodes, kern nodes, and box or rule nodes.
-
-*/
-
-#define bad_node_in_disc_error(p) { \
- if (type(p) == whatsit_node) { \
- formatted_error("linebreak","invalid node with type %s and subtype %i found in discretionary",node_data[type(p)].name,subtype(p)); \
- } else { \
- formatted_error("linebreak","invalid node with type %s found in discretionary",node_data[type(p)].name); \
- } \
-}
-
-static void add_to_widths(halfword s, int line_break_dir, int adjust_spacing, scaled * widths)
-{
- while (s != null) {
- if (is_char_node(s)) {
- widths[1] += pack_width(line_break_dir, dir_TRT, s, true);
- if ((adjust_spacing > 1) && check_expand_pars(font(s))) {
- set_prev_char_p(s);
- add_char_stretch(widths[8], s);
- add_char_shrink(widths[9], s);
- };
- } else {
- switch (type(s)) {
- case hlist_node:
- case vlist_node:
- widths[1] += pack_width(line_break_dir, box_dir(s), s, false);
- break;
- case kern_node:
- if ((adjust_spacing == 2) && (subtype(s) == normal)) {
- add_kern_stretch(widths[8], s);
- add_kern_shrink(widths[9], s);
- }
- /*tex fall through */
- case rule_node:
- widths[1] += width(s);
- break;
- case disc_node:
- break;
- default:
- bad_node_in_disc_error(s);
- break;
- }
- }
- s = vlink(s);
- }
-}
-
-/*tex
-
- This function is used to substract the width of a list of nodes (from a
- discretionary) from one of the width arrays. It is used only once, but
- deserves it own function because of orthogonality with the |add_to_widths|
- function.
-
-*/
-
-static void sub_from_widths(halfword s, int line_break_dir, int adjust_spacing, scaled * widths)
-{
- while (s != null) {
- /*tex Subtract the width of node |s| from |break_width|; */
- if (is_char_node(s)) {
- widths[1] -= pack_width(line_break_dir, dir_TRT, s, true);
- if ((adjust_spacing > 1) && check_expand_pars(font(s))) {
- set_prev_char_p(s);
- sub_char_stretch(widths[8], s);
- sub_char_shrink(widths[9], s);
- }
- } else {
- switch (type(s)) {
- case hlist_node:
- case vlist_node:
- widths[1] -= pack_width(line_break_dir, box_dir(s), s, false);
- break;
- case kern_node:
- if ((adjust_spacing == 2) && (subtype(s) == normal)) {
- sub_kern_stretch(widths[8], s);
- sub_kern_shrink(widths[9], s);
- }
- /*tex fall through */
- case rule_node:
- widths[1] -= width(s);
- break;
- case disc_node:
- break;
- default:
- bad_node_in_disc_error(s);
- break;
- }
- }
- s = vlink(s);
- }
-}
-
-/*tex
-
- When we insert a new active node for a break at |cur_p|, suppose this new
- node is to be placed just before active node |a|; then we essentially want to
- insert `$\delta\,|cur_p|\,\delta^\prime$' before |a|, where
- $\delta=\alpha(a)-\alpha(|cur_p|)$ and
- $\delta^\prime=\alpha(|cur_p|)-\alpha(a)$ in the notation explained above.
- The |cur_active_width| array now holds $\gamma+\beta(|cur_p|)-\alpha(a)$; so
- $\delta$ can be obtained by subtracting |cur_active_width| from the quantity
- $\gamma+\beta(|cur_p|)- \alpha(|cur_p|)$. The latter quantity can be regarded
- as the length of a line ``from |cur_p| to |cur_p|''; we call it the
- |break_width| at |cur_p|.
-
- The |break_width| is usually negative, since it consists of the background
- (which is normally zero) minus the width of nodes following~|cur_p| that are
- eliminated after a break. If, for example, node |cur_p| is a glue node, the
- width of this glue is subtracted from the background; and we also look ahead
- to eliminate all subsequent glue and penalty and kern and math nodes,
- subtracting their widths as well.
-
- Kern nodes do not disappear at a line break unless they are |explicit|.
-
-*/
-
-static void compute_break_width(int break_type, int line_break_dir, int adjust_spacing, halfword p)
-{
- /*tex
-
- Glue and other 'whitespace' to be skipped after a break; used if
- unhyphenated, or |post_break==empty|.
-
- */
- halfword s = p;
- if (break_type > unhyphenated_node && p != null) {
- /*tex
-
- Compute the discretionary |break_width| values.
-
- When |p| is a discretionary break, the length of a line ``from |p| to
- |p|'' has to be defined properly so that the other calculations work
- out. Suppose that the pre-break text at |p| has length $l_0$, the
- post-break text has length $l_1$, and the replacement text has length
- |l|. Suppose also that |q| is the node following the replacement
- text. Then length of a line from |p| to |q| will be computed as
- $\gamma+\beta(q)-\alpha(|p|)$, where $\beta(q)=\beta(|p|)-l_0+l$. The
- actual length will be the background plus $l_1$, so the length from
- |p| to |p| should be $\gamma+l_0+l_1-l$. If the post-break text of
- the discretionary is empty, a break may also discard~|q|; in that
- unusual case we subtract the length of~|q| and any other nodes that
- will be discarded after the discretionary break.
-
- The value of $l_0$ need not be computed, since |line_break| will put
- it into the global variable |disc_width| before calling |try_break|.
-
- In case of nested discretionaries, we always follow the no-break
- path, as we are talking about the breaking on {\it this} position.
-
- */
- sub_from_widths(vlink_no_break(p), line_break_dir, adjust_spacing, break_width);
- add_to_widths(vlink_post_break(p), line_break_dir, adjust_spacing, break_width);
- do_one_seven_eight(add_disc_width_to_break_width);
- if (vlink_post_break(p) == null) {
- /*tex no |post_break|: 'skip' any 'whitespace' following */
- s = vlink(p);
- } else {
- s = null;
- }
- }
- while (s != null) {
- switch (type(s)) {
- case math_node:
- /*tex begin mathskip code */
- if (glue_is_zero(s)) {
- break_width[1] -= surround(s);
- break;
- } else {
- /*tex fall through */
- }
- /*tex end mathskip code */
- case glue_node:
- /*tex Subtract glue from |break_width|; */
- break_width[1] -= width(s);
- break_width[2 + stretch_order(s)] -= stretch(s);
- break_width[7] -= shrink(s);
- break;
- case penalty_node:
- break;
- case kern_node:
- if (subtype(s) != explicit_kern && subtype(s) != italic_kern)
- return;
- else
- break_width[1] -= width(s);
- break;
- default:
- return;
- };
- s = vlink(s);
- }
-}
-
-static void print_break_node(halfword q, fitness_value fit_class, quarterword break_type, halfword cur_p)
-{
- /*tex Print a symbolic description of the new break node. */
- tprint_nl("@@");
- print_int(serial(passive));
- tprint(": line ");
- print_int(line_number(q) - 1);
- print_char('.');
- print_int(fit_class);
- if (break_type == hyphenated_node)
- print_char('-');
- tprint(" t=");
- print_int(total_demerits(q));
- if (do_last_line_fit) {
- /*tex Print additional data in the new active node. */
- tprint(" s=");
- print_scaled(active_short(q));
- if (cur_p == null)
- tprint(" a=");
- else
- tprint(" g=");
- print_scaled(active_glue(q));
- }
- tprint(" -> @");
- if (prev_break(passive) == null)
- print_char('0');
- else
- print_int(serial(prev_break(passive)));
-}
-
-static void print_feasible_break(halfword cur_p, pointer r, halfword b, int pi, int d, boolean artificial_demerits)
-{
- /*tex
-
- Print a symbolic description of this feasible break.
-
- */
- if (printed_node != cur_p) {
- /*tex
-
- Print the list between |printed_node| and |cur_p|, then set
- |printed_node:=cur_p|.
-
- */
- tprint_nl("");
- if (cur_p == null) {
- short_display(vlink(printed_node));
- } else {
- halfword save_link = vlink(cur_p);
- vlink(cur_p) = null;
- tprint_nl("");
- short_display(vlink(printed_node));
- vlink(cur_p) = save_link;
- }
- printed_node = cur_p;
- }
- tprint_nl("@");
- if (cur_p == null) {
- tprint_esc("par");
- } else if (type(cur_p) != glue_node) {
- if (type(cur_p) == penalty_node)
- tprint_esc("penalty");
- else if (type(cur_p) == disc_node)
- tprint_esc("discretionary");
- else if (type(cur_p) == kern_node)
- tprint_esc("kern");
- else
- tprint_esc("math");
- }
- tprint(" via @");
- if (break_node(r) == null)
- print_char('0');
- else
- print_int(serial(break_node(r)));
- tprint(" b=");
- if (b > inf_bad)
- print_char('*');
- else
- print_int(b);
- tprint(" p=");
- print_int(pi);
- tprint(" d=");
- if (artificial_demerits)
- print_char('*');
- else
- print_int(d);
-}
-
-#define add_disc_width_to_active_width(a) active_width[a] += disc_width[a]
-#define update_width(a) cur_active_width[a] += varmem[(r+(a))].cint
-
-#define set_break_width_to_background(a) break_width[a]=background[(a)]
-
-#define convert_to_break_width(a) \
- varmem[(prev_r+(a))].cint = varmem[(prev_r+(a))].cint-cur_active_width[(a)]+break_width[(a)]
-
-#define store_break_width(a) active_width[(a)]=break_width[(a)]
-
-#define new_delta_to_break_width(a) \
- varmem[(q+(a))].cint=break_width[(a)]-cur_active_width[(a)]
-
-#define new_delta_from_break_width(a) \
- varmem[(q+(a))].cint=cur_active_width[(a)]-break_width[(a)]
-
-#define copy_to_cur_active(a) cur_active_width[(a)]=active_width[(a)]
-
-#define combine_two_deltas(a) varmem[(prev_r+(a))].cint += varmem[(r+(a))].cint
-#define downdate_width(a) cur_active_width[(a)] -= varmem[(prev_r+(a))].cint
-#define update_active(a) active_width[(a)]+=varmem[(r+(a))].cint
-
-#define total_font_stretch cur_active_width[8]
-#define total_font_shrink cur_active_width[9]
-
-#define cal_margin_kern_var(a) { \
- character(cp) = character((a)); \
- font(cp) = font((a)); \
- do_subst_font(cp, 1000); \
- if (font(cp) != font((a))) \
- margin_kern_stretch += (left_pw((a)) - left_pw(cp)); \
- font(cp) = font((a)); \
- do_subst_font(cp, -1000); \
- if (font(cp) != font((a))) \
- margin_kern_shrink += (left_pw(cp) - left_pw((a))); \
-}
-
-static void ext_try_break(
- int pi,
- quarterword break_type,
- int line_break_dir,
- int adjust_spacing,
- int par_shape_ptr,
- int adj_demerits,
- int tracing_paragraphs,
- int protrude_chars,
- int line_penalty,
- int last_line_fit,
- int double_hyphen_demerits,
- int final_hyphen_demerits, halfword first_p, halfword cur_p
-)
-{
- /*tex runs through the active list */
- pointer r;
- scaled margin_kern_stretch;
- scaled margin_kern_shrink;
- halfword lp, rp, cp;
- /*tex stays a step behind |r| */
- halfword prev_r = active;
- /*tex a step behind |prev_r|, if |type(prev_r)=delta_node| */
- halfword prev_prev_r = null;
- /*tex maximum line number in current equivalence class of lines */
- halfword old_l = 0;
- /*tex have we found a feasible break at |cur_p|? */
- boolean no_break_yet = true;
- /*tex points to a new node being created */
- halfword q;
- /*tex line number of current active node */
- halfword l;
- /*tex should node |r| remain in the active list? */
- boolean node_r_stays_active;
- /*tex the current line will be justified to this width */
- scaled line_width = 0;
- /*tex possible fitness class of test line */
- fitness_value fit_class;
- /*tex badness of test line */
- halfword b;
- /*tex demerits of test line */
- int d;
- /*tex has |d| been forced to zero? */
- boolean artificial_demerits;
- /*tex used in badness calculations */
- scaled shortfall;
- /*tex glue stretch or shrink of test line, adjustment for last line */
- scaled g = 0;
- /*tex distance from current active node */
- scaled cur_active_width[10] = { 0 };
- /*tex Make sure that |pi| is in the proper range; */
- if (pi >= inf_penalty) {
- /*tex this breakpoint is inhibited by infinite penalty */
- return;
- } else if (pi <= -inf_penalty) {
- /*tex this breakpoint will be forced */
- pi = eject_penalty;
- }
-
- do_all_eight(copy_to_cur_active);
-
- while (1) {
- r = vlink(prev_r);
- /*tex
-
- If node |r| is of type |delta_node|, update |cur_active_width|, set
- |prev_r| and |prev_prev_r|, then |goto continue|. The following code
- uses the fact that |type(active)<>delta_node|.
-
- */
- if (type(r) == delta_node) {
- /*tex implicit */
- do_all_eight(update_width);
- prev_prev_r = prev_r;
- prev_r = r;
- continue;
- }
- /*tex
-
- If a line number class has ended, create new active nodes for the
- best feasible breaks in that class; then |return| if |r=active|,
- otherwise compute the new |line_width|.
-
- The first part of the following code is part of \TeX's inner loop, so
- we don't want to waste any time. The current active node, namely node
- |r|, contains the line number that will be considered next. At the
- end of the list we have arranged the data structure so that
- |r=active| and |line_number(active)>old_l|.
-
- */
- l = line_number(r);
- if (l > old_l) {
- /*tex now we are no longer in the inner loop */
- if ((minimum_demerits < awful_bad)
- && ((old_l != easy_line) || (r == active))) {
- /*tex
-
- Create new active nodes for the best feasible breaks just
- found. It is not necessary to create new active nodes having
- |minimal_demerits| greater than
- |minimum_demerits+abs(adj_demerits)|, since such active nodes
- will never be chosen in the final paragraph breaks. This
- observation allows us to omit a substantial number of
- feasible breakpoints from further consideration.
-
- */
- if (no_break_yet) {
- no_break_yet = false;
- do_all_eight(set_break_width_to_background);
- compute_break_width(break_type, line_break_dir, adjust_spacing, cur_p);
- }
- /*tex
-
- Insert a delta node to prepare for breaks at |cur_p|. We use
- the fact that |type(active)<>delta_node|.
-
- */
- if (type(prev_r) == delta_node) {
- /*tex modify an existing delta node */
- do_all_eight(convert_to_break_width);
- } else if (prev_r == active) {
- /*tex no delta node needed at the beginning */
- do_all_eight(store_break_width);
- } else {
- q = new_node(delta_node, 0);
- vlink(q) = r;
- do_all_eight(new_delta_to_break_width);
- vlink(prev_r) = q;
- prev_prev_r = prev_r;
- prev_r = q;
- }
- if (abs(adj_demerits) >= awful_bad - minimum_demerits)
- minimum_demerits = awful_bad - 1;
- else
- minimum_demerits += abs(adj_demerits);
- for (fit_class = very_loose_fit; fit_class <= tight_fit;
- fit_class++) {
- if (minimal_demerits[fit_class] <= minimum_demerits) {
- /*tex
-
- Insert a new active node from |best_place[fit_class]|
- to |cur_p|. When we create an active node, we also
- create the corresponding passive node.
-
- */
- q = new_node(passive_node, 0);
- vlink(q) = passive;
- passive = q;
- cur_break(q) = cur_p;
- incr(pass_number);
- serial(q) = pass_number;
- prev_break(q) = best_place[fit_class];
- /*tex
-
- Here we keep track of the subparagraph penalties in
- the break nodes.
-
- */
- passive_pen_inter(q) = internal_pen_inter;
- passive_pen_broken(q) = internal_pen_broken;
- passive_last_left_box(q) = internal_left_box;
- passive_last_left_box_width(q) =
- internal_left_box_width;
- if (prev_break(q) != null) {
- passive_left_box(q) = passive_last_left_box(prev_break(q));
- passive_left_box_width(q) = passive_last_left_box_width(prev_break(q));
- } else {
- passive_left_box(q) = init_internal_left_box;
- passive_left_box_width(q) = init_internal_left_box_width;
- }
- passive_right_box(q) = internal_right_box;
- passive_right_box_width(q) = internal_right_box_width;
- q = new_node(break_type, fit_class);
- break_node(q) = passive;
- line_number(q) = best_pl_line[fit_class] + 1;
- total_demerits(q) = minimal_demerits[fit_class];
- if (do_last_line_fit) {
- /*tex
-
- Store additional data in the new active node.
- Here we save these data in the active node
- representing a potential line break.
-
- */
- active_short(q) = best_pl_short[fit_class];
- active_glue(q) = best_pl_glue[fit_class];
- }
- vlink(q) = r;
- vlink(prev_r) = q;
- prev_r = q;
- if (tracing_paragraphs > 0)
- print_break_node(q, fit_class, break_type, cur_p);
- }
- minimal_demerits[fit_class] = awful_bad;
- }
- minimum_demerits = awful_bad;
- /*tex
-
- Insert a delta node to prepare for the next active node. When
- the following code is performed, we will have just inserted
- at least one active node before |r|, so
- |type(prev_r)<>delta_node|.
-
- */
- if (r != active) {
- q = new_node(delta_node, 0);
- vlink(q) = r;
- do_all_eight(new_delta_from_break_width);
- vlink(prev_r) = q;
- prev_prev_r = prev_r;
- prev_r = q;
- }
- }
- if (r == active)
- return;
- /*tex
-
- Compute the new line width. When we come to the following code,
- we have just encountered the first active node~|r| whose
- |line_number| field contains |l|. Thus we want to compute the
- length of the $l\mskip1mu$th line of the current paragraph.
- Furthermore, we want to set |old_l| to the last number in the
- class of line numbers equivalent to~|l|.
-
- */
- if (l > easy_line) {
- old_l = max_halfword - 1;
- line_width = second_width;
- } else {
- old_l = l;
- if (l > last_special_line) {
- line_width = second_width;
- } else if (par_shape_ptr == null) {
- line_width = first_width;
- } else {
- line_width = varmem[(par_shape_ptr + 2 * l + 1)].cint;
- }
- }
- }
- /*tex
-
- If a line number class has ended, create new active nodes for the
- best feasible breaks in that class; then |return| if |r=active|,
- otherwise compute the new |line_width|.
-
- Consider the demerits for a line from |r| to |cur_p|; deactivate node
- |r| if it should no longer be active; then |goto continue| if a line
- from |r| to |cur_p| is infeasible, otherwise record a new feasible
- break.
-
- */
- artificial_demerits = false;
- shortfall = line_width - cur_active_width[1];
- if (break_node(r) == null)
- shortfall -= init_internal_left_box_width;
- else
- shortfall -= passive_last_left_box_width(break_node(r));
- shortfall -= internal_right_box_width;
- if (protrude_chars > 1) {
- halfword l1, o;
- l1 = (break_node(r) == null) ? first_p : cur_break(break_node(r));
- if (cur_p == null) {
- o = null;
- } else {
- o = alink(cur_p);
- assert(vlink(o) == cur_p);
- }
- /*tex
-
- The disc could be a SELECT subtype, to we might need to get the
- last character as |pre_break| from either the |pre_break| list
- (if the previous INIT disc was taken), or the |no_break| (sic)
- list (if the previous INIT disc was not taken).
-
- The last characters (hyphenation character) if these two list
- should always be the same anyway, so we just look at |pre_break|.
-
- Let's look at the right margin first.
-
- */
- if ((cur_p != null) && (type(cur_p) == disc_node) && (vlink_pre_break(cur_p) != null)) {
- /*tex a |disc_node| with non-empty |pre_break|, protrude the last char of |pre_break| */
- o = tlink_pre_break(cur_p);
- } else {
- o = find_protchar_right(l1, o);
- }
- /*tex now the left margin */
- if ((l1 != null) && (type(l1) == disc_node) && (vlink_post_break(l1) != null)) {
- /*tex The first char could be a disc! Protrude the first char. */
- l1 = vlink_post_break(l1);
- } else {
- l1 = find_protchar_left(l1, true);
- }
- shortfall += (left_pw(l1) + right_pw(o));
- }
- if (shortfall != 0) {
- margin_kern_stretch = 0;
- margin_kern_shrink = 0;
- if (protrude_chars > 1) {
- /*tex Calculate variations of marginal kerns. */
- lp = last_leftmost_char;
- rp = last_rightmost_char;
- cp = raw_glyph_node();
- if (lp != null) {
- cal_margin_kern_var(lp);
- }
- if (rp != null) {
- cal_margin_kern_var(rp);
- }
- flush_node(cp);
- }
- if ((shortfall > 0) && ((total_font_stretch + margin_kern_stretch) > 0)) {
- if ((total_font_stretch + margin_kern_stretch) > shortfall)
- shortfall = ((total_font_stretch + margin_kern_stretch) / (max_stretch_ratio / cur_font_step)) / 2;
- else
- shortfall -= (total_font_stretch + margin_kern_stretch);
- } else if ((shortfall < 0) && ((total_font_shrink + margin_kern_shrink) > 0)) {
- if ((total_font_shrink + margin_kern_shrink) > -shortfall)
- shortfall = -((total_font_shrink + margin_kern_shrink) / (max_shrink_ratio / cur_font_step)) / 2;
- else
- shortfall += (total_font_shrink + margin_kern_shrink);
- }
- }
- if (shortfall > 0) {
- /*tex
-
- Set the value of |b| to the badness for stretching the line, and
- compute the corresponding |fit_class|.
-
- When a line must stretch, the available stretchability can be
- found in the subarray |cur_active_width[2..6]|, in units of
- points, sfi, fil, fill and filll.
-
- The present section is part of \TeX's inner loop, and it is most
- often performed when the badness is infinite; therefore it is
- worth while to make a quick test for large width excess and small
- stretchability, before calling the |badness| subroutine.
-
- */
- if ((cur_active_width[3] != 0) || (cur_active_width[4] != 0) ||
- (cur_active_width[5] != 0) || (cur_active_width[6] != 0)) {
- if (do_last_line_fit) {
- if (cur_p == null) {
- /*tex
-
- The last line of a paragraph. Perform computations
- for last line and |goto found|.
-
- Here we compute the adjustment |g| and badness |b|
- for a line from |r| to the end of the paragraph. When
- any of the criteria for adjustment is violated we
- fall through to the normal algorithm.
-
- The last line must be too short, and have infinite
- stretch entirely due to |par_fill_skip|.
-
- */
- if ((active_short(r) == 0) || (active_glue(r) <= 0))
- /*tex
-
- Previous line was neither stretched nor shrunk,
- or was infinitely bad.
-
- */
- goto NOT_FOUND;
- if ((cur_active_width[3] != fill_width[0]) || (cur_active_width[4] != fill_width[1]) ||
- (cur_active_width[5] != fill_width[2]) || (cur_active_width[6] != fill_width[3]))
- /*tex
-
- Infinite stretch of this line not entirely due to |par_fill_skip|.
-
- */
- goto NOT_FOUND;
- if (active_short(r) > 0)
- g = cur_active_width[2];
- else
- g = cur_active_width[7];
- if (g <= 0)
- /*tex No finite stretch resp.\ no shrink. */
- goto NOT_FOUND;
- arith_error = false;
- g = fract(g, active_short(r), active_glue(r),
- max_dimen);
- if (last_line_fit < 1000)
- g = fract(g, last_line_fit, 1000, max_dimen);
- if (arith_error) {
- if (active_short(r) > 0)
- g = max_dimen;
- else
- g = -max_dimen;
- }
- if (g > 0) {
- /*tex
-
- Set the value of |b| to the badness of the last
- line for stretching, compute the corresponding
- |fit_class, and |goto found|. These badness
- computations are rather similar to those of the
- standard algorithm, with the adjustment amount
- |g| replacing the |shortfall|.
-
- */
- if (g > shortfall)
- g = shortfall;
- if (g > 7230584) {
- if (cur_active_width[2] < 1663497) {
- b = inf_bad;
- fit_class = very_loose_fit;
- goto FOUND;
- }
- }
- b = badness(g, cur_active_width[2]);
- if (b > 99) {
- fit_class = very_loose_fit;
- } else if (b > 12) {
- fit_class = loose_fit;
- } else {
- fit_class = decent_fit;
- }
- goto FOUND;
- } else if (g < 0) {
- /*tex
-
- Set the value of |b| to the badness of the last
- line for shrinking, compute the corresponding
- |fit_class, and |goto found||.
-
- */
- if (-g > cur_active_width[7])
- g = -cur_active_width[7];
- b = badness(-g, cur_active_width[7]);
- if (b > 12)
- fit_class = tight_fit;
- else
- fit_class = decent_fit;
- goto FOUND;
- }
- }
- NOT_FOUND:
- shortfall = 0;
- }
- b = 0;
- /*tex Infinite stretch. */
- fit_class = decent_fit;
- } else if (shortfall > 7230584 && cur_active_width[2] < 1663497) {
- b = inf_bad;
- fit_class = very_loose_fit;
- } else {
- b = badness(shortfall, cur_active_width[2]);
- if (b > 99) {
- fit_class = very_loose_fit;
- } else if (b > 12) {
- fit_class = loose_fit;
- } else {
- fit_class = decent_fit;
- }
- }
- } else {
- /*tex
-
- Set the value of |b| to the badness for shrinking the line, and
- compute the corresponding |fit_class|. Shrinkability is never
- infinite in a paragraph; we can shrink the line from |r| to
- |cur_p| by at most |cur_active_width[7]|.
-
- */
- if (-shortfall > cur_active_width[7])
- b = inf_bad + 1;
- else
- b = badness(-shortfall, cur_active_width[7]);
- if (b > 12)
- fit_class = tight_fit;
- else
- fit_class = decent_fit;
- }
- if (do_last_line_fit) {
- /*tex Adjust the additional data for last line; */
- if (cur_p == null)
- shortfall = 0;
- if (shortfall > 0) {
- g = cur_active_width[2];
- } else if (shortfall < 0) {
- g = cur_active_width[7];
- } else {
- g = 0;
- }
- }
- FOUND:
- if ((b > inf_bad) || (pi == eject_penalty)) {
- /*tex
-
- Prepare to deactivate node~|r|, and |goto deactivate| unless
- there is a reason to consider lines of text from |r| to |cur_p|.
- During the final pass, we dare not lose all active nodes, lest we
- lose touch with the line breaks already found. The code shown
- here makes sure that such a catastrophe does not happen, by
- permitting overfull boxes as a last resort. This particular part
- of \TeX\ was a source of several subtle bugs before the correct
- program logic was finally discovered; readers who seek to
- ``improve'' \TeX\ should therefore think thrice before daring to
- make any changes here.
-
- */
- if (final_pass && (minimum_demerits == awful_bad) &&
- (vlink(r) == active) && (prev_r == active)) {
- /*tex Set demerits zero, this break is forced. */
- artificial_demerits = true;
- } else if (b > threshold) {
- goto DEACTIVATE;
- }
- node_r_stays_active = false;
- } else {
- prev_r = r;
- if (b > threshold)
- continue;
- node_r_stays_active = true;
- }
- /*tex
-
- Record a new feasible break. When we get to this part of the code,
- the line from |r| to |cur_p| is feasible, its badness is~|b|, and its
- fitness classification is |fit_class|. We don't want to make an
- active node for this break yet, but we will compute the total
- demerits and record them in the |minimal_demerits| array, if such a
- break is the current champion among all ways to get to |cur_p| in a
- given line-number class and fitness class.
-
- */
- if (artificial_demerits) {
- d = 0;
- } else {
- /*tex Compute the demerits, |d|, from |r| to |cur_p|. */
- d = line_penalty + b;
- if (abs(d) >= 10000)
- d = 100000000;
- else
- d = d * d;
- if (pi != 0) {
- if (pi > 0) {
- d += (pi * pi);
- } else if (pi > eject_penalty) {
- d -= (pi * pi);
- }
- }
- if ((break_type == hyphenated_node) && (type(r) == hyphenated_node)) {
- if (cur_p != null)
- d += double_hyphen_demerits;
- else
- d += final_hyphen_demerits;
- }
- /*tex
-
- Direct calculation of the absolute value in ((|fit_class| - |fitness(r)|) > 1)
- can lead to unexpected results even if the type of the members of |fit_class|, which is |int|
- (see C99 §6.7.2.2), and the integer promotion rules for |fitness(r)|, whose also
- give an |int| type, should set the expression as substraction between two |int|.
- In this case GCC set the type of |fit_class| to |unsigned int| (perhaps because the members are all positives?)
- and hence the expression is converted to a sum of |unsigned int|, leading to a different result.
- The choice of type is implementation-defined, as stated in C99 §6.7.2.2.4:
-
- "Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type.
- The choice of type is implementation-defined, but shall be capable of representing the values
- of all the members of the enumeration."
-
- It's better to use the equivalent expanded expression.
- */
- if ( (fit_class>(fitness(r)+1)) || (fitness(r)>(fit_class+1)) )
- d = d + adj_demerits;
-
- }
- if (tracing_paragraphs > 0) {
- print_feasible_break(cur_p, r, b, pi, d, artificial_demerits);
- }
- /*tex This is the minimum total demerits from the beginning to |cur_p| via |r|. */
- d += total_demerits(r);
- if (d <= minimal_demerits[fit_class]) {
- minimal_demerits[fit_class] = d;
- best_place[fit_class] = break_node(r);
- best_pl_line[fit_class] = l;
- if (do_last_line_fit) {
- /*tex
-
- Store additional data for this feasible break. For each
- feasible break we record the shortfall and glue stretch or
- shrink (or adjustment).
-
- */
- best_pl_short[fit_class] = shortfall;
- best_pl_glue[fit_class] = g;
- }
- if (d < minimum_demerits)
- minimum_demerits = d;
- }
- /*tex Record a new feasible break. */
- if (node_r_stays_active) {
- /*tex |prev_r| has been set to |r|. */
- continue;
- }
- DEACTIVATE:
- /*tex
-
- Deactivate node |r|. When an active node disappears, we must delete
- an adjacent delta node if the active node was at the beginning or the
- end of the active list, or if it was surrounded by delta nodes. We
- also must preserve the property that |cur_active_width| represents
- the length of material from |vlink(prev_r)| to~|cur_p|.
-
- */
- vlink(prev_r) = vlink(r);
- flush_node(r);
- if (prev_r == active) {
- /*tex
-
- Update the active widths, since the first active node has been
- deleted. The following code uses the fact that
- |type(active)<>delta_node|. If the active list has just become
- empty, we do not need to update the |active_width| array, since
- it will be initialized when an active node is next inserted.
-
- */
- r = vlink(active);
- if (type(r) == delta_node) {
- do_all_eight(update_active);
- do_all_eight(copy_to_cur_active);
- vlink(active) = vlink(r);
- flush_node(r);
- }
- } else if (type(prev_r) == delta_node) {
- r = vlink(prev_r);
- if (r == active) {
- do_all_eight(downdate_width);
- vlink(prev_prev_r) = active;
- flush_node(prev_r);
- prev_r = prev_prev_r;
- } else if (type(r) == delta_node) {
- do_all_eight(update_width);
- do_all_eight(combine_two_deltas);
- vlink(prev_r) = vlink(r);
- flush_node(r);
- }
- }
- }
-}
-
-void ext_do_line_break(
- int paragraph_dir,
- int pretolerance,
- int tracing_paragraphs,
- int tolerance,
- scaled emergency_stretch,
- int looseness,
- int adjust_spacing,
- halfword par_shape_ptr,
- int adj_demerits,
- int protrude_chars,
- int line_penalty,
- int last_line_fit,
- int double_hyphen_demerits,
- int final_hyphen_demerits,
- int hang_indent,
- int hsize,
- int hang_after,
- halfword left_skip,
- halfword right_skip,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword widow_penalties_ptr,
- int widow_penalty,
- int broken_penalty,
- halfword final_par_glue
-)
-{
- /*tex Miscellaneous nodes of temporary interest. */
- halfword cur_p, q, r, s;
- int line_break_dir = paragraph_dir;
- /*tex Get ready to start */
- minimum_demerits = awful_bad;
- minimal_demerits[tight_fit] = awful_bad;
- minimal_demerits[decent_fit] = awful_bad;
- minimal_demerits[loose_fit] = awful_bad;
- minimal_demerits[very_loose_fit] = awful_bad;
- fewest_demerits = 0;
- actual_looseness = 0;
- /*tex
-
- We compute the values of |easy_line| and the other local variables
- relating to line length when the |line_break| procedure is initializing
- itself.
-
- */
- if (par_shape_ptr == null) {
- if (hang_indent == 0) {
- last_special_line = 0;
- second_width = hsize;
- second_indent = 0;
- } else {
- halfword used_hang_indent = swap_hang_indent(hang_indent);
- /*tex
-
- Set line length parameters in preparation for hanging
- indentation. We compute the values of |easy_line| and the other
- local variables relating to line length when the |line_break|
- procedure is initializing itself.
-
- */
- last_special_line = abs(hang_after);
- if (hang_after < 0) {
- first_width = hsize - abs(used_hang_indent);
- if (used_hang_indent >= 0)
- first_indent = used_hang_indent;
- else
- first_indent = 0;
- second_width = hsize;
- second_indent = 0;
- } else {
- first_width = hsize;
- first_indent = 0;
- second_width = hsize - abs(used_hang_indent);
- if (used_hang_indent >= 0)
- second_indent = used_hang_indent;
- else
- second_indent = 0;
- }
- }
- } else {
- last_special_line = vinfo(par_shape_ptr + 1) - 1;
- second_indent = varmem[(par_shape_ptr + 2 * (last_special_line + 1))].cint;
- second_width = varmem[(par_shape_ptr + 2 * (last_special_line + 1) + 1)].cint;
- second_indent = swap_parshape_indent(second_indent,second_width);
- }
- if (looseness == 0)
- easy_line = last_special_line;
- else
- easy_line = max_halfword;
- no_shrink_error_yet = true;
- check_shrinkage(left_skip);
- check_shrinkage(right_skip);
- q = left_skip;
- r = right_skip;
- background[1] = width(q) + width(r);
- background[2] = 0;
- background[3] = 0;
- background[4] = 0;
- background[5] = 0;
- background[6] = 0;
- background[2 + stretch_order(q)] = stretch(q);
- background[2 + stretch_order(r)] += stretch(r);
- background[7] = shrink(q) + shrink(r);
- if (adjust_spacing > 1) {
- background[8] = 0;
- background[9] = 0;
- max_stretch_ratio = -1;
- max_shrink_ratio = -1;
- cur_font_step = -1;
- set_prev_char_p(null);
- }
- /*tex
-
- Check for special treatment of last line of paragraph. The new algorithm
- for the last line requires that the stretchability |par_fill_skip| is
- infinite and the stretchability of |left_skip| plus |right_skip| is
- finite.
-
- */
- do_last_line_fit = false;
- if (last_line_fit > 0) {
- q = last_line_fill;
- if ((stretch(q) > 0) && (stretch_order(q) > normal)) {
- if ((background[3] == 0) && (background[4] == 0) && (background[5] == 0) && (background[6] == 0)) {
- do_last_line_fit = true;
- fill_width[0] = 0;
- fill_width[1] = 0;
- fill_width[2] = 0;
- fill_width[3] = 0;
- fill_width[stretch_order(q) - 1] = stretch(q);
- }
- }
- }
- /*tex Initialize |dir_ptr| for |line_break|. */
- if (dir_ptr != null) {
- flush_node_list(dir_ptr);
- dir_ptr = null;
- }
- /*tex Find optimal breakpoints. */
- threshold = pretolerance;
- if (threshold >= 0) {
- if (tracing_paragraphs > 0) {
- begin_diagnostic();
- tprint_nl("@firstpass");
- }
- second_pass = false;
- final_pass = false;
- } else {
- threshold = tolerance;
- second_pass = true;
- final_pass = (emergency_stretch <= 0);
- if (tracing_paragraphs > 0)
- begin_diagnostic();
- }
- while (1) {
- halfword first_p;
- halfword nest_stack[10];
- int nest_index = 0;
- if (threshold > inf_bad)
- threshold = inf_bad;
- /*tex Create an active breakpoint representing the beginning of the paragraph. */
- q = new_node(unhyphenated_node, decent_fit);
- vlink(q) = active;
- break_node(q) = null;
- line_number(q) = cur_list.pg_field + 1;
- total_demerits(q) = 0;
- active_short(q) = 0;
- active_glue(q) = 0;
- vlink(active) = q;
- do_all_eight(store_background);
- passive = null;
- printed_node = temp_head;
- pass_number = 0;
- font_in_short_display = null_font;
- /*tex Create an active breakpoint representing the beginning of the paragraph. */
- auto_breaking = true;
- cur_p = vlink(temp_head);
- /*tex Initialize with first |local_paragraph| node. */
- if ((cur_p != null) && (type(cur_p) == local_par_node)) {
- /*tex This used to be an assert, but may as well force it. */
- alink(cur_p) = temp_head;
- internal_pen_inter = local_pen_inter(cur_p);
- internal_pen_broken = local_pen_broken(cur_p);
- init_internal_left_box = local_box_left(cur_p);
- init_internal_left_box_width = local_box_left_width(cur_p);
- internal_left_box = init_internal_left_box;
- internal_left_box_width = init_internal_left_box_width;
- internal_right_box = local_box_right(cur_p);
- internal_right_box_width = local_box_right_width(cur_p);
- } else {
- internal_pen_inter = 0;
- internal_pen_broken = 0;
- init_internal_left_box = null;
- init_internal_left_box_width = 0;
- internal_left_box = init_internal_left_box;
- internal_left_box_width = init_internal_left_box_width;
- internal_right_box = null;
- internal_right_box_width = 0;
- }
- /*tex Initialize with first |local_paragraph| node. */
- set_prev_char_p(null);
- first_p = cur_p;
- /*tex
-
- To access the first node of paragraph as the first active node has
- |break_node=null|.
-
- */
- while ((cur_p != null) && (vlink(active) != active)) {
- /*tex
-
- |try_break| if |cur_p| is a legal breakpoint; on the 2nd pass,
- also look at |disc_node|s.
-
- */
- while (is_char_node(cur_p)) {
- /*tex
-
- Advance |cur_p| to the node following the present string of
- characters. The code that passes over the characters of words
- in a paragraph is part of \TeX's inner loop, so it has been
- streamlined for speed. We use the fact that
- `\.{\\parfillskip}' glue appears at the end of each
- paragraph; it is therefore unnecessary to check if
- |vlink(cur_p)=null| when |cur_p| is a character node.
-
- */
- active_width[1] += pack_width(line_break_dir, dir_TRT, cur_p, true);
- if ((adjust_spacing > 1) && check_expand_pars(font(cur_p))) {
- set_prev_char_p(cur_p);
- add_char_stretch(active_width[8], cur_p);
- add_char_shrink(active_width[9], cur_p);
- }
- cur_p = vlink(cur_p);
- while (cur_p == null && nest_index > 0) {
- cur_p = nest_stack[--nest_index];
- }
- }
- if (cur_p == null) {
- normal_error("linebreak","invalid list tail, probably missing glue");
- }
- /*tex
-
- Determine legal breaks: As we move through the hlist, we need to
- keep the |active_width| array up to date, so that the badness of
- individual lines is readily calculated by |try_break|. It is
- convenient to use the short name |active_width[1]| for the
- component of active width that represents real width as opposed
- to glue.
-
- */
- switch (type(cur_p)) {
- case hlist_node:
- case vlist_node:
- active_width[1] += pack_width(line_break_dir, box_dir(cur_p), cur_p, false);
- break;
- case rule_node:
- active_width[1] += width(cur_p);
- break;
- case dir_node:
- /*tex Adjust the dir stack for the |line_break| routine. */
- if (subtype(cur_p) == normal_dir) {
- line_break_dir = dir_dir(cur_p);
- /* Adds to |dir_ptr|. */
- push_dir_node(dir_ptr,cur_p);
- } else {
- pop_dir_node(dir_ptr);
- if (dir_ptr != null) {
- line_break_dir = dir_dir(dir_ptr);
- }
- }
- break;
- case local_par_node:
- /*tex Advance past a |local_paragraph| node. */
- internal_pen_inter = local_pen_inter(cur_p);
- internal_pen_broken = local_pen_broken(cur_p);
- internal_left_box = local_box_left(cur_p);
- internal_left_box_width = local_box_left_width(cur_p);
- internal_right_box = local_box_right(cur_p);
- internal_right_box_width = local_box_right_width(cur_p);
- break;
- case math_node:
- auto_breaking = (subtype(cur_p) == after);
- /*tex begin mathskip code */
- if (glue_is_zero(cur_p) || ignore_math_skip(cur_p)) {
- kern_break();
- break;
- } else {
- /*tex fall through */
- }
- /*tex end mathskip code */
- case glue_node:
- /*tex
-
- If node |cur_p| is a legal breakpoint, call |try_break|;
- then update the active widths by including the glue in
- |glue_ptr(cur_p)|.
-
- When node |cur_p| is a glue node, we look at the previous
- to see whether or not a breakpoint is legal at |cur_p|,
- as explained above.
-
- We only break after certain nodes (see texnodes.h), a
- font related kern and a dir node when
- |\breakafterdirmode=1|.
-
- */
- if (auto_breaking) {
- halfword prev_p = alink(cur_p);
- if (prev_p != temp_head && (is_char_node(prev_p)
- || precedes_break(prev_p) || precedes_kern(prev_p) || precedes_dir(prev_p))) {
- ext_try_break(
- 0,
- unhyphenated_node,
- line_break_dir,
- adjust_spacing,
- par_shape_ptr,
- adj_demerits,
- tracing_paragraphs,
- protrude_chars,
- line_penalty,
- last_line_fit,
- double_hyphen_demerits,
- final_hyphen_demerits,
- first_p,
- cur_p
- );
- }
- }
- check_shrinkage(cur_p);
- active_width[1] += width(cur_p);
- active_width[2 + stretch_order(cur_p)] += stretch(cur_p);
- active_width[7] += shrink(cur_p);
- break;
- case kern_node:
- if (subtype(cur_p) == explicit_kern || subtype(cur_p) == italic_kern) {
- kern_break();
- } else {
- active_width[1] += width(cur_p);
- if ((adjust_spacing == 2) && (subtype(cur_p) == normal)) {
- add_kern_stretch(active_width[8], cur_p);
- add_kern_shrink(active_width[9], cur_p);
- }
- }
- break;
- case disc_node:
- /*tex
-
- |select_disc|s are handled by the leading |init_disc|.
-
- */
- if (subtype(cur_p) == select_disc)
- break;
- /*tex
-
- Try to break after a discretionary fragment, then |goto
- done5|. The following code knows that discretionary texts
- contain only character nodes, kern nodes, box nodes, and
- rule nodes. This branch differs a bit from older engines
- because in \LUATEX\ we already have hyphenated the list.
- This means that we need to skip automatic disc nodes. Of
- better, we need to treat discretionaries and explicit
- hyphens always, even in the first pass.
-
- */
- if (second_pass || subtype(cur_p) <= automatic_disc) {
- int actual_penalty = (int) disc_penalty(cur_p);
- s = vlink_pre_break(cur_p);
- do_one_seven_eight(reset_disc_width);
- if (s == null) {
- /*tex trivial pre-break */
- ext_try_break(actual_penalty, hyphenated_node,
- line_break_dir, adjust_spacing,
- par_shape_ptr, adj_demerits,
- tracing_paragraphs, protrude_chars,
- line_penalty, last_line_fit,
- double_hyphen_demerits,
- final_hyphen_demerits, first_p, cur_p);
- } else {
- add_to_widths(s, line_break_dir, adjust_spacing, disc_width);
- do_one_seven_eight(add_disc_width_to_active_width);
- ext_try_break(actual_penalty, hyphenated_node,
- line_break_dir, adjust_spacing,
- par_shape_ptr, adj_demerits,
- tracing_paragraphs, protrude_chars,
- line_penalty, last_line_fit,
- double_hyphen_demerits,
- final_hyphen_demerits, first_p, cur_p);
- if (subtype(cur_p) == init_disc) {
- /*tex
-
- We should at two break points after the one
- we added above:
-
- \startitemize[n]
- \startitem
- which does a possible break in INIT's
- |post_break|
- \stopitem
- \startitem
- which means the |no_break| actually
- was broken just a character later
- \stopitem
- \stopitemize
-
- Do the select-0 case |f-f-i|:
-
- */
- s = vlink_pre_break(vlink(cur_p));
- add_to_widths(s, line_break_dir, adjust_spacing, disc_width);
- ext_try_break(actual_penalty, hyphenated_node,
- line_break_dir, adjust_spacing,
- par_shape_ptr, adj_demerits,
- tracing_paragraphs,
- protrude_chars, line_penalty,
- last_line_fit, double_hyphen_demerits,
- final_hyphen_demerits, first_p,
- vlink(cur_p));
- /*tex This does not work. */
-#if 0
- /*tex Go back to the starting situation. */
- do_one_seven_eight(sub_disc_width_from_active_width);
- do_one_seven_eight(reset_disc_width);
- /*tex Add select |no_break| to |active_width|. */
- s = vlink_no_break(vlink(cur_p));
- add_to_widths(s, line_break_dir, adjust_spacing, disc_width);
- ext_try_break(actual_penalty, hyphenated_node,
- line_break_dir, adjust_spacing,
- par_shape_ptr, adj_demerits,
- tracing_paragraphs,
- protrude_chars, line_penalty,
- last_line_fit, double_hyphen_demerits,
- final_hyphen_demerits, first_p,
- vlink(cur_p));
-#endif
- }
- do_one_seven_eight(sub_disc_width_from_active_width);
- }
- }
- s = vlink_no_break(cur_p);
- add_to_widths(s, line_break_dir, adjust_spacing, active_width);
- break;
- case penalty_node:
- ext_try_break(penalty(cur_p), unhyphenated_node, line_break_dir,
- adjust_spacing, par_shape_ptr, adj_demerits,
- tracing_paragraphs, protrude_chars,
- line_penalty, last_line_fit,
- double_hyphen_demerits, final_hyphen_demerits,
- first_p, cur_p);
- break;
- case boundary_node:
- case whatsit_node:
- /*tex Advance past a whatsit node in the |line_break| loop. */
- case mark_node:
- case ins_node:
- case adjust_node:
- break;
- case glue_spec_node:
- normal_warning("parbuilder","found a glue_spec in a paragraph");
- break;
- default:
- formatted_error("parbuilder","weird node %d in paragraph",type(cur_p));
- }
- cur_p = vlink(cur_p);
- while (cur_p == null && nest_index > 0) {
- cur_p = nest_stack[--nest_index];
- }
- }
- if (cur_p == null) {
- /*tex
-
- Try the final line break at the end of the paragraph, and |goto
- done| if the desired breakpoints have been found.
-
- The forced line break at the paragraph's end will reduce the list
- of breakpoints so that all active nodes represent breaks at
- |cur_p=null|. On the first pass, we insist on finding an active
- node that has the correct ``looseness.'' On the final pass, there
- will be at least one active node, and we will match the desired
- looseness as well as we can.
-
- The global variable |best_bet| will be set to the active node for
- the best way to break the paragraph, and a few other variables
- are used to help determine what is best.
-
- */
- ext_try_break(eject_penalty, hyphenated_node, line_break_dir,
- adjust_spacing, par_shape_ptr, adj_demerits,
- tracing_paragraphs, protrude_chars, line_penalty,
- last_line_fit, double_hyphen_demerits,
- final_hyphen_demerits, first_p, cur_p);
- if (vlink(active) != active) {
- /*tex Find an active node with fewest demerits; */
- r = vlink(active);
- fewest_demerits = awful_bad;
- do {
- if (type(r) != delta_node) {
- if (total_demerits(r) < fewest_demerits) {
- fewest_demerits = total_demerits(r);
- best_bet = r;
- }
- }
- r = vlink(r);
- } while (r != active);
- best_line = line_number(best_bet);
- /*tex
- Find an active node with fewest demerits;
- */
- if (looseness == 0)
- goto DONE;
- /*tex
-
- Find the best active node for the desired looseness;
-
- The adjustment for a desired looseness is a slightly more
- complicated version of the loop just considered. Note that if
- a paragraph is broken into segments by displayed equations,
- each segment will be subject to the looseness calculation,
- independently of the other segments.
-
- */
- r = vlink(active);
- actual_looseness = 0;
- do {
- if (type(r) != delta_node) {
- line_diff = line_number(r) - best_line;
- if (((line_diff < actual_looseness)
- && (looseness <= line_diff))
- || ((line_diff > actual_looseness)
- && (looseness >= line_diff))) {
- best_bet = r;
- actual_looseness = line_diff;
- fewest_demerits = total_demerits(r);
- } else if ((line_diff == actual_looseness) &&
- (total_demerits(r) < fewest_demerits)) {
- best_bet = r;
- fewest_demerits = total_demerits(r);
- }
- }
- r = vlink(r);
- } while (r != active);
- best_line = line_number(best_bet);
- /*tex
- Find the best active node for the desired looseness.
- */
- if ((actual_looseness == looseness) || final_pass)
- goto DONE;
- }
- }
- /*tex Clean up the memory by removing the break nodes. */
- clean_up_the_memory();
- /*tex Clean up the memory by removing the break nodes. */
- if (!second_pass) {
- if (tracing_paragraphs > 0)
- tprint_nl("@secondpass");
- threshold = tolerance;
- second_pass = true;
- final_pass = (emergency_stretch <= 0);
- } else {
- /*tex If at first you do not succeed, then: */
- if (tracing_paragraphs > 0)
- tprint_nl("@emergencypass");
- background[2] += emergency_stretch;
- final_pass = true;
- }
- }
-
- DONE:
- if (tracing_paragraphs > 0) {
- end_diagnostic(true);
- normalize_selector();
- }
- if (do_last_line_fit) {
- /*tex
- Adjust the final line of the paragraph; here we either reset
- |do_last_line_fit| or adjust the |par_fill_skip| glue.
- */
- if (active_short(best_bet) == 0) {
- do_last_line_fit = false;
- } else {
- width(last_line_fill) += (active_short(best_bet) - active_glue(best_bet));
- stretch(last_line_fill) = 0;
- }
- }
- /*tex
- Break the paragraph at the chosen. Once the best sequence of
- breakpoints has been found (hurray), we call on the procedure
- |post_line_break| to finish the remainder of the work. By introducing
- this subprocedure, we are able to keep |line_break| from getting
- extremely long.
-
- the first thing |ext_post_line_break| does is reset |dir_ptr|.
-
- */
- flush_node_list(dir_ptr);
- dir_ptr = null;
- ext_post_line_break(paragraph_dir,
- right_skip,
- left_skip,
- protrude_chars,
- par_shape_ptr,
- adjust_spacing,
- inter_line_penalties_par_ptr,
- inter_line_penalty,
- club_penalty,
- club_penalties_ptr,
- widow_penalties_ptr,
- widow_penalty,
- broken_penalty,
- final_par_glue,
- best_bet,
- last_special_line,
- second_width,
- second_indent, first_width, first_indent, best_line);
- /*tex
-
- Clean up the memory by removing the break nodes.
-
- */
- clean_up_the_memory();
-}
-
-void get_linebreak_info (int *f, int *a)
-{
- *f = fewest_demerits;
- *a = actual_looseness;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/linebreak.h b/Build/source/texk/web2c/luatexdir/tex/linebreak.h
deleted file mode 100644
index d1e1768f704..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/linebreak.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* linebreak.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef LINEBREAK_H
-# define LINEBREAK_H
-
-extern halfword just_box; /* the |hlist_node| for the last line of the new paragraph */
-
-extern void line_break(boolean d, int line_break_context);
-
-# define inf_bad 10000 /* infinitely bad value */
-# define awful_bad 07777777777 /* more than a billion demerits */
-
-extern void initialize_active(void);
-
-extern void ext_do_line_break(int paragraph_dir,
- int pretolerance,
- int tracing_paragraphs,
- int tolerance,
- scaled emergency_stretch,
- int looseness,
- /*
- int hyphen_penalty,
- int ex_hyphen_penalty,
- */
- int adjust_spacing,
- halfword par_shape_ptr,
- int adj_demerits,
- int protrude_chars,
- int line_penalty,
- int last_line_fit,
- int double_hyphen_demerits,
- int final_hyphen_demerits,
- int hang_indent,
- int hsize,
- int hang_after,
- halfword left_skip,
- halfword right_skip,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword widow_penalties_ptr,
- int widow_penalty,
- int broken_penalty, halfword final_par_glue);
-
-extern void get_linebreak_info(int *, int *);
-extern halfword find_protchar_left(halfword l, boolean d);
-extern halfword find_protchar_right(halfword l, halfword r);
-
-/* skipable nodes at the margins during character protrusion */
-
-# define zero_dimensions(a) ( \
- (width((a)) == 0) && \
- (height((a)) == 0) && \
- (depth((a)) == 0) \
-)
-
-# define empty_disc(a) ( \
- (vlink_pre_break(a) == null) && \
- (vlink_post_break(a) == null) && \
- (vlink_no_break(a) == null) \
-)
-
-# define cp_skipable(a) ( (! is_char_node((a))) && ( \
- ((type((a)) == glue_node) && (glue_is_zero((a)))) \
- || (type((a)) == penalty_node) \
- || ((type((a)) == disc_node) && empty_disc(a)) \
- || ((type((a)) == kern_node) && ((width((a)) == 0) || (subtype((a)) == normal))) \
- || ((type((a)) == rule_node) && zero_dimensions(a)) \
- || ((type((a)) == math_node) && (surround((a)) == 0 || (glue_is_zero((a))))) \
- || (type((a)) == dir_node) \
- || ((type((a)) == hlist_node) && (list_ptr((a)) == null) && zero_dimensions(a)) \
- || (type((a)) == local_par_node) \
- || (type((a)) == ins_node) \
- || (type((a)) == mark_node) \
- || (type((a)) == adjust_node) \
- || (type((a)) == boundary_node) \
- || (type((a)) == whatsit_node) \
-) )
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.c b/Build/source/texk/web2c/luatexdir/tex/mainbody.c
deleted file mode 100644
index 2f45f9989d2..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mainbody.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
-
-mainbody.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-This is where the action starts. We're speaking of \LUATEX, a continuation of
-\PDFTEX\ (which included \ETEX) and \ALEPH. As \TEX, \LUATEX\ is a document
-compiler intended to simplify high quality typesetting for many of the world's
-languages. It is an extension of D. E. Knuth's \TEX, which was designed
-essentially for the typesetting of languages using the Latin alphabet. Although
-it is a direct decendant of \TEX, and therefore mostly compatible, there are
-some subtle differences that relate to \UNICODE\ support and \OPENTYPE\ math.
-
-The \ALEPH\ subsystem loosens many of the restrictions imposed by~\TeX: register
-numbers are no longer limited to 8~bits. Fonts may have more than 256~characters,
-more than 256~fonts may be used, etc. We use a similar model. We also borrowed
-the directional model but have upgraded it a bit as well as integrated it more
-tightly.
-
-This program is directly derived from Donald E. Knuth's \TEX; the change history
-which follows and the reward offered for finders of bugs refer specifically to
-\TEX; they should not be taken as referring to \LUATEX, \PDFTEX, nor \ETEX,
-although the change history is relevant in that it demonstrates the evolutionary
-path followed. This program is not \TEX; that name is reserved strictly for the
-program which is the creation and sole responsibility of Professor Knuth.
-
-\starttyping
-% Version 0 was released in September 1982 after it passed a variety of tests.
-% Version 1 was released in November 1983 after thorough testing.
-% Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984).
-% Version 1.2 allowed `0' in response to an error, et alia (October 1984).
-% Version 1.3 made memory allocation more flexible and local (November 1984).
-% Version 1.4 fixed accents right after line breaks, et alia (April 1985).
-% Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985).
-% Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986).
-% Version 2.1 corrected anomalies in discretionary breaks (January 1987).
-% Version 2.2 corrected "(Please type...)" with null \endlinechar (April 1987).
-% Version 2.3 avoided incomplete page in premature termination (August 1987).
-% Version 2.4 fixed \noaligned rules in indented displays (August 1987).
-% Version 2.5 saved cur_order when expanding tokens (September 1987).
-% Version 2.6 added 10sp slop when shipping leaders (November 1987).
-% Version 2.7 improved rounding of negative-width characters (November 1987).
-% Version 2.8 fixed weird bug if no \patterns are used (December 1987).
-% Version 2.9 made \csname\endcsname's "relax" local (December 1987).
-% Version 2.91 fixed \outer\def\a0{}\a\a bug (April 1988).
-% Version 2.92 fixed \patterns, also file names with complex macros (May 1988).
-% Version 2.93 fixed negative halving in allocator when mem_min<0 (June 1988).
-% Version 2.94 kept open_log_file from calling fatal_error (November 1988).
-% Version 2.95 solved that problem a better way (December 1988).
-% Version 2.96 corrected bug in "Infinite shrinkage" recovery (January 1989).
-% Version 2.97 corrected blunder in creating 2.95 (February 1989).
-% Version 2.98 omitted save_for_after at outer level (March 1989).
-% Version 2.99 caught $$\begingroup\halign..$$ (June 1989).
-% Version 2.991 caught .5\ifdim.6... (June 1989).
-% Version 2.992 introduced major changes for 8-bit extensions (September 1989).
-% Version 2.993 fixed a save_stack synchronization bug et alia (December 1989).
-% Version 3.0 fixed unusual displays; was more \output robust (March 1990).
-% Version 3.1 fixed nullfont, disabled \write{\the\prevgraf} (September 1990).
-% Version 3.14 fixed unprintable font names and corrected typos (March 1991).
-% Version 3.141 more of same; reconstituted ligatures better (March 1992).
-% Version 3.1415 preserved nonexplicit kerns, tidied up (February 1993).
-% Version 3.14159 allowed fontmemsize to change; bulletproofing (March 1995).
-% Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002).
-% Version 3.1415926 was a general cleanup with minor fixes (February 2008).
-\stoptyping
-
-Although considerable effort has been expended to make the LuaTeX program correct
-and reliable, no warranty is implied; the authors disclaim any obligation or
-liability for damages, including but not limited to special, indirect, or
-consequential damages arising out of or in connection with the use or performance
-of this software. This work has been a ``labor of love'' and the authors hope
-that users enjoy it.
-
-{\em You will find a lot of comments that originate in original \TEX. We kept them
-as a side effect of the conversion from \WEB\ to \CWEB. Because there is not much
-webbing going on here eventually the files became regular \CCODE\ files with still
-potentially typeset comments. As we add our own comments, and also comments are
-there from \PDFTEX, \ALEPH\ and \ETEX, we get a curious mix. The best comments are
-of course from Don Knuth. All bad comments are ours. All errors are ours too!
-
-Not all comments make sense, because some things are implemented differently, for
-instance some memory management. But the principles of tokens and nodes stayed.
-It anyway means that you sometimes need to keep in mind that the explanation is
-more geared to traditional \TEX. But that's not a bad thing. Sorry Don for any
-confusion we introduced. The readers should have a copy of the \TEX\ books at hand
-anyway.}
-
-A large piece of software like \TeX\ has inherent complexity that cannot be
-reduced below a certain level of difficulty, although each individual part is
-fairly simple by itself. The \.{WEB} language is intended to make the algorithms
-as readable as possible, by reflecting the way the individual program pieces fit
-together and by providing the cross-references that connect different parts.
-Detailed comments about what is going on, and about why things were done in
-certain ways, have been liberally sprinkled throughout the program. These
-comments explain features of the implementation, but they rarely attempt to
-explain the \TeX\ language itself, since the reader is supposed to be familiar
-with {\sl The \TeX book}.
-
-The present implementation has a long ancestry, beginning in the summer of~1977,
-when Michael~F. Plass and Frank~M. Liang designed and coded a prototype @^Plass,
-Michael Frederick@> @^Liang, Franklin Mark@> @^Knuth, Donald Ervin@> based on
-some specifications that the author had made in May of that year. This original
-proto\TeX\ included macro definitions and elementary manipulations on boxes and
-glue, but it did not have line-breaking, page-breaking, mathematical formulas,
-alignment routines, error recovery, or the present semantic nest; furthermore, it
-used character lists instead of token lists, so that a control sequence like
-\.{\\halign} was represented by a list of seven characters. A complete version of
-\TeX\ was designed and coded by the author in late 1977 and early 1978; that
-program, like its prototype, was written in the {\mc SAIL} language, for which an
-excellent debugging system was available. Preliminary plans to convert the {\mc
-SAIL} code into a form somewhat like the present ``web'' were developed by Luis
-Trabb~Pardo and @^Trabb Pardo, Luis Isidoro@> the author at the beginning of
-1979, and a complete implementation was created by Ignacio~A. Zabala in 1979 and
-1980. The \TeX82 program, which @^Zabala Salelles, Ignacio Andr\'es@> was written
-by the author during the latter part of 1981 and the early part of 1982, also
-incorporates ideas from the 1979 implementation of @^Guibas, Leonidas Ioannis@>
-@^Sedgewick, Robert@> @^Wyatt, Douglas Kirk@> \TeX\ in {\mc MESA} that was
-written by Leonidas Guibas, Robert Sedgewick, and Douglas Wyatt at the Xerox Palo
-Alto Research Center. Several hundred refinements were introduced into \TeX82
-based on the experiences gained with the original implementations, so that
-essentially every part of the system has been substantially improved. After the
-appearance of ``Version 0'' in September 1982, this program benefited greatly
-from the comments of many other people, notably David~R. Fuchs and Howard~W.
-Trickey. A final revision in September 1989 extended the input character set to
-eight-bit codes and introduced the ability to hyphenate words from different
-languages, based on some ideas of Michael~J. Ferguson. @^Fuchs, David Raymond@>
-@^Trickey, Howard Wellington@> @^Ferguson, Michael John@>
-
-No doubt there still is plenty of room for improvement, but the author is firmly
-committed to keeping \TeX82 ``frozen'' from now on; stability and reliability are
-to be its main virtues.
-On the other hand, the \.{WEB} description can be extended without changing the
-core of \TeX82 itself, and the program has been designed so that such extensions
-are not extremely difficult to make. The |banner| string defined here should be
-changed whenever \TeX\ undergoes any modifications, so that it will be clear
-which version of \TeX\ might be the guilty party when a problem arises.
-@^extensions to \TeX@> @^system dependencies@>
-
-This program contains code for various features extending \TeX, therefore this
-program is called `\eTeX' and not `\TeX'; the official name `\TeX' by itself is
-reserved for software systems that are fully compatible with each other. A
-special test suite called the ``\.{TRIP} test'' is available for helping to
-determine whether a particular implementation deserves to be known as `\TeX'
-[cf.~Stanford Computer Science report CS1027, November 1984].
-
-A similar test suite called the ``\.{e-TRIP} test'' is available for helping to
-determine whether a particular implementation deserves to be known as `\eTeX'.
-
-This is the first of many sections of \TeX\ where global variables are defined.
-
-*/
-
-/*tex Are we using lua for initializations? */
-
-boolean luainit;
-
-/*tex Print file open and close info? */
-
-boolean tracefilenames;
-
-/*tex
-
-This program has two important variations: (1) There is a long and slow version
-called \.{INITEX}, which does the extra calculations needed to @.INITEX@>
-initialize \TeX's internal tables; and (2)~there is a shorter and faster
-production version, which cuts the initialization to a bare minimum.
-
-*/
-
-/*tex are we \.{INITEX}? */
-
-boolean ini_version;
-
-/*tex was the dump name option used? */
-
-boolean dump_option;
-
-/*tex was a \.{\%\AM format} line seen? */
-
-boolean dump_line;
-
-/*tex temporary for setup */
-
-int bound_default;
-
-/*tex temporary for setup */
-
-char *bound_name;
-
-/*tex width of context lines on terminal error messages */
-
-int error_line;
-
-/*tex
- width of first lines of contexts in terminal error messages; should be
- between 30 and |error_line-15|
-*/
-
-int half_error_line;
-
-/*tex width of longest text lines output; should be at least 60 */
-
-int max_print_line;
-
-/*tex maximum number of strings; must not exceed |max_halfword| */
-
-int max_strings;
-
-/*tex strings available after format loaded */
-
-int strings_free;
-
-/*tex loop variable for initialization */
-
-int font_k;
-
-/*tex
- putting a character in front of a macro trace (feature suggested by PO on
- tex implementor list
-*/
-
-int level_max;
-int level_chr;
-
-/*tex
- maximum number of characters simultaneously present in current lines of open
- files and in control sequences between \.{\\csname} and \.{\\endcsname}; must
- not exceed |max_halfword|
-*/
-
-int buf_size;
-
-/*tex maximum number of simultaneous input sources */
-
-int stack_size;
-
-/*tex
- maximum number of input files and error insertions that can be going on
- simultaneously
-*/
-
-int max_in_open;
-
-/*tex maximum number of simultaneous macro parameters */
-
-int param_size;
-
-/*tex maximum number of semantic levels simultaneously active */
-
-int nest_size;
-
-/*tex
- space for saving values outside of current group; must be at most
- |max_halfword|
-*/
-
-int save_size;
-
-/*tex limits recursive calls of the |expand| procedure */
-
-int expand_depth;
-
-/*tex parse the first line for options */
-
-int parsefirstlinep;
-
-/*tex format messages as file:line:error */
-
-int filelineerrorstylep;
-
-/*tex stop at first error */
-
-int haltonerrorp;
-
-/*tex current filename is quoted */
-
-boolean quoted_filename;
-
-int get_luatexversion(void)
-{
- return luatex_version;
-}
-
-/*tex the number of pages that have been shipped out */
-
-int total_pages = 0;
-
-/*tex recent outputs that didn't ship anything out */
-
-int dead_cycles = 0;
-
-str_number get_luatexrevision(void)
-{
- return luatex_revision;
-}
-
-/*tex
-
-This is it: the part of \TeX\ that executes all those procedures we have written.
-
-We have noted that there are two versions of \TeX82. One, called \.{INITEX},
-@.INITEX@> has to be run first; it initializes everything from scratch, without
-reading a format file, and it has the capability of dumping a format file. The
-other one is called `\.{VIRTEX}'; it is a ``virgin'' program that needs
-@.VIRTEX@> to input a format file in order to get started.
-
-For \LUATEX\ it is important to know that we still dump a format. But, in order
-to gain speed and a smaller footprint, we gzip the format (level 3). We also
-store some information that makes an abort possible in case of an incompatible
-engine version, which is important as \LUATEX\ develops. It is possible to store
-\LUA\ code in the format but not the current upvalues so you still need to
-initialize. Also, traditional fonts are stored, as are extended fonts but any
-additional information needed for instance to deal with \OPENTYPE\ fonts is to be
-handled by \LUA\ code and therefore not present in the format.
-
-*/
-
-#define const_chk(A) do { \
- if (A < inf_##A) \
- A = inf_##A; \
- if (A > sup_##A) \
- A = sup_##A; \
-} while (0)
-
-#define setup_bound_var(A,B,C) do { \
- if (luainit>0) { \
- get_lua_number("texconfig",B,&C); \
- if (C==0) \
- C=A; \
- } else { \
- integer x; \
- setupboundvariable(&x, B, A); \
- C = (int)x; \
- } \
-} while (0)
-
-int ready_already = 0;
-
-int main_initialize(void)
-{
- /*
- In case somebody has inadvertently made bad settings of the
- ``constants,'' \LUATEX\ checks them using a variable called |bad|.
- */
- int bad = 0;
- /*tex
- Bounds that may be set from the configuration file. We want the user to
- be able to specify the names with underscores, but \.{TANGLE} removes
- underscores, so we're stuck giving the names twice, once as a string,
- once as the identifier. How ugly. (We can change that now.)
- */
- setup_bound_var(15000, "max_strings", max_strings);
- setup_bound_var(100, "strings_free", strings_free);
- setup_bound_var(3000, "buf_size", buf_size);
- setup_bound_var(50, "nest_size", nest_size);
- setup_bound_var(15, "max_in_open", max_in_open);
- setup_bound_var(60, "param_size", param_size);
- setup_bound_var(4000, "save_size", save_size);
- setup_bound_var(300, "stack_size", stack_size);
- setup_bound_var(16384, "dvi_buf_size", dvi_buf_size);
- setup_bound_var(79, "error_line", error_line);
- setup_bound_var(50, "half_error_line", half_error_line);
- setup_bound_var(79, "max_print_line", max_print_line);
- setup_bound_var(0, "hash_extra", hash_extra);
- setup_bound_var(72, "pk_dpi", pk_dpi);
- setup_bound_var(10000, "expand_depth", expand_depth);
- setup_bound_var(0, "level_max", level_max);
- setup_bound_var('.', "level_chr", level_chr);
- /*tex
- Check other constants against their sup and inf.
- */
- const_chk(buf_size);
- const_chk(nest_size);
- const_chk(max_in_open);
- const_chk(param_size);
- const_chk(save_size);
- const_chk(stack_size);
- const_chk(dvi_buf_size);
- const_chk(max_strings);
- const_chk(strings_free);
- const_chk(hash_extra);
- const_chk(pk_dpi);
- if (error_line > ssup_error_line) {
- error_line = ssup_error_line;
- }
- /*tex
- Array memory allocation
- */
- buffer = xmallocarray(packed_ASCII_code, (unsigned) buf_size);
- nest = xmallocarray(list_state_record, (unsigned) nest_size);
- save_stack = xmallocarray(save_record, (unsigned) save_size);
- input_stack = xmallocarray(in_state_record, (unsigned) stack_size);
- input_file = xmallocarray(alpha_file, (unsigned) max_in_open);
- input_file_callback_id = xmallocarray(int, (unsigned) max_in_open);
- line_stack = xmallocarray(int, (unsigned) max_in_open);
- eof_seen = xmallocarray(boolean, (unsigned) max_in_open);
- grp_stack = xmallocarray(save_pointer, (unsigned) max_in_open);
- if_stack = xmallocarray(pointer, (unsigned) max_in_open);
- source_filename_stack = xmallocarray(str_number, (unsigned) max_in_open);
- full_source_filename_stack = xmallocarray(char *, (unsigned) max_in_open);
- param_stack = xmallocarray(halfword, (unsigned) param_size);
- dvi_buf = xmallocarray(eight_bits, (unsigned) dvi_buf_size);
- /*tex
- Only in ini mode:
- */
- if (ini_version) {
- fixmem = xmallocarray(smemory_word, fix_mem_init + 1);
- memset(voidcast(fixmem), 0, (fix_mem_init + 1) * sizeof(smemory_word));
- fix_mem_min = 0;
- fix_mem_max = fix_mem_init;
- eqtb_top = eqtb_size + hash_extra;
- if (hash_extra == 0)
- hash_top = undefined_control_sequence;
- else
- hash_top = eqtb_top;
- hash = xmallocarray(two_halves, (unsigned) (hash_top + 1));
- memset(hash, 0, sizeof(two_halves) * (unsigned) (hash_top + 1));
- eqtb = xmallocarray(memory_word, (unsigned) (eqtb_top + 1));
- memset(eqtb, 0, sizeof(memory_word) * (unsigned) (eqtb_top + 1));
- init_string_pool_array((unsigned) max_strings);
- reset_cur_string();
- }
- /*tex
- Check the ``constant'' values...
- */
- if ((half_error_line < 30) || (half_error_line > error_line - 15))
- bad = 1;
- if (max_print_line < 60)
- bad = 2;
- if (dvi_buf_size % 8 != 0)
- bad = 3;
- if (hash_prime > hash_size)
- bad = 5;
- if (max_in_open >= (sup_max_in_open+1)) /* 128 */
- bad = 6;
- /*tex
- Here are the inequalities that the quarterword and halfword values
- must satisfy (or rather, the inequalities that they mustn't satisfy):
- */
- if ((min_quarterword > 0) || (max_quarterword < 0x7FFF))
- bad = 11;
- if ((min_halfword > 0) || (max_halfword < 0x3FFFFFFF))
- bad = 12;
- if ((min_quarterword < min_halfword) || (max_quarterword > max_halfword))
- bad = 13;
- if (font_base < min_quarterword)
- bad = 15;
- if ((save_size > max_halfword) || (max_strings > max_halfword))
- bad = 17;
- if (buf_size > max_halfword)
- bad = 18;
- if (max_quarterword - min_quarterword < 0xFFFF)
- bad = 19;
- if (cs_token_flag + eqtb_size + hash_extra > max_halfword)
- bad = 21;
- if (bad > 0) {
- wterm_cr();
- fprintf(term_out,
- "Ouch---my internal constants have been clobbered! ---case %d",
- (int) bad
- );
- } else {
- /*tex Set global variables to their starting values. */
- initialize();
- if (ini_version) {
- /*tex Initialize all the primitives. */
- no_new_control_sequence = false;
- first = 0;
- initialize_commands();
- initialize_etex_commands();
- init_str_ptr = str_ptr;
- no_new_control_sequence = true;
- fix_date_and_time();
- }
- ready_already = 314159;
- }
- return bad;
-}
-
-
-void main_body(void)
-{
- static char pdftex_map[] = "pdftex.map";
- int bad = main_initialize();
- /*tex in case we quit during initialization */
- history = fatal_error_stop;
- /*tex open the terminal for output */
- t_open_out();
- if (!luainit)
- tracefilenames = true;
- if (bad > 0) {
- goto FINAL_END;
- }
- print_banner(luatex_version_string);
- /*tex
- Get the first line of input and prepare to start When we begin the
- following code, \TeX's tables may still contain garbage; the strings
- might not even be present. Thus we must proceed cautiously to get
- bootstrapped in.
-
- But when we finish this part of the program, \TeX\ is ready to call on
- the |main_control| routine to do its work.
- */
- /*tex
- This copies the command line,
- */
- initialize_inputstack();
- if (buffer[iloc] == '*')
- incr(iloc);
- if ((format_ident == 0) || (buffer[iloc] == '&') || dump_line) {
- char *fname = NULL;
- if (format_ident != 0 && !ini_version) {
- /*tex Erase preloaded format. */
- initialize();
- }
- if ((fname = open_fmt_file()) == NULL)
- goto FINAL_END;
- if (!load_fmt_file(fname)) {
- zwclose(fmt_file);
- goto FINAL_END;
- }
- zwclose(fmt_file);
- while ((iloc < ilimit) && (buffer[iloc] == ' '))
- incr(iloc);
- }
- if (output_mode_option != 0)
- output_mode_par = output_mode_value;
- if (draft_mode_option != 0) {
- draft_mode_par = draft_mode_value;
- }
- /*tex can this be moved? */
- pdf_init_map_file((char *) pdftex_map);
- /* */
- if (end_line_char_inactive)
- decr(ilimit);
- else
- buffer[ilimit] = (packed_ASCII_code) end_line_char_par;
- fix_date_and_time();
- random_seed = (microseconds * 1000) + (epochseconds % 1000000);
- init_randoms(random_seed);
- initialize_math();
- fixup_selector(log_opened_global);
- check_texconfig_init();
- if ((iloc < ilimit) && (get_cat_code(cat_code_table_par, buffer[iloc]) != escape_cmd)) {
- /*tex \.{\\input} assumed */
- start_input();
- }
- /*tex Initialize |text_dir_ptr| */
- text_dir_ptr = new_dir(0);
- /*tex Ready to go! */
- history = spotless;
- /*tex Initialize synctex primitive */
- synctexinitcommand();
- /*tex Come to life. */
- main_control();
- flush_node(text_dir_ptr);
- /*tex Prepare for death. */
- final_cleanup();
- close_files_and_terminate();
- FINAL_END:
- do_final_end();
-}
-
-/*tex
-
-Here we do whatever is needed to complete \TeX's job gracefully on the local
-operating system. The code here might come into play after a fatal error; it must
-therefore consist entirely of ``safe'' operations that cannot produce error
-messages. For example, it would be a mistake to call |str_room| or |make_string|
-at this time, because a call on |overflow| might lead to an infinite loop.
-@^system dependencies@>
-
-Actually there's one way to get error messages, via |prepare_mag|; but that can't
-cause infinite recursion. @^recursion@>
-
-This program doesn't bother to close the input files that may still be open.
-
-*/
-
-void close_files_and_terminate(void)
-{
- int callback_id;
- callback_id = callback_defined(stop_run_callback);
- finalize_write_files();
- if (tracing_stats_par > 0) {
- if (callback_id == 0) {
- /*tex
- Output statistics about this job. The present section goes
- directly to the log file instead of using |print| commands,
- because there's no need for these strings to take up
- |string_pool| memory when a non-{\bf stat} version of \TeX\ is
- being used.
- */
- if (log_opened_global) {
- fprintf(log_file,
- "\n\nHere is how much of LuaTeX's memory you used:\n"
- );
- fprintf(log_file, " %d string%s out of %d\n",
- (int) (str_ptr - init_str_ptr),
- (str_ptr == (init_str_ptr + 1) ? "" : "s"),
- (int) (max_strings - init_str_ptr + STRING_OFFSET)
- );
- fprintf(log_file, " %d,%d words of node,token memory allocated",
- (int) var_mem_max, (int) fix_mem_max
- );
- print_node_mem_stats();
- fprintf(log_file,
- " %d multiletter control sequences out of %ld+%d\n",
- (int) cs_count, (long) hash_size, (int) hash_extra
- );
- fprintf(log_file, " %d font%s using %d bytes\n",
- (int) max_font_id(), (max_font_id() == 1 ? "" : "s"),
- (int) font_bytes
- );
- fprintf(log_file,
- " %di,%dn,%dp,%db,%ds stack positions out of %di,%dn,%dp,%db,%ds\n",
- (int) max_in_stack, (int) max_nest_stack,
- (int) max_param_stack, (int) max_buf_stack,
- (int) max_save_stack + 6, (int) stack_size,
- (int) nest_size, (int) param_size, (int) buf_size,
- (int) save_size
- );
- }
- }
- }
- wake_up_terminal();
- /*tex
- Rubish, these \PDF arguments, passed, needs to be fixed, e.g. with a
- dummy in \DVI.
- */
- wrapup_backend();
- /*tex
- Close {\sl Sync\TeX} file and write status.
- */
- synctexterminate(log_opened_global);
- /*tex
- The following is needed because synctex removes files and we want to keep
- them which means renaming a temp file .. we can't bypass the terminate
- because it might do mem cleanup.
- */
- if (synctex_get_mode() > 0) {
- callback_id = callback_defined(finish_synctex_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "->");
- }
- }
- /* free_text_codes(); */
- /* free_math_codes(); */
- if (log_opened_global) {
- wlog_cr();
- selector = selector - 2;
- if ((selector == term_only) && (callback_id == 0)) {
- tprint_nl("Transcript written on ");
- tprint_file_name(NULL, texmf_log_name, NULL);
- print_char('.');
- print_ln();
- }
- lua_a_close_out(log_file);
- log_opened_global = false;
- }
- callback_id = callback_defined(wrapup_run_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "->");
- }
- free_text_codes();
- free_math_codes();
-}
-
-/*tex
-
-We get to the |final_cleanup| routine when \.{\\end} or \.{\\dump} has been
-scanned and |its_all_over|.
-
-*/
-
-void final_cleanup(void)
-{
- /*tex This one gets the value 0 for \.{\\end}, 1 for \.{\\dump}. */
- int c;
- /*tex Here's one for looping marks: */
- halfword i;
- /*tex This was a global temp_ptr: */
- halfword t;
- c = cur_chr;
- if (job_name == 0)
- open_log_file();
- while (input_ptr > 0)
- if (istate == token_list)
- end_token_list();
- else
- end_file_reading();
- while (open_parens > 0) {
- report_stop_file(filetype_tex);
- decr(open_parens);
- }
- if (cur_level > level_one) {
- tprint_nl("(\\end occurred inside a group at level ");
- print_int(cur_level - level_one);
- print_char(')');
- show_save_groups();
- }
- while (cond_ptr != null) {
- tprint_nl("(\\end occurred when ");
- print_cmd_chr(if_test_cmd, cur_if);
- if (if_line != 0) {
- tprint(" on line ");
- print_int(if_line);
- }
- tprint(" was incomplete)");
- if_line = if_line_field(cond_ptr);
- cur_if = subtype(cond_ptr);
- t = cond_ptr;
- cond_ptr = vlink(cond_ptr);
- flush_node(t);
- }
- if (callback_defined(stop_run_callback) == 0)
- if (history != spotless)
- if ((history == warning_issued) || (interaction < error_stop_mode))
- if (selector == term_and_log) {
- selector = term_only;
- tprint_nl("(see the transcript file for additional information)");
- selector = term_and_log;
- }
- if (c == 1) {
- if (ini_version) {
- for (i = 0; i <= biggest_used_mark; i++) {
- delete_top_mark(i);
- delete_first_mark(i);
- delete_bot_mark(i);
- delete_split_first_mark(i);
- delete_split_bot_mark(i);
- }
- for (c = last_box_code; c <= vsplit_code; c++)
- flush_node_list(disc_ptr[c]);
- if (last_glue != max_halfword) {
- flush_node(last_glue);
- }
- /*tex Flush the pseudo files. */
- while (pseudo_files != null) {
- pseudo_close();
- }
- store_fmt_file();
- return;
- }
- tprint_nl("(\\dump is performed only by INITEX)");
- return;
- }
-}
-
-/*tex
-
-Once \TeX\ is working, you should be able to diagnose most errors with the
-\.{\\show} commands and other diagnostic features.
-
-Because we have made some internal changes the optional debug interface
-has been removed.
-
-*/
diff --git a/Build/source/texk/web2c/luatexdir/tex/mainbody.h b/Build/source/texk/web2c/luatexdir/tex/mainbody.h
deleted file mode 100644
index 0d274aeffbe..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mainbody.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/* mainbody.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef MAINBODY_H
-# define MAINBODY_H
-
-extern int luatex_version;
-extern int luatex_revision;
-extern const char *luatex_version_string;
-extern const char *engine_name;
-
-/*
-The following parameters can be changed at compile time to extend or
-reduce \TeX's capacity. They may have different values in \.{INITEX} and
-in production versions of \TeX.
-@.INITEX@>
-@^system dependencies@>
-*/
-
-# define ssup_max_strings 2097151
-
-# define inf_max_strings 100000
-# define sup_max_strings ssup_max_strings
-# define inf_strings_free 100
-# define sup_strings_free sup_max_strings
-
-# define inf_buf_size 500
-# define sup_buf_size 100000000
-
-# define inf_nest_size 40
-# define sup_nest_size 4000
-
-# define inf_max_in_open 6
-# define sup_max_in_open 600 /* was 127. now okay for some 512 nested lua calls */
-
-# define inf_param_size 60
-# define sup_param_size 32767
-
-# define inf_save_size 600
-# define sup_save_size 500000
-
-# define inf_stack_size 200
-# define sup_stack_size 50000
-
-# define inf_dvi_buf_size 800
-# define sup_dvi_buf_size 65536
-
-# define sup_hash_extra sup_max_strings
-# define inf_hash_extra 0
-
-# define inf_expand_depth 100
-# define sup_expand_depth 10000000
-
-# define inf_level_max 0
-# define sup_level_max 500
-
-# define inf_level_chr 1
-# define sup_level_chr 126
-
-# include <stdio.h>
-
-/* Types in the outer block */
-typedef int ASCII_code; /* characters */
-typedef unsigned char eight_bits; /* unsigned one-byte quantity */
-typedef FILE *alpha_file; /* files that contain textual data */
-typedef FILE *byte_file; /* files that contain binary data */
-
-typedef int str_number;
-typedef int pool_pointer;
-typedef unsigned char packed_ASCII_code;
-
-typedef int scaled; /* this type is used for scaled integers */
-typedef char small_number; /* this type is self-explanatory */
-
-typedef float glue_ratio; /* one-word representation of a glue expansion factor */
-
-typedef unsigned short quarterword;
-typedef int halfword;
-
-typedef unsigned char glue_ord; /* infinity to the 0, 1, 2, 3, or 4 power */
-
-typedef unsigned short group_code; /* |save_level| for a level boundary */
-
-typedef int font_index; /* index into |font_info| */
-
-typedef int save_pointer;
-
-/*
-Characters of text that have been converted to \TeX's internal form
-are said to be of type |ASCII_code|, which is a subrange of the integers.
-
-We are assuming that our runtime system is able to read and write UTF-8.
-
-Some of the ASCII codes without visible characters have been given symbolic
-names in this program because they are used with a special meaning.
-*/
-
-
-# define null_code '\0' /* ASCII code that might disappear */
-# define carriage_return '\r' /* ASCII code used at end of line */
-
-/* Global variables */
-extern boolean luainit; /* are we using lua for initializations */
-extern boolean tracefilenames; /* print file open-close info? */
-
-
-extern boolean ini_version; /* are we \.{INITEX}? */
-extern boolean dump_option;
-extern boolean dump_line;
-extern int bound_default;
-extern char *bound_name;
-extern int error_line;
-extern int half_error_line;
-extern int max_print_line;
-extern int max_strings;
-extern int level_max;
-extern int level_chr;
-extern int strings_free;
-extern int font_k;
-extern int buf_size;
-extern int stack_size;
-extern int max_in_open;
-extern int param_size;
-extern int nest_size;
-extern int save_size;
-extern int expand_depth;
-extern int parsefirstlinep;
-extern int filelineerrorstylep;
-extern int haltonerrorp;
-extern boolean quoted_filename;
-
-extern int total_pages;
-extern int dead_cycles;
-
-/*
-In order to make efficient use of storage space, \TeX\ bases its major data
-structures on a |memory_word|, which contains either a (signed) integer,
-possibly scaled, or a (signed) |glue_ratio|, or a small number of
-fields that are one half or one quarter of the size used for storing
-integers.
-
-If |x| is a variable of type |memory_word|, it contains up to four
-fields that can be referred to as follows:
-$$\vbox{\halign{\hfil#&#\hfil&#\hfil\cr
-|x|&.|int|&(an |integer|)\cr
-|x|&.|sc|\qquad&(a |scaled| integer)\cr
-|x|&.|gr|&(a |glue_ratio|)\cr
-|x.hh.lh|, |x.hh|&.|rh|&(two halfword fields)\cr
-|x.hh.b0|, |x.hh.b1|, |x.hh|&.|rh|&(two quarterword fields, one halfword
- field)\cr
-|x.qqqq.b0|, |x.qqqq.b1|, |x.qqqq|&.|b2|, |x.qqqq.b3|\hskip-100pt
- &\qquad\qquad\qquad(four quarterword fields)\cr}}$$
-This is somewhat cumbersome to write, and not very readable either, but
-macros will be used to make the notation shorter and more transparent.
-The \PASCAL\ code below gives a formal definition of |memory_word| and
-its subsidiary types, using packed variant records. \TeX\ makes no
-assumptions about the relative positions of the fields within a word.
-
-We are assuming 32-bit integers, a halfword must contain at least
-32 bits, and a quarterword must contain at least 16 bits.
-@^system dependencies@>
-
-N.B.: Valuable memory space will be dreadfully wasted unless \TeX\ is compiled
-by a \PASCAL\ that packs all of the |memory_word| variants into
-the space of a single integer. This means, for example, that |glue_ratio|
-words should be |short_real| instead of |real| on some computers. Some
-\PASCAL\ compilers will pack an integer whose subrange is `|0..255|' into
-an eight-bit field, but others insist on allocating space for an additional
-sign bit; on such systems you can get 256 values into a quarterword only
-if the subrange is `|-128..127|'.
-
-The present implementation tries to accommodate as many variations as possible,
-so it makes few assumptions. If integers having the subrange
-`|min_quarterword..max_quarterword|' can be packed into a quarterword,
-and if integers having the subrange `|min_halfword..max_halfword|'
-can be packed into a halfword, everything should work satisfactorily.
-
-It is usually most efficient to have |min_quarterword=min_halfword=0|,
-so one should try to achieve this unless it causes a severe problem.
-The values defined here are recommended for most 32-bit computers.
-
-We cannot use the full range of 32 bits in a halfword, because we have
-to allow negative values for potential backend tricks like web2c's
-dynamic allocation, and parshapes pointers have to be able to store at
-least twice the value |max_halfword| (see below). Therefore,
-|max_halfword| is $2^{30}-1$
-*/
-
-# include "tex/memoryword.h"
-
-# define min_quarterword 0 /*smallest allowable value in a |quarterword| */
-# define max_quarterword 65535 /* largest allowable value in a |quarterword| */
-# define min_halfword -0x3FFFFFFF /* smallest allowable value in a |halfword| */
-# define max_halfword 0x3FFFFFFF
- /* largest allowable value in a |halfword| */
-
-
-/*
-The following procedure, which is called just before \TeX\ initializes its
-input and output, establishes the initial values of the date and time.
-It calls a macro-defined |dateandtime| routine. |dateandtime| in turn is
-also a C macro, which calls |get_date_and_time|, passing it the addresses of
-the day, month, etc., so they can be set by the routine.
-|get_date_and_time| also sets up interrupt catching if that
-is conditionally compiled in the C code.
-@^system dependencies@>
-*/
-
-# define fix_date_and_time() dateandtime(time_par,day_par,month_par,year_par)
-
-extern int get_luatexversion(void);
-extern str_number get_luatexrevision(void);
-
-extern int ready_already;
-
-extern void main_body(void);
-extern void close_files_and_terminate(void);
-
-extern void final_cleanup(void);
-extern void debug_help(void); /* routine to display various things */
-
-extern int main_initialize(void);
-
-/* lazy me */
-# define get_cur_font() equiv(cur_font_loc)
-# define zset_cur_font set_cur_font
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c b/Build/source/texk/web2c/luatexdir/tex/maincontrol.c
deleted file mode 100644
index 22f601ba275..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.c
+++ /dev/null
@@ -1,4245 +0,0 @@
-/*
-
-maincontrol.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-#define mode mode_par
-#define tail tail_par
-#define head head_par
-#define dir_save dirs_par
-
-/*tex
-
-We come now to the |main_control| routine, which contains the master switch that
-causes all the various pieces of \TeX\ to do their things, in the right order.
-
-In a sense, this is the grand climax of the program: It applies all the tools
-that we have worked so hard to construct. In another sense, this is the messiest
-part of the program: It necessarily refers to other pieces of code all over the
-place, so that a person can't fully understand what is going on without paging
-back and forth to be reminded of conventions that are defined elsewhere. We are
-now at the hub of the web, the central nervous system that touches most of the
-other parts and ties them together. @^brain@>
-
-The structure of |main_control| itself is quite simple. There's a label called
-|big_switch|, at which point the next token of input is fetched using
-|get_x_token|. Then the program branches at high speed into one of about 100
-possible directions, based on the value of the current mode and the newly fetched
-command code; the sum |abs(mode)+cur_cmd| indicates what to do next. For example,
-the case `|vmode+letter|' arises when a letter occurs in vertical mode (or
-internal vertical mode); this case leads to instructions that initialize a new
-paragraph and enter horizontal mode.
-
-The big |case| statement that contains this multiway switch has been labeled
-|reswitch|, so that the program can |goto reswitch| when the next token has
-already been fetched. Most of the cases are quite short; they call an ``action
-procedure'' that does the work for that case, and then they either |goto
-reswitch| or they ``fall through'' to the end of the |case| statement, which
-returns control back to |big_switch|. Thus, |main_control| is not an extremely
-large procedure, in spite of the multiplicity of things it must do; it is small
-enough to be handled by PASCAL compilers that put severe restrictions on
-procedure size. @!@^action procedure@>
-
-One case is singled out for special treatment, because it accounts for most of
-\TeX's activities in typical applications. The process of reading simple text and
-converting it into |char_node| records, while looking for ligatures and kerns, is
-part of \TeX's ``inner loop''; the whole program runs efficiently when its inner
-loop is fast, so this part has been written with particular care.
-
-We leave the |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we set
-it equal to |sf_code(cur_chr)|, except that it should never change from a value
-less than 1000 to a value exceeding 1000. The most common case is
-|sf_code(cur_chr)=1000|, so we want that case to be fast.
-
-*/
-
-void adjust_space_factor(void)
-{
- halfword s = get_sf_code(cur_chr);
- if (s == 1000) {
- space_factor_par = 1000;
- } else if (s < 1000) {
- if (s > 0)
- space_factor_par = s;
- } else if (space_factor_par < 1000) {
- space_factor_par = 1000;
- } else {
- space_factor_par = s;
- }
-}
-
-/*tex
-
-To handle the execution state of |main_control|'s eternal loop, an extra global
-variable is used, along with a macro to define its values.
-
-*/
-
-#define goto_next 0
-#define goto_skip_token 1
-#define goto_return 2
-
-static int main_control_state;
-static int local_level = 0;
-
-/*tex
-
-@* Main control helpers.
-
-Here are all the functions that are called from |main_control| that
-are not already defined elsewhere. For the moment, this list simply
-in the order that the appear in |init_main_control|, below.
-
-*/
-
-static void run_char_num (void) {
- scan_char_num();
- cur_chr = cur_val;
- adjust_space_factor();
- tail_append(new_char(cur_font_par, cur_chr));
-}
-
-static void run_char (void) {
- adjust_space_factor();
- tail_append(new_char(cur_font_par, cur_chr));
-}
-
-static void run_node (void) {
- halfword n = cur_chr;
- if (copy_lua_input_nodes_par) {
- n = copy_node_list(n);
- }
- tail_append(n);
- if (nodetype_has_attributes(type(n)) && node_attr(n) == null) {
- build_attribute_list(n);
- }
- while (vlink(n) != null) {
- n = vlink(n);
- tail_append(n);
- if (nodetype_has_attributes(type(n)) && node_attr(n) == null) {
- build_attribute_list(n);
- }
- }
-}
-
-static void run_lua_call(void) {
- if (cur_chr <= 0) {
- normal_error("luacall", "invalid number");
- } else {
- str_number u = save_cur_string();
- luacstrings = 0;
- luafunctioncall(cur_chr);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
-}
-
-/*tex
-
-The occurrence of blank spaces is almost part of \TeX's inner loop, since we
-usually encounter about one space for every five non-blank characters. Therefore
-|main_control| gives second-highest priority to ordinary spaces.
-
-When a glue parameter like \.{\\spaceskip} is set to `\.{0pt}', we will see to it
-later that the corresponding glue specification is precisely |zero_glue|, not
-merely a pointer to some specification that happens to be full of zeroes.
-Therefore it is simple to test whether a glue parameter is zero or~not.
-
-*/
-
-static void run_app_space (void) {
- halfword p; /* was a global temp_ptr */
- int method = disable_space_par ;
- if (method == 1) {
- /*tex Don't inject anything, not even zero skip. */
- } else if (method == 2) {
- p = new_glue(zero_glue);
- couple_nodes(tail,p);
- tail = p;
- } else if ((abs(mode) + cur_cmd == hmode + spacer_cmd) && (!(space_factor_par == 1000))) {
- app_space();
- } else {
- /*tex Append a normal inter-word space to the current list. */
- if (glue_is_zero(space_skip_par)) {
- /*tex Find the glue specification for text spaces in the current font. */
- p = new_glue(zero_glue);
- width(p) = space(cur_font_par);
- stretch(p) = space_stretch(cur_font_par);
- shrink(p) = space_shrink(cur_font_par);
-
- } else {
- p = new_param_glue(space_skip_code);
- }
- /*tex So from now we have a subtype with spaces: */
- subtype(p) = space_skip_code + 1 ;
- couple_nodes(tail,p);
- tail = p;
- }
-}
-
-/*tex
-
-Append a |boundary_node|
-
-*/
-
-static void run_boundary (void) {
- halfword n ;
- n = new_node(boundary_node,cur_chr);
- if ((cur_chr == 1) || (cur_chr == 2) ) {
- /*tex We expect a user boundary or protrusion boundary. */
- scan_int();
- boundary_value(n) = cur_val;
- }
- couple_nodes(tail, n);
- tail = n;
-}
-
-static void run_char_ghost (void) {
- int t;
- t = cur_chr;
- get_x_token();
- if ((cur_cmd == letter_cmd) || (cur_cmd == other_char_cmd)
- || (cur_cmd == char_given_cmd) || (cur_cmd == char_num_cmd)) {
- halfword p = new_glyph(get_cur_font(), cur_chr);
- if (t == 0) {
- set_is_leftghost(p);
- } else {
- set_is_rightghost(p);
- }
- tail_append(p);
- }
-}
-
-static void run_relax (void) {
- return;
-}
-
-/*tex
-
-|ignore_spaces| is a special case: after it has acted, |get_x_token| has already
-fetched the next token from the input, so that operation in |main_control| should
-be skipped.
-
-*/
-
-static void run_ignore_spaces (void) {
- if (cur_chr == 0) {
- /*tex Get the next non-blank non-call... */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- main_control_state = goto_skip_token;
- } else {
- int t = scanner_status;
- scanner_status = normal;
- get_next();
- scanner_status = t;
- cur_cs = prim_lookup(cs_text(cur_cs));
- if (cur_cs != undefined_primitive) {
- cur_cmd = get_prim_eq_type(cur_cs);
- cur_chr = get_prim_equiv(cur_cs);
- cur_tok = (cur_cmd * STRING_OFFSET) + cur_chr;
- main_control_state = goto_skip_token;
- }
- }
-}
-
-/*tex
-
-|stop| is the second special case. We want |main_control| to return to its caller
-if there is nothing left to do.
-
-*/
-
-static void run_stop (void) {
- if (its_all_over()) {
- /*tex this is the only way out */
- main_control_state= goto_return;
- }
-}
-
-static void run_non_math_math (void) {
- back_input();
- new_graf(true);
-}
-
-/*tex
-
- We build up an argument to |set_math_char|:
-
-*/
-
-static void run_math_char_num (void) {
- mathcodeval mval;
- if (cur_chr == 0)
- mval = scan_mathchar(tex_mathcode);
- else if (cur_chr == 1)
- mval = scan_mathchar(umath_mathcode);
- else
- mval = scan_mathchar(umathnum_mathcode);
- math_char_in_text(mval);
-}
-
-/*tex
-
- We build up an argument to |set_math_char|:
-*/
-
-static void run_math_given (void) {
- mathcodeval mval;
- mval = mathchar_from_integer(cur_chr, tex_mathcode);
- math_char_in_text(mval);
-}
-
-/*tex
-
- We build up an argument to |set_math_char| the \LUATEX\ way:
-*/
-
-static void run_xmath_given (void) {
- mathcodeval mval;
- mval = mathchar_from_integer(cur_chr, umath_mathcode);
- math_char_in_text(mval);
-}
-
-/*tex
-
-The most important parts of |main_control| are concerned with \TeX's chief
-mission of box-making. We need to control the activities that put entries on
-vlists and hlists, as well as the activities that convert those lists into boxes.
-All of the necessary machinery has already been developed; it remains for us to
-``push the buttons'' at the right times.
-
-As an introduction to these routines, let's consider one of the simplest cases:
-What happens when `\.{\\hrule}' occurs in vertical mode, or `\.{\\vrule}' in
-horizontal mode or math mode? The code in |main_control| is short, since the
-|scan_rule_spec| routine already does most of what is required; thus, there is no
-need for a special action procedure.
-
-Note that baselineskip calculations are disabled after a rule in vertical mode,
-by setting |prev_depth:=ignore_depth|.
-
-*/
-
-static void run_rule (void) {
- tail_append(scan_rule_spec());
- if (abs(mode) == vmode)
- prev_depth_par = ignore_depth;
- else if (abs(mode) == hmode)
- space_factor_par = 1000;
-}
-
-/*tex
-
-Many of the actions related to box-making are triggered by the appearance of
-braces in the input. For example, when the user says `\.{\\hbox} \.{to}
-\.{100pt\{$\langle\,\hbox{hlist}\,\rangle$\}}' in vertical mode, the information
-about the box size (100pt, |exactly|) is put onto |save_stack| with a level
-boundary word just above it, and |cur_group:=adjusted_hbox_group|; \TeX\ enters
-restricted horizontal mode to process the hlist. The right brace eventually
-causes |save_stack| to be restored to its former state, at which time the
-information about the box size (100pt, |exactly|) is available once again; a box
-is packaged and we leave restricted horizontal mode, appending the new box to the
-current list of the enclosing mode (in this case to the current list of vertical
-mode), followed by any vertical adjustments that were removed from the box by
-|hpack|.
-
-The next few sections of the program are therefore concerned with the treatment
-of left and right curly braces.
-
-If a left brace occurs in the middle of a page or paragraph, it simply introduces
-a new level of grouping, and the matching right brace will not have such a
-drastic effect. Such grouping affects neither the mode nor the current list.
-
-*/
-
-static void run_left_brace (void) {
- new_save_level(simple_group);
- eq_word_define(int_base + no_local_whatsits_code, 0);
- eq_word_define(int_base + no_local_dirs_code, 0);
-}
-
-static void run_begin_group (void) {
- new_save_level(semi_simple_group);
- eq_word_define(int_base + no_local_whatsits_code, 0);
- eq_word_define(int_base + no_local_dirs_code, 0);
-}
-
-static void run_end_group (void) {
- if (cur_group == semi_simple_group) {
- fixup_directions();
- } else {
- off_save();
- }
-}
-
-/*tex
-
-Constructions that require a box are started by calling |scan_box| with a
-specified context code. The |scan_box| routine verifies that a |make_box| command
-comes next and then it calls |begin_box|.
-
-*/
-
-static void run_move (void) {
- int t = cur_chr;
- scan_normal_dimen();
- if (t == 0)
- scan_box(cur_val);
- else
- scan_box(-cur_val);
-}
-
-static void run_leader_ship (void) {
- scan_box(leader_flag - a_leaders + cur_chr);
-}
-
-static void run_make_box (void) {
- begin_box(0);
-}
-
-static void run_box_dir (void) {
- scan_register_num();
- cur_box = box(cur_val);
- scan_optional_equals();
- scan_direction();
- if (cur_box != null)
- box_dir(cur_box) = cur_val;
-}
-
-static void run_box_direction (void) {
- scan_register_num();
- cur_box = box(cur_val);
- scan_optional_equals();
- scan_int();
- check_dir_value(cur_val);
- if (cur_box != null)
- box_dir(cur_box) = cur_val;
-}
-
-/*tex
-
-There is a really small patch to add a new primitive called \.{\\quitvmode}. In
-vertical modes, it is identical to \.{\\indent}, but in horizontal and math modes
-it is really a no-op (as opposed to \.{\\indent}, which executes the
-|indent_in_hmode| procedure).
-
-A paragraph begins when horizontal-mode material occurs in vertical mode, or when
-the paragraph is explicitly started by `\.{\\quitvmode}', `\.{\\indent}' or
-`\.{\\noindent}'.
-
-*/
-
-static void run_start_par_vmode (void) {
- new_graf((cur_chr > 0));
-}
-
-static void run_start_par (void) {
- if (cur_chr != 2)
- indent_in_hmode();
-}
-
-static void run_new_graf (void) {
- back_input();
- new_graf(true);
-}
-
-/*tex
-
-A paragraph ends when a |par_end| command is sensed, or when we are in horizontal
-mode when reaching the right brace of vertical-mode routines like \.{\\vbox},
-\.{\\insert}, or \.{\\output}.
-
-*/
-
-static void run_par_end_vmode (void) {
- normal_paragraph();
- if (mode > 0) {
- checked_page_filter(vmode_par);
- build_page();
- }
-}
-
-static void run_par_end_hmode (void) {
- if (align_state < 0) {
- /*tex This tries to recover from an alignment that didn't end properly. */
- off_save();
- }
- /* This takes us to the enclosing mode, if |mode>0|. */
- end_graf(bottom_level);
- if (mode == vmode) {
- checked_page_filter(hmode_par);
- build_page();
- }
-}
-
-static void append_italic_correction_mmode (void) {
- tail_append(new_kern(0));
-}
-
-static void run_local_box (void) {
- append_local_box(cur_chr);
-}
-
-static void run_halign_mmode (void) {
- if (privileged()) {
- if (cur_group == math_shift_group)
- init_align();
- else
- off_save();
- }
-}
-
-static void run_eq_no (void) {
- if (privileged()) {
- if (cur_group == math_shift_group)
- start_eq_no();
- else
- off_save();
- }
-}
-
-static void run_letter_mmode (void) {
- set_math_char(get_math_code(cur_chr));
-}
-
-static void run_char_num_mmode (void) {
- scan_char_num();
- cur_chr = cur_val;
- set_math_char(get_math_code(cur_chr));
-}
-
-static void run_math_char_num_mmode (void) {
- mathcodeval mval;
- if (cur_chr == 0)
- mval = scan_mathchar(tex_mathcode);
- else if (cur_chr == 1)
- mval = scan_mathchar(umath_mathcode);
- else
- mval = scan_mathchar(umathnum_mathcode);
- set_math_char(mval);
-}
-
-static void run_math_given_mmode (void) {
- mathcodeval mval;
- mval = mathchar_from_integer(cur_chr, tex_mathcode);
- set_math_char(mval);
-}
-
-static void run_xmath_given_mmode (void) {
- mathcodeval mval;
- mval = mathchar_from_integer(cur_chr, umath_mathcode);
- set_math_char(mval);
-}
-
-static void run_delim_num (void) {
- mathcodeval mval;
- if (cur_chr == 0)
- mval = scan_delimiter_as_mathchar(tex_mathcode);
- else
- mval = scan_delimiter_as_mathchar(umath_mathcode);
- set_math_char(mval);
-}
-
-static void run_vcenter (void) {
- scan_spec(vcenter_group);
- normal_paragraph();
- push_nest();
- mode = -vmode;
- prev_depth_par = ignore_depth;
- if (every_vbox_par != null)
- begin_token_list(every_vbox_par, every_vbox_text);
-}
-
-static void run_math_style (void) {
- tail_append(new_style((small_number) cur_chr));
-}
-
-static void run_non_script (void) {
- tail_append(new_glue(zero_glue));
- subtype(tail) = cond_math_glue;
-}
-
-static void run_math_choice (void) {
- if (cur_chr == 0)
- append_choices();
- else
- setup_math_style();
-}
-
-static void run_math_shift (void) {
- if (cur_group == math_shift_group)
- after_math();
- else
- off_save();
-}
-
-static void run_after_assignment (void) {
- get_token();
- after_token = cur_tok;
-}
-
-static void run_after_group (void) {
- get_token();
- save_for_after(cur_tok);
-}
-
-static void run_extension (void) {
- do_extension(0);
-}
-
-static void run_normal (void) {
-{
- switch (cur_chr) {
- case save_pos_code:
- new_whatsit(save_pos_node);
- break;
- case save_cat_code_table_code:
- scan_int();
- if ((cur_val < 0) || (cur_val > 0x7FFF)) {
- print_err("Invalid \\catcode table");
- help1(
- "All \\catcode table ids must be between 0 and 0x7FFF"
- );
- error();
- } else {
- if (cur_val == cat_code_table_par) {
- print_err("Invalid \\catcode table");
- help1(
- "You cannot overwrite the current \\catcode table"
- );
- error();
- } else {
- copy_cat_codes(cat_code_table_par, cur_val);
- }
- }
- break;
- case init_cat_code_table_code:
- scan_int();
- if ((cur_val < 0) || (cur_val > 0x7FFF)) {
- print_err("Invalid \\catcode table");
- help1(
- "All \\catcode table ids must be between 0 and 0x7FFF"
- );
- error();
- } else {
- if (cur_val == cat_code_table_par) {
- print_err("Invalid \\catcode table");
- help1(
- "You cannot overwrite the current \\catcode table"
- );
- error();
- } else {
- initex_cat_codes(cur_val);
- }
- }
- break;
- case set_random_seed_code:
- /* Negative random seed values are silently converted to positive ones */
- scan_int();
- if (cur_val < 0)
- negate(cur_val);
- random_seed = cur_val;
- init_randoms(random_seed);
- break;
- case late_lua_code:
- new_whatsit(late_lua_node); /* type == normal */
- late_lua_name(tail) = scan_lua_state();
- (void) scan_toks(false, false);
- late_lua_data(tail) = def_ref;
- break;
- case late_lua_call_code:
- new_whatsit(late_lua_node);
- late_lua_type(tail) = lua_refid_call;
- scan_int();
- late_lua_data(tail) = cur_val;
- break;
- case expand_font_code:
- read_expand_font();
- break;
- default:
- confusion("int1");
- break;
- }
- }
-}
-
-/*tex
-
-This is experimental and not used for production, only for testing and writing
-macros (some options stay).
-
-*/
-
-#define mathoption_set_int(A) \
- scan_int(); \
- word_define(mathoption_int_base+A, cur_val);
-
-static void run_option(void) {
- int a = 0 ;
- switch (cur_chr) {
- case math_option_code:
- if (scan_keyword("old")) {
- mathoption_set_int(c_mathoption_old_code);
- /*
- } else if (scan_keyword("umathcodemeaning")) {
- mathoption_set_int(c_mathoption_umathcode_meaning_code);
- */
- } else {
- normal_warning("mathoption","unknown key");
- }
- break;
- default:
- /* harmless */
- break;
- }
-}
-
-static void lua_function_call(void) {
- scan_int();
- if (cur_val <= 0) {
- normal_error("luafunctioncall", "invalid number");
- } else {
- str_number u = save_cur_string();
- luacstrings = 0;
- luafunctioncall(cur_val);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
-}
-
-static void lua_bytecode_call(void) {
- scan_int();
- if (cur_val < 0 || cur_val > 65535) {
- normal_error("luabytecodecall", "invalid number");
- } else {
- str_number u = save_cur_string();
- luacstrings = 0;
- luabytecodecall(cur_val);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
-}
-
-/*tex
-
-For mode-independent commands, the following macro is useful.
-
-Also, there is a list of cases where the user has probably gotten into or out of
-math mode by mistake. \TeX\ will insert a dollar sign and rescan the current
-token, and it makes sense ot have a macro for that as well.
-
-*/
-
-#define any_mode(A,B) jump_table[vmode+(A)]=B; jump_table[hmode+(A)]=B; jump_table[mmode+(A)]=B
-#define non_math(A,B) jump_table[vmode+(A)]=B; jump_table[hmode+(A)]=B;
-
-/*tex
-
-The |main_control| uses a jump table, and |init_main_control| sets that table up.
-
-*/
-
-typedef void (*main_control_function) (void);
-
-main_control_function *jump_table;
-
-static void init_main_control (void) {
- jump_table = xmalloc((mmode+max_command_cmd+1) * sizeof(main_control_function)) ;
-
- jump_table[hmode + char_num_cmd] = run_char_num;
- jump_table[hmode + letter_cmd] = run_char;
- jump_table[hmode + other_char_cmd] = run_char;
- jump_table[hmode + char_given_cmd] = run_char;
- jump_table[hmode + spacer_cmd] = run_app_space;
- jump_table[hmode + ex_space_cmd] = run_app_space;
- jump_table[mmode + ex_space_cmd] = run_app_space;
- jump_table[hmode + boundary_cmd] = run_boundary;
- jump_table[hmode + char_ghost_cmd] = run_char_ghost;
- jump_table[mmode + char_ghost_cmd] = run_char_ghost;
- any_mode(relax_cmd, run_relax);
- jump_table[vmode + spacer_cmd] = run_relax;
- jump_table[mmode + spacer_cmd] = run_relax;
- jump_table[mmode + boundary_cmd] = run_relax;
- any_mode(ignore_spaces_cmd,run_ignore_spaces);
- jump_table[vmode + stop_cmd] = run_stop;
- jump_table[vmode + math_char_num_cmd] = run_non_math_math;
- jump_table[vmode + math_given_cmd] = run_non_math_math;
- jump_table[vmode + xmath_given_cmd] = run_non_math_math;
- jump_table[hmode + math_char_num_cmd] = run_math_char_num;
- jump_table[hmode + math_given_cmd] = run_math_given;
- jump_table[hmode + xmath_given_cmd] = run_xmath_given;
-
- jump_table[vmode + vmove_cmd] = report_illegal_case;
- jump_table[hmode + hmove_cmd] = report_illegal_case;
- jump_table[mmode + hmove_cmd] = report_illegal_case;
- any_mode(last_item_cmd, report_illegal_case);
- jump_table[vmode + vadjust_cmd] = report_illegal_case;
- jump_table[vmode + ital_corr_cmd] = report_illegal_case;
- non_math(eq_no_cmd,report_illegal_case);
- any_mode(mac_param_cmd,report_illegal_case);
-
- non_math(sup_mark_cmd, insert_dollar_sign);
- non_math(sub_mark_cmd, insert_dollar_sign);
- non_math(super_sub_script_cmd, insert_dollar_sign);
- non_math(no_super_sub_script_cmd, insert_dollar_sign);
- non_math(math_comp_cmd, insert_dollar_sign);
- non_math(delim_num_cmd, insert_dollar_sign);
- non_math(left_right_cmd, insert_dollar_sign);
- non_math(above_cmd, insert_dollar_sign);
- non_math(radical_cmd, insert_dollar_sign);
- non_math(math_style_cmd, insert_dollar_sign);
- non_math(math_choice_cmd, insert_dollar_sign);
- non_math(vcenter_cmd, insert_dollar_sign);
- non_math(non_script_cmd, insert_dollar_sign);
- non_math(mkern_cmd, insert_dollar_sign);
- non_math(limit_switch_cmd, insert_dollar_sign);
- non_math(mskip_cmd, insert_dollar_sign);
- non_math(math_accent_cmd, insert_dollar_sign);
- jump_table[mmode + endv_cmd] = insert_dollar_sign;
- jump_table[mmode + par_end_cmd] = insert_dollar_sign_par_end;
- jump_table[mmode + stop_cmd] = insert_dollar_sign;
- jump_table[mmode + vskip_cmd] = insert_dollar_sign;
- jump_table[mmode + un_vbox_cmd] = insert_dollar_sign;
- jump_table[mmode + valign_cmd] = insert_dollar_sign;
- jump_table[mmode + hrule_cmd] = insert_dollar_sign;
- jump_table[mmode + no_hrule_cmd] = insert_dollar_sign;
- jump_table[vmode + hrule_cmd] = run_rule;
- jump_table[vmode + no_hrule_cmd] = run_rule;
- jump_table[hmode + vrule_cmd] = run_rule;
- jump_table[hmode + no_vrule_cmd] = run_rule;
- jump_table[mmode + vrule_cmd] = run_rule;
- jump_table[mmode + no_vrule_cmd] = run_rule;
- jump_table[vmode + vskip_cmd] = append_glue;
- jump_table[hmode + hskip_cmd] = append_glue;
- jump_table[mmode + hskip_cmd] = append_glue;
- jump_table[mmode + mskip_cmd] = append_glue;
- any_mode(kern_cmd, append_kern);
- jump_table[mmode + mkern_cmd] = append_kern;
- non_math(left_brace_cmd, run_left_brace);
- any_mode(begin_group_cmd,run_begin_group);
- any_mode(end_group_cmd, run_end_group);
- any_mode(right_brace_cmd, handle_right_brace);
- jump_table[vmode + hmove_cmd] = run_move;
- jump_table[hmode + vmove_cmd] = run_move;
- jump_table[mmode + vmove_cmd] = run_move;
- any_mode(leader_ship_cmd, run_leader_ship);
- any_mode(make_box_cmd, run_make_box);
- any_mode(assign_box_dir_cmd, run_box_dir);
- any_mode(assign_box_direction_cmd, run_box_direction);
- jump_table[vmode + start_par_cmd] = run_start_par_vmode;
- jump_table[hmode + start_par_cmd] = run_start_par;
- jump_table[mmode + start_par_cmd] = run_start_par;
- jump_table[vmode + letter_cmd] = run_new_graf;
- jump_table[vmode + other_char_cmd] = run_new_graf;
- jump_table[vmode + char_num_cmd] = run_new_graf;
- jump_table[vmode + char_given_cmd] = run_new_graf;
- jump_table[vmode + char_ghost_cmd] = run_new_graf;
- jump_table[vmode + math_shift_cmd] = run_new_graf;
- jump_table[vmode + math_shift_cs_cmd] = run_new_graf;
- jump_table[vmode + un_hbox_cmd] = run_new_graf;
- jump_table[vmode + vrule_cmd] = run_new_graf;
- jump_table[vmode + no_vrule_cmd] = run_new_graf;
- jump_table[vmode + accent_cmd] = run_new_graf;
- jump_table[vmode + discretionary_cmd] = run_new_graf;
- jump_table[vmode + hskip_cmd] = run_new_graf;
- jump_table[vmode + valign_cmd] = run_new_graf;
- jump_table[vmode + ex_space_cmd] = run_new_graf;
- jump_table[vmode + boundary_cmd] = run_new_graf;
- jump_table[vmode + par_end_cmd] = run_par_end_vmode;
- jump_table[hmode + par_end_cmd] = run_par_end_hmode;
- jump_table[hmode + stop_cmd] = head_for_vmode;
- jump_table[hmode + vskip_cmd] = head_for_vmode;
- jump_table[hmode + hrule_cmd] = head_for_vmode;
- jump_table[hmode + no_hrule_cmd] = head_for_vmode;
- jump_table[hmode + un_vbox_cmd] = head_for_vmode;
- jump_table[hmode + halign_cmd] = head_for_vmode;
- any_mode(insert_cmd,begin_insert_or_adjust);
- jump_table[hmode + vadjust_cmd] = begin_insert_or_adjust;
- jump_table[mmode + vadjust_cmd] = begin_insert_or_adjust;
- any_mode(mark_cmd, handle_mark);
- any_mode(break_penalty_cmd, append_penalty);
- any_mode(remove_item_cmd, delete_last);
- jump_table[vmode + un_vbox_cmd] = unpackage;
- jump_table[hmode + un_hbox_cmd] = unpackage;
- jump_table[mmode + un_hbox_cmd] = unpackage;
- jump_table[hmode + ital_corr_cmd] = append_italic_correction;
- jump_table[mmode + ital_corr_cmd] = append_italic_correction_mmode;
- jump_table[hmode + discretionary_cmd] = append_discretionary;
- jump_table[mmode + discretionary_cmd] = append_discretionary;
- any_mode(assign_local_box_cmd, run_local_box);
- jump_table[hmode + accent_cmd] = make_accent;
- any_mode(car_ret_cmd,align_error);
- any_mode(tab_mark_cmd,align_error);
- any_mode(no_align_cmd,no_align_error);
- any_mode(omit_cmd, omit_error);
- jump_table[vmode + halign_cmd] = init_align;
- jump_table[hmode + valign_cmd] = init_align;
- jump_table[mmode + halign_cmd] = run_halign_mmode;
- jump_table[vmode + endv_cmd] = do_endv;
- jump_table[hmode + endv_cmd] = do_endv;
- any_mode(end_cs_name_cmd, cs_error);
- jump_table[hmode + math_shift_cmd] = init_math;
- jump_table[hmode + math_shift_cs_cmd] = init_math;
- jump_table[mmode + eq_no_cmd] = run_eq_no;
- jump_table[mmode + left_brace_cmd] = math_left_brace;
- jump_table[mmode + letter_cmd] = run_letter_mmode;
- jump_table[mmode + other_char_cmd] = run_letter_mmode;
- jump_table[mmode + char_given_cmd] = run_letter_mmode;
- jump_table[mmode + char_num_cmd] = run_char_num_mmode;
- jump_table[mmode + math_char_num_cmd] = run_math_char_num_mmode;
- jump_table[mmode + math_given_cmd] = run_math_given_mmode;
- jump_table[mmode + xmath_given_cmd] = run_xmath_given_mmode;
- jump_table[mmode + delim_num_cmd] = run_delim_num;
- jump_table[mmode + math_comp_cmd] = math_math_comp;
- jump_table[mmode + limit_switch_cmd] = math_limit_switch;
- jump_table[mmode + radical_cmd] = math_radical;
- jump_table[mmode + accent_cmd] = math_ac;
- jump_table[mmode + math_accent_cmd] = math_ac;
- jump_table[mmode + vcenter_cmd] = run_vcenter;
- jump_table[mmode + math_style_cmd] = run_math_style;
- jump_table[mmode + non_script_cmd] = run_non_script;
- jump_table[mmode + math_choice_cmd] = run_math_choice;
- jump_table[mmode + above_cmd] = math_fraction;
- jump_table[mmode + sub_mark_cmd] = sub_sup;
- jump_table[mmode + sup_mark_cmd] = sub_sup;
- jump_table[mmode + super_sub_script_cmd] = sub_sup;
- jump_table[mmode + no_super_sub_script_cmd] = no_sub_sup;
- jump_table[mmode + left_right_cmd] = math_left_right;
- jump_table[mmode + math_shift_cmd] = run_math_shift;
- jump_table[mmode + math_shift_cs_cmd] = run_math_shift;
- any_mode(toks_register_cmd, prefixed_command);
- any_mode(assign_toks_cmd, prefixed_command);
- any_mode(assign_int_cmd, prefixed_command);
- any_mode(assign_attr_cmd, prefixed_command);
- any_mode(assign_dir_cmd, prefixed_command);
- any_mode(assign_direction_cmd, prefixed_command);
- any_mode(assign_dimen_cmd, prefixed_command);
- any_mode(assign_glue_cmd, prefixed_command);
- any_mode(assign_mu_glue_cmd, prefixed_command);
- any_mode(assign_font_dimen_cmd, prefixed_command);
- any_mode(assign_font_int_cmd, prefixed_command);
- any_mode(set_aux_cmd, prefixed_command);
- any_mode(set_prev_graf_cmd, prefixed_command);
- any_mode(set_page_dimen_cmd, prefixed_command);
- any_mode(set_page_int_cmd, prefixed_command);
- any_mode(set_box_dimen_cmd, prefixed_command);
- any_mode(set_tex_shape_cmd, prefixed_command);
- any_mode(set_etex_shape_cmd, prefixed_command);
- any_mode(def_char_code_cmd, prefixed_command);
- any_mode(def_del_code_cmd, prefixed_command);
- any_mode(extdef_math_code_cmd, prefixed_command);
- any_mode(extdef_del_code_cmd, prefixed_command);
- any_mode(def_family_cmd, prefixed_command);
- any_mode(set_math_param_cmd, prefixed_command);
- any_mode(set_font_cmd, prefixed_command);
- any_mode(def_font_cmd, prefixed_command);
- any_mode(letterspace_font_cmd, prefixed_command);
- any_mode(copy_font_cmd, prefixed_command);
- any_mode(set_font_id_cmd, prefixed_command);
- any_mode(register_cmd, prefixed_command);
- any_mode(advance_cmd, prefixed_command);
- any_mode(multiply_cmd, prefixed_command);
- any_mode(divide_cmd, prefixed_command);
- any_mode(prefix_cmd, prefixed_command);
- any_mode(let_cmd, prefixed_command);
- any_mode(shorthand_def_cmd, prefixed_command);
- any_mode(read_to_cs_cmd, prefixed_command);
- any_mode(def_cmd, prefixed_command);
- any_mode(set_box_cmd, prefixed_command);
- any_mode(hyph_data_cmd, prefixed_command);
- any_mode(set_interaction_cmd, prefixed_command);
- any_mode(after_assignment_cmd,run_after_assignment);
- any_mode(after_group_cmd,run_after_group);
- any_mode(in_stream_cmd,open_or_close_in);
- any_mode(message_cmd,issue_message);
- any_mode(case_shift_cmd, shift_case);
- any_mode(xray_cmd, show_whatever);
- any_mode(normal_cmd, run_normal);
- any_mode(extension_cmd, run_extension);
- any_mode(option_cmd, run_option);
-
- any_mode(lua_function_call_cmd, lua_function_call);
- any_mode(lua_bytecode_call_cmd, lua_bytecode_call);
- any_mode(def_lua_call_cmd, prefixed_command);
- any_mode(lua_call_cmd, run_lua_call);
- /* any_mode(lua_expandable_call_cmd, run_lua_call); */ /* no! outside jump table anyway, handled in expand() */
- any_mode(node_cmd, run_node);
-
- any_mode(combine_toks_cmd, combine_the_toks);
-}
-
-/*tex
-
- And here is |main_control| itself. It is quite short nowadays.
-
-*/
-
-void main_control(void)
-{
- main_control_state = goto_next;
- init_main_control() ;
- if (equiv(every_job_loc) != null) {
- begin_token_list(equiv(every_job_loc), every_job_text);
- }
- while (1) {
- if (main_control_state == goto_skip_token) {
- main_control_state = goto_next;
- } else {
- get_x_token();
- }
- /*tex
- Give diagnostic information, if requested When a new token has just
- been fetched at |big_switch|, we have an ideal place to monitor
- \TeX's activity.
- */
- if (interrupt != 0 && OK_to_interrupt) {
- back_input();
- check_interrupt();
- continue;
- }
- if (tracing_commands_par > 0) {
- show_cur_cmd_chr();
- }
- /*tex run the command */
- (jump_table[(abs(mode) + cur_cmd)])();
- if (main_control_state == goto_return) {
- return;
- }
- }
- /*tex not reached */
- return;
-}
-
-/*tex
-
-We assume a trailing relax: |{...}\relax|, so we don't need a |back_input()| here.
-
-*/
-
-extern void local_control_message(const char *s)
-{
- tprint("local control level ");
- print_int(local_level);
- tprint(": ");
- tprint(s);
- tprint_nl("");
-}
-
-/*tex Note for me (HH): in luametatex I have the option to use the save stack which for
- some experiments seems to work better. But I'll probably not go forward with
- some intended extension anyway (too messy), so we're currently in sync.
- Instead there are now two optional parameters in |runtoks|, plus a |quittoks|
- companion. I also added some more tracing as well as a warning when we jump
- out of control too often.
-*/
-
-void local_control(void)
-{
- /*tex Wrr to saving the state local_control is like some of the conv_toks which
- is not entirely correct but good enough for now. Future extensions might
- demand another solution.
- */
- int save_scanner_status = scanner_status;
- halfword save_def_ref = def_ref;
- halfword save_warning_index = warning_index;
- int ll = local_level;
- main_control_state = goto_next;
- local_level += 1;
- if (tracing_nesting_par > 2) {
- local_control_message("entering local control");
- }
- while (1) {
- if (main_control_state == goto_skip_token) {
- main_control_state = goto_next;
- } else {
- get_x_token();
- }
- if (interrupt != 0 && OK_to_interrupt) {
- back_input();
- check_interrupt();
- continue;
- }
- if (tracing_commands_par > 0) {
- show_cur_cmd_chr();
- }
- (jump_table[(abs(mode) + cur_cmd)])();
- if (local_level <= ll) {
- main_control_state = goto_next;
- if (tracing_nesting_par > 2) {
- local_control_message("leaving local control due to level change");
- }
- break;
- } else if (main_control_state == goto_return) {
- if (tracing_nesting_par > 2) {
- local_control_message("leaving local control due to triggering");
- }
- break;
- }
- }
- /*tex From the perspective of ending and changing the level this is the
- wrong spot, as it should be done in |end_local_control| in which case
- we should use the save stack. Maybe some day.
- */
- scanner_status = save_scanner_status;
- def_ref = save_def_ref;
- warning_index = save_warning_index;
-}
-
-void end_local_control(void )
-{
- if (local_level > 0) {
- local_level -= 1;
- } else {
- local_control_message("redundant end local control");
- }
-}
-
-/*tex
- We need to go back to the main loop. This is rather nasty and dirty
- and counterintuive code and there might be a cleaner way. Basically
- we trigger the main control state from here.
-
- \starttyping
- 0 0 \directlua{token.scan_list()}\hbox{!}
- -1 0 \setbox0\hbox{x}\directlua{token.scan_list()}\box0
- 1 1 \toks0={\directlua{token.scan_list()}\hbox{x}}\directlua{tex.runtoks(0)}
- 0 0 1 1 \directlua{tex.box[0]=token.scan_list()}\hbox{x\directlua{node.write(token.scan_list())}\hbox{x}}
- 0 0 0 1 \setbox0\hbox{x}\directlua{tex.box[0]=token.scan_list()}\hbox{x\directlua{node.write(token.scan_list())}\box0}
- \stoptyping
-
- It's rather fragile code so we added some tracing options.
-
-*/
-
-halfword local_scan_box(void)
-{
- int old_mode = mode;
- int ll = local_level;
- mode = -hmode;
- scan_box(lua_scan_flag);
- if (local_level == ll) {
- /*tex |\directlua{print(token.scan_list())}\hbox{!}| (n n) */
- if (tracing_nesting_par > 2) {
- local_control_message("entering at end of box scanning");
- }
- local_control();
- } else {
- /*tex |\directlua{print(token.scan_list())}\box0| (n-1 n) */
- /*
- if (tracing_nesting_par > 2) {
- local_control_message("setting level after box scanning");
- }
- */
- local_level = ll;
- }
- mode = old_mode;
- return cur_box;
-}
-
-/*tex
-
- We have an issue with modes when we quit here because we're coming
- from and still staying at the \LUA\ end. So, unless we're already
- nested, we trigger an end_local_level token (an extension code).
-
-*/
-
-static void wrapup_local_scan_box(void)
-{
- /*
- if (tracing_nesting_par > 2) {
- local_control_message("leaving box scanner");
- }
- */
- local_level -= 1;
-}
-
-int current_local_level(void)
-{
- return local_level;
-}
-
-void app_space(void)
-{ /* handle spaces when |space_factor<>1000| */
- halfword q; /* glue node */
- if ((space_factor_par >= 2000) && (! glue_is_zero(xspace_skip_par))) {
- q = new_param_glue(xspace_skip_code);
- /* so from now we have a subtype with spaces: */
- subtype(q) = xspace_skip_code + 1;
- } else {
- if (!glue_is_zero(space_skip_par)) {
- q = new_glue(space_skip_par);
- } else {
- q = new_glue(zero_glue);
- width(q) = space(cur_font_par);
- stretch(q) = space_stretch(cur_font_par);
- shrink(q) = space_shrink(cur_font_par);
- }
- /* Modify the glue specification in |q| according to the space factor */
- if (space_factor_par >= 2000)
- width(q) = width(q) + extra_space(cur_font_par);
- stretch(q) = xn_over_d(stretch(q), space_factor_par, 1000);
- shrink(q) = xn_over_d(shrink(q), 1000, space_factor_par);
-
- /* so from now we have a subtype with spaces: */
- subtype(q) = space_skip_code + 1;
- }
- couple_nodes(tail, q);
- tail = q;
-}
-
-void insert_dollar_sign(void)
-{
- back_input();
- cur_tok = math_shift_token + '$';
- print_err("Missing $ inserted");
- help2(
- "I've inserted a begin-math/end-math symbol since I think",
- "you left one out. Proceed, with fingers crossed."
- );
- ins_error();
-}
-
-/*tex
-
- We can silently ignore \.{\\par}s in a math formula.
-
-*/
-
-void insert_dollar_sign_par_end(void)
-{
- if (!suppress_mathpar_error_par) {
- insert_dollar_sign() ;
- }
-}
-
-/*tex
-
-The `|you_cant|' procedure prints a line saying that the current command is
-illegal in the current mode; it identifies these things symbolically.
-
-*/
-
-void you_cant(void)
-{
- print_err("You can't use `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- print_in_mode(mode);
-}
-
-/*tex
-
-When erroneous situations arise, \TeX\ usually issues an error message specific
-to the particular error. For example, `\.{\\noalign}' should not appear in any
-mode, since it is recognized by the |align_peek| routine in all of its legitimate
-appearances; a special error message is given when `\.{\\noalign}' occurs
-elsewhere. But sometimes the most appropriate error message is simply that the
-user is not allowed to do what he or she has attempted. For example,
-`\.{\\moveleft}' is allowed only in vertical mode, and `\.{\\lower}' only in
-non-vertical modes. Such cases are enumerated here and in the other sections
-referred to under `See also \dots.'
-
-*/
-
-void report_illegal_case(void)
-{
- you_cant();
- help4(
- "Sorry, but I'm not programmed to handle this case;",
- "I'll just pretend that you didn''t ask for it.",
- "If you're in the wrong mode, you might be able to",
- "return to the right one by typing `I}' or `I$' or `I\\par'."
- );
- error();
-}
-
-/*tex
-
-Some operations are allowed only in privileged modes, i.e., in cases that
-|mode>0|. The |privileged| function is used to detect violations of this rule; it
-issues an error message and returns |false| if the current |mode| is negative.
-
-*/
-
-boolean privileged(void)
-{
- if (mode > 0) {
- return true;
- } else {
- report_illegal_case();
- return false;
- }
-}
-
-/*tex
-
-We don't want to leave |main_control| immediately when a |stop| command is
-sensed, because it may be necessary to invoke an \.{\\output} routine several
-times before things really grind to a halt. (The output routine might even say
-`\.{\\gdef\\end\{...\}}', to prolong the life of the job.) Therefore
-|its_all_over| is |true| only when the current page and contribution list are
-empty, and when the last output was not a ``dead cycle.''
-
-*/
-
-
-boolean its_all_over(void)
-{ /* do this when \.{\\end} or \.{\\dump} occurs */
- if (privileged()) {
- if ((page_head == page_tail) && (head == tail) && (dead_cycles == 0)) {
- return true;
- }
- back_input(); /* we will try to end again after ejecting residual material */
- tail_append(new_null_box());
- width(tail) = hsize_par;
- tail_append(new_glue(fill_glue));
- tail_append(new_penalty(-010000000000,final_penalty));
- normal_page_filter(end);
- build_page(); /* append \.{\\hbox to \\hsize\{\}\\vfill\\penalty-'10000000000} */
- }
- return false;
-}
-
-/*tex
-
-The |hskip| and |vskip| command codes are used for control sequences like
-\.{\\hss} and \.{\\vfil} as well as for \.{\\hskip} and \.{\\vskip}. The
-difference is in the value of |cur_chr|.
-
-All the work relating to glue creation has been relegated to the following
-subroutine. It does not call |build_page|, because it is used in at least one
-place where that would be a mistake.
-
-*/
-
-void append_glue(void)
-{
- int s = cur_chr;
- switch (s) {
- case fil_code:
- cur_val = new_glue(fil_glue);
- break;
- case fill_code:
- cur_val = new_glue(fill_glue);
- break;
- case ss_code:
- cur_val = new_glue(ss_glue);
- break;
- case fil_neg_code:
- cur_val = new_glue(fil_neg_glue);
- break;
- case skip_code:
- scan_glue(glue_val_level);
- break;
- case mskip_code:
- scan_glue(mu_val_level);
- break;
- }
- /* now |cur_val| points to the glue specification */
- tail_append(new_glue(cur_val));
- flush_node(cur_val);
- if (s > skip_code) {
- subtype(tail) = mu_glue;
- }
-}
-
-void append_kern(void)
-{
- int s = cur_chr; /* |subtype| of the kern node */
- scan_dimen((s == mu_glue), false, false);
- tail_append(new_kern(cur_val));
- subtype(tail) = (quarterword) s;
-}
-
-/*tex
-
-We have to deal with errors in which braces and such things are not properly
-nested. Sometimes the user makes an error of commission by inserting an extra
-symbol, but sometimes the user makes an error of omission. \TeX\ can't always
-tell one from the other, so it makes a guess and tries to avoid getting into a
-loop.
-
-The |off_save| routine is called when the current group code is wrong. It tries
-to insert something into the user's input that will help clean off the top level.
-
-*/
-
-void off_save(void)
-{
- halfword p, q;
- if (cur_group == bottom_level) {
- /*tex Drop current token and complain that it was unmatched */
- print_err("Extra ");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- help1(
- "Things are pretty mixed up, but I think the worst is over."
- );
- error();
-
- } else {
- back_input();
- p = get_avail();
- set_token_link(temp_token_head, p);
- print_err("Missing ");
- /*tex
- Prepare to insert a token that matches |cur_group|, and print what it
- is. At this point, |link(temp_token_head)=p|, a pointer to an empty
- one-word node.
- */
- switch (cur_group) {
- case semi_simple_group:
- set_token_info(p, cs_token_flag + frozen_end_group);
- tprint_esc("endgroup");
- break;
- case math_shift_group:
- set_token_info(p, math_shift_token + '$');
- print_char('$');
- break;
- case math_left_group:
- set_token_info(p, cs_token_flag + frozen_right);
- q = get_avail();
- set_token_link(p, q);
- p = token_link(p);
- set_token_info(p, other_token + '.');
- tprint_esc("right.");
- break;
- default:
- set_token_info(p, right_brace_token + '}');
- print_char('}');
- break;
- }
- tprint(" inserted");
- ins_list(token_link(temp_token_head));
- help5(
- "I've inserted something that you may have forgotten.",
- "(See the <inserted text> above.)",
- "With luck, this will get me unwedged. But if you",
- "really didn't forget anything, try typing `2' now; then",
- "my insertion and my current dilemma will both disappear."
- );
- error();
- }
-}
-/*tex
-
-The routine for a |right_brace| character branches into many subcases, since a
-variety of things may happen, depending on |cur_group|. Some types of groups are
-not supposed to be ended by a right brace; error messages are given in hopes of
-pinpointing the problem. Most branches of this routine will be filled in later,
-when we are ready to understand them; meanwhile, we must prepare ourselves to
-deal with such errors.
-
-*/
-
-void handle_right_brace(void)
-{
- halfword p, q; /* for short-term use */
- scaled d; /* holds |split_max_depth| in |insert_group| */
- int f; /* holds |floating_penalty| in |insert_group| */
- p = null;
- switch (cur_group) {
- case simple_group:
- fixup_directions();
- break;
- case bottom_level:
- print_err("Too many }'s");
- help2(
- "You've closed more groups than you opened.",
- "Such booboos are generally harmless, so keep going."
- );
- error();
- break;
- case semi_simple_group:
- case math_shift_group:
- case math_left_group:
- extra_right_brace();
- break;
- /*tex
- When the right brace occurs at the end of an \.{\\hbox} or
- \.{\\vbox} or \.{\\vtop} construction, the |package| routine
- comes into action. We might also have to finish a paragraph that
- hasn't ended.
- */
- case hbox_group:
- if (fixup_boxes_par) {
- /*tex
- This is unofficial! Fixing up (also elsewhere) might become default
- some day but for a while I will test this in ConTeXt.
- */
- fixup_directions_only();
- }
- package(0);
- break;
- case adjusted_hbox_group:
- adjust_tail = adjust_head;
- pre_adjust_tail = pre_adjust_head;
- package(0);
- break;
- case vbox_group:
- end_graf(vbox_group);
- package(0);
- break;
- case vtop_group:
- end_graf(vtop_group);
- package(vtop_code);
- break;
- case insert_group:
- end_graf(insert_group);
- q = new_glue(split_top_skip_par);
- d = split_max_depth_par;
- f = floating_penalty_par;
- unsave();
- save_ptr--;
- /*tex
- Now |saved_value(0)| is the insertion number, or the |vadjust| subtype.
- */
- p = vpack(vlink(head), 0, additional, -1);
- pop_nest();
- if (saved_type(0) == saved_insert) {
- tail_append(new_node(ins_node, saved_value(0)));
- height(tail) = height(p) + depth(p);
- ins_ptr(tail) = list_ptr(p);
- split_top_ptr(tail) = q;
- depth(tail) = d;
- float_cost(tail) = f;
- } else if (saved_type(0) == saved_adjust) {
- tail_append(new_node(adjust_node, saved_value(0)));
- adjust_ptr(tail) = list_ptr(p);
- flush_node(q);
- } else {
- confusion("insert_group");
- }
- list_ptr(p) = null;
- flush_node(p);
- if (nest_ptr == 0) {
- checked_page_filter(insert);
- build_page();
- }
- break;
- case output_group:
- /*tex
- this is needed in case the \.{\\output} executes a \.{\\textdir} command.
- */
- if (dir_level(text_dir_ptr) == cur_level) {
- /*tex Remove from |text_dir_ptr| */
- halfword text_dir_tmp = vlink(text_dir_ptr);
- flush_node(text_dir_ptr);
- text_dir_ptr = text_dir_tmp;
- }
- resume_after_output();
- break;
- case disc_group:
- build_discretionary();
- break;
- case local_box_group:
- build_local_box();
- break;
- case align_group:
- back_input();
- cur_tok = cs_token_flag + frozen_cr;
- print_err("Missing \\cr inserted");
- help1(
- "I'm guessing that you meant to end an alignment here."
- );
- ins_error();
- break;
- case no_align_group:
- end_graf(no_align_group);
- unsave();
- align_peek();
- break;
- case vcenter_group:
- end_graf(vcenter_group);
- finish_vcenter();
- break;
- case math_choice_group:
- build_choices();
- break;
- case math_group:
- close_math_group(p);
- break;
- default:
- confusion("rightbrace");
- break;
- }
-}
-
-void extra_right_brace(void)
-{
- print_err("Extra }, or forgotten ");
- switch (cur_group) {
- case semi_simple_group:
- tprint_esc("endgroup");
- break;
- case math_shift_group:
- print_char('$');
- break;
- case math_left_group:
- tprint_esc("right");
- break;
- }
- help5(
- "I've deleted a group-closing symbol because it seems to be",
- "spurious, as in `$x}$'. But perhaps the } is legitimate and",
- "you forgot something else, as in `\\hbox{$x}'. In such cases",
- "the way to recover is to insert both the forgotten and the",
- "deleted material, e.g., by typing `I$}'."
- );
- error();
- incr(align_state);
-}
-
-/*tex
-
-Here is where we clear the parameters that are supposed to revert to their
-default values after every paragraph and when internal vertical mode is entered.
-
-*/
-
-void normal_paragraph(void)
-{
- if (looseness_par != 0)
- eq_word_define(int_base + looseness_code, 0);
- if (hang_indent_par != 0)
- eq_word_define(dimen_base + hang_indent_code, 0);
- if (hang_after_par != 1)
- eq_word_define(int_base + hang_after_code, 1);
- if (par_shape_par_ptr != null)
- eq_define(par_shape_loc, shape_ref_cmd, null);
- if (inter_line_penalties_par_ptr != null)
- eq_define(inter_line_penalties_loc, shape_ref_cmd, null);
- if (shape_mode_par > 0)
- eq_word_define(dimen_base + shape_mode_code, 0);
-}
-
-/*tex
-
-The global variable |cur_box| will point to a newly-made box. If the box is void,
-we will have |cur_box=null|. Otherwise we will have |type(cur_box)=hlist_node| or
-|vlist_node| or |rule_node|; the |rule_node| case can occur only with leaders.
-
-*/
-
-halfword cur_box; /* box to be placed into its context */
-
-/*tex
-
-The |box_end| procedure does the right thing with |cur_box|, if |box_context|
-represents the context as explained above.
-
-*/
-
-void box_end(int box_context)
-{
- if (box_context < box_flag) {
- /*tex
-
- Append box |cur_box| to the current list, shifted by |box_context|.
- The global variable |adjust_tail| will be non-null if and only if the
- current box might include adjustments that should be appended to the
- current vertical list.
-
- */
-
- if (cur_box != null) {
- shift_amount(cur_box) = box_context;
- if (abs(mode) == vmode) {
- if (pre_adjust_tail != null) {
- if (pre_adjust_head != pre_adjust_tail)
- append_list(pre_adjust_head, pre_adjust_tail);
- pre_adjust_tail = null;
- }
- append_to_vlist(cur_box,lua_key_index(box));
- if (adjust_tail != null) {
- if (adjust_head != adjust_tail)
- append_list(adjust_head, adjust_tail);
- adjust_tail = null;
- }
- if (mode > 0) {
- checked_page_filter(box);
- build_page();
- }
- } else {
- if (abs(mode) == hmode)
- space_factor_par = 1000;
- else
- cur_box = new_sub_box(cur_box);
- couple_nodes(tail, cur_box);
- tail = cur_box;
- }
- }
- } else if (box_context < ship_out_flag) {
- /*tex
- Store |cur_box| in a box register
- */
- if (box_context < global_box_flag)
- eq_define(box_base + box_context - box_flag, box_ref_cmd, cur_box);
- else
- geq_define(box_base + box_context - global_box_flag, box_ref_cmd, cur_box);
- } else if (box_context == lua_scan_flag) {
- /*tex
- We are done with scanning so let's return to the caller.
- */
- wrapup_local_scan_box();
- } else if (cur_box != null) {
- /*tex
- The leaders contexts come after shipout and luascan contexts.
- */
- /* if (box_context > lua_scan_flag) { */
- if (box_context >= leader_flag) {
- /*tex
- Append a new leader node that uses |cur_box| and get the next
- non-blank non-relax...
- */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (((cur_cmd == hskip_cmd) && (abs(mode) != vmode)) ||
- ((cur_cmd == vskip_cmd) && (abs(mode) == vmode))) {
- append_glue();
- subtype(tail) = (quarterword) (box_context - (leader_flag - a_leaders));
- leader_ptr(tail) = cur_box;
- } else {
- print_err("Leaders not followed by proper glue");
- help3(
- "You should say `\\leaders <box or rule><hskip or vskip>'.",
- "I found the <box or rule>, but there's no suitable",
- "<hskip or vskip>, so I'm ignoring these leaders."
- );
- back_error();
- flush_node_list(cur_box);
- }
- } else {
- if (box_context != ship_out_flag) {
- normal_error("scanner","shipout expected");
- }
- ship_out(static_pdf, cur_box, SHIPPING_PAGE);
- }
- }
-}
-
-/*tex
-
-the next input should specify a box or perhaps a rule
-
-*/
-
-void scan_box(int box_context)
-{
- /*tex Get the next non-blank non-relax... */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd == make_box_cmd) {
- begin_box(box_context);
- } else if ((box_context >= leader_flag) &&
- ((cur_cmd == hrule_cmd) || (cur_cmd == vrule_cmd) ||
- (cur_cmd == no_hrule_cmd) || (cur_cmd == no_vrule_cmd))) {
- cur_box = scan_rule_spec();
- box_end(box_context);
- } else {
- print_err("A <box> was supposed to be here");
- help3(
- "I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
- "something like that. So you might find something missing in",
- "your output. But keep trying; you can fix this later."
- );
- back_error();
- if (box_context == lua_scan_flag) {
- cur_box = null;
- box_end(box_context);
- }
- }
-}
-
-void new_graf(boolean indented)
-{
- halfword p, q, dir_graf_tmp;
- halfword dir_rover;
- int callback_id;
- if ((mode == vmode) || (head != tail)) {
- tail_append(new_param_glue(par_skip_code));
- }
- callback_id = callback_defined(new_graf_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "db->b", cur_list.mode_field,indented,&indented);
- }
- prev_graf_par = 0;
- push_nest();
- mode = hmode;
- space_factor_par = 1000;
- /*tex Add local paragraph node */
- tail_append(make_local_par_node(new_graf_par_code));
- if (indented) {
- p = new_null_box();
- box_dir(p) = par_direction_par;
- width(p) = par_indent_par;
- subtype(p) = indent_list;
- q = tail;
- tail_append(p);
- } else {
- q = tail;
- }
- dir_rover = text_dir_ptr;
- while (dir_rover != null) {
- if ((vlink(dir_rover) != null) || (dir_dir(dir_rover) != par_direction_par)) {
- dir_graf_tmp = new_dir(dir_dir(dir_rover));
- try_couple_nodes(dir_graf_tmp,vlink(q));
- couple_nodes(q,dir_graf_tmp);
- }
- dir_rover = vlink(dir_rover);
- }
- q = head;
- while (vlink(q) != null)
- q = vlink(q);
- tail = q;
- if (every_par_par != null)
- begin_token_list(every_par_par, every_par_text);
- if (nest_ptr == 1) {
- checked_page_filter(new_graf);
- /*tex put |par_skip| glue on current page */
- build_page();
- }
-}
-
-void indent_in_hmode(void)
-{
- halfword p;
- if (cur_chr > 0) {
- /*tex \.{\\indent} */
- p = new_null_box();
- width(p) = par_indent_par;
- if (abs(mode) == hmode)
- space_factor_par = 1000;
- else
- p = new_sub_box(p);
- tail_append(p);
- }
-}
-
-void head_for_vmode(void)
-{
- if (mode < 0) {
- if ((cur_cmd != hrule_cmd) && (cur_cmd != no_hrule_cmd)) {
- off_save();
- } else {
- print_err("You can't use `\\hrule' here except with leaders");
- help2(
- "To put a horizontal rule in an hbox or an alignment,",
- "you should use \\leaders or \\hrulefill (see The TeXbook)."
- );
- error();
- }
- } else {
- back_input();
- cur_tok = par_token;
- back_input();
- token_type = inserted;
- }
-}
-
-/*tex
-
-|dir_save| would have been set by |line_break| by means of |post_line_break|, but
-this is not done right now, as it introduces pretty heavy memory leaks. This
-means the current code might be wrong in some way that relates to in-paragraph
-displays.
-
-*/
-
-void end_graf(int line_break_context)
-{
- if (mode == hmode) {
- if ((head == tail) || (vlink(head) == tail)) {
- if (vlink(head) == tail)
- flush_node(vlink(head));
- /*tex |null| paragraphs are ignored, all contain a |local_paragraph| node */
- pop_nest();
- } else {
- line_break(false, line_break_context);
- }
- if (dir_save != null) {
- flush_node_list(dir_save);
- dir_save = null;
- }
- normal_paragraph();
- error_count = 0;
- }
-}
-
-void begin_insert_or_adjust(void)
-{
- if (cur_cmd != vadjust_cmd) {
- scan_register_num();
- if (cur_val == output_box_par) {
- print_err("You can't \\insert");
- print_int(output_box_par);
- help1(
- "I'm changing to \\insert0; box \\outputbox is special."
- );
- error();
- cur_val = 0;
- }
- set_saved_record(0, saved_insert, 0, cur_val);
- } else if (scan_keyword("pre")) {
- set_saved_record(0, saved_adjust, 0, 1);
- } else {
- set_saved_record(0, saved_adjust, 0, 0);
- }
- save_ptr++;
- new_save_level(insert_group);
- scan_left_brace();
- normal_paragraph();
- push_nest();
- mode = -vmode;
- prev_depth_par = ignore_depth;
-}
-
-/*tex
-
-I (TH)'ve renamed the |make_mark| procedure to this, because if the current chr
-code is 1, then the actual command was \.{\\clearmarks}, which does not generate
-a mark node but instead destroys the current mark tokenlists.
-
-*/
-
-void handle_mark(void)
-{
- halfword p; /* new node */
- halfword c; /* the mark class */
- if (cur_chr == clear_marks_code) {
- scan_mark_num();
- c = cur_val;
- delete_top_mark(c);
- delete_bot_mark(c);
- delete_first_mark(c);
- delete_split_first_mark(c);
- delete_split_bot_mark(c);
- } else {
- if (cur_chr == 0) {
- c = 0;
- } else {
- scan_mark_num();
- c = cur_val;
- if (c > biggest_used_mark)
- biggest_used_mark = c;
- }
- p = scan_toks(false, true);
- p = new_node(mark_node, 0); /* the |subtype| is not used */
- mark_class(p) = c;
- mark_ptr(p) = def_ref;
- couple_nodes(tail, p);
- tail = p;
- }
-}
-
-void append_penalty(void)
-{
- scan_int();
- tail_append(new_penalty(cur_val,user_penalty));
- if (mode == vmode) {
- checked_page_filter(penalty);
- build_page();
- }
-}
-
-/*tex
-
-When |delete_last| is called, |cur_chr| is the |type| of node that will be
-deleted, if present.
-
-The |remove_item| command removes a penalty, kern, or glue node if it appears at
-the tail of the current list, using a brute-force linear scan. Like
-\.{\\lastbox}, this command is not allowed in vertical mode (except internal
-vertical mode), since the current list in vertical mode is sent to the page
-builder. But if we happen to be able to implement it in vertical mode, we do.
-
-*/
-
-void delete_last(void)
-{
- halfword p, q; /* run through the current list */
- if ((mode == vmode) && (tail == head)) {
- /*tex
- Apologize for inability to do the operation now, unless \.{\\unskip}
- follows non-glue
- */
- if ((cur_chr != glue_node) || (last_glue != max_halfword)) {
- you_cant();
- if (cur_chr == kern_node) {
- help2(
- "Sorry...I usually can't take things from the current page.",
- "Try `I\\kern-\\lastkern' instead."
- );
- } else if (cur_chr != glue_node) {
- help2
- ("Sorry...I usually can't take things from the current page.",
- "Perhaps you can make the output routine do it.");
- } else {
- help2
- ("Sorry...I usually can't take things from the current page.",
- "Try `I\\vskip-\\lastskip' instead.");
- }
- error();
- }
- } else {
- /*tex Todo: clean this up! */
- if (!is_char_node(tail)) {
- if (type(tail) == cur_chr) {
- q = head;
- do {
- p = q;
- if (!is_char_node(q)) {
- if (type(q) == disc_node) {
- if (p == tail)
- return;
- }
- }
- q = vlink(p);
- } while (q != tail);
- vlink(p) = null;
- flush_node_list(tail);
- tail = p;
- }
- }
- }
-}
-
-void unpackage(void)
-{
- halfword p; /* the box */
- halfword r; /* to remove marginal kern nodes */
- int c; /* should we copy? */
- halfword s; /* for varmem assignment */
- if (cur_chr > copy_code) {
- /*tex Handle saved items and |goto done| */
- try_couple_nodes(tail, disc_ptr[cur_chr]);
- disc_ptr[cur_chr] = null;
- goto DONE;
- }
- c = cur_chr;
- scan_register_num();
- p = box(cur_val);
- if (p == null)
- return;
- if ((abs(mode) == mmode)
- || ((abs(mode) == vmode) && (type(p) != vlist_node))
- || ((abs(mode) == hmode) && (type(p) != hlist_node))) {
- print_err("Incompatible list can't be unboxed");
- help3(
- "Sorry, Pandora. (You sneaky devil.)",
- "I refuse to unbox an \\hbox in vertical mode or vice versa.",
- "And I can't open any boxes in math mode."
- );
- error();
- return;
- }
- if (c == copy_code) {
- s = copy_node_list(list_ptr(p));
- try_couple_nodes(tail,s);
- } else {
- try_couple_nodes(tail,list_ptr(p));
- box(cur_val) = null;
- list_ptr(p) = null;
- flush_node(p);
- }
- DONE:
- while (vlink(tail) != null) {
- r = vlink(tail);
- if (!is_char_node(r) && (type(r) == margin_kern_node)) {
- try_couple_nodes(tail,vlink(r));
- flush_node(r);
- }
- tail = vlink(tail);
- }
-}
-
-/*tex
-
-Italic corrections are converted to kern nodes when the |ital_corr| command
-follows a character. In math mode the same effect is achieved by appending a kern
-of zero here, since italic corrections are supplied later.
-
-*/
-
-void append_italic_correction(void)
-{
- halfword p; /* |char_node| at the tail of the current list */
- internal_font_number f; /* the font in the |char_node| */
- if (tail != head) {
- if (is_char_node(tail))
- p = tail;
- else
- return;
- f = font(p);
- tail_append(new_kern(char_italic(f, character(p))));
- subtype(tail) = italic_kern;
- }
-}
-
-void append_local_box(int kind)
-{
- incr(save_ptr);
- set_saved_record(-1, saved_boxtype, 0, kind);
- new_save_level(local_box_group);
- scan_left_brace();
- push_nest();
- mode = -hmode;
- space_factor_par = 1000;
-}
-
-/*tex
-
-Discretionary nodes are easy in the common case `\.{\\-}', but in the general
-case we must process three braces full of items.
-
-The space factor does not change when we append a discretionary node, but it
-starts out as 1000 in the subsidiary lists.
-
-*/
-
-void append_discretionary(void)
-{
- int c;
- tail_append(new_disc());
- subtype(tail) = (quarterword) cur_chr;
- if (cur_chr == explicit_disc) {
- /* |\-| */
- c = get_pre_hyphen_char(cur_lang_par);
- if (c > 0) {
- vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c);
- alink(vlink(pre_break(tail))) = pre_break(tail);
- tlink(pre_break(tail)) = vlink(pre_break(tail));
- }
- c = get_post_hyphen_char(cur_lang_par);
- if (c > 0) {
- vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c);
- alink(vlink(post_break(tail))) = post_break(tail);
- tlink(post_break(tail)) = vlink(post_break(tail));
- }
- set_explicit_disc_penalty(tail);
- } else if (cur_chr == automatic_disc) {
- /*tex As done in hyphenator: */
- c = get_pre_exhyphen_char(cur_lang_par);
- if (c <= 0) {
- c = ex_hyphen_char_par;
- }
- if (c > 0) {
- vlink(pre_break(tail)) = new_char(equiv(cur_font_loc), c);
- alink(vlink(pre_break(tail))) = pre_break(tail);
- tlink(pre_break(tail)) = vlink(pre_break(tail));
- }
- c = get_post_exhyphen_char(cur_lang_par);
- if (c > 0) {
- vlink(post_break(tail)) = new_char(equiv(cur_font_loc), c);
- alink(vlink(post_break(tail))) = post_break(tail);
- tlink(post_break(tail)) = vlink(post_break(tail));
- }
- c = ex_hyphen_char_par;
- if (c > 0) {
- vlink(no_break(tail)) = new_char(equiv(cur_font_loc), c);
- alink(vlink(no_break(tail))) = no_break(tail);
- tlink(no_break(tail)) = vlink(no_break(tail));
- }
- set_automatic_disc_penalty(tail);
- } else {
- /*tex |\discretionary| */
- if (scan_keyword("penalty")) {
- scan_int();
- disc_penalty(tail) = cur_val;
- }
- incr(save_ptr);
- set_saved_record(-1, saved_disc, 0, 0);
- new_save_level(disc_group);
- scan_left_brace();
- push_nest();
- mode = -hmode;
- space_factor_par = 1000;
- /*tex Already preset: |disc_penalty(tail) = hyphen_penalty_par;| */
- }
-}
-
-/*tex
-
-The test for |p != null| ensures that empty \.{\\localleftbox} and
-\.{\\localrightbox} commands are not applied.
-
-*/
-
-void build_local_box(void)
-{
- halfword p;
- int kind;
- unsave();
- assert(saved_type(-1) == saved_boxtype);
- kind = saved_value(-1);
- decr(save_ptr);
- p = vlink(head);
- pop_nest();
- if (p != null) {
- /*tex
- Somehow |filtered_hpack| goes beyond the first node so we loose it.
- */
- /*tex
- There is no need for |new_hyphenation(p, null);| here as we're in
- an |\hbox|.
- */
- (void) new_ligkern(p, null);
- p = lua_hpack_filter(p, 0, additional, local_box_group, -1, null);
- /*tex
- We really need something packed so we play safe! This feature is inherited
- but could have been delegated to a callback anyway.
- */
- p = hpack(p, 0, additional, -1);
- }
- if (kind == 0)
- eq_define(local_left_box_base, box_ref_cmd, p);
- else
- eq_define(local_right_box_base, box_ref_cmd, p);
- if (abs(mode) == hmode) {
- /*tex Add local paragraph node */
- tail_append(make_local_par_node(local_box_par_code));
- }
- eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits_par + 1);
-}
-
-/*tex
-
-The three discretionary lists are constructed somewhat as if they were hboxes.
-A~subroutine called |build_discretionary| handles the transitions. (This is sort
-of fun.)
-
-*/
-
-void build_discretionary(void)
-{
- halfword p, q; /* for link manipulation */
- int n; /* length of discretionary list */
- unsave();
- /*tex
- Prune the current list, if necessary, until it contains only |char_node|,
- |kern_node|, |hlist_node|, |vlist_node| and |rule_node| items; set |n| to
- the length of the list, and set |q| to the lists tail. During this loop,
- |p=vlink(q)| and there are |n| items preceding |p|.
- */
- q = head;
- p = vlink(q);
- n = 0;
- while (p != null) {
- if (!is_char_node(p) && type(p) > rule_node && type(p) != kern_node) {
- print_err("Improper discretionary list");
- help1(
- "Discretionary lists must contain only boxes and kerns."
- );
- error();
- begin_diagnostic();
- tprint_nl("The following discretionary sublist has been deleted:");
- show_box(p);
- end_diagnostic(true);
- flush_node_list(p);
- vlink(q) = null;
- break;
- }
- alink(p) = q;
- q = p;
- p = vlink(q);
- incr(n);
- }
-
- p = vlink(head);
- pop_nest();
- assert(saved_type(-1) == saved_disc);
- switch (saved_value(-1)) {
- case 0:
- if (n > 0) {
- vlink(pre_break(tail)) = p;
- alink(p) = pre_break(tail);
- tlink(pre_break(tail)) = q;
- }
- break;
- case 1:
- if (n > 0) {
- vlink(post_break(tail)) = p;
- alink(p) = post_break(tail);
- tlink(post_break(tail)) = q;
- }
- break;
- case 2:
- /*tex
- Attach list |p| to the current list, and record its length; then
- finish up and |return|
- */
- if ((n > 0) && (abs(mode) == mmode)) {
- print_err("Illegal math \\discretionary");
- help2(
- "Sorry: The third part of a discretionary break must be",
- "empty, in math formulas. I had to delete your third part."
- );
- flush_node_list(p);
- error();
- } else {
- if (n > 0) {
- vlink(no_break(tail)) = p;
- alink(p) = no_break(tail);
- tlink(no_break(tail)) = q;
- }
- }
- decr(save_ptr);
- /*tex There are no other cases. */
- return;
- break;
- }
- set_saved_record(-1, saved_disc, 0, (saved_value(-1) + 1));
- new_save_level(disc_group);
- scan_left_brace();
- push_nest();
- mode = -hmode;
- space_factor_par = 1000;
-}
-
-/*tex
-
-The positioning of accents is straightforward but tedious. Given an accent of
-width |a|, designed for characters of height |x| and slant |s|; and given a
-character of width |w|, height |h|, and slant |t|: We will shift the accent down
-by |x-h|, and we will insert kern nodes that have the effect of centering the
-accent over the character and shifting the accent to the right by
-$\delta={1\over2}(w-a)+h\cdot t-x\cdot s$. If either character is absent from the
-font, we will simply use the other, without shifting.
-
-*/
-
-void make_accent(void)
-{
- double s, t; /* amount of slant */
- halfword p, q, r; /* character, box, and kern nodes */
- internal_font_number f; /* relevant font */
- scaled a, h, x, w, delta; /* heights and widths, as explained above */
- scan_char_num();
- f = equiv(cur_font_loc);
- p = new_glyph(f, cur_val);
- if (p != null) {
- x = x_height(f);
- /*tex real division */
- s = float_cast(slant(f)) / float_constant(65536);
- a = glyph_width(p);
- do_assignments();
- /*tex
- Create a character node |q| for the next character, but set |q:=null|
- if problems arise
- */
- q = null;
- f = equiv(cur_font_loc);
- if ((cur_cmd == letter_cmd) ||
- (cur_cmd == other_char_cmd) || (cur_cmd == char_given_cmd)) {
- q = new_glyph(f, cur_chr);
- } else if (cur_cmd == char_num_cmd) {
- scan_char_num();
- q = new_glyph(f, cur_val);
- } else {
- back_input();
- }
-
- if (q != null) {
- /*tex
- Append the accent with appropriate kerns, then set |p:=q|. The
- kern nodes appended here must be distinguished from other kerns,
- lest they be wiped away by the hyphenation algorithm or by a
- previous line break. The two kerns are computed with
- (machine-dependent) |real| arithmetic, but their sum is
- machine-independent; the net effect is machine-independent,
- because the user cannot remove these nodes nor access them via
- \.{\\lastkern}.
- */
- t = float_cast(slant(f)) / float_constant(65536); /* real division */
- w = glyph_width(q);
- h = glyph_height(q);
- if (h != x) {
- /*tex the accent must be shifted up or down */
- p = hpack(p, 0, additional, -1);
- shift_amount(p) = x - h;
- }
- /*tex real multiplication */
- delta = round(float_cast(w - a) / float_constant(2) + h * t - x * s);
- r = new_kern(delta);
- subtype(r) = accent_kern;
- couple_nodes(tail, r);
- couple_nodes(r, p);
- tail = new_kern(-a - delta);
- subtype(tail) = accent_kern;
- couple_nodes(p, tail);
- p = q;
-
- }
- couple_nodes(tail, p);
- tail = p;
- space_factor_par = 1000;
- }
-}
-
-/*tex
-
-When `\.{\\cr}' or `\.{\\span}' or a tab mark comes through the scanner into
-|main_control|, it might be that the user has foolishly inserted one of them into
-something that has nothing to do with alignment. But it is far more likely that a
-left brace or right brace has been omitted, since |get_next| takes actions
-appropriate to alignment only when `\.{\\cr}' or `\.{\\span}' or tab marks occur
-with |align_state=0|. The following program attempts to make an appropriate
-recovery.
-
-*/
-
-void align_error(void)
-{
- if (abs(align_state) > 2) {
- /*tex
- Express consternation over the fact that no alignment is in progress.
- */
- print_err("Misplaced ");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- if (cur_tok == tab_token + '&') {
- help6(
- "I can't figure out why you would want to use a tab mark",
- "here. If you just want an ampersand, the remedy is",
- "simple: Just type `I\\&' now. But if some right brace",
- "up above has ended a previous alignment prematurely,",
- "you're probably due for more error messages, and you",
- "might try typing `S' now just to see what is salvageable."
- );
- } else {
- help5(
- "I can't figure out why you would want to use a tab mark",
- "or \\cr or \\span just now. If something like a right brace",
- "up above has ended a previous alignment prematurely,",
- "you're probably due for more error messages, and you",
- "might try typing `S' now just to see what is salvageable."
- );
- }
- error();
-
- } else {
- back_input();
- if (align_state < 0) {
- print_err("Missing { inserted");
- incr(align_state);
- cur_tok = left_brace_token + '{';
- } else {
- print_err("Missing } inserted");
- decr(align_state);
- cur_tok = right_brace_token + '}';
- }
- help3(
- "I've put in what seems to be necessary to fix",
- "the current column of the current alignment.",
- "Try to go on, since this might almost work."
- );
- ins_error();
- }
-}
-
-/*tex
-
-The help messages here contain a little white lie, since \.{\\noalign} and
-\.{\\omit} are allowed also after `\.{\\noalign\{...\}}'.
-
-*/
-
-void no_align_error(void)
-{
- print_err("Misplaced \\noalign");
- help2(
- "I expect to see \\noalign only after the \\cr of",
- "an alignment. Proceed, and I'll ignore this case."
- );
- error();
-}
-
-void omit_error(void)
-{
- print_err("Misplaced \\omit");
- help2(
- "I expect to see \\omit only after tab marks or the \\cr of",
- "an alignment. Proceed, and I'll ignore this case."
- );
- error();
-}
-
-/*tex
-
-We've now covered most of the abuses of \.{\\halign} and \.{\\valign}. Let's take
-a look at what happens when they are used correctly.
-
-An |align_group| code is supposed to remain on the |save_stack| during an entire
-alignment, until |fin_align| removes it.
-
-A devious user might force an |endv| command to occur just about anywhere; we
-must defeat such hacks.
-
-*/
-
-void do_endv(void)
-{
- base_ptr = input_ptr;
- input_stack[base_ptr] = cur_input;
- while ((input_stack[base_ptr].index_field != v_template) &&
- (input_stack[base_ptr].loc_field == null) &&
- (input_stack[base_ptr].state_field == token_list))
- decr(base_ptr);
- if ((input_stack[base_ptr].index_field != v_template) ||
- (input_stack[base_ptr].loc_field != null) ||
- (input_stack[base_ptr].state_field != token_list))
- fatal_error("(interwoven alignment preambles are not allowed)");
- /*tex interwoven alignment preambles... */
- if (cur_group == align_group) {
- end_graf(align_group);
- if (fin_col())
- fin_row();
- } else {
- off_save();
- }
-}
-
-/*tex
-
-Finally, \.{\\endcsname} is not supposed to get through to |main_control|.
-
-*/
-
-void cs_error(void)
-{
- print_err("Extra \\endcsname");
- help1(
- "I'm ignoring this, since I wasn't doing a \\csname."
- );
- error();
-}
-
-/*tex
-
-Assignments to values in |eqtb| can be global or local. Furthermore, a control
-sequence can be defined to be `\.{\\long}', `\.{\\protected}', or `\.{\\outer}',
-and it might or might not be expanded. The prefixes `\.{\\global}', `\.{\\long}',
-`\.{\\protected}', and `\.{\\outer}' can occur in any order. Therefore we assign
-binary numeric codes, making it possible to accumulate the union of all specified
-prefixes by adding the corresponding codes. (PASCAL's |set| operations could also
-have been used.)
-
-Every prefix, and every command code that might or might not be prefixed, calls
-the action procedure |prefixed_command|. This routine accumulates a sequence of
-prefixes until coming to a non-prefix, then it carries out the command.
-
-*/
-
-/*tex
-
-If the user says, e.g., `\.{\\global\\global}', the redundancy is silently
-accepted. The different types of code values have different legal ranges; the
-following program is careful to check each case properly.
-
-*/
-
-#define check_def_code(A) do { \
- if (((cur_val<0)&&(p<(A)))||(cur_val>n)) { \
- print_err("Invalid code ("); \
- print_int(cur_val); \
- if (p<(A)) \
- tprint("), should be in the range 0.."); \
- else \
- tprint("), should be at most "); \
- print_int(n); \
- help1( \
- "I'm going to use 0 instead of that illegal code value." \
- ); \
- error(); \
- cur_val=0; \
- } \
-} while (0)
-
-/*
-halfword swap_hang_indent(halfword indentation, halfword shape_mode) {
- if (shape_mode == 1 || shape_mode == 3 || shape_mode == -1 || shape_mode == -3) {
- return negate(indentation);
- } else {
- return indentation;
- }
-}
-
-halfword swap_parshape_indent(halfword indentation, halfword width, halfword shape_mode) {
- if (shape_mode == 2 || shape_mode == 3 || shape_mode == -2 || shape_mode == -3) {
- return hsize_par - width - indentation;
- } else {
- return indentation;
- }
-}
-
-*/
-
-void prefixed_command(void)
-{
- int a; /* accumulated prefix codes so far */
- internal_font_number f; /* identifies a font */
- halfword j; /* index into a \.{\\parshape} specification */
- halfword p, q; /* for temporary short-term use */
- int n; /* ditto */
- boolean e, check_glue; /* should a definition be expanded? or was \.{\\let} not done? */
- mathcodeval mval; /* for handling of \.{\\mathchardef}s */
- a = 0;
- while (cur_cmd == prefix_cmd) {
- if (!odd(a / cur_chr))
- a = a + cur_chr;
- /*tex
- Get the next non-blank non-relax...
- */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- if (cur_cmd <= max_non_prefixed_command) {
- /*tex
- Discard erroneous prefixes and |return|
- */
- print_err("You can't use a prefix with `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- print_char('\'');
- help2(
- "I'll pretend you didn't say \\long or \\outer or \\global or",
- "\\protected."
- );
- back_error();
- return;
- }
- if (tracing_commands_par > 2)
- show_cur_cmd_chr();
- }
- /*tex
- Discard the prefixes \.{\\long} and \.{\\outer} if they are irrelevant
- */
- if (a >= 8) {
- j = protected_token;
- a = a - 8;
- } else {
- j = 0;
- }
- if ((cur_cmd != def_cmd) && (cur_cmd != def_lua_call_cmd) && ((a % 4 != 0) || (j != 0))) {
- print_err("You can't use `\\long' or `\\outer' or `\\protected' with `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- print_char('\'');
- help1(
- "I'll pretend you didn't say \\long or \\outer or \\protected here."
- );
- error();
- }
- /*tex
- Adjust for the setting of \.{\\globaldefs}
- */
- if (global_defs_par != 0) {
- if (global_defs_par < 0) {
- if (is_global(a))
- a = a - 4;
- } else {
- if (!is_global(a))
- a = a + 4;
- }
- }
- switch (cur_cmd) {
- case set_font_cmd:
- /*tex
- Here's an example of the way many of the following routines operate.
- (Unfortunately, they aren't all as simple as this.)
- */
- define(cur_font_loc, data_cmd, cur_chr);
- break;
- case def_cmd:
- /*tex
- When a |def| command has been scanned, |cur_chr| is odd if the
- definition is supposed to be global, and |cur_chr>=2| if the
- definition is supposed to be expanded.
- */
- if (odd(cur_chr) && !is_global(a) && (global_defs_par >= 0))
- a = a + 4;
- e = (cur_chr >= 2);
- get_r_token();
- p = cur_cs;
- q = scan_toks(true, e);
- if (j != 0) {
- q = get_avail();
- set_token_info(q, j);
- set_token_link(q, token_link(def_ref));
- set_token_link(def_ref, q);
- }
- define(p, call_cmd + (a % 4), def_ref);
- break;
- case let_cmd:
- n = cur_chr;
- switch (n) {
- case 0:
- /*tex |glet| */
- if (!is_global(a) && (global_defs_par >= 0)) {
- a = a + 4;
- }
- case 1:
- /*tex |let| */
- get_r_token();
- p = cur_cs;
- do {
- get_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok == other_token + '=') {
- get_token();
- if (cur_cmd == spacer_cmd)
- get_token();
- }
- break;
- case 2:
- /*tex |futurelet| */
- get_r_token();
- p = cur_cs;
- get_token();
- q = cur_tok;
- get_token();
- back_input();
- cur_tok = q;
- /*tex
- We look ahead and then back up. Note that |back_input| doesn't
- affect |cur_cmd|, |cur_chr|
- */
- back_input();
- break;
- case 3:
- /*tex |letcharcode| */
- scan_int();
- if (cur_val > 0) {
- /*tex HH: I need to do a more extensive test later. */
- p = active_to_cs(cur_val, true);
- do {
- get_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok == other_token + '=') {
- get_token();
- if (cur_cmd == spacer_cmd)
- get_token();
- }
- } else {
- p = null;
- tex_error("invalid number for \\letcharcode",NULL);
- }
- break;
- default:
- /*tex We please the compiler. */
- p = null;
- confusion("let");
- break;
- }
- if (cur_cmd >= call_cmd)
- add_token_ref(cur_chr);
- define(p, cur_cmd, cur_chr);
- break;
- case shorthand_def_cmd:
- /*tex
- We temporarily define |p| to be |relax|, so that an occurrence of
- |p| while scanning the definition will simply stop the scanning
- instead of producing an ``undefined control sequence'' error or
- expanding the previous meaning. This allows, for instance,
- `\.{\\chardef\\foo=123\\foo}'.
- */
- n = cur_chr;
- get_r_token();
- p = cur_cs;
- define(p, relax_cmd, too_big_char);
- scan_optional_equals();
- switch (n) {
- case char_def_code:
- scan_char_num();
- define(p, char_given_cmd, cur_val);
- break;
- case math_char_def_code:
- mval = scan_mathchar(tex_mathcode);
- /* if (math_umathcode_meaning_par == 1) { */
- /* cur_val = (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + mval.character_value; */
- /* define(p, xmath_given_cmd, cur_val); */
- /* } else { */
- cur_val = (mval.class_value * 16 + mval.family_value) * 256 + mval.character_value;
- define(p, math_given_cmd, cur_val);
- /* } */
- break;
- case xmath_char_def_code:
- mval = scan_mathchar(umath_mathcode);
- cur_val = (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + mval.character_value;
- define(p, xmath_given_cmd, cur_val);
- break;
- case umath_char_def_code:
- mval = scan_mathchar(umathnum_mathcode);
- cur_val = (mval.class_value + (8 * mval.family_value)) * (65536 * 32) + mval.character_value;
- define(p, xmath_given_cmd, cur_val);
- break;
- default:
- scan_register_num();
- switch (n) {
- case count_def_code:
- define(p, assign_int_cmd, count_base + cur_val);
- break;
- case attribute_def_code:
- define(p, assign_attr_cmd, attribute_base + cur_val);
- break;
- case dimen_def_code:
- define(p, assign_dimen_cmd, scaled_base + cur_val);
- break;
- case skip_def_code:
- define(p, assign_glue_cmd, skip_base + cur_val);
- break;
- case mu_skip_def_code:
- define(p, assign_mu_glue_cmd, mu_skip_base + cur_val);
- break;
- case toks_def_code:
- define(p, assign_toks_cmd, toks_base + cur_val);
- break;
- default:
- confusion("shorthand_def");
- break;
- }
- break;
- }
- break;
- case read_to_cs_cmd:
- j = cur_chr;
- scan_int();
- n = cur_val;
- if (!scan_keyword("to")) {
- print_err("Missing `to' inserted");
- help2(
- "You should have said `\\read<number> to \\cs'.",
- "I'm going to look for the \\cs now."
- );
- error();
- }
- get_r_token();
- p = cur_cs;
- read_toks(n, p, j);
- define(p, call_cmd, cur_val);
- break;
- case toks_register_cmd:
- case assign_toks_cmd:
- /*tex
- The token-list parameters, \.{\\output} and \.{\\everypar}, etc.,
- receive their values in the following way. (For safety's sake, we
- place an enclosing pair of braces around an \.{\\output} list.)
- */
- q = cur_cs;
- if (cur_cmd == toks_register_cmd) {
- scan_register_num();
- p = toks_base + cur_val;
- } else {
- /*tex |p=every_par_loc| or |output_routine_loc| or \dots */
- p = cur_chr;
- }
- scan_optional_equals();
- /*tex Get the next non-blank non-relax non-call token */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- if (cur_cmd != left_brace_cmd) {
- /*tex
- If the right-hand side is a token parameter or token
- register, finish the assignment and |goto done|
- */
- if (cur_cmd == toks_register_cmd) {
- scan_register_num();
- cur_cmd = assign_toks_cmd;
- cur_chr = toks_base + cur_val;
- }
- if (cur_cmd == assign_toks_cmd) {
- q = equiv(cur_chr);
- if (q == null) {
- define(p, undefined_cs_cmd, null);
- } else {
- add_token_ref(q);
- define(p, call_cmd, q);
- }
- goto DONE;
- }
- }
- back_input();
- cur_cs = q;
- q = scan_toks(false, false);
- if (token_link(def_ref) == null) { /* empty list: revert to the default */
- define(p, undefined_cs_cmd, null);
- free_avail(def_ref);
- } else {
- if (p == output_routine_loc) { /* enclose in curlies */
- p = get_avail();
- set_token_link(q, p);
- p = output_routine_loc;
- q = token_link(q);
- set_token_info(q, right_brace_token + '}');
- q = get_avail();
- set_token_info(q, left_brace_token + '{');
- set_token_link(q, token_link(def_ref));
- set_token_link(def_ref, q);
- }
- define(p, call_cmd, def_ref);
- }
- break;
- case assign_int_cmd:
- /*tex Similar routines are used to assign values to the numeric parameters. */
- p = cur_chr;
- scan_optional_equals();
- scan_int();
- assign_internal_value(a, p, cur_val);
- break;
- case assign_attr_cmd:
- p = cur_chr;
- scan_optional_equals();
- scan_int();
- if ((p - attribute_base) > max_used_attr)
- max_used_attr = (p - attribute_base);
- attr_list_cache = cache_disabled;
- word_define(p, cur_val);
- break;
- case assign_direction_cmd:
- case assign_dir_cmd:
- /*tex Assign direction codes. */
- if (cur_cmd == assign_direction_cmd) {
- p = cur_chr;
- scan_optional_equals();
- scan_int();
- check_dir_value(cur_val);
- cur_chr = p;
- } else {
- scan_direction();
- }
- switch (cur_chr) {
- case int_base + page_direction_code:
- eq_word_define(int_base + page_direction_code, cur_val);
- break;
- case int_base + body_direction_code:
- eq_word_define(int_base + body_direction_code, cur_val);
- break;
- case int_base + par_direction_code:
- eq_word_define(int_base + par_direction_code, cur_val);
- break;
- case int_base + math_direction_code:
- eq_word_define(int_base + math_direction_code, cur_val);
- break;
- case int_base + text_direction_code:
- case int_base + line_direction_code:
- /*
- pre version 0.97 this was a commented section because various tests hint that this
- is unnecessary and sometimes even produces weird results, like:
-
- (\hbox{\textdir TRT ABC\textdir TLT DEF}))
-
- becomes
-
- (DEFCBA)
-
- in the output when we use
-
- tail_append(new_dir(text_direction_par)
-
- but when we append the reverse of the current it goes better
-
- */
- check_glue = (cur_chr == (int_base + line_direction_code));
- if (check_glue) {
- cur_chr = int_base + text_direction_code ;
- }
- if (abs(mode) == hmode) {
- if (no_local_dirs_par > 0) {
- /*tex |tail| is non zero but we test anyway. */
- if (check_glue && (tail != null && type(tail) == glue_node)) {
- halfword prev = alink(tail);
- halfword dirn = new_dir(text_direction_par);
- subtype(dirn) = cancel_dir;
- couple_nodes(prev,dirn);
- couple_nodes(dirn,tail);
- } else {
- tail_append(new_dir(text_direction_par));
- subtype(tail) = cancel_dir;
- }
- } else {
- /*tex What is the use of nolocaldirs? Maybe we should get rid of it. */
- }
- update_text_dir_ptr(cur_val);
- tail_append(new_dir(cur_val));
- dir_level(tail) = cur_level;
- } else {
- update_text_dir_ptr(cur_val);
- }
- eq_word_define(int_base + text_direction_code, cur_val);
- eq_word_define(int_base + no_local_dirs_code, no_local_dirs_par + 1);
- break;
- }
- break;
- case assign_dimen_cmd:
- p = cur_chr;
- scan_optional_equals();
- scan_normal_dimen();
- assign_internal_value(a, p, cur_val);
- break;
- case assign_glue_cmd:
- case assign_mu_glue_cmd:
- p = cur_chr;
- n = cur_cmd;
- scan_optional_equals();
- if (n == assign_mu_glue_cmd)
- scan_glue(mu_val_level);
- else
- scan_glue(glue_val_level);
- define(p, glue_ref_cmd, cur_val);
- break;
- case def_char_code_cmd:
- case def_del_code_cmd:
- /*tex Let |n| be the largest legal code value, based on |cur_chr| */
- if (cur_chr == cat_code_base)
- n = max_char_code;
- else if (cur_chr == sf_code_base)
- n = 077777;
- else
- n = biggest_char;
- p = cur_chr;
- if (cur_chr == math_code_base) {
- if (is_global(a))
- cur_val1 = level_one;
- else
- cur_val1 = cur_level;
- scan_extdef_math_code(cur_val1, tex_mathcode);
- } else if (cur_chr == lc_code_base) {
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- scan_int();
- check_def_code(lc_code_base);
- define_lc_code(p, cur_val);
- } else if (cur_chr == uc_code_base) {
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- scan_int();
- check_def_code(uc_code_base);
- define_uc_code(p, cur_val);
- } else if (cur_chr == sf_code_base) {
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- scan_int();
- check_def_code(sf_code_base);
- define_sf_code(p, cur_val);
- } else if (cur_chr == cat_code_base) {
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- scan_int();
- check_def_code(cat_code_base);
- define_cat_code(p, cur_val);
- } else if (cur_chr == del_code_base) {
- if (is_global(a))
- cur_val1 = level_one;
- else
- cur_val1 = cur_level;
- scan_extdef_del_code(cur_val1, tex_mathcode);
- }
- break;
- case extdef_math_code_cmd:
- case extdef_del_code_cmd:
- if (is_global(a))
- cur_val1 = level_one;
- else
- cur_val1 = cur_level;
- if (cur_chr == math_code_base)
- scan_extdef_math_code(cur_val1, umath_mathcode);
- else if (cur_chr == math_code_base + 1)
- scan_extdef_math_code(cur_val1, umathnum_mathcode);
- else if (cur_chr == del_code_base)
- scan_extdef_del_code(cur_val1, umath_mathcode);
- else if (cur_chr == del_code_base + 1)
- scan_extdef_del_code(cur_val1, umathnum_mathcode);
- break;
- case def_family_cmd:
- p = cur_chr;
- scan_math_family_int();
- cur_val1 = cur_val;
- scan_optional_equals();
- scan_font_ident();
- define_fam_fnt(cur_val1, p, cur_val);
- break;
- case set_math_param_cmd:
- p = cur_chr;
- get_token();
- if (cur_cmd != math_style_cmd) {
- print_err("Missing math style, treated as \\displaystyle");
- help1(
- "A style should have been here; I inserted `\\displaystyle'."
- );
- cur_val1 = display_style;
- back_error();
- } else {
- cur_val1 = cur_chr;
- }
- scan_optional_equals();
- if (p < math_param_first_mu_glue) {
- if (p == math_param_radical_degree_raise)
- scan_int();
- else
- scan_dimen(false, false, false);
- } else {
- scan_glue(mu_val_level);
- if (cur_val == thin_mu_skip_par)
- cur_val = thin_mu_skip_code;
- else if (cur_val == med_mu_skip_par)
- cur_val = med_mu_skip_code;
- else if (cur_val == thick_mu_skip_par)
- cur_val = thick_mu_skip_code;
- }
- define_math_param(p, cur_val1, cur_val);
- break;
- case register_cmd:
- case advance_cmd:
- case multiply_cmd:
- case divide_cmd:
- do_register_command(a);
- break;
- case set_box_cmd:
- /*tex
- The processing of boxes is somewhat different, because we may
- need to scan and create an entire box before we actually change
- the value of the old one.
- */
- scan_register_num();
- if (is_global(a))
- n = global_box_flag + cur_val;
- else
- n = box_flag + cur_val;
- scan_optional_equals();
- if (set_box_allowed) {
- scan_box(n);
- } else {
- print_err("Improper \\setbox");
- help3(
- "Sorry, \\setbox is not allowed after \\halign in a display,",
- "between \\accent and an accented character, or in immediate",
- "assignments."
- );
- error();
- }
- break;
- case set_aux_cmd:
- /*tex
- The |space_factor| or |prev_depth| settings are changed when a
- |set_aux| command is sensed. Similarly, |prev_graf| is changed in
- the presence of |set_prev_graf|, and |dead_cycles| or
- |insert_penalties| in the presence of |set_page_int|. These
- definitions are always global.
- */
- alter_aux();
- break;
- case set_prev_graf_cmd:
- alter_prev_graf();
- break;
- case set_page_dimen_cmd:
- alter_page_so_far();
- break;
- case set_page_int_cmd:
- alter_integer();
- break;
- case set_box_dimen_cmd:
- /*tex
- When some dimension of a box register is changed, the change
- isn't exactly global; but \TeX\ does not look at the \.{\\global}
- switch.
- */
- alter_box_dimen();
- break;
- case set_tex_shape_cmd:
- q = cur_chr;
- scan_optional_equals();
- scan_int();
- n = cur_val;
- if (n <= 0) {
- p = null;
- } else {
- p = new_node(shape_node, 2 * (n + 1) + 1);
- vinfo(p + 1) = n;
- for (j = 1; j <= n; j++) {
- scan_normal_dimen();
- varmem[p + 2 * j].cint = cur_val; /* indentation */
- scan_normal_dimen();
- varmem[p + 2 * j + 1].cint = cur_val; /* width */
- }
- }
- define(q, shape_ref_cmd, p);
- break;
- case set_etex_shape_cmd:
- q = cur_chr;
- scan_optional_equals();
- scan_int();
- n = cur_val;
- if (n <= 0) {
- p = null;
- } else {
- n = (cur_val / 2) + 1;
- p = new_node(shape_node, 2 * n + 1 + 1);
- vinfo(p + 1) = n;
- n = cur_val;
- varmem[p + 2].cint = n; /* number of penalties */
- for (j = p + 3; j <= p + n + 2; j++) {
- scan_int();
- varmem[j].cint = cur_val; /* penalty values */
- }
- if (!odd(n))
- varmem[p + n + 3].cint = 0; /* unused */
- }
- define(q, shape_ref_cmd, p);
- break;
- case hyph_data_cmd:
- /*tex
- All of \TeX's parameters are kept in |eqtb| except the font
- information, the interaction mode, and the hyphenation tables;
- these are strictly global.
- */
- switch (cur_chr) {
- case 0:
- new_hyph_exceptions();
- break;
- case 1:
- new_patterns();
- break;
- case 2:
- new_pre_hyphen_char();
- break;
- case 3:
- new_post_hyphen_char();
- break;
- case 4:
- new_pre_exhyphen_char();
- break;
- case 5:
- new_post_exhyphen_char();
- break;
- case 6:
- new_hyphenation_min();
- break;
- case 7:
- new_hj_code();
- break;
- }
- break;
- case assign_font_dimen_cmd:
- set_font_dimen();
- break;
- case assign_font_int_cmd:
- n = cur_chr;
- scan_font_ident();
- f = cur_val;
- if (n == no_lig_code) {
- set_no_ligatures(f);
- } else if (n < lp_code_base) {
- scan_optional_equals();
- scan_int();
- if (n == 0)
- set_hyphen_char(f, cur_val);
- else
- set_skew_char(f, cur_val);
- } else {
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- scan_int();
- switch (n) {
- case lp_code_base:
- set_lp_code(f, p, cur_val);
- break;
- case rp_code_base:
- set_rp_code(f, p, cur_val);
- break;
- case ef_code_base:
- set_ef_code(f, p, cur_val);
- break;
- case tag_code:
- set_tag_code(f, p, cur_val);
- break;
- }
- }
- break;
- case def_font_cmd:
- /*tex Here is where the information for a new font gets loaded. */
- tex_def_font((small_number) a);
- break;
- case def_lua_call_cmd:
- get_r_token();
- p = cur_cs;
- scan_optional_equals();
- scan_int();
- if (j != 0) {
- define(p, lua_call_cmd, cur_val);
- } else {
- define(p, lua_expandable_call_cmd, cur_val);
- }
- break;
- case letterspace_font_cmd:
- new_letterspaced_font((small_number) a);
- break;
- case copy_font_cmd:
- make_font_copy((small_number) a);
- break;
- case set_font_id_cmd:
- scan_int();
- if (is_valid_font(cur_val))
- zset_cur_font(cur_val);
- break ;
- case set_interaction_cmd:
- new_interaction();
- break;
- default:
- confusion("prefix");
- break;
- }
- /*tex End of assignments cases. */
- DONE:
- /*tex Insert a token saved by \.{\\afterassignment}, if any. */
- if (after_token != 0) {
- cur_tok = after_token;
- back_input();
- after_token = 0;
- }
-}
-
-void fixup_directions(void)
-{
- int temp_no_whatsits = no_local_whatsits_par;
- int temp_no_dirs = no_local_dirs_par;
- int temporary_dir = text_direction_par;
- if (dir_level(text_dir_ptr) == cur_level) {
- /* Remove from |text_dir_ptr|. */
- halfword text_dir_tmp = vlink(text_dir_ptr);
- flush_node(text_dir_ptr);
- text_dir_ptr = text_dir_tmp;
- }
- unsave();
- if (abs(mode) == hmode) {
- if (temp_no_dirs != 0) {
- /* Add local dir node. */
- tail_append(new_dir(text_direction_par));
- dir_dir(tail) = temporary_dir;
- subtype(tail) = cancel_dir;
- }
- if (temp_no_whatsits != 0) {
- /*tex Add local paragraph node. */
- tail_append(make_local_par_node(hmode_par_par_code));
- }
- }
-}
-
-/*tex
-
- This is experimental and needs more checking!
-
-*/
-
-void fixup_directions_only(void)
-{
- int temp_no_dirs = no_local_dirs_par;
- int temporary_dir = text_direction_par;
- if (dir_level(text_dir_ptr) == cur_level) {
- /* Remove from |text_dir_ptr|. */
- halfword text_dir_tmp = vlink(text_dir_ptr);
- flush_node(text_dir_ptr);
- text_dir_ptr = text_dir_tmp;
- }
- if (temp_no_dirs != 0) {
- /* Add local dir node. */
- tail_append(new_dir(text_direction_par));
- dir_dir(tail) = temporary_dir;
- subtype(tail) = cancel_dir;
- }
-}
-
-/*tex
-
-When a control sequence is to be defined, by \.{\\def} or \.{\\let} or something
-similar, the |get_r_token| routine will substitute a special control sequence for
-a token that is not redefinable.
-
-*/
-
-void get_r_token(void)
-{
- RESTART:
- do {
- get_token();
- } while (cur_tok == space_token);
- if ((cur_cs == 0) || (cur_cs > eqtb_top) ||
- ((cur_cs > frozen_control_sequence) && (cur_cs <= eqtb_size))) {
- print_err("Missing control sequence inserted");
- help5(
- "Please don't say `\\def cs{...}', say `\\def\\cs{...}'.",
- "I've inserted an inaccessible control sequence so that your",
- "definition will be completed without mixing me up too badly.",
- "You can recover graciously from this error, if you're",
- "careful; see exercise 27.2 in The TeXbook."
- );
- if (cur_cs == 0)
- back_input();
- cur_tok = cs_token_flag + frozen_protection;
- ins_error();
- goto RESTART;
- }
-}
-
-void assign_internal_value(int a, halfword p, int val)
-{
- halfword n;
- if ((p >= int_base) && (p < attribute_base)) {
- switch ((p - int_base)) {
- case cat_code_table_code:
- if (valid_catcode_table(val)) {
- if (val != cat_code_table_par)
- word_define(p, val);
- } else {
- print_err("Invalid \\catcode table");
- help2(
- "You can only switch to a \\catcode table that is initialized",
- "using \\savecatcodetable or \\initcatcodetable, or to table 0"
- );
- error();
- }
- break;
- case output_box_code:
- if ((val > 65535) | (val < 0)) {
- print_err("Invalid \\outputbox");
- help1(
- "The value for \\outputbox has to be between 0 and 65535."
- );
- error();
- } else {
- word_define(p, val);
- }
- break;
- case new_line_char_code:
- if (val > 127) {
- print_err("Invalid \\newlinechar");
- help2(
- "The value for \\newlinechar has to be no higher than 127.",
- "Your invalid assignment will be ignored."
- );
- error();
- } else {
- word_define(p, val);
- }
- break;
- case end_line_char_code:
- if (val > 127) {
- print_err("Invalid \\endlinechar");
- help2(
- "The value for \\endlinechar has to be no higher than 127.",
- "Your invalid assignment will be ignored."
- );
- error();
- } else {
- word_define(p, val);
- }
- break;
- case language_code:
- if (val < 0) {
- word_define(int_base + cur_lang_code, -1);
- word_define(p, -1);
- } else if (val > 16383) {
- print_err("Invalid \\language");
- help2(
- "The absolute value for \\language has to be no higher than 16383.",
- "Your invalid assignment will be ignored."
- );
- error();
- } else {
- word_define(int_base + cur_lang_code, val);
- word_define(p, val);
- }
- break;
- default:
- word_define(p, val);
- break;
- }
- /*tex
- If we are defining subparagraph penalty levels while we are in hmode,
- then we put out a whatsit immediately, otherwise we leave it alone.
- This mechanism might not be sufficiently powerful, and some other
- algorithm, searching down the stack, might be necessary. Good first
- step.
- */
- if ((abs(mode) == hmode) &&
- ((p == (int_base + local_inter_line_penalty_code)) ||
- (p == (int_base + local_broken_penalty_code)))) {
- /*tex Add local paragraph node */
- tail_append(make_local_par_node(penalty_par_code));
- eq_word_define(int_base + no_local_whatsits_code, no_local_whatsits_par + 1);
- }
- } else if ((p >= dimen_base) && (p <= eqtb_size)) {
- if (p == (dimen_base + page_left_offset_code)) {
- n = val - one_true_inch;
- word_define(dimen_base + h_offset_code, n);
- } else if (p == (dimen_base + h_offset_code)) {
- n = val + one_true_inch;
- word_define(dimen_base + page_left_offset_code, n);
- } else if (p == (dimen_base + page_top_offset_code)) {
- n = val - one_true_inch;
- word_define(dimen_base + v_offset_code, n);
- } else if (p == (dimen_base + v_offset_code)) {
- n = val + one_true_inch;
- word_define(dimen_base + page_top_offset_code, n);
- }
- word_define(p, val);
- } else if ((p >= local_base) && (p < toks_base)) {
- /*tex internal locals */
- define(p, call_cmd, val);
- } else {
- confusion("assign internal value");
- }
-}
-
-/*tex
-
-We use the fact that |register| $<$ |advance| $<$ |multiply| $<$ |divide|/ We
-compute the register location |l| and its type |p| but |return| if invalid. Here
-we use the fact that the consecutive codes |int_val..mu_val| and
-|assign_int..assign_mu_glue| correspond to each other nicely.
-
-*/
-
-void do_register_command(int a)
-{
- int p;
- halfword q = cur_cmd;
- halfword l = 0;
- if (q != register_cmd) {
- get_x_token();
- if ((cur_cmd >= assign_int_cmd) && (cur_cmd <= assign_mu_glue_cmd)) {
- l = cur_chr;
- p = cur_cmd - assign_int_cmd;
- goto FOUND;
- }
- if (cur_cmd != register_cmd) {
- print_err("You can't use `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- tprint("' after ");
- print_cmd_chr((quarterword) q, 0);
- help1(
- "I'm forgetting what you said and not changing anything."
- );
- error();
- return;
- }
- }
- p = cur_chr;
- scan_register_num();
- if (p == int_val_level)
- l = cur_val + count_base;
- else if (p == attr_val_level)
- l = cur_val + attribute_base;
- else if (p == dimen_val_level)
- l = cur_val + scaled_base;
- else if (p == glue_val_level)
- l = cur_val + skip_base;
- else if (p == mu_val_level)
- l = cur_val + mu_skip_base;
- FOUND:
- if (q == register_cmd) {
- scan_optional_equals();
- } else if (scan_keyword("by")) {
- /*tex optional `\.{by}' */
- }
- arith_error = false;
- if (q < multiply_cmd) {
- /*tex Compute result of |register| or |advance|, put it in |cur_val|. */
- if (p < glue_val_level) {
- if ((p == int_val_level) || (p == attr_val_level))
- scan_int();
- else
- scan_normal_dimen();
- if (q == advance_cmd)
- cur_val = cur_val + eqtb[l].cint;
- } else {
- scan_glue(p);
- if (q == advance_cmd) {
- /* Compute the sum of two glue specs */
- halfword r = equiv(l);
- q = new_spec(cur_val);
- flush_node(cur_val);
- width(q) = width(q) + width(r);
- if (stretch(q) == 0) {
- stretch_order(q) = normal;
- }
- if (stretch_order(q) == stretch_order(r)) {
- stretch(q) = stretch(q) + stretch(r);
- } else if ((stretch_order(q) < stretch_order(r)) && (stretch(r) != 0)) {
- stretch(q) = stretch(r);
- stretch_order(q) = stretch_order(r);
- }
- if (shrink(q) == 0) {
- shrink_order(q) = normal;
- }
- if (shrink_order(q) == shrink_order(r)) {
- shrink(q) = shrink(q) + shrink(r);
- } else if ((shrink_order(q) < shrink_order(r)) && (shrink(r) != 0)) {
- shrink(q) = shrink(r);
- shrink_order(q) = shrink_order(r);
- }
- cur_val = q;
- }
- }
- } else {
- /*tex Compute result of |multiply| or |divide|, put it in |cur_val| */
- scan_int();
- if (p < glue_val_level) {
- if (q == multiply_cmd) {
- if ((p == int_val_level) || (p == attr_val_level)) {
- cur_val = mult_integers(eqtb[l].cint, cur_val);
- } else {
- cur_val = nx_plus_y(eqtb[l].cint, cur_val, 0);
- }
- } else {
- cur_val = x_over_n(eqtb[l].cint, cur_val);
- }
- } else {
- halfword s = equiv(l);
- halfword r = new_spec(s);
- if (q == multiply_cmd) {
- width(r) = nx_plus_y(width(s), cur_val, 0);
- stretch(r) = nx_plus_y(stretch(s), cur_val, 0);
- shrink(r) = nx_plus_y(shrink(s), cur_val, 0);
- } else {
- width(r) = x_over_n(width(s), cur_val);
- stretch(r) = x_over_n(stretch(s), cur_val);
- shrink(r) = x_over_n(shrink(s), cur_val);
- }
- cur_val = r;
- }
- }
- if (arith_error) {
- print_err("Arithmetic overflow");
- help2(
- "I can't carry out that multiplication or division,",
- "since the result is out of range."
- );
- if (p >= glue_val_level)
- flush_node(cur_val);
- error();
- return;
- }
- if (p < glue_val_level) {
- if (p == attr_val_level) {
- if ((l - attribute_base) > max_used_attr)
- max_used_attr = (l - attribute_base);
- attr_list_cache = cache_disabled;
- }
- if ((p == int_val_level) || (p == dimen_val_level))
- assign_internal_value(a, l, cur_val);
- else
- word_define(l, cur_val);
- } else {
- define(l, glue_ref_cmd, cur_val);
- }
-}
-
-void alter_aux(void)
-{
- halfword c; /* |hmode| or |vmode| */
- if (cur_chr != abs(mode)) {
- report_illegal_case();
- } else {
- c = cur_chr;
- scan_optional_equals();
- if (c == vmode) {
- scan_normal_dimen();
- prev_depth_par = cur_val;
- } else {
- scan_int();
- if ((cur_val <= 0) || (cur_val > 32767)) {
- print_err("Bad space factor");
- help1(
- "I allow only values in the range 1..32767 here."
- );
- int_error(cur_val);
- } else {
- space_factor_par = cur_val;
- }
- }
- }
-}
-
-void alter_prev_graf(void)
-{
- int p = nest_ptr; /* index into |nest| */
- while (abs(nest[p].mode_field) != vmode)
- decr(p);
- scan_optional_equals();
- scan_int();
- if (cur_val < 0) {
- print_err("Bad \\prevgraf");
- help1(
- "I allow only nonnegative values here."
- );
- int_error(cur_val);
- } else {
- nest[p].pg_field = cur_val;
- }
-}
-
-void alter_page_so_far(void)
-{
- int c = cur_chr; /* index into |page_so_far| */
- scan_optional_equals();
- scan_normal_dimen();
- page_so_far[c] = cur_val;
-}
-
-/*tex
- The value of |c| is 0 for \.{\\deadcycles}, 1 for \.{\\insertpenalties}, etc.
-*/
-
-void alter_integer(void)
-{
- int c = cur_chr;
- scan_optional_equals();
- scan_int();
- if (c == 0) {
- dead_cycles = cur_val;
- } else if (c == 2) {
- if ((cur_val < batch_mode) || (cur_val > error_stop_mode)) {
- print_err("Bad interaction mode");
- help2(
- "Modes are 0=batch, 1=nonstop, 2=scroll, and",
- "3=errorstop. Proceed, and I'll ignore this case."
- );
- int_error(cur_val);
- } else {
- cur_chr = cur_val;
- new_interaction();
- }
- } else {
- insert_penalties = cur_val;
- }
-}
-
-void alter_box_dimen(void)
-{
- int c; /* |width_offset| or |height_offset| or |depth_offset| */
- int b; /* box number */
- c = cur_chr;
- scan_register_num();
- b = cur_val;
- scan_optional_equals();
- scan_normal_dimen();
- if (box(b) != null)
- varmem[box(b) + c].cint = cur_val;
-}
-
-void new_interaction(void)
-{
- print_ln();
- interaction = cur_chr;
- if (interaction == batch_mode)
- kpse_make_tex_discard_errors = 1;
- else
- kpse_make_tex_discard_errors = 0;
- fixup_selector(log_opened_global);
-}
-
-/*tex
-
-The \.{\\afterassignment} command puts a token into the global variable
-|after_token|. This global variable is examined just after every assignment has
-been performed. It's value is zero, or a saved token.
-
-*/
-
-halfword after_token;
-
-/*tex
-
- Here is a procedure that might be called `Get the next non-blank non-relax
- non-call non-assignment token'.
-
-*/
-
-void do_assignments(void)
-{
- while (true) {
- /*tex Get the next non-blank non-relax... */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd <= max_non_prefixed_command)
- return;
- set_box_allowed = false;
- prefixed_command();
- set_box_allowed = true;
- }
-}
-
-/*tex |cur_chr| is 1 for \.{\\openin}, 0 for \.{\\closein}: */
-
-void open_or_close_in(void)
-{
- int c = cur_chr;
- int n;
- char *fn;
- scan_four_bit_int();
- n = cur_val;
- if (read_open[n] != closed) {
- lua_a_close_in(read_file[n], (n + 1));
- read_open[n] = closed;
- }
- if (c != 0) {
- scan_optional_equals();
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- back_input();
- if (cur_cmd != left_brace_cmd) {
- /*tex Set |cur_name| to desired file name. */
- scan_file_name();
- } else {
- scan_file_name_toks();
- }
- fn = pack_file_name(cur_name, cur_area, cur_ext);
- if (lua_a_open_in(&(read_file[n]), fn, (n + 1))) {
- read_open[n] = just_open;
- }
- }
-}
-
-/*tex
- Has the long \.{\\errmessage} help been used?
-*/
-
-boolean long_help_seen;
-
-void issue_message(void)
-{
- int old_setting; /* holds |selector| setting */
- int c; /* identifies \.{\\message} and \.{\\errmessage} */
- str_number s; /* the message */
- c = cur_chr;
- (void) scan_toks(false, true);
- old_setting = selector;
- selector = new_string;
- token_show(def_ref);
- selector = old_setting;
- flush_list(def_ref);
- str_room(1);
- s = make_string();
- if (c == 0) {
- /*tex Print string |s| on the terminal */
- if (term_offset + (int) str_length(s) > max_print_line - 2)
- print_ln();
- else if ((term_offset > 0) || (file_offset > 0))
- print_char(' ');
- print(s);
- update_terminal();
-
- } else {
- /*tex
- Print string |s| as an error message. If \.{\\errmessage} occurs
- often in |scroll_mode|, without user-defined \.{\\errhelp}, we don't
- want to give a long help message each time. So we give a verbose
- explanation only once.
- */
- print_err("");
- print(s);
- if (err_help_par != null) {
- use_err_help = true;
- } else if (long_help_seen) {
- help1(
- "(That was another \\errmessage.)"
- );
- } else {
- if (interaction < error_stop_mode)
- long_help_seen = true;
- help4(
- "This error message was generated by an \\errmessage",
- "command, so I can't give any explicit help.",
- "Pretend that you're Hercule Poirot: Examine all clues,",
- "and deduce the truth by order and method."
- );
- }
- error();
- use_err_help = false;
-
- }
- flush_str(s);
-}
-
-/*tex
-
-The |error| routine calls on |give_err_help| if help is requested from the
-|err_help| parameter.
-
-*/
-
-void give_err_help(void)
-{
- token_show(err_help_par);
-}
-
-/*tex
-
-The \.{\\uppercase} and \.{\\lowercase} commands are implemented by building a
-token list and then changing the cases of the letters in it.
-
-*/
-
-void shift_case(void)
-{
- halfword b; /* |lc_code_base| or |uc_code_base| */
- halfword p; /* runs through the token list */
- halfword t; /* token */
- halfword c; /* character code */
- halfword i; /* inbetween */
- b = cur_chr;
- p = scan_toks(false, false);
- p = token_link(def_ref);
- while (p != null) {
- /*tex
- Change the case of the token in |p|, if a change is appropriate. When
- the case of a |chr_code| changes, we don't change the |cmd|. We also
- change active characters.
- */
- t = token_info(p);
- if (t < cs_token_flag) {
- c = t % STRING_OFFSET;
- if (b == uc_code_base)
- i = get_uc_code(c);
- else
- i = get_lc_code(c);
- if (i != 0)
- set_token_info(p, t - c + i);
- } else if (is_active_cs(cs_text(t - cs_token_flag))) {
- c = active_cs_value(cs_text(t - cs_token_flag));
- if (b == uc_code_base)
- i = get_uc_code(c);
- else
- i = get_lc_code(c);
- if (i != 0)
- set_token_info(p, active_to_cs(i, true) + cs_token_flag);
- }
- p = token_link(p);
- }
- back_list(token_link(def_ref));
- free_avail(def_ref);
-}
-
-/*tex
-
-We come finally to the last pieces missing from |main_control|, namely the
-`\.{\\show}' commands that are useful when debugging.
-
-*/
-
-void show_whatever(void)
-{
- halfword p; /* tail of a token list to show */
- int t; /* type of conditional being shown */
- int m; /* upper bound on |fi_or_else| codes */
- int l; /* line where that conditional began */
- int n; /* level of \.{\\if...\\fi} nesting */
- switch (cur_chr) {
- case show_lists:
- begin_diagnostic();
- show_activities();
- break;
- case show_box_code:
- /*tex Show the current contents of a box. */
- scan_register_num();
- begin_diagnostic();
- tprint_nl("> \\box");
- print_int(cur_val);
- print_char('=');
- if (box(cur_val) == null)
- tprint("void");
- else
- show_box(box(cur_val));
- break;
- case show_code:
- /*tex Show the current meaning of a token, then |goto common_ending|. */
- get_token();
- if (interaction == error_stop_mode)
- wake_up_terminal();
- tprint_nl("> ");
- if (cur_cs != 0) {
- sprint_cs(cur_cs);
- print_char('=');
- }
- print_meaning();
- goto COMMON_ENDING;
- break;
- /*tex Cases for |show_whatever| */
- case show_groups:
- begin_diagnostic();
- show_save_groups();
- break;
- case show_ifs:
- begin_diagnostic();
- tprint_nl("");
- print_ln();
- if (cond_ptr == null) {
- tprint_nl("### ");
- tprint("no active conditionals");
- } else {
- p = cond_ptr;
- n = 0;
- do {
- incr(n);
- p = vlink(p);
- } while (p != null);
- p = cond_ptr;
- t = cur_if;
- l = if_line;
- m = if_limit;
- do {
- tprint_nl("### level ");
- print_int(n);
- tprint(": ");
- print_cmd_chr(if_test_cmd, t);
- if (m == fi_code)
- tprint_esc("else");
- print_if_line(l);
- decr(n);
- t = if_limit_subtype(p);
- l = if_line_field(p);
- m = if_limit_type(p);
- p = vlink(p);
- } while (p != null);
- }
- break;
- default:
- /*tex
- Show the current value of some parameter or register, then |goto
- common_ending|.
- */
- p = the_toks();
- if (interaction == error_stop_mode)
- wake_up_terminal();
- tprint_nl("> ");
- token_show(temp_token_head);
- flush_list(token_link(temp_token_head));
- goto COMMON_ENDING;
- break;
- }
- /*tex Complete a potentially long \.{\\show} command: */
- end_diagnostic(true);
- print_err("OK");
- if (selector == term_and_log) {
- if (tracing_online_par <= 0) {
- selector = term_only;
- tprint(" (see the transcript file)");
- selector = term_and_log;
- }
- }
- COMMON_ENDING:
- if (interaction < error_stop_mode) {
- help0();
- decr(error_count);
- } else if (tracing_online_par > 0) {
- help3(
- "This isn't an error message; I'm just \\showing something.",
- "Type `I\\show...' to show more (e.g., \\show\\cs,",
- "\\showthe\\count10, \\showbox255, \\showlists)."
- );
- } else {
- help5(
- "This isn't an error message; I'm just \\showing something.",
- "Type `I\\show...' to show more (e.g., \\show\\cs,",
- "\\showthe\\count10, \\showbox255, \\showlists).",
- "And type `I\\tracingonline=1\\show...' to show boxes and",
- "lists on your terminal as well as in the transcript file."
- );
- }
- error();
-}
-
-/*tex
- This procedure gets things started properly:
-*/
-
-void initialize(void)
-{
- int k; /* index into |mem|, |eqtb|, etc. */
- /*tex
- Initialize whatever \TeX\ might access and set initial values of key
- variables
- */
- initialize_errors();
- initialize_arithmetic();
- max_used_attr = -1;
- attr_list_cache = cache_disabled;
- initialize_nesting();
- /*tex Start a new current page: */
- page_contents = empty;
- page_tail = page_head;
-#if 0
- vlink(page_head) = null;
-#endif
- last_glue = max_halfword;
- last_penalty = 0;
- last_kern = 0;
- last_node_type = -1;
- page_depth = 0;
- page_max_depth = 0;
-
- initialize_equivalents();
- no_new_control_sequence = true; /* new identifiers are usually forbidden */
- init_primitives();
-
- mag_set = 0;
- initialize_marks();
- initialize_read();
-
- static_pdf = init_pdf_struct(static_pdf); /* should be init_backend() */
-
- format_ident = 0;
- format_name = get_nullstr();
- initialize_directions();
- initialize_write_files();
- seconds_and_micros(epochseconds, microseconds);
- initialize_start_time(static_pdf);
-
- edit_name_start = 0;
- stop_at_space = true;
-
- if (ini_version) {
- /*tex Initialize table entries (done by \.{INITEX} only). */
- init_node_mem(500);
- initialize_tokens();
- /*tex Initialize the special list heads and constant nodes. */
- initialize_alignments();
- initialize_buildpage();
-
- initialize_active();
-
- set_eq_type(undefined_control_sequence, undefined_cs_cmd);
- set_equiv(undefined_control_sequence, null);
- set_eq_level(undefined_control_sequence, level_zero);
- for (k = null_cs; k <= (eqtb_top - 1); k++)
- eqtb[k] = eqtb[undefined_control_sequence];
- set_equiv(glue_base, zero_glue);
- set_eq_level(glue_base, level_one);
- set_eq_type(glue_base, glue_ref_cmd);
- for (k = glue_base + 1; k <= local_base - 1; k++) {
- eqtb[k] = eqtb[glue_base];
- }
- par_shape_par_ptr = null;
- set_eq_type(par_shape_loc, shape_ref_cmd);
- set_eq_level(par_shape_loc, level_one);
- for (k = etex_pen_base; k <= (etex_pens - 1); k++)
- eqtb[k] = eqtb[par_shape_loc];
- for (k = output_routine_loc; k <= toks_base + biggest_reg; k++)
- eqtb[k] = eqtb[undefined_control_sequence];
- box(0) = null;
- set_eq_type(box_base, box_ref_cmd);
- set_eq_level(box_base, level_one);
- for (k = box_base + 1; k <= (box_base + biggest_reg); k++)
- eqtb[k] = eqtb[box_base];
- cur_font_par = null_font;
- set_eq_type(cur_font_loc, data_cmd);
- set_eq_level(cur_font_loc, level_one);
- set_equiv(cat_code_base, 0);
- set_eq_type(cat_code_base, data_cmd);
- set_eq_level(cat_code_base, level_one);
- eqtb[internal_math_param_base] = eqtb[cat_code_base];
- eqtb[lc_code_base] = eqtb[cat_code_base];
- eqtb[uc_code_base] = eqtb[cat_code_base];
- eqtb[sf_code_base] = eqtb[cat_code_base];
- eqtb[math_code_base] = eqtb[cat_code_base];
- cat_code_table_par = 0;
- initialize_math_codes();
- initialize_text_codes();
- initex_cat_codes(0);
- for (k = '0'; k <= '9'; k++)
- set_math_code(k, math_use_current_family_code, 0, k, level_one);
- for (k = 'A'; k <= 'Z'; k++) {
- set_math_code(k, math_use_current_family_code, 1, k, level_one);
- set_math_code((k + 32), math_use_current_family_code, 1, (k + 32), level_one);
- set_lc_code(k, k + 32, level_one);
- set_lc_code(k + 32, k + 32, level_one);
- set_uc_code(k, k, level_one);
- set_uc_code(k + 32, k, level_one);
- set_sf_code(k, 999, level_one);
- }
- for (k = int_base; k <= attribute_base - 1; k++)
- eqtb[k].cint = 0;
- for (k = attribute_base; k <= del_code_base - 1; k++)
- eqtb[k].cint = UNUSED_ATTRIBUTE;
- mag_par = 1000;
- tolerance_par = 10000;
- hang_after_par = 1;
- max_dead_cycles_par = 25;
- math_pre_display_gap_factor_par = 2000;
- pre_bin_op_penalty_par = inf_penalty;
- math_script_box_mode_par = 1;
- math_script_char_mode_par = 1;
- pre_rel_penalty_par = inf_penalty;
- compound_hyphen_mode_par = 1;
- escape_char_par = '\\';
- end_line_char_par = carriage_return;
- set_del_code('.', 0, 0, 0, 0, level_one); /* this null delimiter is used in error recovery */
- ex_hyphen_char_par = '-';
- output_box_par = 255;
- for (k = dimen_base; k <= eqtb_size; k++)
- eqtb[k].cint = 0;
- page_left_offset_par = one_inch;
- page_top_offset_par = one_inch;
- page_right_offset_par = one_inch;
- page_bottom_offset_par = one_inch;
- ini_init_primitives();
- hash_used = frozen_control_sequence;
- hash_high = 0;
- cs_count = 0;
- set_eq_type(frozen_dont_expand, dont_expand_cmd);
- cs_text(frozen_dont_expand) = maketexstring("notexpanded:");
- set_eq_type(frozen_primitive, ignore_spaces_cmd);
- set_equiv(frozen_primitive, 1);
- set_eq_level(frozen_primitive, level_one);
- cs_text(frozen_primitive) = maketexstring("primitive");
- create_null_font();
- font_bytes = 0;
- px_dimen_par = one_bp;
- math_eqno_gap_step_par = 1000 ;
- math_flatten_mode_par = 1; /* ord */
- cs_text(frozen_protection) = maketexstring("inaccessible");
- format_ident = maketexstring(" (INITEX)");
- cs_text(end_write) = maketexstring("endwrite");
- set_eq_level(end_write, level_one);
- set_eq_type(end_write, outer_call_cmd);
- set_equiv(end_write, null);
- /*tex Bah, this is a bad place do do this. */
- set_pdf_major_version(1);
- set_pdf_minor_version(0);
- }
- synctexoffset = int_base + synctex_code;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h b/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
deleted file mode 100644
index 04608c11e9b..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/maincontrol.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* maincontrol.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef MAINCONTROL_H
-# define MAINCONTROL_H
-
-# define fil_code 0 /* identifies \.{\\hfil} and \.{\\vfil} */
-# define fill_code 1 /* identifies \.{\\hfill} and \.{\\vfill} */
-# define ss_code 2 /* identifies \.{\\hss} and \.{\\vss} */
-# define fil_neg_code 3 /* identifies \.{\\hfilneg} and \.{\\vfilneg} */
-# define skip_code 4 /* identifies \.{\\hskip} and \.{\\vskip} */
-# define mskip_code 5 /* identifies \.{\\mskip} */
-
-/* The |prefixed_command| does not have to adjust |a| so that |a mod 4=0|,
-since the following routines test for the \.{\\global} prefix as follows.
-*/
-
-# define is_global(a) (a>=4)
-
-# define define(A,B,C) do { \
- if (is_global(a)) \
- geq_define((A),(quarterword)(B),(C)); \
- else \
- eq_define((A),(quarterword)(B),(C)); \
- } while (0)
-
-# define word_define(A,B) do { \
- if (is_global(a)) \
- geq_word_define((A),(B)); \
- else \
- eq_word_define((A),(B)); \
- } while (0)
-
-# define define_lc_code(A,B) do { \
- if (is_global(a)) \
- set_lc_code((A),(B),level_one); \
- else \
- set_lc_code((A),(B),cur_level); \
- } while (0)
-
-# define define_uc_code(A,B) do { \
- if (is_global(a)) \
- set_uc_code((A),(B),level_one); \
- else \
- set_uc_code((A),(B),cur_level); \
-} while (0)
-
-# define define_sf_code(A,B) do { \
- if (is_global(a)) \
- set_sf_code((A),(B),level_one); \
- else \
- set_sf_code((A),(B),cur_level); \
- } while (0)
-
-# define define_cat_code(A,B) do { \
- if (is_global(a)) \
- set_cat_code(cat_code_table_par,(A),(B),level_one); \
- else \
- set_cat_code(cat_code_table_par,(A),(B),cur_level); \
- } while (0)
-
-# define define_fam_fnt(A,B,C) do { \
- if (is_global(a)) \
- def_fam_fnt((A),(B),(C),level_one); \
- else \
- def_fam_fnt((A),(B),(C),cur_level); \
- } while (0)
-
-# define define_math_param(A,B,C) do { \
- if (is_global(a)) \
- def_math_param((A),(B),(C),level_one); \
- else \
- def_math_param((A),(B),(C),cur_level); \
- } while (0)
-
-extern halfword cur_box; /* box to be placed into its context */
-
-/*
-A \.{\\chardef} creates a control sequence whose |cmd| is |char_given|;
-a \.{\\mathchardef} creates a control sequence whose |cmd| is |math_given|;
-and the corresponding |chr| is the character code or math code. A \.{\\countdef}
-or \.{\\dimendef} or \.{\\skipdef} or \.{\\muskipdef} creates a control
-sequence whose |cmd| is |assign_int| or \dots\ or |assign_mu_glue|, and the
-corresponding |chr| is the |eqtb| location of the internal register in question.
-*/
-
-# define char_def_code 0 /* |shorthand_def| for \.{\\chardef} */
-# define math_char_def_code 1 /* |shorthand_def| for \.{\\mathchardef} */
-# define xmath_char_def_code 2 /* |shorthand_def| for \.{\\Umathchardef} */
-# define count_def_code 3 /* |shorthand_def| for \.{\\countdef} */
-# define attribute_def_code 4 /* |shorthand_def| for \.{\\attributedef} */
-# define dimen_def_code 5 /* |shorthand_def| for \.{\\dimendef} */
-# define skip_def_code 6 /* |shorthand_def| for \.{\\skipdef} */
-# define mu_skip_def_code 7 /* |shorthand_def| for \.{\\muskipdef} */
-# define toks_def_code 8 /* |shorthand_def| for \.{\\toksdef} */
-# define umath_char_def_code 9 /* |shorthand_def| for \.{\\Umathcharnumdef} */
-
-extern void adjust_space_factor(void);
-extern void main_control(void);
-extern void app_space(void);
-extern void insert_dollar_sign(void);
-extern void insert_dollar_sign_par_end(void);
-extern void you_cant(void);
-extern void report_illegal_case(void);
-extern boolean privileged(void);
-extern boolean its_all_over(void);
-extern void append_glue(void);
-extern void append_kern(void);
-extern void off_save(void);
-extern void handle_right_brace(void);
-extern void extra_right_brace(void);
-extern void normal_paragraph(void);
-extern void box_end(int box_context);
-extern void scan_box(int box_context);
-extern void new_graf(boolean indented);
-extern void indent_in_hmode(void);
-extern void head_for_vmode(void);
-extern void end_graf(int);
-extern void begin_insert_or_adjust(void);
-extern void handle_mark(void);
-extern void append_penalty(void);
-extern void delete_last(void);
-extern void unpackage(void);
-extern void append_italic_correction(void);
-extern void append_local_box(int kind);
-extern void append_discretionary(void);
-extern void build_local_box(void);
-extern void build_discretionary(void);
-extern void make_accent(void);
-extern void align_error(void);
-extern void no_align_error(void);
-extern void omit_error(void);
-extern void do_endv(void);
-extern void cs_error(void);
-extern void prefixed_command(void);
-extern void fixup_directions(void);
-extern void fixup_directions_only(void);
-
-
-/* Assignments from Lua need helpers. */
-
-# define is_int_assign(cmd) (cmd==assign_int_cmd)
-# define is_attr_assign(cmd) (cmd==assign_attr_cmd)
-# define is_dim_assign(cmd) (cmd==assign_dimen_cmd)
-# define is_glue_assign(cmd) (cmd==assign_glue_cmd)
-# define is_mu_glue_assign(cmd) (cmd==assign_mu_glue_cmd)
-# define is_toks_assign(cmd) (cmd==assign_toks_cmd)
-
-# define show_code 0 /* \.{\\show} */
-# define show_box_code 1 /* \.{\\showbox} */
-# define show_the_code 2 /* \.{\\showthe} */
-# define show_lists 3 /* \.{\\showlists} */
-# define show_groups 4 /* \.{\\showgroups} */
-# define show_tokens 5 /* \.{\\showtokens} , must be odd! */
-# define show_ifs 6 /* \.{\\showifs} */
-
-# define print_if_line(A) if ((A)!=0) { \
- tprint(" entered on line "); print_int((A)); \
- }
-
-/*
- extern halfword swap_hang_indent(halfword indentation, halfword shape_mode);
- extern halfword swap_parshape_indent(halfword indentation, halfword width, halfword shape_mode);
-*/
-
-#define swap_hang_indent(indentation) \
- ( ((shape_mode_par == 1 || shape_mode_par == 3 || shape_mode_par == -1 || shape_mode_par == -3)) ? negate(indentation) : indentation )
-
-#define swap_parshape_indent(indentation,width) \
- ( ((shape_mode_par == 2 || shape_mode_par == 3 || shape_mode_par == -2 || shape_mode_par == -3)) ? (hsize_par - width - indentation) : indentation )
-
-extern void get_r_token(void);
-extern void assign_internal_value(int a, halfword p, int cur_val);
-extern void do_register_command(int a);
-extern void alter_aux(void);
-extern void alter_prev_graf(void);
-extern void alter_page_so_far(void);
-extern void alter_integer(void);
-extern void alter_box_dimen(void);
-extern void new_interaction(void);
-extern halfword after_token;
-extern void do_assignments(void);
-extern void open_or_close_in(void);
-extern boolean long_help_seen;
-extern void issue_message(void);
-extern void give_err_help(void);
-extern void shift_case(void);
-extern void show_whatever(void);
-
-extern void initialize(void); /* this procedure gets things started properly */
-
-/*extern int local_level;*/
-
-extern void local_control(void);
-extern halfword local_scan_box(void);
-extern int current_local_level(void);
-extern void end_local_control(void);
-extern void local_control_message(const char *s);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/mathcodes.c b/Build/source/texk/web2c/luatexdir/tex/mathcodes.c
deleted file mode 100644
index 42e8b0b15b9..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mathcodes.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
-
-mathnodes.w
-
-Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-We support tre traditional math codes as well as larger ones suitable for
-\UNICODE\ input and fonts.
-
-*/
-
-static sa_tree mathcode_head = NULL;
-
-/*tex the |0xFFFFFFFF| is a flag value. */
-
-#define MATHCODESTACK 8
-#define MATHCODEDEFAULT 0xFFFFFFFF
-#define MATHCODEACTIVE 0xFFFFFFFE
-
-/*tex
-
-Delcodes are also went larger.
-
-*/
-
-static sa_tree delcode_head = NULL;
-
-#define DELCODESTACK 4
-#define DELCODEDEFAULT 0xFFFFFFFF
-
-/*tex
-
-We now get lots of helpers for definitions and printing. The storage model
-that we use is different because we can hav emany more so we need to be
-sparse. Therefore we use trees.
-
-*/
-
-
-#define print_hex_digit(A) do { \
- if ((A)>=10) print_char('A'+(A)-10); \
- else print_char('0'+(A)); \
- } while (0)
-
-#define two_hex(A) do { \
- print_hex_digit((A)/16); \
- print_hex_digit((A)%16); \
- } while (0)
-
-#define four_hex(A) do { \
- two_hex((A)/256); \
- two_hex((A)%256); \
- } while (0)
-
-#define six_hex(A) do { \
- two_hex((A)/65536); \
- two_hex(((A)%65536)/256); \
- two_hex((A)%256); \
- } while (0)
-
-mathcodeval mathchar_from_integer(int value, int extcode)
-{
- mathcodeval mval;
- if (extcode == tex_mathcode) {
- mval.class_value = (value / 0x1000);
- mval.family_value = ((value % 0x1000) / 0x100);
- mval.character_value = (value % 0x100);
- } else {
- int mfam = (value / 0x200000) & 0x7FF;
- mval.class_value = mfam % 0x08;
- mval.family_value = mfam / 0x08;
- mval.character_value = value & 0x1FFFFF;
- }
- return mval;
-}
-
-void show_mathcode_value_old(int value)
-{
- print_char('"');
- four_hex(value);
-}
-
-void show_mathcode_value(mathcodeval c)
-{
- print_char('"');
- print_hex_digit(c.class_value);
- print_char('"');
- two_hex(c.family_value);
- print_char('"');
- six_hex(c.character_value);
-}
-
-static void show_mathcode(int n)
-{
- mathcodeval c = get_math_code(n);
- tprint_esc("Umathcode");
- print_int(n);
- print_char('=');
- show_mathcode_value(c);
-}
-
-static void unsavemathcode(quarterword gl)
-{
- sa_stack_item st;
- if (mathcode_head->stack == NULL)
- return;
- while (mathcode_head->stack_ptr > 0 && abs(mathcode_head->stack[mathcode_head->stack_ptr].level) >= gl) {
- st = mathcode_head->stack[mathcode_head->stack_ptr];
- if (st.level > 0) {
- rawset_sa_item(mathcode_head, st.code, st.value);
- if (tracing_restores_par > 1) {
- begin_diagnostic();
- print_char('{');
- tprint("restoring");
- print_char(' ');
- show_mathcode(st.code);
- print_char('}');
- end_diagnostic(false);
- }
- }
- (mathcode_head->stack_ptr)--;
- }
-}
-
-void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword level)
-{
- sa_tree_item v;
- if (mathclass == 8 && mathfamily == 0 && mathcharacter == 0) {
- v.uint_value = MATHCODEACTIVE;
- } else {
- v.math_code_value.class_value = mathclass;
- v.math_code_value.family_value = mathfamily;
- v.math_code_value.character_value = mathcharacter;
- }
- set_sa_item(mathcode_head, n, v, level);
- if (tracing_assigns_par > 1) {
- begin_diagnostic();
- print_char('{');
- tprint("assigning");
- print_char(' ');
- show_mathcode(n);
- print_char('}');
- end_diagnostic(false);
- }
-}
-
-mathcodeval get_math_code(int n)
-{
- mathcodeval d;
- sa_tree_item v = get_sa_item(mathcode_head, n);
- if (v.uint_value == MATHCODEDEFAULT) {
- d.class_value = 0;
- d.family_value = 0;
- d.character_value = n;
- } else if (v.uint_value == MATHCODEACTIVE) {
- d.class_value = 8;
- d.family_value = 0;
- d.character_value = 0;
- } else {
- d.class_value = v.math_code_value.class_value;
- if (d.class_value == 8) {
- d.family_value = 0;
- d.character_value = n;
- } else {
- d.family_value = v.math_code_value.family_value;
- d.character_value = v.math_code_value.character_value;
- }
- }
- return d;
-}
-
-int get_math_code_num(int n)
-{
- mathcodeval d = get_math_code(n);
- return (d.class_value + (d.family_value * 8)) * (65536 * 32) + d.character_value;
-}
-
-static void initializemathcode(void)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.uint_value = MATHCODEDEFAULT;
- mathcode_head = new_sa_tree(MATHCODESTACK, 1, sa_value);
-}
-
-static void dumpmathcode(void)
-{
- dump_sa_tree(mathcode_head,"mathcodes");
-}
-
-static void undumpmathcode(void)
-{
- mathcode_head = undump_sa_tree("mathcodes");
-}
-
-static void show_delcode(int n)
-{
- delcodeval c;
- c = get_del_code(n);
- tprint_esc("Udelcode");
- print_int(n);
- print_char('=');
- if (c.small_family_value < 0) {
- print_char('-');
- print_char('1');
- } else {
- print_char('"');
- two_hex(c.small_family_value);
- six_hex(c.small_character_value);
- }
-}
-
-static void unsavedelcode(quarterword gl)
-{
- sa_stack_item st;
- if (delcode_head->stack == NULL)
- return;
- while (delcode_head->stack_ptr > 0 && abs(delcode_head->stack[delcode_head->stack_ptr].level) >= gl) {
- st = delcode_head->stack[delcode_head->stack_ptr];
- if (st.level > 0) {
- rawset_sa_item(delcode_head, st.code, st.value);
- if (tracing_restores_par > 1) {
- begin_diagnostic();
- print_char('{');
- tprint("restoring");
- print_char(' ');
- show_delcode(st.code);
- print_char('}');
- end_diagnostic(false);
- }
- }
- (delcode_head->stack_ptr)--;
- }
-}
-
-void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl)
-{
- sa_tree_item v;
- v.del_code_value.class_value = 0;
- v.del_code_value.small_family_value = smathfamily;
- v.del_code_value.small_character_value = smathcharacter;
- v.del_code_value.dummy_value = 0;
- v.del_code_value.large_family_value = lmathfamily;
- v.del_code_value.large_character_value = lmathcharacter;
- /*tex Always global! */
- set_sa_item(delcode_head, n, v, gl);
- if (tracing_assigns_par > 1) {
- begin_diagnostic();
- print_char('{');
- tprint("assigning");
- print_char(' ');
- show_delcode(n);
- print_char('}');
- end_diagnostic(false);
- }
-}
-
-delcodeval get_del_code(int n)
-{
- delcodeval d;
- sa_tree_item v = get_sa_item(delcode_head, n);
- if (v.uint_value == DELCODEDEFAULT) {
- d.class_value = 0;
- d.small_family_value = -1;
- d.small_character_value = 0;
- d.large_family_value = 0;
- d.large_character_value = 0;
- } else {
- d.class_value = v.del_code_value.class_value;
- d.small_family_value = v.del_code_value.small_family_value;
- d.small_character_value = v.del_code_value.small_character_value;
- d.large_family_value = v.del_code_value.large_family_value;
- d.large_character_value = v.del_code_value.large_character_value;
- }
- return d;
-}
-
-/*tex
-
-This really only works for old-style delcodes!
-
-*/
-
-int get_del_code_num(int n)
-{
- delcodeval d = get_del_code(n);
- if (d.small_family_value < 0) {
- return -1;
- } else {
- return ((d.small_family_value * 256 + d.small_character_value) * 4096 +
- (d.large_family_value * 256) + d.large_character_value);
- }
-}
-
-static void initializedelcode(void)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.uint_value = DELCODEDEFAULT;
- delcode_head = new_sa_tree(DELCODESTACK, 2, sa_value);
-}
-
-static void dumpdelcode(void)
-{
- dump_sa_tree(delcode_head,"delcodes");
-}
-
-static void undumpdelcode(void)
-{
- delcode_head = undump_sa_tree("delcodes");
-}
-
-void unsave_math_codes(quarterword grouplevel)
-{
- unsavemathcode(grouplevel);
- unsavedelcode(grouplevel);
-}
-
-void initialize_math_codes(void)
-{
- initializemathcode();
- initializedelcode();
-}
-
-void free_math_codes(void)
-{
- destroy_sa_tree(mathcode_head);
- destroy_sa_tree(delcode_head);
-}
-
-void dump_math_codes(void)
-{
- dumpmathcode();
- dumpdelcode();
-}
-
-void undump_math_codes(void)
-{
- undumpmathcode();
- undumpdelcode();
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/mathcodes.h b/Build/source/texk/web2c/luatexdir/tex/mathcodes.h
deleted file mode 100644
index fe731ff2be5..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mathcodes.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* mathcodes.h
-
- Copyright 2009-2012 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef MATHCODES_H
-# define MATHCODES_H
-
-/* this is a flag for |scan_delimiter| */
-
-# define no_mathcode 0
-# define tex_mathcode 8
-# define umath_mathcode 21
-# define umathnum_mathcode 22
-
-typedef struct mathcodeval {
- int class_value;
- int family_value;
- int character_value;
-} mathcodeval;
-
-void set_math_code(int n, int mathclass, int mathfamily, int mathcharacter, quarterword gl);
-
-mathcodeval get_math_code(int n);
-int get_math_code_num(int n);
-int get_del_code_num(int n);
-mathcodeval scan_mathchar(int extcode);
-mathcodeval scan_delimiter_as_mathchar(int extcode);
-
-mathcodeval mathchar_from_integer(int value, int extcode);
-void show_mathcode_value(mathcodeval d);
-void show_mathcode_value_old(int value);
-
-typedef struct delcodeval {
- int class_value;
- int small_family_value;
- int small_character_value;
- int large_family_value;
- int large_character_value;
-} delcodeval;
-
-void set_del_code(int n, int smathfamily, int smathcharacter, int lmathfamily, int lmathcharacter, quarterword gl);
-
-delcodeval get_del_code(int n);
-
-void unsave_math_codes(quarterword grouplevel);
-void initialize_math_codes(void);
-void dump_math_codes(void);
-void undump_math_codes(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/memoryword.c b/Build/source/texk/web2c/luatexdir/tex/memoryword.c
deleted file mode 100644
index 7bf758dd0d4..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/memoryword.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-memoryword.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-The debug code is no longer present!
-
-*/
diff --git a/Build/source/texk/web2c/luatexdir/tex/memoryword.h b/Build/source/texk/web2c/luatexdir/tex/memoryword.h
deleted file mode 100644
index 5db2bb8cb36..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/memoryword.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* memoryword.h
-
- Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-/* This header file is extra special because it is read in from
- within the pascal source */
-
-#ifndef MEMORYWORD_H
-# define MEMORYWORD_H
-
-/* texmfmem.h: the memory_word type, which is too hard to translate
- automatically from Pascal. We have to make sure the byte-swapping
- that the (un)dumping routines do suffices to put things in the right
- place in memory.
-
- A memory_word can be broken up into a `twohalves' or a
- `fourquarters', and a `twohalves' can be further broken up. Here is
- a picture. ..._M = most significant byte, ..._L = least significant
- byte.
-
-
- BigEndian:
- twohalves.v: RH_MM RH_ML RH_LM RH_LL LH_MM LH_ML LH_LM LH_LL
- twohalves.u: ---------JUNK---------- ----B0----- ----B1-----
- fourquarters: ----B0----- ----B1----- ----B2----- ----B3-----
- twoints: ---------CINT0--------- ---------CINT1---------
-
- LittleEndian:
- twohalves.v: LH_LL LH_LM LH_ML LH_MM RH_LL RH_LM RH_ML RH_MM
- twohalves.u: ----B1----- ----B0-----
- fourquarters: ----B3----- ----B2----- ----B1----- ----B0-----
- twoints: ---------CINT1--------- ---------CINT0---------
-
-*/
-
-
-typedef union {
- struct {
-# ifdef WORDS_BIGENDIAN
- halfword RH, LH;
-# else
- halfword LH, RH;
-# endif
- } v;
-
- struct { /* Make B0,B1 overlap the most significant bytes of LH. */
-# ifdef WORDS_BIGENDIAN
- halfword junk;
- quarterword B0, B1;
-# else /* not WORDS_BIGENDIAN */
- /* If 32-bit memory words, have to do something. */
- quarterword B1, B0;
-# endif /* LittleEndian */
- } u;
-} two_halves;
-
-typedef struct {
- struct {
-# ifdef WORDS_BIGENDIAN
- quarterword B0, B1, B2, B3;
-# else
- quarterword B3, B2, B1, B0;
-# endif
- } u;
-} four_quarters;
-
-typedef struct {
-# ifdef WORDS_BIGENDIAN
- int CINT0, CINT1;
-# else
- int CINT1, CINT0;
-# endif
-} two_ints;
-
-typedef struct {
- glue_ratio GLUE;
-} glues;
-
-typedef union {
- two_halves hh;
- four_quarters qqqq;
- two_ints ii;
- glues gg;
-} memory_word;
-
-# define b0 u.B0
-# define b1 u.B1
-# define b2 u.B2
-# define b3 u.B3
-
-# define rh v.RH
-# define lhfield v.LH
-
-# define cint ii.CINT0
-# define cint1 ii.CINT1
-
-# define gr gg.GLUE
-
-/* the next five defines are needed for the prototypes in web2c's coerce.h */
-
-# define memoryword memory_word
-# define strnumber str_number
-# define packedASCIIcode packed_ASCII_code
-# define poolpointer pool_pointer
-
-typedef FILE *word_file;
-
-# ifdef DEBUG
-extern void print_word(memory_word w);
-# endif
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.c b/Build/source/texk/web2c/luatexdir/tex/mlist.c
deleted file mode 100644
index 2ac631ea339..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mlist.c
+++ /dev/null
@@ -1,4830 +0,0 @@
-/*
-
-Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-/*tex
-
- In traditional \TeX\ the italic correction is added to the width of the
- glyph. This is part of the engine design and related font design. In opentype
- math this is different. There the italic correction had more explicit usage.
- The 1.7 spec says:
-
- \startitemize
-
- \startitem
- {\em italic correction:} When a run of slanted characters is followed by
- a straight character (such as an operator or a delimiter), the italics
- correction of the last glyph is added to its advance width.
-
- When positioning limits on an N-ary operator (e.g., integral sign), the
- horizontal position of the upper limit is moved to the right by ½ of the
- italics correction, while the position of the lower limit is moved to the
- left by the same distance.
-
- When positioning superscripts and subscripts, their default horizontal
- positions are also different by the amount of the italics correction of
- the preceding glyph.
- \stopitem
-
- \startitem
- {\em math kerning:} Set the default horizontal position for the
- superscript as shifted relative to the position of the subscript by the
- italics correction of the base glyph.
- \stopitem
-
- \stopitemize
-
- Before this was specified we had to gamble a bit and assume that cambria was
- the font benchmark and trust our eyes (and msword) for the logic. I must
- admit that I have been fighting these italics in fonts (and the heuristics
- that Lua\TeX\ provided) right from the start (e.g. using Lua based
- postprocessing) but by now we know more and have more fonts to test with.
- More fonts are handy because not all fonts are alike when it comes to
- italics. Axis are another area of concern, as it looks like opentype math
- fonts often already apply that shift.
-
-*/
-
-#define is_new_mathfont(A) ((font_math_params(A) >0) && (math_old_par == 0))
-#define is_old_mathfont(A,B) ((font_math_params(A)==0) && (font_params(A)>=(B)))
-#define do_new_math(A) ((font_math_params(A) >0) && (font_oldmath(A) == 0) && (math_old_par == 0))
-#define protect_glyph(A) subtype(A)=256
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-#define reset_attributes(p,newatt) do { \
- delete_attribute_ref(node_attr(p)); \
- node_attr(p) = newatt; \
- if (newatt!=null) { \
- add_node_attr_ref(node_attr(p)); \
- } \
- } while (0)
-
-#define DEFINE_MATH_PARAMETERS(A,B,C,D) do { \
- if (B==text_size) { \
- def_math_param(A, text_style, (C),D); \
- def_math_param(A, cramped_text_style, (C),D); \
- } else if (B==script_size) { \
- def_math_param(A, script_style, (C),D); \
- def_math_param(A, cramped_script_style, (C),D); \
- } else if (B==script_script_size) { \
- def_math_param(A, script_script_style, (C),D); \
- def_math_param(A, cramped_script_script_style, (C),D); \
- } \
- } while (0)
-
-#define DEFINE_DMATH_PARAMETERS(A,B,C,D) do { \
- if (B==text_size) { \
- def_math_param(A, display_style,(C),D); \
- def_math_param(A, cramped_display_style,(C),D); \
- } \
- } while (0)
-
-#define font_MATH_par(a,b) \
- (font_math_params(a)>=b ? font_math_param(a,b) : undefined_math_parameter)
-
-/*tex
-
- Here are the math parameters that are font-dependant.
-
- Before an mlist is converted to an hlist, \TeX\ makes sure that the fonts in
- family~2 have enough parameters to be math-symbol fonts, and that the fonts
- in family~3 have enough parameters to be math-extension fonts. The
- math-symbol parameters are referred to by using the following macros, which
- take a size code as their parameter; for example, |num1(cur_size)| gives the
- value of the |num1| parameter for the current size.
-
-*/
-
-#define total_mathsy_params 22
-#define total_mathex_params 13
-
-#define mathsy(A,B) font_param(fam_fnt(2,A),B)
-
-/*tex height of `\.x' */
-
-#define math_x_height(A) mathsy(A,5)
-
-/*tex \.{18mu} */
-
-#define math_quad(A) mathsy(A,6)
-
-/*tex numerator shift-up in display styles */
-
-#define num1(A) mathsy(A,8)
-
-/*tex numerator shift-up in non-display, non-\.{\\atop} */
-
-#define num2(A) mathsy(A,9)
-
-/*tex numerator shift-up in non-display \.{\\atop} */
-
-#define num3(A) mathsy(A,10)
-
-/*tex denominator shift-down in display styles */
-
-#define denom1(A) mathsy(A,11)
-
-/*tex denominator shift-down in non-display styles */
-
-#define denom2(A) mathsy(A,12)
-
-/*tex superscript shift-up in uncramped display style */
-
-#define sup1(A) mathsy(A,13)
-
-/*tex superscript shift-up in uncramped non-display */
-
-#define sup2(A) mathsy(A,14)
-
-/*tex superscript shift-up in cramped styles */
-
-#define sup3(A) mathsy(A,15)
-
-/*tex subscript shift-down if superscript is absent */
-
-#define sub1(A) mathsy(A,16)
-
-/*tex subscript shift-down if superscript is present */
-
-#define sub2(A) mathsy(A,17)
-
-/*tex superscript baseline below top of large box */
-
-#define sup_drop(A) mathsy(A,18)
-
-/*tex subscript baseline below bottom of large box */
-
-#define sub_drop(A) mathsy(A,19)
-
-/*tex size of \.{\\atopwithdelims} delimiters in display styles */
-
-#define delim1(A) mathsy(A,20)
-
-/*tex size of \.{\\atopwithdelims} delimiters in non-displays */
-
-#define delim2(A) mathsy(A,21)
-
-/*tex height of fraction lines above the baseline */
-
-#define axis_height(A) mathsy(A,22)
-
-/*tex
-
- The math-extension parameters have similar macros, but the size code is
- omitted (since it is always |cur_size| when we refer to such parameters).
-
-*/
-
-#define mathex(A,B) font_param(fam_fnt(3,A),B)
-
-/*tex thickness of \.{\\over} bars */
-
-#define default_rule_thickness(A) mathex(A,8)
-
-/*tex minimum clearance above a displayed op */
-
-#define big_op_spacing1(A) mathex(A,9)
-
-/*tex minimum clearance below a displayed op */
-
-#define big_op_spacing2(A) mathex(A,10)
-
-/*tex minimum baselineskip above displayed op */
-
-#define big_op_spacing3(A) mathex(A,11)
-
-/*tex minimum baselineskip below displayed op */
-
-#define big_op_spacing4(A) mathex(A,12)
-
-/*tex padding above and below displayed limits */
-
-#define big_op_spacing5(A) mathex(A,13)
-
-/*tex
-
- \LUATEX makes a bunch of extensions cf. the |MATH| table in \OPENTYPE, but
- some of the |MathConstants| values have no matching usage in \LUATEX\ right
- now.
-
- \startitemize
-
- \startitem
- |ScriptPercentScaleDown| |ScriptScriptPercentScaleDown|: These should
- be handled by the macro package, on the engine side there are three
- separate fonts.
- \stopitem
-
- \startitem
- |DelimitedSubFormulaMinHeight|: This is perhaps related to word's
- natural math input? We have no idea what to do about it.
- \stopitem
-
- \startitem
- |MathLeading|: \LUATEX does not currently handle multi-line displays,
- and the parameter does not seem to make much sense elsewhere.
- \stopitem
-
- \startitem
- |FlattenedAccentBaseHeight|: This is based on the |flac| |GSUB|
- feature. It would not be hard to support that, but proper math accent
- placements cf.\ |MATH| needs support for |MathTopAccentAttachment|
- table to be implemented first.
- \stopitem
-
- \stopitemize
-
-*/
-
-static void math_param_error(const char *param, int style)
-{
- char s[256];
- const char *hlp[] = {
- "Sorry, but I can't typeset math unless various parameters have",
- "been set. This is normally done by loading special math fonts",
- "into the math family slots. Your font set is lacking at least",
- "the parameter mentioned earlier.",
- NULL
- };
- snprintf(s, 256, "Math error: parameter \\Umath%s\\%sstyle is not set", param, math_style_names[style]);
- tex_error(s, hlp);
- return;
-}
-
-static scaled accent_base_height(int f)
-{
- scaled a;
- if (do_new_math(f)) {
- a = font_MATH_par(f, AccentBaseHeight);
- if (a == undefined_math_parameter)
- a = x_height(f);
- } else {
- a = x_height(f);
- }
- return a;
-}
-
-/*tex
-
- The non-staticness of this function is for the benefit of |texmath.w|.
- Watch out, this one uses the style! The style and size numbers don't
- match because we have cramped styles.
-
-*/
-
-scaled get_math_quad_style(int var)
-{
- scaled a = get_math_param(math_param_quad, var);
- if (a == undefined_math_parameter) {
- math_param_error("quad", var);
- return 0;
- } else {
- return a;
- }
-}
-
-/*tex
-
- For this reason the next one is different because it is called with a size
- specifier instead of a style specifier.
-
-*/
-
-static scaled math_axis_size(int b)
-{
- scaled a;
- int var;
- if (b == script_size)
- var = script_style;
- else if (b == script_script_size)
- var = script_script_style;
- else
- var = text_style;
- a = get_math_param(math_param_axis, var);
- if (a == undefined_math_parameter) {
- math_param_error("axis", var);
- return 0;
- } else {
- return a;
- }
-}
-
-scaled get_math_quad_size(int b)
-{
- int var;
- if (b == script_size)
- var = script_style;
- else if (b == script_script_size)
- var = script_script_style;
- else
- var = text_style;
- return get_math_param(math_param_quad, var);
-}
-
-static scaled minimum_operator_size(int var)
-{
- scaled a = get_math_param(math_param_operator_size, var);
- return a;
-}
-
-/*tex
-
- Old-style fonts do not define the |radical_rule|. This allows |make_radical|
- to select the backward compatibility code, and it means that we can't raise
- an error here.
-
-*/
-
-static scaled radical_rule_par(int var)
-{
- scaled a = get_math_param(math_param_radical_rule, var);
- return a;
-}
-
-/*tex
-
- Now follow all the trivial math parameters.
-
-*/
-
-#define get_math_param_or_error(a,b) do_get_math_param_or_error(a, math_param_##b, #b)
-#define get_math_param_or_zero(a,b) do_get_math_param_or_zero(a, math_param_##b, #b)
-
-static scaled do_get_math_param_or_error(int var, int param, const char *name)
-{
- scaled a = get_math_param(param, var);
- if (a == undefined_math_parameter) {
- math_param_error(name, var);
- a = 0;
- }
- return a;
-}
-
-static scaled do_get_math_param_or_zero(int var, int param, const char *name)
-{
- scaled a = get_math_param(param, var);
- if (a == undefined_math_parameter) {
- a = 0;
- }
- return a;
-}
-
-/*tex
-
- A variant on a suggestion on the list based on analysis by UV.
-
-*/
-
-static scaled get_delimiter_height(scaled max_d, scaled max_h, boolean axis) {
- scaled delta, delta1, delta2;
- if (axis) {
- delta2 = max_d + math_axis_size(cur_size);
- } else {
- delta2 = max_d;
- }
- delta1 = max_h + max_d - delta2;
- if (delta2 > delta1) {
- /*tex |delta1| is max distance from axis */
- delta1 = delta2;
- }
- delta = (delta1 / 500) * delimiter_factor_par;
- delta2 = delta1 + delta1 - delimiter_shortfall_par;
- if (delta < delta2) {
- return delta2;
- } else {
- return delta;
- }
-}
-
-#define radical_degree_before(a) get_math_param_or_error(a, radical_degree_before)
-#define radical_degree_after(a) get_math_param_or_error(a, radical_degree_after)
-#define radical_degree_raise(a) get_math_param_or_error(a, radical_degree_raise)
-
-#define connector_overlap_min(a) get_math_param_or_error(a, connector_overlap_min)
-
-#define overbar_rule(a) get_math_param_or_error(a, overbar_rule)
-#define overbar_kern(a) get_math_param_or_error(a, overbar_kern)
-#define overbar_vgap(a) get_math_param_or_error(a, overbar_vgap)
-
-#define underbar_rule(a) get_math_param_or_error(a, underbar_rule)
-#define underbar_kern(a) get_math_param_or_error(a, underbar_kern)
-#define underbar_vgap(a) get_math_param_or_error(a, underbar_vgap)
-
-#define under_delimiter_vgap(a) get_math_param_or_error(a, under_delimiter_vgap)
-#define under_delimiter_bgap(a) get_math_param_or_error(a, under_delimiter_bgap)
-
-#define over_delimiter_vgap(a) get_math_param_or_error(a, over_delimiter_vgap)
-#define over_delimiter_bgap(a) get_math_param_or_error(a, over_delimiter_bgap)
-
-#define radical_vgap(a) get_math_param_or_error(a, radical_vgap)
-#define radical_kern(a) get_math_param_or_error(a, radical_kern)
-
-#define stack_vgap(a) get_math_param_or_error(a, stack_vgap)
-#define stack_num_up(a) get_math_param_or_error(a, stack_num_up)
-#define stack_denom_down(a) get_math_param_or_error(a, stack_denom_down)
-
-#define fraction_rule(a) get_math_param_or_error(a, fraction_rule)
-#define fraction_num_vgap(a) get_math_param_or_error(a, fraction_num_vgap)
-#define fraction_denom_vgap(a) get_math_param_or_error(a, fraction_denom_vgap)
-#define fraction_num_up(a) get_math_param_or_error(a, fraction_num_up)
-#define fraction_denom_down(a) get_math_param_or_error(a, fraction_denom_down)
-#define fraction_del_size_new(a) get_math_param_or_error(a, fraction_del_size)
-/* fraction_del_size_old(a) get_math_param (a, math_param_fraction_del_size) */
-#define fraction_del_size_old(a) get_math_param_or_error(a, fraction_del_size)
-
-#define skewed_fraction_hgap(a) get_math_param_or_error(a, skewed_fraction_hgap)
-#define skewed_fraction_vgap(a) get_math_param_or_error(a, skewed_fraction_vgap)
-
-#define limit_above_vgap(a) get_math_param_or_error(a, limit_above_vgap)
-#define limit_above_bgap(a) get_math_param_or_error(a, limit_above_bgap)
-#define limit_above_kern(a) get_math_param_or_error(a, limit_above_kern)
-
-#define limit_below_vgap(a) get_math_param_or_error(a, limit_below_vgap)
-#define limit_below_bgap(a) get_math_param_or_error(a, limit_below_bgap)
-#define limit_below_kern(a) get_math_param_or_error(a, limit_below_kern)
-
-#define nolimit_sub_factor(a) get_math_param_or_zero(a, nolimit_sub_factor)
-#define nolimit_sup_factor(a) get_math_param_or_zero(a, nolimit_sup_factor)
-
-#define sub_shift_drop(a) get_math_param_or_error(a, sub_shift_drop)
-#define sup_shift_drop(a) get_math_param_or_error(a, sup_shift_drop)
-#define sub_shift_down(a) get_math_param_or_error(a, sub_shift_down)
-#define sub_sup_shift_down(a) get_math_param_or_error(a, sub_sup_shift_down)
-#define sup_shift_up(a) get_math_param_or_error(a, sup_shift_up)
-#define sub_top_max(a) get_math_param_or_error(a, sub_top_max)
-#define sup_bottom_min(a) get_math_param_or_error(a, sup_bottom_min)
-#define sup_sub_bottom_max(a) get_math_param_or_error(a, sup_sub_bottom_max)
-#define subsup_vgap(a) get_math_param_or_error(a, subsup_vgap)
-
-#define space_after_script(a) get_math_param_or_error(a, space_after_script)
-
-void fixup_math_parameters(int fam_id, int size_id, int f, int lvl)
-{
- if (is_new_mathfont(f)) {
-
- /*tex Fix all known parameters. */
-
- DEFINE_MATH_PARAMETERS(math_param_quad, size_id,
- font_size(f), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_quad, size_id,
- font_size(f), lvl);
- DEFINE_MATH_PARAMETERS(math_param_axis, size_id,
- font_MATH_par(f, AxisHeight), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_axis, size_id,
- font_MATH_par(f, AxisHeight), lvl);
- DEFINE_MATH_PARAMETERS(math_param_overbar_kern, size_id,
- font_MATH_par(f, OverbarExtraAscender), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_kern, size_id,
- font_MATH_par(f, OverbarExtraAscender), lvl);
- DEFINE_MATH_PARAMETERS(math_param_overbar_rule, size_id,
- font_MATH_par(f, OverbarRuleThickness), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_rule, size_id,
- font_MATH_par(f, OverbarRuleThickness), lvl);
- DEFINE_MATH_PARAMETERS(math_param_overbar_vgap, size_id,
- font_MATH_par(f, OverbarVerticalGap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_vgap, size_id,
- font_MATH_par(f, OverbarVerticalGap), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_kern, size_id,
- font_MATH_par(f, UnderbarExtraDescender), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_kern, size_id,
- font_MATH_par(f, UnderbarExtraDescender), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_rule, size_id,
- font_MATH_par(f, UnderbarRuleThickness), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_rule, size_id,
- font_MATH_par(f, UnderbarRuleThickness), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_vgap, size_id,
- font_MATH_par(f, UnderbarVerticalGap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_vgap, size_id,
- font_MATH_par(f, UnderbarVerticalGap), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_under_delimiter_vgap, size_id,
- font_MATH_par(f, StretchStackGapAboveMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_under_delimiter_vgap, size_id,
- font_MATH_par(f, StretchStackGapAboveMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_under_delimiter_bgap, size_id,
- font_MATH_par(f, StretchStackBottomShiftDown), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_under_delimiter_bgap, size_id,
- font_MATH_par(f, StretchStackBottomShiftDown), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_over_delimiter_vgap, size_id,
- font_MATH_par(f, StretchStackGapBelowMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_over_delimiter_vgap, size_id,
- font_MATH_par(f, StretchStackGapBelowMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_over_delimiter_bgap, size_id,
- font_MATH_par(f, StretchStackTopShiftUp), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_over_delimiter_bgap, size_id,
- font_MATH_par(f, StretchStackTopShiftUp), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_stack_num_up, size_id,
- font_MATH_par(f, StackTopShiftUp), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_num_up, size_id,
- font_MATH_par(f, StackTopDisplayStyleShiftUp), lvl);
- DEFINE_MATH_PARAMETERS(math_param_stack_denom_down, size_id,
- font_MATH_par(f, StackBottomShiftDown), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_denom_down, size_id,
- font_MATH_par(f, StackBottomDisplayStyleShiftDown), lvl);
- DEFINE_MATH_PARAMETERS(math_param_stack_vgap, size_id,
- font_MATH_par(f, StackGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_vgap, size_id,
- font_MATH_par(f, StackDisplayStyleGapMin), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_radical_kern, size_id,
- font_MATH_par(f, RadicalExtraAscender), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_kern, size_id,
- font_MATH_par(f, RadicalExtraAscender), lvl);
-
- DEFINE_DMATH_PARAMETERS(math_param_operator_size, size_id,
- font_MATH_par(f, DisplayOperatorMinHeight), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_radical_rule, size_id,
- font_MATH_par(f, RadicalRuleThickness), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_rule, size_id,
- font_MATH_par(f, RadicalRuleThickness), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_vgap, size_id,
- font_MATH_par(f, RadicalVerticalGap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_vgap, size_id,
- font_MATH_par(f, RadicalDisplayStyleVerticalGap), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_before, size_id,
- font_MATH_par(f, RadicalKernBeforeDegree), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_before, size_id,
- font_MATH_par(f, RadicalKernBeforeDegree), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_after, size_id,
- font_MATH_par(f, RadicalKernAfterDegree), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_after, size_id,
- font_MATH_par(f, RadicalKernAfterDegree), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_raise, size_id,
- font_MATH_par(f, RadicalDegreeBottomRaisePercent), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_raise, size_id,
- font_MATH_par(f, RadicalDegreeBottomRaisePercent), lvl);
-
- if (size_id == text_size) {
- def_math_param(math_param_sup_shift_up, display_style,
- font_MATH_par(f, SuperscriptShiftUp), lvl);
- def_math_param(math_param_sup_shift_up, cramped_display_style,
- font_MATH_par(f, SuperscriptShiftUpCramped), lvl);
- def_math_param(math_param_sup_shift_up, text_style,
- font_MATH_par(f, SuperscriptShiftUp), lvl);
- def_math_param(math_param_sup_shift_up, cramped_text_style,
- font_MATH_par(f, SuperscriptShiftUpCramped), lvl);
- } else if (size_id == script_size) {
- def_math_param(math_param_sup_shift_up, script_style,
- font_MATH_par(f, SuperscriptShiftUp), lvl);
- def_math_param(math_param_sup_shift_up, cramped_script_style,
- font_MATH_par(f, SuperscriptShiftUpCramped), lvl);
- } else if (size_id == script_script_size) {
- def_math_param(math_param_sup_shift_up, script_script_style,
- font_MATH_par(f, SuperscriptShiftUp), lvl);
- def_math_param(math_param_sup_shift_up, cramped_script_script_style,
- font_MATH_par(f, SuperscriptShiftUpCramped), lvl);
- }
-
- DEFINE_MATH_PARAMETERS(math_param_sub_shift_drop, size_id,
- font_MATH_par(f, SubscriptBaselineDropMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_shift_drop, size_id,
- font_MATH_par(f, SubscriptBaselineDropMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sup_shift_drop, size_id,
- font_MATH_par(f, SuperscriptBaselineDropMax), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sup_shift_drop, size_id,
- font_MATH_par(f, SuperscriptBaselineDropMax), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sub_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDown), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDown), lvl);
-
- if (font_MATH_par(f, SubscriptShiftDownWithSuperscript) != undefined_math_parameter) {
- DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDownWithSuperscript), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDownWithSuperscript), lvl);
- } else {
- DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDown), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- font_MATH_par(f, SubscriptShiftDown), lvl);
- }
-
- DEFINE_MATH_PARAMETERS(math_param_sub_top_max, size_id,
- font_MATH_par(f, SubscriptTopMax), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_top_max, size_id,
- font_MATH_par(f, SubscriptTopMax), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sup_bottom_min, size_id,
- font_MATH_par(f, SuperscriptBottomMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sup_bottom_min, size_id,
- font_MATH_par(f, SuperscriptBottomMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sup_sub_bottom_max, size_id,
- font_MATH_par(f, SuperscriptBottomMaxWithSubscript), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sup_sub_bottom_max, size_id,
- font_MATH_par(f, SuperscriptBottomMaxWithSubscript), lvl);
- DEFINE_MATH_PARAMETERS(math_param_subsup_vgap, size_id,
- font_MATH_par(f, SubSuperscriptGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_subsup_vgap, size_id,
- font_MATH_par(f, SubSuperscriptGapMin), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_limit_above_vgap, size_id,
- font_MATH_par(f, UpperLimitGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_vgap, size_id,
- font_MATH_par(f, UpperLimitGapMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_above_bgap, size_id,
- font_MATH_par(f, UpperLimitBaselineRiseMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_bgap, size_id,
- font_MATH_par(f, UpperLimitBaselineRiseMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_above_kern, size_id,
- 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_kern, size_id,
- 0, lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_vgap, size_id,
- font_MATH_par(f, LowerLimitGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_vgap, size_id,
- font_MATH_par(f, LowerLimitGapMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_bgap, size_id,
- font_MATH_par(f, LowerLimitBaselineDropMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_bgap, size_id,
- font_MATH_par(f, LowerLimitBaselineDropMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_kern, size_id,
- 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_kern, size_id,
- 0, lvl);
- DEFINE_MATH_PARAMETERS(math_param_nolimit_sub_factor, size_id,
- font_MATH_par(f, NoLimitSubFactor), lvl); /* bonus */
- DEFINE_DMATH_PARAMETERS(math_param_nolimit_sub_factor, size_id,
- font_MATH_par(f, NoLimitSubFactor), lvl); /* bonus */
- DEFINE_MATH_PARAMETERS(math_param_nolimit_sup_factor, size_id,
- font_MATH_par(f, NoLimitSupFactor), lvl); /* bonus */
- DEFINE_DMATH_PARAMETERS(math_param_nolimit_sup_factor, size_id,
- font_MATH_par(f, NoLimitSupFactor), lvl); /* bonus */
-
- DEFINE_MATH_PARAMETERS(math_param_fraction_rule, size_id,
- font_MATH_par(f, FractionRuleThickness), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_rule, size_id,
- font_MATH_par(f, FractionRuleThickness), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_num_vgap, size_id,
- font_MATH_par(f, FractionNumeratorGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_num_vgap, size_id,
- font_MATH_par(f, FractionNumeratorDisplayStyleGapMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_num_up, size_id,
- font_MATH_par(f, FractionNumeratorShiftUp), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_num_up, size_id,
- font_MATH_par(f, FractionNumeratorDisplayStyleShiftUp), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_denom_vgap, size_id,
- font_MATH_par(f, FractionDenominatorGapMin), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_denom_vgap, size_id,
- font_MATH_par(f,FractionDenominatorDisplayStyleGapMin), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_denom_down, size_id,
- font_MATH_par(f, FractionDenominatorShiftDown), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_denom_down, size_id,
- font_MATH_par(f, FractionDenominatorDisplayStyleShiftDown), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_fraction_del_size, size_id,
- font_MATH_par(f, FractionDelimiterSize), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_del_size, size_id,
- font_MATH_par(f, FractionDelimiterDisplayStyleSize), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_skewed_fraction_hgap, size_id,
- font_MATH_par(f, SkewedFractionHorizontalGap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_skewed_fraction_hgap, size_id,
- font_MATH_par(f, SkewedFractionHorizontalGap), lvl);
- DEFINE_MATH_PARAMETERS(math_param_skewed_fraction_vgap, size_id,
- font_MATH_par(f, SkewedFractionVerticalGap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_skewed_fraction_vgap, size_id,
- font_MATH_par(f, SkewedFractionVerticalGap), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_space_after_script, size_id,
- font_MATH_par(f, SpaceAfterScript), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_space_after_script, size_id,
- font_MATH_par(f, SpaceAfterScript), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_connector_overlap_min, size_id,
- font_MATH_par(f, MinConnectorOverlap), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_connector_overlap_min, size_id,
- font_MATH_par(f, MinConnectorOverlap), lvl);
-
- } else if (fam_id == 2 && is_old_mathfont(f, total_mathsy_params)) {
-
- /*tex Fix old-style |sy| parameters. */
-
- DEFINE_MATH_PARAMETERS(math_param_quad, size_id,
- math_quad(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_quad, size_id,
- math_quad(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_axis, size_id,
- axis_height(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_axis, size_id,
- axis_height(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_stack_num_up, size_id,
- num3(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_num_up, size_id,
- num1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_stack_denom_down, size_id,
- denom2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_denom_down, size_id,
- denom1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_num_up, size_id,
- num2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_num_up, size_id,
- num1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_denom_down, size_id,
- denom2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_denom_down, size_id,
- denom1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_del_size, size_id,
- delim2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_del_size, size_id,
- delim1(size_id), lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_skewed_fraction_hgap, size_id,
- 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_skewed_fraction_hgap, size_id,
- 0, lvl);
- DEFINE_MATH_PARAMETERS(math_param_skewed_fraction_vgap, size_id,
- 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_skewed_fraction_vgap, size_id,
- 0, lvl);
-
- if (size_id == text_size) {
- def_math_param(math_param_sup_shift_up, display_style,
- sup1(size_id), lvl);
- def_math_param(math_param_sup_shift_up, cramped_display_style,
- sup3(size_id), lvl);
- def_math_param(math_param_sup_shift_up, text_style,
- sup2(size_id), lvl);
- def_math_param(math_param_sup_shift_up, cramped_text_style,
- sup3(size_id), lvl);
- } else if (size_id == script_size) {
- def_math_param(math_param_sub_shift_drop, display_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop, cramped_display_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop, text_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop, cramped_text_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, display_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, cramped_display_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, text_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, cramped_text_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_up, script_style,
- sup2(size_id), lvl);
- def_math_param(math_param_sup_shift_up, cramped_script_style,
- sup3(size_id), lvl);
- } else if (size_id == script_script_size) {
- def_math_param(math_param_sub_shift_drop, script_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop, cramped_script_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop, script_script_style,
- sub_drop(size_id), lvl);
- def_math_param(math_param_sub_shift_drop,
- cramped_script_script_style, sub_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, script_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, cramped_script_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop, script_script_style,
- sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_drop,
- cramped_script_script_style, sup_drop(size_id), lvl);
- def_math_param(math_param_sup_shift_up, script_script_style,
- sup2(size_id), lvl);
- def_math_param(math_param_sup_shift_up, cramped_script_script_style,
- sup3(size_id), lvl);
- }
-
- DEFINE_MATH_PARAMETERS(math_param_sub_shift_down, size_id,
- sub1(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_shift_down, size_id,
- sub1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- sub2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_sup_shift_down, size_id,
- sub2(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sub_top_max, size_id,
- (abs(math_x_height(size_id) * 4) / 5), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sub_top_max, size_id,
- (abs(math_x_height(size_id) * 4) / 5), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sup_bottom_min, size_id,
- (abs(math_x_height(size_id)) / 4), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sup_bottom_min, size_id,
- (abs(math_x_height(size_id)) / 4), lvl);
- DEFINE_MATH_PARAMETERS(math_param_sup_sub_bottom_max, size_id,
- (abs(math_x_height(size_id) * 4) / 5), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_sup_sub_bottom_max, size_id,
- (abs(math_x_height(size_id) * 4) / 5), lvl);
-
- /*tex
-
- The display-size |radical_vgap| is done twice because it needs values
- from both the sy and the ex font.
-
- */
-
- DEFINE_DMATH_PARAMETERS(math_param_radical_vgap, size_id,
- (default_rule_thickness(size_id) + (abs(math_x_height(size_id)) / 4)), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_raise, size_id,
- 60, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_raise, size_id,
- 60, lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_before, size_id,
- xn_over_d(get_math_quad_size(size_id), 5, 18), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_before, size_id,
- xn_over_d(get_math_quad_size(size_id), 5, 18), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_degree_after, size_id,
- (-xn_over_d (get_math_quad_size(size_id), 10, 18)), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_degree_after, size_id,
- (-xn_over_d (get_math_quad_size(size_id), 10, 18)), lvl);
-
- } else if (fam_id == 3 && is_old_mathfont(f, total_mathex_params)) {
-
- /*tex Fix old-style |ex| parameters. */
-
- DEFINE_MATH_PARAMETERS(math_param_overbar_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_overbar_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_overbar_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_overbar_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_underbar_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_underbar_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_radical_kern, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_radical_vgap, size_id,
- (default_rule_thickness(size_id) + (abs(default_rule_thickness(size_id)) / 4)), lvl);
- DEFINE_MATH_PARAMETERS(math_param_stack_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_stack_vgap, size_id,
- 7 * default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_rule, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_num_vgap, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_num_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_fraction_denom_vgap, size_id,
- default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_fraction_denom_vgap, size_id,
- 3 * default_rule_thickness(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_above_vgap, size_id,
- big_op_spacing1(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_vgap, size_id,
- big_op_spacing1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_above_bgap, size_id,
- big_op_spacing3(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_bgap, size_id,
- big_op_spacing3(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_above_kern, size_id,
- big_op_spacing5(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_above_kern, size_id,
- big_op_spacing5(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_vgap, size_id,
- big_op_spacing2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_vgap, size_id,
- big_op_spacing2(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_bgap, size_id,
- big_op_spacing4(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_bgap, size_id,
- big_op_spacing4(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_limit_below_kern, size_id,
- big_op_spacing5(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_limit_below_kern, size_id,
- big_op_spacing5(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_nolimit_sub_factor, size_id,
- font_MATH_par(f, NoLimitSubFactor), lvl); /* bonus */
- DEFINE_DMATH_PARAMETERS(math_param_nolimit_sub_factor, size_id,
- font_MATH_par(f, NoLimitSubFactor), lvl); /* bonus */
- DEFINE_MATH_PARAMETERS(math_param_nolimit_sup_factor, size_id,
- font_MATH_par(f, NoLimitSupFactor), lvl); /* bonus */
- DEFINE_DMATH_PARAMETERS(math_param_nolimit_sup_factor, size_id,
- font_MATH_par(f, NoLimitSupFactor), lvl); /* bonus */
- DEFINE_MATH_PARAMETERS(math_param_subsup_vgap, size_id,
- 4 * default_rule_thickness(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_subsup_vgap, size_id,
- 4 * default_rule_thickness(size_id), lvl);
-
- /*tex
-
- All of the |space_after_script|s are done in
- |finalize_math_parameters| because the \.{\\scriptspace} may have
- been altered by the user.
-
- */
-
- DEFINE_MATH_PARAMETERS(math_param_connector_overlap_min, size_id,
- 0, lvl);
- DEFINE_DMATH_PARAMETERS(math_param_connector_overlap_min, size_id,
- 0, lvl);
-
- DEFINE_MATH_PARAMETERS(math_param_under_delimiter_vgap, size_id,
- big_op_spacing2(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_under_delimiter_vgap, size_id,
- big_op_spacing2(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_under_delimiter_bgap, size_id,
- big_op_spacing4(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_under_delimiter_bgap, size_id,
- big_op_spacing4(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_over_delimiter_vgap, size_id,
- big_op_spacing1(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_over_delimiter_vgap, size_id,
- big_op_spacing1(size_id), lvl);
- DEFINE_MATH_PARAMETERS(math_param_over_delimiter_bgap, size_id,
- big_op_spacing3(size_id), lvl);
- DEFINE_DMATH_PARAMETERS(math_param_over_delimiter_bgap, size_id,
- big_op_spacing3(size_id), lvl);
-
- /*tex
-
- The display-size |radical_vgap| is done twice because it needs values
- from both the sy and the ex font.
-
- */
-
- DEFINE_DMATH_PARAMETERS(math_param_radical_vgap, size_id,
- (default_rule_thickness(size_id) + (abs(math_x_height(size_id)) / 4)), lvl);
-
- }
-}
-
-/*tex
-
- This needs to be called just at the start of |mlist_to_hlist|, for backward
- compatibility with \.{\\scriptspace}.
-
-*/
-
-static void finalize_math_parameters(void)
-{
- int saved_trace = tracing_assigns_par;
- tracing_assigns_par = 0;
- if (get_math_param(math_param_space_after_script, display_style) == undefined_math_parameter) {
- def_math_param(math_param_space_after_script, display_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, text_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, script_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, script_script_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, cramped_display_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, cramped_text_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, cramped_script_style,
- script_space_par, level_one);
- def_math_param(math_param_space_after_script, cramped_script_script_style,
- script_space_par, level_one);
- }
- tracing_assigns_par = saved_trace;
-}
-
-/*tex
-
- In order to convert mlists to hlists, i.e., noads to nodes, we need several
- subroutines that are conveniently dealt with now.
-
- Let us first introduce the macros that make it easy to get at the parameters
- and other font information. A size code, which is a multiple of 256, is added
- to a family number to get an index into the table of internal font numbers
- for each combination of family and size. (Be alert: Size codes get larger as
- the type gets smaller.)
-
-*/
-
-static const char *math_size_string(int s)
-{
- if (s == text_size)
- return "textfont";
- else if (s == script_size)
- return "scriptfont";
- else
- return "scriptscriptfont";
-}
-
-/*tex
-
- When the style changes, the following piece of program computes associated
- information:
-
-*/
-
-#define setup_cur_size(a) do { \
- if (a==script_style || a==cramped_script_style) \
- cur_size = script_size; \
- else if (a==script_script_style || a==cramped_script_script_style) \
- cur_size = script_script_size; \
- else \
- cur_size = text_size; \
-} while (0)
-
-
-/*tex
-
- A simple routine that creates a flat copy of a nucleus.
-
-*/
-
-static pointer math_clone(pointer q)
-{
- pointer x;
- if (q == null)
- return null;
- x = new_node(type(q), 0);
- reset_attributes(x, node_attr(q));
- if (type(q) == math_char_node) {
- math_fam(x) = math_fam(q);
- math_character(x) = math_character(q);
- } else {
- math_list(x) = math_list(q);
- }
- return x;
-}
-
-/*tex
-
- Here is a function that returns a pointer to a rule node having a given
- thickness |t|. The rule will extend horizontally to the boundary of the vlist
- that eventually contains it.
-
-*/
-
-static pointer do_fraction_rule(scaled t, pointer att, halfword some_rule, halfword cur_size, halfword cur_fam)
-{
- pointer p;
- if (math_rules_mode_par) {
- p = new_rule(some_rule);
- rule_math_size(p) = cur_size;
- rule_math_font(p) = fam_fnt(cur_fam, cur_size);
- } else {
- p = new_rule(normal_rule);
- }
- rule_dir(p) = math_direction_par;
- height(p) = t;
- depth(p) = 0;
- reset_attributes(p, att);
- return p;
-}
-
-/*tex
-
- The |overbar| function returns a pointer to a vlist box that consists of a
- given box |b|, above which has been placed a kern of height |k| under a
- fraction rule of thickness |t| under additional space of height |ht|.
-
-*/
-
-static pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att, halfword index, halfword cur_size, halfword cur_fam)
-{
- pointer p, q;
- p = new_kern(k);
- reset_attributes(p, att);
- couple_nodes(p,b);
- q = do_fraction_rule(t, att, index, cur_size, cur_fam);
- couple_nodes(q,p);
- p = new_kern(ht);
- reset_attributes(p, att);
- couple_nodes(p,q);
- q = vpackage(p, 0, additional, max_dimen, math_direction_par);
- reset_attributes(q, att);
- return q;
-}
-
-/*tex
-
- Here is a subroutine that creates a new box, whose list contains a single
- character, and whose width includes the italic correction for that character.
- The height or depth of the box will be negative, if the height or depth of
- the character is negative; thus, this routine may deliver a slightly
- different result than |hpack| would produce.
-
-*/
-
-static pointer char_box(internal_font_number f, int c, pointer bb)
-{
- /*tex The new box and its character node. */
- pointer b, p;
- b = new_null_box();
- if (do_new_math(f))
- width(b) = char_width(f, c);
- else
- width(b) = char_width(f, c) + char_italic(f, c);
- height(b) = char_height(f, c);
- depth(b) = char_depth(f, c);
- subtype(b) = math_char_list ;
- reset_attributes(b, bb);
- p = new_glyph(f, c);
- protect_glyph(p);
- reset_attributes(p, bb);
- list_ptr(b) = p;
- return b;
-}
-
-/*tex
-
- Another handy subroutine computes the height plus depth of a given character:
-
-*/
-
-static scaled height_plus_depth(internal_font_number f, int c)
-{
- return (char_height(f, c) + char_depth(f, c));
-}
-
-/*tex
-
- When we build an extensible character, it's handy to have the following
- subroutine, which puts a given character on top of the characters already in
- box |b|:
-
-*/
-
-static scaled stack_into_box(pointer b, internal_font_number f, int c)
-{
- /*tex New node placed into |b|: */
- pointer p, q;
- /*tex Italic gets added to width. */
- p = char_box(f, c, node_attr(b));
- if (type(b) == vlist_node) {
- try_couple_nodes(p,list_ptr(b));
- list_ptr(b) = p;
- height(b) = height(p);
- if (width(b) < width(p))
- width(b) = width(p);
- return height_plus_depth(f, c);
- } else {
- q = list_ptr(b);
- if (q == null) {
- list_ptr(b) = p;
- } else {
- while (vlink(q) != null)
- q = vlink(q);
- couple_nodes(q,p);
- }
- if (height(b) < height(p))
- height(b) = height(p);
- if (depth(b) < depth(p))
- depth(b) = depth(p);
- return char_width(f, c);
- }
-}
-
-static void stack_glue_into_box(pointer b, scaled min, scaled max) {
- halfword p = new_glue(zero_glue);
- width(p) = min;
- stretch(p) = max - min;
- if (node_attr(b) != null) {
- reset_attributes(p, node_attr(b));
- }
- if (type(b) == vlist_node) {
- try_couple_nodes(p,list_ptr(b));
- list_ptr(b) = p;
- } else {
- halfword q = list_ptr(b);
- if (q == null) {
- list_ptr(b) = p;
- } else {
- while (vlink(q) != null) {
- q = vlink(q);
- }
- couple_nodes(q,p);
- }
- }
-}
-
-/*tex
-
- \TeX's most important routine for dealing with formulas is called
- |mlist_to_hlist|. After a formula has been scanned and represented as an
- mlist, this routine converts it to an hlist that can be placed into a box or
- incorporated into the text of a paragraph. The explicit parameter |cur_mlist|
- points to the first node or noad in the given mlist (and it might be |null|);
- the parameter |penalties| is |true| if penalty nodes for potential line
- breaks are to be inserted into the resulting hlist, the parameter |cur_style|
- is a style code. After |mlist_to_hlist| has acted, |vlink(temp_head)| points
- to the translated hlist.
-
- Since mlists can be inside mlists, the procedure is recursive. And since this
- is not part of \TeX's inner loop, the program has been written in a manner
- that stresses compactness over efficiency.
-
-*/
-
-/*tex Size code corresponding to |cur_style|: */
-
-int cur_size = 0;
-
-static pointer get_delim_box(internal_font_number fnt, halfword chr, scaled v, scaled min_overlap, int horizontal, halfword att)
-{
- int callback_id = callback_defined(make_extensible_callback);
- if (callback_id > 0) {
- /*tex
- This call is not optimized as it hardly makes sense to use it ... special
- and a it of feature creep too.
- */
- halfword b = null;
- run_callback(callback_id, "ddddbN->N",fnt,chr,v,min_overlap,horizontal,att,&b);
- if (b == null) {
- /*tex
- We see this as a signal to do it the \TEX\ way.
- */
- } else if (type(b) == hlist_node || type(b) == vlist_node) {
- return b;
- } else {
- formatted_error("fonts","invalid extensible character %i created for font %i, [h|v]list expected",chr,fnt);
- }
- }
- return make_extensible(fnt, chr, v, min_overlap, horizontal, att);
-}
-
-pointer make_extensible(internal_font_number fnt, halfword chr, scaled v, scaled min_overlap, int horizontal, halfword att)
-{
- /*tex new box */
- pointer b;
- /*tex natural (maximum) size of the stack */
- scaled b_max;
- /*tex amount of possible shrink in the stack */
- scaled s_max;
- extinfo *cur;
- extinfo *ext;
- scaled prev_overlap;
- /*tex a temporary counter number of extensible pieces */
- int i;
- /*tex number of times to repeat each repeatable item in |ext| */
- int with_extenders;
- int num_extenders, num_normal;
- scaled a, c, d;
- b = new_null_box();
- with_extenders = -1;
- num_extenders = 0;
- num_normal = 0;
- if (min_overlap < 0) {
- min_overlap = 0;
- }
- if (horizontal) {
- type(b) = (quarterword) hlist_node;
- ext = get_charinfo_hor_variants(char_info(fnt,chr));
- } else {
- type(b) = (quarterword) vlist_node;
- ext = get_charinfo_vert_variants(char_info(fnt,chr));
- }
- if (att != null) {
- reset_attributes(b,att);
- }
- cur = ext;
- while (cur != NULL) {
- if (!char_exists(fnt, cur->glyph)) {
- const char *hlp[] = {
- "Each glyph part in an extensible item should exist in the font.",
- "I will give up trying to find a suitable size for now. Fix your font!",
- NULL
- };
- tex_error("Variant part doesn't exist.", hlp);
- width(b) = null_delimiter_space_par;
- return b;
- }
- if (cur->extender > 0)
- num_extenders++;
- else
- num_normal++;
- /*tex No negative overlaps or advances are allowed. */
- if (cur->start_overlap < 0 || cur->end_overlap < 0 || cur->advance < 0) {
- const char *hlp[] = {
- "All measurements in extensible items should be positive.",
- "To get around this problem, I have changed the font metrics.",
- "Fix your font!",
- NULL
- };
- tex_error("Extensible recipe has negative fields.", hlp);
- if (cur->start_overlap < 0)
- cur->start_overlap = 0;
- if (cur->end_overlap < 0)
- cur->end_overlap = 0;
- if (cur->advance < 0)
- cur->advance = 0;
- }
- cur = cur->next;
- }
- if (num_normal == 0) {
- const char *hlp[] = {
- "Each extensible recipe should have at least one non-repeatable part.",
- "To get around this problem, I have changed the first part to be",
- "non-repeatable. Fix your font!",
- NULL
- };
- tex_error("Extensible recipe has no fixed parts.", hlp);
- ext->extender = 0;
- num_normal = 1;
- num_extenders--;
- }
- /*tex
-
- |ext| holds a linked list of numerous items that may or may not be
- repeatable. For the total height, we have to figure out how many items
- are needed to create a stack of at least |v|.
-
- The next |while| loop does that. It has two goals: it finds out the
- natural height |b_max| of the all the parts needed to reach at least |v|,
- and it sets |with_extenders| to the number of times each of the
- repeatable items in |ext| has to be repeated to reach that height.
-
- */
- cur = ext;
- b_max = 0;
- while (b_max < v && num_extenders > 0) {
- b_max = 0;
- prev_overlap = 0;
- with_extenders++;
- for (cur = ext; cur != NULL; cur = cur->next) {
- if (cur->extender == 0) {
- c = cur->start_overlap;
- if (min_overlap < c)
- c = min_overlap;
- if (prev_overlap < c)
- c = prev_overlap;
- a = cur->advance;
- if (a == 0) {
- /*tex for tfm fonts */
- if (horizontal) {
- a = char_width(fnt, cur->glyph);
- } else {
- a = height_plus_depth(fnt, cur->glyph);
- }
- if (a < 0) {
- formatted_error("fonts","bad extensible character %i in font %i",chr,fnt);
- }
- }
- b_max += a - c;
- prev_overlap = cur->end_overlap;
- } else {
- i = with_extenders;
- while (i > 0) {
- c = cur->start_overlap;
- if (min_overlap < c)
- c = min_overlap;
- if (prev_overlap < c)
- c = prev_overlap;
- a = cur->advance;
- if (a == 0) {
- /*tex for tfm fonts */
- if (horizontal) {
- a = char_width(fnt, cur->glyph);
- } else {
- a = height_plus_depth(fnt, cur->glyph);
- }
- if (a < 0) {
- formatted_error("fonts","bad extensible character %i in font %i",chr,fnt);
- }
- }
- b_max += a - c;
- prev_overlap = cur->end_overlap;
- i--;
- }
- }
- }
- }
- /*tex
-
- Assemble box using |with_extenders| copies of each extender, with
- appropriate glue wherever an overlap occurs.
-
- */
- prev_overlap = 0;
- b_max = 0;
- s_max = 0;
- for (cur = ext; cur != NULL; cur = cur->next) {
- if (cur->extender == 0) {
- c = cur->start_overlap;
- if (prev_overlap < c)
- c = prev_overlap;
- d = c;
- if (min_overlap < c)
- c = min_overlap;
- if (d > 0) {
- stack_glue_into_box(b, -d, -c);
- s_max += (-c) - (-d);
- b_max -= d;
- }
- b_max += stack_into_box(b, fnt, cur->glyph);
- prev_overlap = cur->end_overlap;
- i--;
- } else {
- i = with_extenders;
- while (i > 0) {
- c = cur->start_overlap;
- if (prev_overlap < c)
- c = prev_overlap;
- d = c;
- if (min_overlap < c)
- c = min_overlap;
- if (d > 0) {
- stack_glue_into_box(b, -d, -c);
- s_max += (-c) - (-d);
- b_max -= d;
- }
- b_max += stack_into_box(b, fnt, cur->glyph);
- prev_overlap = cur->end_overlap;
- i--;
- }
- }
- }
- /*tex Set glue so as to stretch the connections if needed. */
- d = 0;
- if (v > b_max && s_max > 0) {
- d = v-b_max;
- /*tex Don't stretch more than |s_max|. */
- if (d > s_max)
- d = s_max;
- glue_order(b) = normal;
- glue_sign(b) = stretching;
- glue_set(b) = unfloat(d/(float) s_max);
- b_max += d;
- }
- if (horizontal) {
- width(b) = b_max;
- subtype(b) = math_h_extensible_list;
- } else {
- height(b) = b_max;
- subtype(b) = math_v_extensible_list;
- }
- return b;
-}
-
-/*tex
-
- The |var_delimiter| function, which finds or constructs a sufficiently large
- delimiter, is the most interesting of the auxiliary functions that currently
- concern us. Given a pointer |d| to a delimiter field in some noad, together
- with a size code |s| and a vertical distance |v|, this function returns a
- pointer to a box that contains the smallest variant of |d| whose height plus
- depth is |v| or more. (And if no variant is large enough, it returns the
- largest available variant.) In particular, this routine will construct
- arbitrarily large delimiters from extensible components, if |d| leads to such
- characters.
-
- The value returned is a box whose |shift_amount| has been set so that the box
- is vertically centered with respect to the axis in the given size. If a
- built-up symbol is returned, the height of the box before shifting will be
- the height of its topmost component.
-
-*/
-
-static void endless_loop_error(internal_font_number g, int y)
-{
- char s[256];
- const char *hlp[] = {
- "You managed to create a seemingly endless charlist chain in the current",
- "font. I have counted until 10000 already and still have not escaped, so"
- "I will jump out of the loop all by myself now. Fix your font!",
- NULL
- };
- snprintf(s, 256, "Math error: endless loop in charlist (U+%04x in %s)", (int) y, font_name(g));
- tex_error(s, hlp);
-}
-
-static pointer do_delimiter(pointer q, pointer d, int s, scaled v, boolean flat, int cur_style, boolean shift, boolean *stack, scaled *delta, int *same)
-{
- /*tex the box that will be constructed */
- pointer b;
- /*tex best-so-far and tentative font codes */
- internal_font_number f, g;
- /*tex best-so-far and tentative character codes */
- int c, i, x, y;
- /*tex height-plus-depth of a tentative character */
- scaled u;
- /*tex largest height-plus-depth so far */
- scaled w = 0;
- /*tex runs through font family members */
- int z;
- /*tex are we trying the ``large'' variant? */
- boolean large_attempt = false;
- /*tex to save the current attribute list */
- pointer att = null;
- int emas = 0 ;
- boolean do_parts = false;
- boolean parts_done = false;
- extinfo *ext;
-
- if (d && ! small_fam(d) && ! large_fam(d) && ! small_char(d) && ! large_char(d)) {
- halfword b = new_null_box();
- subtype(b) = math_v_delimiter_list;
- if (! flat)
- width(b) = null_delimiter_space_par;
- node_attr(b) = node_attr(d);
- node_attr(d) = null;
- flush_node(d);
- return b;
- }
-
- f = null_font;
- c = 0;
- if (d == null) {
- goto FOUND;
- }
- z = small_fam(d);
- x = small_char(d);
- i = 0;
- if (same != NULL) {
- emas = *same ;
- same = 0;
- }
- while (true) {
- /*tex
-
- The search process is complicated slightly by the facts that some of
- the characters might not be present in some of the fonts, and they
- might not be probed in increasing order of height.
-
- */
- if ((z != 0) || (x != 0)) {
- g = fam_fnt(z, s);
- if (g != null_font) {
- y = x;
- CONTINUE:
- i++;
- if (char_exists(g, y)) {
- if (flat)
- u = char_width(g, y);
- else
- u = height_plus_depth(g, y);
- if (u > w) {
- f = g;
- c = y;
- w = u;
- if (u >= v)
- goto FOUND;
- }
- if (char_tag(g, y) == ext_tag) {
- f = g;
- c = y;
- do_parts = true;
- goto FOUND;
- }
- if (i > 10000) {
- endless_loop_error(g, y);
- goto FOUND;
- }
- if (char_tag(g, y) == list_tag) {
- y = char_remainder(g, y);
- goto CONTINUE;
- }
- }
- }
- }
- if (large_attempt) {
- /*tex There were none large enough. */
- goto FOUND;
- }
- large_attempt = true;
- z = large_fam(d);
- x = large_char(d);
- }
- FOUND:
- if (d != null) {
- att = node_attr(d);
- node_attr(d) = null;
- flush_node(d);
- }
- if (f != null_font) {
- /*tex
-
- When the following code is executed, |do_parts| will be true if a
- built-up symbol is supposed to be returned.
-
- */
- ext = NULL;
- if ((do_parts) && ((!flat && (ext = get_charinfo_vert_variants(char_info(f,c))) != NULL)
- || ( flat && (ext = get_charinfo_hor_variants (char_info(f,c))) != NULL))) {
- parts_done = true;
- if (flat) {
- b = get_delim_box(f, c, v, connector_overlap_min(cur_style), 1, att);
- } else {
- b = get_delim_box(f, c, v, connector_overlap_min(cur_style), 0, att);
- }
- if (delta != NULL) {
- if (do_new_math(f)) {
- *delta = char_vert_italic(f,x);
- } else {
- *delta = char_italic(f,x);
- }
- }
- if (stack != NULL)
- *stack = true ;
- } else {
- parts_done = false;
- if (same != NULL && x == c) {
- *same = emas;
- }
- /*tex
- Here italic is added to width in traditional fonts which makes the delimiter get
- the real width. An \OPENTYPE\ font already has the right width.
- */
- b = char_box(f, c, att);
- /*tex
- There is one case where |delta| (ic) gets subtracted but only for a traditional
- font. In that case the traditional width (which is fake width + italic) becomes
- less and the delta is added. See (**). (On the mailing list font |ntxexx| was
- mentioned as test case by MK.)
- */
- if (delta != NULL) {
- *delta = char_italic(f, c);
- }
- if (stack != NULL)
- *stack = false ;
- }
- } else {
- b = new_null_box();
- reset_attributes(b, att);
- if (flat) {
- width(b) = 0;
- subtype(b) = math_h_delimiter_list;
- } else {
- /*tex Use this width if no delimiter was found. */
- width(b) = null_delimiter_space_par;
- subtype(b) = math_v_delimiter_list;
- }
- if (delta != NULL) {
- *delta = 0;
- }
- if (stack != NULL)
- *stack = false ;
- }
- if (!flat) {
- /*tex when emas ~= 0 then we have a non scaled character */
- if (emas != 0 && delimitermodesamenos) {
- /*tex same character and no shift when same forced */
- goto DONE;
- }
- if (! parts_done && delimitermodecharnos) {
- /*tex same character and no shift when same forced */
- goto DONE;
- }
- if (delimitermodenoshift) {
- /*tex no shift forced */
- goto DONE;
- }
- /*tex vertical variant */
- shift_amount(b) = half(height(b) - depth(b));
- if (shift) {
- shift_amount(b) -= math_axis_size(s);
- }
- }
- DONE:
- delete_attribute_ref(att);
- return b;
-}
-
-/*tex
-
- The next subroutine is much simpler; it is used for numerators and
- denominators of fractions as well as for displayed operators and their limits
- above and below. It takes a given box~|b| and changes it so that the new box
- is centered in a box of width~|w|. The centering is done by putting \.{\\hss}
- glue at the left and right of the list inside |b|, then packaging the new
- box; thus, the actual box might not really be centered, if it already
- contains infinite glue.
-
- The given box might contain a single character whose italic correction has
- been added to the width of the box; in this case a compensating kern is
- inserted.
-
-*/
-
-static pointer rebox(pointer b, scaled w)
-{
- /*tex temporary registers for list manipulation */
- pointer p, q, r, att;
- /*tex font in a one-character box */
- internal_font_number f;
- /*tex width of a character without italic correction */
- scaled v;
- if ((width(b) != w) && (list_ptr(b) != null)) {
- if (type(b) == vlist_node) {
- p = hpack(b, 0, additional, -1);
- reset_attributes(p, node_attr(b));
- b = p;
- }
- p = list_ptr(b);
- att = node_attr(b);
- add_node_attr_ref(att);
- if ((is_char_node(p)) && (vlink(p) == null)) {
- f = font(p);
- v = char_width(f, character(p));
- if (v != width(b)) {
- q = new_kern(width(b) - v);
- reset_attributes(q, att);
- couple_nodes(p,q);
- }
- }
- list_ptr(b) = null;
- flush_node(b);
- b = new_glue(ss_glue);
- reset_attributes(b, att);
- couple_nodes(b,p);
- while (vlink(p) != null)
- p = vlink(p);
- q = new_glue(ss_glue);
- reset_attributes(q, att);
- couple_nodes(p,q);
- r = hpack(b, w, exactly, -1);
- reset_attributes(r, att);
- delete_attribute_ref(att);
- return r;
- } else {
- width(b) = w;
- return b;
- }
-}
-
-/*tex
-
- Here is a subroutine that creates a new glue specification from another one
- that is expressed in `\.{mu}', given the value of the math unit.
-
-*/
-
-#define mu_mult(A) mult_and_add(n,(A),xn_over_d((A),f,unity),max_dimen)
-
-static pointer math_glue(pointer g, scaled m)
-{
- /*tex integer part of |m| */
- int n = x_over_n(m, unity);
- /*tex fraction part of |m| */
- scaled f = tex_remainder;
- /*tex the new glue specification */
- pointer p;
- if (f < 0) {
- decr(n);
- f = f + unity;
- }
- p = new_node(glue_node, 0);
- /* convert \.{mu} to \.{pt} */
- width(p) = mu_mult(width(g));
- stretch_order(p) = stretch_order(g);
- if (stretch_order(p) == normal)
- stretch(p) = mu_mult(stretch(g));
- else
- stretch(p) = stretch(g);
- shrink_order(p) = shrink_order(g);
- if (shrink_order(p) == normal)
- shrink(p) = mu_mult(shrink(g));
- else
- shrink(p) = shrink(g);
- return p;
-}
-
-static void math_glue_to_glue(pointer p, scaled m)
-{
- /*tex integer part of |m| */
- int n = x_over_n(m, unity);
- /*tex fraction part of |m| */
- scaled f = tex_remainder;
- if (f < 0) {
- decr(n);
- f = f + unity;
- }
- /* convert \.{mu} to \.{pt} */
- width(p) = mu_mult(width(p));
- if (stretch_order(p) == normal)
- stretch(p) = mu_mult(stretch(p));
- if (shrink_order(p) == normal)
- shrink(p) = mu_mult(shrink(p));
- subtype(p) = normal;
-}
-
-/*tex
-
- The |math_kern| subroutine removes |mu_glue| from a kern node, given the
- value of the math unit.
-
-*/
-static void math_kern(pointer p, scaled m)
-{
- /*tex integer part of |m| */
- int n;
- /*tex fraction part of |m| */
- scaled f;
- if (subtype(p) == mu_glue) {
- n = x_over_n(m, unity);
- f = tex_remainder;
- if (f < 0) {
- decr(n);
- f = f + unity;
- }
- width(p) = mu_mult(width(p));
- /* this is weird, it's not a italic but explicit_kern */
- subtype(p) = italic_kern;
- }
-}
-
-void run_mlist_to_hlist(halfword p, boolean penalties, int mstyle)
-{
- int callback_id;
- int a, sfix, i;
- if (p == null) {
- vlink(temp_head) = null;
- return;
- }
- finalize_math_parameters();
- callback_id = callback_defined(mlist_to_hlist_callback);
- if (callback_id > 0) {
- sfix = lua_gettop(Luas);
- if (!get_callback(Luas, callback_id)) {
- lua_settop(Luas, sfix);
- return;
- }
- alink(p) = null ;
- nodelist_to_lua(Luas, p);
- lua_push_math_style_name(Luas, mstyle);
- lua_pushboolean(Luas, penalties);
- if ((i=lua_pcall(Luas, 3, 1, 0)) != 0) {
- formatted_warning("mlist to hlist","error: %s",lua_tostring(Luas, -1));
- lua_settop(Luas, sfix);
- luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
- return;
- }
- a = nodelist_from_lua(Luas,-1);
- /* alink(vlink(a)) = null; */
- vlink(temp_head) = a;
- lua_settop(Luas, sfix);
- } else if (callback_id == 0) {
- mlist_to_hlist(p, penalties, mstyle);
- } else {
- vlink(temp_head) = null;
- }
-}
-
-/*tex
-
- The recursion in |mlist_to_hlist| is due primarily to a subroutine called
- |clean_box| that puts a given noad field into a box using a given math style;
- |mlist_to_hlist| can call |clean_box|, which can call |mlist_to_hlist|.
-
- The box returned by |clean_box| is ``clean'' in the sense that its
- |shift_amount| is zero.
-
-*/
-
-static pointer clean_box(pointer p, int s, int cur_style, halfword st)
-{
- /*tex beginning of a list to be boxed */
- pointer q;
- /*tex box to be returned */
- pointer x;
- /*tex temporary pointer */
- pointer r;
- /*tex beginning of mlist to be translated */
- pointer mlist = null;
- switch (type(p)) {
- case math_char_node:
- mlist = new_noad();
- r = math_clone(p);
- nucleus(mlist) = r;
- break;
- case sub_box_node:
- q = math_list(p);
- goto FOUND;
- break;
- case sub_mlist_node:
- mlist = math_list(p);
- break;
- default:
- q = new_null_box();
- subtype(q) = math_list_list;
- goto FOUND;
- }
- mlist_to_hlist(mlist, false, s);
- /*tex recursive call */
- q = vlink(temp_head);
- setup_cur_size(cur_style);
- FOUND:
- if (is_char_node(q) || (q == null))
- x = hpack(q, 0, additional, -1);
- else if ((vlink(q) == null) && (type(q) <= vlist_node) && (shift_amount(q) == 0))
- /*tex It's already clean. */
- x = q;
- else
- x = hpack(q, 0, additional, -1);
- if (x != q && q != null)
- reset_attributes(x, node_attr(q));
- subtype(x) = st;
- /*tex Here we save memory space in a common case. */
- q = list_ptr(x);
- if (is_char_node(q)) {
- r = vlink(q);
- if (r != null) {
- if (vlink(r) == null) {
- if (!is_char_node(r)) {
- if (type(r) == kern_node) {
- /*tex Unneeded italic correction. */
- flush_node(r);
- vlink(q) = null;
- }
- }
- }
- }
- }
- return x;
-}
-
-/*tex
-
- It is convenient to have a procedure that converts a |math_char| field to an
- ``unpacked'' form. The |fetch| routine sets |cur_f| and |cur_c| to the font
- code and character code of a given noad field. It also takes care of issuing
- error messages for nonexistent characters; in such cases,
- |char_exists(cur_f,cur_c)| will be |false| after |fetch| has acted, and the
- field will also have been reset to |null|.
-
- The outputs of |fetch| are placed in global variables.
-
-*/
-
-/*tex the |font| field of a |math_char| */
-
-internal_font_number cur_f;
-
-/*tex the |character| field of a |math_char| */
-
-int cur_c;
-
-/*tex Here we unpack the |math_char| field |a|. */
-
-static void fetch(pointer a)
-{
- cur_c = math_character(a);
- cur_f = fam_fnt(math_fam(a), cur_size);
- if (cur_f == null_font) {
- char *msg;
- const char *hlp[] = {
- "Somewhere in the math formula just ended, you used the",
- "stated character from an undefined font family. For example,",
- "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed,",
- "and I'll try to forget that I needed that character.",
- NULL
- };
- msg = xmalloc(256);
- snprintf(msg, 255, "\\%s%d is undefined (character %d)",
- math_size_string(cur_size), (int) math_fam(a), (int) cur_c);
- tex_error(msg, hlp);
- free(msg);
- } else if (!(char_exists(cur_f, cur_c))) {
- char_warning(cur_f, cur_c);
- }
-}
-
-/*tex
-
- We need to do a lot of different things, so |mlist_to_hlist| makes two passes
- over the given mlist.
-
- The first pass does most of the processing: It removes ``mu'' spacing from
- glue, it recursively evaluates all subsidiary mlists so that only the
- top-level mlist remains to be handled, it puts fractions and square roots and
- such things into boxes, it attaches subscripts and superscripts, and it
- computes the overall height and depth of the top-level mlist so that the size
- of delimiters for a |fence_noad| will be known. The hlist resulting from each
- noad is recorded in that noad's |new_hlist| field, an integer field that
- replaces the |nucleus| or |thickness|.
-
- The second pass eliminates all noads and inserts the correct glue and
- penalties between nodes.
-
-*/
-
-static void assign_new_hlist(pointer q, pointer r)
-{
- switch (type(q)) {
- case fraction_noad:
- math_list(numerator(q)) = null;
- flush_node(numerator(q));
- numerator(q) = null;
- math_list(denominator(q)) = null;
- flush_node(denominator(q));
- denominator(q) = null;
- break;
- case radical_noad:
- case simple_noad:
- case accent_noad:
- if (nucleus(q) != null) {
- math_list(nucleus(q)) = null;
- flush_node(nucleus(q));
- nucleus(q) = null;
- }
- break;
- }
- new_hlist(q) = r;
-}
-
-#define choose_mlist(A) do { p=A(q); A(q)=null; } while (0)
-
-/*tex
-
- Most of the actual construction work of |mlist_to_hlist| is done by
- procedures with names like |make_fraction|, |make_radical|, etc. To
- illustrate the general setup of such procedures, let's begin with a couple of
- simple ones.
-
-*/
-
-static void make_over(pointer q, int cur_style, int cur_size, int cur_fam)
-{
- /*tex
-
- No rule adaption yet, maybe never as overbars should be proper
- extensibles.
-
- */
- pointer p;
- scaled f, t;
- scaled used_thickness = overbar_rule(cur_style);
- scaled used_fam = cur_fam;
- if (math_rule_thickness_mode_par > 0) {
- f = noad_fam(q);
- if (f >= 0) {
- t = fam_fnt(f,cur_size);
- if (do_new_math(t)) {
- t = font_MATH_par(t, OverbarRuleThickness);
- if (t != undefined_math_parameter) {
- used_thickness = t;
- used_fam = f;
- }
- }
- }
- }
- p = overbar(clean_box(nucleus(q), cramped_style(cur_style), cur_style, math_nucleus_list),
- overbar_vgap(cur_style), used_thickness, overbar_kern(cur_style),
- node_attr(nucleus(q)), math_over_rule, cur_size, used_fam);
- subtype(p) = math_over_list;
- math_list(nucleus(q)) = p;
- type(nucleus(q)) = sub_box_node;
-}
-
-static void make_under(pointer q, int cur_style, int cur_size, int cur_fam)
-{
- /*tex
-
- No rule adaption yet, maybe never as underbars should be proper
- extensibles.
-
- */
- /*tex temporary registers for box construction */
- pointer p, x, y, r;
- /*tex overall height plus depth */
- scaled delta;
- scaled f, t;
- scaled used_thickness = underbar_rule(cur_style);
- scaled used_fam = cur_fam;
- x = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- p = new_kern(underbar_vgap(cur_style));
- reset_attributes(p, node_attr(q));
- couple_nodes(x,p);
- if (math_rule_thickness_mode_par > 0) {
- f = noad_fam(q);
- if (f >= 0) {
- t = fam_fnt(f,cur_size);
- if (do_new_math(t)) {
- t = font_MATH_par(t, UnderbarRuleThickness);
- if (t != undefined_math_parameter) {
- used_thickness = t;
- used_fam = f;
- }
- }
- }
- }
- r = do_fraction_rule(used_thickness, node_attr(q), math_under_rule, cur_size, used_fam);
- couple_nodes(p,r);
- y = vpackage(x, 0, additional, max_dimen, math_direction_par);
- reset_attributes(y, node_attr(q));
- subtype(y) = math_under_list;
- delta = height(y) + depth(y) + underbar_kern(cur_style);
- height(y) = height(x);
- depth(y) = delta - height(y);
- math_list(nucleus(q)) = y;
- type(nucleus(q)) = sub_box_node;
-}
-
-static void make_vcenter(pointer q)
-{
- /*tex the box that should be centered vertically */
- pointer v;
- /*tex its height plus depth */
- scaled delta;
- v = math_list(nucleus(q));
- if (type(v) != vlist_node)
- confusion("vcenter");
- delta = height(v) + depth(v);
- height(v) = math_axis_size(cur_size) + half(delta);
- depth(v) = delta - height(v);
-}
-
-/*tex
-
- According to the rules in the \.{DVI} file specifications, we ensure
- alignment between a square root sign and the rule above its nucleus by
- assuming that the baseline of the square-root symbol is the same as the
- bottom of the rule. The height of the square-root symbol will be the
- thickness of the rule, and the depth of the square-root symbol should exceed
- or equal the height-plus-depth of the nucleus plus a certain minimum
- clearance~|psi|. The symbol will be placed so that the actual clearance is
- |psi| plus half the excess.
-
-*/
-
-static void make_hextension(pointer q, int cur_style)
-{
- pointer e, p;
- halfword w;
- boolean stack = false;
- e = do_delimiter(q, left_delimiter(q), cur_size, radicalwidth(q), true, cur_style, true, &stack, NULL, NULL);
- w = width(e);
- if (!stack&& (radicalwidth(q) != 0) && (radicalwidth(q) != width(e))) {
- if (radicalmiddle(q)) {
- p = new_kern(half(radicalwidth(q)-w));
- reset_attributes(p, node_attr(q));
- couple_nodes(p,e);
- e = p;
- w = radicalwidth(q);
- } else if (radicalexact(q)) {
- w = radicalwidth(q);
- }
- }
- e = hpack(e, 0, additional, -1);
- width(e) = w ;
- reset_attributes(e, node_attr(q));
- math_list(nucleus(q)) = e;
- left_delimiter(q) = null;
-}
-
-static void make_radical(pointer q, int cur_style)
-{
- /*tex temporary registers for box construction */
- pointer x, y, p, l1, l2;
- /*tex dimensions involved in the calculation */
- scaled delta, clr, theta, h, f;
- scaled t, used_fam ;
- x = clean_box(nucleus(q), cramped_style(cur_style), cur_style, math_nucleus_list);
- clr = radical_vgap(cur_style);
- theta = radical_rule_par(cur_style);
- used_fam = small_fam(left_delimiter(q));
- /*tex
-
- We can take the rule width from the fam/style of the delimiter or use the
- most recent math parameters value.
-
- */
- if (math_rule_thickness_mode_par > 0) {
- f = small_fam(left_delimiter(q));
- if (f >= 0) {
- t = fam_fnt(f,cur_size);
- if (do_new_math(t)) {
- t = font_MATH_par(t, RadicalRuleThickness);
- if (t != undefined_math_parameter) {
- theta = t;
- used_fam = f;
- }
- }
- }
- }
- if (theta == undefined_math_parameter) {
- /*tex a real radical */
- theta = fraction_rule(cur_style);
- y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL);
- /*tex
-
- If |y| is a composite then set |theta| to the height of its top
- character, else set it to the height of |y|.
-
- */
- l1 = list_ptr(y);
- if ((l1 != null) && (type(l1) == hlist_node)) {
- /*tex possible composite */
- l2 = list_ptr(l1);
- if ((l2 != null) && (type(l2) == glyph_node)) {
- /*tex top character */
- theta = char_height(font(l2), character(l2));
- } else {
- theta = height(y);
- }
- } else {
- theta = height(y);
- }
- } else {
- /*tex
-
- Not really a radical but we use its node, historical sharing (like in
- mathml).
-
- */
- y = do_delimiter(q, left_delimiter(q), cur_size, height(x) + depth(x) + clr + theta, false, cur_style, true, NULL, NULL, NULL);
- }
- /*tex
-
- Weird hack, in overbar we use small_fam(left_delimiter(q)) so actually
- small_fam(0).
-
- */
- left_delimiter(q) = null;
- delta = (depth(y) + height(y) - theta) - (height(x) + depth(x) + clr);
- if (delta > 0) {
- /*tex increase the actual clearance */
- clr = clr + half(delta);
- }
- shift_amount(y) = (height(y) - theta) - (height(x) + clr);
- h = depth(y) + height(y);
- p = overbar(x, clr, theta, radical_kern(cur_style), node_attr(y), math_radical_rule, cur_size, used_fam);
- subtype(p) = math_radical_list;
- couple_nodes(y,p);
- if (degree(q) != null) {
- scaled wr, br, ar;
- pointer r = clean_box(degree(q), script_script_style, cur_style, math_degree_list);
- reset_attributes(r, node_attr(degree(q)));
- wr = width(r);
- if (wr == 0) {
- flush_node(r);
- } else {
- br = radical_degree_before(cur_style);
- ar = radical_degree_after(cur_style);
- if (-ar > (wr + br))
- ar = -(wr + br);
- x = new_kern(ar);
- reset_attributes(x, node_attr(degree(q)));
- couple_nodes(x,y);
- shift_amount(r) =
- -((xn_over_d(h, radical_degree_raise(cur_style), 100)) -
- depth(y) - shift_amount(y));
- couple_nodes(r,x);
- x = new_kern(br);
- reset_attributes(x, node_attr(degree(q)));
- couple_nodes(x,r);
- y = x;
- }
- /*tex for \.{\\Uroot ..{<list>}{}} : */
- math_list(degree(q)) = null;
- flush_node(degree(q));
- }
- p = hpack(y, 0, additional, -1);
- reset_attributes(p, node_attr(q));
- math_list(nucleus(q)) = p;
- type(nucleus(q)) = sub_box_node;
-}
-
-/*tex Construct a vlist box: */
-
-static pointer wrapup_over_under_delimiter(pointer x, pointer y, pointer q, scaled shift_up, scaled shift_down, halfword st)
-{
- pointer p;
- pointer v = new_null_box();
- type(v) = vlist_node;
- subtype(v) = st;
- height(v) = shift_up + height(x);
- depth(v) = depth(y) + shift_down;
- reset_attributes(v, node_attr(q));
- p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));
- reset_attributes(p, node_attr(q));
- couple_nodes(p,y);
- couple_nodes(x,p);
- list_ptr(v) = x;
- return v;
-}
-
-/*tex When |exact| use radicalwidth (|y| is delimiter). */
-
-#define fixup_widths(q,x,y) do { \
- if (width(y) >= width(x)) { \
- if (radicalwidth(q) != 0) { \
- shift_amount(x) += half(width(y)-width(x)) ; \
- } \
- width(x) = width(y); \
- } else { \
- if (radicalwidth(q) != 0) { \
- shift_amount(y) += half(width(x)-width(y)) ; \
- } \
- width(y) = width(x); \
- } \
-} while (0)
-
-
-#define check_radical(q,stack,r,t) do { \
- if (!stack && (width(r) >= width(t)) && (radicalwidth(q) != 0) && (radicalwidth(q) != width(r))) { \
- if (radicalleft(q)) { \
- halfword p = new_kern(radicalwidth(q)-width(r)); \
- reset_attributes(p, node_attr(q)); \
- couple_nodes(p,r); \
- r = hpack(p, 0, additional, -1); \
- width(r) = radicalwidth(q); \
- reset_attributes(r, node_attr(q)); \
- } else if (radicalmiddle(q)) { \
- halfword p = new_kern(half(radicalwidth(q)-width(r))); \
- reset_attributes(p, node_attr(q)); \
- couple_nodes(p,r); \
- r = hpack(p, 0, additional, -1); \
- width(r) = radicalwidth(q); \
- reset_attributes(r, node_attr(q)); \
- } else if (radicalright(q)) { \
- /*tex also kind of exact compared to vertical */ \
- r = hpack(r, 0, additional, -1); \
- width(r) = radicalwidth(q); \
- reset_attributes(r, node_attr(q)); \
- } \
- } \
-} while (0)
-
-#define check_widths(q,p) do { \
- if (radicalwidth(q) != 0) { \
- wd = radicalwidth(q); \
- } else { \
- wd = width(p); \
- } \
-} while (0)
-
-/*tex
-
- This has the |nucleus| box |x| as a limit above an extensible delimiter |y|.
-
-*/
-
-static void make_over_delimiter(pointer q, int cur_style)
-{
- pointer x, y, v;
- scaled shift_up, shift_down, clr, delta, wd;
- boolean stack;
- x = clean_box(nucleus(q), sub_style(cur_style), cur_style, math_nucleus_list);
- check_widths(q,x);
- y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL);
- left_delimiter(q) = null;
- check_radical(q,stack,y,x);
- fixup_widths(q, x, y);
- shift_up = over_delimiter_bgap(cur_style);
- shift_down = 0;
- clr = over_delimiter_vgap(cur_style);
- delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
- if (delta > 0) {
- shift_up = shift_up + delta;
- }
- v = wrapup_over_under_delimiter(x, y, q, shift_up, shift_down, math_over_delimiter_list);
- /*tex This also equals |width(y)|: */
- width(v) = width(x);
- math_list(nucleus(q)) = v;
- type(nucleus(q)) = sub_box_node;
-}
-
-/*tex
-
- This has the extensible delimiter |x| as a limit below |nucleus| box |y|.
-
-*/
-
-static void make_under_delimiter(pointer q, int cur_style)
-{
- pointer x, y, v;
- scaled shift_up, shift_down, clr, delta, wd;
- boolean stack;
- y = clean_box(nucleus(q), sup_style(cur_style), cur_style, math_nucleus_list);
- check_widths(q,y);
- x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL);
- left_delimiter(q) = null;
- check_radical(q,stack,x,y);
- fixup_widths(q, x, y);
- shift_up = 0;
- shift_down = under_delimiter_bgap(cur_style);
- clr = under_delimiter_vgap(cur_style);
- delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
- if (delta > 0) {
- shift_down = shift_down + delta;
- }
- v = wrapup_over_under_delimiter(x, y, q, shift_up, shift_down, math_under_delimiter_list);
- /*tex This also equals |width(y)|: */
- width(v) = width(y);
- math_list(nucleus(q)) = v;
- type(nucleus(q)) = sub_box_node;
-}
-
-/*tex
-
- This has the extensible delimiter |x| as a limit above |nucleus| box |y|.
-
-*/
-
-static void make_delimiter_over(pointer q, int cur_style)
-{
- pointer x, y, v;
- scaled shift_up, shift_down, clr, actual, wd;
- boolean stack;
- y = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- check_widths(q,y);
- x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL);
- left_delimiter(q) = null;
- check_radical(q,stack,x,y);
- fixup_widths(q, x, y);
- shift_up = over_delimiter_bgap(cur_style)-height(x)-depth(x);
- shift_down = 0;
- clr = over_delimiter_vgap(cur_style);
- actual = shift_up - height(y);
- if (actual < clr) {
- shift_up = shift_up + (clr-actual);
- }
- v = wrapup_over_under_delimiter(x, y, q, shift_up, shift_down, math_over_delimiter_list);
- /*tex This also equals |width(y)|: */
- width(v) = width(x);
- math_list(nucleus(q)) = v;
- type(nucleus(q)) = sub_box_node;
-}
-
-/*tex
-
- This has the extensible delimiter |y| as a limit below a |nucleus| box |x|.
-
-*/
-
-static void make_delimiter_under(pointer q, int cur_style)
-{
- pointer x, y, v;
- scaled shift_up, shift_down, clr, actual, wd;
- boolean stack;
- x = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- check_widths(q,x);
- y = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL);
- left_delimiter(q) = null;
- check_radical(q,stack,y,x);
- fixup_widths(q, x, y);
- shift_up = 0;
- shift_down = under_delimiter_bgap(cur_style) - height(y)-depth(y);
- clr = under_delimiter_vgap(cur_style);
- actual = shift_down - depth(x);
- if (actual<clr) {
- shift_down += (clr-actual);
- }
- v = wrapup_over_under_delimiter(x, y, q, shift_up, shift_down, math_under_delimiter_list);
- /*tex This also equals |width(y)|: */
- width(v) = width(y);
- math_list(nucleus(q)) = v;
- type(nucleus(q)) = sub_box_node;
-}
-
-/*tex
-
- Slants are not considered when placing accents in math mode. The accenter is
- centered over the accentee, and the accent width is treated as zero with
- respect to the size of the final box.
-
-*/
-
-#define TOP_CODE 1
-#define BOT_CODE 2
-#define OVERLAY_CODE 4
-#define STRETCH_ACCENT_CODE 8
-
-static boolean compute_accent_skew(pointer q, int flags, scaled *s)
-{
- /*tex temporary register for box construction */
- pointer p;
- /*tex will be true if a top-accent is placed in |s| */
- boolean s_is_absolute = false;
- if (type(nucleus(q)) == math_char_node) {
- fetch(nucleus(q));
- if (do_new_math(cur_f)) {
- /*tex
- There is no bot_accent so let's assume similarity
-
- \starttyping
- if (flags & (TOP_CODE | OVERLAY_CODE)) {
- *s = char_top_accent(cur_f, cur_c);
- if (*s != INT_MIN) {
- s_is_absolute = true;
- }
- } else {
- *s = char_bot_accent(cur_f, cur_c);
- if (*s != INT_MIN) {
- s_is_absolute = true;
- }
- }
- \stoptyping
- */
- *s = char_top_accent(cur_f, cur_c);
- if (*s != INT_MIN) {
- s_is_absolute = true;
- }
- } else {
- if (flags & TOP_CODE) {
- *s = get_kern(cur_f, cur_c, skew_char(cur_f));
- } else {
- *s = 0;
- }
- }
- } else if (type(nucleus(q)) == sub_mlist_node) {
- /*tex
- If |nucleus(q)| is a |sub_mlist_node| composed of an |accent_noad| we:
-
- \startitemize
- \startitem
- use the positioning of the nucleus of that noad, recursing until
- \stopitem
- \startitem
- the inner most |accent_noad|. This way multiple stacked accents
- are
- \stopitem
- \startitem
- aligned to the inner most one.
- \stopitem
- \stoptitemize
-
- The vlink test was added in version 1.06, so that we only consider a
- lone noad:
-
- $
- \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } r } \quad
- \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } r } \quad
- \Umathaccent bottom 0 0 "023DF { l \Umathaccent fixed 0 0 "00302 { m } } \quad
- \Umathaccent bottom 0 0 "023DF { \Umathaccent fixed 0 0 "00302 { m } } \quad
- \Umathaccent bottom 0 0 "023DF { l r }
- $
-
- */
- p = math_list(nucleus(q));
- if (type(p) == accent_noad && vlink(p) == null) {
- s_is_absolute = compute_accent_skew(p, flags, s);
- }
- } else {
- }
-
- return s_is_absolute;
-}
-
-static void do_make_math_accent(pointer q, internal_font_number f, int c, int flags, int cur_style)
-{
- /*tex temporary registers for box construction */
- pointer p, r, x, y;
- /*tex amount to skew the accent to the right */
- scaled s;
- /*tex height of character being accented */
- scaled h;
- /*tex space to remove between accent and accentee */
- scaled delta;
- /*tex width of the accentee, not including sub/superscripts */
- scaled w;
- /*tex will be true if a top-accent is placed in |s| */
- boolean s_is_absolute;
- scaled fraction ;
- scaled ic = 0;
- scaled target ;
- extinfo *ext;
- pointer attr_p;
- attr_p = (flags & TOP_CODE ? top_accent_chr(q) : flags & BOT_CODE ? bot_accent_chr(q) : overlay_accent_chr(q));
- fraction = accentfraction(q);
- c = cur_c;
- f = cur_f;
- s = 1;
- if (fraction == 0) {
- fraction = 1000;
- }
- /*tex Compute the amount of skew, or set |s| to an alignment point */
- s_is_absolute = compute_accent_skew(q, flags, &s);
- x = clean_box(nucleus(q), cramped_style(cur_style), cur_style, math_nucleus_list);
- w = width(x);
- h = height(x);
- if (do_new_math(cur_f) && !s_is_absolute) {
- s = half(w);
- s_is_absolute = true;
- }
- /*tex Switch to a larger accent if available and appropriate */
- y = null;
- ext = NULL;
- if (flags & OVERLAY_CODE) {
- if (fraction > 0) {
- target = xn_over_d(h,fraction,1000);
- } else {
- target = h;
- }
- } else {
- if (fraction > 0) {
- target = xn_over_d(w,fraction,1000);
- } else {
- target = w;
- }
- }
- if ((flags & STRETCH_ACCENT_CODE) && (char_width(f, c) < w)) {
- while (1) {
- if ((char_tag(f, c) == ext_tag) && ((ext = get_charinfo_hor_variants(char_info(f, c))) != NULL)) {
- /*tex a bit weird for an overlay but anyway, here we don't need a factor as we don't step */
- y = get_delim_box(f, c, w, connector_overlap_min(cur_style), 1, node_attr(attr_p));
- break;
- } else if (char_tag(f, c) != list_tag) {
- break;
- } else {
- int yy = char_remainder(f, c);
- if (!char_exists(f, yy)) {
- break;
- } else if (flags & OVERLAY_CODE) {
- if (char_height(f, yy) > target) {
- break;
- }
- } else {
- if (char_width(f, yy) > target)
- break;
- }
- c = yy;
- }
- }
- }
- if (y == null) {
- /*tex italic gets added to width */
- y = char_box(f, c, node_attr(attr_p));
- }
- if (flags & TOP_CODE) {
- if (h < accent_base_height(f)) {
- delta = h;
- } else {
- delta = accent_base_height(f);
- }
- } else if (flags & OVERLAY_CODE) {
- /*tex center the accent vertically around the accentee */
- delta = half(height(y) + depth(y) + height(x) + depth(x));
- } else {
- delta = 0; /* hm */
- }
- if ((supscr(q) != null) || (subscr(q) != null)) {
- if (type(nucleus(q)) == math_char_node) {
- /*tex swap the subscript and superscript into box |x| */
- flush_node_list(x);
- x = new_noad();
- r = math_clone(nucleus(q));
- nucleus(x) = r;
- supscr(x) = supscr(q);
- supscr(q) = null;
- subscr(x) = subscr(q);
- subscr(q) = null;
- type(nucleus(q)) = sub_mlist_node;
- math_list(nucleus(q)) = x;
- x = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- delta = delta + height(x) - h;
- h = height(x);
- }
- } else if ((vlink(q) != null) && (type(nucleus(q)) == math_char_node)) {
- /*tex only pure math char nodes */
- internal_font_number f = fam_fnt(math_fam(nucleus(q)),cur_size);
- if (do_new_math(f)) {
- ic = char_italic(f,math_character(nucleus(q)));
- }
- }
- /*tex the top accents of both characters are aligned */
- if (s_is_absolute) {
- scaled sa;
- if (ext != NULL) {
- /*tex if the accent is extensible just take the center */
- sa = half(width(y));
- } else {
- /*tex
- There is no bot_accent so let's assume similarity
-
- \starttyping
- if (flags & BOT_CODE) {
- sa = char_bot_accent(f, c);
- } else {
- sa = char_top_accent(f, c);
- }
- \stoptyping
- */
- sa = char_top_accent(f, c);
- }
- if (sa == INT_MIN) {
- /*tex just take the center */
- sa = half(width(y));
- }
- if (math_direction_par == dir_TRT) {
- shift_amount(y) = s + sa - width(y);
- } else {
- shift_amount(y) = s - sa;
- }
- } else {
- if (width(y)== 0) {
- shift_amount(y) = s + w;
- } else if (math_direction_par == dir_TRT) {
- shift_amount(y) = s + width(y); /* ok? */
- } else {
- shift_amount(y) = s + half(w - width(y));
- }
- }
- width(y) = 0;
- if (flags & (TOP_CODE | OVERLAY_CODE)) {
- p = new_kern(-delta);
- reset_attributes(p, node_attr(q));
- couple_nodes(p,x);
- couple_nodes(y,p);
- } else {
- couple_nodes(x,y);
- y = x;
- }
- r = vpackage(y, 0, additional, max_dimen, math_direction_par);
- reset_attributes(r, node_attr(q));
- subtype(r) = math_accent_list;
- width(r) = width(x);
- y = r;
- if (flags & (TOP_CODE | OVERLAY_CODE)) {
- if (height(y) < h) {
- /*tex make the height of box |y| equal to |h| */
- p = new_kern(h - height(y));
- reset_attributes(p, node_attr(q));
- try_couple_nodes(p,list_ptr(y));
- list_ptr(y) = p;
- height(y) = h;
- }
- } else {
- shift_amount(y) = -(h - height(y));
- }
- if (ic != 0) {
- /*tex old font codepath has ic built in, new font code doesn't */
- width(r) += ic ;
- }
- math_list(nucleus(q)) = y;
- type(nucleus(q)) = sub_box_node;
-}
-
-static void make_math_accent(pointer q, int cur_style)
-{
- int topstretch = !(subtype(q) % 2);
- int botstretch = !(subtype(q) / 2);
-
- if (top_accent_chr(q) != null) {
- fetch(top_accent_chr(q));
- if (char_exists(cur_f, cur_c)) {
- do_make_math_accent(q, cur_f, cur_c, TOP_CODE | (topstretch ? STRETCH_ACCENT_CODE : 0), cur_style);
- }
- flush_node(top_accent_chr(q));
- top_accent_chr(q) = null;
- }
- if (bot_accent_chr(q) != null) {
- fetch(bot_accent_chr(q));
- if (char_exists(cur_f, cur_c)) {
- do_make_math_accent(q, cur_f, cur_c, BOT_CODE | (botstretch ? STRETCH_ACCENT_CODE : 0), cur_style);
- }
- flush_node(bot_accent_chr(q));
- bot_accent_chr(q) = null;
- }
- if (overlay_accent_chr(q) != null) {
- fetch(overlay_accent_chr(q));
- if (char_exists(cur_f, cur_c)) {
- do_make_math_accent(q, cur_f, cur_c, OVERLAY_CODE | STRETCH_ACCENT_CODE, cur_style);
- }
- flush_node(overlay_accent_chr(q));
- overlay_accent_chr(q) = null;
- }
-}
-
-/*tex
-
- The |make_fraction| procedure is a bit different because it sets
- |new_hlist(q)| directly rather than making a sub-box.
-
-*/
-
-static void make_fraction(pointer q, int cur_style)
-{
- pointer p, p1, p2, v, x, y, z, l, r, m;
- scaled delta, delta1, delta2, shift_up, shift_down, clr1, clr2, f, t;\
- /*tex
-
- We can take the rule width from an explicitly set fam, even if a fraction
- itself has no character, otherwise we just use the math parameter.
-
- */
- scaled used_fam = math_rules_fam_par;
- if (math_rule_thickness_mode_par > 0 && thickness(q) != 0) {
- f = fraction_fam(q);
- if (f >= 0) {
- t = fam_fnt(f,cur_size);
- if (do_new_math(t)) {
- t = font_MATH_par(t, FractionRuleThickness);
- if (t != undefined_math_parameter) {
- thickness(q) = t;
- used_fam = f;
- }
- }
- }
- }
- if (thickness(q) == default_code)
- thickness(q) = fraction_rule(cur_style);
- /*tex
-
- Create equal-width boxes |x| and |z| for the numerator and denominator,
- and compute the default amounts |shift_up| and |shift_down| by which they
- are displaced from the baseline.
-
- */
- x = clean_box(numerator(q), num_style(cur_style), cur_style, math_numerator_list);
- z = clean_box(denominator(q), denom_style(cur_style), cur_style, math_denominator_list);
- if (middle_delimiter(q) != null) {
- delta = 0;
- m = do_delimiter(q, middle_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL);
- middle_delimiter(q) = null;
- } else {
- m = null ;
- if (width(x) < width(z)) {
- x = rebox(x, width(z));
- } else {
- z = rebox(z, width(x));
- }
- }
- if (m != null) {
- shift_up = 0;
- shift_down = 0;
- } else if (thickness(q) == 0) {
- shift_up = stack_num_up(cur_style);
- shift_down = stack_denom_down(cur_style);
- /*tex
-
- The numerator and denominator must be separated by a certain minimum
- clearance, called |clr| in the following program. The difference
- between |clr| and the actual clearance is |2delta|.
-
- */
- clr1 = stack_vgap(cur_style);
- delta = half(clr1 - ((shift_up - depth(x)) - (height(z) - shift_down)));
- if (delta > 0) {
- shift_up = shift_up + delta;
- shift_down = shift_down + delta;
- }
- } else {
- shift_up = fraction_num_up(cur_style);
- shift_down = fraction_denom_down(cur_style);
- /*tex
-
- In the case of a fraction line, the minimum clearance depends on the
- actual thickness of the line.
-
- */
- clr1 = fraction_num_vgap(cur_style);
- clr2 = fraction_denom_vgap(cur_style);
- delta = half(thickness(q));
- if (fractionexact(q)) {
- delta1 = clr1 - ((shift_up - depth(x) ) - (math_axis_size(cur_size) + delta));
- delta2 = clr2 - ((shift_down - height(z)) + (math_axis_size(cur_size) - delta));
- } else {
- clr1 = ext_xn_over_d(clr1, thickness(q), fraction_rule(cur_style));
- clr2 = ext_xn_over_d(clr2, thickness(q), fraction_rule(cur_style));
- delta1 = clr1 - ((shift_up - depth(x) ) - (math_axis_size(cur_size) + delta));
- delta2 = clr2 - ((shift_down - height(z)) + (math_axis_size(cur_size) - delta));
- }
- if (delta1 > 0) {
- shift_up = shift_up + delta1;
- }
- if (delta2 > 0) {
- shift_down = shift_down + delta2;
- }
- }
- if (m != null) {
- /*tex
-
- Construct a hlist box for the fraction, according to |hgap| and
- |vgap|.
-
- */
- shift_up = skewed_fraction_vgap(cur_style);
-
- if (!fractionnoaxis(q)) {
- shift_up += half(math_axis_size(cur_size));
- }
- shift_down = shift_up;
- v = new_null_box();
- reset_attributes(v, node_attr(q));
- type(v) = hlist_node;
- subtype(v) = math_numerator_list;
- list_ptr(v) = x;
- width(v) = width(x);
- height(v) = height(x) + shift_up;
- depth(v) = depth(x);
- shift_amount(v) = - shift_up;
- x = v;
- v = new_null_box();
- reset_attributes(v, node_attr(q));
- type(v) = hlist_node;
- subtype(v) = math_denominator_list;
- list_ptr(v) = z;
- width(v) = width(z);
- height(v) = height(z);
- depth(v) = depth(z) + shift_down;
- shift_amount(v) = shift_down;
- z = v;
- v = new_null_box();
- subtype(v) = math_fraction_list;
- reset_attributes(v, node_attr(q));
- type(v) = hlist_node;
- if (height(x) > height(z)) {
- height(v) = height(x);
- } else {
- height(v) = height(z);
- }
- if (depth(x) > depth(z)) {
- depth(v) = depth(x);
- } else {
- depth(v) = depth(z);
- }
- if (height(m) > height(v)) {
- height(v) = height(m);
- }
- if (depth(m) > depth(v)) {
- depth(v) = depth(m);
- }
- if (fractionexact(q)) {
- delta1 = -half(skewed_fraction_hgap(cur_style));
- delta2 = delta1;
- width(v) = width(x) + width(z) + width(m) - skewed_fraction_hgap(cur_style);
- } else {
- delta1 = half(skewed_fraction_hgap(cur_style)-width(m));
- delta2 = half(skewed_fraction_hgap(cur_style)+width(m));
- width(v) = width(x) + width(z) + skewed_fraction_hgap(cur_style);
- width(m) = 0;
- }
- p1 = new_kern(delta1);
- reset_attributes(p1, node_attr(q));
- p2 = new_kern(delta2);
- reset_attributes(p2, node_attr(q));
- couple_nodes(x,p1);
- couple_nodes(p1,m);
- couple_nodes(m,p2);
- couple_nodes(p2,z);
- list_ptr(v) = x;
- } else {
- /*tex
-
- Construct a vlist box for the fraction, according to |shift_up| and
- |shift_down|.
-
- */
- v = new_null_box();
- type(v) = vlist_node;
- subtype(v) = math_fraction_list;
- height(v) = shift_up + height(x);
- depth(v) = depth(z) + shift_down;
- /*tex This also equals |width(z)|. */
- width(v) = width(x);
- reset_attributes(v, node_attr(q));
- if (thickness(q) && ! fractionnorule(q)) {
- y = do_fraction_rule(thickness(q), node_attr(q), math_fraction_rule, cur_size, used_fam);
- p = new_kern((math_axis_size(cur_size) - delta) - (height(z) - shift_down));
- reset_attributes(p, node_attr(q));
- couple_nodes(y,p);
- couple_nodes(p,z);
- p = new_kern((shift_up - depth(x)) - (math_axis_size(cur_size) + delta));
- couple_nodes(p,y);
- } else {
- p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));
- couple_nodes(p,z);
- }
- reset_attributes(p, node_attr(q));
- couple_nodes(x,p);
- list_ptr(v) = x;
- }
- /*tex
-
- Put the fraction into a box with its delimiters, and make |new_hlist(q)|
- point to it.
-
- */
- if (do_new_math(cur_f)) {
- delta = fraction_del_size_new(cur_style);
- if (delta == undefined_math_parameter) {
- delta = get_delimiter_height(depth(v), height(v), true);
- }
- } else {
- delta = fraction_del_size_old(cur_style);
- }
- l = do_delimiter(q, left_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL);
- left_delimiter(q) = null;
- r = do_delimiter(q, right_delimiter(q), cur_size, delta, false, cur_style, true, NULL, NULL, NULL);
- right_delimiter(q) = null;
- couple_nodes(l,v);
- couple_nodes(v,r);
- y = hpack(l, 0, additional, -1);
- reset_attributes(y, node_attr(q));
- /*tex There can also be a nested one: */
- subtype(y) = math_fraction_list;
- assign_new_hlist(q, y);
-}
-
-/*tex
-
- If the nucleus of an |op_noad| is a single character, it is to be centered
- vertically with respect to the axis, after first being enlarged (via a
- character list in the font) if we are in display style. The normal convention
- for placing displayed limits is to put them above and below the operator in
- display style.
-
- The italic correction is removed from the character if there is a subscript
- and the limits are not being displayed. The |make_op| routine returns the
- value that should be used as an offset between subscript and superscript.
-
- After |make_op| has acted, |subtype(q)| will be |limits| if and only if the
- limits have been set above and below the operator. In that case,
- |new_hlist(q)| will already contain the desired final box.
-
-*/
-
-static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift);
-static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same);
-
-static scaled make_op(pointer q, int cur_style)
-{
- /*tex offset between subscript and superscript */
- scaled delta = 0;
- scaled dummy = 0;
- /*tex temporary registers for box construction */
- pointer p, v, x, y, z, n;
- /*tex register for character examination */
- int c;
- /*tex dimensions for box calculation */
- scaled shift_up, shift_down;
- boolean axis_shift = false;
- scaled ok_size;
- if ((subtype(q) == op_noad_type_normal) && (cur_style < text_style)) {
- subtype(q) = op_noad_type_limits;
- }
- if (type(nucleus(q)) == math_char_node) {
- fetch(nucleus(q));
- if (cur_style < text_style) {
- /*tex try to make it larger */
- ok_size = minimum_operator_size(cur_style);
- if (ok_size != undefined_math_parameter) {
- /*tex creating a temporary delimiter is the cleanest way */
- y = new_node(delim_node, 0);
- reset_attributes(y, node_attr(nucleus(q)));
- small_fam(y) = math_fam(nucleus(q));
- small_char(y) = math_character(nucleus(q));
- x = do_delimiter(q, y, text_size, ok_size, false, cur_style, true, NULL, &delta, NULL);
- if (delta != 0) {
- if (do_new_math(cur_f)) {
- /*tex
- As we never added italic correction we don't need to compensate. The ic
- is stored in a special field of the node and applied in some occasions.
- */
- } else if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits)) {
- /*tex
- Here we (selectively) remove the italic correction that always gets added
- in a traditional font. See (**). In \OPENTYPE\ mode we insert italic kerns,
- but in traditional mode it's width manipulation. This actually makes sense
- because those fonts have a fake width and the italic correction sets that
- right.
- */
- width(x) -= delta;
- }
- }
- } else {
- ok_size = height_plus_depth(cur_f, cur_c) + 1;
- while ((char_tag(cur_f, cur_c) == list_tag) && height_plus_depth(cur_f, cur_c) < ok_size) {
- c = char_remainder(cur_f, cur_c);
- if (!char_exists(cur_f, c))
- break;
- cur_c = c;
- math_character(nucleus(q)) = c;
- }
- delta = char_italic(cur_f, cur_c);
- x = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- if (delta != 0) {
- if (do_new_math(cur_f)) {
- /*tex we never added italic correction */
- } else if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits)) {
- /*tex remove italic correction */
- width(x) -= delta;
- }
- }
- axis_shift = true;
- }
- } else {
- /*tex normal size */
- delta = char_italic(cur_f, cur_c);
- x = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- if (delta != 0) {
- if (do_new_math(cur_f)) {
- /*tex we never added italic correction */
- } else if ((subscr(q) != null) && (subtype(q) != op_noad_type_limits)) {
- /*tex remove italic correction */
- width(x) -= delta;
- }
- }
- axis_shift = true;
- }
- if (axis_shift) {
- /*tex center vertically */
- shift_amount(x) = half(height(x) - depth(x)) - math_axis_size(cur_size);
- }
- type(nucleus(q)) = sub_box_node;
- math_list(nucleus(q)) = x;
- }
- /*tex we now handle op_nod_type_no_limits here too */
- if (subtype(q) == op_noad_type_no_limits) {
- if (do_new_math(cur_f)) {
- /*tex
- Not:
-
- \starttyping
- if (delta != 0) {
- delta = half(delta) ;
- }
- \stoptyping
- */
- p = check_nucleus_complexity(q, &dummy, cur_style, NULL);
- if ((subscr(q) == null) && (supscr(q) == null)) {
- assign_new_hlist(q, p);
- } else {
- /*tex
- Not:
-
- \starttyping
- make_scripts(q, p, 0, cur_style, delta, -delta);
- \stoptyping
- */
- int mode = math_nolimits_mode_par; /* wins */
- /*tex
-
- For easy configuration ... fonts are somewhat inconsistent
- and the values for italic correction run from 30 to 60\% of.
- the width.
-
- */
- switch (mode) {
- case 0 :
- /*tex full bottom correction */
- make_scripts(q, p, 0, cur_style, 0, -delta);
- break;
- case 1 :
- /*tex |MathConstants| driven */
- make_scripts(q, p, 0, cur_style,
- round_xn_over_d(delta, nolimit_sup_factor(cur_style), 1000),
- -round_xn_over_d(delta, nolimit_sub_factor(cur_style), 1000));
- break ;
- case 2 :
- /*tex no correction */
- make_scripts(q, p, 0, cur_style, 0, 0);
- break ;
- case 3 :
- /*tex half bottom correction */
- make_scripts(q, p, 0, cur_style, 0, -half(delta));
- break;
- case 4 :
- /*tex half bottom and top correction */
- make_scripts(q, p, 0, cur_style, half(delta), -half(delta));
- break;
- default :
- if (mode > 15) {
- /*tex for quickly testing values */
- make_scripts(q, p, 0, cur_style, 0, -round_xn_over_d(delta, mode, 1000));
- } else {
- make_scripts(q, p, 0, cur_style, 0, 0);
- }
- break;
- }
- }
- delta = 0;
- } else {
- /*tex similar code then the caller (before CHECK_DIMENSIONS) */
- p = check_nucleus_complexity(q, &delta, cur_style, NULL);
- if ((subscr(q) == null) && (supscr(q) == null)) {
- assign_new_hlist(q, p);
- } else {
- make_scripts(q, p, delta, cur_style, 0, 0);
- }
- }
- } else if (subtype(q) == op_noad_type_limits) {
- /*tex
-
- The following program builds a vlist box |v| for displayed limits.
- The width of the box is not affected by the fact that the limits may
- be skewed.
-
- */
- x = clean_box(supscr(q), sup_style(cur_style), cur_style, math_sup_list);
- y = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list);
- z = clean_box(subscr(q), sub_style(cur_style), cur_style, math_sub_list);
- v = new_null_box();
- reset_attributes(v, node_attr(q));
- type(v) = vlist_node;
- subtype(v) = math_limits_list;
- if (do_new_math(cur_f)) {
- n = nucleus(q);
- if (n != null) {
- if ((type(n) == sub_mlist_node) || (type(n) == sub_box_node)) {
- n = math_list(n);
- if (n != null) {
- if (type(n) == hlist_node) {
- /*tex just a not scaled char */
- n = list_ptr(n);
- while (n != null) {
- if (type(n) == glyph_node) {
- delta = char_italic(font(n),character(n));
- }
- n = vlink(n);
- }
- } else {
- while (n != null) {
- if (type(n) == fence_noad) {
- if (delimiteritalic(n) > delta) {
- /*tex we can have dummies, the period ones */
- delta = delimiteritalic(n);
- }
- }
- n = vlink(n);
- }
- }
- }
- } else {
- n = nucleus(q);
- if (type(n) == math_char_node) {
- delta = char_italic(fam_fnt(math_fam(n),cur_size),math_character(n));
- }
- }
- }
- }
- width(v) = width(y);
- if (width(x) > width(v))
- width(v) = width(x);
- if (width(z) > width(v))
- width(v) = width(z);
- x = rebox(x, width(v));
- y = rebox(y, width(v));
- z = rebox(z, width(v));
- shift_amount(x) = half(delta);
- shift_amount(z) = -shift_amount(x);
- /*tex v is the still empty target */
- height(v) = height(y);
- depth(v) = depth(y);
- /*tex
-
- Attach the limits to |y| and adjust |height(v)|, |depth(v)| to
- account for their presence.
-
- We use |shift_up| and |shift_down| in the following program for the
- amount of glue between the displayed operator |y| and its limits |x|
- and |z|.
-
- The vlist inside box |v| will consist of |x| followed by |y| followed
- by |z|, with kern nodes for the spaces between and around them;
- |b| is baseline and |v| is the minumum gap.
-
- */
- if (supscr(q) == null) {
- list_ptr(x) = null;
- flush_node(x);
- list_ptr(v) = y;
- } else {
- shift_up = limit_above_bgap(cur_style) - depth(x);
- if (shift_up < limit_above_vgap(cur_style))
- shift_up = limit_above_vgap(cur_style);
- p = new_kern(shift_up);
- reset_attributes(p, node_attr(q));
- couple_nodes(p,y);
- couple_nodes(x,p);
- p = new_kern(limit_above_kern(cur_style));
- reset_attributes(p, node_attr(q));
- couple_nodes(p,x);
- list_ptr(v) = p;
- height(v) = height(v) + limit_above_kern(cur_style) + height(x) + depth(x) + shift_up;
- }
- if (subscr(q) == null) {
- list_ptr(z) = null;
- flush_node(z);
- } else {
- shift_down = limit_below_bgap(cur_style) - height(z);
- if (shift_down < limit_below_vgap(cur_style))
- shift_down = limit_below_vgap(cur_style);
- p = new_kern(shift_down);
- reset_attributes(p, node_attr(q));
- couple_nodes(y,p);
- couple_nodes(p,z);
- p = new_kern(limit_below_kern(cur_style));
- reset_attributes(p, node_attr(q));
- couple_nodes(z,p);
- depth(v) = depth(v) + limit_below_kern(cur_style) + height(z) + depth(z) + shift_down;
- }
- if (subscr(q) != null) {
- math_list(subscr(q)) = null;
- flush_node(subscr(q));
- subscr(q) = null;
- }
- if (supscr(q) != null) {
- math_list(supscr(q)) = null;
- flush_node(supscr(q));
- supscr(q) = null;
- }
- assign_new_hlist(q, v);
- if (do_new_math(cur_f)) {
- delta = 0;
- }
- }
- return delta;
-}
-
-/*tex
-
- A ligature found in a math formula does not create a ligature, because there
- is no question of hyphenation afterwards; the ligature will simply be stored
- in an ordinary |glyph_node|, after residing in an |ord_noad|.
-
- The |type| is converted to |math_text_char| here if we would not want to
- apply an italic correction to the current character unless it belongs to a
- math font (i.e., a font with |space=0|).
-
- No boundary characters enter into these ligatures.
-
-*/
-
-#define simple_char_noad(p) (\
- (p != null) && \
- (type(p) == simple_noad) && \
- (subtype(p) <= punct_noad_type) && \
- (type(nucleus(p)) == math_char_node) \
-)
-
-#define same_nucleus_fam(p,q) \
- (math_fam(nucleus(p)) == math_fam(nucleus(q)))
-
-static void make_ord(pointer q)
-{
- /*tex the left-side character for lig/kern testing */
- int a;
- /*tex temporary registers for list manipulation */
- pointer p, r, s;
- /*tex a kern */
- scaled k;
- /*tex a ligature */
- liginfo lig;
- RESTART:
- if (subscr(q) == null && supscr(q) == null && type(nucleus(q)) == math_char_node) {
- p = vlink(q);
- if (simple_char_noad(p) && same_nucleus_fam(p,q)) {
- type(nucleus(q)) = math_text_char_node;
- fetch(nucleus(q));
- a = cur_c;
- /*tex add italic correction */
- if (do_new_math(cur_f) && (char_italic(cur_f,math_character(nucleus(q))) != 0)) {
- p = new_kern(char_italic(cur_f,math_character(nucleus(q))));
- subtype(p) = italic_kern;
- reset_attributes(p, node_attr(q));
- couple_nodes(p,vlink(q));
- couple_nodes(q,p);
- return;
- }
- /*tex construct ligatures, quite unlikely in new math fonts */
- if ((has_kern(cur_f, a)) || (has_lig(cur_f, a))) {
- cur_c = math_character(nucleus(p));
- /*tex
-
- If character |a| has a kern with |cur_c|, attach the kern
- after~|q|; or if it has a ligature with |cur_c|, combine
- noads |q| and~|p| appropriately; then |return| if the cursor
- has moved past a noad, or |goto restart|.
-
- Note that a ligature between an |ord_noad| and another kind
- of noad is replaced by an |ord_noad|, when the two noads
- collapse into one.
-
- We could make a parenthesis (say) change shape when it
- follows certain letters. Presumably a font designer will
- define such ligatures only when this convention makes sense.
-
- */
- if (disable_lig_par == 0 && has_lig(cur_f, a)) {
- lig = get_ligature(cur_f, a, cur_c);
- if (is_valid_ligature(lig)) {
- /*tex allow a way out of infinite ligature loop */
- check_interrupt();
- switch (lig_type(lig)) {
- case 1:
- /*tex \.{=:\char`\|} */
- case 5:
- /*tex \.{=:\char`\|>} */
- math_character(nucleus(q)) = lig_replacement(lig);
- break;
- case 2:
- /*tex \.{\char`\|=:} */
- case 6:
- /*tex \.{\char`\|=:>} */
- math_character(nucleus(p)) = lig_replacement(lig);
- break;
- case 3:
- /*tex \.{\char`\|=:\char`\|} */
- case 7:
- /*tex \.{\char`\|=:\char`\|>} */
- case 11:
- /*tex \.{\char`\|=:\char`\|>>} */
- r = new_noad();
- reset_attributes(r, node_attr(q));
- s = new_node(math_char_node, 0);
- reset_attributes(s, node_attr(q));
- nucleus(r) = s;
- math_character(nucleus(r)) = lig_replacement(lig);
- math_fam(nucleus(r)) = math_fam(nucleus(q));
- couple_nodes(q,r);
- couple_nodes(r,p);
- if (lig_type(lig) < 11) {
- type(nucleus(r)) = math_char_node;
- } else {
- /*tex prevent combination */
- type(nucleus(r)) = math_text_char_node;
- }
- break;
- default:
- try_couple_nodes(q,vlink(p));
- math_character(nucleus(q)) = lig_replacement(lig); /* \.{=:} */
- subscr(q) = subscr(p);
- supscr(q) = supscr(p);
- subscr(p) = null ;
- supscr(p) = null ;
- flush_node(p);
- break;
- }
- if (lig_type(lig) > 3)
- return;
- type(nucleus(q)) = math_char_node;
- goto RESTART;
- }
- }
- if (disable_kern_par == 0 && has_kern(cur_f, a)) {
- /*tex todo: should this use mathkerns? */
- k = get_kern(cur_f, a, cur_c);
- if (k != 0) {
- p = new_kern(k);
- reset_attributes(p, node_attr(q));
- couple_nodes(p,vlink(q));
- couple_nodes(q,p);
- return;
- }
- }
- }
- }
- }
-}
-
-/*tex
-
- If the fonts for the left and right bits of a mathkern are not both new-style
- fonts, then return a sentinel value meaning: please use old-style italic
- correction placement
-
-*/
-
-#define MATH_KERN_NOT_FOUND 0x7FFFFFFF
-
-/*tex
-
- This function tries to find the kern needed for proper cut-ins. The left side
- doesn't move, but the right side does, so the first order of business is to
- create a staggered fence line on the left side of the right character.
-
- The microsoft spec says that there are four quadrants, but the actual images
- say.
-
-*/
-
-static scaled math_kern_at(internal_font_number f, int c, int side, int v)
-{
- int h, k, numkerns;
- scaled *kerns_heights;
- scaled kern = 0;
- /*tex Known to exist: */
- charinfo *co = char_info(f, c);
- numkerns = get_charinfo_math_kerns(co, side);
- if (numkerns == 0)
- return kern;
- if (side == top_left_kern) {
- kerns_heights = co->top_left_math_kern_array;
- } else if (side == bottom_left_kern) {
- kerns_heights = co->bottom_left_math_kern_array;
- } else if (side == top_right_kern) {
- kerns_heights = co->top_right_math_kern_array;
- } else if (side == bottom_right_kern) {
- kerns_heights = co->bottom_right_math_kern_array;
- } else {
- /*tex Not reached: */
- confusion("math_kern_at");
- kerns_heights = NULL;
- }
- if (v < kerns_heights[0])
- return kerns_heights[1];
- for (k = 0; k < numkerns; k++) {
- h = kerns_heights[(k * 2)];
- kern = kerns_heights[(k * 2) + 1];
- if (h > v) {
- return kern;
- }
- }
- return kern;
-}
-
-static scaled find_math_kern(internal_font_number l_f, int l_c, internal_font_number r_f, int r_c, int cmd, scaled shift)
-{
- scaled corr_height_top = 0, corr_height_bot = 0;
- scaled krn_l = 0, krn_r = 0, krn = 0;
- if ((!do_new_math(l_f)) || (!do_new_math(r_f)) || (!char_exists(l_f,l_c)) || (!char_exists(r_f,r_c)))
- return MATH_KERN_NOT_FOUND;
- if (cmd == sup_mark_cmd) {
- corr_height_top = char_height(l_f, l_c);
- /*tex bottom of superscript */
- corr_height_bot = -char_depth(r_f, r_c) + shift;
- krn_l = math_kern_at(l_f, l_c, top_right_kern, corr_height_top);
- krn_r = math_kern_at(r_f, r_c, bottom_left_kern, corr_height_top);
- krn = (krn_l + krn_r);
- krn_l = math_kern_at(l_f, l_c, top_right_kern, corr_height_bot);
- krn_r = math_kern_at(r_f, r_c, bottom_left_kern, corr_height_bot);
- if ((krn_l + krn_r) < krn)
- krn = (krn_l + krn_r);
- return (krn);
- } else if (cmd == sub_mark_cmd) {
- /*tex top of subscript */
- corr_height_top = char_height(r_f, r_c) - shift;
- corr_height_bot = -char_depth(l_f, l_c);
- krn_l = math_kern_at(l_f, l_c, bottom_right_kern, corr_height_top);
- krn_r = math_kern_at(r_f, r_c, top_left_kern, corr_height_top);
- krn = (krn_l + krn_r);
- krn_l = math_kern_at(l_f, l_c, bottom_right_kern, corr_height_bot);
- krn_r = math_kern_at(r_f, r_c, top_left_kern, corr_height_bot);
- if ((krn_l + krn_r) < krn)
- krn = (krn_l + krn_r);
- return (krn);
- } else {
- confusion("find_math_kern");
- }
- /*tex Not reached: */
- return 0;
-}
-
-/*tex Just a small helper: */
-
-static pointer attach_hkern_to_new_hlist(pointer q, scaled delta2, halfword subtyp)
-{
- pointer y;
- pointer z = new_kern(delta2);
- if (subtyp != 0) {
- subtype(z) = subtyp;
- }
- reset_attributes(z, node_attr(q));
- if (new_hlist(q) == null) {
- /*tex this is somewhat weird */
- new_hlist(q) = z;
- } else {
- y = new_hlist(q);
- while (vlink(y) != null)
- y = vlink(y);
- couple_nodes(y,z);
- }
- return new_hlist(q);
-}
-
-/*tex
-
- The purpose of |make_scripts(q,it)| is to attach the subscript and/or
- superscript of noad |q| to the list that starts at |new_hlist(q)|, given that
- subscript and superscript aren't both empty. The superscript will be
- horizontally shifted over |delta1|, the subscript over |delta2|.
-
- We set |shift_down| and |shift_up| to the minimum amounts to shift the
- baseline of subscripts and superscripts based on the given nucleus.
-
- Note: We need to look at a character but also at the first one in a sub list
- and there we ignore leading kerns and glue. Elsewhere is code that removes
- kerns assuming that is italic correction. The heuristics are unreliable for
- the new fonts so eventualy there will be an option to ignore such
- corrections.
-
-*/
-
-#define analyze_script(init,su_n,su_f,su_c) do { \
- su_n = init; \
- if (su_n != null) { \
- if (math_script_char_mode_par > 0 && type(su_n) == math_char_node) { \
- fetch(su_n); \
- if (char_exists(cur_f, cur_c)) { \
- su_f = cur_f; \
- su_c = cur_c; \
- } else { \
- su_n = null; \
- } \
- } else if (math_script_box_mode_par > 0 && type(su_n) == sub_mlist_node) { \
- su_n = math_list(su_n); \
- while (su_n != null) { \
- if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
- su_n = vlink(su_n); \
- } else if (type(su_n) == simple_noad) { \
- su_n = nucleus(su_n); \
- if (type(su_n) == math_char_node) { \
- fetch(su_n); \
- if (char_exists(cur_f, cur_c)) { \
- su_f = cur_f; \
- su_c = cur_c; \
- } else { \
- su_n = null; \
- } \
- } else { \
- su_n = null; \
- } \
- break; \
- } else { \
- su_n = null; \
- break; \
- } \
- } \
- } else if (type(su_n) == sub_box_node) { \
- su_n = math_list(su_n); \
- if (su_n != null) { \
- if (type(su_n) == hlist_node) { \
- su_n = list_ptr(su_n); \
- } \
- if (su_n != null) { \
- if (math_script_box_mode_par == 2) { \
- while (su_n != null) { \
- if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
- su_n = vlink(su_n); \
- } else if (type(su_n) == glyph_node) { \
- if (char_exists(font(su_n), character(su_n))) { \
- su_f = font(su_n); \
- su_c = character(su_n); \
- } else { \
- su_n = null; \
- } \
- break ; \
- } else { \
- su_n = null; \
- break; \
- } \
- } \
- } else if (math_script_box_mode_par == 3) { \
- int boundary = -1; \
- while (su_n != null) { \
- if ((type(su_n) == boundary_node) && (subtype(su_n) == user_boundary)) { \
- boundary = boundary_value(su_n); \
- su_n = vlink(su_n); \
- } else if ((type(su_n) == kern_node) || (type(su_n) == glue_node)) { \
- su_n = vlink(su_n); \
- } else if ((boundary > -1) && (type(su_n) == glyph_node)) { \
- if (char_exists(font(su_n), character(su_n))) { \
- su_f = font(su_n); \
- su_c = character(su_n); \
- } else { \
- su_n = null; \
- } \
- break ; \
- } else { \
- su_n = null; \
- break; \
- } \
- } \
- } \
- } \
- } else { \
- su_n = null; \
- } \
- } else { \
- su_n = null; \
- } \
- } \
- } while (0) \
-
-#define x_su_style(n,cur_style,su_style) \
- (noadoptionnosubscript(n) ? cur_style : su_style(cur_style))
-
-static void make_scripts(pointer q, pointer p, scaled it, int cur_style, scaled supshift, scaled subshift)
-{
- pointer x, y, z;
- scaled shift_up, shift_down, clr;
- scaled delta1, delta2;
- halfword sub_n, sup_n, subtyp;
- internal_font_number sub_f, sup_f;
- int sub_c, sup_c;
- sub_n = null;
- sup_n = null;
- sub_f = 0;
- sup_f = 0;
- sub_c = 0;
- sup_c = 0;
- delta1 = it;
- delta2 = 0;
- subtyp = 0;
- switch (type(nucleus(q))) {
- case math_char_node:
- case math_text_char_node:
- if ((subscr(q) == null) && (delta1 != 0)) {
- /*tex todo: selective italic correction */
- x = new_kern(delta1);
- subtype(x) = italic_kern;
- reset_attributes(x, node_attr(nucleus(q)));
- couple_nodes(p,x);
- delta1 = 0;
- }
- }
- assign_new_hlist(q, p);
- if (is_char_node(p)) {
- shift_up = 0;
- shift_down = 0;
- } else {
- z = hpack(p, 0, additional, -1);
- shift_up = height(z) - sup_shift_drop(cur_style); /* r18 */
- shift_down = depth(z) + sub_shift_drop(cur_style); /* r19 */
- list_ptr(z) = null;
- flush_node(z);
- }
- if (is_char_node(p)) {
- /*tex We look at the subscript character (_i) or first character in a list (_{ij}). */
- analyze_script(subscr(q),sub_n,sub_f,sub_c);
- /*tex We look at the superscript character (^i) or first character in a list (^{ij}). */
- analyze_script(supscr(q),sup_n,sup_f,sup_c);
- }
- if (supscr(q) == null) {
- /*tex
-
- Construct a subscript box |x| when there is no superscript. When
- there is a subscript without a superscript, the top of the subscript
- should not exceed the baseline plus four-fifths of the x-height.
-
- */
- x = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style, math_sub_list);
- width(x) = width(x) + space_after_script(cur_style);
- switch (math_scripts_mode_par) {
- case 1:
- shift_down = sub_shift_down(cur_style) ;
- break;
- case 2:
- shift_down = sub_sup_shift_down(cur_style) ;
- break;
- case 3:
- shift_down = sub_sup_shift_down(cur_style) ;
- break;
- case 4:
- shift_down = sub_shift_down(cur_style) + half(sub_sup_shift_down(cur_style)-sub_shift_down(cur_style)) ;
- break;
- case 5:
- shift_down = sub_shift_down(cur_style) ;
- break;
- default:
- if (shift_down < sub_shift_down(cur_style))
- shift_down = sub_shift_down(cur_style);
- clr = height(x) - sub_top_max(cur_style);
- if (shift_down < clr)
- shift_down = clr;
- break;
- }
- shift_amount(x) = shift_down;
- /*tex Now find and correct for horizontal shift. */
- subtyp = 0;
- if (sub_n != null) {
- delta2 = find_math_kern(font(p), character(p),sub_f,sub_c,sub_mark_cmd, shift_down);
- if (delta2 == MATH_KERN_NOT_FOUND) {
- delta2 = subshift ;
- } else {
- delta2 = delta2 + subshift ;
- subtyp = font_kern;
- }
- } else {
- delta2 = subshift ;
- }
- if (delta2 != 0) {
- p = attach_hkern_to_new_hlist(q, delta2, subtyp);
- }
- } else {
- /*tex
-
- Construct a superscript box |x|. The bottom of a superscript should
- never descend below the baseline plus one-fourth of the x-height.
-
- */
- x = clean_box(supscr(q), (noadoptionnosupscript(q) ? cur_style : sup_style(cur_style)), cur_style, math_sup_list);
- width(x) = width(x) + space_after_script(cur_style);
- switch (math_scripts_mode_par) {
- case 1:
- shift_up = sup_shift_up(cur_style);
- break;
- case 2:
- shift_up = sup_shift_up(cur_style) ;
- break;
- case 3:
- shift_up = sup_shift_up(cur_style) + sub_sup_shift_down(cur_style) - sub_shift_down(cur_style) ;
- break;
- case 4:
- shift_up = sup_shift_up(cur_style) + half(sub_sup_shift_down(cur_style)-sub_shift_down(cur_style)) ;
- break;
- case 5:
- shift_up = sup_shift_up(cur_style) + sub_sup_shift_down(cur_style)-sub_shift_down(cur_style) ;
- break;
- default:
- clr = sup_shift_up(cur_style);
- if (shift_up < clr)
- shift_up = clr;
- clr = depth(x) + sup_bottom_min(cur_style);
- if (shift_up < clr)
- shift_up = clr;
- break;
- }
- if (subscr(q) == null) {
- shift_amount(x) = -shift_up;
- /*tex Now find and correct for horizontal shift. */
- subtyp = 0;
- if (sup_n != null) {
- clr = find_math_kern(font(p),character(p),sup_f,sup_c,sup_mark_cmd,shift_up);
- if (clr == MATH_KERN_NOT_FOUND) {
- clr = supshift ;
- } else {
- clr = clr + supshift ;
- subtyp = font_kern;
- }
- } else {
- clr = supshift;
- }
- if (clr != 0) {
- p = attach_hkern_to_new_hlist(q, clr, subtyp);
- }
- } else {
- /*tex
-
- Construct a sub/superscript combination box |x|, with the
- superscript offset by |delta|. When both subscript and
- superscript are present, the subscript must be separated from the
- superscript by at least four times |default_rule_thickness| If
- this condition would be violated, the subscript moves down, after
- which both subscript and superscript move up so that the bottom
- of the superscript is at least as high as the baseline plus
- four-fifths of the x-height.
-
- */
- y = clean_box(subscr(q), (noadoptionnosubscript(q) ? cur_style : sub_style(cur_style)), cur_style, math_sub_list);
- width(y) = width(y) + space_after_script(cur_style);
- switch (math_scripts_mode_par) {
- case 1:
- shift_down = sub_shift_down(cur_style) ;
- break;
- case 2:
- shift_down = sub_sup_shift_down(cur_style) ;
- break;
- case 3:
- shift_down = sub_sup_shift_down(cur_style) ;
- break;
- case 4:
- shift_down = sub_shift_down(cur_style) + half(sub_sup_shift_down(cur_style)-sub_shift_down(cur_style)) ;
- break;
- case 5:
- shift_down = sub_shift_down(cur_style) ;
- break;
- default:
- if (shift_down < sub_sup_shift_down(cur_style))
- shift_down = sub_sup_shift_down(cur_style);
- clr = subsup_vgap(cur_style) - ((shift_up - depth(x)) - (height(y) - shift_down));
- if (clr > 0) {
- shift_down = shift_down + clr;
- clr = sup_sub_bottom_max(cur_style) - (shift_up - depth(x));
- if (clr > 0) {
- shift_up = shift_up + clr;
- shift_down = shift_down - clr;
- }
- }
- break;
- }
- /*tex Now find and correct for horizontal shift. */
- subtyp = 0;
- if (sub_n != null) {
- delta2 = find_math_kern(font(p), character(p),sub_f,sub_c,sub_mark_cmd, shift_down);
- if (delta2 == MATH_KERN_NOT_FOUND) {
- delta2 = subshift ;
- } else {
- delta2 = delta2 + subshift ;
- subtyp = font_kern;
- }
- } else {
- delta2 = subshift ;
- }
- if (delta2 != 0) {
- p = attach_hkern_to_new_hlist(q, delta2, subtyp);
- }
- /*tex
-
- Now the horizontal shift for the superscript; the superscript is
- also to be shifted by |delta1| (the italic correction).
-
- */
- clr = MATH_KERN_NOT_FOUND;
- if (sup_n != null) {
- clr = find_math_kern(font(p),character(p),sup_f,sup_c,sup_mark_cmd,shift_up);
- }
- /*tex
-
- The delta can already have been applied and now be 0.
-
- */
- if (delta2 == MATH_KERN_NOT_FOUND)
- delta2 = - supshift ;
- else
- delta2 = delta2 - supshift ;
- if (clr != MATH_KERN_NOT_FOUND) {
- shift_amount(x) = clr + delta1 - delta2;
- } else {
- shift_amount(x) = delta1 - delta2;
- }
- /*tex todo: only if kern != 0 */
- p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));
- reset_attributes(p, node_attr(q));
- couple_nodes(x,p);
- couple_nodes(p,y);
- /*tex We end up with funny dimensions. */
- x = vpackage(x, 0, additional, max_dimen, math_direction_par);
- reset_attributes(x, node_attr(q));
- subtype(x) = math_scripts_list;
- shift_amount(x) = shift_down;
- }
- }
- if (new_hlist(q) == null) {
- new_hlist(q) = x;
- } else {
- p = new_hlist(q);
- while (vlink(p) != null)
- p = vlink(p);
- couple_nodes(p,x);
- }
- if (subscr(q) != null) {
- math_list(subscr(q)) = null;
- flush_node(subscr(q));
- subscr(q) = null;
- }
- if (supscr(q) != null) {
- math_list(supscr(q)) = null;
- flush_node(supscr(q));
- supscr(q) = null;
- }
-}
-
-/*tex
-
- The |make_left_right| function constructs a left or right delimiter of the
- required size and returns the value |open_noad| or |close_noad|. The
- |left_noad_side| and |right_noad_side| will both be based on the original
- |style|, so they will have consistent sizes.
-
-*/
-
-static small_number make_left_right(pointer q, int style, scaled max_d, scaled max_h)
-{
- scaled delta;
- pointer tmp, lst;
- scaled ic = 0;
- boolean stack = false;
- boolean axis = false;
- int same = subtype(q);
- setup_cur_size(style);
- if ((delimiterheight(q)!=0) || (delimiterdepth(q)!=0)) {
-
- delta = delimiterheight(q) + delimiterdepth(q);
- tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, false, &stack, &ic, &same);
- delimiteritalic(q) = ic;
- /*tex
-
- Beware, a stacked delimiter has a shift but no corrected height/depth
- (yet).
-
- */
- if (stack) {
- shift_amount(tmp) = delimiterdepth(q);
- }
- if (delimiterexact(q)) {
- delimiterheight(q) = height(tmp) - shift_amount(tmp);
- delimiterdepth(q) = depth(tmp) + shift_amount(tmp);
- }
- if (delimiteraxis(q)) {
- delimiterheight(q) += math_axis_size(cur_size);
- delimiterdepth(q) -= math_axis_size(cur_size);
- shift_amount(tmp) -= math_axis_size(cur_size);
- }
- lst = new_node(hlist_node,0);
- reset_attributes(lst, node_attr(q));
- box_dir(lst) = dir_TLT ;
- height(lst) = delimiterheight(q);
- depth(lst) = delimiterdepth(q);
- width(lst) = width(tmp);
- list_ptr(lst) = tmp;
- tmp = lst ;
- } else {
- axis = ! delimiternoaxis(q);
- delta = get_delimiter_height(max_d,max_h,axis);
- tmp = do_delimiter(q, delimiter(q), cur_size, delta, false, style, axis, &stack, &ic, &same);
- delimiteritalic(q) = ic;
- }
- delimiter(q) = null;
- assign_new_hlist(q, tmp);
- delimitersamesize(q) = same;
- if (delimiterclass(q) >= ord_noad_type) {
- if (delimiterclass(q) <= inner_noad_type) {
- return delimiterclass(q);
- } else {
- return ord_noad_type;
- }
- } else if (subtype(q) == left_noad_side) {
- return open_noad_type;
- } else {
- return close_noad_type;
- }
-}
-
-#define TEXT_STYLES(A,B) do { \
- def_math_param(A,display_style,(B),level_one); \
- def_math_param(A,cramped_display_style,(B),level_one); \
- def_math_param(A,text_style,(B),level_one); \
- def_math_param(A,cramped_text_style,(B),level_one); \
- } while (0)
-
-#define SCRIPT_STYLES(A,B) do { \
- def_math_param(A,script_style,(B),level_one); \
- def_math_param(A,cramped_script_style,(B),level_one); \
- def_math_param(A,script_script_style,(B),level_one); \
- def_math_param(A,cramped_script_script_style,(B),level_one); \
- } while (0)
-
-#define ALL_STYLES(A,B) do { \
- TEXT_STYLES(A,(B)); \
- SCRIPT_STYLES(A,(B)); \
- } while (0)
-
-#define SPLIT_STYLES(A,B,C) do { \
- TEXT_STYLES(A,(B)); \
- SCRIPT_STYLES(A,(C)); \
- } while (0)
-
-void initialize_math_spacing(void)
-{
- ALL_STYLES (math_param_ord_ord_spacing, 0);
- ALL_STYLES (math_param_ord_op_spacing, thin_mu_skip_code);
- SPLIT_STYLES (math_param_ord_bin_spacing, med_mu_skip_code, 0);
- SPLIT_STYLES (math_param_ord_rel_spacing, thick_mu_skip_code, 0);
- ALL_STYLES (math_param_ord_open_spacing, 0);
- ALL_STYLES (math_param_ord_close_spacing, 0);
- ALL_STYLES (math_param_ord_punct_spacing, 0);
- SPLIT_STYLES (math_param_ord_inner_spacing, thin_mu_skip_code, 0);
-
- ALL_STYLES (math_param_op_ord_spacing, thin_mu_skip_code);
- ALL_STYLES (math_param_op_op_spacing, thin_mu_skip_code);
- ALL_STYLES (math_param_op_bin_spacing, 0);
- SPLIT_STYLES (math_param_op_rel_spacing, thick_mu_skip_code, 0);
- ALL_STYLES (math_param_op_open_spacing, 0);
- ALL_STYLES (math_param_op_close_spacing, 0);
- ALL_STYLES (math_param_op_punct_spacing, 0);
- SPLIT_STYLES (math_param_op_inner_spacing, thin_mu_skip_code, 0);
-
- SPLIT_STYLES (math_param_bin_ord_spacing, med_mu_skip_code, 0);
- SPLIT_STYLES (math_param_bin_op_spacing, med_mu_skip_code, 0);
- ALL_STYLES (math_param_bin_bin_spacing, 0);
- ALL_STYLES (math_param_bin_rel_spacing, 0);
- SPLIT_STYLES (math_param_bin_open_spacing, med_mu_skip_code, 0);
- ALL_STYLES (math_param_bin_close_spacing, 0);
- ALL_STYLES (math_param_bin_punct_spacing, 0);
- SPLIT_STYLES (math_param_bin_inner_spacing, med_mu_skip_code, 0);
-
- SPLIT_STYLES (math_param_rel_ord_spacing, thick_mu_skip_code, 0);
- SPLIT_STYLES (math_param_rel_op_spacing, thick_mu_skip_code, 0);
- ALL_STYLES (math_param_rel_bin_spacing, 0);
- ALL_STYLES (math_param_rel_rel_spacing, 0);
- SPLIT_STYLES (math_param_rel_open_spacing, thick_mu_skip_code, 0);
- ALL_STYLES (math_param_rel_close_spacing, 0);
- ALL_STYLES (math_param_rel_punct_spacing, 0);
- SPLIT_STYLES (math_param_rel_inner_spacing, thick_mu_skip_code, 0);
-
- ALL_STYLES (math_param_open_ord_spacing, 0);
- ALL_STYLES (math_param_open_op_spacing, 0);
- ALL_STYLES (math_param_open_bin_spacing, 0);
- ALL_STYLES (math_param_open_rel_spacing, 0);
- ALL_STYLES (math_param_open_open_spacing, 0);
- ALL_STYLES (math_param_open_close_spacing, 0);
- ALL_STYLES (math_param_open_punct_spacing, 0);
- ALL_STYLES (math_param_open_inner_spacing, 0);
-
- ALL_STYLES (math_param_close_ord_spacing, 0);
- ALL_STYLES (math_param_close_op_spacing, thin_mu_skip_code);
- SPLIT_STYLES (math_param_close_bin_spacing, med_mu_skip_code, 0);
- SPLIT_STYLES (math_param_close_rel_spacing, thick_mu_skip_code, 0);
- ALL_STYLES (math_param_close_open_spacing, 0);
- ALL_STYLES (math_param_close_close_spacing, 0);
- ALL_STYLES (math_param_close_punct_spacing, 0);
- SPLIT_STYLES (math_param_close_inner_spacing, thin_mu_skip_code, 0);
-
- SPLIT_STYLES (math_param_punct_ord_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_op_spacing, thin_mu_skip_code, 0);
- ALL_STYLES (math_param_punct_bin_spacing, 0);
- SPLIT_STYLES (math_param_punct_rel_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_open_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_close_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_punct_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_punct_inner_spacing, thin_mu_skip_code, 0);
-
- SPLIT_STYLES (math_param_inner_ord_spacing, thin_mu_skip_code, 0);
- ALL_STYLES (math_param_inner_op_spacing, thin_mu_skip_code);
- SPLIT_STYLES (math_param_inner_bin_spacing, med_mu_skip_code, 0);
- SPLIT_STYLES (math_param_inner_rel_spacing, thick_mu_skip_code, 0);
- SPLIT_STYLES (math_param_inner_open_spacing, thin_mu_skip_code, 0);
- ALL_STYLES (math_param_inner_close_spacing, 0);
- SPLIT_STYLES (math_param_inner_punct_spacing, thin_mu_skip_code, 0);
- SPLIT_STYLES (math_param_inner_inner_spacing, thin_mu_skip_code, 0);
-}
-
-#define both_types(A,B) ((A)*16+(B))
-
-static pointer math_spacing_glue(int l_type, int r_type, int mstyle, scaled mmu)
-{
- int x = -1;
- pointer z = null;
- if (l_type == op_noad_type_limits || l_type == op_noad_type_no_limits)
- l_type = op_noad_type_normal;
- if (r_type == op_noad_type_limits || r_type == op_noad_type_no_limits)
- r_type = op_noad_type_normal;
- switch (both_types(l_type, r_type)) {
- case both_types(ord_noad_type, ord_noad_type ): x = get_math_param(math_param_ord_ord_spacing,mstyle); break;
- case both_types(ord_noad_type, op_noad_type_normal): x = get_math_param(math_param_ord_op_spacing,mstyle); break;
- case both_types(ord_noad_type, bin_noad_type ): x = get_math_param(math_param_ord_bin_spacing,mstyle); break;
- case both_types(ord_noad_type, rel_noad_type ): x = get_math_param(math_param_ord_rel_spacing,mstyle); break;
- case both_types(ord_noad_type, open_noad_type ): x = get_math_param(math_param_ord_open_spacing,mstyle); break;
- case both_types(ord_noad_type, close_noad_type ): x = get_math_param(math_param_ord_close_spacing,mstyle); break;
- case both_types(ord_noad_type, punct_noad_type ): x = get_math_param(math_param_ord_punct_spacing,mstyle); break;
- case both_types(ord_noad_type, inner_noad_type ): x = get_math_param(math_param_ord_inner_spacing,mstyle); break;
- case both_types(op_noad_type_normal, ord_noad_type ): x = get_math_param(math_param_op_ord_spacing,mstyle); break;
- case both_types(op_noad_type_normal, op_noad_type_normal): x = get_math_param(math_param_op_op_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(op_noad_type_normal, bin_noad_type ): x = get_math_param(math_param_op_bin_spacing,mstyle); break;
- /* */
- case both_types(op_noad_type_normal, rel_noad_type ): x = get_math_param(math_param_op_rel_spacing,mstyle); break;
- case both_types(op_noad_type_normal, open_noad_type ): x = get_math_param(math_param_op_open_spacing,mstyle); break;
- case both_types(op_noad_type_normal, close_noad_type ): x = get_math_param(math_param_op_close_spacing,mstyle); break;
- case both_types(op_noad_type_normal, punct_noad_type ): x = get_math_param(math_param_op_punct_spacing,mstyle); break;
- case both_types(op_noad_type_normal, inner_noad_type ): x = get_math_param(math_param_op_inner_spacing,mstyle); break;
- case both_types(bin_noad_type, ord_noad_type ): x = get_math_param(math_param_bin_ord_spacing,mstyle); break;
- case both_types(bin_noad_type, op_noad_type_normal): x = get_math_param(math_param_bin_op_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(bin_noad_type, bin_noad_type ): x = get_math_param(math_param_bin_bin_spacing,mstyle); break;
- case both_types(bin_noad_type, rel_noad_type ): x = get_math_param(math_param_bin_rel_spacing,mstyle); break;
- /* */
- case both_types(bin_noad_type, open_noad_type ): x = get_math_param(math_param_bin_open_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(bin_noad_type, close_noad_type ): x = get_math_param(math_param_bin_close_spacing,mstyle); break;
- case both_types(bin_noad_type, punct_noad_type ): x = get_math_param(math_param_bin_punct_spacing,mstyle); break;
- /* */
- case both_types(bin_noad_type, inner_noad_type ): x = get_math_param(math_param_bin_inner_spacing,mstyle); break;
- case both_types(rel_noad_type, ord_noad_type ): x = get_math_param(math_param_rel_ord_spacing,mstyle); break;
- case both_types(rel_noad_type, op_noad_type_normal): x = get_math_param(math_param_rel_op_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(rel_noad_type, bin_noad_type ): x = get_math_param(math_param_rel_bin_spacing,mstyle); break;
- /* */
- case both_types(rel_noad_type, rel_noad_type ): x = get_math_param(math_param_rel_rel_spacing,mstyle); break;
- case both_types(rel_noad_type, open_noad_type ): x = get_math_param(math_param_rel_open_spacing,mstyle); break;
- case both_types(rel_noad_type, close_noad_type ): x = get_math_param(math_param_rel_close_spacing,mstyle); break;
- case both_types(rel_noad_type, punct_noad_type ): x = get_math_param(math_param_rel_punct_spacing,mstyle); break;
- case both_types(rel_noad_type, inner_noad_type ): x = get_math_param(math_param_rel_inner_spacing,mstyle); break;
- case both_types(open_noad_type, ord_noad_type ): x = get_math_param(math_param_open_ord_spacing,mstyle); break;
- case both_types(open_noad_type, op_noad_type_normal): x = get_math_param(math_param_open_op_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(open_noad_type, bin_noad_type ): x = get_math_param(math_param_open_bin_spacing,mstyle); break;
- /* */
- case both_types(open_noad_type, rel_noad_type ): x = get_math_param(math_param_open_rel_spacing,mstyle); break;
- case both_types(open_noad_type, open_noad_type ): x = get_math_param(math_param_open_open_spacing,mstyle); break;
- case both_types(open_noad_type, close_noad_type ): x = get_math_param(math_param_open_close_spacing,mstyle); break;
- case both_types(open_noad_type, punct_noad_type ): x = get_math_param(math_param_open_punct_spacing,mstyle); break;
- case both_types(open_noad_type, inner_noad_type ): x = get_math_param(math_param_open_inner_spacing,mstyle); break;
- case both_types(close_noad_type, ord_noad_type ): x = get_math_param(math_param_close_ord_spacing,mstyle); break;
- case both_types(close_noad_type, op_noad_type_normal): x = get_math_param(math_param_close_op_spacing,mstyle); break;
- case both_types(close_noad_type, bin_noad_type ): x = get_math_param(math_param_close_bin_spacing,mstyle); break;
- case both_types(close_noad_type, rel_noad_type ): x = get_math_param(math_param_close_rel_spacing,mstyle); break;
- case both_types(close_noad_type, open_noad_type ): x = get_math_param(math_param_close_open_spacing,mstyle); break;
- case both_types(close_noad_type, close_noad_type ): x = get_math_param(math_param_close_close_spacing,mstyle); break;
- case both_types(close_noad_type, punct_noad_type ): x = get_math_param(math_param_close_punct_spacing,mstyle); break;
- case both_types(close_noad_type, inner_noad_type ): x = get_math_param(math_param_close_inner_spacing,mstyle); break;
- case both_types(punct_noad_type, ord_noad_type ): x = get_math_param(math_param_punct_ord_spacing,mstyle); break;
- case both_types(punct_noad_type, op_noad_type_normal): x = get_math_param(math_param_punct_op_spacing,mstyle); break;
- /* shouldn't happen */
- case both_types(punct_noad_type, bin_noad_type ): x = get_math_param(math_param_punct_bin_spacing,mstyle); break;
- /* */
- case both_types(punct_noad_type, rel_noad_type ): x = get_math_param(math_param_punct_rel_spacing,mstyle); break;
- case both_types(punct_noad_type, open_noad_type ): x = get_math_param(math_param_punct_open_spacing,mstyle); break;
- case both_types(punct_noad_type, close_noad_type ): x = get_math_param(math_param_punct_close_spacing,mstyle); break;
- case both_types(punct_noad_type, punct_noad_type ): x = get_math_param(math_param_punct_punct_spacing,mstyle); break;
- case both_types(punct_noad_type, inner_noad_type ): x = get_math_param(math_param_punct_inner_spacing,mstyle); break;
- case both_types(inner_noad_type, ord_noad_type ): x = get_math_param(math_param_inner_ord_spacing,mstyle); break;
- case both_types(inner_noad_type, op_noad_type_normal): x = get_math_param(math_param_inner_op_spacing,mstyle); break;
- case both_types(inner_noad_type, bin_noad_type ): x = get_math_param(math_param_inner_bin_spacing,mstyle); break;
- case both_types(inner_noad_type, rel_noad_type ): x = get_math_param(math_param_inner_rel_spacing,mstyle); break;
- case both_types(inner_noad_type, open_noad_type ): x = get_math_param(math_param_inner_open_spacing,mstyle); break;
- case both_types(inner_noad_type, close_noad_type ): x = get_math_param(math_param_inner_close_spacing,mstyle); break;
- case both_types(inner_noad_type, punct_noad_type ): x = get_math_param(math_param_inner_punct_spacing,mstyle); break;
- case both_types(inner_noad_type, inner_noad_type ): x = get_math_param(math_param_inner_inner_spacing,mstyle); break;
- }
- if (x < 0) {
- confusion("mathspacing");
- }
- if (x != 0) {
- if (x <= thick_mu_skip_code) {
- /*tex trap thin/med/thick settings cf.\ old \TeX */
- z = math_glue(glue_par(x), mmu);
- /*tex store a symbolic subtype */
- subtype(z) = (quarterword) (x + 1);
- } else {
- z = math_glue(x, mmu);
- }
- }
- return z;
-}
-
-static pointer check_nucleus_complexity(halfword q, scaled * delta, int cur_style, int *same)
-{
- pointer p = null;
- pointer t = null;
- if (same != NULL) {
- *same = 0;
- }
- switch (type(nucleus(q))) {
- case math_char_node:
- case math_text_char_node:
- fetch(nucleus(q));
- if (char_exists(cur_f, cur_c)) {
- /*tex we could look at neighbours */
- if (do_new_math(cur_f)) {
- /*tex cf spec only the last one */
- *delta = 0 ;
- } else {
- *delta = char_italic(cur_f, cur_c);
- }
- p = new_glyph(cur_f, cur_c);
- protect_glyph(p);
- reset_attributes(p, node_attr(nucleus(q)));
- if (do_new_math(cur_f)) {
- if (get_char_cat_code(cur_c) == 11) {
- /*tex no italic correction in mid-word of text font */
- *delta = 0;
- }
- } else {
- /*tex no italic correction in mid-word of text font */
- if (((type(nucleus(q))) == math_text_char_node) && (space(cur_f) != 0)) {
- *delta = 0;
- }
- }
- /*tex so we only add italic correction when we have no scripts */
- if ((subscr(q) == null) && (supscr(q) == null) && (*delta != 0)) {
- pointer x = new_kern(*delta);
- subtype(x) = italic_kern;
- reset_attributes(x, node_attr(nucleus(q)));
- couple_nodes(p,x);
- *delta = 0;
- } else if (do_new_math(cur_f)) {
- /*tex Needs checking but looks ok. It must be more selective. */
- *delta = char_italic(cur_f, cur_c);
- }
- }
- break;
- case sub_box_node:
- p = math_list(nucleus(q));
- break;
- case sub_mlist_node:
- t = math_list(nucleus(q));
- /*tex Recursive call: */
- mlist_to_hlist(t, false, cur_style);
- if (same != NULL && type(t) == fence_noad && delimitersamesize(t)) {
- *same = delimitersamesize(t) ;
- }
- setup_cur_size(cur_style);
- p = hpack(vlink(temp_head), 0, additional, -1);
- reset_attributes(p, node_attr(nucleus(q)));
- break;
- default:
- confusion("mlist2");
- }
- return p;
-}
-
-/*tex
-
- Here is the overall plan of |mlist_to_hlist|, and the list of its local
- variables.
-
-*/
-
-void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style)
-{
- /*tex runs through the mlist */
- pointer q = mlist;
- /*tex the most recent noad preceding |q| */
- pointer r = null;
- /*tex tuck global parameter away as local variable */
- int style = cur_style;
- /*tex the |type| of noad |r|, or |op_noad| if |r=null| */
- int r_type = simple_noad;
- /*tex the |subtype| of noad |r| if |r_type| is |fence_noad| */
- int r_subtype = op_noad_type_normal;
- /*tex the effective |type| of noad |q| during the second pass */
- int t;
- /*tex the effective |subtype| of noad |q| during the second pass */
- int t_subtype;
- pointer p = null;
- pointer pp = null;
- pointer z = null;
- halfword nxt ;
- int same = 0;
- /*tex a penalty to be inserted */
- int pen;
- /*tex a penalty to be inserted */
- int prepen;
- /*tex maximum height of the list translated so far */
- scaled max_hl = 0;
- /*tex maximum depth of the list translated so far */
- scaled max_d = 0;
- /*tex italic correction offset for subscript and superscript */
- scaled delta;
- /*tex the math unit width corresponding to |cur_size| */
- scaled cur_mu;
- r_subtype = op_noad_type_normal;
- setup_cur_size(cur_style);
- cur_mu = x_over_n(get_math_quad_size(cur_size), 18);
- if (math_penalties_mode_par) {
- /*tex
- We could do this via the callback but it's nice to have it as
- primitive too.
- */
- penalties = 1;
- }
- while (q != null) {
- /*tex
-
- We use the fact that no character nodes appear in an mlist, hence the
- field |type(q)| is always present.One of the things we must do on the
- first pass is change a |bin_noad| to an |ord_noad| if the |bin_noad|
- is not in the context of a binary operator. The values of |r| and
- |r_type| make this fairly easy.
-
- */
- RESWITCH:
- delta = 0;
- nxt = vlink(q);
- switch (type(q)) {
- case simple_noad:
- switch (subtype(q)) {
- case bin_noad_type:
- switch (r_type) {
- case simple_noad:
- switch (r_subtype) {
- case bin_noad_type:
- case op_noad_type_normal:
- case op_noad_type_limits:
- case op_noad_type_no_limits:
- case rel_noad_type:
- case open_noad_type:
- case punct_noad_type:
- subtype(q) = ord_noad_type;
- goto RESWITCH;
- break;
- }
- break;
- case fence_noad:
- if (r_subtype == left_noad_side) {
- /*tex So these can best be the same size. */
- subtype(q) = ord_noad_type;
- goto RESWITCH;
- }
- break;
- }
- break;
- case over_noad_type:
- make_over(q, cur_style, cur_size, math_rules_fam_par);
- break;
- case under_noad_type:
- make_under(q, cur_style, cur_size, math_rules_fam_par);
- break;
- case vcenter_noad_type:
- make_vcenter(q);
- break;
- case rel_noad_type:
- case close_noad_type:
- case punct_noad_type:
- if (r_type == simple_noad && r_subtype == bin_noad_type) {
- /*tex Assumes the same size; can't this go. */
- type(r) = simple_noad;
- subtype(r) = ord_noad_type;
- }
- break;
- case op_noad_type_normal:
- case op_noad_type_limits:
- case op_noad_type_no_limits:
- delta = make_op(q, cur_style);
- if ((subtype(q) == op_noad_type_limits) || (subtype(q) == op_noad_type_no_limits))
- goto CHECK_DIMENSIONS;
- break;
- case ord_noad_type:
- make_ord(q);
- break;
- case open_noad_type:
- case inner_noad_type:
- break;
- }
- break;
- case fence_noad:
- if (subtype(q) != left_noad_side) {
- if (r_type == simple_noad && r_subtype == bin_noad_type) {
- /*tex Assumes the same size. */
- type(r) = simple_noad;
- subtype(r) = ord_noad_type;
- }
- }
- goto DONE_WITH_NOAD;
- break;
- case fraction_noad:
- make_fraction(q, cur_style);
- goto CHECK_DIMENSIONS;
- break;
- case radical_noad:
- if (subtype(q) == 7)
- make_hextension(q, cur_style);
- else if (subtype(q) == 6)
- make_delimiter_over(q, cur_style);
- else if (subtype(q) == 5)
- make_delimiter_under(q, cur_style);
- else if (subtype(q) == 4)
- make_over_delimiter(q, cur_style);
- else if (subtype(q) == 3)
- make_under_delimiter(q, cur_style);
- else
- make_radical(q, cur_style);
- break;
- case accent_noad:
- make_math_accent(q, cur_style);
- break;
- case style_node:
- cur_style = subtype(q);
- setup_cur_size(cur_style);
- cur_mu = x_over_n(get_math_quad_style(cur_style), 18);
- goto DONE_WITH_NODE;
- break;
- case choice_node:
- switch (cur_style / 2) {
- case 0:
- /*tex |display_style=0| */
- choose_mlist(display_mlist);
- break;
- case 1:
- /*tex |text_style=2| */
- choose_mlist(text_mlist);
- break;
- case 2:
- /*tex |script_style=4| */
- choose_mlist(script_mlist);
- break;
- case 3:
- /*tex |script_script_style=6| */
- choose_mlist(script_script_mlist);
- break;
- }
- flush_node_list(display_mlist(q));
- flush_node_list(text_mlist(q));
- flush_node_list(script_mlist(q));
- flush_node_list(script_script_mlist(q));
- type(q) = style_node;
- subtype(q) = (quarterword) cur_style;
- if (p != null) {
- z = vlink(q);
- couple_nodes(q,p);
- while (vlink(p) != null)
- p = vlink(p);
- try_couple_nodes(p,z);
- }
- goto DONE_WITH_NODE;
- break;
- case ins_node:
- case mark_node:
- case adjust_node:
- case boundary_node:
- case whatsit_node:
- case penalty_node:
- case disc_node:
- goto DONE_WITH_NODE;
- break;
- case rule_node:
- if (height(q) > max_hl)
- max_hl = height(q);
- if (depth(q) > max_d)
- max_d = depth(q);
- goto DONE_WITH_NODE;
- break;
- case glue_node:
- /*tex
-
- Conditional math glue (`\.{\\nonscript}') results in a
- |glue_node| pointing to |zero_glue|, with
- |subtype(q)=cond_math_glue|; in such a case the node
- following will be eliminated if it is a glue or kern node and
- if the current size is different from |text_size|.
-
- Unconditional math glue (`\.{\\muskip}') is converted to
- normal glue by multiplying the dimensions by |cur_mu|.
-
- */
- if (subtype(q) == mu_glue) {
- math_glue_to_glue(q, cur_mu);
- } else if ((cur_size != text_size) && (subtype(q) == cond_math_glue)) {
- p = vlink(q);
- if (p != null)
- if ((type(p) == glue_node) || (type(p) == kern_node)) {
- if (vlink(p) != null) {
- couple_nodes(q,vlink(p));
- vlink(p) = null;
- } else {
- vlink(q) = null;
- }
- flush_node_list(p);
- }
- }
- goto DONE_WITH_NODE;
- break;
- case kern_node:
- math_kern(q, cur_mu);
- goto DONE_WITH_NODE;
- break;
- default:
- confusion("mlist1");
- }
- /*tex
-
- When we get to the following part of the program, we have ``fallen
- through'' from cases that did not lead to |check_dimensions| or
- |done_with_noad| or |done_with_node|. Thus, |q|~points to a noad
- whose nucleus may need to be converted to an hlist, and whose
- subscripts and superscripts need to be appended if they are present.
-
- If |nucleus(q)| is not a |math_char|, the variable |delta| is the
- amount by which a superscript should be moved right with respect to a
- subscript when both are present.
-
- */
- same = 0 ;
- p = check_nucleus_complexity(q, &delta, cur_style, &same);
- if (same) {
- noadextra4(q) = same ;
- }
- if ((subscr(q) == null) && (supscr(q) == null)) {
- /*tex
-
- Adding italic correction here is kind of fuzzy because some
- characters already have that built in. However, we also add it in
- the scripts so if it's optional here it also should be there.
-
- */
- if (nxt && (math_italics_mode_par > 0) && (delta != 0)) {
- if (type(nxt) == simple_noad) {
- switch (subtype(nxt)) {
- case ord_noad_type:
- case bin_noad_type:
- case rel_noad_type:
- case open_noad_type:
- case close_noad_type:
- case punct_noad_type:
- delta = 0;
- break;
- case inner_noad_type:
- if (! delimitermodeitalics) {
- delta = 0;
- }
- break;
- case op_noad_type_normal:
- case op_noad_type_limits:
- case op_noad_type_no_limits:
- case under_noad_type:
- case over_noad_type:
- case vcenter_noad_type:
- break;
- default:
- break;
- }
- }
- if (delta != 0) {
- pointer d = new_kern(delta);
- subtype(d) = italic_kern;
- reset_attributes(d, node_attr(q));
- couple_nodes(p,d);
- }
- }
- assign_new_hlist(q, p);
- } else {
- /*tex top, bottom */
- make_scripts(q, p, delta, cur_style, 0, 0);
- }
- CHECK_DIMENSIONS:
- z = hpack(new_hlist(q), 0, additional, -1);
- if (height(z) > max_hl)
- max_hl = height(z);
- if (depth(z) > max_d)
- max_d = depth(z);
- list_ptr(z) = null;
- /*tex only drop the \.{\\hbox} */
- flush_node(z);
- DONE_WITH_NOAD:
- r = q;
- r_type = type(r);
- r_subtype = subtype(r);
- if (r_type == fence_noad) {
- r_subtype = left_noad_side;
- cur_style = style;
- setup_cur_size(cur_style);
- /*tex style */
- cur_mu = x_over_n(get_math_quad_size(cur_size), 18);
- }
- DONE_WITH_NODE:
- q = vlink(q);
- }
- if (r_type == simple_noad && r_subtype == bin_noad_type) {
- type(r) = simple_noad;
- subtype(r) = ord_noad_type;
- }
- /*tex
-
- Make a second pass over the mlist, removing all noads and inserting the
- proper spacing and penalties.
-
- We have now tied up all the loose ends of the first pass of
- |mlist_to_hlist|. The second pass simply goes through and hooks
- everything together with the proper glue and penalties. It also handles
- the |fence_noad|s that might be present, since |max_hl| and |max_d| are
- now known. Variable |p| points to a node at the current end of the final
- hlist.
-
- */
- p = temp_head;
- vlink(p) = null;
- q = mlist;
- r_type = 0;
- r_subtype = 0;
- cur_style = style;
- setup_cur_size(cur_style);
- cur_mu = x_over_n(get_math_quad_size(cur_size), 18);
- NEXT_NODE:
- while (q != null) {
- /*tex
-
- If node |q| is a style node, change the style and |goto delete_q|;
- otherwise if it is not a noad, put it into the hlist, advance |q|,
- and |goto done|; otherwise set |s| to the size of noad |q|, set |t|
- to the associated type (|ord_noad.. inner_noad|), and set |pen| to
- the associated penalty.
-
- Just before doing the big |case| switch in the second pass, the
- program sets up default values so that most of the branches are
- short.
-
- */
- t = simple_noad;
- t_subtype = ord_noad_type;
- pen = inf_penalty;
- prepen = inf_penalty;
- switch (type(q)) {
- case simple_noad:
- t_subtype = subtype(q);
- switch (t_subtype) {
- case bin_noad_type:
- pen = bin_op_penalty_par;
- prepen = pre_bin_op_penalty_par;
- break;
- case rel_noad_type:
- pen = rel_penalty_par;
- prepen = pre_rel_penalty_par;
- break;
- case vcenter_noad_type:
- case over_noad_type:
- case under_noad_type:
- t_subtype = ord_noad_type;
- break;
- }
- case radical_noad:
- break;
- case accent_noad:
- break;
- case fraction_noad:
- t = simple_noad;
- t_subtype = inner_noad_type;
- break;
- case fence_noad:
- t_subtype = make_left_right(q, style, max_d, max_hl);
- break;
- case style_node:
- /*tex Change the current style and |goto delete_q| */
- cur_style = subtype(q);
- setup_cur_size(cur_style);
- cur_mu = x_over_n(get_math_quad_style(cur_style), 18);
- goto DELETE_Q;
- break;
- case whatsit_node:
- case penalty_node:
- case rule_node:
- case disc_node:
- case adjust_node:
- case ins_node:
- case mark_node:
- case glue_node:
- case kern_node:
- couple_nodes(p,q);
- p = q;
- q = vlink(q);
- vlink(p) = null;
- goto NEXT_NODE;
- break;
- default:
- confusion("mlist3");
- }
- /*tex Append inter-element spacing based on |r_type| and |t| */
- if (r_type > 0) {
- /*tex not the first noad */
- pp = p;
- if (delimitermodeordinal && t_subtype == inner_noad_type && noadextra4(q) == 1) {
- z = math_spacing_glue(r_subtype, ord_noad_type, cur_style, cur_mu);
- } else {
- z = math_spacing_glue(r_subtype, t_subtype, cur_style, cur_mu);
- }
- if (z != null) {
- reset_attributes(z, node_attr(p));
- couple_nodes(p,z);
- p = z;
- }
- if (penalties && prepen < inf_penalty && type(pp) != penalty_node) {
- /*tex no checking of prev node type */
- z = new_penalty(prepen,noad_penalty);
- reset_attributes(z, node_attr(p));
- couple_nodes(p,z);
- p = z;
- }
- }
- /*tex
-
- Append any |new_hlist| entries for |q|, and any appropriate
- penalties. We insert a penalty node after the hlist entries of noad
- |q| if |pen| is not an ``infinite'' penalty, and if the node
- immediately following |q| is not a penalty node or a |rel_noad| or
- absent entirely.
-
- */
- if (new_hlist(q) != null) {
- couple_nodes(p,new_hlist(q));
- do {
- p = vlink(p);
- } while (vlink(p) != null);
- }
- if (penalties && vlink(q) != null && pen < inf_penalty) {
- r_type = type(vlink(q));
- r_subtype = subtype(vlink(q));
- if (r_type != penalty_node && (r_type != simple_noad || r_subtype != rel_noad_type)) {
- z = new_penalty(pen,noad_penalty);
- reset_attributes(z, node_attr(q));
- couple_nodes(p,z);
- p = z;
- }
- }
- if (type(q) == fence_noad && subtype(q) == right_noad_side) {
- t = simple_noad;
- t_subtype = open_noad_type;
- }
- r_type = t;
- r_subtype = t_subtype;
- DELETE_Q:
- r = q;
- q = vlink(q);
- /*tex
-
- The m-to-hlist conversion takes place in-place, so the various
- dependant fields may not be freed (as would happen if |flush_node|
- was called). A low-level |free_node| is easier than attempting to
- nullify such dependant fields for all possible node and noad types.
-
- */
- if (nodetype_has_attributes(type(r))) {
- delete_attribute_ref(node_attr(r));
- }
- reset_node_properties(r);
- free_node(r, get_node_size(type(r), subtype(r)));
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.h b/Build/source/texk/web2c/luatexdir/tex/mlist.h
deleted file mode 100644
index dc08e0cdd6f..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/mlist.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* mlist.h
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef MLIST_H
-# define MLIST_H 1
-
-extern int cur_size;
-
-extern halfword del_width;
-extern halfword del_height;
-extern halfword del_depth;
-extern halfword del_shift;
-
-extern void run_mlist_to_hlist(halfword, boolean, int);
-extern void mlist_to_hlist(halfword, boolean, int);
-extern void fixup_math_parameters(int fam_id, int size_id, int f, int lvl);
-
-extern scaled get_math_quad_style(int a);
-extern scaled get_math_quad_size(int a);
-
-extern pointer make_extensible(internal_font_number fnt, halfword chr, scaled v, scaled min_overlap, int horizontal, halfword att);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/nesting.c b/Build/source/texk/web2c/luatexdir/tex/nesting.c
deleted file mode 100644
index bbad50b3cdb..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/nesting.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
-
-nesting.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex These are for |show_activities|: */
-
-#define page_goal page_so_far[0]
-
-/*tex
-
-\TeX\ is typically in the midst of building many lists at once. For example, when
-a math formula is being processed, \TeX\ is in math mode and working on an mlist;
-this formula has temporarily interrupted \TeX\ from being in horizontal mode and
-building the hlist of a paragraph; and this paragraph has temporarily interrupted
-\TeX\ from being in vertical mode and building the vlist for the next page of a
-document. Similarly, when a \.{\\vbox} occurs inside of an \.{\\hbox}, \TeX\ is
-temporarily interrupted from working in restricted horizontal mode, and it enters
-internal vertical mode. The ``semantic nest'' is a stack that keeps track of what
-lists and modes are currently suspended.
-
-At each level of processing we are in one of six modes:
-
-|vmode| stands for vertical mode (the page builder);
-
-|hmode| stands for horizontal mode (the paragraph builder);
-
-|mmode| stands for displayed formula mode;
-
-|-vmode| stands for internal vertical mode (e.g., in a \.{\\vbox});
-
-|-hmode| stands for restricted horizontal mode (e.g., in an \.{\\hbox});
-
-|-mmode| stands for math formula mode (not displayed).
-
-The mode is temporarily set to zero while processing \.{\\write} texts in the
-|ship_out| routine.
-
-Numeric values are assigned to |vmode|, |hmode|, and |mmode| so that \TeX's ``big
-semantic switch'' can select the appropriate thing to do by computing the value
-|abs(mode)+cur_cmd|, where |mode| is the current mode and |cur_cmd| is the
-current command code.
-
-*/
-
-static const char *string_mode(int m)
-{
- if (m > 0) {
- switch (m / (max_command_cmd + 1)) {
- case 0:
- return "vertical mode";
- break;
- case 1:
- return "horizontal mode";
- break;
- case 2:
- return "display math mode";
- break;
- default:
- break;
- }
- } else if (m == 0) {
- return "no mode";
- } else {
- switch ((-m) / (max_command_cmd + 1)) {
- case 0:
- return "internal vertical mode";
- break;
- case 1:
- return "restricted horizontal mode";
- break;
- case 2:
- return "math mode";
- break;
- default:
- break;
- }
- }
- return "unknown mode";
-}
-
-void print_mode(int m)
-{
- tprint(string_mode(m));
-}
-
-void print_in_mode(int m)
-{
- tprint("' in ");
- tprint(string_mode(m));
-}
-
-int get_mode_id(void)
-{
- int m = cur_list.mode_field;
- if (m > 0) {
- switch (m / (max_command_cmd + 1)) {
- case 0:
- return 'v';
- break;
- case 1:
- return 'h';
- break;
- case 2:
- return 'm';
- break;
- default:
- return '\0';
- break;
- }
- } else if (m == 0) {
- return 'n';;
- } else {
- switch ((-m) / (max_command_cmd + 1)) {
- case 0:
- return 'V';
- break;
- case 1:
- return 'H';
- break;
- case 2:
- return 'M';
- break;
- default:
- return '\0';
- break;
- }
- }
-}
-
-/*tex
-
-The state of affairs at any semantic level can be represented by five values:
-
-|mode| is the number representing the semantic mode, as just explained.
-
-|head| is a |pointer| to a list head for the list being built; |link(head)|
-therefore points to the first element of the list, or to |null| if the list is
-empty.
-
-|tail| is a |pointer| to the final node of the list being built; thus,
-|tail=head| if and only if the list is empty.
-
-|prev_graf| is the number of lines of the current paragraph that have already
-been put into the present vertical list.
-
-|aux| is an auxiliary |memory_word| that gives further information that is needed
-to characterize the situation.
-
-In vertical mode, |aux| is also known as |prev_depth|; it is the scaled value
-representing the depth of the previous box, for use in baseline calculations, or
-it is |<=-1000|pt if the next box on the vertical list is to be exempt from
-baseline calculations. In horizontal mode, |aux| is also known as |space_factor|;
-it holds the current space factor used in spacing calculations. In math mode,
-|aux| is also known as |incompleat_noad|; if not |null|, it points to a record
-that represents the numerator of a generalized fraction for which the denominator
-is currently being formed in the current list.
-
-There is also a sixth quantity, |mode_line|, which correlates the semantic nest
-with the user's input; |mode_line| contains the source line number at which the
-current level of nesting was entered. The negative of this line number is the
-|mode_line| at the level of the user's output routine.
-
-A seventh quantity, |eTeX_aux|, is used by the extended features eTeX. In math
-mode it is known as |delim_ptr| and points to the most recent |fence_noad| of a
-|math_left_group|.
-
-In horizontal mode, the |prev_graf| field is used for initial language data.
-
-The semantic nest is an array called |nest| that holds the |mode|, |head|,
-|tail|, |prev_graf|, |aux|, and |mode_line| values for all semantic levels below
-the currently active one. Information about the currently active level is kept in
-the global quantities |mode|, |head|, |tail|, |prev_graf|, |aux|, and
-|mode_line|, which live in a struct that is ready to be pushed onto |nest| if
-necessary.
-
-The math field is used by various bits and pieces in |texmath.w|
-
-This implementation of \TeX\ uses two different conventions for representing
-sequential stacks. @^stack conventions@>@^conventions for representing stacks@>
-
-1) If there is frequent access to the top entry, and if the stack is essentially
-never empty, then the top entry is kept in a global variable (even better would
-be a machine register), and the other entries appear in the array
-$\\{stack}[0\to(\\{ptr}-1)]$. The semantic stack is handled this way.
-
-2) If there is infrequent top access, the entire stack contents are in the array
-$\\{stack}[0\to(\\{ptr}-1)]$. For example, the |save_stack| is treated this way,
-as we have seen.
-
-In |nest_ptr| we have the first unused location of |nest|, and |max_nest_stack|
-has the maximum of |nest_ptr| when pushing. In |shown_mode| we store the most
-recent mode shown by \.{\\tracingcommands} and with |save_tail| we can examine
-whether we have an auto kern before a glue.
-
-*/
-
-list_state_record *nest;
-int nest_ptr, max_nest_stack, shown_mode;
-halfword save_tail;
-
-/*tex
-
-We will see later that the vertical list at the bottom semantic level is split
-into two parts; the ``current page'' runs from |page_head| to |page_tail|, and
-the ``contribution list'' runs from |contrib_head| to |tail| of semantic level
-zero. The idea is that contributions are first formed in vertical mode, then
-``contributed'' to the current page (during which time the page-breaking
-decisions are made). For now, we don't need to know any more details about the
-page-building process.
-
-*/
-
-void initialize_nesting(void)
-{
- nest_ptr = 0;
- max_nest_stack = 0;
- shown_mode = 0;
- cur_list.mode_field = vmode;
- cur_list.head_field = contrib_head;
- cur_list.tail_field = contrib_head;
- cur_list.eTeX_aux_field = null;
- cur_list.prev_depth_field = ignore_depth;
- cur_list.space_factor_field = 1000;
- cur_list.incompleat_noad_field = null;
- cur_list.ml_field = 0;
- cur_list.pg_field = 0;
- cur_list.dirs_field = null;
- init_math_fields();
-}
-
-/*tex
-
-Here is a common way to make the current list grow:
-
-*/
-
-void tail_append(halfword p)
-{
- couple_nodes(cur_list.tail_field, p);
- cur_list.tail_field = vlink(cur_list.tail_field);
-}
-
-halfword pop_tail(void)
-{
- halfword n, r;
- if (cur_list.tail_field != cur_list.head_field) {
- r = cur_list.tail_field;
- if (vlink(alink(cur_list.tail_field)) == cur_list.tail_field) {
- n = alink(cur_list.tail_field);
- } else {
- n = cur_list.head_field;
- while (vlink(n) != cur_list.tail_field)
- n = vlink(n);
- }
- cur_list.tail_field = n;
- alink(r) = null;
- vlink(n) = null;
- return r;
- } else {
- return null;
- }
-}
-
-/*tex
-
-When \TeX's work on one level is interrupted, the state is saved by calling
-|push_nest|. This routine changes |head| and |tail| so that a new (empty) list is
-begun; it does not change |mode| or |aux|.
-
-*/
-
-void push_nest(void)
-{
- if (nest_ptr > max_nest_stack) {
- max_nest_stack = nest_ptr;
- if (nest_ptr == nest_size)
- overflow("semantic nest size", (unsigned) nest_size);
- }
- incr(nest_ptr);
- cur_list.mode_field = nest[nest_ptr - 1].mode_field;
- cur_list.head_field = new_node(temp_node, 0);
- cur_list.tail_field = cur_list.head_field;
- cur_list.eTeX_aux_field = null;
- cur_list.ml_field = line;
- cur_list.pg_field = 0;
- cur_list.dirs_field = null;
- cur_list.prev_depth_field = nest[nest_ptr - 1].prev_depth_field;
- cur_list.space_factor_field = nest[nest_ptr - 1].space_factor_field;
- cur_list.incompleat_noad_field = nest[nest_ptr - 1].incompleat_noad_field;
- init_math_fields();
-}
-
-/*tex
-
-Conversely, when \TeX\ is finished on the current level, the former state is
-restored by calling |pop_nest|. This routine will never be called at the lowest
-semantic level, nor will it be called unless |head| is a node that should be
-returned to free memory.
-
-*/
-
-void pop_nest(void)
-{
- flush_node(cur_list.head_field);
- decr(nest_ptr);
-}
-
-/*tex
-
-Here is a procedure that displays what \TeX\ is working on, at all levels.
-
-*/
-
-void show_activities(void)
-{
- /*tex Index into |nest|: */
- int p;
- /*tex The mode: */
- int m;
- /*tex For showing the current page: */
- halfword q, r;
- /*tex Ditto: */
- int t;
- tprint_nl("");
- print_ln();
- for (p = nest_ptr; p >= 0; p--) {
- m = nest[p].mode_field;
- tprint_nl("### ");
- print_mode(m);
- tprint(" entered at line ");
- print_int(abs(nest[p].ml_field));
- if (nest[p].ml_field < 0)
- tprint(" (\\output routine)");
- if (p == 0) {
- /*tex Show the status of the current page */
- if (page_head != page_tail) {
- tprint_nl("### current page:");
- if (output_active)
- tprint(" (held over for next output)");
- show_box(vlink(page_head));
- if (page_contents > empty) {
- tprint_nl("total height ");
- print_totals();
- tprint_nl(" goal height ");
- print_scaled(page_goal);
- r = vlink(page_ins_head);
- while (r != page_ins_head) {
- print_ln();
- tprint_esc("insert");
- t = subtype(r);
- print_int(t);
- tprint(" adds ");
- if (count(t) == 1000)
- t = height(r);
- else
- t = x_over_n(height(r), 1000) * count(t);
- print_scaled(t);
- if (type(r) == split_up_node) {
- q = page_head;
- t = 0;
- do {
- q = vlink(q);
- if ((type(q) == ins_node)
- && (subtype(q) == subtype(r)))
- incr(t);
- } while (q != broken_ins(r));
- tprint(", #");
- print_int(t);
- tprint(" might split");
- }
- r = vlink(r);
- }
- }
- }
- if (vlink(contrib_head) != null)
- tprint_nl("### recent contributions:");
- }
- show_box(vlink(nest[p].head_field));
- /*tex Show the auxiliary field, |a|. */
- switch (abs(m) / (max_command_cmd + 1)) {
- case 0:
- tprint_nl("prevdepth ");
- if (nest[p].prev_depth_field <= ignore_depth)
- tprint("ignored");
- else
- print_scaled(nest[p].prev_depth_field);
- if (nest[p].pg_field != 0) {
- tprint(", prevgraf ");
- print_int(nest[p].pg_field);
- if (nest[p].pg_field != 1)
- tprint(" lines");
- else
- tprint(" line");
- }
- break;
- case 1:
- tprint_nl("spacefactor ");
- print_int(nest[p].space_factor_field);
- break;
- case 2:
- if (nest[p].incompleat_noad_field != null) {
- tprint("this will be denominator of:");
- show_box(nest[p].incompleat_noad_field);
- }
- break;
- }
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/nesting.h b/Build/source/texk/web2c/luatexdir/tex/nesting.h
deleted file mode 100644
index 238522a77d1..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/nesting.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* nesting.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef NESTING_H
-# define NESTING_H
-
-# define vmode 1 /* vertical mode */
-# define hmode (vmode+max_command_cmd+1)
- /* horizontal mode */
-# define mmode (hmode+max_command_cmd+1)
- /* math mode */
-
-extern void print_mode(int m);
-extern void print_in_mode(int m);
-extern int get_mode_id(void);
-
-# define ignore_depth -65536000 /* magic dimension value to mean `ignore me' */
-
-typedef struct list_state_record_ {
- int mode_field;
- halfword head_field;
- halfword tail_field;
- halfword eTeX_aux_field;
- int pg_field;
- int ml_field;
- halfword prev_depth_field;
- halfword space_factor_field;
- halfword incompleat_noad_field;
- halfword dirs_field;
- int math_field;
- int math_style_field;
-} list_state_record;
-
-extern list_state_record *nest;
-extern int nest_ptr;
-extern int max_nest_stack;
-# define cur_list nest[nest_ptr]
- /* the ``top'' semantic state */
-extern int shown_mode;
-extern halfword save_tail;
-
-extern void push_nest(void);
-extern void pop_nest(void);
-extern void initialize_nesting(void);
-
-extern void tail_append(halfword p);
-extern halfword pop_tail(void);
-
-
-extern void show_activities(void);
-
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.c b/Build/source/texk/web2c/luatexdir/tex/packaging.c
deleted file mode 100644
index 3d23c8b7320..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/packaging.c
+++ /dev/null
@@ -1,2145 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
- We're essentially done with the parts of \TeX\ that are concerned with the
- input (|get_next|) and the output (|ship_out|). So it's time to get heavily
- into the remaining part, which does the real work of typesetting.
-
- After lists are constructed, \TeX\ wraps them up and puts them into boxes.
- Two major subroutines are given the responsibility for this task: |hpack|
- applies to horizontal lists (hlists) and |vpack| applies to vertical lists
- (vlists). The main duty of |hpack| and |vpack| is to compute the dimensions
- of the resulting boxes, and to adjust the glue if one of those dimensions is
- pre-specified. The computed sizes normally enclose all of the material inside
- the new box; but some items may stick out if negative glue is used, if the
- box is overfull, or if a \.{\\vbox} includes other boxes that have been
- shifted left.
-
- The subroutine call |hpack(p,w,m)| returns a pointer to an |hlist_node| for a
- box containing the hlist that starts at |p|. Parameter |w| specifies a width;
- and parameter |m| is either `|exactly|' or `|additional|'. Thus,
- |hpack(p,w,exactly)| produces a box whose width is exactly |w|, while
- |hpack(p,w,additional)| yields a box whose width is the natural width plus
- |w|. It is convenient to define a macro called `|natural|' to cover the most
- common case, so that we can say |hpack(p,natural)| to get a box that has the
- natural width of list |p|.
-
- Similarly, |vpack(p,w,m)| returns a pointer to a |vlist_node| for a box
- containing the vlist that starts at |p|. In this case |w| represents a height
- instead of a width; the parameter |m| is interpreted as in |hpack|.
-
- The parameters to |hpack| and |vpack| correspond to \TeX's primitives like
- `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note that
- `\.{\\hbox}' with no dimension following it is equivalent to `\.{\\hbox}
- \.{spread} \.{0pt}'. The |scan_spec| subroutine scans such constructions in
- the user's input, including the mandatory left brace that follows them, and
- it puts the specification onto |save_stack| so that the desired box can later
- be obtained by executing the following code: $$\vbox{\halign{#\hfil\cr
- |save_ptr:=save_ptr-1;|\cr |hpack(p,saved_value(0),saved_level(0)).|\cr}}$$
-
-*/
-
-/*tex Scan a box specification and left brace: */
-
-void scan_spec(group_code c)
-{
- int spec_code;
- boolean done = false ;
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd == left_brace_cmd) {
- spec_code = additional;
- cur_val = 0;
- done = true;
- } else {
- /*tex todo: attr */
- back_input();
- if (scan_keyword("to")) {
- spec_code = exactly;
- scan_normal_dimen();
- } else if (scan_keyword("spread")) {
- spec_code = additional;
- scan_normal_dimen();
- } else {
- spec_code = additional;
- cur_val = 0;
- }
- }
- set_saved_record(0, saved_boxspec, spec_code, cur_val);
- save_ptr++;
- new_save_level(c);
- if (!done) {
- scan_left_brace();
- }
-}
-
-/*tex
-
- When scanning, special care is necessary to ensure that the special
- |save_stack| codes are placed just below the new group code, because scanning
- can change |save_stack| when \.{\\csname} appears.
-
- This coincides with the text on |dir| and |attr| keywords, as these are
- exaclty the uses of \.{\\hbox}, \.{\\vbox}, and \.{\\vtop} in the input
- stream (the others are \.{\\vcenter}, \.{\\valign}, and \.{\\halign}).
-
-*/
-
-/*tex Scan a box specification and left brace: */
-
-#define first_char_is(a,A) (cur_cs == 0 && (cur_chr == a || cur_chr == A))
-
-void scan_full_spec(group_code c, int spec_direction, int just_pack)
-{
- int s, i, v, spec_code;
- boolean done = false ;
- halfword attr_list;
- boolean attr_done = false ;
- boolean dir_done = false ;
- if (attr_list_cache == cache_disabled)
- update_attribute_cache();
- attr_list = attr_list_cache;
- /*tex The box context: */
- s = saved_value(0);
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd == left_brace_cmd) {
- goto QUICK;
- } else {
- back_input();
- goto KEYWORDS;
- }
- CONTINUE:
- while (cur_cmd == relax_cmd || cur_cmd == spacer_cmd) {
- get_x_token();
- if (cur_cmd == left_brace_cmd) {
- goto QUICK;
- } else if (cur_cmd != relax_cmd && cur_cmd != spacer_cmd) {
- back_input();
- break;
- }
- }
- KEYWORDS:
- /*tex Multiple |attr| keys possible (before or after dir). */
- if (scan_keyword("attr")) {
- scan_register_num();
- i = cur_val;
- scan_optional_equals();
- scan_int();
- v = cur_val;
- if (! attr_done) {
- attr_list = copy_attribute_list(attr_list_cache);
- attr_done = true;
- }
- attr_list = do_set_attribute(attr_list, i, v);
- goto CONTINUE;
- }
- /*tex We only permit one |(b)dir| directive. */
- if (! dir_done) {
- if (scan_keyword("bdir")) {
- scan_int();
- check_dir_value(cur_val);
- spec_direction = cur_val;
- dir_done = true;
- goto CONTINUE;
- }
- if (scan_keyword("dir")) {
- scan_direction();
- spec_direction = cur_val;
- dir_done = true;
- goto CONTINUE;
- }
- }
- /*tex Only one |to| or |spread| key possible and it comes last. */
- if (scan_keyword("to")) {
- spec_code = exactly;
- } else if (scan_keyword("spread")) {
- spec_code = additional;
- } else {
- spec_code = additional;
- cur_val = 0;
- goto FOUND;
- }
- scan_normal_dimen();
- goto FOUND;
- QUICK:
- spec_code = additional;
- cur_val = 0;
- done = true;
- FOUND:
- add_node_attr_ref(attr_list);
- set_saved_record(0, saved_boxcontext, 0, s);
- set_saved_record(1, saved_boxspec, spec_code, cur_val);
- /*tex Adjust |text_dir_ptr| for |scan_spec|. */
- if (spec_direction != -1) {
- set_saved_record(2, saved_boxdir, spec_direction, text_dir_ptr);
- text_dir_ptr = new_dir(spec_direction);
- } else {
- set_saved_record(2, saved_boxdir, spec_direction, null);
- }
- set_saved_record(3, saved_boxattr, 0, attr_list);
- set_saved_record(4, saved_boxpack, 0, just_pack);
- save_ptr += 5;
- new_save_level(c);
- if (! done) {
- scan_left_brace();
- }
- /*tex No gain in |if (body_direction_par != spec_direction)| etc. */
- eq_word_define(int_base + body_direction_code, spec_direction);
- eq_word_define(int_base + par_direction_code, spec_direction);
- eq_word_define(int_base + text_direction_code, spec_direction);
-}
-
-/*tex
-
- To figure out the glue setting, |hpack| and |vpack| determine how much
- stretchability and shrinkability are present, considering all four orders of
- infinity. The highest order of infinity that has a nonzero coefficient is
- then used as if no other orders were present.
-
- For example, suppose that the given list contains six glue nodes with the
- respective stretchabilities 3pt, 8fill, 5fil, 6pt, $-3$fil, $-8$fill. Then
- the total is essentially 2fil; and if a total additional space of 6pt is to
- be achieved by stretching, the actual amounts of stretch will be 0pt, 0pt,
- 15pt, 0pt, $-9$pt, and 0pt, since only `fil' glue will be considered. (The
- `fill' glue is therefore not really stretching infinitely with respect to
- `fil'; nobody would actually want that to happen.)
-
- The arrays |total_stretch| and |total_shrink| are used to determine how much
- glue of each kind is present. A global variable |last_badness| is used to
- implement \.{\\badness}.
-
-*/
-
-/*tex Glue found by |hpack| or |vpack|. */
-
-scaled total_stretch[5];
-scaled total_shrink[5];
-
-/*tex Badness of the most recently packaged box. */
-
-int last_badness;
-
-/*tex
-
- If the global variable |adjust_tail| is non-null, the |hpack| routine also
- removes all occurrences of |ins_node|, |mark_node|, and |adjust_node| items
- and appends the resulting material onto the list that ends at location
- |adjust_tail|.
-
-*/
-
-/*tex Tail of adjustment list. */
-
-halfword adjust_tail;
-
-/*tex
-
- Materials in \.{\\vadjust} used with \.{pre} keyword will be appended to
- |pre_adjust_tail| instead of |adjust_tail|.
-
-*/
-
-halfword pre_adjust_tail;
-
-halfword last_leftmost_char;
-halfword last_rightmost_char;
-
-/*tex Pointers to the prev and next char of an implicit kern. */
-
-halfword next_char_p;
-halfword prev_char_p;
-
-/*tex This procedure is called repeatedly from inside the line break algorithm. */
-
-void set_prev_char_p(halfword p)
-{
- prev_char_p = p;
-}
-
-/*tex
-
- The kern stretch / shrink code was (or had become) rather weird ... the width
- field is set, and then used in a second calculation, repeatedly, so why is
- that ... maybe some some weird left-over ... anyway, the values are so small
- that in practice they are not significant at all when the backend sees them
- because a few hundred sp positive or negative are just noise there (so
- adjustlevel 3 has hardly any consequence for the result but is more
- efficient).
-
-*/
-
-scaled char_stretch(halfword p)
-{
- internal_font_number f = font(p);
- int m = font_max_stretch(f);
- if (m > 0) {
- int c = character(p);
- int ef = get_ef_code(f, c);
- if (ef > 0) {
- scaled dw = calc_char_width(f, c, m) - char_width(f, c);
- if (dw > 0) {
- return round_xn_over_d(dw, ef, 1000);
- }
- }
- }
- return 0;
-}
-
-scaled char_shrink(halfword p)
-{
- internal_font_number f = font(p);
- int m = font_max_shrink(f);
- if (m > 0) {
- int c = character(p);
- int ef = get_ef_code(f, c);
- if (ef > 0) {
- scaled dw = char_width(f, c) - calc_char_width(f, c, -m);
- if (dw > 0) {
- return round_xn_over_d(dw, ef, 1000);
- }
- }
- }
- return 0;
-}
-
-scaled kern_stretch(halfword p)
-{
- int m;
- scaled d, e, x;
- scaled w = width(p) ;
- halfword l;
- halfword r;
- if (w == 0) {
- /*tex Why bother about zero kerns. */
- return 0;
- }
- l = prev_char_p ;
- if ((l == null) || (vlink(l) != p)) {
- /*tex We only care about kerns following a char. */
- return 0;
- }
- r = vlink(p);
- if (r == null) {
- /*tex We only care about kerns between a char and something else. */
- }
- if (!(is_char_node(l) && is_char_node(r))) {
- /*tex We want two chars (but but don't care about the fonts). */
- return 0;
- }
- /*tex We use the old logic, kind of, but average the ef as we might depend on proper overlap. */
- m = (font_max_stretch(font(l)) + font_max_stretch(font(r)))/2;
- if (m == 0) {
- /*tex nothing to kern */
- return 0;
- }
- d = round_xn_over_d(w, 1000 + m, 1000);
- /*tex We use the old logic, kind of, but average the ef as we might depend on proper overlap. */
- e = (get_ef_code(font(l), character(l)) + get_ef_code(font(r), character(r)))/2 ;
- if (e == 1000) {
- x = d - w;
- } else {
- x = round_xn_over_d(d - w, e, 1000);
- }
- return x;
-}
-
-scaled kern_shrink(halfword p)
-{
- int m;
- scaled d, e, x;
- scaled w = width(p) ;
- halfword l;
- halfword r;
- if (w == 0) {
- /*tex Why bother about zero kerns. */
- return 0;
- }
- l = prev_char_p ;
- if ((l == null) || (vlink(l) != p)) {
- /*tex We only care about kerns following a char. */
- return 0;
- }
- r = vlink(p);
- if (r == null) {
- /*tex We only care about kerns between a char and something else. */
- }
- if (!(is_char_node(l) && is_char_node(r))) {
- /*tex We want two chars (but but don't care about the fonts). */
- return 0;
- }
- /*tex We use the old logic, kind of, but average the ef as we might depend on proper overlap. */
- m = (font_max_shrink(font(l)) + font_max_shrink(font(r)))/2;
- if (m == 0) {
- /*tex Nothing to kern. */
- return 0;
- }
- d = round_xn_over_d(w, 1000 - m, 1000);
- e = (get_ef_code(font(l), character(l)) + get_ef_code(font(r), character(r)))/2 ;
- if (e == 1000) {
- x = w - d ;
- } else {
- x = round_xn_over_d(w - d, e, 1000);
- }
- return x;
-}
-
-void do_subst_font(halfword p, int ex_ratio)
-{
- if (type(p) == disc_node) {
- halfword r = vlink(pre_break(p));
- while (r != null) {
- if (is_char_node(r))
- do_subst_font(r, ex_ratio);
- r = vlink(r);
- }
- r = vlink(post_break(p));
- while (r != null) {
- if (is_char_node(r))
- do_subst_font(r, ex_ratio);
- r = vlink(r);
- }
- r = vlink(no_break(p));
- while (r != null) {
- if (is_char_node(r))
- do_subst_font(r, ex_ratio);
- r = vlink(r);
- }
- return;
- }
- if (! is_char_node(p)) {
- normal_error("font expansion", "invalid node type");
- return;
- } else {
- internal_font_number f = font(p);
- int ef = get_ef_code(f, character(p));
- if (ef == 0)
- return;
- if ((font_max_stretch(f) > 0) && (ex_ratio > 0)) {
- int ex_stretch = ext_xn_over_d(ex_ratio * ef, font_max_stretch(f), 1000000);
- ex_glyph(p) = fix_expand_value(f, ex_stretch)*1000;
- } else if ((font_max_shrink(f) > 0) && (ex_ratio < 0)) {
- int ex_shrink = ext_xn_over_d(ex_ratio * ef, font_max_shrink(f), 1000000);
- ex_glyph(p) = fix_expand_value(f, ex_shrink)*1000;
- }
- }
-}
-
-scaled char_pw(halfword p, int side)
-{
- internal_font_number f;
- int c, w;
- if (side == left_side)
- last_leftmost_char = null;
- else
- last_rightmost_char = null;
- if (p == null)
- return 0;
- if (!is_char_node(p))
- return 0;
- f = font(p);
- if (side == left_side) {
- c = get_lp_code(f, character(p));
- last_leftmost_char = p;
- } else {
- c = get_rp_code(f, character(p));
- last_rightmost_char = p;
- }
- if (c == 0)
- return 0;
- w = quad(f);
- return round_xn_over_d(w, c, 1000);
-}
-
-halfword new_margin_kern(scaled w, halfword p, int side)
-{
- halfword k, q;
- k = new_node(margin_kern_node, side);
- width(k) = w;
- if (p == null)
- normal_error("margin kerning", "invalid pointer to marginal char node");
- q = new_char(font(p), character(p));
- margin_char(k) = q;
- return k;
-}
-
-/*tex
-
- Here we prepare for |hpack|, which is place where we do font substituting
- when font expansion is being used.
-
-*/
-
-/*tex The current expansion ratio, needed for recursive call. */
-
-int font_expand_ratio = 0;
-
-int ignore_math_skip(halfword p)
-{
- if (math_skip_mode == 6) {
- if (subtype(p) == after) {
- if (math_skip_boundary(vlink(p))) {
- return 0;
- }
- } else {
- if (math_skip_boundary(alink(p))) {
- return 0;
- }
- }
- } else if (math_skip_mode == 7) {
- if (subtype(p) == after) {
- if (! math_skip_boundary(vlink(p))) {
- return 0;
- }
- } else {
- if (! math_skip_boundary(alink(p))) {
- return 0;
- }
- }
- } else {
- return 0;
- }
- reset_glue_to_zero(p);
- return 1;
-}
-
-halfword hpack(halfword p, scaled w, int m, int pack_direction)
-{
- /*tex the box node that will be returned */
- halfword r;
- /*tex trails behind |p| */
- halfword q;
- /*tex height */
- scaled h = 0;
- /*tex depth */
- scaled d = 0;
- /*tex natural width */
- scaled x = 0;
- scaled_whd whd;
- /*tex shift amount */
- scaled s;
- /*tex order of infinity */
- int o;
- /*tex for managing the direction stack */
- halfword dir_ptr1 = null;
- /*tex the current direction */
- int hpack_dir;
- int disc_level = 0;
- halfword pack_interrupt[8];
- scaled font_stretch = 0;
- scaled font_shrink = 0;
- int adjust_spacing = adjust_spacing_par;
- last_badness = 0;
- /*tex the box node that will be returned */
- r = new_node(hlist_node, min_quarterword);
- if (pack_direction == -1) {
- hpack_dir = text_direction_par;
- } else {
- hpack_dir = pack_direction;
- }
- box_dir(r) = hpack_dir;
- /*tex
-
- A potential optimimization, save a little but neglectable in practice
- (not so many empty boxes are used):
-
- \starttyping
- if (p == null) {
- width(r) = w;
- return r;
- }
- \stoptyping
-
- */
- /*tex push null */
- push_dir(dir_ptr1,hpack_dir);
- /*tex hm, adding something to a node address? */
- q = r + list_offset;
- vlink(q) = p;
- if (m == cal_expand_ratio) {
- /*tex Why not always: */
- prev_char_p = null;
- }
- if (adjust_spacing > 2) {
- adjust_spacing = 0;
- }
- total_stretch[normal] = 0;
- total_shrink[normal] = 0;
- total_stretch[sfi] = 0;
- total_shrink[sfi] = 0;
- total_stretch[fil] = 0;
- total_shrink[fil] = 0;
- total_stretch[fill] = 0;
- total_shrink[fill] = 0;
- total_stretch[filll] = 0;
- total_shrink[filll] = 0;
- RESWITCH:
- while ((p != null) || (disc_level > 0)) {
- if (p == null) {
- decr(disc_level);
- p = pack_interrupt[disc_level];
- goto RESWITCH;
- }
- /*tex
-
- Examine node |p| in the hlist, taking account of its effect on the
- dimensions of the new box, or moving it to the adjustment list; then
- advance |p| to the next node.
-
- */
- while (is_char_node(p)) {
- /*tex
-
- Incorporate character dimensions into the dimensions of the hbox
- that will contain~it, then move to the next node.
-
- The following code is part of \TeX's inner loop; i.e., adding
- another character of text to the user's input will cause each of
- these instructions to be exercised one more time.
-
- */
- if (m >= cal_expand_ratio) {
- prev_char_p = p;
- if (m == cal_expand_ratio) {
- font_stretch += char_stretch(p);
- font_shrink += char_shrink(p);
- } else if (m == subst_ex_font) {
- do_subst_font(p, font_expand_ratio);
- }
- }
- whd = pack_width_height_depth(hpack_dir, dir_TRT, p, true);
- x += whd.wd;
- if (whd.ht > h)
- h = whd.ht;
- if (whd.dp > d)
- d = whd.dp;
- p = vlink(p);
- }
- if (p != null) {
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- /*tex
-
- Incorporate box dimensions into the dimensions of the
- hbox that will contain~it
-
- The code here implicitly uses the fact that running
- dimensions are indicated by |null_flag|, which will be
- ignored in the calculations because it is a highly
- negative number.
-
- */
- s = shift_amount(p);
- whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false);
- x += whd.wd;
- if (whd.ht - s > h)
- h = whd.ht - s;
- if (whd.dp + s > d)
- d = whd.dp + s;
- break;
- case rule_node:
- case unset_node:
- x += width(p);
- if (height(p) > h)
- h = height(p);
- if (depth(p) > d)
- d = depth(p);
- break;
- case math_node:
- /*tex Begin mathskip code. */
- if (glue_is_zero(p) || ignore_math_skip(p)) {
- x += surround(p);
- break;
- } else {
- /*tex Fall through. */
- }
- /*tex End mathskip code. */
- case glue_node:
- /*tex Incorporate glue into the horizontal totals. */
- x += width(p);
- o = stretch_order(p);
- total_stretch[o] = total_stretch[o] + stretch(p);
- o = shrink_order(p);
- total_shrink[o] = total_shrink[o] + shrink(p);
- if (subtype(p) >= a_leaders) {
- halfword g = leader_ptr(p);
- if (height(g) > h)
- h = height(g);
- if (depth(g) > d)
- d = depth(g);
- }
- break;
- case kern_node:
- x += width(p);
- if (subtype(p) == font_kern && adjust_spacing) {
- /*tex So only when 1 or 2. */
- if (m == cal_expand_ratio) {
- font_stretch = font_stretch + kern_stretch(p);
- font_shrink = font_shrink + kern_shrink(p);
- } else if (m == subst_ex_font) {
- /*tex This is the finalizer. */
- int k = 0;
- if (font_expand_ratio > 0) {
- k = kern_stretch(p);
- } else if (font_expand_ratio < 0) {
- k = kern_shrink(p);
- }
- ex_kern(p) = k;
- x += k;
- }
- }
- break;
- case disc_node:
- if (m == subst_ex_font)
- do_subst_font(p, font_expand_ratio);
- if ((subtype(p) != select_disc) && (vlink(no_break(p)) != null)) {
- pack_interrupt[disc_level] = vlink(p);
- incr(disc_level);
- p = no_break(p);
- }
- break;
- case dir_node:
- /*tex Adjust the dir stack for the |hpack| routine. */
- if (subtype(p) == normal_dir) {
- hpack_dir = dir_dir(p);
- push_dir_node(dir_ptr1,p);
- } else {
- pop_dir_node(dir_ptr1);
- if (dir_ptr1 != null)
- hpack_dir = dir_dir(dir_ptr1);
- }
- break;
- case margin_kern_node:
- if (m == cal_expand_ratio) {
- int f = font(margin_char(p));
- do_subst_font(margin_char(p), 1000);
- if (f != font(margin_char(p)))
- font_stretch = font_stretch - width(p) - char_pw(margin_char(p), subtype(p));
- font(margin_char(p)) = f;
- do_subst_font(margin_char(p), -1000);
- if (f != font(margin_char(p)))
- font_shrink = font_shrink - width(p) - char_pw(margin_char(p), subtype(p));
- font(margin_char(p)) = f;
- } else if (m == subst_ex_font) {
- do_subst_font(margin_char(p), font_expand_ratio);
- width(p) = -char_pw(margin_char(p), subtype(p));
- }
- x += width(p);
- break;
- case ins_node:
- case mark_node:
- case adjust_node:
- /*tex
-
- Transfer node |p| to the adjustment list.\Although node
- |q| is not necessarily the immediate predecessor of node
- |p|, it always points to some node in the list preceding
- |p|. Thus, we can delete nodes by moving |q| when
- necessary. The algorithm takes linear time, and the extra
- computation does not intrude on the inner loop unless it
- is necessary to make a deletion.
-
- */
- if (adjust_tail != null || pre_adjust_tail != null) {
- while (vlink(q) != p)
- q = vlink(q);
- if (type(p) == adjust_node) {
- if (adjust_pre(p) != 0)
- update_adjust_list(pre_adjust_tail);
- else
- update_adjust_list(adjust_tail);
- p = vlink(p);
- adjust_ptr(vlink(q)) = null;
- flush_node(vlink(q));
- } else {
- vlink(adjust_tail) = p;
- adjust_tail = p;
- p = vlink(p);
- }
- vlink(q) = p;
- p = q;
- }
- break;
- default:
- break;
- }
- p = vlink(p);
- }
- }
-
- if (adjust_tail != null)
- vlink(adjust_tail) = null;
- if (pre_adjust_tail != null)
- vlink(pre_adjust_tail) = null;
- height(r) = h;
- depth(r) = d;
- /*tex
-
- Determine the value of |width(r)| and the appropriate glue setting; then
- |return| or |goto common_ending|.
-
- When we get to the present part of the program, |x| is the natural width
- of the box being packaged.
-
- */
- if (m == additional)
- w = x + w;
- width(r) = w;
- x = w - x;
- /*tex Now |x| is the excess to be made up. */
- if (x == 0) {
- glue_sign(r) = normal;
- glue_order(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- goto EXIT;
- } else if (x > 0) {
- /*tex
-
- Determine horizontal glue stretch setting, then |return| or
- |goto common_ending|.
-
- If |hpack| is called with |m=cal_expand_ratio| we calculate
- |font_expand_ratio| and return without checking for overfull or
- underfull box.
-
- */
- if (total_stretch[filll] != 0)
- o = filll;
- else if (total_stretch[fill] != 0)
- o = fill;
- else if (total_stretch[fil] != 0)
- o = fil;
- else if (total_stretch[sfi] != 0)
- o = sfi;
- else
- o = normal;
- if ((m == cal_expand_ratio) && (o == normal) && (font_stretch > 0)) {
- font_expand_ratio = divide_scaled_n(x, font_stretch, 1000.0);
- goto EXIT;
- }
- glue_order(r) = (quarterword) o;
- glue_sign(r) = stretching;
- if (total_stretch[o] != 0) {
- glue_set(r) = unfloat((double) x / total_stretch[o]);
- } else {
- /*tex There's nothing to stretch. */
- glue_sign(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- }
- if (o == normal) {
- if (list_ptr(r) != null) {
- /*tex
-
- Report an underfull hbox and |goto common_ending|, if this
- box is sufficiently bad.
-
- */
- last_badness = badness(x, total_stretch[normal]);
- if (last_badness > hbadness_par) {
- int callback_id = callback_defined(hpack_quality_callback);
- if (callback_id > 0) {
- halfword rule = null;
- if (last_badness > 100) {
- run_callback(callback_id, "SdNdd->N","underfull",last_badness,r,abs(pack_begin_line),line,&rule);
- } else {
- run_callback(callback_id, "SdNdd->N","loose",last_badness,r,abs(pack_begin_line),line,&rule);
- }
- if (rule != null) {
- while (vlink(q) != null) {
- q = vlink(q);
- }
- couple_nodes(q,rule);
- }
- } else {
- print_ln();
- if (last_badness > 100) {
- tprint_nl("Underfull \\hbox (badness ");
- } else {
- tprint_nl("Loose \\hbox (badness ");
- }
- print_int(last_badness);
- goto COMMON_ENDING;
- }
- }
- }
- }
- goto EXIT;
- } else {
- /*tex
-
- Determine horizontal glue shrink setting, then |return| or |goto
- common_ending|,
-
- */
- if (total_shrink[filll] != 0)
- o = filll;
- else if (total_shrink[fill] != 0)
- o = fill;
- else if (total_shrink[fil] != 0)
- o = fil;
- else if (total_shrink[sfi] != 0)
- o = sfi;
- else
- o = normal;
- if ((m == cal_expand_ratio) && (o == normal) && (font_shrink > 0)) {
- font_expand_ratio = divide_scaled_n(x, font_shrink, 1000.0);
- goto EXIT;
- }
- glue_order(r) = (quarterword) o;
- glue_sign(r) = shrinking;
- if (total_shrink[o] != 0) {
- glue_set(r) = unfloat((double) (-x) / (double) total_shrink[o]);
- } else {
- /*tex There's nothing to shrink. */
- glue_sign(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- }
- if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) {
- int overshoot = -x - total_shrink[normal] ;
- last_badness = 1000000;
- /*tex Use the maximum shrinkage */
- set_glue_ratio_one(glue_set(r));
- /*tex
-
- Report an overfull hbox and |goto common_ending|, if this box is
- sufficiently bad.
-
- */
- if ((overshoot > hfuzz_par) || (hbadness_par < 100)) {
- int callback_id = callback_defined(hpack_quality_callback);
- halfword rule = null;
- if (callback_id > 0) {
- run_callback(callback_id, "SdNdd->N","overfull",overshoot,r,abs(pack_begin_line),line,&rule);
- } else if (overfull_rule_par > 0) {
- rule = new_rule(normal_rule);
- rule_dir(rule) = box_dir(r);
- width(rule) = overfull_rule_par;
- }
- if (rule != null) {
- while (vlink(q) != null) {
- q = vlink(q);
- }
- couple_nodes(q,rule);
- }
- if (callback_id == 0) {
- print_ln();
- tprint_nl("Overfull \\hbox (");
- print_scaled(overshoot);
- tprint("pt too wide");
- goto COMMON_ENDING;
- }
- }
- } else if (o == normal) {
- if (list_ptr(r) != null) {
- /*tex
-
- Report a tight hbox and |goto common_ending|, if this box is
- sufficiently bad.
-
- */
- last_badness = badness(-x, total_shrink[normal]);
- if (last_badness > hbadness_par) {
- int callback_id = callback_defined(hpack_quality_callback);
- if (callback_id > 0) {
- halfword rule = null;
- run_callback(callback_id, "SdNdd->N","tight",last_badness,r,abs(pack_begin_line),line,&rule);
- if (rule != null) {
- while (vlink(q) != null) {
- q = vlink(q);
- }
- couple_nodes(q,rule);
- }
- } else {
- print_ln();
- tprint_nl("Tight \\hbox (badness ");
- print_int(last_badness);
- goto COMMON_ENDING;
- }
- }
- }
- }
- goto EXIT;
- }
-
- COMMON_ENDING:
- /*tex Finish issuing a diagnostic message for an overfull or underfull hbox. */
- if (output_active) {
- tprint(") has occurred while \\output is active");
- } else {
- if (pack_begin_line != 0) {
- if (pack_begin_line > 0) {
- tprint(") in paragraph at lines ");
- } else {
- tprint(") in alignment at lines ");
- }
- print_int(abs(pack_begin_line));
- tprint("--");
- } else {
- tprint(") detected at line ");
- }
- print_int(line);
- }
-
- print_ln();
- font_in_short_display = null_font;
- short_display(list_ptr(r));
- print_ln();
- begin_diagnostic();
- show_box(r);
- end_diagnostic(true);
- EXIT:
- if ((m == cal_expand_ratio) && (font_expand_ratio != 0)) {
- font_expand_ratio = fix_int(font_expand_ratio, -1000, 1000);
- q = list_ptr(r);
- list_ptr(r) = null;
- flush_node(r);
- /*tex This nested call uses the more or less global font_expand_ratio. */
- r = hpack(q, w, subst_ex_font, hpack_dir);
- }
- while (dir_ptr1 != null)
- pop_dir_node(dir_ptr1);
- /*tex Here we reset the |font_expand_ratio|. */
- font_expand_ratio = 0;
- return r;
-}
-
-halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, int pac, int just_pack, halfword attr)
-{
- halfword q;
- if (just_pack) {
- q = vlink(p);
- } else if (type(p) == temp_node && vlink(p) == null) {
- q = vlink(p);
- } else {
- new_hyphenation(p, qt);
- /*tex We don't care about the tail in this case. */
- (void) new_ligkern(p, qt);
- q = vlink(p);
- /*tex Maybe here: |alink(p) = null|. */
- /*tex ignores empty anyway. Maybe also pass tail? */
- q = lua_hpack_filter(q, w, m, grp, pac, attr);
- }
- return hpack(q, w, m, pac);
-}
-
-/*tex
-
- Here is a function to calculate the natural whd of a (horizontal) node list.
-
-*/
-
-scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, int g_sign, int g_order, int pack_direction)
-{
- /*tex shift amount */
- scaled s;
- /*tex points to a glue specification */
- halfword g;
- int hpack_dir;
- /*tex For recursion */
- scaled_whd xx;
- scaled_whd whd, siz = { 0, 0, 0 };
- scaled gp = 0;
- scaled gm = 0;
- if (pack_direction == -1) {
- hpack_dir = text_direction_par;
- } else {
- hpack_dir = pack_direction;
- }
- while (p != pp && p != null) {
- while (is_char_node(p) && p != pp) {
- whd = pack_width_height_depth(hpack_dir, dir_TRT, p, true);
- siz.wd += whd.wd;
- if (whd.ht > siz.ht)
- siz.ht = whd.ht;
- if (whd.dp > siz.dp)
- siz.dp = whd.dp;
- p = vlink(p);
- }
- if (p != pp && p != null) {
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- s = shift_amount(p);
- whd = pack_width_height_depth(hpack_dir, box_dir(p), p, false);
- siz.wd += whd.wd;
- if (whd.ht - s > siz.ht)
- siz.ht = whd.ht - s;
- if (whd.dp + s > siz.dp)
- siz.dp = whd.dp + s;
- break;
- case rule_node:
- case unset_node:
- siz.wd += width(p);
- if (height(p) > siz.ht)
- siz.ht = height(p);
- if (depth(p) > siz.dp)
- siz.dp = depth(p);
- break;
- case math_node:
- /*tex Begin mathskip code. */
- if (glue_is_zero(p) || ignore_math_skip(p)) {
- siz.wd += surround(p);
- break;
- } else {
- /*tex Fall through. */
- }
- /*tex End mathskip code. */
- case glue_node:
- siz.wd += width(p);
- if (g_sign != normal) {
- if (g_sign == stretching) {
- if (stretch_order(p) == g_order) {
- /*tex
- |siz.wd += float_round(float_cast(g_mult) * float_cast(stretch(p)))|
- */
- gp += stretch(p);
- }
- } else if (shrink_order(p) == g_order) {
- /*tex
- |siz.wd -= float_round(float_cast(g_mult) * float_cast(shrink(p)));|
- */
- gm += shrink(p);
- }
- }
- if (subtype(p) >= a_leaders) {
- g = leader_ptr(p);
- if (height(g) > siz.ht)
- siz.ht = height(g);
- if (depth(g) > siz.dp)
- siz.dp = depth(g);
- }
- break;
- case margin_kern_node:
- siz.wd += width(p);
- break;
- case kern_node:
- siz.wd += width(p) + ex_kern(p);
- break;
- case disc_node:
- xx = natural_sizes(no_break(p), null, g_mult, g_sign, g_order, hpack_dir);
- siz.wd += xx.wd;
- if (xx.ht > siz.ht)
- siz.ht = xx.ht;
- if (xx.dp > siz.dp)
- siz.dp = xx.dp;
- break;
- default:
- break;
- }
- p = vlink(p);
- }
-
- }
- if (g_sign != normal) {
- if (g_sign == stretching) {
- siz.wd += float_round(float_cast(g_mult) * float_cast(gp));
- } else {
- siz.wd -= float_round(float_cast(g_mult) * float_cast(gm));
- }
- }
- return siz;
-}
-
-/*tex
-
- In order to provide a decent indication of where an overfull or underfull box
- originated, we use a global variable |pack_begin_line| that is set nonzero
- only when |hpack| is being called by the paragraph builder or the alignment
- finishing routine.
-
- The source file line where the current paragraph or alignment began; a
- negative value denotes alignment:
-
-*/
-
-int pack_begin_line;
-
-/*tex
-
- The |vpack| subroutine is actually a special case of a slightly more general
- routine called |vpackage|, which has four parameters. The fourth parameter,
- which is |max_dimen| in the case of |vpack|, specifies the maximum depth of
- the page box that is constructed. The depth is first computed by the normal
- rules; if it exceeds this limit, the reference point is simply moved down
- until the limiting depth is attained.
-
-*/
-
-halfword vpackage(halfword p, scaled h, int m, scaled l, int pack_direction)
-{
- /*tex the box node that will be returned */
- halfword r;
- /*tex width */
- scaled w = 0;
- /*tex depth */
- scaled d = 0;
- /*tex natural height */
- scaled x = 0;
- scaled_whd whd;
- /*tex shift amount */
- scaled s;
- /*tex order of infinity */
- int o;
- last_badness = 0;
- r = new_node(vlist_node, 0);
- if (pack_direction == -1) {
- box_dir(r) = body_direction_par;
- } else {
- box_dir(r) = pack_direction;
- }
- subtype(r) = min_quarterword;
- shift_amount(r) = 0;
- list_ptr(r) = p;
- total_stretch[normal] = 0;
- total_shrink[normal] = 0;
- total_stretch[sfi] = 0;
- total_shrink[sfi] = 0;
- total_stretch[fil] = 0;
- total_shrink[fil] = 0;
- total_stretch[fill] = 0;
- total_shrink[fill] = 0;
- total_stretch[filll] = 0;
- total_shrink[filll] = 0;
- while (p != null) {
- /*tex
-
- Examine node |p| in the vlist, taking account of its effect on the
- dimensions of the new box; then advance |p| to the next node.
-
- */
- if (is_char_node(p)) {
- confusion("vpack");
- } else {
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- /*tex
-
- Incorporate box dimensions into the dimensions of the vbox
- that will contain it.
-
- */
- s = shift_amount(p);
- whd = pack_width_height_depth(box_dir(r), box_dir(p), p, false);
- if (whd.wd + s > w)
- w = whd.wd + s;
- x += d + whd.ht;
- d = whd.dp;
- break;
- case rule_node:
- case unset_node:
- x += d + height(p);
- d = depth(p);
- if (width(p) > w)
- w = width(p);
- break;
- case glue_node:
- /*tex Incorporate glue into the vertical totals. */
- x += d;
- d = 0;
- x += width(p);
- o = stretch_order(p);
- total_stretch[o] = total_stretch[o] + stretch(p);
- o = shrink_order(p);
- total_shrink[o] = total_shrink[o] + shrink(p);
- if (subtype(p) >= a_leaders) {
- halfword g = leader_ptr(p);
- if (width(g) > w)
- w = width(g);
- }
- break;
- case kern_node:
- x += d + width(p);
- d = 0;
- break;
- default:
- break;
- }
- }
- p = vlink(p);
- }
- width(r) = w;
- if (d > l) {
- x += d - l;
- depth(r) = l;
- } else {
- depth(r) = d;
- }
- /*tex
-
- Determine the value of |height(r)| and the appropriate glue setting; then
- |return| or |goto common_ending|.
-
- When we get to the present part of the program, |x| is the natural height
- of the box being packaged.
- */
- if (m == additional)
- h = x + h;
- height(r) = h;
- x = h - x;
- /*tex Now |x| is the excess to be made up. */
- if (x == 0) {
- glue_sign(r) = normal;
- glue_order(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- return r;
- } else if (x > 0) {
- /*tex
-
- Determine vertical glue stretch setting, then |return| or |goto
- common_ending|.
-
- */
- if (total_stretch[filll] != 0)
- o = filll;
- else if (total_stretch[fill] != 0)
- o = fill;
- else if (total_stretch[fil] != 0)
- o = fil;
- else if (total_stretch[sfi] != 0)
- o = sfi;
- else
- o = normal;
- glue_order(r) = (quarterword) o;
- glue_sign(r) = stretching;
- if (total_stretch[o] != 0) {
- glue_set(r) = unfloat((double) x / total_stretch[o]);
- } else {
- /*tex There's nothing to stretch. */
- glue_sign(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- }
- if (o == normal) {
- if (list_ptr(r) != null) {
- /*tex
-
- Report an underfull vbox and |goto common_ending|, if this
- box is sufficiently bad.
-
- */
- last_badness = badness(x, total_stretch[normal]);
- if (last_badness > vbadness_par) {
- int callback_id = callback_defined(vpack_quality_callback);
- if (callback_id > 0) {
- if (last_badness > 100) {
- run_callback(callback_id, "SdNdd->","underfull",last_badness,r,abs(pack_begin_line),line);
- } else {
- run_callback(callback_id, "SdNdd->","loose",last_badness,r,abs(pack_begin_line),line);
- }
- goto EXIT;
- } else {
- print_ln();
- if (last_badness > 100) {
- tprint_nl("Underfull \\vbox (badness ");
- } else {
- tprint_nl("Loose \\vbox (badness ");
- }
- print_int(last_badness);
- goto COMMON_ENDING;
- }
- }
- }
- }
- return r;
- } else {
- /*tex
-
- Determine vertical glue shrink setting, then |return| or |goto
- common_ending|.
-
- */
- if (total_shrink[filll] != 0)
- o = filll;
- else if (total_shrink[fill] != 0)
- o = fill;
- else if (total_shrink[fil] != 0)
- o = fil;
- else if (total_shrink[sfi] != 0)
- o = sfi;
- else
- o = normal;
- glue_order(r) = (quarterword) o;
- glue_sign(r) = shrinking;
- if (total_shrink[o] != 0) {
- glue_set(r) = unfloat((double) (-x) / total_shrink[o]);
- } else {
- /*tex There's nothing to shrink. */
- glue_sign(r) = normal;
- set_glue_ratio_zero(glue_set(r));
- }
- if ((total_shrink[o] < -x) && (o == normal) && (list_ptr(r) != null)) {
- int overshoot = -x - total_shrink[normal];
- last_badness = 1000000;
- /*tex Use the maximum shrinkage */
- set_glue_ratio_one(glue_set(r));
- /*tex
-
- Report an overfull vbox and |goto common_ending|, if this box is
- sufficiently bad.
-
- */
- if ((overshoot > vfuzz_par) || (vbadness_par < 100)) {
- int callback_id = callback_defined(vpack_quality_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "SdNdd->","overfull",overshoot,r,abs(pack_begin_line),line);
- goto EXIT;
- } else {
- print_ln();
- tprint_nl("Overfull \\vbox (");
- print_scaled(-x - total_shrink[normal]);
- tprint("pt too high");
- goto COMMON_ENDING;
- }
- }
- } else if (o == normal) {
- if (list_ptr(r) != null) {
- /*tex
-
- Report a tight vbox and |goto common_ending|, if this box is
- sufficiently bad.
-
- */
- last_badness = badness(-x, total_shrink[normal]);
- if (last_badness > vbadness_par) {
- int callback_id = callback_defined(vpack_quality_callback);
- if (callback_id > 0) {
- run_callback(callback_id, "SdNdd->","tight",last_badness,r,abs(pack_begin_line),line);
- goto EXIT;
- } else {
- print_ln();
- tprint_nl("Tight \\vbox (badness ");
- print_int(last_badness);
- goto COMMON_ENDING;
- }
- }
- }
- }
- return r;
- }
-
- COMMON_ENDING:
- /*tex Finish issuing a diagnostic message or an overfull or underfull vbox. */
- if (output_active) {
- tprint(") has occurred while \\output is active");
- } else {
- if (pack_begin_line != 0) {
- /*tex It's actually negative. */
- tprint(") in alignment at lines ");
- print_int(abs(pack_begin_line));
- tprint("--");
- } else {
- tprint(") detected at line ");
- }
- print_int(line);
- print_ln();
- }
- begin_diagnostic();
- show_box(r);
- end_diagnostic(true);
- EXIT:
- return r;
-}
-
-halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp, int pack_direction, int just_pack, halfword attr)
-{
- halfword q = p;
- if (!just_pack)
- q = lua_vpack_filter(q, h, m, l, grp, pack_direction, attr);
- return vpackage(q, h, m, l, pack_direction);
-}
-
-void finish_vcenter(void)
-{
- halfword p;
- unsave();
- save_ptr--;
- p = vpack(vlink(cur_list.head_field), saved_value(0), saved_level(0), -1);
- pop_nest();
- p = math_vcenter_group(p);
- tail_append(p);
-}
-
-void package(int c)
-{
- halfword saved0, saved2, saved3, saved4;
- int grp = cur_group;
- scaled d = box_max_depth_par;
- unsave();
- save_ptr -= 5;
- saved0 = saved_value(0);
- saved2 = saved_value(2);
- saved3 = saved_value(3);
- saved4 = saved_value(4);
- if (cur_list.mode_field == -hmode) {
- cur_box = filtered_hpack(cur_list.head_field, cur_list.tail_field,
- saved_value(1), saved_level(1), grp, saved_level(2), saved4, saved3);
- subtype(cur_box) = hbox_list;
- } else {
- cur_box = filtered_vpackage(vlink(cur_list.head_field),
- saved_value(1), saved_level(1), d, grp, saved_level(2), saved4, saved3);
- if (c == vtop_code) {
- /*tex
-
- Read just the height and depth of |cur_box|, for \.{\\vtop}. The
- height of a `\.{\\vtop}' box is inherited from the first item on
- its list, if that item is an |hlist_node|, |vlist_node|, or
- |rule_node|; otherwise the \.{\\vtop} height is zero.
-
- */
- scaled h = 0;
- halfword p = list_ptr(cur_box);
- if ((p != null) && (type(p) <= rule_node)) {
- /* hlist, vlist, rule */
- h = height(p);
- }
- depth(cur_box) = depth(cur_box) - h + height(cur_box);
- height(cur_box) = h;
- }
- }
- if (saved2 != null) {
- /*tex Adjust back |text_dir_ptr| for |scan_spec| */
- flush_node_list(text_dir_ptr);
- text_dir_ptr = saved2;
-
- }
- replace_attribute_list(cur_box, saved3);
- pop_nest();
- box_end(saved0);
-}
-
-/*tex
-
- When a box is being appended to the current vertical list, the baselineskip
- calculation is handled by the |append_to_vlist| routine.
-
-*/
-
-void append_to_vlist(halfword b, int location)
-{
- /*tex The deficiency of space between baselines: */
- scaled d;
- /*tex A new glue node. */
- halfword p;
- boolean mirrored = (type(b) == hlist_node) && is_mirrored(box_dir(b)) ;
- halfword result = null;
- halfword next_depth = ignore_depth;
- boolean prev_set = false ;
- if (lua_appendtovlist_callback(b,location,prev_depth_par,mirrored,&result,&next_depth,&prev_set)) {
- while (result != null) {
- couple_nodes(cur_list.tail_field, result);
- cur_list.tail_field = result;
- result = vlink(result);
- }
- if (prev_set) {
- prev_depth_par = next_depth;
- }
- } else {
- if (prev_depth_par > ignore_depth) {
- if (mirrored) {
- d = width(baseline_skip_par) - prev_depth_par - depth(b);
- } else {
- d = width(baseline_skip_par) - prev_depth_par - height(b);
- }
- if (d < line_skip_limit_par) {
- p = new_param_glue(line_skip_code);
- } else {
- p = new_skip_param(baseline_skip_code);
- width(p) = d;
- }
- couple_nodes(cur_list.tail_field, p);
- cur_list.tail_field = p;
- }
- couple_nodes(cur_list.tail_field, b);
- cur_list.tail_field = b;
- if (mirrored) {
- prev_depth_par = height(b);
- } else {
- prev_depth_par = depth(b);
- }
- }
-}
-
-/*tex
-
- When |saving_vdiscards| is positive then the glue, kern, and penalty nodes
- removed by the page builder or by \.{\\vsplit} from the top of a vertical
- list are saved in special lists instead of being discarded.
-
-*/
-
-/*tex last item removed by page builder */
-
-#define tail_page_disc disc_ptr[copy_code]
-
-/*tex first item removed by page builder */
-
-#define page_disc disc_ptr[last_box_code]
-
-/*tex first item removed by \.{\\vsplit} */
-
-#define split_disc disc_ptr[vsplit_code]
-
-/*tex List pointers. */
-
-halfword disc_ptr[(vsplit_code + 1)];
-
-/*tex
-
- The |vsplit| procedure, which implements \TeX's \.{\\vsplit} operation, is
- considerably simpler than |line_break| because it doesn't have to worry about
- hyphenation, and because its mission is to discover a single break instead of
- an optimum sequence of breakpoints. But before we get into the details of
- |vsplit|, we need to consider a few more basic things.
-
- A subroutine called |prune_page_top| takes a pointer to a vlist and returns a
- pointer to a modified vlist in which all glue, kern, and penalty nodes have
- been deleted before the first box or rule node. However, the first box or
- rule is actually preceded by a newly created glue node designed so that the
- topmost baseline will be at distance |split_top_skip| from the top, whenever
- this is possible without backspacing.
-
- When the second argument |s| is |false| the deleted nodes are destroyed,
- otherwise they are collected in a list starting at |split_disc|.
-
-*/
-
-halfword prune_page_top(halfword p, boolean s)
-{
- halfword q;
- /*tex Lags one step behind |p|. */
- halfword prev_p = temp_head;
- halfword r = null;
- vlink(temp_head) = p;
- while (p != null) {
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case rule_node:
- /*tex Insert glue for |split_top_skip| and set |p:=null|. */
- q = new_skip_param(split_top_skip_code);
- vlink(prev_p) = q;
- vlink(q) = p;
- if (width(q) > height(p))
- width(q) = width(q) - height(p);
- else
- width(q) = 0;
- p = null;
- break;
- case boundary_node:
- case whatsit_node:
- case mark_node:
- case ins_node:
- prev_p = p;
- p = vlink(prev_p);
- break;
- case glue_node:
- case kern_node:
- case penalty_node:
- q = p;
- p = vlink(q);
- vlink(q) = null;
- vlink(prev_p) = p;
- if (s) {
- if (split_disc == null)
- split_disc = q;
- else
- vlink(r) = q;
- r = q;
- } else {
- flush_node_list(q);
- }
- break;
- default:
- confusion("pruning");
- break;
- }
- }
- return vlink(temp_head);
-}
-
-/*tex
-
- The next subroutine finds the best place to break a given vertical list so as
- to obtain a box of height~|h|, with maximum depth~|d|. A pointer to the
- beginning of the vertical list is given, and a pointer to the optimum
- breakpoint is returned. The list is effectively followed by a forced break,
- i.e., a penalty node with the |eject_penalty|; if the best break occurs at
- this artificial node, the value |null| is returned.
-
-*/
-
-/*tex The distance from first active node to |cur_p|: */
-
-scaled active_height[10];
-
-/*tex
-
- An array of six |scaled| distances is used to keep track of the height from
- the beginning of the list to the current place, just as in |line_break|. In
- fact, we use one of the same arrays, only changing its name to reflect its
- new significance.
-
-*/
-
-#define do_all_six(A) A(1);A(2);A(3);A(4);A(5);A(6);A(7)
-#define set_height_zero(A) active_height[A]=0 /* initialize the height to zero */
-
-/*tex
-
- A global variable |best_height_plus_depth| will be set to the natural size of
- the box that corresponds to the optimum breakpoint found by |vert_break|.
- (This value is used by the insertion-splitting algorithm of the page
- builder.)
-
-*/
-
-/*tex The height of the best box, without stretching or shrinking: */
-
-scaled best_height_plus_depth;
-
-halfword vert_break(halfword p, scaled h, scaled d)
-{
- /*tex
- If |p| is a glue node, |type(prev_p)| determines whether |p| is a legal
- breakpoint, an initial glue node is not a legal breakpoint.
- */
- halfword prev_p = p;
- /*tex penalty value */
- int pi = 0;
- /*tex badness at a trial breakpoint */
- int b;
- /*tex |type| of the node following a kern */
- int t;
- /*tex the smallest badness plus penalties found so far */
- int least_cost;
- /*tex the most recent break that leads to |least_cost| */
- halfword best_place = null;
- /*tex depth of previous box in the list */
- scaled prev_dp = 0;
- least_cost = awful_bad;
- do_all_six(set_height_zero);
- while (1) {
- /*tex
-
- If node |p| is a legal breakpoint, check if this break is the best
- known, and |goto done| if |p| is null or if the page-so-far is
- already too full to accept more stuff.
-
- A subtle point to be noted here is that the maximum depth~|d| might
- be negative, so |cur_height| and |prev_dp| might need to be corrected
- even after a glue or kern node.
- */
- if (p == null) {
- pi = eject_penalty;
- } else {
- /*tex
-
- Use node |p| to update the current height and depth measurements;
- if this node is not a legal breakpoint, |goto not_found| or
- |update_heights|, otherwise set |pi| to the associated penalty at
- the break.
-
- */
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case rule_node:
- cur_height = cur_height + prev_dp + height(p);
- prev_dp = depth(p);
- goto NOT_FOUND;
- break;
- case boundary_node:
- case whatsit_node:
- goto NOT_FOUND;
- break;
- case glue_node:
- if (precedes_break(prev_p))
- pi = 0;
- else
- goto UPDATE_HEIGHTS;
- break;
- case kern_node:
- if (vlink(p) == null)
- t = penalty_node;
- else
- t = type(vlink(p));
- if (t == glue_node)
- pi = 0;
- else
- goto UPDATE_HEIGHTS;
- break;
- case penalty_node:
- pi = penalty(p);
- break;
- case mark_node:
- case ins_node:
- goto NOT_FOUND;
- break;
- default:
- confusion("vertbreak");
- break;
- }
- }
- /*tex
-
- Check if node |p| is a new champion breakpoint; then |goto done| if
- |p| is a forced break or if the page-so-far is already too full.
-
- */
- if (pi < inf_penalty) {
- /*tex Compute the badness, |b|, using |awful_bad| if the box is too full. */
- if (cur_height < h) {
- if ((active_height[3] != 0) || (active_height[4] != 0) ||
- (active_height[5] != 0) || (active_height[6] != 0))
- b = 0;
- else
- b = badness(h - cur_height, active_height[2]);
- } else if (cur_height - h > active_height[7]) {
- b = awful_bad;
- } else {
- b = badness(cur_height - h, active_height[7]);
- }
- if (b < awful_bad) {
- if (pi <= eject_penalty)
- b = pi;
- else if (b < inf_bad)
- b = b + pi;
- else
- b = deplorable;
- }
- if (b <= least_cost) {
- best_place = p;
- least_cost = b;
- best_height_plus_depth = cur_height + prev_dp;
- }
- if ((b == awful_bad) || (pi <= eject_penalty))
- goto DONE;
- }
- if ((type(p) < glue_node) || (type(p) > kern_node))
- goto NOT_FOUND;
- UPDATE_HEIGHTS:
- /*tex
-
- Update the current height and depth measurements with respect to a
- glue or kern node~|p|. Vertical lists that are subject to the
- |vert_break| procedure should not contain infinite shrinkability,
- since that would permit any amount of information to ``fit'' on one
- page.
-
- */
- if (type(p) != kern_node) {
- active_height[2 + stretch_order(p)] += stretch(p);
- active_height[7] += shrink(p);
- if ((shrink_order(p) != normal) && (shrink(p) != 0)) {
- print_err("Infinite glue shrinkage found in box being split");
- help4(
- "The box you are \\vsplitting contains some infinitely",
- "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
- "Such glue doesn't belong there; but you can safely proceed,",
- "since the offensive shrinkability has been made finite."
- );
- error();
- shrink_order(p) = normal;
- }
- }
- cur_height = cur_height + prev_dp + width(p);
- prev_dp = 0;
- NOT_FOUND:
- if (prev_dp > d) {
- cur_height = cur_height + prev_dp - d;
- prev_dp = d;
- }
- prev_p = p;
- p = vlink(prev_p);
- }
- DONE:
- return best_place;
-}
-
-/*tex
-
- Now we are ready to consider |vsplit| itself. Most of its work is
- accomplished by the two subroutines that we have just considered.
-
- Given the number of a vlist box |n|, and given a desired page height |h|, the
- |vsplit| function finds the best initial segment of the vlist and returns a
- box for a page of height~|h|. The remainder of the vlist, if any, replaces
- the original box, after removing glue and penalties and adjusting for
- |split_top_skip|. Mark nodes in the split-off box are used to set the values
- of |split_first_mark| and |split_bot_mark|; we use the fact that
- |split_first_mark(x)=null| if and only if |split_bot_mark(x)=null|.
-
- The original box becomes ``void'' if and only if it has been entirely
- extracted. The extracted box is ``void'' if and only if the original box was
- void (or if it was, erroneously, an hlist box).
-
-*/
-
-/*tex Extract a page of height |h| from box |n|: */
-
-halfword vsplit(halfword n, scaled h, int m)
-{
- /*tex the box to be split */
- halfword v;
- /*tex the direction of the box to be split */
- int vdir;
- /*tex runs through the vlist */
- halfword p;
- /*tex points to where the break occurs */
- halfword q;
- /*tex for traversing marks lists */
- halfword i;
- v = box(n);
- vdir = box_dir(v);
- flush_node_list(split_disc);
- split_disc = null;
- for (i = 0; i <= biggest_used_mark; i++) {
- delete_split_first_mark(i);
- delete_split_bot_mark(i);
- }
- /*tex Dispense with trivial cases of void or bad boxes. */
- if (v == null) {
- return null;
- }
- if (type(v) != vlist_node) {
- print_err("\\vsplit needs a \\vbox");
- help2(
- "The box you are trying to split is an \\hbox.",
- "i can't split such a box, so I''ll leave it alone."
- );
- error();
- return null;
- }
- q = vert_break(list_ptr(v), h, split_max_depth_par);
- /*tex
-
- Look at all the marks in nodes before the break, and set the final link
- to |null| at the break. It's possible that the box begins with a penalty
- node that is the ``best'' break, so we must be careful to handle this
- special case correctly.
-
- */
- p = list_ptr(v);
- if (p == q) {
- list_ptr(v) = null;
- } else {
- while (1) {
- if (type(p) == mark_node) {
- if (split_first_mark(mark_class(p)) == null) {
- set_split_first_mark(mark_class(p), mark_ptr(p));
- set_split_bot_mark(mark_class(p), split_first_mark(mark_class(p)));
- set_token_ref_count(split_first_mark(mark_class(p)),
- token_ref_count(split_first_mark(mark_class(p))) + 2);
- } else {
- delete_token_ref(split_bot_mark(mark_class(p)));
- set_split_bot_mark(mark_class(p), mark_ptr(p));
- add_token_ref(split_bot_mark(mark_class(p)));
- }
- }
- if (vlink(p) == q) {
- vlink(p) = null;
- break;
- }
- p = vlink(p);
- }
- }
- q = prune_page_top(q, saving_vdiscards_par > 0);
- p = list_ptr(v);
- list_ptr(v) = null;
- flush_node(v);
- if (q == null) {
- /*tex The |eq_level| of the box stays the same. */
- box(n) = null;
- } else {
- box(n) = filtered_vpackage(q, 0, additional, max_depth_par, split_keep_group, vdir, 0, 0);
- }
- if (m == exactly) {
- return filtered_vpackage(p, h, exactly, split_max_depth_par, split_off_group, vdir, 0, 0);
- } else {
- return filtered_vpackage(p, 0, additional, max_depth_par, split_off_group, vdir, 0, 0);
- }
-}
-
-/*tex
-
- Now that we can see what eventually happens to boxes, we can consider the
- first steps in their creation. The |begin_box| routine is called when
- |box_context| is a context specification, |cur_chr| specifies the type of box
- desired, and |cur_cmd=make_box|.
-
-*/
-
-void begin_box(int box_context)
-{
- /*tex run through the current list */
- halfword q;
- /*tex 0 or |vmode| or |hmode| */
- halfword k;
- /*tex a box number */
- int n;
- int spec_direction = -1;
- int just_pack = 0;
- int split_mode = exactly ;
- switch (cur_chr) {
- case box_code:
- scan_register_num();
- cur_box = box(cur_val);
- /*tex The box becomes void, at the same level. */
- box(cur_val) = null;
- break;
- case copy_code:
- scan_register_num();
- cur_box = copy_node_list(box(cur_val));
- break;
- case last_box_code:
- /*tex
-
- If the current list ends with a box node, delete it from the list
- and make |cur_box| point to it; otherwise set |cur_box:=null|.
-
- */
- cur_box = null;
- if (abs(cur_list.mode_field) == mmode) {
- you_cant();
- help1("Sorry; this \\lastbox will be void.");
- error();
- } else if ((cur_list.mode_field == vmode) && (cur_list.head_field == cur_list.tail_field)) {
- you_cant();
- help2(
- "Sorry...I usually can't take things from the current page.",
- "This \\lastbox will therefore be void."
- );
- error();
- } else {
- if (cur_list.head_field != cur_list.tail_field) {
- if ((type(cur_list.tail_field) == hlist_node) || (type(cur_list.tail_field) == vlist_node)) {
- /*tex Remove the last box */
- q = alink(cur_list.tail_field);
- if (q == null || vlink(q) != cur_list.tail_field) {
- q = cur_list.head_field;
- while (vlink(q) != cur_list.tail_field)
- q = vlink(q);
- }
- uncouple_node(cur_list.tail_field);
- cur_box = cur_list.tail_field;
- shift_amount(cur_box) = 0;
- cur_list.tail_field = q;
- vlink(cur_list.tail_field) = null;
- }
- }
- }
- break;
- case vsplit_code:
- /*tex
-
- Split off part of a vertical box, make |cur_box| point to it.
- Here we deal with things like `\.{\\vsplit 13 to 100pt}'.
-
- */
- scan_register_num();
- n = cur_val;
- if (scan_keyword("upto")) {
- split_mode = additional ;
- } else if (!scan_keyword("to")) {
- print_err("Missing `to' inserted");
- help2(
- "I'm working on `\\vsplit<box number> to <dimen>';",
- "will look for the <dimen> next."
- );
- error();
- }
- scan_normal_dimen();
- cur_box = vsplit(n, cur_val, split_mode);
- break;
- default:
- /*tex
-
- Initiate the construction of an hbox or vbox, then |return|. Here
- is where we enter restricted horizontal mode or internal vertical
- mode, in order to make a box.
-
- */
- switch (cur_chr) {
- case tpack_code:
- cur_chr = vtop_code;
- just_pack = 1;
- break;
- case vpack_code:
- cur_chr = vtop_code + vmode;
- just_pack = 1;
- break;
- case hpack_code:
- cur_chr = vtop_code + hmode;
- just_pack = 1;
- break;
- }
- k = cur_chr - vtop_code;
- set_saved_record(0, saved_boxcontext, 0, box_context);
- switch (abs(cur_list.mode_field)) {
- case vmode:
- spec_direction = body_direction_par;
- break;
- case hmode:
- spec_direction = text_direction_par;
- break;
- case mmode:
- spec_direction = math_direction_par;
- break;
- }
- if (k == hmode) {
- if ((box_context < box_flag) && (abs(cur_list.mode_field) == vmode))
- scan_full_spec(adjusted_hbox_group, spec_direction,just_pack);
- else
- scan_full_spec(hbox_group, spec_direction,just_pack);
- } else {
- if (k == vmode) {
- scan_full_spec(vbox_group, spec_direction,just_pack);
- } else {
- scan_full_spec(vtop_group, spec_direction,just_pack);
- k = vmode;
- }
- normal_paragraph();
- }
- push_nest();
-/* new */
-/* eq_word_define(int_base + no_local_whatsits_code, 0); */
-eq_word_define(int_base + no_local_dirs_code, 0);
- cur_list.mode_field = -k;
- if (k == vmode) {
- prev_depth_par = ignore_depth;
- if (every_vbox_par != null)
- begin_token_list(every_vbox_par, every_vbox_text);
- } else {
- space_factor_par = 1000;
- if (every_hbox_par != null)
- begin_token_list(every_hbox_par, every_hbox_text);
- }
- return;
- break;
- }
- /*tex In simple cases, we use the box immediately. */
- box_end(box_context);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/packaging.h b/Build/source/texk/web2c/luatexdir/tex/packaging.h
deleted file mode 100644
index 9353afeaf20..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/packaging.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* packaging.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef PACKAGING_H
-# define PACKAGING_H
-
-/* We define some constants used when calling |hpack| to deal with font expansion. */
-
-typedef enum {
- exactly = 0, /*a box dimension is pre-specified */
- additional, /*a box dimension is increased from the natural one */
- cal_expand_ratio, /* calculate amount for font expansion after breaking paragraph into lines */
- subst_ex_font /* substitute fonts */
-} hpack_subtypes;
-
-# define substituted 3 /* |subtype| of kern nodes that should be substituted */
-
-extern void scan_spec(group_code c);
-extern void scan_full_spec(group_code c, int spec_direction, int justpack);
-
-extern scaled total_stretch[5];
-extern scaled total_shrink[5]; /* glue found by |hpack| or |vpack| */
-extern int last_badness; /* badness of the most recently packaged box */
-extern halfword adjust_tail; /* tail of adjustment list */
-extern halfword pre_adjust_tail;
-extern int font_expand_ratio; /* current expansion ratio */
-extern halfword last_leftmost_char;
-extern halfword last_rightmost_char;
-extern halfword next_char_p; /* pointer to the next char of an implicit kern */
-extern halfword prev_char_p; /* pointer to the previous char of an implicit kern */
-
-extern void set_prev_char_p(halfword p);
-extern scaled char_stretch(halfword p);
-extern scaled char_shrink(halfword p);
-extern scaled kern_stretch(halfword p);
-extern scaled kern_shrink(halfword p);
-extern void do_subst_font(halfword p, int ex_ratio);
-extern scaled char_pw(halfword p, int side);
-extern halfword new_margin_kern(scaled w, halfword p, int side);
-
-# define update_adjust_list(A) do { \
- if (A == null) \
- normal_error("pre vadjust", "adjust_tail or pre_adjust_tail is null"); \
- vlink(A) = adjust_ptr(p); \
- while (vlink(A) != null) \
- A = vlink(A); \
- } while (0)
-
-extern halfword filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, int d, int just_pack, halfword attr);
-extern scaled_whd natural_sizes(halfword p, halfword pp, glue_ratio g_mult, int g_sign, int g_order, int d);
-extern halfword hpack(halfword p, scaled w, int m, int d);
-
-extern int pack_begin_line;
-
-extern halfword vpackage(halfword p, scaled h, int m, scaled l, int d);
-extern halfword filtered_vpackage(halfword p, scaled h, int m, scaled l, int grp, int d, int just_pack, halfword attr);
-extern void finish_vcenter(void);
-extern void package(int c);
-extern void append_to_vlist(halfword b, int location);
-
-# define vpack(A,B,C,D) vpackage(A,B,C,max_dimen,D) /* special case of unconstrained depth */
-
-extern halfword prune_page_top(halfword p, boolean s);
-extern scaled active_height[10]; /* distance from first active node to~|cur_p| */
-
-# define cur_height active_height[1] /* the natural height */
-# define awful_bad 07777777777 /* more than a billion demerits */
-# define deplorable 100000 /* more than |inf_bad|, but less than |awful_bad| */
-
-extern scaled best_height_plus_depth; /* height of the best box, without stretching or shrinking */
-
-extern halfword vert_break(halfword p, scaled h, scaled d);
-extern halfword vsplit(halfword n, scaled h, int m); /* extracts a page of height |h| from box |n| */
-
-# define box_code 0 /* |chr_code| for `\.{\\box}' */
-# define copy_code 1 /* |chr_code| for `\.{\\copy}' */
-# define last_box_code 2 /* |chr_code| for `\.{\\lastbox}' */
-# define vsplit_code 3 /* |chr_code| for `\.{\\vsplit}' */
-# define tpack_code 4
-# define vpack_code 5
-# define hpack_code 6
-# define vtop_code 7 /* |chr_code| for `\.{\\vtop}' */
-
-# define tail_page_disc disc_ptr[copy_code] /* last item removed by page builder */
-# define page_disc disc_ptr[last_box_code] /* first item removed by page builder */
-# define split_disc disc_ptr[vsplit_code] /* first item removed by \.{\\vsplit} */
-
-extern halfword disc_ptr[(vsplit_code + 1)]; /* list pointers */
-
-/*
-
-Now let's turn to the question of how \.{\\hbox} is treated. We actually need to
-consider also a slightly larger context, since constructions like
-
-`\.{\\setbox3=}\penalty0\.{\\hbox...}' and
-`\.{\\leaders}\penalty0\.{\\hbox...}' and
-`\.{\\lower3.8pt\\hbox...}'
-
-are supposed to invoke quite different actions after the box has been packaged.
-Conversely, constructions like `\.{\\setbox3=}' can be followed by a variety of
-different kinds of boxes, and we would like to encode such things in an efficient
-way.
-
-In other words, there are two problems: To represent the context of a box, and to
-represent its type. The first problem is solved by putting a ``context code'' on
-the |save_stack|, just below the two entries that give the dimensions produced by
-|scan_spec|. The context code is either a (signed) shift amount, or it is a large
-integer |>=box_flag|, where |box_flag=@t$2^{30}$@>|. Codes |box_flag| through
-|box_flag+biggest_reg| represent `\.{\\setbox0}' through
-`\.{\\setbox}|biggest_reg|'; codes |box_flag+biggest_reg+1| through
-|box_flag+2*biggest_reg| represent `\.{\\global\\setbox0}' through
-`\.{\\global\\setbox}|biggest_reg|'; code |box_flag+2*number_regs| represents
-`\.{\\shipout}'; and codes |box_flag+2*number_regs+1| through
-|box_flag+2*number_regs+3| represent `\.{\\leaders}', `\.{\\cleaders}', and
-`\.{\\xleaders}'.
-
-The second problem is solved by giving the command code |make_box| to all control
-sequences that produce a box, and by using the following |chr_code| values to
-distinguish between them: |box_code|, |copy_code|, |last_box_code|,
-|vsplit_code|, |vtop_code|, |vtop_code+vmode|, and |vtop_code+hmode|, where the
-latter two are used denote \.{\\vbox} and \.{\\hbox}, respectively.
-
-*/
-
-# define box_flag 010000000000 /* context code for `\.{\\setbox0}' */
-# define global_box_flag (box_flag+number_regs) /* context code for `\.{\\global\\setbox0}' */
-# define max_global_box_flag (global_box_flag+number_regs)
-# define ship_out_flag (max_global_box_flag+1) /* context code for `\.{\\shipout}' */
-# define lua_scan_flag (max_global_box_flag+2) /* context code for |scan_list| */
-# define leader_flag (max_global_box_flag+3) /* context code for `\.{\\leaders}' */
-
-extern void begin_box(int box_context);
-
-#define math_skip_boundary(n) \
-(n && type(n) == glue_node && (subtype(n) == space_skip_subtype || subtype(n) == xspace_skip_subtype))
-
-extern int ignore_math_skip(halfword p) ;
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c
deleted file mode 100644
index c6f82d56052..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
-
-postlinebreak.w
-
-Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-So far we have gotten a little way into the |line_break| routine, having covered
-its important |try_break| subroutine. Now let's consider the rest of the process.
-
-The main loop of |line_break| traverses the given hlist, starting at
-|vlink(temp_head)|, and calls |try_break| at each legal breakpoint. A variable
-called |auto_breaking| is set to true except within math formulas, since glue
-nodes are not legal breakpoints when they appear in formulas.
-
-The current node of interest in the hlist is pointed to by |cur_p|. Another
-variable, |prev_p|, is usually one step behind |cur_p|, but the real meaning of
-|prev_p| is this: If |type(cur_p)=glue_node| then |cur_p| is a legal breakpoint
-if and only if |auto_breaking| is true and |prev_p| does not point to a glue
-node, penalty node, explicit kern node, or math node.
-
-The total number of lines that will be set by |post_line_break| is
-|best_line-prev_graf-1|. The last breakpoint is specified by
-|break_node(best_bet)|, and this passive node points to the other breakpoints via
-the |prev_break| links. The finishing-up phase starts by linking the relevant
-passive nodes in forward order, changing |prev_break| to |next_break|. (The
-|next_break| fields actually reside in the same memory space as the |prev_break|
-fields did, but we give them a new name because of their new significance.) Then
-the lines are justified, one by one.
-
-The |post_line_break| must also keep an dir stack, so that it can output end
-direction instructions at the ends of lines and begin direction instructions at
-the beginnings of lines.
-
-*/
-
-/*tex The new name for |prev_break| after links are reversed: */
-
-#define next_break prev_break
-
-/*tex The |int|s are actually halfwords. */
-
-void ext_post_line_break(int paragraph_dir,
- int right_skip,
- int left_skip,
- int protrude_chars,
- halfword par_shape_ptr,
- int adjust_spacing,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword widow_penalties_ptr,
- int widow_penalty,
- int broken_penalty,
- halfword final_par_glue,
- halfword best_bet,
- halfword last_special_line,
- scaled second_width,
- scaled second_indent,
- scaled first_width,
- scaled first_indent, halfword best_line)
-{
-
- boolean have_directional = true;
- /*tex temporary registers for list manipulation */
- halfword q, r;
- halfword k;
- scaled w;
- /*tex was a break at glue? */
- boolean glue_break;
- /*tex was the current break at a discretionary node? */
- boolean disc_break;
- /*tex and did it have a nonempty post-break part? */
- boolean post_disc_break;
- /*tex width of line number |cur_line| */
- scaled cur_width;
- /*tex left margin of line number |cur_line| */
- scaled cur_indent;
- /*tex use when calculating penalties between lines */
- int pen;
- /*tex |cur_p|, but localized */
- halfword cur_p;
- /*tex the current line number being justified */
- halfword cur_line;
- /*tex the current direction: */
- dir_ptr = cur_list.dirs_field;
- /*tex
- Reverse the links of the relevant passive nodes, setting |cur_p| to the
- first breakpoint. The job of reversing links in a list is conveniently
- regarded as the job of taking items off one stack and putting them on
- another. In this case we take them off a stack pointed to by |q| and
- having |prev_break| fields; we put them on a stack pointed to by |cur_p|
- and having |next_break| fields. Node |r| is the passive node being moved
- from stack to stack.
- */
- q = break_node(best_bet);
- /*tex |cur_p| will become the first breakpoint; */
- cur_p = null;
- do {
- r = q;
- q = prev_break(q);
- next_break(r) = cur_p;
- cur_p = r;
- } while (q != null);
- /*tex prevgraf + 1 */
- cur_line = cur_list.pg_field + 1;
- do {
- /*tex
- Justify the line ending at breakpoint |cur_p|, and append it to the
- current vertical list, together with associated penalties and other
- insertions.
-
- The current line to be justified appears in a horizontal list
- starting at |vlink(temp_head)| and ending at |cur_break(cur_p)|. If
- |cur_break(cur_p)| is a glue node, we reset the glue to equal the
- |right_skip| glue; otherwise we append the |right_skip| glue at the
- right. If |cur_break(cur_p)| is a discretionary node, we modify the
- list so that the discretionary break is compulsory, and we set
- |disc_break| to |true|. We also append the |left_skip| glue at the
- left of the line, unless it is zero.
- */
- if (dir_ptr != null) {
- /*tex Insert dir nodes at the beginning of the current line. */
- for (q = dir_ptr; q != null; q = vlink(q)) {
- halfword tmp = new_dir(dir_dir(q));
- halfword nxt = vlink(temp_head);
- delete_attribute_ref(node_attr(tmp));
- node_attr(tmp) = node_attr(temp_head);
- add_node_attr_ref(node_attr(tmp));
- couple_nodes(temp_head, tmp);
- /*tex \.{\\break}\.{\\par} */
- try_couple_nodes(tmp, nxt);
- }
- flush_node_list(dir_ptr);
- dir_ptr = null;
- }
- /*tex
- Modify the end of the line to reflect the nature of the break and to
- include \.{\\rightskip}; also set the proper value of |disc_break|.
- At the end of the following code, |q| will point to the final node on
- the list about to be justified. In the meanwhile |r| will point to
- the node we will use to insert end-of-line stuff after. |q==null|
- means we use the final position of |r|.
- */
-
- if (temp_head != null) {
- /*tex begin mathskip code */
- q = temp_head;
- while(q != null) {
- if (type(q) == math_node) {
- surround(q) = 0 ;
- reset_glue_to_zero(q);
- break;
- } else if ((type(q) == hlist_node) && (subtype(q) == indent_list)) {
- /* go on */
- } else if (is_char_node(q)) {
- break;
- } else if (non_discardable(q)) {
- break;
- } else if (type(q) == kern_node && subtype(q) != explicit_kern && subtype(q) != italic_kern) {
- break;
- }
- q = vlink(q);
- }
- /*tex end mathskip code */
- }
-
- r = cur_break(cur_p);
- q = null;
- disc_break = false;
- post_disc_break = false;
- glue_break = false;
-
-
- if (r == null) {
- for (r = temp_head; vlink(r) != null; r = vlink(r));
- if (r == final_par_glue) {
- /*tex This should almost always be true... */
- q = r;
- /*tex |q| refers to the last node of the line (and paragraph) */
- r = alink(r);
- }
- /*tex |r| refers to the node after which the dir nodes should be closed */
- } else if (type(r) == math_node) {
- surround(r) = 0;
- /*tex begin mathskip code */
- reset_glue_to_zero(r);
- /*tex end mathskip code */
- } else if (type(r) == glue_node) {
- copy_glue_values(r,right_skip);
- subtype(r) = right_skip_code + 1;
- glue_break = true;
- /*tex |q| refers to the last node of the line */
- q = r;
- r = alink(r);
- assert(vlink(r) == q);
- /*tex |r| refers to the node after which the dir nodes should be closed */
- } else if (type(r) == disc_node) {
- halfword a = alink(r);
- halfword v = vlink(r);
- assert(a != null);
- assert(v != null);
- switch (subtype(r)) {
- case select_disc:
- if (vlink_pre_break(r) != null) {
- flush_node_list(vlink_pre_break(r));
- vlink_pre_break(r) = null;
- tlink_pre_break(r) = null;
- }
- if (vlink_no_break(r) != null) {
- couple_nodes(a, vlink_no_break(r));
- couple_nodes(tlink_no_break(r), r);
- vlink_no_break(r) = null;
- tlink_no_break(r) = null;
- }
- assert(type(a) == disc_node && subtype(a) == init_disc);
- flush_node_list(vlink_no_break(a));
- vlink_no_break(a) = null;
- tlink_no_break(a) = null;
- flush_node_list(vlink_pre_break(a));
- vlink_pre_break(a) = null;
- tlink_pre_break(a) = null;
- flush_node_list(vlink_post_break(a));
- vlink_post_break(a) = null;
- tlink_post_break(a) = null;
- break;
- case init_disc:
- assert(type(v) == disc_node && subtype(v) == select_disc);
- subtype(v) = syllable_disc;
- flush_node_list(vlink_no_break(v));
- vlink_no_break(v) = vlink_post_break(r);
- tlink_no_break(v) = tlink_post_break(r);
- vlink_post_break(r) = null;
- tlink_post_break(r) = null;
- default:
- if (vlink_no_break(r) != null) {
- flush_node_list(vlink_no_break(r));
- vlink_no_break(r) = null;
- tlink_no_break(r) = null;
- }
- if (vlink_pre_break(r) != null) {
- couple_nodes(a, vlink_pre_break(r));
- couple_nodes(tlink_pre_break(r), r);
- vlink_pre_break(r) = null;
- tlink_pre_break(r) = null;
- }
- }
- if (vlink_post_break(r) != null) {
- couple_nodes(r, vlink_post_break(r));
- couple_nodes(tlink_post_break(r), v);
- vlink_post_break(r) = null;
- tlink_post_break(r) = null;
- post_disc_break = true;
- }
- disc_break = true;
- } else if (type(r) == kern_node) {
- width(r) = 0;
- }
- /*tex Adjust the dir stack based on dir nodes in this line. */
- if (have_directional) {
- halfword e, p;
- for (e = vlink(temp_head); e != null && e != cur_break(cur_p); e = vlink(e)) {
- if (type(e) == dir_node) {
- if (subtype(e) == normal_dir) {
- dir_ptr = do_push_dir_node(dir_ptr, e);
- } else if (dir_ptr != null && dir_dir(dir_ptr) == dir_dir(e)) {
- dir_ptr = do_pop_dir_node(dir_ptr);
- }
- }
- }
- assert(e == cur_break(cur_p));
- /*tex Insert dir nodes at the end of the current line. */
- e = vlink(r);
- for (p = dir_ptr; p != null; p = vlink(p)) {
- halfword s = new_dir(dir_dir(p));
- subtype(s) = cancel_dir;
- delete_attribute_ref(node_attr(s));
- node_attr(s) = node_attr(r);
- add_node_attr_ref(node_attr(s));
- couple_nodes(r, s);
- try_couple_nodes(s, e);
- r = s;
- }
- }
- if (passive_right_box(cur_p) != null) {
- halfword s = copy_node_list(passive_right_box(cur_p));
- halfword e = vlink(r);
- couple_nodes(r, s);
- try_couple_nodes(s, e);
- r = s;
- }
- if (q == null) {
- q = r;
- }
- /*tex
- Now [q] refers to the last node on the line and therefore the
- rightmost breakpoint. The only exception is the case of a
- discretionary break with non-empty |pre_break|, then |q| has been
- changed to the last node of the |pre_break| list. If the par ends
- with a \break command, the last line is utterly empty. That is the
- case of |q==temp_head|.
- */
- if (q != temp_head && protrude_chars > 0) {
- halfword p, ptmp;
- if (disc_break && (is_char_node(q) || (type(q) != disc_node))) {
- /*tex |q| is reset to the last node of |pre_break| */
- p = q;
- ptmp = p;
- } else {
- /*tex get |vlink(p) = q| */
- p = alink(q);
- assert(vlink(p) == q);
- ptmp = p;
- }
- p = find_protchar_right(vlink(temp_head), p);
- w = char_pw(p, right_side);
- if (w != 0) {
- /*tex we have found a marginal kern, append it after |ptmp| */
- k = new_margin_kern(-w, last_rightmost_char, right_side);
- delete_attribute_ref(node_attr(k));
- node_attr(k) = node_attr(p);
- add_node_attr_ref(node_attr(k));
- try_couple_nodes(k, vlink(ptmp));
- couple_nodes(ptmp,k);
- if (ptmp == q)
- q = vlink(q);
- }
- }
- /*tex
- If |q| was not a breakpoint at glue and has been reset to |rightskip|
- then we append |rightskip| after |q| now.
- */
- if (!glue_break) {
- /*tex Put the \.{\\rightskip} glue after node |q|. */
- halfword r1 = new_glue((right_skip == null ? zero_glue : right_skip));
- subtype(r1) = right_skip_code+1;
- try_couple_nodes(r1,vlink(q));
- delete_attribute_ref(node_attr(r1));
- node_attr(r1) = node_attr(q);
- add_node_attr_ref(node_attr(r1));
- couple_nodes(q,r1);
- q = r1;
- }
- /*tex
- Modify the end of the line to reflect the nature of the break and to
- include \.{\\rightskip}; also set the proper value of |disc_break|;
- Also put the \.{\\leftskip} glue at the left and detach this line.
-
- The following code begins with |q| at the end of the list to be
- justified. It ends with |q| at the beginning of that list, and with
- |vlink(temp_head)| pointing to the remainder of the paragraph, if
- any.
- */
- r = vlink(q);
- vlink(q) = null;
-
- q = vlink(temp_head);
- try_couple_nodes(temp_head, r);
- if (passive_left_box(cur_p) != null && passive_left_box(cur_p) != 0) {
- halfword s;
- r = copy_node_list(passive_left_box(cur_p));
- s = vlink(q);
- couple_nodes(r,q);
- q = r;
- if ((cur_line == cur_list.pg_field + 1) && (s != null)) {
- if (type(s) == hlist_node) {
- if (list_ptr(s) == null) {
- q = vlink(q);
- try_couple_nodes(r,vlink(s));
- try_couple_nodes(s, r);
- }
- }
- }
- }
- /*tex
- At this point |q| is the leftmost node; all discardable nodes have
- been discarded
- */
- if (protrude_chars > 0) {
- halfword p;
- p = q;
- p = find_protchar_left(p, false);
- w = char_pw(p, left_side);
- if (w != 0) {
- k = new_margin_kern(-w, last_leftmost_char, left_side);
- delete_attribute_ref(node_attr(k));
- node_attr(k) = node_attr(q);
- add_node_attr_ref(node_attr(k));
- couple_nodes(k,q);
- q = k;
- }
- }
- if (! glue_is_zero(left_skip)) {
- r = new_glue(left_skip);
- subtype(r) = left_skip_code+1;
- delete_attribute_ref(node_attr(r));
- node_attr(r) = node_attr(q);
- add_node_attr_ref(node_attr(r));
- couple_nodes(r,q);
- q = r;
- }
- /*tex
- Put the \.{\\leftskip} glue at the left and detach this line. Call
- the packaging subroutine, setting |just_box| to the justified box.
- Now |q| points to the hlist that represents the current line of the
- paragraph. We need to compute the appropriate line width, pack the
- line into a box of this size, and shift the box by the appropriate
- amount of indentation.
- */
- if (cur_line > last_special_line) {
- cur_width = second_width;
- cur_indent = second_indent;
- } else if (par_shape_ptr == null) {
- cur_width = first_width;
- cur_indent = first_indent;
- } else {
- cur_indent = varmem[(par_shape_ptr + 2 * cur_line)].cint;
- cur_width = varmem[(par_shape_ptr + 2 * cur_line + 1)].cint;
- /* needs checking */
- cur_indent = swap_parshape_indent(cur_indent,cur_width);
- }
- adjust_tail = adjust_head;
- pre_adjust_tail = pre_adjust_head;
- if (adjust_spacing > 0) {
- just_box = hpack(q, cur_width, cal_expand_ratio, paragraph_dir);
- } else {
- just_box = hpack(q, cur_width, exactly, paragraph_dir);
- }
- shift_amount(just_box) = cur_indent;
- subtype(just_box) = line_list;
- /*tex
- Call the packaging subroutine, setting |just_box| to the justified
- box.
- */
- if ((vlink(contrib_head) != null))
- checked_break_filter(pre_box);
- if (pre_adjust_head != pre_adjust_tail) {
- append_list(pre_adjust_head, pre_adjust_tail);
- checked_break_filter(pre_adjust);
- }
- pre_adjust_tail = null;
- append_to_vlist(just_box,lua_key_index(post_linebreak));
- checked_break_filter(box);
- if (adjust_head != adjust_tail) {
- append_list(adjust_head, adjust_tail);
- checked_break_filter(adjust);
- }
- adjust_tail = null;
- /*tex
- Append the new box to the current vertical list, followed by the list
- of special nodes taken out of the box by the packager. Append a
- penalty node, if a nonzero penalty is appropriate. Penalties between
- the lines of a paragraph come from club and widow lines, from the
- |inter_line_penalty| parameter, and from lines that end at
- discretionary breaks. Breaking between lines of a two-line paragraph
- gets both club-line and widow-line penalties. The local variable
- |pen| will be set to the sum of all relevant penalties for the
- current line, except that the final line is never penalized.
- */
- if (cur_line + 1 != best_line) {
- q = inter_line_penalties_ptr;
- if (q != null) {
- r = cur_line;
- if (r > penalty(q))
- r = penalty(q);
- pen = penalty(q + r);
- } else {
- if (passive_pen_inter(cur_p) != 0) {
- pen = passive_pen_inter(cur_p);
- } else {
- pen = inter_line_penalty;
- }
- }
- q = club_penalties_ptr;
- if (q != null) {
- /*tex prevgraf */
- r = cur_line - cur_list.pg_field;
- if (r > penalty(q))
- r = penalty(q);
- pen += penalty(q + r);
- } else if (cur_line == cur_list.pg_field + 1) {
- /*tex prevgraf */
- pen += club_penalty;
- }
- q = widow_penalties_ptr;
- if (q != null) {
- r = best_line - cur_line - 1;
- if (r > penalty(q))
- r = penalty(q);
- pen += penalty(q + r);
- } else if (cur_line + 2 == best_line) {
- pen += widow_penalty;
- }
- if (disc_break) {
- if (passive_pen_broken(cur_p) != 0) {
- pen += passive_pen_broken(cur_p);
- } else {
- pen += broken_penalty;
- }
- }
- if (pen != 0) {
- r = new_penalty(pen,linebreak_penalty);
- couple_nodes(cur_list.tail_field, r);
- cur_list.tail_field = r;
- }
- }
- /*tex
- Append a penalty node, if a nonzero penalty is appropriate. Justify
- the line ending at breakpoint |cur_p|, and append it to the current
- vertical list, together with associated penalties and other
- insertions.
- */
- incr(cur_line);
- cur_p = next_break(cur_p);
- if (cur_p != null && !post_disc_break) {
- /*tex
- Prune unwanted nodes at the beginning of the next line. Glue and
- penalty and kern and math nodes are deleted at the beginning of a
- line, except in the anomalous case that the node to be deleted is
- actually one of the chosen breakpoints. Otherwise the pruning
- done here is designed to match the lookahead computation in
- |try_break|, where the |break_width| values are computed for
- non-discretionary breakpoints.
- */
- r = temp_head;
- /*tex
- Normally we have a matching math open and math close node but
- when we cross a line the open node is removed, including any glue
- or penalties following it. This is however not that nice for
- callbacks that rely on symmetry. Of course this only counts for
- one liners, as we can still have only a begin or end node on a
- line. The end_of_math lua helper is made robust against this
- although there you should be aware of the fact that one can end
- up in the middle of math in callbacks that don't work on whole
- paragraphs, but at least this branch makes sure that some proper
- analysis is possible. (todo: check if math glyphs have the
- subtype marked done).
- */
- while (1) {
- q = vlink(r);
- /*
- if (q == cur_break(cur_p) || is_char_node(q))
- break;
- if (!((type(q) == local_par_node))) {
- if (non_discardable(q) || (type(q) == kern_node && subtype(q) != explicit_kern && subtype(q) != italic_kern))
- break;
- }
- */
- if (type(q) == math_node) {
- /*tex begin mathskip code */
- surround(q) = 0 ;
- reset_glue_to_zero(q);
- /*tex end mathskip code */
- }
- if (q == cur_break(cur_p)) {
- break;
- } else if (is_char_node(q)) {
- break;
- } else if (type(q) == local_par_node) {
- /*tex weird, in the middle somewhere */
- } else if (non_discardable(q)) {
- break;
- } else if (type(q) == kern_node && subtype(q) != explicit_kern && subtype(q) != italic_kern) {
- break;
- }
- r = q;
- }
- if (r != temp_head) {
- vlink(r) = null;
- flush_node_list(vlink(temp_head));
- try_couple_nodes(temp_head, q);
- }
- }
- } while (cur_p != null);
- if ((cur_line != best_line) || (vlink(temp_head) != null))
- confusion("line breaking");
- /*tex prevgraf */
- cur_list.pg_field = best_line - 1;
- /*tex |dir_save| */
- cur_list.dirs_field = dir_ptr;
- dir_ptr = null;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h b/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
deleted file mode 100644
index 4aee1492c71..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/postlinebreak.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* postlinebreak.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef POSTLINEBREAK_H
-# define POSTLINEBREAK_H
-
-# define append_list(A,B) do { \
- couple_nodes(cur_list.tail_field,vlink((A))); \
- cur_list.tail_field = (B); \
-} while (0)
-
-void ext_post_line_break(int paragraph_dir,
- int right_skip,
- int left_skip,
- int protrude_chars,
- halfword par_shape_ptr,
- int adjust_spacing,
- halfword inter_line_penalties_ptr,
- int inter_line_penalty,
- int club_penalty,
- halfword club_penalties_ptr,
- halfword widow_penalties_ptr,
- int widow_penalty,
- int broken_penalty,
- halfword final_par_glue,
- halfword best_bet,
- halfword last_special_line,
- scaled second_width,
- scaled second_indent,
- scaled first_width,
- scaled first_indent, halfword best_line);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/primitive.c b/Build/source/texk/web2c/luatexdir/tex/primitive.c
deleted file mode 100644
index f16d69a333c..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/primitive.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
-
-primitive.w
-
-Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-Control sequences are stored and retrieved by means of a fairly standard hash
-table algorithm called the method of ``coalescing lists'' (cf.\ Algorithm 6.4C in
-{\sl The Art of Computer Programming\/}). Once a control sequence enters the
-table, it is never removed, because there are complicated situations involving
-\.{\\gdef} where the removal of a control sequence at the end of a group would be
-a mistake preventable only by the introduction of a complicated reference-count
-mechanism.
-
-The actual sequence of letters forming a control sequence identifier is stored in
-the |str_pool| array together with all the other strings. An auxiliary array
-|hash| consists of items with two halfword fields per word. The first of these,
-called |next(p)|, points to the next identifier belonging to the same coalesced
-list as the identifier corresponding to~|p|; and the other, called |text(p)|,
-points to the |str_start| entry for |p|'s identifier. If position~|p| of the hash
-table is empty, we have |text(p)=0|; if position |p| is either empty or the end
-of a coalesced hash list, we have |next(p)=0|. An auxiliary pointer variable
-called |hash_used| is maintained in such a way that all locations |p>=hash_used|
-are nonempty. The global variable |cs_count| tells how many multiletter control
-sequences have been defined, if statistics are being kept.
-
-A global boolean variable called |no_new_control_sequence| is set to |true|
-during the time that new hash table entries are forbidden.
-
-*/
-
-/*tex The hash table: */
-
-two_halves *hash;
-
-/*tex Allocation pointer for |hash|: */
-
-halfword hash_used;
-
-/*tex |hash_extra=hash| above |eqtb_size|: */
-
-int hash_extra;
-
-/*tex Maximum of the hash array: */
-
-halfword hash_top;
-
-/*tex Pointer to next high hash location: */
-
-halfword hash_high;
-
-/*tex Are new identifiers legal? */
-
-boolean no_new_control_sequence;
-
-/*tex Total number of known identifiers: */
-
-int cs_count;
-
-/*tex Test if all positions are occupied: */
-
-#define hash_is_full (hash_used==hash_base)
-
-/*tex
-
- \.{\\primitive} support needs a few extra variables and definitions,
- like:
-
-*/
-
-#define prim_base 1
-
-/*tex
-
-The arrays |prim| and |prim_eqtb| are used for name -> cmd,chr lookups. The are
-modelled after |hash| and |eqtb|, except that primitives do not have an
-|eq_level|, that field is replaced by |origin|.
-
-*/
-
-/*tex Link for coalesced lists: */
-
-#define prim_next(a) prim[(a)].lhfield
-
-/*tex String number for control sequence name: */
-
-#define prim_text(a) prim[(a)].rh
-
-/*tex Test if all positions are occupied: */
-
-#define prim_is_full (prim_used==prim_base)
-
-#define prim_origin_field(a) (a).hh.b1
-
-#define prim_eq_type_field(a) (a).hh.b0
-
-#define prim_equiv_field(a) (a).hh.rh
-
-/*tex Level of definition: */
-
-#define prim_origin(a) prim_origin_field(prim_eqtb[(a)])
-
-/*tex Command code for equivalent: */
-
-#define prim_eq_type(a) prim_eq_type_field(prim_eqtb[(a)])
-
-/*tex Equivalent value: */
-
-#define prim_equiv(a) prim_equiv_field(prim_eqtb[(a)])
-
-/*tex Allocation pointer for |prim|: */
-
-static pointer prim_used;
-
-/*tex The primitives table: */
-
-static two_halves prim[(prim_size + 1)];
-
-static memory_word prim_eqtb[(prim_size + 1)];
-
-/*tex
-
-The array |prim_data| works the other way around, it is used for cmd,chr -> name
-lookups.
-
-*/
-
-typedef struct prim_info {
- /*tex Number of name entries: */
- halfword subids;
- /*tex Offset to be used for |chr_code|s: */
- halfword offset;
- /*tex Array of names: */
- str_number *names;
-} prim_info;
-
-static prim_info prim_data[(last_cmd + 1)];
-
-/*tex
-
-Initialize the memory arrays:
-
-*/
-
-void init_primitives(void)
-{
- int k;
- memset(prim_data, 0, (sizeof(prim_info) * (last_cmd + 1)));
- memset(prim, 0, (sizeof(two_halves) * (prim_size + 1)));
- memset(prim_eqtb, 0, (sizeof(memory_word) * (prim_size + 1)));
- for (k = 0; k <= prim_size; k++) {
- prim_eq_type(k) = undefined_cs_cmd;
- }
-}
-
-/*tex Nothing is used (yet). */
-
-void ini_init_primitives(void)
-{
- prim_used = prim_size;
-}
-
-
-/*tex
-
-The value of |hash_prime| should be roughly 85\%! of |hash_size|, and it should
-be a prime number. The theory of hashing tells us to expect fewer than two table
-probes, on the average, when the search is successful. [See J.~S. Vitter, {\sl
-Journal of the ACM\/ \bf30} (1983), 231--258.] @^Vitter, Jeffrey Scott@>
-
-*/
-
-static halfword compute_hash(const char *j, unsigned int l, halfword prime_number)
-{
- int k;
- halfword h = (unsigned char) *j;
- for (k = 1; k <= (int)(l - 1); k++) {
- h = h + h + (unsigned char) *(j + k);
- while (h >= prime_number) {
- h = h - prime_number;
- }
- }
- return h;
-}
-
-/*tex
-
-Here is the subroutine that searches the primitive table for an identifier.
-
-*/
-
-pointer prim_lookup(str_number s)
-{
- /*tex The hash code: */
- int h;
- /*tex The index in the |hash| array: */
- pointer p;
- unsigned char *j;
- unsigned l;
- if (s < STRING_OFFSET) {
- p = s;
- if ((p < 0) || (get_prim_eq_type(p) == undefined_cs_cmd)) {
- p = undefined_primitive;
- }
- } else {
- j = str_string(s);
- l = (unsigned) str_length(s);
- h = compute_hash((char *) j, l, prim_prime);
- /*tex We start searching here; note that |0<=h<hash_prime|. */
- p = h + prim_base;
- while (1) {
- if (prim_text(p) > 0)
- if (str_length(prim_text(p)) == l)
- if (str_eq_str(prim_text(p), s))
- goto FOUND;
- if (prim_next(p) == 0) {
- if (no_new_control_sequence) {
- p = undefined_primitive;
- } else {
- /*tex Insert a new primitive after |p|, then make |p| point to it. */
- if (prim_text(p) > 0) {
- do {
- /*tex Search for an empty location in |prim| */
- if (prim_is_full) {
- overflow("primitive size", prim_size);
- }
- decr(prim_used);
- } while (prim_text(prim_used) != 0);
- prim_next(p) = prim_used;
- p = prim_used;
- }
- prim_text(p) = s;
- }
- goto FOUND;
- }
- p = prim_next(p);
- }
- }
- FOUND:
- return p;
-}
-
-/*tex
-
-How to test a csname for primitive-ness?
-
-*/
-
-boolean is_primitive(str_number csname)
-{
- int n, m;
- char *ss;
- m = prim_lookup(csname);
- ss = makecstring(csname);
- n = string_lookup(ss, str_length(csname));
- free(ss);
- return ((n != undefined_cs_cmd) && (m != undefined_primitive) &&
- (eq_type(n) == prim_eq_type(m)) && (equiv(n) == prim_equiv(m)));
-}
-
-
-/*tex
-
-A few simple accessors.
-
-*/
-
-quarterword get_prim_eq_type(int p)
-{
- return prim_eq_type(p);
-}
-
-quarterword get_prim_origin(int p)
-{
- return prim_origin(p);
-}
-
-halfword get_prim_equiv(int p)
-{
- return prim_equiv(p);
-}
-
-str_number get_prim_text(int p)
-{
- return prim_text(p);
-}
-
-
-/*tex
-
-Dumping and undumping.
-
-*/
-
-void dump_primitives(void)
-{
- int p, q;
- for (p = 0; p <= prim_size; p++) {
- dump_hh(prim[p]);
- }
- for (p = 0; p <= prim_size; p++) {
- dump_wd(prim_eqtb[p]);
- }
- for (p = 0; p <= last_cmd; p++) {
- dump_int(prim_data[p].offset);
- dump_int(prim_data[p].subids);
- for (q = 0; q < prim_data[p].subids; q++) {
- dump_int(prim_data[p].names[q]);
- }
- }
-}
-
-void undump_primitives(void)
-{
- int p, q;
- for (p = 0; p <= prim_size; p++) {
- undump_hh(prim[p]);
- }
- for (p = 0; p <= prim_size; p++) {
- undump_wd(prim_eqtb[p]);
- }
- for (p = 0; p <= last_cmd; p++) {
- undump_int(prim_data[p].offset);
- undump_int(prim_data[p].subids);
- if (prim_data[p].subids > 0) {
- prim_data[p].names = (str_number *) xmalloc((unsigned) ((unsigned) prim_data[p].subids * sizeof(str_number *)));
- for (q = 0; q < prim_data[p].subids; q++) {
- undump_int(prim_data[p].names[q]);
- }
- }
- }
-}
-
-/*tex
-
-We need to put \TeX's ``primitive'' control sequences into the hash table,
-together with their command code (which will be the |eq_type|) and an operand
-(which will be the |equiv|). The |primitive| procedure does this, in a way that
-no \TeX\ user can. The global value |cur_val| contains the new |eqtb| pointer
-after |primitive| has acted.
-
-Because the definitions of the actual user-accessible name of a primitive can be
-postponed until runtime, the function |primitive_def| is needed that does nothing
-except creating the control sequence name.
-
-*/
-
-void primitive_def(const char *s, size_t l, quarterword c, halfword o)
-{
- int nncs = no_new_control_sequence;
- no_new_control_sequence = false;
- /*tex This creates the |text()| string: */
- cur_val = string_lookup(s, l);
- no_new_control_sequence = nncs;
- eq_level(cur_val) = level_one;
- eq_type(cur_val) = c;
- equiv(cur_val) = o;
-}
-
-/*tex
-
-The function |store_primitive_name| sets up the bookkeeping for the reverse
-lookup. It is quite paranoid, because it is easy to mess this up accidentally.
-
-The |offset| is needed because sometimes character codes (in |o|) are indices
-into |eqtb| or are offset by a magical value to make sure they do not conflict
-with something else. We don't want the |prim_data[c].names| to have too many
-entries as it will just be wasted room, so |offset| is substracted from |o|
-because creating or accessing the array. The |assert(idx<=0xFFFF)| is not
-strictly needed, but it helps catch errors of this kind.
-
-*/
-
-static void store_primitive_name(str_number s, quarterword c, halfword o, halfword offset)
-{
- int idx;
- /*
- if (prim_data[c].offset != 0 && prim_data[c].offset != offset) {
- assert(false);
- }
- */
- prim_data[c].offset = offset;
- idx = ((int) o - offset);
- /*
- assert(idx >= 0);
- assert(idx <= 0xFFFF);
- */
- if (prim_data[c].subids < (idx + 1)) {
- str_number *new = (str_number *) xcalloc((unsigned) (idx + 1), sizeof(str_number *));
- if (prim_data[c].names != NULL) {
- /*
- assert(prim_data[c].subids);
- */
- memcpy(new, (prim_data[c].names), (unsigned) (prim_data[c].subids) * sizeof(str_number));
- free(prim_data[c].names);
- }
- prim_data[c].names = new;
- prim_data[c].subids = idx + 1;
- }
- prim_data[c].names[idx] = s;
-}
-
-/*tex
-
-Compared to tex82, |primitive| has two extra parameters. The |off| is an offset
-that will be passed on to |store_primitive_name|, the |cmd_origin| is the bit
-that is used to group primitives by originator.
-
-*/
-
-void primitive(const char *thes, quarterword c, halfword o, halfword off, int cmd_origin)
-{
- /*tex Needed to fill |prim_eqtb|: */
- int prim_val;
- str_number ss;
- ss = maketexstring(thes);
- if (cmd_origin == tex_command || cmd_origin == core_command) {
- primitive_def(thes, strlen(thes), c, o);
- }
- prim_val = prim_lookup(ss);
- prim_origin(prim_val) = (quarterword) cmd_origin;
- prim_eq_type(prim_val) = c;
- prim_equiv(prim_val) = o;
- store_primitive_name(ss, c, o, off);
-}
-
-/*tex
-
-Here is a helper that does the actual hash insertion. This code far from ideal:
-the existance of |hash_extra| changes all the potential (short) coalesced lists
-into a single (long) one. This will create a slowdown.
-
-*/
-
-static halfword insert_id(halfword p, const unsigned char *j, unsigned int l)
-{
- unsigned saved_cur_length;
- unsigned saved_cur_string_size;
- unsigned char *saved_cur_string;
- const unsigned char *k;
- if (cs_text(p) > 0) {
- if (hash_high < hash_extra) {
- incr(hash_high);
- /*tex
- Can't we use |eqtb_top| here (perhaps because that is not
- finalized yet when called from |primitive|?
- */
- cs_next(p) = hash_high + eqtb_size;
- p = cs_next(p);
- } else {
- /*tex
- Search for an empty location in |hash|.
- */
- do {
- if (hash_is_full)
- overflow("hash size", (unsigned) (hash_size + hash_extra));
- decr(hash_used);
- } while (cs_text(hash_used) != 0);
- cs_next(p) = hash_used;
- p = hash_used;
- }
- }
- saved_cur_length = cur_length;
- saved_cur_string = cur_string;
- saved_cur_string_size = cur_string_size;
- reset_cur_string();
- for (k = j; k <= j + l - 1; k++) {
- append_char(*k);
- }
- cs_text(p) = make_string();
- cur_length = saved_cur_length;
- xfree(cur_string);
- cur_string = saved_cur_string;
- cur_string_size = saved_cur_string_size;
- incr(cs_count);
- return p;
-}
-
-
-/*tex
-
-Here is the subroutine that searches the hash table for an identifier that
-matches a given string of length |l>1| appearing in |buffer[j.. (j+l-1)]|. If the
-identifier is found, the corresponding hash table address is returned. Otherwise,
-if the global variable |no_new_control_sequence| is |true|, the dummy address
-|undefined_control_sequence| is returned. Otherwise the identifier is inserted
-into the hash table and its location is returned.
-
-*/
-
-pointer id_lookup(int j, int l)
-{
- /*tex The hash code: */
- int h;
- /*tex The index in |hash| array: */
- pointer p;
- h = compute_hash((char *) (buffer + j), (unsigned) l, hash_prime);
- /*tex We start searching here. Note that |0<=h<hash_prime|: */
- p = h + hash_base;
- while (1) {
- if (cs_text(p) > 0)
- if (str_length(cs_text(p)) == (unsigned) l)
- if (str_eq_buf(cs_text(p), j))
- goto FOUND;
- if (cs_next(p) == 0) {
- if (no_new_control_sequence) {
- p = undefined_control_sequence;
- } else {
- p = insert_id(p, (buffer + j), (unsigned) l);
- }
- goto FOUND;
- }
- p = cs_next(p);
- }
- FOUND:
- return p;
-}
-
-/*tex
-
-Here is a similar subroutine for finding a primitive in the hash.
-This one is based on a C string.
-
-*/
-
-pointer string_lookup(const char *s, size_t l)
-{
- /*tex The hash code: */
- int h;
- /*tex The index in |hash| array: */
- pointer p;
- h = compute_hash(s, (unsigned) l, hash_prime);
- /*tex We start searching here. Note that |0<=h<hash_prime|: */
- p = h + hash_base;
- while (1) {
- if (cs_text(p) > 0)
- if (str_eq_cstr(cs_text(p), s, l))
- goto FOUND;
- if (cs_next(p) == 0) {
- if (no_new_control_sequence) {
- p = undefined_control_sequence;
- } else {
- p = insert_id(p, (const unsigned char *) s, (unsigned) l);
- }
- goto FOUND;
- }
- p = cs_next(p);
- }
- FOUND:
- return p;
-}
-
-/*tex
-
-The |print_cmd_chr| routine prints a symbolic interpretation of a command code
-and its modifier. This is used in certain `\.{You can\'t}' error messages, and in
-the implementation of diagnostic routines like \.{\\show}.
-
-The body of |print_cmd_chr| use to be a rather tedious listing of print commands,
-and most of it was essentially an inverse to the |primitive| routine that enters
-a \TeX\ primitive into |eqtb|.
-
-Thanks to |prim_data|, there is no need for all that tediousness. What is left of
-|primt_cnd_chr| are just the exceptions to the general rule that the
-|cmd,chr_code| pair represents in a single primitive command.
-
-*/
-
-#define chr_cmd(A) do { tprint(A); print(chr_code); } while (0)
-
-static void prim_cmd_chr(quarterword cmd, halfword chr_code)
-{
- int idx = chr_code - prim_data[cmd].offset;
- if (cmd <= last_cmd &&
- idx >= 0 && idx < prim_data[cmd].subids &&
- prim_data[cmd].names != NULL && prim_data[cmd].names[idx] != 0) {
- tprint_esc("");
- print(prim_data[cmd].names[idx]);
- } else {
- /* \TEX82 didn't print the |cmd,idx| information, but it may be useful. */
- tprint("[unknown command code! (");
- print_int(cmd);
- tprint(", ");
- print_int(idx);
- tprint(")]");
- }
-}
-
-void print_cmd_chr(quarterword cmd, halfword chr_code)
-{
- int n;
- switch (cmd) {
- case left_brace_cmd:
- chr_cmd("begin-group character ");
- break;
- case right_brace_cmd:
- chr_cmd("end-group character ");
- break;
- case math_shift_cmd:
- chr_cmd("math shift character ");
- break;
- case mac_param_cmd:
- if (chr_code == tab_mark_cmd_code)
- tprint_esc("alignmark");
- else
- chr_cmd("macro parameter character ");
- break;
- case sup_mark_cmd:
- chr_cmd("superscript character ");
- break;
- case sub_mark_cmd:
- chr_cmd("subscript character ");
- break;
- case endv_cmd:
- tprint("end of alignment template");
- break;
- case spacer_cmd:
- chr_cmd("blank space ");
- break;
- case letter_cmd:
- chr_cmd("the letter ");
- break;
- case other_char_cmd:
- chr_cmd("the character ");
- break;
- case tab_mark_cmd:
- if (chr_code == span_code)
- tprint_esc("span");
- else if (chr_code == tab_mark_cmd_code)
- tprint_esc("aligntab");
- else
- chr_cmd("alignment tab character ");
- break;
- case if_test_cmd:
- if (chr_code >= unless_code)
- tprint_esc("unless");
- prim_cmd_chr(cmd, (chr_code % unless_code));
- break;
- case char_given_cmd:
- tprint_esc("char");
- print_qhex(chr_code);
- break;
- case math_given_cmd:
- /*tex
- Okay, it's better for old macro packages that mess with meaning
- to report a traditional value. A compromise.
- */
- tprint_esc("mathchar");
- show_mathcode_value_old(chr_code);
- break;
- case xmath_given_cmd:
- tprint_esc("Umathchar");
- show_mathcode_value(mathchar_from_integer(chr_code, umath_mathcode));
- break;
- case lua_expandable_call_cmd:
- tprint("expandable luacall ");
- print_int(chr_code);
- break;
- case lua_local_call_cmd:
- tprint("local luacall ");
- print_int(chr_code);
- break;
- case lua_call_cmd:
- tprint("luacall ");
- print_int(chr_code);
- break;
- case set_font_cmd:
- tprint("select font ");
- tprint(font_name(chr_code));
- if (font_size(chr_code) != font_dsize(chr_code)) {
- tprint(" at ");
- print_scaled(font_size(chr_code));
- tprint("pt");
- }
- break;
- case undefined_cs_cmd:
- tprint("undefined");
- break;
- case call_cmd:
- case long_call_cmd:
- case outer_call_cmd:
- case long_outer_call_cmd:
- n = cmd - call_cmd;
- if (token_info(token_link(chr_code)) == protected_token)
- n = n + 4;
- if (odd(n / 4))
- tprint_esc("protected");
- if (odd(n))
- tprint_esc("long");
- if (odd(n / 2))
- tprint_esc("outer");
- if (n > 0)
- tprint(" ");
- tprint("macro");
- break;
- case assign_glue_cmd:
- case assign_mu_glue_cmd:
- if (chr_code < skip_base) {
- prim_cmd_chr(cmd, chr_code);
- } else if (chr_code < mu_skip_base) {
- tprint_esc("skip");
- print_int(chr_code - skip_base);
- } else {
- tprint_esc("muskip");
- print_int(chr_code - mu_skip_base);
- }
- break;
- case assign_toks_cmd:
- if (chr_code >= toks_base) {
- tprint_esc("toks");
- print_int(chr_code - toks_base);
- } else {
- prim_cmd_chr(cmd, chr_code);
- }
- break;
- case assign_int_cmd:
- if (chr_code < count_base) {
- prim_cmd_chr(cmd, chr_code);
- } else {
- tprint_esc("count");
- print_int(chr_code - count_base);
- }
- break;
- case assign_attr_cmd:
- tprint_esc("attribute");
- print_int(chr_code - attribute_base);
- break;
- case assign_dimen_cmd:
- if (chr_code < scaled_base) {
- prim_cmd_chr(cmd, chr_code);
- } else {
- tprint_esc("dimen");
- print_int(chr_code - scaled_base);
- }
- break;
- case normal_cmd:
- if (chr_code < prim_data[cmd].subids && prim_data[cmd].names[chr_code] != 0) {
- prim_cmd_chr(cmd, chr_code);
- } else {
- tprint("[unknown command! (");
- print_int(chr_code);
- tprint(")]");
- }
- break;
- case extension_cmd:
- if (chr_code < prim_data[cmd].subids && prim_data[cmd].names[chr_code] != 0) {
- prim_cmd_chr(cmd, chr_code);
- } else {
- tprint("[unknown extension! (");
- print_int(chr_code);
- tprint(")]");
-
- }
- break;
- case node_cmd:
- tprint("node ");
- print_int(chr_code);
- break;
- default:
- /*tex These are most commands, actually. */
- prim_cmd_chr(cmd, chr_code);
- break;
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/primitive.h b/Build/source/texk/web2c/luatexdir/tex/primitive.h
deleted file mode 100644
index b6b13c74f73..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/primitive.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* primitive.h
-
- Copyright 2008-2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef LUATEX_PRIMITIVE_H
-# define LUATEX_PRIMITIVE_H 1
-
-/* This enum is a list of origins for primitive commands */
-
-typedef enum {
- /* Can be modified as suggested ?*/
- tex_command = 1, /* 1 */
- etex_command = 2, /* 2 */
- pdftex_command = 16, /* 4 */ /* obsolete */
- luatex_command = 32, /* 8 */
- core_command = 64, /* 16 */
- no_command = 128, /* 32 */
- umath_command = 256, /* 64 */ /* obsolete */
-} command_origin;
-
-# define hash_size 65536 /* maximum number of control sequences; it should be at most about |(fix_mem_max-fix_mem_min)/10| */
-# define hash_prime 55711 /* a prime number equal to about 85\pct! of |hash_size| */
-
-extern two_halves *hash; /* the hash table */
-extern halfword hash_used; /* allocation pointer for |hash| */
-extern int hash_extra; /* |hash_extra=hash| above |eqtb_size| */
-extern halfword hash_top; /* maximum of the hash array */
-extern halfword hash_high; /* pointer to next high hash location */
-extern boolean no_new_control_sequence; /* are new identifiers legal? */
-extern int cs_count; /* total number of known identifiers */
-
-# define cs_next(a) hash[(a)].lhfield /* link for coalesced lists */
-# define cs_text(a) hash[(a)].rh
- /* string number for control sequence name */
-
-# define undefined_primitive 0
-# define prim_size 2100 /* maximum number of primitives */
-# define prim_prime 1777 /* about 85\pct! of |primitive_size| */
-
-extern void init_primitives(void);
-extern void ini_init_primitives(void);
-
-extern halfword compute_pool_hash(pool_pointer j, pool_pointer l,
- halfword prime_number);
-extern pointer prim_lookup(str_number s);
-
-extern boolean is_primitive(str_number csname);
-
-extern quarterword get_prim_eq_type(int p);
-extern halfword get_prim_equiv(int p);
-extern str_number get_prim_text(int p);
-extern quarterword get_prim_origin(int p);
-
-extern void dump_primitives(void);
-extern void undump_primitives(void);
-
-# define primitive_tex(a,b,c,d) primitive((a),(b),(c),(d),tex_command)
-# define primitive_etex(a,b,c,d) primitive((a),(b),(c),(d),etex_command)
-# define primitive_pdftex(a,b,c,d) primitive((a),(b),(c),(d),pdftex_command)
-# define primitive_luatex(a,b,c,d) primitive((a),(b),(c),(d),luatex_command)
-# define primitive_umath(a,b,c,d) primitive((a),(b),(c),(d),umath_command)
-# define primitive_core(a,b,c,d) primitive((a),(b),(c),(d),core_command)
-# define primitive_no(a,b,c,d) primitive((a),(b),(c),(d),no_command)
-
-extern void primitive(const char *ss, quarterword c, halfword o, halfword off,
- int cmd_origin);
-extern void primitive_def(const char *s, size_t l, quarterword c, halfword o);
-extern void print_cmd_chr(quarterword cmd, halfword chr_code);
-
-extern pointer string_lookup(const char *s, size_t l);
-extern pointer id_lookup(int j, int l);
-
-#endif /* LUATEX_PRIMITIVE_H */
diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.c b/Build/source/texk/web2c/luatexdir/tex/printing.c
deleted file mode 100644
index 31125d2ebca..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/printing.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/*
-
-printing.w
-
-Copyright 2009-2013 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-#define wlog(A) fputc(A,log_file)
-#define wterm(A) fputc(A,term_out)
-
-int new_string_line = 0;
-int escape_controls = 1;
-
-/*tex
-
-Messages that are sent to a user's terminal and to the transcript-log file are
-produced by several `|print|' procedures. These procedures will direct their
-output to a variety of places, based on the setting of the global variable
-|selector|, which has the following possible values:
-
-\startitemize
-
-\startitem
- |term_and_log|, the normal setting, prints on the terminal and on the
- transcript file.
-\stopitem
-
-\startitem
- |log_only|, prints only on the transcript file.
-\stopitem
-
-\startitem
- |term_only|, prints only on the terminal.
-\stopitem
-
-\startitem
- |no_print|, doesn't print at all. This is used only in rare cases before the
- transcript file is open.
-\stopitem
-
-\startitem
- |pseudo|, puts output into a cyclic buffer that is used by the |show_context|
- routine; when we get to that routine we shall discuss the reasoning behind
- this curious mode.
-\stopitem
-
-\startitem
- |new_string|, appends the output to the current string in the string pool.
-\stopitem
-
-\startitem
- 0 to 15, prints on one of the sixteen files for \.{\\write} output.
-\stopitem
-
-\stopitemize
-
-The symbolic names `|term_and_log|', etc., have been assigned numeric codes that
-satisfy the convenient relations |no_print+1=term_only|, |no_print+2=log_only|,
-|term_only+2=log_only+1=term_and_log|.
-
-Three additional global variables, |tally| and |term_offset| and |file_offset|,
-record the number of characters that have been printed since they were most
-recently cleared to zero. We use |tally| to record the length of (possibly very
-long) stretches of printing; |term_offset| and |file_offset|, on the other hand,
-keep track of how many characters have appeared so far on the current line that
-has been output to the terminal or to the transcript file, respectively.
-
-*/
-
-/*tex transcript of \TeX\ session */
-
-alpha_file log_file;
-
-/*tex where to print a message */
-
-int selector = term_only;
-
-/*tex digits in a number being output */
-
-int dig[23];
-
-/*tex the number of characters recently printed */
-
-int tally = 0;
-
-/*tex the number of characters on the current terminal line */
-
-int term_offset = 0;
-
-/*tex the number of characters on the current file line */
-
-int file_offset = 0;
-
-/*tex circular buffer for pseudoprinting */
-
-packed_ASCII_code trick_buf[(ssup_error_line + 1)];
-
-/*tex threshold for pseudoprinting, explained later */
-
-int trick_count;
-
-/*tex another variable for pseudoprinting */
-
-int first_count;
-
-/*tex for minor adjustments to |show_token_list| */
-
-boolean inhibit_par_tokens = false;
-
-/*tex
-
-To end a line of text output, we call |print_ln|
-
-*/
-
-void print_ln(void)
-{
- switch (selector) {
- case no_print:
- break;
- case term_only:
- wterm_cr();
- term_offset = 0;
- break;
- case log_only:
- wlog_cr();
- file_offset = 0;
- break;
- case term_and_log:
- wterm_cr();
- wlog_cr();
- term_offset = 0;
- file_offset = 0;
- break;
- case pseudo:
- break;
- case new_string:
- if (new_string_line > 0)
- print_char(new_string_line);
- break;
- default:
- fprintf(write_file[selector], "\n");
- break;
- }
- /*tex |tally| is not affected */
-}
-
-/*tex
-
-The |print_char| procedure sends one byte to the desired destination. All
-printing comes through |print_ln| or |print_char|, except for the case of
-|tprint| (see below).
-
-The checking of the line length is an inheritance from previosu engines and we
-might drop it after release 1.0. We're not too picky about the exact match of
-that length because we have utf output so length is then a bit fuzzy anyway.
-
-*/
-
-#define needs_escaping(A) \
- ((! escape_controls) || (A>=0x20) || (A==0x0A) || (A==0x0D) || (A==0x09))
-
-#define escaped_char(A) \
- A+64
-
-#define wterm_char(A) \
- if (needs_escaping(A)) { \
- wterm(A); \
- } else { \
- if (term_offset+2>=max_print_line) { \
- wterm_cr(); \
- term_offset=0; \
- } \
- wterm('^'); \
- wterm('^'); \
- wterm(escaped_char(A)); \
- term_offset += 2; \
- }
-
-#define needs_wrapping(A,B) \
- ( (A>=0xC0) && \
- (((A>=0xF0) && (B+4>=max_print_line)) || \
- ((A>=0xE0) && (B+3>=max_print_line)) || \
- ( (B+2>=max_print_line))) \
- )
-
-#define fix_term_offset(A) \
- if (needs_wrapping(A,term_offset)){ \
- wterm_cr(); \
- term_offset=0; \
- }
-
-#define fix_log_offset(A) \
- if (needs_wrapping(A,file_offset)){ \
- wlog_cr(); \
- file_offset=0; \
- }
-
-void print_char(int s)
-{
- if (s < 0 || s > 255) {
- formatted_warning("print","weird character %i",s);
- return;
- }
- if (s == new_line_char_par) {
- if (selector < pseudo) {
- print_ln();
- return;
- }
- }
- switch (selector) {
- case no_print:
- break;
- case term_only:
- fix_term_offset(s);
- wterm_char(s);
- incr(term_offset);
- if (term_offset == max_print_line) {
- wterm_cr();
- term_offset = 0;
- }
- break;
- case log_only:
- fix_log_offset(s);
- wlog(s);
- incr(file_offset);
- if (file_offset == max_print_line) {
- wlog_cr();
- file_offset = 0;
- }
- break;
- case term_and_log:
- fix_term_offset(s);
- fix_log_offset(s);
- wterm_char(s);
- wlog(s);
- incr(term_offset);
- incr(file_offset);
- if (term_offset == max_print_line) {
- wterm_cr();
- term_offset = 0;
- }
- if (file_offset == max_print_line) {
- wlog_cr();
- file_offset = 0;
- }
- break;
- case pseudo:
- if (tally < trick_count)
- trick_buf[tally % error_line] = (packed_ASCII_code) s;
- break;
- case new_string:
- append_char(s);
- break;
- default:
- fprintf(write_file[selector], "%c", s);
- }
- incr(tally);
-}
-
-/*tex
-
-An entire string is output by calling |print|. Note that if we are outputting the
-single standard ASCII character \.c, we could call |print("c")|, since |"c"=99|
-is the number of a single-character string, as explained above. But
-|print_char("c")| is quicker, so \TeX\ goes directly to the |print_char| routine
-when it knows that this is safe. (The present implementation assumes that it is
-always safe to print a visible ASCII character.)
-
-The first 256 entries above the 17th unicode plane are used for a special trick:
-when \TeX\ has to print items in that range, it will instead print the character
-that results from substracting 0x110000 from that value. This allows
-byte-oriented output to things like \.{\\specials} and \.{\\pdfextension
-literals}. Todo: Perhaps it would be useful to do the same substraction while
-typesetting.
-
-
-*/
-
-void print(int s)
-{
- if (s >= str_ptr) {
- normal_warning("print","bad string pointer");
- return;
- } else if (s < STRING_OFFSET) {
- if (s < 0) {
- normal_warning("print","bad string offset");
- } else {
- /*tex We're not sure about this so it's disabled for now! */
- if ((false) && (selector > pseudo)) {
- /*tex internal strings are not expanded */
- print_char(s);
- return;
- }
- if (s == new_line_char_par) {
- if (selector < pseudo) {
- print_ln();
- return;
- }
- }
- if (s <= 0x7F) {
- print_char(s);
- } else if (s <= 0x7FF) {
- print_char(0xC0 + (s / 0x40));
- print_char(0x80 + (s % 0x40));
- } else if (s <= 0xFFFF) {
- print_char(0xE0 + (s / 0x1000));
- print_char(0x80 + ((s % 0x1000) / 0x40));
- print_char(0x80 + ((s % 0x1000) % 0x40));
- } else if (s >= 0x110000) {
- int c = s - 0x110000;
- if (c >= 256) {
- formatted_warning("print", "bad raw byte to print (c=%d), skipped",c);
- } else {
- print_char(c);
- }
- } else {
- print_char(0xF0 + (s / 0x40000));
- print_char(0x80 + ((s % 0x40000) / 0x1000));
- print_char(0x80 + (((s % 0x40000) % 0x1000) / 0x40));
- print_char(0x80 + (((s % 0x40000) % 0x1000) % 0x40));
- }
- }
- return;
- }
- if (selector == new_string) {
- append_string(str_string(s), (unsigned) str_length(s));
- return;
- }
- lprint(&str_lstring(s));
-}
-
-void lprint (lstring *ss) {
- /*tex current character code position */
- unsigned char *j, *l;
- j = ss->s;
- l = j + ss->l;
- while (j < l) {
- /*tex I don't bother checking the last two bytes explicitly */
- /* 0x110000 in utf=8: 0xF4 0x90 0x80 0x80 */
- if ((j < l - 4) && (*j == 0xF4) && (*(j + 1) == 0x90)) {
- int c = (*(j + 2) - 128) * 64 + (*(j + 3) - 128);
- assert(c >= 0 && c < 256);
- print_char(c);
- j = j + 4;
- } else {
- print_char(*j);
- incr(j);
- }
- }
-}
-
-/*tex
-
-The procedure |print_nl| is like |print|, but it makes sure that the string
-appears at the beginning of a new line.
-
-*/
-
-/*tex Moev to the beginning of the next line. */
-
-void print_nlp(void)
-{
- if (new_string_line > 0) {
- print_char(new_string_line);
- } else if (((term_offset > 0) && (odd(selector))) ||
- ((file_offset > 0) && (selector >= log_only))) {
- print_ln();
- }
-}
-
-/*tex Prints string |s| at beginning of the next line. */
-
-void print_nl(str_number s)
-{
- print_nlp();
- print(s);
-}
-
-/*tex
-
-|char *| versions of the same procedures. |tprint| is different because it uses
-buffering, which works well because most of the output actually comes through
-|tprint|.
-
-*/
-
-#define t_flush_buffer(target,offset) \
- buffer[i++] = '\n'; \
- buffer[i++] = '\0';\
- fputs(buffer, target); \
- i = 0; \
- buffer[0] = '\0'; \
- offset=0;
-
-void tprint(const char *sss)
-{
- char *buffer = NULL;
- int i = 0;
- int newlinechar = (lua_only == 1) ? 10 : new_line_char_par;
- int dolog = 0;
- int doterm = 0;
- switch (selector) {
- case no_print:
- return;
- break;
- case term_only:
- doterm = 1;
- break;
- case log_only:
- dolog = 1;
- break;
- case term_and_log:
- dolog = 1;
- doterm = 1;
- break;
- case pseudo:
- while (*sss) {
- if (tally < trick_count) {
- trick_buf[tally % error_line] = (packed_ASCII_code) *sss++;
- tally++;
- } else {
- return;
- }
- }
- return;
- break;
- case new_string:
- append_string((const unsigned char *)sss, (unsigned) strlen(sss));
- return;
- break;
- default:
- {
- char *newstr = xstrdup(sss);
- char *s;
- for (s=newstr;*s;s++) {
- if (*s == newlinechar) {
- *s = '\n';
- }
- }
- fputs(newstr, write_file[selector]);
- free(newstr);
- return;
- }
- break;
- }
- /*tex What is left is the 3 term/log settings. */
- if (dolog || doterm) {
- buffer = xmalloc(strlen(sss)*3);
- /*tex The |wrapup_run| callback acts when the log file is already closed.*/
- if (dolog && log_opened_global) {
- const unsigned char *ss = (const unsigned char *) sss;
- while (*ss) {
- int s = *ss++;
- if (needs_wrapping(s,file_offset) || s == newlinechar) {
- t_flush_buffer(log_file,file_offset);
- }
- if (s != newlinechar) {
- buffer[i++] = s;
- if (file_offset++ == max_print_line) {
- t_flush_buffer(log_file,file_offset);
- }
- }
- }
- if (*buffer) {
- buffer[i++] = '\0';
- fputs(buffer, log_file);
- buffer[0] = '\0';
- }
- i = 0;
- }
- if (doterm) {
- const unsigned char *ss = (const unsigned char *) sss;
- while (*ss) {
- int s = *ss++;
- if (needs_wrapping(s,term_offset) || s == newlinechar) {
- t_flush_buffer(term_out,term_offset);
- }
- if (s != newlinechar) {
- if (needs_escaping(s)) {
- buffer[i++] = s;
- } else {
- buffer[i++] = '^';
- buffer[i++] = '^';
- buffer[i++] = escaped_char(s);
- term_offset += 2;
- }
- if (++term_offset == max_print_line) {
- t_flush_buffer(term_out,term_offset);
- }
- }
- }
- if (*buffer) {
- buffer[i++] = '\0';
- fputs(buffer, term_out);
- }
- }
- free(buffer);
- }
-}
-
-void tprint_nl(const char *s)
-{
- print_nlp();
- tprint(s);
-}
-
-/*tex
-
-Here is the very first thing that \TeX\ prints: a headline that identifies the
-version number and format package. The |term_offset| variable is temporarily
-incorrect, but the discrepancy is not serious since we assume that the banner and
-format identifier together will occupy at most |max_print_line| character
-positions.
-
-*/
-
-void print_banner(const char *v)
-{
- int callback_id = callback_defined(start_run_callback);
- if (callback_id == 0) {
- fprintf(term_out, "This is " MyName ", Version %s%s ", v, WEB2CVERSION);
- if (format_ident > 0)
- print(format_ident);
- print_ln();
- if (show_luahashchars) {
- wterm(' ');
- fprintf(term_out,"Number of bits used by the hash function (" my_name "): %d",LUAI_HASHLIMIT);
- print_ln();
- }
- if (shellenabledp) {
- wterm(' ');
- if (restrictedshell) {
- fprintf(term_out, "restricted ");
- }
- fprintf(term_out, "system commands enabled.\n");
- }
- } else if (callback_id > 0) {
- run_callback(callback_id, "->");
- }
-}
-
-void log_banner(const char *v)
-{
- const char *months[] = { " ",
- "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
- "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
- };
- unsigned month = (unsigned) month_par;
- if (month > 12)
- month = 0;
- fprintf(log_file, "This is " MyName ", Version %s%s ", v, WEB2CVERSION);
- print(format_ident);
- print_char(' ');
- print_char(' ');
- print_int(day_par);
- print_char(' ');
- fprintf(log_file, "%s", months[month]);
- print_char(' ');
- print_int(year_par);
- print_char(' ');
- print_two(time_par / 60);
- print_char(':');
- print_two(time_par % 60);
- if (shellenabledp) {
- wlog_cr();
- wlog(' ');
- if (restrictedshell)
- fprintf(log_file, "restricted ");
- fprintf(log_file, "system commands enabled.");
- }
- if (filelineerrorstylep) {
- wlog_cr();
- fprintf(log_file, " file:line:error style messages enabled.");
- }
-}
-
-void print_version_banner(void)
-{
- fprintf(term_out, "%s", luatex_banner);
-}
-
-/*tex
-
-The procedure |print_esc| prints a string that is preceded by the user's escape
-character (which is usually a backslash).
-
-*/
-
-void print_esc(str_number s)
-{
- /*tex Set variable |c| to the current escape character: */
- int c = escape_char_par;
- if (c >= 0 && c < 0x110000)
- print(c);
- print(s);
-}
-
-/*tex
-
-This prints escape character, then |s|.
-
-*/
-
-void tprint_esc(const char *s)
-{
- /*tex Set variable |c| to the current escape character: */
- int c = escape_char_par;
- if (c >= 0 && c < 0x110000)
- print(c);
- tprint(s);
-}
-
-/*tex
-
-An array of digits in the range |0..15| is printed by |print_the_digs|.
-
-*/
-
-void print_the_digs(eight_bits k)
-{
- /*tex prints |dig[k-1]|$\,\ldots\,$|dig[0]| */
- while (k-- > 0) {
- if (dig[k] < 10)
- print_char('0' + dig[k]);
- else
- print_char('A' - 10 + dig[k]);
- }
-}
-
-/*tex
-
-The following procedure, which prints out the decimal representation of a given
-integer |n|, has been written carefully so that it works properly if |n=0| or if
-|(-n)| would cause overflow. It does not apply |mod| or |div| to negative
-arguments, since such operations are not implemented consistently by all PASCAL
-compilers.
-
-*/
-
-void print_int(longinteger n)
-{
- /*tex index to current digit; we assume that $|n|<10^{23}$ */
- int k = 0;
- /*tex used to negate |n| in possibly dangerous cases */
- longinteger m;
- if (n < 0) {
- print_char('-');
- if (n > -100000000) {
- n = -n;
- } else {
- m = -1 - n;
- n = m / 10;
- m = (m % 10) + 1;
- k = 1;
- if (m < 10)
- dig[0] = (int) m;
- else {
- dig[0] = 0;
- incr(n);
- }
- }
- }
- do {
- dig[k] = (int) (n % 10);
- n = n / 10;
- incr(k);
- } while (n != 0);
- print_the_digs((eight_bits) k);
-}
-
-/*tex
-
-Here is a trivial procedure to print two digits; it is usually called with a
-parameter in the range |0<=n<=99|.
-
-*/
-
-void print_two(int n)
-{
- n = abs(n) % 100;
- print_char('0' + (n / 10));
- print_char('0' + (n % 10));
-}
-
-/*tex
-
-Hexadecimal printing of nonnegative integers is accomplished by |print_hex|.
-
-*/
-
-void print_qhex(int n)
-{
- /*tex index to current digit; we assume that $0\L n<16^{22}$ */
- int k = 0 ;
- print_char('"');
- do {
- dig[k] = n % 16;
- n = n / 16;
- incr(k);
- } while (n != 0);
- print_the_digs((eight_bits) k);
-}
-
-/*tex
-
-Roman numerals are produced by the |print_roman_int| routine. Readers who like
-puzzles might enjoy trying to figure out how this tricky code works; therefore no
-explanation will be given. Notice that 1990 yields \.{mcmxc}, not \.{mxm}.
-
-*/
-
-void print_roman_int(int n)
-{
- char *j, *k;
- int u, v;
- char mystery[] = "m2d5c2l5x2v5i";
- j = (char *) mystery;
- v = 1000;
- while (1) {
- while (n >= v) {
- print_char(*j);
- n = n - v;
- }
- if (n <= 0) {
- /*tex nonpositive input produces no output */
- return;
- }
- k = j + 2;
- u = v / (*(k - 1) - '0');
- if (*(k - 1) == '2') {
- k = k + 2;
- u = u / (*(k - 1) - '0');
- }
- if (n + u >= v) {
- print_char(*k);
- n = n + u;
- } else {
- j = j + 2;
- v = v / (*(j - 1) - '0');
- }
- }
-}
-
-/*tex
-
-The |print| subroutine will not print a string that is still being created. The
-following procedure will.
-
-*/
-
-void print_current_string(void)
-{
- /*tex points to current character code */
- unsigned j = 0;
- while (j < cur_length)
- print_char(cur_string[j++]);
-}
-
-/*tex
-
-The procedure |print_cs| prints the name of a control sequence, given a pointer
-to its address in |eqtb|. A space is printed after the name unless it is a single
-nonletter or an active character. This procedure might be invoked with invalid
-data, so it is ``extra robust.'' The individual characters must be printed one at
-a time using |print|, since they may be unprintable.
-
-*/
-
-void print_cs(int p)
-{
- str_number t = cs_text(p);
- if (p < hash_base) {
- /* nullcs */
- if (p == null_cs) {
- tprint_esc("csname");
- tprint_esc("endcsname");
- print_char(' ');
- } else {
- tprint_esc("IMPOSSIBLE.");
- }
- } else if ((p >= undefined_control_sequence) &&
- ((p <= eqtb_size) || p > eqtb_size + hash_extra)) {
- tprint_esc("IMPOSSIBLE.");
- } else if (t >= str_ptr) {
- tprint_esc("NONEXISTENT.");
- } else {
- if (is_active_cs(t)) {
- print(active_cs_value(t));
- } else {
- print_esc(t);
- if (single_letter(t)) {
- if (get_cat_code(cat_code_table_par, pool_to_unichar(str_string(t))) == letter_cmd)
- print_char(' ');
- } else {
- print_char(' ');
- }
- }
- }
-}
-
-/*tex
-
-Here is a similar procedure; it avoids the error checks, and it never prints a
-space after the control sequence.
-
-*/
-void sprint_cs(pointer p)
-{
- str_number t;
- if (p == null_cs) {
- tprint_esc("csname");
- tprint_esc("endcsname");
- } else {
- t = cs_text(p);
- if (is_active_cs(t))
- print(active_cs_value(t));
- else
- print_esc(t);
- }
-}
-
-void sprint_cs_name(pointer p)
-{
- str_number t;
- if (p != null_cs) {
- t = cs_text(p);
- if (is_active_cs(t))
- print(active_cs_value(t));
- else
- print(t);
- }
-}
-
-/*tex
-
-This procedure is never called when |interaction<scroll_mode|.
-
-*/
-
-void prompt_input(const char *s)
-{
- wake_up_terminal();
- tprint(s);
- term_input();
-}
-
-/*tex
-
-Then there is a subroutine that prints glue stretch and shrink, possibly followed
-by the name of finite units:
-
-*/
-
-void print_glue(scaled d, int order, const char *s)
-{
- print_scaled(d);
- if ((order < normal) || (order > filll)) {
- tprint("foul");
- } else if (order > normal) {
- tprint("fi");
- while (order > sfi) {
- print_char('l');
- decr(order);
- }
- } else if (s != NULL) {
- tprint(s);
- }
-}
-
-/*tex
-
-The next subroutine prints a whole glue specification
-
-*/
-
-void print_spec(int p, const char *s)
-{
- if (p < 0) {
- print_char('*');
- } else {
- print_scaled(width(p));
- if (s != NULL)
- tprint(s);
- if (stretch(p) != 0) {
- tprint(" plus ");
- print_glue(stretch(p), stretch_order(p), s);
- }
- if (shrink(p) != 0) {
- tprint(" minus ");
- print_glue(shrink(p), shrink_order(p), s);
- }
- }
-}
-
-/*tex
-
-We can reinforce our knowledge of the data structures just introduced by
-considering two procedures that display a list in symbolic form. The first of
-these, called |short_display|, is used in ``overfull box'' messages to give the
-top-level description of a list. The other one, called |show_node_list|, prints a
-detailed description of exactly what is in the data structure.
-
-The philosophy of |short_display| is to ignore the fine points about exactly what
-is inside boxes, except that ligatures and discretionary breaks are expanded. As
-a result, |short_display| is a recursive procedure, but the recursion is never
-more than one level deep. @^recursion@>
-
-A global variable |font_in_short_display| keeps track of the font code that is
-assumed to be present when |short_display| begins; deviations from this font will
-be printed.
-
-*/
-
-/*tex An internal font number: */
-
-int font_in_short_display;
-
-/*tex
-
-Boxes, rules, inserts, whatsits, marks, and things in general that are sort of
-``complicated'' are indicated only by printing `\.{[]}'.
-
-We print a bit more than original \TEX. A value of 0 or 1 or any large value will
-behave the same as before. The reason for this extension is that a |name| not
-always makes sense.
-
-\starttyping
-0 \foo xyz
-1 \foo (bar)
-2 <bar> xyz
-3 <bar @ ..> xyz
-4 <id>
-5 <id: bar>
-6 <id: bar @ ..> xyz
-\stoptyping
-
-*/
-
-void print_font_identifier(internal_font_number f)
-{
- str_number fonttext;
- fonttext = font_id_text(f);
- if (tracing_fonts_par >= 2 && tracing_fonts_par <= 6) {
- /*tex < > is less likely to clash with text parenthesis */
- tprint("<");
- if (tracing_fonts_par >= 2 && tracing_fonts_par <= 3) {
- print_font_name(f);
- if (tracing_fonts_par >= 3 || font_size(f) != font_dsize(f)) {
- tprint(" @ ");
- print_scaled(font_size(f));
- tprint("pt");
- }
- } else if (tracing_fonts_par >= 4 && tracing_fonts_par <= 6) {
- print_int(f);
- if (tracing_fonts_par >= 5) {
- tprint(": ");
- print_font_name(f);
- if (tracing_fonts_par >= 6 || font_size(f) != font_dsize(f)) {
- tprint(" @ ");
- print_scaled(font_size(f));
- tprint("pt");
- }
- }
- }
- print_char('>');
- } else {
- /*tex old method, inherited from pdftex */
- if (fonttext > 0) {
- print_esc(fonttext);
- } else {
- tprint_esc("FONT");
- print_int(f);
- }
- if (tracing_fonts_par > 0) {
- tprint(" (");
- print_font_name(f);
- if (font_size(f) != font_dsize(f)) {
- tprint("@");
- print_scaled(font_size(f));
- tprint("pt");
- }
- print_char(')');
- }
- }
-}
-
-/*tex
- We could do this much nicer but then we need to also adapt short_display a
- bit and we have to be as compatible as possible in the log for some macro
- packages.
-
- The callback is also responsible for either or not reporting the character
- number itself.
-*/
-
-void print_character_info(halfword p)
-{
- int callback_id = callback_defined(glyph_info_callback);
- if (callback_id) {
- char* str = NULL;
- run_callback(callback_id, "N->R", p, &str);
- if (str == NULL) {
- print_qhex(character(p));
- } else {
- tprint(str);
- free(str);
- }
- } else {
- print(character(p));
- }
-}
-
-/*tex
- This prints highlights of list |p|.
-*/
-
-void short_display(int p)
-{
- while (p != null) {
- if (is_char_node(p)) {
- if (lig_ptr(p) != null) {
- short_display(lig_ptr(p));
- } else {
- if (font(p) != font_in_short_display) {
- if (!is_valid_font(font(p))) {
- print_char('*');
- } else {
- print_font_identifier(font(p));
- }
- print_char(' ');
- font_in_short_display = font(p);
- }
- print_character_info(p);
- }
- } else {
- /*tex Print a short indication of the contents of node |p| */
- print_short_node_contents(p);
- }
- p = vlink(p);
- }
-}
-
-/*tex
-
-The |show_node_list| routine requires some auxiliary subroutines: one to print a
-font-and-character combination, one to print a token list without its reference
-count, and one to print a rule dimension.
-
-*/
-
-/*tex
-
-This prints |char_node| data.
-
-*/
-
-void print_font_and_char(int p)
-{
- if (!is_valid_font(font(p)))
- print_char('*');
- else
- print_font_identifier(font(p));
- print_char(' ');
- print_character_info(p);
-}
-
-/*tex
-
-This prints token list data in braces
-
-*/
-
-void print_mark(int p)
-{
- print_char('{');
- if ((p < (int) fix_mem_min) || (p > (int) fix_mem_end))
- tprint_esc("CLOBBERED.");
- else
- show_token_list(token_link(p), null, max_print_line - 10);
- print_char('}');
-}
-
-/*tex
-
-This prints dimensions of a rule node.
-
-*/
-
-void print_rule_dimen(scaled d)
-{
- if (is_running(d))
- print_char('*');
- else
- print_scaled(d);
-}
-
-/*tex
-
-Since boxes can be inside of boxes, |show_node_list| is inherently recursive,
-@^recursion@> up to a given maximum number of levels. The history of nesting is
-indicated by the current string, which will be printed at the beginning of each
-line; the length of this string, namely |cur_length|, is the depth of nesting.
-
-A global variable called |depth_threshold| is used to record the maximum depth of
-nesting for which |show_node_list| will show information. If we have
-|depth_threshold=0|, for example, only the top level information will be given
-and no sublists will be traversed. Another global variable, called |breadth_max|,
-tells the maximum number of items to show at each level; |breadth_max| had better
-be positive, or you won't see anything.
-
-*/
-
-/*tex The maximum nesting depth in box displays: */
-
-int depth_threshold;
-
-/*tex The maximum number of items shown at the same list level: */
-
-int breadth_max;
-
-/*tex
-
-The recursive machinery is started by calling |show_box|. Assign the values
-|depth_threshold:=show_box_depth| and |breadth_max:=show_box_breadth|
-
-*/
-
-void show_box(halfword p)
-{
- depth_threshold = show_box_depth_par;
- breadth_max = show_box_breadth_par;
- if (breadth_max <= 0)
- breadth_max = 5;
- /*tex the show starts at |p| */
- show_node_list(p);
- print_ln();
-}
-
-/*tex
-
-Helper for debugging purposes. It prints highlights of list |p|
-
-*/
-
-void short_display_n(int p, int m)
-{
- int i = 0;
- font_in_short_display = null_font;
- if (p == null)
- return;
- while (p != null) {
- if (is_char_node(p)) {
- if (p <= max_halfword) {
- if (font(p) != font_in_short_display) {
- if (!is_valid_font(font(p)))
- print_char('*');
- else
- print_font_identifier(font(p));
- print_char(' ');
- font_in_short_display = font(p);
- }
- print_character_info(p);
- }
- } else {
- if ( (type(p) == glue_node) ||
- (type(p) == disc_node) ||
- (type(p) == penalty_node) ||
- ((type(p) == kern_node) && (subtype(p) == explicit_kern ||
- subtype(p) == italic_kern ))) {
- incr(i);
- }
- if (i >= m)
- return;
- if (type(p) == disc_node) {
- print_char('|');
- short_display(vlink(pre_break(p)));
- print_char('|');
- short_display(vlink(post_break(p)));
- print_char('|');
- } else {
- /*tex Print a short indication of the contents of node |p| */
- print_short_node_contents(p);
- }
- }
- p = vlink(p);
- if (p == null)
- return;
- }
- update_terminal();
-}
-
-/*tex
-
-When debugging a macro package, it can be useful to see the exact control
-sequence names in the format file. For example, if ten new csnames appear, it's
-nice to know what they are, to help pinpoint where they came from. (This isn't a
-truly ``basic'' printing procedure, but that's a convenient module in which to
-put it.)
-
-*/
-
-void print_csnames(int hstart, int hfinish)
-{
- int h;
- unsigned char *c, *l;
- fprintf(stderr, "fmtdebug:csnames from %d to %d:", (int) hstart, (int) hfinish);
- for (h = hstart; h <= hfinish; h++) {
- if (cs_text(h) > 0) {
- /*tex We have anything at this position. */
- c = str_string(cs_text(h));
- l = c + str_length(cs_text(h));
- while (c < l) {
- /*tex Print the characters. */
- fputc(*c++, stderr);
- }
- fprintf(stderr, "|");
- }
- }
-}
-
-/*tex
-
-A helper for printing file:line:error style messages. Look for a filename in
-|full_source_filename_stack|, and if we fail to find one fall back on the
-non-file:line:error style.
-
-*/
-
-void print_file_line(void)
-{
- int level = in_open;
- while ((level > 0) && (full_source_filename_stack[level] == 0))
- decr(level);
- if (level == 0) {
- tprint_nl("! ");
- } else {
- tprint_nl("");
- tprint(full_source_filename_stack[level]);
- print_char(':');
- if (level == in_open)
- print_int(line);
- else
- print_int(line_stack[level + 1]);
- tprint(": ");
- }
-}
-
-/*tex
-
-\TeX\ is occasionally supposed to print diagnostic information that goes only
-into the transcript file, unless |tracing_online| is positive. Here are two
-routines that adjust the destination of print commands:
-
-*/
-
-void begin_diagnostic(void)
-{
- global_old_setting = selector;
- if ((tracing_online_par <= 0) && (selector == term_and_log)) {
- decr(selector);
- if (history == spotless)
- history = warning_issued;
- }
-}
-
-/*tex
-
-Restore proper conditions after tracing.
-
-*/
-
-void end_diagnostic(boolean blank_line)
-{
- tprint_nl("");
- if (blank_line)
- print_ln();
- selector = global_old_setting;
-}
-
-/*
- Indentation (based on a suggestion by PO on tex-implementors but adapted to
- out situation and with built-in limits and so.
-*/
-
-void print_input_level(void)
-{
- int callback_id = callback_defined(input_level_string_callback);
- if (callback_id>0) {
- char *s = NULL;
- if (run_callback(callback_id, "d->S", input_ptr, &s)) {
- if (s && strlen(s) > 0) {
- tprint_nl(s);
- free(s);
- } else {
- print_ln();
- }
- } else {
- print_ln();
- }
- } else {
- int m = level_max;
- if (m) {
- int l = input_ptr;
- int c = level_chr > 0 ? level_chr : '.';
- if (l > m) {
- tprint_nl("[");
- print_int((l/m)*m);
- print(']');
- l = l % m;
- } else {
- print_ln();
- }
- while (l > 0) {
- print(c);
- l--;
- }
- } else {
- print_ln();
- }
- }
-}
-
-/*tex
-
-Of course we had better declare another global variable, if the previous routines
-are going to work.
-
-*/
-
-int global_old_setting;
diff --git a/Build/source/texk/web2c/luatexdir/tex/printing.h b/Build/source/texk/web2c/luatexdir/tex/printing.h
deleted file mode 100644
index 0d87f3d4ae7..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/printing.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* printing.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef PRINTING_H
-# define PRINTING_H
-
-#define last_file_selector 127 /* was 15 */
-
-/*
- Nicer will be to start these with 0 and then use an offset for the write
- registers internally.
-*/
-
-typedef enum {
- no_print = last_file_selector + 1, /* 16 */ /* |selector| setting that makes data disappear */
- term_only = last_file_selector + 2, /* 17 */ /* printing is destined for the terminal only */
- log_only = last_file_selector + 3, /* 18 */ /* printing is destined for the transcript file only */
- term_and_log = last_file_selector + 4, /* 19 */ /* normal |selector| setting */
- pseudo = last_file_selector + 5, /* 20 */ /* special |selector| setting for |show_context| */
- new_string = last_file_selector + 6, /* 21 */ /* printing is deflected to the string pool */
-} selector_settings;
-
-extern int escape_controls;
-extern int new_string_line;
-
-# define ssup_error_line 255
-# define max_selector new_string /* highest selector setting */
-
-extern alpha_file log_file;
-extern int selector;
-extern int dig[23];
-extern int tally;
-extern int term_offset;
-extern int file_offset;
-extern packed_ASCII_code trick_buf[(ssup_error_line + 1)];
-extern int trick_count;
-extern int first_count;
-extern boolean inhibit_par_tokens;
-
-/*
- Macro abbreviations for output to the terminal and to the log file are
- defined here for convenience. Some systems need special conventions
- for terminal output, and it is possible to adhere to those conventions
- by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section.
- @^system dependencies@>
-*/
-
-# define wterm_cr() fprintf(term_out,"\n")
-# define wlog_cr() fprintf(log_file,"\n")
-
-extern void print_ln(void);
-extern void print_char(int s);
-extern void print(int s);
-extern void lprint (lstring *ss);
-extern void print_nl(str_number s);
-extern void print_nlp(void);
-extern void print_banner(const char *);
-extern void log_banner(const char *);
-extern void print_version_banner(void);
-extern void print_esc(str_number s);
-extern void print_the_digs(eight_bits k);
-extern void print_int(longinteger n);
-extern void print_two(int n);
-extern void print_qhex(int n);
-extern void print_roman_int(int n);
-extern void print_current_string(void);
-
-# define print_font_name(A) tprint(font_name(A))
-
-extern void print_cs(int p);
-extern void sprint_cs(pointer p);
-extern void sprint_cs_name(pointer p);
-extern void tprint(const char *s);
-extern void tprint_nl(const char *s);
-extern void tprint_esc(const char *s);
-
-extern void prompt_input(const char *s);
-
-# define single_letter(A) \
- ((str_length(A)==1)|| \
- ((str_length(A)==4)&&*(str_string((A)))>=0xF0)|| \
- ((str_length(A)==3)&&*(str_string((A)))>=0xE0)|| \
- ((str_length(A)==2)&&*(str_string((A)))>=0xC0))
-
-# define is_active_cs(a) \
- (a && str_length(a)>3 && \
- ( *str_string(a) == 0xEF) && \
- (*(str_string(a)+1) == 0xBF) && \
- (*(str_string(a)+2) == 0xBF))
-
-# define active_cs_value(A) pool_to_unichar((str_string((A))+3))
-
-extern void print_glue(scaled d, int order, const char *s); /* prints a glue component */
-extern void print_spec(int p, const char *s); /* prints a glue specification */
-
-extern int font_in_short_display; /* an internal font number */
-extern void print_font_identifier(internal_font_number f);
-extern void short_display(int p); /* prints highlights of list |p| */
-extern void print_font_and_char(int p); /* prints |char_node| data */
-extern void print_mark(int p); /* prints token list data in braces */
-extern void print_rule_dimen(scaled d); /* prints dimension in rule node */
-extern int depth_threshold; /* maximum nesting depth in box displays */
-extern int breadth_max; /* maximum number of items shown at the same list level */
-extern void show_box(halfword p);
-extern void short_display_n(int p, int m); /* prints highlights of list |p| */
-
-extern void print_csnames(int hstart, int hfinish);
-extern void print_file_line(void);
-
-extern void begin_diagnostic(void);
-extern void print_input_level(void);
-extern void end_diagnostic(boolean blank_line);
-extern int global_old_setting;
-
-extern void print_character_info(halfword p);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.c b/Build/source/texk/web2c/luatexdir/tex/scanning.c
deleted file mode 100644
index deddbf5649b..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/scanning.c
+++ /dev/null
@@ -1,2751 +0,0 @@
-/*
-
-Copyright 2009-2012 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-static void scan_expr(void);
-
-/*tex
-
- Let's turn now to some procedures that \TeX\ calls upon frequently to digest
- certain kinds of patterns in the input. Most of these are quite simple; some
- are quite elaborate. Almost all of the routines call |get_x_token|, which can
- cause them to be invoked recursively.
-
- The |scan_left_brace| routine is called when a left brace is supposed to be
- the next non-blank token. (The term ``left brace'' means, more precisely, a
- character whose catcode is |left_brace|.) \TeX\ allows \.{\\relax} to appear
- before the |left_brace|.
-
-*/
-
-/* This reads a mandatory |left_brace|: */
-
-void scan_left_brace(void)
-{
- /*tex Get the next non-blank non-relax non-call token */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd != left_brace_cmd) {
- print_err("Missing { inserted");
- help4(
- "A left brace was mandatory here, so I've put one in.",
- "You might want to delete and/or insert some corrections",
- "so that I will find a matching right brace soon.",
- "If you're confused by all this, try typing `I}' now."
- );
- back_error();
- cur_tok = left_brace_token + '{';
- cur_cmd = left_brace_cmd;
- cur_chr = '{';
- incr(align_state);
- }
-}
-
-/*tex
-
- The |scan_optional_equals| routine looks for an optional `\.=' sign preceded
- by optional spaces; `\.{\\relax}' is not ignored here.
-
-*/
-
-void scan_optional_equals(void)
-{
- /*tex Get the next non-blank non-call token */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok != other_token + '=')
- back_input();
-}
-
-/*tex
-
- Here is a procedure that sounds an alarm when mu and non-mu units are being
- switched.
-
-*/
-
-static void mu_error(void)
-{
- print_err("Incompatible glue units");
- help1("I'm going to assume that 1mu=1pt when they're mixed.");
- error();
-}
-
-/*tex
-
- The next routine `|scan_something_internal|' is used to fetch internal
- numeric quantities like `\.{\\hsize}', and also to handle the `\.{\\the}'
- when expanding constructions like `\.{\\the\\toks0}' and
- `\.{\\the\\baselineskip}'. Soon we will be considering the |scan_int|
- procedure, which calls |scan_something_internal|; on the other hand,
- |scan_something_internal| also calls |scan_int|, for constructions like
- `\.{\\catcode\`\\\$}' or `\.{\\fontdimen} \.3 \.{\\ff}'. So we have to
- declare |scan_int| as a |forward| procedure. A few other procedures are also
- declared at this point.
-
- \TeX\ doesn't know exactly what to expect when |scan_something_internal|
- begins. For example, an integer or dimension or glue value could occur
- immediately after `\.{\\hskip}'; and one can even say \.{\\the} with respect
- to token lists in constructions like `\.{\\xdef\\o\{\\the\\output\}}'. On the
- other hand, only integers are allowed after a construction like
- `\.{\\count}'. To handle the various possibilities, |scan_something_internal|
- has a |level| parameter, which tells the ``highest'' kind of quantity that
- |scan_something_internal| is allowed to produce. Eight levels are
- distinguished, namely |int_val|, |attr_val|, |dimen_val|, |glue_val|,
- |mu_val|, |dir_val|, |ident_val|, and |tok_val|.
-
- The output of |scan_something_internal| (and of the other routines
- |scan_int|, |scan_dimen|, and |scan_glue| below) is put into the global
- variable |cur_val|, and its level is put into |cur_val_level|. The highest
- values of |cur_val_level| are special: |mu_val| is used only when |cur_val|
- points to something in a ``muskip'' register, or to one of the three
- parameters \.{\\thinmuskip}, \.{\\medmuskip}, \.{\\thickmuskip}; |ident_val|
- is used only when |cur_val| points to a font identifier; |tok_val| is used
- only when |cur_val| points to |null| or to the reference count of a token
- list. The last two cases are allowed only when |scan_something_internal| is
- called with |level=tok_val|.
-
- If the output is glue, |cur_val| will point to a glue specification, and the
- reference count of that glue will have been updated to reflect this
- reference; if the output is a nonempty token list, |cur_val| will point to
- its reference count, but in this case the count will not have been updated.
- Otherwise |cur_val| will contain the integer or scaled value in question.
-
-*/
-
-/*tex The value returned by numeric scanners: */
-
-int cur_val;
-
-/*tex Delcodes are sometimes 51 digits: */
-
-int cur_val1;
-
-/*tex The level of this value: */
-
-int cur_val_level;
-
-#define scanned_result(A,B) do { \
- cur_val=A; \
- cur_val_level=B; \
-} while (0)
-
-/*tex
-
- When a |glue_val| changes to a |dimen_val|, we use the width component of the
- glue; there is no need to decrease the reference count, since it has not yet
- been increased. When a |dimen_val| changes to an |int_val|, we use scaled
- points so that the value doesn't actually change. And when a |mu_val| changes
- to a |glue_val|, the value doesn't change either.
-
-*/
-
-static void downgrade_cur_val(boolean delete_glue)
-{
- if (cur_val_level == glue_val_level) {
- halfword m = cur_val;
- cur_val = width(m);
- if (delete_glue)
- flush_node(m);
- } else if (cur_val_level == mu_val_level) {
- mu_error();
- }
- decr(cur_val_level);
-}
-
-void negate_cur_val(boolean modify_glue)
-{
- if (cur_val_level >= glue_val_level) {
- if (modify_glue) {
- /*tex We modify in-place. */
- } else {
- cur_val = new_spec(cur_val);
- }
- negate(width(cur_val));
- negate(stretch(cur_val));
- negate(shrink(cur_val));
- } else {
- negate(cur_val);
- }
-}
-
-/*tex
-
- Some of the internal items can be fetched both routines, and these have been
- split off into the next routine, that returns true if the command code was
- understood.
-
-*/
-
-static boolean short_scan_something_internal(int cmd, int chr, int level, boolean negative)
-{
- /*tex |chr_code| part of the operand token */
- halfword m;
- /*tex general purpose index */
- halfword q;
- /*tex index into |nest| */
- int p;
- int save_cur_chr;
- boolean succeeded = true;
- m = chr;
- switch (cmd) {
- case assign_toks_cmd:
- scanned_result(equiv(m), tok_val_level);
- break;
- case assign_int_cmd:
- scanned_result(eqtb[m].cint, int_val_level);
- break;
- case assign_attr_cmd:
- scanned_result(eqtb[m].cint, int_val_level);
- break;
- case assign_dimen_cmd:
- scanned_result(eqtb[m].cint, dimen_val_level);
- break;
- case assign_glue_cmd:
- scanned_result(equiv(m), glue_val_level);
- break;
- case assign_mu_glue_cmd:
- scanned_result(equiv(m), mu_val_level);
- break;
- case assign_direction_cmd:
- if (m == (int_base + line_direction_code)) {
- m = int_base + text_direction_code;
- }
- scanned_result(eqtb[m].cint, int_val_level);
- break;
- case assign_dir_cmd:
- if (m == (int_base + line_direction_code)) {
- m = int_base + text_direction_code;
- }
- scanned_result(eqtb[m].cint, dir_val_level);
- break;
- case math_style_cmd:
- scanned_result(m, int_val_level);
- break;
- case set_aux_cmd:
- /*tex Fetch the |space_factor| or the |prev_depth|. */
- if (abs(cur_list.mode_field) != m) {
- print_err("Improper ");
- print_cmd_chr(set_aux_cmd, m);
- help4(
- "You can refer to \\spacefactor only in horizontal mode;",
- "you can refer to \\prevdepth only in vertical mode; and",
- "neither of these is meaningful inside \\write. So",
- "I'm forgetting what you said and using zero instead."
- );
- error();
- if (level != tok_val_level)
- scanned_result(0, dimen_val_level);
- else
- scanned_result(0, int_val_level);
- } else if (m == vmode) {
- scanned_result(prev_depth_par, dimen_val_level);
- } else {
- scanned_result(space_factor_par, int_val_level);
- }
- break;
- case set_prev_graf_cmd:
- /*tex Fetch the |prev_graf| */
- if (cur_list.mode_field == 0) {
- /*tex |prev_graf=0| within \.{\\write} */
- scanned_result(0, int_val_level);
- } else {
- p = nest_ptr;
- while (abs(nest[p].mode_field) != vmode)
- decr(p);
- scanned_result(nest[p].pg_field, int_val_level);
- }
- break;
- case set_page_int_cmd:
- /*tex Fetch the |dead_cycles| or the |insert_penalties| */
- if (m == 0)
- cur_val = dead_cycles;
- else if (m == 2)
- cur_val = interaction;
- else
- cur_val = insert_penalties;
- cur_val_level = int_val_level;
- break;
- case set_page_dimen_cmd:
- /*tex Fetch something on the |page_so_far|. */
- if ((page_contents == empty) && (!output_active)) {
- if (m == 0)
- cur_val = max_dimen;
- else
- cur_val = 0;
- } else {
- cur_val = page_so_far[m];
- }
- cur_val_level = dimen_val_level;
- break;
- case set_tex_shape_cmd:
- /*tex Fetch the |par_shape| size. */
- if (par_shape_par_ptr == null)
- cur_val = 0;
- else
- cur_val = vinfo(par_shape_par_ptr + 1);
- cur_val_level = int_val_level;
- break;
- case set_etex_shape_cmd:
- /*tex Fetch a penalties array element. */
- scan_int();
- if ((equiv(m) == null) || (cur_val < 0)) {
- cur_val = 0;
- } else {
- if (cur_val > penalty(equiv(m)))
- cur_val = penalty(equiv(m));
- cur_val = penalty(equiv(m) + cur_val);
- }
- cur_val_level = int_val_level;
- break;
- case char_given_cmd:
- case math_given_cmd:
- case xmath_given_cmd:
- scanned_result(cur_chr, int_val_level);
- break;
- case last_item_cmd:
- /*tex
-
- Because the items in this case directly refer to |cur_chr|, it
- needs to be saved and restored.
-
- */
- save_cur_chr = cur_chr;
- cur_chr = chr;
- /*tex
-
- Fetch an item in the current node, if appropriate. Here is where
- \.{\\lastpenalty}, \.{\\lastkern}, and \.{\\ } are implemented.
- The reference count for \.{\\lastskip} will be updated later.
-
- We also handle \.{\\inputlineno} and \.{\\badness} here, because
- they are legal in similar contexts.
-
- */
- if (m >= input_line_no_code) {
- if (m >= eTeX_glue) {
- /*tex Process an expression and |return|. */
- if (m < eTeX_mu) {
- if (m == mu_to_glue_code) {
- scan_mu_glue();
- };
- cur_val_level = glue_val_level;
- } else if (m < eTeX_expr) {
- if (m == glue_to_mu_code) {
- scan_normal_glue();
- }
- cur_val_level = mu_val_level;
- } else {
- cur_val_level = m - eTeX_expr + int_val_level;
- scan_expr();
- }
- /*tex
-
- This code for reducing |cur_val_level| and\slash or
- negating the result is similar to the one for all the
- other cases of |scan_something_internal|; we free a
- glue_spec when needed.
-
- */
- while (cur_val_level > level) {
- downgrade_cur_val(true);
- }
- if (negative) {
- /*tex
-
- We get a new glue spec node with negated values and
- the old intermediate is deleted.
-
- */
- negate_cur_val(true);
- }
- return succeeded;
- } else if (m >= eTeX_dim) {
- switch (m) {
- case font_char_wd_code:
- case font_char_ht_code:
- case font_char_dp_code:
- case font_char_ic_code:
- scan_font_ident();
- q = cur_val;
- scan_char_num();
- if (char_exists(q, cur_val)) {
- switch (m) {
- case font_char_wd_code:
- cur_val = char_width(q, cur_val);
- break;
- case font_char_ht_code:
- cur_val = char_height(q, cur_val);
- break;
- case font_char_dp_code:
- cur_val = char_depth(q, cur_val);
- break;
- case font_char_ic_code:
- cur_val = char_italic(q, cur_val);
- break;
- }
- } else {
- cur_val = 0;
- }
- break;
- case par_shape_length_code:
- case par_shape_indent_code:
- case par_shape_dimen_code:
- q = cur_chr - par_shape_length_code;
- scan_int();
- if ((par_shape_par_ptr == null) || (cur_val <= 0)) {
- cur_val = 0;
- } else {
- if (q == 2) {
- q = cur_val % 2;
- cur_val = (cur_val + q) / 2;
- }
- if (cur_val > vinfo(par_shape_par_ptr + 1))
- cur_val = vinfo(par_shape_par_ptr + 1);
- cur_val =
- varmem[par_shape_par_ptr + 2 * cur_val - q + 1].cint;
- }
- cur_val_level = dimen_val_level;
- break;
- case glue_stretch_code:
- case glue_shrink_code:
- scan_normal_glue();
- q = cur_val;
- if (m == glue_stretch_code)
- cur_val = stretch(q);
- else
- cur_val = shrink(q);
- flush_node(q);
- break;
- }
- cur_val_level = dimen_val_level;
- } else {
- switch (m) {
- case input_line_no_code:
- cur_val = line;
- break;
- case badness_code:
- cur_val = last_badness;
- break;
- case luatex_version_code:
- cur_val = get_luatexversion();
- break;
- case last_saved_box_resource_index_code:
- cur_val = last_saved_box_index;
- break;
- case last_saved_image_resource_index_code:
- cur_val = last_saved_image_index;
- break;
- case last_saved_image_resource_pages_code:
- cur_val = last_saved_image_pages;
- break;
- case last_x_pos_code:
- cur_val = last_position.h;
- break;
- case last_y_pos_code:
- cur_val = last_position.v;
- break;
- case random_seed_code:
- cur_val = random_seed;
- break;
- case eTeX_version_code:
- cur_val = eTeX_version;
- break;
- case eTeX_minor_version_code:
- cur_val = eTeX_minor_version;
- break;
- case current_group_level_code:
- cur_val = cur_level - level_one;
- break;
- case current_group_type_code:
- cur_val = cur_group;
- break;
- case current_if_level_code:
- q = cond_ptr;
- cur_val = 0;
- while (q != null) {
- incr(cur_val);
- q = vlink(q);
- }
- break;
- case current_if_type_code:
- if (cond_ptr == null)
- cur_val = 0;
- else if (cur_if < unless_code)
- cur_val = cur_if + 1;
- else
- cur_val = -(cur_if - unless_code + 1);
- break;
- case current_if_branch_code:
- if ((if_limit == or_code) || (if_limit == else_code))
- cur_val = 1;
- else if (if_limit == fi_code)
- cur_val = -1;
- else
- cur_val = 0;
- break;
- case glue_stretch_order_code:
- case glue_shrink_order_code:
- case eTeX_glue_stretch_order_code:
- case eTeX_glue_shrink_order_code:
- scan_normal_glue();
- q = cur_val;
- if (m == glue_stretch_order_code || m == eTeX_glue_stretch_order_code) {
- cur_val = stretch_order(q);
- } else {
- cur_val = shrink_order(q);
- }
- if (cur_val && (m == eTeX_glue_stretch_order_code || m == eTeX_glue_shrink_order_code)) {
- cur_val = (cur_val == 1) ? - 1 : cur_val - 1;
- }
- flush_node(q);
- break;
- }
- cur_val_level = int_val_level;
- }
- } else {
- if (cur_chr == glue_val_level)
- cur_val = zero_glue;
- else
- cur_val = 0;
- if (cur_chr == last_node_type_code) {
- cur_val_level = int_val_level;
- if ((cur_list.tail_field == cur_list.head_field)
- || (cur_list.mode_field == 0))
- cur_val = -1;
- } else {
- /*tex assumes identical values */
- cur_val_level = cur_chr;
- }
- if ((cur_list.tail_field != contrib_head) && (cur_list.mode_field != 0)) {
- switch (cur_chr) {
- case lastpenalty_code:
- if (type(cur_list.tail_field) == penalty_node)
- cur_val = penalty(cur_list.tail_field);
- break;
- case lastkern_code:
- if (type(cur_list.tail_field) == kern_node)
- cur_val = width(cur_list.tail_field);
- break;
- case lastskip_code:
- if (type(cur_list.tail_field) == glue_node)
- cur_val = cur_list.tail_field;
- if (subtype(cur_list.tail_field) == mu_glue)
- cur_val_level = mu_val_level;
- break;
- case last_node_type_code:
- cur_val = visible_last_node_type(cur_list.tail_field);
- break;
- }
- } else if ((cur_list.mode_field == vmode) && (cur_list.tail_field == cur_list.head_field)) {
- switch (cur_chr) {
- case lastpenalty_code:
- cur_val = last_penalty;
- break;
- case lastkern_code:
- cur_val = last_kern;
- break;
- case lastskip_code:
- if (last_glue != max_halfword)
- cur_val = last_glue;
- break;
- case last_node_type_code:
- cur_val = last_node_type;
- break;
- }
- }
- }
- cur_chr = save_cur_chr;
- break;
- default:
- succeeded = false;
- }
- if (succeeded) {
- while (cur_val_level > level) {
- /*tex Convert |cur_val| to a lower level. */
- downgrade_cur_val(false);
- }
- /*tex
-
- Fix the reference count, if any, and negate |cur_val| if |negative|.
- If |cur_val| points to a glue specification at this point, the
- reference count for the glue does not yet include the reference by
- |cur_val|. If |negative| is |true|, |cur_val_level| is known to be
- |<=mu_val|.
-
- */
- if (negative) {
- /*tex We create a new (negated) glue spec and keep the old one. */
- negate_cur_val(false);
- } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) {
- cur_val = new_spec(cur_val);
- }
- }
- return succeeded;
-}
-
-/*tex
-
- First, here is a short routine that is called from lua code. All the real
- work is delegated to |short_scan_something_internal| that is shared between
- this routine and |scan_something_internal|.
-
-*/
-
-void scan_something_simple(halfword cmd, halfword subitem)
-{
- /*tex Negative is never true. */
- if (!short_scan_something_internal(cmd, subitem, tok_val_level, false)) {
- /*tex Complain that |texlib| can not do this; give zero result. */
- print_err("You can't use `");
- print_cmd_chr((quarterword) cmd, subitem);
- tprint("' as tex library index");
- help1("I'm forgetting what you said and using zero instead.");
- error();
- scanned_result(0, int_val_level);
- }
-}
-
-/*tex
-
- OK, we're ready for |scan_something_internal| itself. A second parameter,
- |negative|, is set |true| if the value that is found should be negated. It is
- assumed that |cur_cmd| and |cur_chr| represent the first token of the
- internal quantity to be scanned; an error will be signalled if
- |cur_cmd<min_internal| or |cur_cmd>max_internal|.
-
-*/
-
-/*tex Fetch an internal parameter: */
-
-void scan_something_internal(int level, boolean negative)
-{
- /*tex |chr_code| part of the operand token */
- halfword m;
- /*tex accumulators */
- int n, k;
- RESTART:
- m = cur_chr;
- if (!short_scan_something_internal(cur_cmd, cur_chr, level, negative)) {
- switch (cur_cmd) {
- case def_char_code_cmd:
- /*tex Fetch a character code from some table */
- scan_char_num();
- if (m == math_code_base) {
- cur_val1 = get_math_code_num(cur_val);
- scanned_result(cur_val1, int_val_level);
- } else if (m == lc_code_base) {
- cur_val1 = get_lc_code(cur_val);
- scanned_result(cur_val1, int_val_level);
- } else if (m == uc_code_base) {
- cur_val1 = get_uc_code(cur_val);
- scanned_result(cur_val1, int_val_level);
- } else if (m == sf_code_base) {
- cur_val1 = get_sf_code(cur_val);
- scanned_result(cur_val1, int_val_level);
- } else if (m == cat_code_base) {
- cur_val1 = get_cat_code(cat_code_table_par, cur_val);
- scanned_result(cur_val1, int_val_level);
- } else {
- confusion("def_char");
- }
- break;
- case def_del_code_cmd:
- case extdef_del_code_cmd:
- /*tex Fetch a character code from some table. */
- scan_char_num();
- cur_val1 = get_del_code_num(cur_val);
- scanned_result(cur_val1, int_val_level);
- break;
- case extdef_math_code_cmd:
- /*tex Fetch an extended math code table value. */
- scan_char_num();
- cur_val1 = get_math_code_num(cur_val);
- scanned_result(cur_val1, int_val_level);
- break;
- case toks_register_cmd:
- case set_font_cmd:
- case def_font_cmd:
- case letterspace_font_cmd:
- case copy_font_cmd:
- /*tex Fetch a token list or font identifier, provided that |level=tok_val|. */
- if (level != tok_val_level) {
- print_err("Missing number, treated as zero");
- help3(
- "A number should have been here; I inserted `0'.",
- "(If you can't figure out why I needed to see a number,",
- "look up `weird error' in the index to The TeXbook.)"
- );
- back_error();
- scanned_result(0, dimen_val_level);
- } else if (cur_cmd == toks_register_cmd) {
- scan_register_num();
- m = toks_base + cur_val;
- scanned_result(equiv(m), tok_val_level);
- } else {
- back_input();
- scan_font_ident();
- scanned_result(font_id_base + cur_val, ident_val_level);
- }
- break;
- case set_font_id_cmd:
- scan_int();
- scanned_result(font_id_base + cur_val, ident_val_level);
- break;
- case def_family_cmd:
- /*tex Fetch a math font identifier. */
- scan_char_num();
- cur_val1 = fam_fnt(cur_val, m);
- scanned_result(font_id_base + cur_val1, ident_val_level);
- break;
- case set_math_param_cmd:
- /*tex Fetch a math parameter. */
- cur_val1 = cur_chr;
- get_token();
- if (cur_cmd != math_style_cmd) {
- print_err("Missing math style, treated as \\displaystyle");
- help1("A style should have been here; I inserted `\\displaystyle'.");
- cur_val = display_style;
- back_error();
- } else {
- cur_val = cur_chr;
- }
- if (cur_val1 < math_param_first_mu_glue) {
- if (cur_val1 == math_param_radical_degree_raise) {
- cur_val1 = get_math_param(cur_val1, cur_chr);
- scanned_result(cur_val1, int_val_level);
- } else {
- cur_val1 = get_math_param(cur_val1, cur_chr);
- scanned_result(cur_val1, dimen_val_level);
- }
- } else {
- cur_val1 = get_math_param(cur_val1, cur_chr);
- if (cur_val1 == thin_mu_skip_code)
- cur_val1 = thin_mu_skip_par;
- else if (cur_val1 == med_mu_skip_code)
- cur_val1 = med_mu_skip_par;
- else if (cur_val1 == thick_mu_skip_code)
- cur_val1 = thick_mu_skip_par;
- scanned_result(cur_val1, mu_val_level);
- }
- break;
- case assign_box_dir_cmd:
- scan_register_num();
- m = cur_val;
- if (box(m) != null)
- cur_val = box_dir(box(m));
- else
- cur_val = 0;
- cur_val_level = dir_val_level;
- break;
- case set_box_dimen_cmd:
- /*tex Fetch a box dimension. */
- scan_register_num();
- if (box(cur_val) == null)
- cur_val = 0;
- else
- cur_val = varmem[box(cur_val) + m].cint;
- cur_val_level = dimen_val_level;
- break;
- case assign_font_dimen_cmd:
- /*tex Fetch a font dimension. */
- get_font_dimen();
- break;
- case assign_font_int_cmd:
- /*tex Fetch a font integer. */
- scan_font_ident();
- if (m == 0) {
- scanned_result(hyphen_char(cur_val), int_val_level);
- } else if (m == 1) {
- scanned_result(skew_char(cur_val), int_val_level);
- } else if (m == no_lig_code) {
- scanned_result(test_no_ligatures(cur_val), int_val_level);
- } else {
- n = cur_val;
- scan_char_num();
- k = cur_val;
- switch (m) {
- case lp_code_base:
- scanned_result(get_lp_code(n, k), int_val_level);
- break;
- case rp_code_base:
- scanned_result(get_rp_code(n, k), int_val_level);
- break;
- case ef_code_base:
- scanned_result(get_ef_code(n, k), int_val_level);
- break;
- case tag_code:
- scanned_result(get_tag_code(n, k), int_val_level);
- break;
- }
- }
- break;
- case register_cmd:
- /*tex Fetch a register */
- scan_register_num();
- switch (m) {
- case int_val_level:
- cur_val = count(cur_val);
- break;
- case attr_val_level:
- cur_val = attribute(cur_val);
- break;
- case dimen_val_level:
- cur_val = dimen(cur_val);
- break;
- case glue_val_level:
- cur_val = skip(cur_val);
- break;
- case mu_val_level:
- cur_val = mu_skip(cur_val);
- break;
- }
- cur_val_level = m;
- break;
- case ignore_spaces_cmd:
- /*tex Trap unexpandable primitives. */
- if (cur_chr == 1) {
- /*tex
-
- Reset |cur_tok| for unexpandable primitives, goto
- restart. This block deals with unexpandable
- \.{\\primitive} appearing at a spot where an integer or
- an internal values should have been found. It fetches the
- next token then resets |cur_cmd|, |cur_cs|, and
- |cur_tok|, based on the primitive value of that token. No
- expansion takes place, because the next token may be all
- sorts of things. This could trigger further expansion
- creating new errors.
-
- */
- get_token();
- cur_cs = prim_lookup(cs_text(cur_cs));
- if (cur_cs != undefined_primitive) {
- cur_cmd = get_prim_eq_type(cur_cs);
- cur_chr = get_prim_equiv(cur_cs);
- cur_tok = token_val(cur_cmd, cur_chr);
- } else {
- cur_cmd = relax_cmd;
- cur_chr = 0;
- cur_tok = cs_token_flag + frozen_relax;
- cur_cs = frozen_relax;
- }
- goto RESTART;
- }
- break;
- case hyph_data_cmd:
- switch (cur_chr) {
- case 0:
- case 1:
- goto DEFAULT;
- break;
- case 2:
- cur_val = get_pre_hyphen_char(language_par);
- cur_val_level = int_val_level;
- break;
- case 3:
- cur_val = get_post_hyphen_char(language_par);
- cur_val_level = int_val_level;
- break;
- case 4:
- cur_val = get_pre_exhyphen_char(language_par);
- cur_val_level = int_val_level;
- break;
- case 5:
- cur_val = get_post_exhyphen_char(language_par);
- cur_val_level = int_val_level;
- break;
- case 6:
- cur_val = get_hyphenation_min(language_par);
- cur_val_level = int_val_level;
- break;
- case 7:
- scan_int();
- cur_val = get_hj_code(language_par,cur_val);
- cur_val_level = int_val_level;
- break;
- }
- break;
- default:
- DEFAULT:
- /*tex Complain that \.{\\the} can not do this; give zero result. */
- print_err("You can't use `");
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- tprint("' after \\the");
- help1("I'm forgetting what you said and using zero instead.");
- error();
- if (level != tok_val_level)
- scanned_result(0, dimen_val_level);
- else
- scanned_result(0, int_val_level);
- break;
- }
- while (cur_val_level > level) {
- /*tex Convert |cur_val| to a lower level. */
- downgrade_cur_val(false);
- }
- /*tex
-
- Fix the reference count, if any, and negate |cur_val| if |negative|.
- If |cur_val| points to a glue specification at this point, the
- reference count for the glue does not yet include the reference by
- |cur_val|. If |negative| is |true|, |cur_val_level| is known to be
- |<=mu_val|.
-
- */
- if (negative) {
- /*tex We create a new (negated) glue spec and keep the old one. */
- negate_cur_val(false);
- } else if ((cur_val_level >= glue_val_level) && (cur_val_level <= mu_val_level)) {
- cur_val = new_spec(cur_val);
- }
- }
-}
-
-/*tex
-
- It is nice to have routines that say what they do, so the original
- |scan_eight_bit_int| is superceded by |scan_register_num| and
- |scan_mark_num|. It may become split up even further in the future.
-
- Many of the |restricted classes| routines are the essentially the same except
- for the upper limit and the error message, so it makes sense to combine these
- all into one function.
-
-*/
-
-void scan_limited_int(int max, const char *name)
-{
- char hlp[80];
- scan_int();
- if ((cur_val < 0) || (cur_val > max)) {
- if (name == NULL) {
- snprintf(hlp, 80, "Since I expected to read a number between 0 and %d,", max);
- print_err("Bad number");
- } else {
- char msg[80];
- snprintf(hlp, 80, "A %s must be between 0 and %d.", name, max);
- snprintf(msg, 80, "Bad %s", name);
- print_err(msg);
- }
- help2(hlp, "I changed this one to zero.");
- int_error(cur_val);
- cur_val = 0;
- }
-}
-
-void scan_fifteen_bit_int(void)
-{
- scan_real_fifteen_bit_int();
- cur_val = ((cur_val / 0x1000) * 0x1000000) + (((cur_val % 0x1000) / 0x100) * 0x10000) + (cur_val % 0x100);
-}
-
-void scan_fifty_one_bit_int(void)
-{
- int iiii;
- scan_int();
- if ((cur_val < 0) || (cur_val > 0777777777)) {
- print_err("Bad delimiter code");
- help2(
- "A numeric delimiter (first part) must be between 0 and 2^{27}-1.",
- "I changed this one to zero."
- );
- int_error(cur_val);
- cur_val = 0;
- }
- iiii = cur_val;
- scan_int();
- if ((cur_val < 0) || (cur_val > 0xFFFFFF)) {
- print_err("Bad delimiter code");
- help2(
- "A numeric delimiter (second part) must be between 0 and 2^{24}-1.",
- "I changed this one to zero."
- );
- int_error(cur_val);
- cur_val = 0;
- }
- cur_val1 = cur_val;
- cur_val = iiii;
-}
-
-/*tex
-
- An integer number can be preceded by any number of spaces and `\.+' or `\.-'
- signs. Then comes either a decimal constant (i.e., radix 10), an octal
- constant (i.e., radix 8, preceded by~'), a hexadecimal constant (radix 16,
- preceded by~"), an alphabetic constant (preceded by~`), or an internal
- variable. After scanning is complete, |cur_val| will contain the answer,
- which must be at most $2^{31}-1=2147483647$ in absolute value. The value of
- |radix| is set to 10, 8, or 16 in the cases of decimal, octal, or hexadecimal
- constants, otherwise |radix| is set to zero. An optional space follows a
- constant.
-
-*/
-
-/*tex |scan_int| sets this to 8, 10, 16, or zero */
-
-int radix;
-
-/*tex
-
- The |scan_int| routine is used also to scan the integer part of a fraction;
- for example, the `\.3' in `\.{3.14159}' will be found by |scan_int|. The
- |scan_dimen| routine assumes that |cur_tok=point_token| after the integer
- part of such a fraction has been scanned by |scan_int|, and that the decimal
- point has been backed up to be scanned again.
-
-*/
-
-/*tex Sets |cur_val| to an integer: */
-
-void scan_int(void)
-{
- /*tex should the answer be negated? */
- boolean negative;
- /*tex |$2^{31}$ / radix|, the threshold of danger */
- int m;
- /*tex the digit just scanned */
- int d;
- /*tex have no digits appeared? */
- boolean vacuous;
- /*tex has an error message been issued? */
- boolean OK_so_far;
- radix = 0;
- OK_so_far = true;
- /*tex Get the next non-blank non-sign token; set |negative| appropriately. */
- negative = false;
- do {
- /*tex Get the next non-blank non-call token. */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok == other_token + '-') {
- negative = !negative;
- cur_tok = other_token + '+';
- }
- } while (cur_tok == other_token + '+');
-
- RESTART:
- if (cur_tok == alpha_token) {
- /*tex
-
- Scan an alphabetic character code into |cur_val|. A space is ignored
- after an alphabetic character constant, so that such constants behave
- like numeric ones.
-
- */
- /*tex Suppress macro expansion: */
- get_token();
- if (cur_tok < cs_token_flag) {
- cur_val = cur_chr;
- if (cur_cmd <= right_brace_cmd) {
- if (cur_cmd == right_brace_cmd)
- incr(align_state);
- else
- decr(align_state);
- }
- } else {
- /*tex The value of a csname in this context is its name. */
- str_number txt = cs_text(cur_tok - cs_token_flag);
- if (is_active_cs(txt))
- cur_val = active_cs_value(txt);
- else if (single_letter(txt))
- cur_val = pool_to_unichar(str_string(txt));
- else
- cur_val = (biggest_char + 1);
- }
- if (cur_val > biggest_char) {
- print_err("Improper alphabetic constant");
- help2(
- "A one-character control sequence belongs after a ` mark.",
- "So I'm essentially inserting \\0 here."
- );
- cur_val = '0';
- back_error();
- } else {
- /*tex Scan an optional space. */
- get_x_token();
- if (cur_cmd != spacer_cmd)
- back_input();
- }
-
- } else if (cur_tok == cs_token_flag + frozen_primitive) {
- /*tex
-
- Reset |cur_tok| for unexpandable primitives, goto restart This block
- deals with unexpandable \.{\\primitive} appearing at a spot where an
- integer or an internal values should have been found. It fetches the
- next token then resets |cur_cmd|, |cur_cs|, and |cur_tok|, based on
- the primitive value of that token. No expansion takes place, because
- the next token may be all sorts of things. This could trigger further
- expansion creating new errors.
-
- */
- get_token();
- cur_cs = prim_lookup(cs_text(cur_cs));
- if (cur_cs != undefined_primitive) {
- cur_cmd = get_prim_eq_type(cur_cs);
- cur_chr = get_prim_equiv(cur_cs);
- cur_tok = token_val(cur_cmd, cur_chr);
- } else {
- cur_cmd = relax_cmd;
- cur_chr = 0;
- cur_tok = cs_token_flag + frozen_relax;
- cur_cs = frozen_relax;
- }
- goto RESTART;
- } else if (cur_cmd == math_style_cmd) {
- cur_val = cur_chr;
- } else if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
- scan_something_internal(int_val_level, false);
- } else {
- /*tex Scan a numeric constant. */
- radix = 10;
- m = 214748364;
- if (cur_tok == octal_token) {
- radix = 8;
- m = 02000000000;
- get_x_token();
- } else if (cur_tok == hex_token) {
- radix = 16;
- m = 01000000000;
- get_x_token();
- }
- vacuous = true;
- cur_val = 0;
- /*tex Accumulate the constant until |cur_tok| is not a suitable digit. */
- while (1) {
- if ((cur_tok < zero_token + radix) && (cur_tok >= zero_token) && (cur_tok <= nine_token)) {
- d = cur_tok - zero_token;
- } else if (radix == 16) {
- if ((cur_tok <= A_token + 5) && (cur_tok >= A_token)) {
- d = cur_tok - A_token + 10;
- } else if ((cur_tok <= other_A_token + 5) && (cur_tok >= other_A_token)) {
- d = cur_tok - other_A_token + 10;
- } else {
- break;
- }
- } else {
- break;
- }
- vacuous = false;
- if ((cur_val >= m) && ((cur_val > m) || (d > 7) || (radix != 10))) {
- if (OK_so_far) {
- print_err("Number too big");
- help2(
- "I can only go up to 2147483647='17777777777=\"7FFFFFFF,",
- "so I'm using that number instead of yours."
- );
- error();
- cur_val = infinity;
- OK_so_far = false;
- }
- } else {
- cur_val = cur_val * radix + d;
- }
- get_x_token();
- }
- if (vacuous) {
- /*tex Express astonishment that no number was here */
- print_err("Missing number, treated as zero");
- help3(
- "A number should have been here; I inserted `0'.",
- "(If you can't figure out why I needed to see a number,",
- "look up `weird error' in the index to The TeXbook.)"
- );
- back_error();
- } else if (cur_cmd != spacer_cmd) {
- back_input();
- }
- }
- if (negative)
- negate(cur_val);
-}
-
-/*tex
-
- The following code is executed when |scan_something_internal| was called
- asking for |mu_val|, when we really wanted a ``mudimen'' instead of
- ``muglue.''
-
-*/
-
-static void coerce_glue(void)
-{
- int v;
- if (cur_val_level >= glue_val_level) {
- v = width(cur_val);
- flush_node(cur_val);
- cur_val = v;
- }
-}
-
-/*tex
-
- The |scan_dimen| routine is similar to |scan_int|, but it sets |cur_val| to a
- |scaled| value, i.e., an integral number of sp. One of its main tasks is
- therefore to interpret the abbreviations for various kinds of units and to
- convert measurements to scaled points.
-
- There are three parameters: |mu| is |true| if the finite units must be
- `\.{mu}', while |mu| is |false| if `\.{mu}' units are disallowed; |inf| is
- |true| if the infinite units `\.{fil}', `\.{fill}', `\.{filll}' are
- permitted; and |shortcut| is |true| if |cur_val| already contains an integer
- and only the units need to be considered.
-
- The order of infinity that was found in the case of infinite glue is returned
- in the global variable |cur_order|.
-
-*/
-
-/*tex The order of infinity found by |scan_dimen|: */
-
-int cur_order;
-
-/*tex
-
- Constructions like `\.{-\'77 pt}' are legal dimensions, so |scan_dimen| may
- begin with |scan_int|. This explains why it is convenient to use |scan_int|
- also for the integer part of a decimal fraction.
-
- Several branches of |scan_dimen| work with |cur_val| as an integer and with
- an auxiliary fraction |f|, so that the actual quantity of interest is
- $|cur_val|+|f|/2^{16}$. At the end of the routine, this ``unpacked''
- representation is put into the single word |cur_val|, which suddenly switches
- significance from |integer| to |scaled|.
-
- The necessary conversion factors can all be specified exactly as fractions
- whose numerator and denominator add to 32768 or less. According to the
- definitions here, $\rm2660\,dd\approx1000.33297\,mm$; this agrees well with
- the value $\rm1000.333\,mm$ cited by Bosshard \^{Bosshard, Hans Rudolf} in
- {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980). The Didot
- point has been newly standardized in 1978; it's now exactly $\rm
- 1\,nd=0.375\,mm$. Conversion uses the equation
- $0.375=21681/20320/72.27\cdot25.4$. The new Cicero follows the new Didot
- point; $\rm 1\,nc=12\,nd$. These would lead to the ratios $21681/20320$ and
- $65043/5080$, respectively. The closest approximations supported by the
- algorithm would be $11183/10481$ and $1370/107$. In order to maintain the
- relation $\rm 1\,nc=12\,nd$, we pick the ratio $685/642$ for $\rm nd$,
- however.
-
-*/
-
-static void scan_dimen_mu_error(void) {
- print_err("Illegal unit of measure (mu inserted)");
- help4(
- "The unit of measurement in math glue must be mu.",
- "To recover gracefully from this error, it's best to",
- "delete the erroneous units; e.g., type `2' to delete",
- "two letters. (See Chapter 27 of The TeXbook.)"
- );
- error();
-}
-
-static void scan_dimen_unknown_unit_error(void) {
- print_err("Illegal unit of measure (pt inserted)");
- help6(
- "Dimensions can be in units of em, ex, in, pt, pc,",
- "cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!",
- "I'll assume that you meant to say pt, for printer's points.",
- "To recover gracefully from this error, it's best to",
- "delete the erroneous units; e.g., type `2' to delete",
- "two letters. (See Chapter 27 of The TeXbook.)"
- );
- error();
-}
-
-static void scan_dimen_out_of_range_error(void) {
- print_err("Dimension too large");
- help2(
- "I can't work with sizes bigger than about 19 feet.",
- "Continue and I'll use the largest value I can."
- );
- error();
-}
-
-#define set_conversion(A,B) do { num=(A); denom=(B); } while(0)
-
-/*tex
-
- This function sets |cur_val| to a dimension. It could be optimized a bit more
- (but not now, something for luatex > 1).
-
-*/
-
-void scan_dimen(boolean mu, boolean inf, boolean shortcut)
-{
- /*tex should the answer be negated? */
- boolean negative = false;
- boolean is_true = false;
- /*tex numerator of a fraction whose denominator is $2^{16}$ */
- int f = 0;
- /*tex conversion ratio for the scanned units */
- int num = 0;
- int denom = 0;
- /*tex top of decimal digit stack */
- halfword q;
- /*tex an internal dimension */
- scaled v;
- /*tex temporary storage of |cur_val| */
- int save_cur_val;
- arith_error = false;
- cur_order = normal;
- if (!shortcut) {
- /*tex Get the next non-blank non-sign. */
- do {
- /*tex Get the next non-blank non-call token. */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok == minus_token) {
- negative = !negative;
- cur_tok = plus_token;
- }
- } while (cur_tok == plus_token);
- if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
- /*tex Fetch an internal dimension and |goto attach_sign|, or fetch an internal integer. */
- if (mu) {
- scan_something_internal(mu_val_level, false);
- coerce_glue();
- if (cur_val_level == mu_val_level) {
- goto ATTACH_SIGN;
- } else if (cur_val_level != int_val_level) {
- mu_error();
- }
- } else {
- scan_something_internal(dimen_val_level, false);
- if (cur_val_level == dimen_val_level) {
- goto ATTACH_SIGN;
- }
- }
- } else {
- back_input();
- if (cur_tok == continental_point_token) {
- cur_tok = point_token;
- }
- if (cur_tok != point_token) {
- scan_int();
- } else {
- radix = 10;
- cur_val = 0;
- }
- if (cur_tok == continental_point_token) {
- cur_tok = point_token;
- }
- if ((radix == 10) && (cur_tok == point_token)) {
- /*tex
-
- Scan decimal fraction. When the following code is executed,
- we have |cur_tok=point_token|, but this token has been backed
- up using |back_input|; we must first discard it. It turns out
- that a decimal point all by itself is equivalent to
- `\.{0.0}'. Let's hope people don't use that fact.
-
- */
- int k = 0;
- halfword p = null;
- int kk;
- /*tex The |point_token| is being re-scanned. */
- get_token();
- while (1) {
- get_x_token();
- if ((cur_tok > nine_token) || (cur_tok < zero_token))
- break;
- if (k < 17) {
- /*tex Digits for |k>=17| cannot affect the result. */
- q = get_avail();
- set_token_link(q, p);
- set_token_info(q, cur_tok - zero_token);
- p = q;
- incr(k);
- }
- }
- for (kk = k; kk >= 1; kk--) {
- dig[kk - 1] = token_info(p);
- q = p;
- p = token_link(p);
- free_avail(q);
- }
- f = round_decimals(k);
- if (cur_cmd != spacer_cmd) {
- back_input();
- }
- }
- }
- }
- if (cur_val < 0) {
- /*tex In this case |f=0|. */
- negative = !negative;
- negate(cur_val);
- }
- /*tex
-
- Scan units and set |cur_val| to $x\cdot(|cur_val|+f/2^{16})$, where there
- are |x| sp per unit; |goto attach_sign| if the units are internal. Now
- comes the harder part: At this point in the program, |cur_val| is a
- nonnegative integer and $f/2^{16}$ is a nonnegative fraction less than 1;
- we want to multiply the sum of these two quantities by the appropriate
- factor, based on the specified units, in order to produce a |scaled|
- result, and we want to do the calculation with fixed point arithmetic
- that does not overflow.
-
- */
- if (inf) {
- if (scan_keyword("fi")) {
- cur_order = sfi;
- if (scan_keyword("l")) {
- cur_order = fil;
- if (scan_keyword("l")) {
- cur_order = fill;
- if (scan_keyword("l")) {
- cur_order = filll;
- }
- }
- }
- goto ATTACH_FRACTION;
- }
- }
- /*tex
-
- Scan for (u)units that are internal dimensions; |goto attach_sign| with
- |cur_val| set if found.
-
- */
- save_cur_val = cur_val;
- /*tex
-
- Get the next non-blank non-call; a pitty if just backed up the input.
-
- */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
-
- if ((cur_cmd < min_internal_cmd) || (cur_cmd > max_internal_cmd)) {
- back_input();
- } else {
- /*tex |math_given_cmd|, |xmath_given_cmd| and |last_item_cmd} */
- if (mu) {
- scan_something_internal(mu_val_level, false);
- coerce_glue();
- if (cur_val_level != mu_val_level) {
- mu_error();
- }
- } else {
- scan_something_internal(dimen_val_level, false);
- }
- v = cur_val;
- goto FOUND;
- }
- /*tex Bah |true| forces to split the unit scanner. */
- if (mu) {
- /*tex Scan for (m)\.{mu} units and |goto attach_fraction|. */
- if (! scan_keyword("mu")) {
- scan_dimen_mu_error();
- }
- goto ATTACH_FRACTION;
- } else if (scan_keyword("em")) {
- v = quad(get_cur_font());
- } else if (scan_keyword("ex")) {
- v = x_height(get_cur_font());
- } else if (scan_keyword("px")) {
- v = px_dimen_par;
- } else {
- goto PICKUP_UNIT;
- }
- /*tex Scan an optional space (after em, ex or px) */
- get_x_token();
- if (cur_cmd != spacer_cmd) {
- back_input();
- }
- FOUND:
- cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000));
- goto ATTACH_SIGN;
- /*tex
-
- Scan for (a)all other units and adjust |cur_val| and |f| accordingly;
- |goto done| in the case of scaled points.
-
- */
- PICKUP_UNIT:
- if (scan_keyword("pt")) {
- /*tex The easy case: */
- goto SCALE_VALUE;
- } else if (scan_keyword("mm")) {
- set_conversion(7227, 2540);
- goto SCALE_VALUE;
- } else if (scan_keyword("cm")) {
- set_conversion(7227, 254);
- goto SCALE_VALUE;
- } else if (scan_keyword("sp")) {
- goto DONE;
- } else if (scan_keyword("bp")) {
- set_conversion(7227, 7200);
- goto SCALE_VALUE;
- } else if (scan_keyword("in")) {
- set_conversion(7227, 100);
- goto SCALE_VALUE;
- } else if (scan_keyword("dd")) {
- set_conversion(1238, 1157);
- goto SCALE_VALUE;
- } else if (scan_keyword("cc")) {
- set_conversion(14856, 1157);
- goto SCALE_VALUE;
- } else if (scan_keyword("pc")) {
- set_conversion(12, 1);
- goto SCALE_VALUE;
- } else if (scan_keyword("nd")) {
- set_conversion(685, 642);
- goto SCALE_VALUE;
- } else if (scan_keyword("nc")) {
- set_conversion(1370, 107);
- goto SCALE_VALUE;
- } else if (!is_true && scan_keyword("true")) {
- is_true = true;
- goto PICKUP_UNIT;
- }
- /*tex Complain about unknown unit and |goto done2|. */
- scan_dimen_unknown_unit_error();
- goto BAD_NEWS;
- SCALE_VALUE:
- /*tex Adjust |f| for the magnification ratio. */
- if (is_true) {
- /*tex Maybe at some point we will drop mag completely, even in \DVI\ mode. */
- if (output_mode_used <= OMODE_DVI) {
- prepare_mag();
- if (mag_par != 1000) {
- cur_val = xn_over_d(cur_val, 1000, mag_par);
- f = (1000 * f + 0200000 * tex_remainder) / mag_par;
- cur_val = cur_val + (f / 0200000);
- f = f % 0200000;
- }
- } else {
- /*tex in \PDF\ mode we're always |true|. */
- one_true_inch = one_inch;
- }
- }
- if (num) {
- cur_val = xn_over_d(cur_val, num, denom);
- f = (num * f + 0200000 * tex_remainder) / denom;
- cur_val = cur_val + (f / 0200000);
- f = f % 0200000;
- }
- BAD_NEWS:
- ATTACH_FRACTION:
- if (cur_val >= 040000) {
- arith_error = true;
- } else {
- cur_val = cur_val * unity + f;
- }
- DONE:
- /*tex Scan an optional space; this happens too often. */
- get_x_token();
- if (cur_cmd != spacer_cmd) {
- back_input();
- }
- ATTACH_SIGN:
- if (arith_error || (abs(cur_val) >= 010000000000)) {
- /*tex Report that this dimension is out of range. */
- scan_dimen_out_of_range_error();
- cur_val = max_dimen;
- arith_error = false;
- }
- if (negative) {
- negate(cur_val);
- }
-}
-
-/*tex
-
- The final member of \TeX's value-scanning trio is |scan_glue|, which makes
- |cur_val| point to a glue specification. The reference count of that glue
- spec will take account of the fact that |cur_val| is pointing to~it.
-
- The |level| parameter should be either |glue_val| or |mu_val|.
-
- Since |scan_dimen| was so much more complex than |scan_int|, we might expect
- |scan_glue| to be even worse. But fortunately, it is very simple, since most
- of the work has already been done.
-
-*/
-
-void scan_glue(int level)
-{
- /*tex should the answer be negated? */
- boolean negative = false;
- /*tex new glue specification */
- halfword q = null;
- /*tex does |level=mu_val|? */
- boolean mu = (level == mu_val_level);
- /*tex Get the next non-blank non-sign. */
- do {
- /*tex Get the next non-blank non-call token. */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_tok == minus_token) {
- negative = !negative;
- cur_tok = plus_token;
- }
- } while (cur_tok == plus_token);
- if ((cur_cmd >= min_internal_cmd) && (cur_cmd <= max_internal_cmd)) {
- scan_something_internal(level, negative);
- if (cur_val_level >= glue_val_level) {
- if (cur_val_level != level)
- mu_error();
- return;
- }
- if (cur_val_level == int_val_level)
- scan_dimen(mu, false, true);
- else if (level == mu_val_level)
- mu_error();
- } else {
- back_input();
- scan_dimen(mu, false, false);
- if (negative)
- negate(cur_val);
- }
- /*tex
-
- Create a new glue specification whose width is |cur_val|; scan for its
- stretch and shrink components.
-
- */
- q = new_spec(zero_glue);
- width(q) = cur_val;
- if (scan_keyword("plus")) {
- scan_dimen(mu, true, false);
- stretch(q) = cur_val;
- stretch_order(q) = (quarterword) cur_order;
- }
- if (scan_keyword("minus")) {
- scan_dimen(mu, true, false);
- shrink(q) = cur_val;
- shrink_order(q) = (quarterword) cur_order;
- }
- cur_val = q;
-}
-
-/*tex
-
- This procedure is supposed to scan something like `\.{\\skip\\count12}',
- i.e., whatever can follow `\.{\\the}', and it constructs a token list
- containing something like `\.{-3.0pt minus 0.5fill}'.
-
-*/
-
-halfword the_toks(void)
-{
- /*tex holds |selector| setting */
- int old_setting;
- /*tex used for copying a token list */
- halfword p, q, r;
- /*tex value of |cur_chr| */
- int c;
- str_number s;
- halfword retval;
- /*tex Handle \.{\\unexpanded} or \.{\\detokenize} and |return|. */
- if (odd(cur_chr)) {
- c = cur_chr;
- scan_general_text();
- if (c == 1) {
- return cur_val;
- } else {
- old_setting = selector;
- selector = new_string;
- p = get_avail();
- set_token_link(p, token_link(temp_token_head));
- token_show(p);
- flush_list(p);
- selector = old_setting;
- s = make_string();
- retval = str_toks(str_lstring(s));
- flush_str(s);
- return retval;
- }
- }
- get_x_token();
- scan_something_internal(tok_val_level, false);
- if (cur_val_level >= ident_val_level) {
- /*tex Copy the token list */
- p = temp_token_head;
- set_token_link(p, null);
- if (cur_val_level == ident_val_level) {
- store_new_token(cs_token_flag + cur_val);
- } else if (cur_val != null) {
- /*tex Do not copy the reference count! */
- r = token_link(cur_val);
- while (r != null) {
- fast_store_new_token(token_info(r));
- r = token_link(r);
- }
- }
- return p;
- } else {
- old_setting = selector;
- selector = new_string;
- switch (cur_val_level) {
- case int_val_level:
- print_int(cur_val);
- break;
- case attr_val_level:
- print_int(cur_val);
- break;
- case dir_val_level:
- print_dir_par(cur_val);
- break;
- case dimen_val_level:
- print_scaled(cur_val);
- tprint("pt");
- break;
- case glue_val_level:
- print_spec(cur_val, "pt");
- flush_node(cur_val);
- break;
- case mu_val_level:
- print_spec(cur_val, "mu");
- flush_node(cur_val);
- break;
- }
- selector = old_setting;
- s = make_string();
- retval = str_toks(str_lstring(s));
- flush_str(s);
- return retval;
- }
-}
-
-str_number the_scanned_result(void)
-{
- /*tex holds |selector| setting */
- int old_setting;
- /*tex return value */
- str_number r;
- old_setting = selector;
- selector = new_string;
- if (cur_val_level >= ident_val_level) {
- if (cur_val != null) {
- show_token_list(token_link(cur_val), null, -1);
- r = make_string();
- } else {
- r = get_nullstr();
- }
- } else {
- switch (cur_val_level) {
- case int_val_level:
- print_int(cur_val);
- break;
- case attr_val_level:
- print_int(cur_val);
- break;
- case dir_val_level:
- print_dir_par(cur_val);
- break;
- case dimen_val_level:
- print_scaled(cur_val);
- tprint("pt");
- break;
- case glue_val_level:
- print_spec(cur_val, "pt");
- flush_node(cur_val);
- break;
- case mu_val_level:
- print_spec(cur_val, "mu");
- flush_node(cur_val);
- break;
- }
- r = make_string();
- }
- selector = old_setting;
- return r;
-}
-
-/*tex
-
- The following routine is used to implement `\.{\\fontdimen} |n| |f|'. The
- boolean parameter |writing| is set |true| if the calling program intends to
- change the parameter value.
-
-*/
-
-static void font_param_error(int f)
-{
- print_err("Font ");
- print_esc(font_id_text(f));
- tprint(" has only ");
- print_int(font_params(f));
- tprint(" fontdimen parameters");
- help2(
- "To increase the number of font parameters, you must",
- "use \\fontdimen immediately after the \\font is loaded."
- );
- error();
-}
-
-void set_font_dimen(void)
-{
- internal_font_number f;
- int n;
- scan_int();
- n = cur_val;
- scan_font_ident();
- f = cur_val;
- if (n <= 0) {
- font_param_error(f);
- } else if (n > font_params(f)) {
- if (font_used(f)) {
- font_param_error(f);
- } else {
- /*tex Increase the number of parameters in the font. */
- do {
- set_font_param(f, (font_params(f) + 1), 0);
- } while (n != font_params(f));
- }
- }
- scan_optional_equals();
- scan_normal_dimen();
- set_font_param(f, n, cur_val);
-}
-
-void get_font_dimen(void)
-{
- internal_font_number f;
- /*tex The parameter number: */
- int n;
- scan_int();
- n = cur_val;
- scan_font_ident();
- f = cur_val;
- /*tex Initialize return value: */
- cur_val = 0;
- if (n <= 0) {
- font_param_error(f);
- goto EXIT;
- } else if (n > font_params(f)) {
- if (font_used(f)) {
- font_param_error(f);
- goto EXIT;
- } else {
- /*tex Increase the number of parameters in the font. */
- do {
- set_font_param(f, (font_params(f) + 1), 0);
- } while (n != font_params(f));
- }
- }
- cur_val = font_param(f, n);
- EXIT:
- scanned_result(cur_val, dimen_val_level);
-}
-
-/*tex
-
- Here's a similar procedure that returns a pointer to a rule node. This
- routine is called just after \TeX\ has seen \.{\\hrule} or \.{\\vrule};
- therefore |cur_cmd| will be either |hrule| or |vrule|. The idea is to store
- the default rule dimensions in the node, then to override them if
- `\.{height}' or `\.{width}' or `\.{depth}' specifications are found (in any
- order).
-
-*/
-
-halfword scan_rule_spec(void)
-{
- /*tex |width|, |depth|, and |height| all equal |null_flag| now */
- halfword q;
- if (cur_cmd == no_vrule_cmd) {
- q = new_rule(empty_rule);
- cur_cmd = vrule_cmd;
- } else if (cur_cmd == no_hrule_cmd) {
- q = new_rule(empty_rule);
- cur_cmd = hrule_cmd;
- } else {
- q = new_rule(normal_rule);
- }
- if (cur_cmd == vrule_cmd) {
- width(q) = default_rule;
- rule_dir(q) = body_direction_par;
- } else {
- height(q) = default_rule;
- depth(q) = 0;
- rule_dir(q) = text_direction_par;
- }
- RESWITCH:
- if (scan_keyword("width")) {
- scan_normal_dimen();
- width(q) = cur_val;
- goto RESWITCH;
- }
- if (scan_keyword("height")) {
- scan_normal_dimen();
- height(q) = cur_val;
- goto RESWITCH;
- }
- if (scan_keyword("depth")) {
- scan_normal_dimen();
- depth(q) = cur_val;
- goto RESWITCH;
- }
- return q;
-}
-
-/*tex Declare procedures that scan font-related stuff. */
-
-void scan_font_ident(void)
-{
- internal_font_number f;
- halfword m;
- /*tex Get the next non-blank non-call. */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if ((cur_cmd == def_font_cmd) || (cur_cmd == letterspace_font_cmd) || (cur_cmd == copy_font_cmd)) {
- f = get_cur_font();
- } else if (cur_cmd == set_font_cmd) {
- f = cur_chr;
- set_font_touched(f, 1);
- } else if (cur_cmd == def_family_cmd) {
- m = cur_chr;
- scan_math_family_int();
- f = fam_fnt(cur_val, m);
- set_font_touched(f, 1);
- } else {
- print_err("Missing font identifier");
- help2(
- "I was looking for a control sequence whose",
- "current meaning has been defined by \\font."
- );
- back_error();
- f = null_font;
- }
- cur_val = f;
-}
-
-/*tex
-
- The |scan_general_text| procedure is much like |scan_toks(false,false)|, but
- will be invoked via |expand|, i.e., recursively.
-
- The token list (balanced text) created by |scan_general_text| begins at
- |link(temp_token_head)| and ends at |cur_val|. (If |cur_val=temp_token_head|,
- the list is empty.)
-
-*/
-
-void scan_general_text(void)
-{
- /*tex Here we save |scanner_status|: */
- int s;
- /*tex Here we save |warning_index|: */
- halfword w;
- /*tex Here we save |def_ref|: */
- halfword d;
- /*tex The tail of the token list being built: */
- halfword p;
- /*tex The new node being added to the token list via |store_new_token|: */
- halfword q;
- /*tex The number of unmatched left braces: */
- halfword unbalance;
- s = scanner_status;
- w = warning_index;
- d = def_ref;
- scanner_status = absorbing;
- warning_index = cur_cs;
- p = get_avail();
- def_ref = p;
- set_token_ref_count(def_ref, 0);
- p = def_ref;
- /*tex Remove the compulsory left brace. */
- scan_left_brace();
- unbalance = 1;
- while (1) {
- get_token();
- if (cur_tok < right_brace_limit) {
- if (cur_cmd < right_brace_cmd) {
- incr(unbalance);
- } else {
- decr(unbalance);
- if (unbalance == 0)
- break;
- }
- }
- store_new_token(cur_tok);
- }
- q = token_link(def_ref);
- /*tex Discard reference count. */
- free_avail(def_ref);
- if (q == null)
- cur_val = temp_token_head;
- else
- cur_val = p;
- set_token_link(temp_token_head, q);
- scanner_status = s;
- warning_index = w;
- def_ref = d;
-}
-
-/*tex
-
- The |get_x_or_protected| procedure is like |get_x_token| except that
- protected macros are not expanded. It sets |cur_cmd|, |cur_chr|,
- |cur_tok|,and expands non-protected macros.
-
-*/
-
-void get_x_or_protected(void)
-{
-
- while (1) {
- get_token();
- if (cur_cmd <= max_command_cmd)
- return;
- if ((cur_cmd >= call_cmd) && (cur_cmd < end_template_cmd)) {
- if (token_info(token_link(cur_chr)) == protected_token)
- return;
- }
- expand();
- }
-}
-
-/*tex
-
- |scan_toks|. This function returns a pointer to the tail of a new token list,
- and it also makes |def_ref| point to the reference count at the head of that
- list.
-
- There are two boolean parameters, |macro_def| and |xpand|. If |macro_def| is
- true, the goal is to create the token list for a macro definition; otherwise
- the goal is to create the token list for some other \TeX\ primitive:
- \.{\\mark}, \.{\\output}, \.{\\everypar}, \.{\\lowercase}, \.{\\uppercase},
- \.{\\message}, \.{\\errmessage}, \.{\\write}, or \.{\\special}. In the latter
- cases a left brace must be scanned next; this left brace will not be part of
- the token list, nor will the matching right brace that comes at the end. If
- |xpand| is false, the token list will simply be copied from the input using
- |get_token|. Otherwise all expandable tokens will be expanded until
- unexpandable tokens are left, except that the results of expanding
- `\.{\\the}' are not expanded further. If both |macro_def| and |xpand| are
- true, the expansion applies only to the macro body (i.e., to the material
- following the first |left_brace| character).
-
- The value of |cur_cs| when |scan_toks| begins should be the |eqtb| address of
- the control sequence to display in ``runaway'' error messages.
-
-*/
-
-halfword scan_toks(boolean macro_def, boolean xpand)
-{
- /*tex token representing the highest parameter number */
- halfword t;
- /*tex saved token */
- halfword s;
- /*tex tail of the token list being built */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex number of unmatched left braces */
- halfword unbalance;
- /*tex possible `\.{\#\{}' token */
- halfword hash_brace;
- if (macro_def)
- scanner_status = defining;
- else
- scanner_status = absorbing;
- warning_index = cur_cs;
- p = get_avail();
- def_ref = p;
- set_token_ref_count(def_ref, 0);
- p = def_ref;
- hash_brace = 0;
- t = zero_token;
- if (macro_def) {
- /*tex Scan and build the parameter part of the macro definition. */
- while (1) {
- /*tex Set |cur_cmd|, |cur_chr|, |cur_tok|: */
- get_token();
- if (cur_tok < right_brace_limit)
- break;
- if (cur_cmd == mac_param_cmd) {
- /*tex
-
- If the next character is a parameter number, make
- |cur_tok| a |match| token; but if it is a left brace,
- store `|left_brace|, |end_match|', set |hash_brace|, and
- |goto done|.
-
- */
- s = match_token + cur_chr;
- get_token();
- /* if (cur_cmd == left_brace_cmd) { */
- if (cur_tok < left_brace_limit) {
- hash_brace = cur_tok;
- store_new_token(cur_tok);
- store_new_token(end_match_token);
- goto DONE;
- }
- if (t == nine_token) {
- print_err("You already have nine parameters");
- help2(
- "I'm going to ignore the # sign you just used,",
- "as well as the token that followed it."
- );
- error();
- } else {
- incr(t);
- if (cur_tok != t) {
- print_err("Parameters must be numbered consecutively");
- help2(
- "I've inserted the digit you should have used after the #.",
- "Type `1' to delete what you did use."
- );
- back_error();
- }
- cur_tok = s;
- }
- }
- store_new_token(cur_tok);
- }
- store_new_token(end_match_token);
- if (cur_cmd == right_brace_cmd) {
- /*tex Express shock at the missing left brace; |goto found|. */
- print_err("Missing { inserted");
- incr(align_state);
- help2(
- "Where was the left brace? You said something like `\\def\\a}',",
- "which I'm going to interpret as `\\def\\a{}'."
- );
- error();
- goto FOUND;
- }
-
- } else {
- /*tex Remove the compulsory left brace. */
- scan_left_brace();
- }
- DONE:
- /*tex Scan and build the body of the token list; |goto found| when finished. */
- unbalance = 1;
- while (1) {
- if (xpand) {
- /*tex
-
- Expand the next part of the input. Here we insert an entire token
- list created by |the_toks| without expanding it further.
-
- */
- while (1) {
- get_next();
- if (cur_cmd >= call_cmd) {
- if (token_info(token_link(cur_chr)) == protected_token) {
- cur_cmd = relax_cmd;
- cur_chr = no_expand_flag;
- }
- }
- if (cur_cmd <= max_command_cmd)
- break;
- if (cur_cmd != the_cmd) {
- expand();
- } else {
- q = the_toks();
- if (token_link(temp_token_head) != null) {
- set_token_link(p, token_link(temp_token_head));
- p = q;
- }
- }
- }
- x_token();
- } else {
- get_token();
- }
- if (cur_tok < right_brace_limit) {
- if (cur_cmd < right_brace_cmd) {
- incr(unbalance);
- } else {
- decr(unbalance);
- if (unbalance == 0)
- goto FOUND;
- }
- } else if (cur_cmd == mac_param_cmd) {
- if (macro_def) {
- /*tex Look for parameter number or \.{\#\#}. */
- s = cur_tok;
- if (xpand)
- get_x_token();
- else
- get_token();
- if (cur_cmd != mac_param_cmd) {
- if ((cur_tok <= zero_token) || (cur_tok > t)) {
- print_err("Illegal parameter number in definition of ");
- sprint_cs(warning_index);
- help3(
- "You meant to type ## instead of #, right?",
- "Or maybe a } was forgotten somewhere earlier, and things",
- "are all screwed up? I'm going to assume that you meant ##."
- );
- back_error();
- cur_tok = s;
- } else {
- cur_tok = out_param_token - '0' + cur_chr;
- }
- }
- }
- }
- store_new_token(cur_tok);
- }
- FOUND:
- scanner_status = normal;
- if (hash_brace != 0)
- store_new_token(hash_brace);
- return p;
-}
-
-/*tex
-
- Here we declare two trivial procedures in order to avoid mutually recursive
- procedures with parameters.
-
-*/
-
-void scan_normal_glue(void)
-{
- scan_glue(glue_val_level);
-}
-
-void scan_mu_glue(void)
-{
- scan_glue(mu_val_level);
-}
-
-/*tex
-
- The |scan_expr| procedure scans and evaluates an expression. Evaluating an
- expression is a recursive process: When the left parenthesis of a
- subexpression is scanned we descend to the next level of recursion; the
- previous level is resumed with the matching right parenthesis.
-
-*/
-
-typedef enum {
- /*tex \.( seen, or \.( $\langle\it expr\rangle$ \.) seen */
- expr_none = 0,
- /*tex \.( $\langle\it expr\rangle$ \.+ seen */
- expr_add = 1,
- /*tex \.( $\langle\it expr\rangle$ \.- seen */
- expr_sub = 2,
- /*tex $\langle\it term\rangle$ \.* seen */
- expr_mult = 3,
- /*tex $\langle\it term\rangle$ \./ seen */
- expr_div = 4,
- /*tex $\langle\it term\rangle$ \.* $\langle\it factor\rangle$ \./ seen */
- expr_scale = 5,
-} expression_states;
-
-/*tex
-
- We want to make sure that each term and (intermediate) result is in the
- proper range. Integer values must not exceed |infinity| ($2^{31}-1$) in
- absolute value, dimensions must not exceed |max_dimen| ($2^{30}-1$). We avoid
- the absolute value of an integer, because this might fail for the value
- $-2^{31}$ using 32-bit arithmetic.
-
-*/
-
-/* Clear a number or dimension and set |arith_error|: */
-
-#define num_error(A) do { \
- arith_error=true; \
- A=0; \
-} while (0)
-
-/*tex Clear a glue spec and set |arith_error|: */
-
-#define glue_error(A) do { \
- arith_error=true; \
- reset_glue_to_zero(A); \
-} while (0)
-
-#define normalize_glue(A) do { \
- if (stretch(A)==0) stretch_order(A)=normal; \
- if (shrink(A)==0) shrink_order(A)=normal; \
-} while (0)
-
-/*tex
-
- Parenthesized subexpressions can be inside expressions, and this nesting has
- a stack. Seven local variables represent the top of the expression stack: |p|
- points to pushed-down entries, if any; |l| specifies the type of expression
- currently beeing evaluated; |e| is the expression so far and |r| is the state
- of its evaluation; |t| is the term so far and |s| is the state of its
- evaluation; finally |n| is the numerator for a combined multiplication and
- division, if any.
-
-*/
-
-#define expr_add_sub(A,B,C) add_or_sub((A),(B),(C),(r==expr_sub))
-#define expr_a(A,B) expr_add_sub((A),(B),max_dimen)
-
-/*tex
-
- The function |add_or_sub(x,y,max_answer,negative)| computes the sum (for
- |negative=false|) or difference (for |negative=true|) of |x| and |y|,
- provided the absolute value of the result does not exceed |max_answer|.
-
-*/
-
-inline static int add_or_sub(int x, int y, int max_answer, boolean negative)
-{
- int a;
- if (negative)
- negate(y);
- if (x >= 0) {
- if (y <= max_answer - x)
- a = x + y;
- else
- num_error(a);
- } else if (y >= -max_answer - x) {
- a = x + y;
- } else {
- num_error(a);
- }
- return a;
-}
-
-#define expr_m(A) A = nx_plus_y((A),f,0)
-#define expr_d(A) A=quotient((A),f)
-
-/*tex
-
- The function |quotient(n,d)| computes the rounded quotient $q=\lfloor
- n/d+{1\over2}\rfloor$, when $n$ and $d$ are positive.
-
-*/
-
-inline static int quotient(int n, int d)
-{
- /*tex Should the answer be negated? */
- boolean negative;
- /*tex The answer: */
- int a;
- if (d == 0) {
- num_error(a);
- } else {
- if (d > 0) {
- negative = false;
- } else {
- negate(d);
- negative = true;
- }
- if (n < 0) {
- negate(n);
- negative = !negative;
- }
- a = n / d;
- n = n - a * d;
- /*tex Avoid certain compiler optimizations! */
- d = n - d;
- if (d + n >= 0)
- incr(a);
- if (negative)
- negate(a);
- }
- return a;
-}
-
-#define expr_s(A) A=fract((A),n,f,max_dimen)
-
-/*tex
-
- Finally, the function |fract(x,n,d,max_answer)| computes the integer
- $q=\lfloor xn/d+{1\over2}\rfloor$, when $x$, $n$, and $d$ are positive and
- the result does not exceed |max_answer|. We can't use floating point
- arithmetic since the routine must produce identical results in all cases; and
- it would be too dangerous to multiply by~|n| and then divide by~|d|, in
- separate operations, since overflow might well occur. Hence this subroutine
- simulates double precision arithmetic, somewhat analogous to Metafont's
- |make_fraction| and |take_fraction| routines.
-
-*/
-
-int fract(int x, int n, int d, int max_answer)
-{
- /*tex should the answer be negated? */
- boolean negative;
- /*tex the answer */
- int a;
- /*tex a proper fraction */
- int f;
- /*tex smallest integer such that |2*h>=d| */
- int h;
- /*tex intermediate remainder */
- int r;
- /*tex temp variable */
- int t;
- if (d == 0)
- goto TOO_BIG;
- a = 0;
- if (d > 0) {
- negative = false;
- } else {
- negate(d);
- negative = true;
- }
- if (x < 0) {
- negate(x);
- negative = !negative;
- } else if (x == 0) {
- goto DONE;
- }
- if (n < 0) {
- negate(n);
- negative = !negative;
- }
- t = n / d;
- if (t > max_answer / x)
- goto TOO_BIG;
- a = t * x;
- n = n - t * d;
- if (n == 0)
- goto FOUND;
- t = x / d;
- if (t > (max_answer - a) / n)
- goto TOO_BIG;
- a = a + t * n;
- x = x - t * d;
- if (x == 0)
- goto FOUND;
- if (x < n) {
- t = x;
- x = n;
- n = t;
- }
- /*tex
-
- Now |0<n<=x<d| and we compute $f=\lfloor xn/d+{1\over2}\rfloor$. The loop
- here preserves the following invariant relations between |f|, |x|, |n|,
- and~|r|: (i)~$f+\lfloor(xn+(r+d))/d\rfloor=\lfloor
- x_0n_0/d+{1\over2}\rfloor$; (ii)~|-d<=r<0<n<=x<d|, where $x_0$, $n_0$ are
- the original values of~$x$ and $n$.
-
- Notice that the computation specifies |(x-d)+x| instead of |(x+x)-d|,
- because the latter could overflow.
-
- */
- f = 0;
- r = (d / 2) - d;
- h = -r;
- while (1) {
- if (odd(n)) {
- r = r + x;
- if (r >= 0) {
- r = r - d;
- incr(f);
- }
- }
- n = n / 2;
- if (n == 0)
- break;
- if (x < h) {
- x = x + x;
- } else {
- t = x - d;
- x = t + x;
- f = f + n;
- if (x < n) {
- if (x == 0)
- break;
- t = x;
- x = n;
- n = t;
- }
- }
- }
- if (f > (max_answer - a))
- goto TOO_BIG;
- a = a + f;
- FOUND:
- if (negative)
- negate(a);
- goto DONE;
- TOO_BIG:
- num_error(a);
- DONE:
- return a;
-}
-
-/*tex Scans and evaluates an expression: */
-
-static void scan_expr(void)
-{
- /*tex saved values of |arith_error| */
- boolean a, b;
- /*tex type of expression */
- int l;
- /*tex state of expression so far */
- int r;
- /*tex state of term so far */
- int s;
- /*tex next operation or type of next factor */
- int o;
- /*tex expression so far */
- int e;
- /*tex term so far */
- int t;
- /*tex current factor */
- int f;
- /*tex numerator of combined multiplication and division */
- int n;
- /*tex top of expression stack */
- halfword p;
- /*tex for stack manipulations */
- halfword q;
- l = cur_val_level;
- a = arith_error;
- b = false;
- p = null;
- /*tex Scan and evaluate an expression |e| of type |l|. */
- RESTART:
- r = expr_none;
- e = 0;
- s = expr_none;
- t = 0;
- n = 0;
- CONTINUE:
- if (s == expr_none)
- o = l;
- else
- o = int_val_level;
- /*tex
-
- Scan a factor |f| of type |o| or start a subexpression. Get the next
- non-blank non-call token.
-
- */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
-
- if (cur_tok == other_token + '(') {
- /*tex Push the expression stack and |goto restart|. */
- q = new_node(expr_node, 0);
- vlink(q) = p;
- expr_type(q) = (quarterword) l;
- expr_state(q) = (quarterword) (4 * s + r);
- expr_e_field(q) = e;
- expr_t_field(q) = t;
- expr_n_field(q) = n;
- p = q;
- l = o;
- goto RESTART;
- }
- back_input();
- if ((o == int_val_level) || (o == attr_val_level))
- scan_int();
- else if (o == dimen_val_level)
- scan_normal_dimen();
- else if (o == glue_val_level)
- scan_normal_glue();
- else
- scan_mu_glue();
- f = cur_val;
-
- FOUND:
- /*tex
-
- Scan the next operator and set |o| and Get the next non-blank non-call
- token.
-
- */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
-
- if (cur_tok == other_token + '+') {
- o = expr_add;
- } else if (cur_tok == other_token + '-') {
- o = expr_sub;
- } else if (cur_tok == other_token + '*') {
- o = expr_mult;
- } else if (cur_tok == other_token + '/') {
- o = expr_div;
- } else {
- o = expr_none;
- if (p == null) {
- if (cur_cmd != relax_cmd)
- back_input();
- } else if (cur_tok != other_token + ')') {
- print_err("Missing ) inserted for expression");
- help1("I was expecting to see `+', `-', `*', `/', or `)'. Didn't.");
- back_error();
- }
- }
- arith_error = b;
- /*tex Make sure that |f| is in the proper range. */
- if (((l == int_val_level) || (l == attr_val_level)) || (s > expr_sub)) {
- if ((f > infinity) || (f < -infinity))
- num_error(f);
- } else if (l == dimen_val_level) {
- if (abs(f) > max_dimen)
- num_error(f);
- } else {
- if ((abs(width(f)) > max_dimen) || (abs(stretch(f)) > max_dimen) || (abs(shrink(f)) > max_dimen))
- glue_error(f);
- }
- /*tex Cases for evaluation of the current term. */
- switch (s) {
- case expr_none:
- /*tex
-
- Applying the factor |f| to the partial term |t| (with the
- operator |s|) is delayed until the next operator |o| has been
- scanned. Here we handle the first factor of a partial term. A
- glue spec has to be copied unless the next operator is a right
- parenthesis; this allows us later on to simply modify the glue
- components.
-
- */
- t = f;
- if ((l >= glue_val_level) && (o != expr_none)) {
- /*tex Do we really need to copy here? */
- normalize_glue(t);
- } else {
- t = f;
- }
- break;
- case expr_mult:
- /*tex
-
- If a multiplication is followed by a division, the two operations
- are combined into a `scaling' operation. Otherwise the term |t|
- is multiplied by the factor |f|.
-
- */
- if (o == expr_div) {
- n = f;
- o = expr_scale;
- } else if ((l == int_val_level) || (l == attr_val_level)) {
- t = mult_integers(t, f);
- } else if (l == dimen_val_level) {
- expr_m(t);
- } else {
- expr_m(width(t));
- expr_m(stretch(t));
- expr_m(shrink(t));
- }
- break;
- case expr_div:
- /*tex Here we divide the term |t| by the factor |f|. */
- if (l < glue_val_level) {
- expr_d(t);
- } else {
- expr_d(width(t));
- expr_d(stretch(t));
- expr_d(shrink(t));
- }
- break;
- case expr_scale:
- /*tex Here the term |t| is multiplied by the quotient $n/f$. */
- if ((l == int_val_level) || (l == attr_val_level)) {
- t = fract(t, n, f, infinity);
- } else if (l == dimen_val_level) {
- expr_s(t);
- } else {
- expr_s(width(t));
- expr_s(stretch(t));
- expr_s(shrink(t));
- }
- break;
- }
- if (o > expr_sub) {
- s = o;
- } else {
- /*tex
-
- Evaluate the current expression. When a term |t| has been completed
- it is copied to, added to, or subtracted from the expression |e|.
-
- */
- s = expr_none;
- if (r == expr_none) {
- e = t;
- } else if ((l == int_val_level) || (l == attr_val_level)) {
- e = expr_add_sub(e, t, infinity);
- } else if (l == dimen_val_level) {
- e = expr_a(e, t);
- } else {
- /*tex
-
- Compute the sum or difference of two glue specs. We know that
- |stretch_order(e)>normal| implies |stretch(e)<>0| and
- |shrink_order(e)>normal| implies |shrink(e)<>0|.
-
- */
- width(e) = expr_a(width(e), width(t));
- if (stretch_order(e) == stretch_order(t)) {
- stretch(e) = expr_a(stretch(e), stretch(t));
- } else if ((stretch_order(e) < stretch_order(t)) && (stretch(t) != 0)) {
- stretch(e) = stretch(t);
- stretch_order(e) = stretch_order(t);
- }
- if (shrink_order(e) == shrink_order(t)) {
- shrink(e) = expr_a(shrink(e), shrink(t));
- } else if ((shrink_order(e) < shrink_order(t)) && (shrink(t) != 0)) {
- shrink(e) = shrink(t);
- shrink_order(e) = shrink_order(t);
- }
- flush_node(t);
- normalize_glue(e);
- }
- r = o;
- }
- b = arith_error;
- if (o != expr_none)
- goto CONTINUE;
- if (p != null) {
- /*tex Pop the expression stack and |goto found|. */
- f = e;
- q = p;
- e = expr_e_field(q);
- t = expr_t_field(q);
- n = expr_n_field(q);
- s = expr_state(q) / 4;
- r = expr_state(q) % 4;
- l = expr_type(q);
- p = vlink(q);
- flush_node(q);
- goto FOUND;
- }
-
- if (b) {
- print_err("Arithmetic overflow");
- help2(
- "I can't evaluate this expression,",
- "since the result is out of range."
- );
- error();
- if (l >= glue_val_level) {
- reset_glue_to_zero(e);
- } else {
- e = 0;
- }
- }
- arith_error = a;
- cur_val = e;
- cur_val_level = l;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/scanning.h b/Build/source/texk/web2c/luatexdir/tex/scanning.h
deleted file mode 100644
index e4189a0f67a..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/scanning.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* scanning.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef SCANNING_H
-# define SCANNING_H
-
-typedef enum {
- int_val_level = 0, /* integer values */
- attr_val_level, /* integer values */
- dimen_val_level, /* dimension values */
- glue_val_level, /* glue specifications */
- mu_val_level, /* math glue specifications */
- dir_val_level, /* directions */
- ident_val_level, /* font identifier */
- tok_val_level, /* token lists */
-} value_level_code;
-
-extern void scan_left_brace(void);
-extern void scan_optional_equals(void);
-
-extern int cur_val; /* value returned by numeric scanners */
-extern int cur_val1; /* delcodes are sometimes 51 digits */
-extern int cur_val_level; /* the ``level'' of this value */
-
-extern void scan_something_simple(halfword cmd, halfword subitem);
-extern void scan_something_internal(int level, boolean negative);
-
-extern void scan_limited_int(int max, const char *name);
-
-extern void negate_cur_val(boolean delete_glue);
-
-# define scan_register_num() scan_limited_int(65535,"register code")
-# define scan_mark_num() scan_limited_int(65535,"marks code")
-# define scan_char_num() scan_limited_int(biggest_char,"character code")
-# define scan_four_bit_int() scan_limited_int(15,NULL)
-# define scan_math_family_int() scan_limited_int(255,"math family")
-# define scan_real_fifteen_bit_int() scan_limited_int(32767,"mathchar")
-# define scan_big_fifteen_bit_int() scan_limited_int(0x7FFFFFF,"extended mathchar")
-# define scan_twenty_seven_bit_int() scan_limited_int(0777777777,"delimiter code")
-
-extern void scan_fifteen_bit_int(void);
-extern void scan_fifty_one_bit_int(void);
-
-# define octal_token (other_token+'\'') /* apostrophe, indicates an octal constant */
-# define hex_token (other_token+'"') /* double quote, indicates a hex constant */
-# define alpha_token (other_token+'`') /* reverse apostrophe, precedes alpha constants */
-# define point_token (other_token+'.') /* decimal point */
-# define comma_token (other_token+',') /* decimal comma */
-# define plus_token (other_token + '+')
-# define minus_token (other_token + '-')
-# define continental_point_token (other_token+',') /* decimal point, Eurostyle */
-# define infinity 017777777777 /* the largest positive value that \TeX\ knows */
-# define zero_token (other_token+'0') /* zero, the smallest digit */
-# define nine_token (other_token+'9') /* zero, the smallest digit */
-# define A_token (letter_token+'A') /* the smallest special hex digit */
-# define other_A_token (other_token+'A') /* special hex digit of type |other_char| */
-extern int radix;
-
-extern void scan_int(void);
-
-extern int cur_order;
-
-# define scan_normal_dimen() scan_dimen(false,false,false)
-
-extern void scan_dimen(boolean mu, boolean inf, boolean shortcut);
-extern void scan_glue(int level);
-
-extern halfword the_toks(void);
-extern str_number the_scanned_result(void);
-extern void set_font_dimen(void);
-extern void get_font_dimen(void);
-
-# define default_rule 26214 /* 0.4\thinspace pt */
-
-extern halfword scan_rule_spec(void);
-
-extern void scan_font_ident(void);
-extern void scan_general_text(void);
-extern void get_x_or_protected(void);
-extern halfword scan_toks(boolean macrodef, boolean xpand);
-
-extern void scan_normal_glue(void);
-extern void scan_mu_glue(void);
-
-/* extern int add_or_sub(int x, int y, int max_answer, boolean negative); */
-/* extern int quotient(int n, int d); */
-extern int fract(int x, int n, int d, int max_answer);
-
-/* extern void scan_expr(void); */
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/stringpool.c b/Build/source/texk/web2c/luatexdir/tex/stringpool.c
deleted file mode 100644
index bc09f814b00..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/stringpool.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
-
-stringpool.w
-
-Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-Control sequence names and diagnostic messages are variable-length strings of
-eight-bit characters. Since PASCAL did not have a well-developed string
-mechanism, \TeX\ did all of its string processing by homegrown methods.
-
-Elaborate facilities for dynamic strings are not needed, so all of the necessary
-operations can be handled with a simple data structure. The array |str_pool|
-contains all of the (eight-bit) bytes off all of the strings, and the array
-|str_start| contains indices of the starting points of each string. Strings are
-referred to by integer numbers, so that string number |s| comprises the
-characters |str_pool[j]| for |str_start_macro(s)<=j<str_start_macro(s+1)|.
-Additional integer variables |pool_ptr| and |str_ptr| indicate the number of
-entries used so far in |str_pool| and |str_start|, respectively; locations
-|str_pool[pool_ptr]| and |str_start_macro(str_ptr)| are ready for the next string
-to be allocated.
-
-String numbers 0 to |biggest_char| are reserved for strings that correspond to
-single UNICODE characters. This is in accordance with the conventions of \.{WEB}
-which converts single-character strings into the ASCII code number of the single
-character involved.
-
-*/
-
-/*tex The array of strings: */
-
-lstring *string_pool;
-
-/*tex
- This variable lives |STRING_OFFSET| below |string_pool| (handy for debugging:
- |_string_pool[str_ptr] == str_string(str_ptr)|:
-*/
-
-lstring *_string_pool;
-
-/*tex The number of the current string being created: */
-
-str_number str_ptr = (STRING_OFFSET + 1);
-
-/*tex The starting value of |str_ptr|: */
-
-str_number init_str_ptr;
-
-/*tex
- The current string buffer, the current index in that buffer, the malloced
- size of |cur_string| and the occupied byte count:
-*/
-
-unsigned char *cur_string;
-unsigned cur_length;
-unsigned cur_string_size;
-unsigned pool_size;
-
-/*tex
-
-Once a sequence of characters has been appended to |cur_string|, it officially
-becomes a string when the function |make_string| is called. This function returns
-the identification number of the new string as its value.
-
-*/
-
-void reset_cur_string(void)
-{
- cur_length = 0;
- cur_string_size = 255;
- cur_string = (unsigned char *) xmalloc(256);
- memset(cur_string, 0, 256);
-}
-
-str_number make_string(void)
-{
- if (str_ptr == (max_strings + STRING_OFFSET)) {
- overflow(
- "number of strings",
- (unsigned) (max_strings - init_str_ptr + STRING_OFFSET)
- );
- }
- str_room(1);
- cur_string[cur_length] = '\0'; /* now |lstring.s| is always a valid C string */
- str_string(str_ptr) = (unsigned char *) cur_string;
- str_length(str_ptr) = cur_length;
- pool_size += cur_length;
- reset_cur_string();
- str_ptr++;
- return (str_ptr - 1);
-}
-
-int pool_to_unichar(unsigned char *t)
-{
- return (int) str2uni(t);
-}
-
-/*tex
-
-The following subroutine compares string |s| with another string of the same
-length that appears in |buffer| starting at position |k|; the result is |true| if
-and only if the strings are equal. Empirical tests indicate that |str_eq_buf| is
-used in such a way that it tends to return |true| about 80 percent of the time.
-
-*/
-
-boolean str_eq_buf(str_number s, int k)
-{
- int a;
- if (s < STRING_OFFSET) {
- a = buffer_to_unichar(k);
- if (a != s)
- return false;
- } else {
- unsigned char *j = str_string(s);
- unsigned char *l = j + str_length(s);
- while (j < l) {
- if (*j++ != buffer[k++])
- return false;
- }
- }
- return true;
-}
-
-/*tex
-
-Here is a similar routine, but it compares two strings in the string pool, and it
-does not assume that they have the same length.
-
-*/
-
-boolean str_eq_str(str_number s, str_number t)
-{
- int a = 0;
- unsigned char *j, *k, *l;
- if (s < STRING_OFFSET) {
- if (t >= STRING_OFFSET) {
- k = str_string(t);
- if (s <= 0x7F && (str_length(t) == 1) && *k == s)
- return true;
- a = pool_to_unichar(k);
- if (a != s)
- return false;
- } else {
- if (t != s)
- return false;
- }
- } else if (t < STRING_OFFSET) {
- j = str_string(s);
- if (t <= 0x7F && (str_length(s) == 1) && *j == t)
- return true;
- a = pool_to_unichar(j);
- if (a != t)
- return false;
- } else {
- if (str_length(s) != str_length(t))
- return false;
- k = str_string(t);
- j = str_string(s);
- l = j + str_length(s);
- while (j < l) {
- if (*j++ != *k++)
- return false;
- }
- }
- return true;
-}
-
-/*tex A string compare helper: */
-
-boolean str_eq_cstr(str_number r, const char *s, size_t l)
-{
- if (l != (size_t) str_length(r))
- return false;
- return (strncmp((const char *) (str_string(r)), s, l) == 0);
-}
-
-
-/*tex
-
-The initial values of |str_pool|, |str_start|, |pool_ptr|, and |str_ptr| are
-computed by the \.{INITEX} program, based in part on the information that \.{WEB}
-has output while processing \TeX.
-
-The first |string_offset| strings are single-characters strings matching Unicode.
-There is no point in generating all of these. But |str_ptr| has initialized
-properly, otherwise |print_char| cannot see the difference between characters and
-strings.
-
-*/
-
-boolean get_strings_started(void)
-{
- reset_cur_string();
- return true;
-}
-
-/*tex
-
-The string recycling routines. \TeX{} uses 2 upto 4 {\it new\/} strings when
-scanning a filename in an \.{\\input}, \.{\\openin}, or \.{\\openout} operation.
-These strings are normally lost because the reference to them are not saved after
-finishing the operation. |search_string| searches through the string pool for the
-given string and returns either 0 or the found string number.
-
-*/
-
-str_number search_string(str_number search)
-{
- str_number s;
- size_t len;
- len = str_length(search);
- if (len == 0) {
- return get_nullstr();
- } else {
- /*tex We start the search with newest string below |s|; |search>1|! */
- s = search - 1;
- while (s >= STRING_OFFSET) {
- /* The first |string_offset| of strings depend on the implementation! */
- if (str_length(s) == len)
- if (str_eq_str(s, search))
- return s;
- s--;
- }
- }
- return 0;
-}
-
-str_number maketexstring(const char *s)
-{
- if (s == NULL || *s == 0)
- return get_nullstr();
- return maketexlstring(s, strlen(s));
-}
-
-str_number maketexlstring(const char *s, size_t l)
-{
- if (s == NULL || l == 0)
- return get_nullstr();
- str_string(str_ptr) = xmalloc((unsigned) (l + 1));
- memcpy(str_string(str_ptr), s, (l + 1));
- str_length(str_ptr) = (unsigned) l;
- str_ptr++;
- return (str_ptr - 1);
-}
-
-/*tex
-
- This appends a C string to a \TEX\ string:
-
-*/
-
-void append_string(const unsigned char *s, unsigned l)
-{
- if (s == NULL || *s == 0)
- return;
- l = (unsigned) strlen((const char *) s);
- str_room(l);
- memcpy(cur_string + cur_length, s, l);
- cur_length += l;
- return;
-}
-
-char *makecstring(int s)
-{
- size_t l;
- return makeclstring(s, &l);
-}
-
-char *makeclstring(int s, size_t * len)
-{
- if (s < STRING_OFFSET) {
- *len = (size_t) utf8_size(s);
- return (char *) uni2str((unsigned) s);
- } else {
- unsigned l = (unsigned) str_length(s);
- char *cstrbuf = xmalloc(l + 1);
- memcpy(cstrbuf, str_string(s), l);
- cstrbuf[l] = '\0';
- *len = (size_t) l;
- return cstrbuf;
- }
-}
-
-int dump_string_pool(void)
-{
- int j;
- int l;
- int k = str_ptr;
- dump_int(k - STRING_OFFSET);
- for (j = STRING_OFFSET + 1; j < k; j++) {
- l = (int) str_length(j);
- if (str_string(j) == NULL)
- l = -1;
- dump_int(l);
- if (l > 0)
- dump_things(*str_string(j), str_length(j));
- }
- return (k - STRING_OFFSET);
-}
-
-int undump_string_pool(void)
-{
- int j;
- int x;
- undump_int(str_ptr);
- if (max_strings < str_ptr + strings_free)
- max_strings = str_ptr + strings_free;
- str_ptr += STRING_OFFSET;
- if (ini_version)
- libcfree(string_pool);
- init_string_pool_array((unsigned) max_strings);
- for (j = STRING_OFFSET + 1; j < str_ptr; j++) {
- undump_int(x);
- if (x >= 0) {
- str_length(j) = (unsigned) x;
- pool_size += (unsigned) x;
- str_string(j) = xmallocarray(unsigned char, (unsigned) (x + 1));
- undump_things(*str_string(j), (unsigned) x);
- *(str_string(j) + str_length(j)) = '\0';
- } else {
- str_length(j) = 0;
- }
- }
- init_str_ptr = str_ptr;
- return str_ptr;
-}
-
-void init_string_pool_array(unsigned s)
-{
- string_pool = xmallocarray(lstring, s);
- _string_pool = string_pool - STRING_OFFSET;
- memset(string_pool, 0, s * sizeof(lstring));
- /* seed the null string */
- string_pool[0].s = xmalloc(1);
- string_pool[0].s[0] = '\0';
-}
-
-/*tex
-
- To destroy an already made string, we say |flush_str|.
-
-*/
-
-void flush_str(str_number s)
-{
- if (s > STRING_OFFSET) {
- /*tex Don't ever delete the null string! */
- pool_size -= (unsigned) str_length(s);
- str_length(s) = 0;
- xfree(str_string(s));
- }
- while (str_string((str_ptr - 1)) == NULL)
- str_ptr--;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/stringpool.h b/Build/source/texk/web2c/luatexdir/tex/stringpool.h
deleted file mode 100644
index 2ba156046fd..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/stringpool.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* stringpool.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef STRINGPOOL_H
-# define STRINGPOOL_H
-
-/* Both lua and tex strings can contains null, but C strings cannot, so: */
-
-typedef struct {
- unsigned char *s;
- size_t l;
-} lstring;
-
-typedef struct {
- const char *s;
- size_t l;
-} const_lstring;
-
-extern lstring *string_pool;
-
-extern str_number str_ptr;
-extern str_number init_str_ptr;
-
-# define STRING_OFFSET 0x200000
-# define STRING_OFFSET_BITS 21
-
-# define get_nullstr() STRING_OFFSET
-
-# define biggest_char 1114111 /* 0x10FFFF, the largest allowed character number; must be |< max_halfword| */
-# define too_big_char (biggest_char+1) /* 1114112, |biggest_char+1| */
-# define special_char (biggest_char+2) /* 1114113, |biggest_char+2| */
-# define number_chars (biggest_char+3) /* 1114112, |biggest_char+1| */
-
-/*
- Several of the elementary string operations are performed using
- macros instead of procedures, because many of the
- operations are done quite frequently and we want to avoid the
- overhead of procedure calls. For example, here is
- a simple macro that computes the length of a string.
-*/
-
-# define str_length(a) string_pool[(a)-STRING_OFFSET].l
-# define str_string(a) string_pool[(a)-STRING_OFFSET].s
-# define str_lstring(a) string_pool[(a)-STRING_OFFSET]
-
-/* Strings are created by appending character codes to |str_pool|.
- The |append_char| macro, defined here, does not check to see if the
- value of |pool_ptr| has gotten too high; this test is supposed to be
- made before |append_char| is used. There is also a |flush_char|
- macro, which erases the last character appended.
-
- To test if there is room to append |l| more characters to |str_pool|,
- we shall write |str_room(l)|, which aborts \TeX\ and gives an
- apologetic error message if there isn't enough room.
-*/
-
-/* The length of the current string is called |cur_length|: */
-
-extern unsigned char *cur_string;
-extern unsigned cur_length;
-extern unsigned cur_string_size;
-extern unsigned pool_size;
-
-# define EXTRA_STRING 500
-
-/* put |ASCII_code| \# at the end of |str_pool| */
-# define append_char(A) do { \
- if (cur_string==NULL) reset_cur_string(); \
- else str_room(1); \
- cur_string[cur_length++]=(unsigned char)(A); \
- } while (0)
-
-# define str_room(wsize) do { \
- unsigned nsize; \
- if ((cur_length+wsize) > cur_string_size) { \
- nsize = cur_string_size + cur_string_size / 5 + EXTRA_STRING; \
- if (nsize < (unsigned)(wsize)) { \
- nsize = wsize + EXTRA_STRING; \
- } \
- cur_string = (unsigned char *) xreallocarray(cur_string, unsigned char, nsize); \
- memset (cur_string+cur_length,0,nsize-cur_length); \
- cur_string_size = nsize; \
- } \
- } while (0)
-
-# define flush_char() --cur_length /* forget the last character in the pool */
-
-extern str_number make_string(void);
-extern boolean str_eq_buf(str_number s, int k);
-extern boolean str_eq_str(str_number s, str_number t);
-extern boolean str_eq_cstr(str_number, const char *, size_t);
-extern boolean get_strings_started(void);
-extern void reset_cur_string(void);
-
-# define save_cur_string() (cur_length>0 ? make_string() : 0)
-
-# define restore_cur_string(u) if (u!=0) { \
- unsigned l = (unsigned)str_length(u); \
- xfree(cur_string); \
- reset_cur_string(); \
- str_room(l); \
- memcpy(cur_string, str_string(u),l); \
- cur_length = l; \
- flush_str(u); \
- u=0; \
- }
-
-
-extern str_number search_string(str_number search);
-extern int pool_to_unichar(unsigned char *t);
-
-extern str_number maketexstring(const char *);
-extern str_number maketexlstring(const char *, size_t);
-extern void append_string(const unsigned char *s, unsigned l);
-
-extern char *makecstring(int);
-extern char *makeclstring(int, size_t *);
-
-extern int dump_string_pool(void);
-extern int undump_string_pool(void);
-
-extern void init_string_pool_array(unsigned s);
-extern void flush_str(str_number s);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c b/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
deleted file mode 100644
index 1ec4b12bf06..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texdeffont.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-
-texdeffont.w
-
-Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-When the user defines \.{\\font\\f}, say, \TeX\ assigns an internal number to the
-user's font~\.{\\f}. Adding this number to |font_id_base| gives the |eqtb|
-location of a ``frozen'' control sequence that will always select the font.
-
-The variable |a| in the following code indicates the global nature of the value
-to be set. It's used in the |define| macro. Here we're never global.
-
-There's not much scanner code here because the other scanners are defined where
-they make most sense.
-
-*/
-
-int font_bytes;
-
-void set_cur_font(internal_font_number f)
-{
- int a = 0;
- define(cur_font_loc, data_cmd, f);
-}
-
-/*tex
-
- This prints a scaled real, rounded to five digits.
-
-*/
-
-static char *scaled_to_string(scaled s)
-{
- static char result[16];
- int n, k;
- /*tex The amount of allowable inaccuracy: */
- scaled delta;
- k = 0;
- if (s < 0) {
- /*tex Only print the sign, if negative */
- result[k++] = '-';
- s = -s;
- }
- {
- int l = 0;
- char digs[8] = { 0 };
- n = s / unity;
- /*tex Process the integer part: */
- do {
- digs[l++] = (char) (n % 10);
- n = n / 10;;
- } while (n > 0);
- while (l > 0) {
- result[k++] = (char) (digs[--l] + '0');
- }
- }
- result[k++] = '.';
- s = 10 * (s % unity) + 5;
- delta = 10;
- do {
- if (delta > unity) {
- /*tex Round the last digit: */
- s = s + 0100000 - 050000;
- }
- result[k++] = (char) ('0' + (s / unity));
- s = 10 * (s % unity);
- delta = delta * 10;
- } while (s > delta);
- result[k] = 0;
- return (char *) result;
-}
-
-void tex_def_font(small_number a)
-{
- /*tex The user's font identifier. */
- pointer u;
- /*tex This runs through existing fonts. */
- internal_font_number f;
- /*tex The name for the frozen font identifier. */
- str_number t, d;
- /*tex Thos holds the |selector| setting. */
- int old_setting;
- /*tex Stated `at' size, or negative of scaled magnification. */
- scaled s = -1000;
- /*tex The natural direction of the font. */
- int natural_dir = -1;
- char *fn;
- if (job_name == 0) {
- /*tex Avoid confusing \.{texput} with the font name. */
- open_log_file();
- }
- get_r_token();
- u = cur_cs;
- if (a >= 4) {
- geq_define(u, set_font_cmd, null_font);
- } else {
- eq_define(u, set_font_cmd, null_font);
- }
- scan_optional_equals();
- /*tex Get the next non-blank non-call token. */
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- if (cur_cmd != left_brace_cmd) {
- back_input();
- scan_file_name();
- if (cur_area != get_nullstr() || cur_ext != get_nullstr()) {
- /*tex
- Have to do some rescue-ing here, fonts only have a name, no area
- nor extension.
- */
- old_setting = selector;
- selector = new_string;
- if (cur_area != get_nullstr()) {
- print(cur_area);
- flush_str(cur_area);
- }
- if (cur_name != get_nullstr()) {
- print(cur_name);
- flush_str(cur_name);
- }
- if (cur_ext != get_nullstr()) {
- print(cur_ext);
- flush_str(cur_ext);
- }
- selector = old_setting;
- cur_area = get_nullstr();
- cur_name = make_string();
- cur_ext = get_nullstr();
- }
- } else {
- back_input();
- (void) scan_toks(false, true);
- old_setting = selector;
- selector = new_string;
- token_show(def_ref);
- selector = old_setting;
- flush_list(def_ref);
- cur_area = get_nullstr();
- cur_name = make_string();
- cur_ext = get_nullstr();
- }
- /*tex
- Scan the font size specification. The next variable keeps |cur_name| from
- being changed
- */
- name_in_progress = true;
- if (scan_keyword("at")) {
- /*tex Put the positive `at' size into |s|. */
- scan_normal_dimen();
- s = cur_val;
- if ((s <= 0) || (s >= 01000000000)) {
- char err[256];
- const char *errhelp[] = {
- "I can only handle fonts at positive sizes that are",
- "less than 2048pt, so I've changed what you said to 10pt.",
- NULL
- };
- snprintf(err, 255, "Improper `at' size (%spt), replaced by 10pt", scaled_to_string(s));
- tex_error(err, errhelp);
- s = 10 * unity;
- }
- } else if (scan_keyword("scaled")) {
- scan_int();
- s = -cur_val;
- if ((cur_val <= 0) || (cur_val > 32768)) {
- char err[256];
- const char *errhelp[] = {
- "The magnification ratio must be between 1 and 32768.",
- NULL
- };
- snprintf(err, 255, "Illegal magnification has been changed to 1000 (%d)", (int) cur_val);
- tex_error(err, errhelp);
- s = -1000;
- }
- }
- /*tex
- There is no real reason to support this obsolete key as there are no useful
- fonts out there so let's get rid of this overhead. This also means that
- |natural_dir| can go away.
- */
- /*
- if (scan_keyword("naturaldir")) {
- scan_direction();
- natural_dir = cur_val;
- }
- */
- name_in_progress = false;
- fn = makecstring(cur_name);
- f = read_font_info(u, fn, s, natural_dir);
- xfree(fn);
- equiv(u) = f;
- eqtb[font_id_base + f] = eqtb[u];
- /*tex
-
- This is tricky: when we redefine a string we loose the old one. So this
- will change as it's only used to display the |\fontname| so we can store
- that with the font.
-
- */
- d = cs_text(font_id_base + f);
- t = (u >= null_cs) ? cs_text(u) : maketexstring("FONT");
- if (!d) {
- /*tex We have a new string. */
- cs_text(font_id_base + f) = t;
- } else if ((d!=t) && str_eq_str(d,t)){
- /*tex We have a duplicate string. */
- flush_str(t);
- } else if (d!=t){
- d = search_string(t);
- if (d) {
- /*tex We have already such a string. */
- cs_text(font_id_base + f) = d;
- flush_str(t);
- } else {
- /*tex The old value is lost but still in the pool. */
- cs_text(font_id_base + f) = t;
- }
- }
- if (cur_name == str_ptr-1) {
- flush_str(cur_name);
- cur_name = get_nullstr();
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texdeffont.h b/Build/source/texk/web2c/luatexdir/tex/texdeffont.h
deleted file mode 100644
index 24782f5fbe4..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texdeffont.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* texdeffont.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef TEXDEFFONT_H
-# define TEXDEFFONT_H
-
-extern int font_bytes;
-
-extern void set_cur_font(internal_font_number f);
-
-extern void tex_def_font(small_number a);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.c b/Build/source/texk/web2c/luatexdir/tex/texfileio.c
deleted file mode 100644
index 4e0677a564b..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texfileio.c
+++ /dev/null
@@ -1,1509 +0,0 @@
-/*
-
-Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-#include <string.h>
-#include <kpathsea/absolute.h>
-
-/*tex
-
-The bane of portability is the fact that different operating systems treat input
-and output quite differently, perhaps because computer scientists have not given
-sufficient attention to this problem. People have felt somehow that input and
-output are not part of ``real'' programming. Well, it is true that some kinds of
-programming are more fun than others. With existing input/output conventions
-being so diverse and so messy, the only sources of joy in such parts of the code
-are the rare occasions when one can find a way to make the program a little less
-bad than it might have been. We have two choices, either to attack I/O now and
-get it over with, or to postpone I/O until near the end. Neither prospect is very
-attractive, so let's get it over with.
-
-The basic operations we need to do are (1)~inputting and outputting of text, to
-or from a file or the user's terminal; (2)~inputting and outputting of eight-bit
-bytes, to or from a file; (3)~instructing the operating system to initiate
-(``open'') or to terminate (``close'') input or output from a specified file;
-(4)~testing whether the end of an input file has been reached.
-
-\TeX\ needs to deal with two kinds of files. We shall use the term |alpha_file|
-for a file that contains textual data, and the term |byte_file| for a file that
-contains eight-bit binary information. These two types turn out to be the same on
-many computers, but sometimes there is a significant distinction, so we shall be
-careful to distinguish between them. Standard protocols for transferring such
-files from computer to computer, via high-speed networks, are now becoming
-available to more and more communities of users.
-
-The program actually makes use also of a third kind of file, called a
-|word_file|, when dumping and reloading base information for its own
-initialization. We shall define a word file later; but it will be possible for us
-to specify simple operations on word files before they are defined.
-
-We finally did away with |nameoffile| and |namelength|, but the variables have to
-be kept otherwise there will be link errors from |openclose.c| in the web2c
-library
-
-*/
-
-char *nameoffile;
-int namelength;
-
-/*tex
-
- When input files are opened via a callback, they will also be read using
- callbacks. for that purpose, the |open_read_file_callback| returns an integer
- to uniquely identify a callback table. This id replaces the file point |f| in
- this case, because the input does not have to be a file in the traditional
- sense.
-
- Signalling this fact is achieved by having two arrays of integers.
-
-*/
-
-int *input_file_callback_id;
-int read_file_callback_id[17];
-
-/*tex
-
- Here we handle |-output-directory|. We assume that it is OK to look here
- first. Possibly it would be better to replace lookups in "." with lookups in
- the |output_directory| followed by "." but to do this requires much more
- invasive surgery in libkpathsea.
-
-*/
-
-static char *find_in_output_directory(const char *s)
-{
- if (output_directory && !kpse_absolute_p(s, false)) {
- FILE *f_ptr;
- char *ftemp = concat3(output_directory, DIR_SEP_STRING, s);
- /*tex This code is used for input files only. */
- f_ptr = fopen(ftemp, "rb");
- if (f_ptr) {
- fclose(f_ptr);
- return ftemp;
- } else {
- free(ftemp);
-
- }
- }
- return NULL;
-}
-
-/*tex
-
- Find an \.{\\input} or \.{\\read} file. |n| differentiates between those
- case.
-
-*/
-
-int kpse_available(const char *m) {
- if (!kpse_init) {
- fprintf(stdout,"missing kpse replacement callback '%s', quitting\n",m);
- exit(1);
- }
- return 1 ;
-}
-
-char *luatex_find_read_file(const char *s, int n, int callback_index)
-{
- char *ftemp = NULL;
- int callback_id = callback_defined(callback_index);
- if (callback_id > 0) {
- (void) run_callback(callback_id, "dS->R", n, s, &ftemp);
- } else if (kpse_available("find_read_file")) {
- /*tex Use kpathsea here. */
- ftemp = find_in_output_directory(s);
- if (!ftemp)
- ftemp = kpse_find_file(s, kpse_tex_format, 1);
- }
- if (ftemp) {
- if (fullnameoffile)
- free(fullnameoffile);
- fullnameoffile = xstrdup(ftemp);
- }
- return ftemp;
-}
-
-/*tex Find other files types. */
-
-char *luatex_find_file(const char *s, int callback_index)
-{
- char *ftemp = NULL;
- int callback_id = callback_defined(callback_index);
- if (callback_id > 0) {
- (void) run_callback(callback_id, "S->R", s, &ftemp);
- } else if (kpse_available("find_read_file")) {
- /*tex Use kpathsea here. */
- switch (callback_index) {
- case find_enc_file_callback:
- ftemp = kpse_find_file(s, kpse_enc_format, 0);
- break;
- case find_map_file_callback:
- ftemp = kpse_find_file(s, kpse_fontmap_format, 0);
- break;
- case find_type1_file_callback:
- ftemp = kpse_find_file(s, kpse_type1_format, 0);
- break;
- case find_truetype_file_callback:
- ftemp = kpse_find_file(s, kpse_truetype_format, 0);
- break;
- case find_opentype_file_callback:
- ftemp = kpse_find_file(s, kpse_opentype_format, 0);
- if (ftemp == NULL)
- ftemp = kpse_find_file(s, kpse_truetype_format, 0);
- break;
- case find_data_file_callback:
- ftemp = find_in_output_directory(s);
- if (!ftemp)
- ftemp = kpse_find_file(s, kpse_tex_format, 1);
- break;
- case find_font_file_callback:
- ftemp = kpse_find_file(s, kpse_ofm_format, 1);
- if (ftemp == NULL)
- ftemp = kpse_find_file(s, kpse_tfm_format, 1);
- break;
- case find_vf_file_callback:
- ftemp = kpse_find_file(s, kpse_ovf_format, 0);
- if (ftemp == NULL)
- ftemp = kpse_find_file(s, kpse_vf_format, 0);
- break;
- case find_cidmap_file_callback:
- ftemp = kpse_find_file(s, kpse_cid_format, 0);
- break;
- default:
- printf("luatex_find_file(): do not know how to handle file %s of type %d\n", s, callback_index);
- break;
- }
- }
- return ftemp;
-}
-
-/*tex
-
- \LUATEX\ used to have private functions for these that did not use kpathsea,
- but since the file paranoia tests have to come from kpathsea anyway, that is
- no longer useful. The only downside to using luatex is that if one wants to
- disable kpathsea via the Lua startup script, it is now an absolute
- requirement that all file discovery callbacks are specified. Just using the
- find_read_file, but not setting open_read_file, for example, does not work
- any more if kpathsea is not to be used at all.
-
-*/
-
-#define openoutnameok(A) kpse_out_name_ok (A)
-#define openinnameok(A) kpse_in_name_ok (A)
-
-/*tex
-
- Open an input file F, using the kpathsea format FILEFMT and passing
- |FOPEN_MODE| to fopen. The filename is in `fn'. We return whether or not the
- open succeeded.
-
-*/
-
-boolean luatex_open_input(FILE ** f_ptr, const char *fn, int filefmt, const_string fopen_mode, boolean must_exist)
-{
- /*tex We haven't found anything yet. */
- string fname = NULL;
- *f_ptr = NULL;
- if (fullnameoffile)
- free(fullnameoffile);
- fullnameoffile = NULL;
- fname = kpse_find_file(fn, (kpse_file_format_type) filefmt, must_exist);
- if (fname) {
- fullnameoffile = xstrdup(fname);
- /*tex
-
- If we found the file in the current directory, don't leave the `./'
- at the beginning of `fn', since it looks dumb when `tex foo' says
- `(./foo.tex ... )'. On the other hand, if the user said `tex ./foo',
- and that's what we opened, then keep it -- the user specified it, so
- we shouldn't remove it.
-
- */
- if (fname[0] == '.' && IS_DIR_SEP(fname[1]) && (fn[0] != '.' || !IS_DIR_SEP(fn[1]))) {
- unsigned i = 0;
- while (fname[i + 2] != 0) {
- fname[i] = fname[i + 2];
- i++;
- }
- fname[i] = 0;
- }
- /*tex This fopen is not allowed to fail. */
- *f_ptr = xfopen(fname, fopen_mode);
- }
- if (*f_ptr) {
- recorder_record_input(fname);
- }
- return *f_ptr != NULL;
-}
-
-boolean luatex_open_output(FILE ** f_ptr, const char *fn, const_string fopen_mode)
-{
- char *fname;
- boolean absolute = kpse_absolute_p(fn, false);
- /*tex If we have an explicit output directory, use it. */
- if (output_directory && !absolute) {
- fname = concat3(output_directory, DIR_SEP_STRING, fn);
- } else {
- fname = xstrdup(fn);
- }
- /*tex Is the filename openable as given? */
- *f_ptr = fopen(fname, fopen_mode);
- if (!*f_ptr) {
- /*tex Can't open as given. Try the envvar. */
- string texmfoutput = kpse_var_value("TEXMFOUTPUT");
- if (texmfoutput && *texmfoutput && !absolute) {
- fname = concat3(texmfoutput, DIR_SEP_STRING, fn);
- *f_ptr = fopen(fname, fopen_mode);
- }
- }
- if (*f_ptr) {
- recorder_record_output(fname);
- }
- free(fname);
- return *f_ptr != NULL;
-}
-
-boolean lua_a_open_in(alpha_file * f, char *fn, int n)
-{
- int k;
- char *fnam;
- int callback_id;
- boolean ret = true;
- boolean file_ok = true;
- if (n == 0) {
- input_file_callback_id[iindex] = 0;
- } else {
- read_file_callback_id[n] = 0;
- }
- if (*fn == '|')
- fnam = fn;
- else
- fnam = luatex_find_read_file(fn, n, find_read_file_callback);
- if (!fnam)
- return false;
- callback_id = callback_defined(open_read_file_callback);
- if (callback_id > 0) {
- k = run_and_save_callback(callback_id, "S->", fnam);
- if (k > 0) {
- ret = true;
- if (n == 0)
- input_file_callback_id[iindex] = k;
- else
- read_file_callback_id[n] = k;
- } else {
- /*tex read failed */
- file_ok = false;
- }
- } else {
- /*tex no read callback */
- if (openinnameok(fn)) {
- ret = open_in_or_pipe(f, fnam, kpse_tex_format, FOPEN_RBIN_MODE, (n == 0 ? true : false));
- } else {
- /*tex open failed */
- file_ok = false;
- }
- }
- if (!file_ok) {
- ret = false;
- }
- return ret;
-}
-
-boolean lua_a_open_out(alpha_file * f, char *fn, int n)
-{
- boolean test;
- char *fnam = NULL;
- int callback_id;
- boolean ret = false;
- callback_id = callback_defined(find_write_file_callback);
- if (callback_id > 0) {
- test = run_callback(callback_id, "dS->R", n, fn, &fnam);
- if ((test) && (fnam != NULL) && (strlen(fnam) > 0)) {
- /*tex
-
- There is no message here because if that is needed the macro
- package should do that in the callback code. As elsewhere,
- messaging is left to \LUA\ then.
-
- */
- ret = open_outfile(f, fnam, FOPEN_W_MODE);
- free(fnam);
- }
- } else {
- if (openoutnameok(fn)) {
- if (n > 0 && selector != term_only) {
- /*tex
-
- This message to the log is for downward compatibility with
- other tex's as there are scripts out there that act on this
- message. An alternative is to let a macro package write an
- explicit message.
-
- */
- fprintf(log_file,"\n\\openout%i = %s\n",n-1,fn);
- }
- ret = open_out_or_pipe(f, fn, FOPEN_W_MODE);
- }
- }
- return ret;
-}
-
-boolean lua_b_open_out(alpha_file * f, char *fn)
-{
- boolean test;
- char *fnam = NULL;
- int callback_id;
- boolean ret = false;
- callback_id = callback_defined(find_output_file_callback);
- if (callback_id > 0) {
- test = run_callback(callback_id, "S->R", fn, &fnam);
- if ((test) && (fnam != NULL) && (strlen(fnam) > 0)) {
- ret = open_outfile(f, fnam, FOPEN_WBIN_MODE);
- free(fnam);
- }
- } else {
- if (openoutnameok(fn)) {
- ret = luatex_open_output(f, fn, FOPEN_WBIN_MODE);
- }
- }
- return ret;
-}
-
-void lua_a_close_in(alpha_file f, int n)
-{
- int callback_id;
- if (n == 0)
- callback_id = input_file_callback_id[iindex];
- else
- callback_id = read_file_callback_id[n];
- if (callback_id > 0) {
- run_saved_callback(callback_id, "close", "->");
- destroy_saved_callback(callback_id);
- if (n == 0)
- input_file_callback_id[iindex] = 0;
- else
- read_file_callback_id[n] = 0;
- } else {
- close_file_or_pipe(f);
- }
-}
-
-void lua_a_close_out(alpha_file f)
-{
- close_file_or_pipe(f);
-}
-
-/*tex
-
- Binary input and output are done with C's ordinary procedures, so we don't
- have to make any other special arrangements for binary~I/O. Text output is
- also easy to do with standard routines. The treatment of text input is more
- difficult, however, because of the necessary translation to |ASCII_code|
- values. \TeX's conventions should be efficient, and they should blend nicely
- with the user's operating environment.
-
- Input from text files is read one line at a time, using a routine called
- |lua_input_ln|. This function is defined in terms of global variables called
- |buffer|, |first|, and |last| that will be described in detail later; for
- now, it suffices for us to know that |buffer| is an array of |ASCII_code|
- values, and that |first| and |last| are indices into this array representing
- the beginning and ending of a line of text.
-
-*/
-
-/*tex lines of characters being read */
-
-packed_ASCII_code *buffer;
-
-/*tex the first unused position in |buffer| */
-
-int first;
-
-/*tex end of the line just input to |buffer| */
-
-int last;
-
-/*tex largest index used in |buffer| */
-
-int max_buf_stack;
-
-/*tex
-
- The |lua_input_ln| function brings the next line of input from the specified
- file into available positions of the buffer array and returns the value
- |true|, unless the file has already been entirely read, in which case it
- returns |false| and sets |last:=first|. In general, the |ASCII_code| numbers
- that represent the next line of the file are input into |buffer[first]|,
- |buffer[first+1]|, \dots, |buffer[last-1]|; and the global variable |last| is
- set equal to |first| plus the length of the line. Trailing blanks are removed
- from the line; thus, either |last=first| (in which case the line was entirely
- blank) or |buffer[last-1]<>" "|.
-
- An overflow error is given, however, if the normal actions of |lua_input_ln|
- would make |last>=buf_size|; this is done so that other parts of \TeX\ can
- safely look at the contents of |buffer[last+1]| without overstepping the
- bounds of the |buffer| array. Upon entry to |lua_input_ln|, the condition
- |first<buf_size| will always hold, so that there is always room for an
- ``empty'' line.
-
- The variable |max_buf_stack|, which is used to keep track of how large the
- |buf_size| parameter must be to accommodate the present job, is also kept up
- to date by |lua_input_ln|.
-
- If the |bypass_eoln| parameter is |true|, |lua_input_ln| will do a |get|
- before looking at the first character of the line; this skips over an |eoln|
- that was in |f^|. The procedure does not do a |get| when it reaches the end
- of the line; therefore it can be used to acquire input from the user's
- terminal as well as from ordinary text files.
-
- Since the inner loop of |lua_input_ln| is part of \TeX's ``inner
- loop''---each character of input comes in at this place---it is wise to
- reduce system overhead by making use of special routines that read in an
- entire array of characters at once, if such routines are available.
-
-*/
-
-boolean lua_input_ln(alpha_file f, int n, boolean bypass_eoln)
-{
- boolean lua_result;
- int last_ptr;
- int callback_id;
- /*tex Todo: variable can be removed: */
- (void) bypass_eoln;
- if (n == 0)
- callback_id = input_file_callback_id[iindex];
- else
- callback_id = read_file_callback_id[n];
- if (callback_id > 0) {
- last = first;
- last_ptr = first;
- lua_result =
- run_saved_callback(callback_id, "reader", "->l", &last_ptr);
- if ((lua_result == true) && (last_ptr != 0)) {
- last = last_ptr;
- if (last > max_buf_stack)
- max_buf_stack = last;
- } else {
- lua_result = false;
- }
- } else {
- lua_result = input_ln(f, bypass_eoln);
- }
- if (lua_result == true) {
- /*tex Fix up the input buffer using callbacks */
- if (last >= first) {
- callback_id = callback_defined(process_input_buffer_callback);
- if (callback_id > 0) {
- last_ptr = first;
- lua_result =
- run_callback(callback_id, "l->l", (last - first),
- &last_ptr);
- if ((lua_result == true) && (last_ptr != 0)) {
- last = last_ptr;
- if (last > max_buf_stack)
- max_buf_stack = last;
- }
- }
- }
- return true;
- }
- return false;
-}
-
-/*tex
-
- We need a special routine to read the first line of \TeX\ input from the
- user's terminal. This line is different because it is read before we have
- opened the transcript file; there is sort of a ``chicken and egg'' problem
- here. If the user types `\.{\\input paper}' on the first line, or if some
- macro invoked by that line does such an \.{\\input}, the transcript file will
- be named `\.{paper.log}'; but if no \.{\\input} commands are performed during
- the first line of terminal input, the transcript file will acquire its
- default name `\.{texput.log}'. (The transcript file will not contain error
- messages generated by the first line before the first \.{\\input} command.)
-
- The first line is special also because it may be read before \TeX\ has input
- a format file. In such cases, normal error messages cannot yet be given. The
- following code uses concepts that will be explained later.
-
- Different systems have different ways to get started. But regardless of what
- conventions are adopted, the routine that initializes the terminal should
- satisfy the following specifications:
-
- \startitemize[n]
-
- \startitem
- It should open file |term_in| for input from the terminal. (The file
- |term_out| will already be open for output to the terminal.)
- \stopitem
-
- \startitem
- If the user has given a command line, this line should be considered
- the first line of terminal input. Otherwise the user should be
- prompted with `\.{**}', and the first line of input should be
- whatever is typed in response.
- \stopitem
-
- \startitem
- The first line of input, which might or might not be a command line,
- should appear in locations |first| to |last-1| of the |buffer| array.
- \stopitem
-
- \startitem
- The global variable |loc| should be set so that the character to be
- read next by \TeX\ is in |buffer[loc]|. This character should not be
- blank, and we should have |loc<last|.
- \stopitem
-
- \stopitemize
-
- It may be necessary to prompt the user several times before a non-blank line
- comes in. The prompt is `\.{**}' instead of the later `\.*' because the
- meaning is slightly different: `\.{\\input}' need not be typed immediately
- after~`\.{**}'.)
-
- The following program does the required initialization. Iff anything has been
- specified on the command line, then |t_open_in| will return with |last >
- first|.
-
-*/
-
-boolean init_terminal(void)
-{
- /*tex This gets the terminal input started. */
- t_open_in();
- if (last > first) {
- iloc = first;
- while ((iloc < last) && (buffer[iloc] == ' '))
- incr(iloc);
- if (iloc < last) {
- return true;
- }
- }
- while (1) {
- wake_up_terminal();
- fputs("**", term_out);
- update_terminal();
- if (!input_ln(term_in, true)) {
- /*tex This shouldn't happen. */
- fputs("\n! End of file on the terminal... why?\n", term_out);
- return false;
- }
- iloc = first;
- while ((iloc < last) && (buffer[iloc] == ' ')) {
- incr(iloc);
- }
- /*tex Return unless the line was all blank. */
- if (iloc < last) {
- return true;
- }
- fputs("Please type the name of your input file.\n", term_out);
- }
-}
-
-
-/*tex
-
- Here is a procedure that asks the user to type a line of input, assuming that
- the |selector| setting is either |term_only| or |term_and_log|. The input is
- placed into locations |first| through |last-1| of the |buffer| array, and
- echoed on the transcript file if appropriate.
-
-*/
-
-void term_input(void)
-{
- /*tex Index into |buffer|: */
- int k;
- /*tex Now the user sees the prompt for sure: */
- update_terminal();
- if (!input_ln(term_in, true))
- fatal_error("End of file on the terminal!");
- /*tex The user's line ended with \.{<return>}: */
- term_offset = 0;
- /*tex Prepare to echo the input. */
- decr(selector);
- if (last != first) {
- for (k = first; k <= last - 1; k++)
- print_char(buffer[k]);
- }
- print_ln();
- /*tex Restore previous status. */
- incr(selector);
-}
-
-/*tex
-
- It's time now to fret about file names. Besides the fact that different
- operating systems treat files in different ways, we must cope with the fact
- that completely different naming conventions are used by different groups of
- people. The following programs show what is required for one particular
- operating system; similar routines for other systems are not difficult to
- devise.
-
- \TeX\ assumes that a file name has three parts: the name proper; its
- ``extension''; and a ``file area'' where it is found in an external file
- system. The extension of an input file or a write file is assumed to be
- `\.{.tex}' unless otherwise specified; it is `\.{.log}' on the transcript
- file that records each run of \TeX; it is `\.{.tfm}' on the font metric files
- that describe characters in the fonts \TeX\ uses; it is `\.{.dvi}' on the
- output files that specify typesetting information; and it is `\.{.fmt}' on
- the format files written by \.{INITEX} to initialize \TeX. The file area can
- be arbitrary on input files, but files are usually output to the user's
- current area. If an input file cannot be found on the specified area, \TeX\
- will look for it on a special system area; this special area is intended for
- commonly used input files like \.{webmac.tex}.
-
- Simple uses of \TeX\ refer only to file names that have no explicit extension
- or area. For example, a person usually says `\.{\\input} \.{paper}' or
- `\.{\\font\\tenrm} \.= \.{helvetica}' instead of `\.{\\input} \.{paper.new}'
- or `\.{\\font\\tenrm} \.= \.{<csd.knuth>test}'. Simple file names are best,
- because they make the \TeX\ source files portable; whenever a file name
- consists entirely of letters and digits, it should be treated in the same way
- by all implementations of \TeX. However, users need the ability to refer to
- other files in their environment, especially when responding to error
- messages concerning unopenable files; therefore we want to let them use the
- syntax that appears in their favorite operating system.
-
- The following procedures don't allow spaces to be part of file names; but
- some users seem to like names that are spaced-out. System-dependent changes
- to allow such things should probably be made with reluctance, and only when
- an entire file name that includes spaces is ``quoted'' somehow.
-
- Here are the global values that file names will be scanned into.
-
-*/
-
-/*tex name of file just scanned */
-
-str_number cur_name;
-
-/*tex file area just scanned, or \.{""} */
-
-str_number cur_area;
-
-/*tex file extension just scanned, or \.{""} */
-
-str_number cur_ext;
-
-/*tex
-
- The file names we shall deal with have the following structure: If the name
- contains `\./' or `\.:' (for Amiga only), the file area consists of all
- characters up to and including the final such character; otherwise the file
- area is null. If the remaining file name contains `\..', the file extension
- consists of all such characters from the last `\..' to the end, otherwise the
- file extension is null.
-
- We can scan such file names easily by using two global variables that keep
- track of the occurrences of area and extension delimiters:
-
-*/
-
-/*tex the most recent `\./', if any */
-
-pool_pointer area_delimiter;
-
-/*tex the relevant `\..', if any */
-
-pool_pointer ext_delimiter;
-
-/*tex
-
- Input files that can't be found in the user's area may appear in a standard
- system area called |TEX_area|. Font metric files whose areas are not given
- explicitly are assumed to appear in a standard system area called
- |TEX_font_area|. $\Omega$'s compiled translation process files whose areas
- are not given explicitly are assumed to appear in a standard system area.
- These system area names will, of course, vary from place to place.
-
-*/
-
-#define append_to_fn(A) do { \
- c=(A); \
- if (c!='"') { \
- if (k<file_name_size) fn[k++]=(unsigned char)(c); \
- } \
- } while (0)
-
-
-char *pack_file_name(str_number n, str_number a, str_number e)
-{
- /*tex character being packed */
- ASCII_code c;
- /*tex index into |str_pool| */
- unsigned char *j;
- /*tex number of positions filled in |fn| */
- int k = 0;
- unsigned char *fn = xmallocarray(packed_ASCII_code, str_length(a) + str_length(n) + str_length(e) + 1);
- for (j = str_string(a); j < str_string(a) + str_length(a); j++)
- append_to_fn(*j);
- for (j = str_string(n); j < str_string(n) + str_length(n); j++)
- append_to_fn(*j);
- for (j = str_string(e); j < str_string(e) + str_length(e); j++)
- append_to_fn(*j);
- fn[k] = 0;
- return (char *) fn;
-}
-
-/*tex
-
- A messier routine is also needed, since format file names must be scanned
- before \TeX's string mechanism has been initialized. We shall use the global
- variable |TEX_format_default| to supply the text for default system areas and
- extensions related to format files.
-
- Under \UNIX\ we don't give the area part, instead depending on the path
- searching that will happen during file opening. Also, the length will be set
- in the main program.
-
-*/
-
-char *TEX_format_default;
-
-
-/*tex
-
- This part of the program becomes active when a ``virgin'' \TeX\ is trying to
- get going, just after the preliminary initialization, or when the user is
- substituting another format file by typing `\.\&' after the initial `\.{**}'
- prompt. The buffer contains the first line of input in
- |buffer[loc..(last-1)]|, where |loc<last| and |buffer[loc]<>" "|.
-
-*/
-
-char *open_fmt_file(void)
-{
- /*tex The first space after the format file name: */
- int j;
- char *fmt = NULL;
- int dist;
- j = iloc;
- if (buffer[iloc] == '&') {
- incr(iloc);
- j = iloc;
- buffer[last] = ' ';
- while (buffer[j] != ' ')
- incr(j);
- fmt = xmalloc((unsigned) (j - iloc + 1));
- strncpy(fmt, (char *) (buffer + iloc), (size_t) (j - iloc));
- fmt[j - iloc] = 0;
- dist = (int) (strlen(fmt) - strlen(DUMP_EXT));
- if (!(strstr(fmt, DUMP_EXT) == fmt + dist))
- fmt = concat(fmt, DUMP_EXT);
- if (zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE))
- goto FOUND;
- wake_up_terminal();
- fprintf(stdout, "Sorry, I can't find the format `%s'; will try `%s'.\n",
- fmt, TEX_format_default);
- update_terminal();
- }
- /*tex Now pull out all the stops: try for the system \.{plain} file. */
- fmt = TEX_format_default;
- if (!zopen_w_input(&fmt_file, fmt, DUMP_FORMAT, FOPEN_RBIN_MODE)) {
- wake_up_terminal();
- fprintf(stdout, "I can't find the format file `%s'!\n",
- TEX_format_default);
- return NULL;
- }
- FOUND:
- iloc = j;
- return fmt;
-}
-
-/*tex
-
- The global variable |name_in_progress| is used to prevent recursive use of
- |scan_file_name|, since the |begin_name| and other procedures communicate via
- global variables. Recursion would arise only by devious tricks like
- `\.{\\input\\input f}'; such attempts at sabotage must be thwarted.
- Furthermore, |name_in_progress| prevents \.{\\input} from being initiated
- when a font size specification is being scanned.
-
- Another global variable, |job_name|, contains the file name that was first
- \.{\\input} by the user. This name is extended by `\.{.log}' and `\.{.dvi}'
- and `\.{.fmt}' in the names of \TeX's output files.
-
-*/
-
-/*tex is a file name being scanned? */
-
-boolean name_in_progress;
-
-/*tex principal file name */
-
-str_number job_name;
-
-/*tex has the transcript file been opened? */
-
-boolean log_opened_global;
-
-/*tex
-
- Initially |job_name=0|; it becomes nonzero as soon as the true name is known.
- We have |job_name=0| if and only if the `\.{log}' file has not been opened,
- except of course for a short time just after |job_name| has become nonzero.
-
-*/
-
-/*tex full name of the log file */
-
-unsigned char *texmf_log_name;
-
-/*tex
-
- The |open_log_file| routine is used to open the transcript file and to help
- it catch up to what has previously been printed on the terminal.
-
-*/
-
-void open_log_file(void)
-{
- /*tex previous |selector| setting */
- int old_setting;
- /*tex index into |buffer| */
- int k;
- /*tex end of first input line */
- int l;
- char *fn;
- old_setting = selector;
- if (job_name == 0)
- job_name = getjobname(maketexstring("texput"));
- fn = pack_job_name(".fls");
- recorder_change_filename(fn);
- fn = pack_job_name(".log");
- while (!lua_a_open_out(&log_file, fn, 0)) {
- /*tex
-
- Try to get a different log file name. Sometimes |open_log_file| is
- called at awkward moments when \TeX\ is unable to print error
- messages or even to |show_context|. The |prompt_file_name| routine
- can result in a |fatal_error|, but the |error| routine will not be
- invoked because |log_opened| will be false.
-
- The normal idea of |batch_mode| is that nothing at all should be
- written on the terminal. However, in the unusual case that no log
- file could be opened, we make an exception and allow an explanatory
- message to be seen.
-
- Incidentally, the program always refers to the log file as a
- `\.{transcript file}', because some systems cannot use the extension
- `\.{.log}' for this file.
- */
- selector = term_only;
- fn = prompt_file_name("transcript file name", ".log");
- }
- texmf_log_name = (unsigned char *) xstrdup(fn);
- selector = log_only;
- log_opened_global = true;
- if (callback_defined(start_run_callback) == 0) {
- /*tex Print the banner line, including current date and time. */
- log_banner(luatex_version_string);
- /*tex Make sure bottom level is in memory. */
- input_stack[input_ptr] = cur_input;
- tprint_nl("**");
- /*tex The last position of first line. */
- l = input_stack[0].limit_field;
- if (buffer[l] == end_line_char_par) {
- /*tex maybe also handle multichar endlinechar */
- decr(l);
- }
- for (k = 1; k <= l; k++) {
- print_char(buffer[k]);
- }
- /*tex now the transcript file contains the first line of input */
- print_ln();
- }
- /*tex should be done always */
- flush_loggable_info();
- /*tex should be done always */
- selector = old_setting + 2;
-}
-
-/*tex
-
- This function is needed by synctex to make its log appear in the right spot
- when |output_directory| is set.
-
-*/
-
-char *get_full_log_name (void)
-{
- if (output_directory) {
- char *ret = xmalloc(strlen((char *)texmf_log_name)+2+strlen(output_directory));
- ret = strcpy(ret, output_directory);
- strcat(ret, "/");
- strcat(ret, (char *)texmf_log_name);
- return ret;
- } else {
- return xstrdup((const char*)texmf_log_name);
- }
-}
-
-/*tex Synctex uses this to get the anchored path of an input file. */
-
-char *luatex_synctex_get_current_name (void)
-{
- char *pwdbuf = NULL, *ret;
- if (kpse_absolute_p(fullnameoffile, false)) {
- return xstrdup(fullnameoffile);
- }
- pwdbuf = xgetcwd();
- ret = concat3(pwdbuf, DIR_SEP_STRING, fullnameoffile);
- free(pwdbuf) ;
- return ret;
-}
-
-/*tex
-
- Let's turn now to the procedure that is used to initiate file reading when an
- `\.{\\input}' command is being processed.
-
-*/
-
-void start_input(void)
-{
- str_number temp_str;
- char *fn;
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
-
- back_input();
- if (cur_cmd != left_brace_cmd) {
- /*tex Set |cur_name| to desired file name. */
- scan_file_name();
- } else {
- scan_file_name_toks();
- }
- fn = pack_file_name(cur_name, cur_area, cur_ext);
- while (1) {
- /*tex Set up |cur_file| and new level of input. */
- begin_file_reading();
- if (lua_a_open_in(&cur_file, fn, 0)) {
- break;
- }
- /*tex Remove the level that didn't work. */
- end_file_reading();
- fn = prompt_file_name("input file name", "");
- }
- iname = maketexstring(fullnameoffile);
- /*tex
-
- Now that we have |fullnameoffile|, it is time to post-adjust |cur_name|
- and |cur_ext| for trailing |.tex|.
-
- */
- {
- char *n, *p;
- n = p = fullnameoffile + strlen(fullnameoffile);
- while (p>fullnameoffile) {
- p--;
- if (IS_DIR_SEP(*p)) {
- break;
- }
- }
- if (IS_DIR_SEP(*p)) {
- p++;
- }
- while (n>fullnameoffile) {
- n--;
- if (*n == '.') {
- break;
- }
- }
- if (n>p) {
- int q = *n;
- cur_ext = maketexstring(n);
- *n = 0;
- cur_name = maketexstring(p);
- *n = q;
- }
- }
- source_filename_stack[in_open] = iname;
- full_source_filename_stack[in_open] = xstrdup(fullnameoffile);
- /*tex We can try to conserve string pool space now. */
- temp_str = search_string(iname);
- if (temp_str > 0) {
- flush_str(iname);
- iname = temp_str;
- }
- if (job_name == 0) {
- job_name = getjobname(cur_name);
- open_log_file();
- }
- /*tex
-
- |open_log_file| doesn't |show_context|, so |limit| and |loc| needn't be
- set to meaningful values yet.
-
- */
- report_start_file(filetype_tex,fullnameoffile);
- incr(open_parens);
- update_terminal();
- istate = new_line;
- /*tex Prepare new file {\sl Sync\TeX} information. */
- if (! synctex_get_no_files()) {
- /*tex Give control to the {\sl Sync\TeX} controller. */
- synctexstartinput();
- }
- /*tex
-
- Read the first line of the new file. Here we have to remember to tell the
- |lua_input_ln| routine not to start with a |get|. If the file is empty,
- it is considered to contain a single blank line.
-
- */
- line = 1;
- if (lua_input_ln(cur_file, 0, false)) {
- ;
- }
- firm_up_the_line();
- if (end_line_char_inactive)
- decr(ilimit);
- else
- buffer[ilimit] = (packed_ASCII_code) end_line_char_par;
- first = ilimit + 1;
- iloc = istart;
-}
-
-/*tex
-
- Because the format is zipped we read and write dump files through zlib.
- Earlier versions recast |*f| from |FILE *| to |gzFile|, but there is no
- guarantee that these have the same size, so a static variable is needed.
-
-*/
-
-static gzFile gz_fmtfile = NULL;
-
-/*tex
-
- As distributed, the dump files are architecture dependent; specifically,
- BigEndian and LittleEndian architectures produce different files. These
- routines always output BigEndian files. This still does not guarantee them to
- be architecture-independent, because it is possible to make a format that
- dumps a glue ratio, i.e., a floating-point number. Fortunately, none of the
- standard formats do that.
-
-*/
-
-#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
-
-/*tex
-
- This macro is always invoked as a statement. It assumes a variable `temp'.
-
-*/
-
-# define SWAP(x, y) do { temp = x; x = y; y = temp; } while (0)
-
-/*tex
-
- Make the NITEMS items pointed at by P, each of size SIZE, be the
- opposite-endianness of whatever they are now.
-
-*/
-
-static void swap_items(char *pp, int nitems, int size)
-{
- char temp;
- unsigned total = (unsigned) (nitems * size);
- char *q = xmalloc(total);
- char *p = q;
- memcpy(p,pp,total);
- /*tex
-
- Since `size' does not change, we can write a while loop for each case,
- and avoid testing `size' for each time.
-
- */
- switch (size) {
- case 16:
- /*tex
-
- 16-byte items happen on the DEC Alpha machine when we are not doing
- sharable memory dumps.
-
- */
- while (nitems--) {
- SWAP(p[0], p[15]);
- SWAP(p[1], p[14]);
- SWAP(p[2], p[13]);
- SWAP(p[3], p[12]);
- SWAP(p[4], p[11]);
- SWAP(p[5], p[10]);
- SWAP(p[6], p[9]);
- SWAP(p[7], p[8]);
- p += size;
- }
- break;
-
- case 12:
- while (nitems--) {
- SWAP(p[0], p[11]);
- SWAP(p[1], p[10]);
- SWAP(p[2], p[9]);
- SWAP(p[3], p[8]);
- SWAP(p[4], p[7]);
- SWAP(p[5], p[6]);
- p += size;
- }
- break;
-
- case 8:
- while (nitems--) {
- SWAP(p[0], p[7]);
- SWAP(p[1], p[6]);
- SWAP(p[2], p[5]);
- SWAP(p[3], p[4]);
- p += size;
- }
- break;
-
- case 4:
- while (nitems--) {
- SWAP(p[0], p[3]);
- SWAP(p[1], p[2]);
- p += size;
- }
- break;
-
- case 2:
- while (nitems--) {
- SWAP(p[0], p[1]);
- p += size;
- }
- break;
- case 1:
- /*tex Nothing to do. */
- break;
- default:
- FATAL1("Can't swap a %d-byte item for (un)dumping", size);
- }
- memcpy(pp,q,total);
- xfree(q);
-}
-#endif
-
-/*tex
-
- That second swap is to make sure following calls don't get confused in the
- case of |dump_things|.
-
-*/
-
-void do_zdump(char *p, int item_size, int nitems, FILE * out_file)
-{
- int err;
- (void) out_file;
- if (nitems == 0)
- return;
-#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
- swap_items(p, nitems, item_size);
-#endif
- if (gzwrite(gz_fmtfile, (void *) p, (unsigned) (item_size * nitems)) !=
- item_size * nitems) {
- fprintf(stderr, "! Could not write %d %d-byte item(s): %s.\n", nitems, item_size, gzerror(gz_fmtfile, &err));
- uexit(1);
- }
-#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
- swap_items(p, nitems, item_size);
-#endif
-}
-
-void do_zundump(char *p, int item_size, int nitems, FILE * in_file)
-{
- int err;
- (void) in_file;
- if (nitems == 0)
- return;
- if (gzread(gz_fmtfile, (void *) p, (unsigned) (item_size * nitems)) <= 0) {
- fprintf(stderr, "Could not undump %d %d-byte item(s): %s.\n", nitems, item_size, gzerror(gz_fmtfile, &err));
- uexit(1);
- }
-#if !defined (WORDS_BIGENDIAN) && !defined (NO_DUMP_SHARE)
- swap_items(p, nitems, item_size);
-#endif
-}
-
-/*tex
-
- Tests has shown that a level 3 compression is the most optimal tradeoff
- between file size and load time.
-
-*/
-
-#define COMPRESSION "R3"
-
-boolean zopen_w_input(FILE ** f, const char *fname, int format, const_string fopen_mode)
-{
- int callbackid;
- int res;
- char *fnam;
- callbackid = callback_defined(find_format_file_callback);
- if (callbackid > 0) {
- res = run_callback(callbackid, "S->R", fname, &fnam);
- if (res && fnam && strlen(fnam) > 0) {
- *f = fopen(fnam, fopen_mode);
- if (*f == NULL) {
- return 0;
- }
- } else {
- return 0;
- }
- } else {
- res = luatex_open_input(f, fname, format, fopen_mode, true);
- }
- if (res) {
- gz_fmtfile = gzdopen(fileno(*f), "rb" COMPRESSION);
- }
- return res;
-}
-
-boolean zopen_w_output(FILE ** f, const char *s, const_string fopen_mode)
-{
- int res = 1;
- if (luainit) {
- *f = fopen(s, fopen_mode);
- if (*f == NULL) {
- return 0;
- }
- } else {
- res = luatex_open_output(f, s, fopen_mode);
- }
- if (res) {
- gz_fmtfile = gzdopen(fileno(*f), "wb" COMPRESSION);
- }
- return res;
-}
-
-void zwclose(FILE * f)
-{
- (void) f;
- gzclose(gz_fmtfile);
-}
-
-/*tex Create the \DVI\ or \PDF\ file. */
-
-int open_outfile(FILE ** f, const char *name, const char *mode)
-{
- FILE *res;
- res = fopen(name, mode);
- if (res != NULL) {
- *f = res;
- return 1;
- }
- return 0;
-}
-
-/*tex The caller should set |tfm_buffer=NULL| and |tfm_size=0|. */
-
-int readbinfile(FILE * f, unsigned char **tfm_buffer, int *tfm_size)
-{
- void *buf;
- int size;
- if (fseek(f, 0, SEEK_END) == 0) {
- size = (int) ftell(f);
- if (size > 0) {
- buf = xmalloc((unsigned) size);
- if (fseek(f, 0, SEEK_SET) == 0) {
- if (fread((void *) buf, (size_t) size, 1, f) == 1) {
- *tfm_buffer = (unsigned char *) buf;
- *tfm_size = size;
- return 1;
- }
- }
- } else {
- *tfm_buffer = NULL;
- *tfm_size = 0;
- return 1;
- }
- }
- /*tex Either seek failed or we have a zero-sized file. */
- return 0;
-}
-
-/*tex
-
- Like |os.execute()|, the |runpopen()| function is called only when
- |shellenabledp == 1|. Unlike |os.execute()| we write errors to stderr, since
- we have nowhere better to use; and of course we return a file handle (or
- NULL) instead of a status indicator.
-
-*/
-
-static FILE *runpopen(char *cmd, const char *mode)
-{
- FILE *f = NULL;
- char *safecmd = NULL;
- char *cmdname = NULL;
- int allow;
-#ifdef WIN32
- char *pp;
-
- for (pp = cmd; *pp; pp++) {
- if (*pp == '\'') *pp = '"';
- }
-#endif
- /*tex If |restrictedshell| is zero, any command is allowed. */
- if (restrictedshell == 0) {
- allow = 1;
- } else {
- const char *thecmd = cmd;
- allow = shell_cmd_is_allowed(thecmd, &safecmd, &cmdname);
- }
- if (allow == 1)
- f = popen(cmd, mode);
- else if (allow == 2)
- f = popen(safecmd, mode);
- else if (allow == -1)
- fprintf(stderr, "\nrunpopen quotation error in command line: %s\n", cmd);
- else
- fprintf(stderr, "\nrunpopen command not allowed: %s\n", cmdname);
- if (safecmd)
- free(safecmd);
- if (cmdname)
- free(cmdname);
- return f;
-}
-
-/*tex
-
- The code that implements |popen()| needs an array for tracking possible pipe
- file pointers, because these need to be closed using |pclose()|.
-
-*/
-
-#define NUM_PIPES 16
-static FILE *pipes[NUM_PIPES];
-
-#ifdef WIN32
-FILE *Poptr;
-#endif
-
-boolean open_in_or_pipe(FILE ** f_ptr, char *fn, int filefmt, const_string fopen_mode, boolean must_exist)
-{
- string fname = NULL;
- int i;
- /*tex
-
- Opening a read pipe is straightforward, only have to skip past the pipe
- symbol in the file name. filename quoting is assumed to happen elsewhere
- (it does :-))
-
- */
- if (shellenabledp && *fn == '|') {
- /*tex The user requested a pipe. */
- *f_ptr = NULL;
- fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
- strcpy(fname, fn);
- if (fullnameoffile)
- free(fullnameoffile);
- fullnameoffile = xstrdup(fname);
- recorder_record_input(fname + 1);
- *f_ptr = runpopen(fname + 1, "r");
- free(fname);
- for (i = 0; i < NUM_PIPES; i++) {
- if (pipes[i] == NULL) {
- pipes[i] = *f_ptr;
- break;
- }
- }
- if (*f_ptr)
- setvbuf(*f_ptr, (char *) NULL, _IONBF, 0);
-#ifdef WIN32
- Poptr = *f_ptr;
-#endif
- return *f_ptr != NULL;
- }
- return luatex_open_input(f_ptr, fn, filefmt, fopen_mode, must_exist);
-}
-
-
-boolean open_out_or_pipe(FILE ** f_ptr, char *fn, const_string fopen_mode)
-{
- string fname;
- int i;
- /*tex
-
- Opening a write pipe takes a little bit more work, because TeX will
- perhaps have appended ".tex". To avoid user confusion as much as
- possible, this extension is stripped only when the command is a bare
- word. Some small string trickery is needed to make sure the correct
- number of bytes is free()-d afterwards.
- */
- if (shellenabledp && *fn == '|') {
- /*tex The user requested a pipe. */
- fname = (string) xmalloc((unsigned) (strlen(fn) + 1));
- strcpy(fname, fn);
- if (strchr(fname, ' ') == NULL && strchr(fname, '>') == NULL) {
- /*tex
-
- \METAPOST\ and \METAFIONT\ currently do not use this code, but it
- is better to be prepared. Hm, what has this todo with \LUATEX ?
-
- */
- if (STREQ((fname + strlen(fname) - 3), "tex"))
- *(fname + strlen(fname) - 4) = 0;
- *f_ptr = runpopen(fname + 1, "w");
- *(fname + strlen(fname)) = '.';
- } else {
- *f_ptr = runpopen(fname + 1, "w");
- }
- recorder_record_output(fname + 1);
- free(fname);
- for (i = 0; i < NUM_PIPES; i++) {
- if (pipes[i] == NULL) {
- pipes[i] = *f_ptr;
- break;
- }
- }
- if (*f_ptr)
- setvbuf(*f_ptr, (char *) NULL, _IONBF, 0);
- return *f_ptr != NULL;
- }
- return luatex_open_output(f_ptr, fn, fopen_mode);
-}
-
-
-void close_file_or_pipe(FILE * f)
-{
- int i;
- if (shellenabledp) {
- for (i = 0; i <= 15; i++) {
- /*tex If this file was a pipe, |pclose()| it and return. */
- if (pipes[i] == f) {
- if (f) {
- pclose(f);
-#ifdef WIN32
- Poptr = NULL;
-#endif
- }
- pipes[i] = NULL;
- return;
- }
- }
- }
- close_file(f);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texfileio.h b/Build/source/texk/web2c/luatexdir/tex/texfileio.h
deleted file mode 100644
index c6366500766..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texfileio.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* texfileio.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef TEXFILEIO_H
-# define TEXFILEIO_H
-
-extern int *input_file_callback_id;
-extern int read_file_callback_id[17];
-
-extern char *luatex_find_read_file(const char *s, int n, int callback_index);
-extern boolean luatex_open_input(FILE ** f_ptr, const char *fn, int filefmt,
- const_string fopen_mode, boolean must_exist);
-extern boolean luatex_open_output(FILE ** f_ptr, const char *fn,
- const_string fopen_mode);
-
-extern boolean lua_a_open_in(alpha_file * f, char *fn, int n);
-extern boolean lua_a_open_out(alpha_file * f, char *fn, int n);
-extern boolean lua_b_open_out(alpha_file * f, char *fn);
-extern void lua_a_close_in(alpha_file f, int n);
-extern void lua_a_close_out(alpha_file f);
-
-extern packed_ASCII_code *buffer;
-extern int first;
-extern int last;
-extern int max_buf_stack;
-
-extern boolean lua_input_ln(alpha_file f, int n, boolean bypass_eoln);
-
-/*
-The user's terminal acts essentially like other files of text, except
-that it is used both for input and for output. When the terminal is
-considered an input file, the file variable is called |term_in|, and when it
-is considered an output file the file variable is |term_out|.
-@^system dependencies@>
-*/
-
-# define term_in stdin /* the terminal as an input file */
-# define term_out stdout /* the terminal as an output file */
-
-
-/*
-Here is how to open the terminal files. |t_open_out| does nothing.
-|t_open_in|, on the other hand, does the work of ``rescanning,'' or getting
-any command line arguments the user has provided. It's defined in C.
-*/
-
-# define t_open_out() /* output already open for text output */
-
-/*
-Sometimes it is necessary to synchronize the input/output mixture that
-happens on the user's terminal, and three system-dependent
-procedures are used for this
-purpose. The first of these, |update_terminal|, is called when we want
-to make sure that everything we have output to the terminal so far has
-actually left the computer's internal buffers and been sent.
-The second, |clear_terminal|, is called when we wish to cancel any
-input that the user may have typed ahead (since we are about to
-issue an unexpected error message). The third, |wake_up_terminal|,
-is supposed to revive the terminal if the user has disabled it by
-some instruction to the operating system. The following macros show how
-these operations can be specified with {\mc UNIX}. |update_terminal|
-does an |fflush|. |clear_terminal| is redefined
-to do nothing, since the user should control the terminal.
-@^system dependencies@>
-*/
-
-# define update_terminal() fflush (term_out)
-# define clear_terminal() do { ; } while (0)
-# define wake_up_terminal() do { ; } while (0) /* cancel the user's cancellation of output */
-
-extern boolean init_terminal(void);
-extern void term_input(void);
-
-extern str_number cur_name;
-extern str_number cur_area;
-extern str_number cur_ext;
-extern pool_pointer area_delimiter;
-extern pool_pointer ext_delimiter;
-
-extern char *pack_file_name(str_number n, str_number a, str_number e);
-
-# define file_name_size 512
-
-# define format_area_length 0 /* length of its area part */
-# define format_ext_length 4 /* length of its `\.{.fmt}' part */
-# define format_extension ".fmt"
- /* the extension, as a constant */
-
-extern char *TEX_format_default;
-
-extern char *open_fmt_file(void);
-
-extern boolean name_in_progress; /* is a file name being scanned? */
-extern str_number job_name; /* principal file name */
-extern boolean log_opened_global; /* has the transcript file been opened? */
-
-extern unsigned char *texmf_log_name; /* full name of the log file */
-
-extern void open_log_file(void);
-extern char *get_full_log_name (void);
-extern void start_input(void);
-
-extern int open_outfile(FILE ** f, const char *name, const char *mode);
-
-extern boolean zopen_w_input(FILE **, const char *, int,
- const_string fopen_mode);
-extern boolean zopen_w_output(FILE **, const char *, const_string fopen_mode);
-extern void zwclose(FILE *);
-
-# define read_tfm_file readbinfile
-# define read_vf_file readbinfile
-# define read_data_file readbinfile
-
-extern boolean openinnameok(const_string);
-extern boolean openoutnameok(const_string);
-
-# ifdef WIN32
-extern FILE *Poptr;
-# endif
-
-extern boolean open_in_or_pipe(FILE **, char *, int, const_string fopen_mode,
- boolean must_exist);
-extern boolean open_out_or_pipe(FILE **, char *, const_string fopen_mode);
-extern void close_file_or_pipe(FILE *);
-
-extern char *luatex_synctex_get_current_name(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.c b/Build/source/texk/web2c/luatexdir/tex/texmath.c
deleted file mode 100644
index 4d2bf80ecd6..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texmath.c
+++ /dev/null
@@ -1,2727 +0,0 @@
-/*
-
-Copyright 2008-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-#define mode mode_par
-#define tail tail_par
-#define head head_par
-#define dir_save dirs_par
-
-/*tex
-
- Concerning display skips, \TEX\ normally always inserts before and only after
- when larger than zero. THis can ow be controlled with |\mathdisplayskipmode|:
-
- \starttabulate
- \NC 0 \NC normal \TEX \NC \NR
- \NC 1 \NC always \NC \NR
- \NC 2 \NC non-zero \NC \NR
- \NC 3 \NC ignore \NC \NR
- \stoptabulate
-
-*/
-
-#define back_error(A,B) do { \
- OK_to_interrupt=false; \
- back_input(); \
- OK_to_interrupt=true; \
- tex_error(A,B); \
- } while (0)
-
-int scan_math(pointer, int);
-int scan_math_style(pointer, int);
-pointer fin_mlist(pointer);
-
-/*tex
-
- When \TeX\ reads a formula that is enclosed between \.\$'s, it constructs an
- {\sl mlist}, which is essentially a tree structure representing that formula.
- An mlist is a linear sequence of items, but we can regard it as a tree
- structure because mlists can appear within mlists. For example, many of the
- entries can be subscripted or superscripted, and such ``scripts'' are mlists
- in their own right.
-
- An entire formula is parsed into such a tree before any of the actual
- typesetting is done, because the current style of type is usually not known
- until the formula has been fully scanned. For example, when the formula
- `\.{\$a+b \\over c+d\$}' is being read, there is no way to tell that
- `\.{a+b}' will be in script size until `\.{\\over}' has appeared.
-
- During the scanning process, each element of the mlist being built is
- classified as a relation, a binary operator, an open parenthesis, etc., or as
- a construct like `\.{\\sqrt}' that must be built up. This classification
- appears in the mlist data structure.
-
- After a formula has been fully scanned, the mlist is converted to an hlist so
- that it can be incorporated into the surrounding text. This conversion is
- controlled by a recursive procedure that decides all of the appropriate
- styles by a ``top-down'' process starting at the outermost level and working
- in towards the subformulas. The formula is ultimately pasted together using
- combinations of horizontal and vertical boxes, with glue and penalty nodes
- inserted as necessary.
-
- An mlist is represented internally as a linked list consisting chiefly of
- ``noads'' (pronounced ``no-adds''), to distinguish them from the somewhat
- similar ``nodes'' in hlists and vlists. Certain kinds of ordinary nodes are
- allowed to appear in mlists together with the noads; \TeX\ tells the
- difference by means of the |type| field, since a noad's |type| is always
- greater than that of a node. An mlist does not contain character nodes, hlist
- nodes, vlist nodes, math nodes or unset nodes; in particular, each mlist item
- appears in the variable-size part of |mem|, so the |type| field is always
- present.
-
- Each noad is five or more words long. The first word contains the |type| and
- |subtype| and |link| fields that are already so familiar to us; the second
- contains the attribute list pointer, and the third, fourth an fifth words are
- called the noad's |nucleus|, |subscr|, and |supscr| fields. (This use of a
- combined attribute list is temporary. Eventually, each of fields need their
- own list)
-
- Consider, for example, the simple formula `\.{\$x\^2\$}', which would be
- parsed into an mlist containing a single element called an |ord_noad|. The
- |nucleus| of this noad is a representation of `\.x', the |subscr| is empty,
- and the |supscr| is a representation of `\.2'.
-
- The |nucleus|, |subscr|, and |supscr| fields are further broken into
- subfields. If |p| points to a noad, and if |q| is one of its principal fields
- (e.g., |q=subscr(p)|), |q=null| indicates a field with no value (the
- corresponding attribute of noad |p| is not present). Otherwise, there are
- several possibilities for the subfields, depending on the |type| of |q|.
-
- \startitemize
-
- \startitem
- |type(q)=math_char_node| means that |math_fam(q)| refers to one of
- the sixteen font families, and |character(q)| is the number of a
- character within a font of that family, as in a character node.
- \stopitem
-
- \startitem
- |type(q)=math_text_char_node| is similar, but the character is
- unsubscripted and unsuperscripted and it is followed immediately by
- another character from the same font. (This |type| setting appears
- only briefly during the processing; it is used to suppress unwanted
- italic corrections.)
- \stopitem
-
- \startitem
- |type(q)=sub_box_node| means that |math_list(q)| points to a box node
- (either an |hlist_node| or a |vlist_node|) that should be used as the
- value of the field. The |shift_amount| in the subsidiary box node is
- the amount by which that box will be shifted downward.
- \stopitem
-
- \startitem
- |type(q)=sub_mlist_node| means that |math_list(q)| points to an
- mlist; the mlist must be converted to an hlist in order to obtain the
- value of this field.
- \stopitem
-
- \startitem
- In the latter case, we might have |math_list(q)=null|. This is not
- the same as |q=null|; for example, `\.{\$P\_\{\}\$}' and `\.{\$P\$}'
- produce different results (the former will not have the ``italic
- correction'' added to the width of |P|, but the ``script skip'' will
- be added).
- \stopitem
-
- \startitemize
-
-*/
-
-static void unsave_math(void)
-{
- unsave();
- decr(save_ptr);
- flush_node_list(text_dir_ptr);
- assert(saved_type(0) == saved_textdir);
- text_dir_ptr = saved_value(0);
-}
-
-/*tex
-
- Sometimes it is necessary to destroy an mlist. The following subroutine
- empties the current list, assuming that |abs(mode)=mmode|.
-
-*/
-
-void flush_math(void)
-{
- flush_node_list(vlink(head));
- flush_node_list(incompleat_noad_par);
- vlink(head) = null;
- tail = head;
- incompleat_noad_par = null;
-}
-
-/*tex Before we can do anything in math mode, we need fonts. */
-
-#define MATHFONTSTACK 8
-#define MATHFONTDEFAULT 0
-
-static sa_tree math_fam_head = NULL;
-
-int fam_fnt(int fam_id, int size_id)
-{
- int n = fam_id + (256 * size_id);
- return (int) get_sa_item(math_fam_head, n).int_value;
-}
-
-void def_fam_fnt(int fam_id, int size_id, int f, int lvl)
-{
- int n = fam_id + (256 * size_id);
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = f;
- set_sa_item(math_fam_head, n, sa_value, lvl);
- fixup_math_parameters(fam_id, size_id, f, lvl);
- if (tracing_assigns_par > 1) {
- begin_diagnostic();
- tprint("{assigning");
- print_char(' ');
- print_cmd_chr(def_family_cmd, size_id);
- print_int(fam_id);
- print_char('=');
- print_font_identifier(fam_fnt(fam_id, size_id));
- print_char('}');
- end_diagnostic(false);
- }
-}
-
-static void unsave_math_fam_data(int gl)
-{
- sa_stack_item st;
- if (math_fam_head->stack == NULL)
- return;
- while (math_fam_head->stack_ptr > 0 &&
- abs(math_fam_head->stack[math_fam_head->stack_ptr].level)
- >= (int) gl) {
- st = math_fam_head->stack[math_fam_head->stack_ptr];
- if (st.level > 0) {
- rawset_sa_item(math_fam_head, st.code, st.value);
- /*tex Now do a trace message, if requested. */
- if (tracing_restores_par > 1) {
- int size_id = st.code / 256;
- int fam_id = st.code % 256;
- begin_diagnostic();
- tprint("{restoring");
- print_char(' ');
- print_cmd_chr(def_family_cmd, size_id);
- print_int(fam_id);
- print_char('=');
- print_font_identifier(fam_fnt(fam_id, size_id));
- print_char('}');
- end_diagnostic(false);
- }
- }
- (math_fam_head->stack_ptr)--;
- }
-}
-
-/*tex Parameters */
-
-#define MATHPARAMSTACK 8
-#define MATHPARAMDEFAULT undefined_math_parameter
-
-static sa_tree math_param_head = NULL;
-
-void def_math_param(int param_id, int style_id, scaled value, int lvl)
-{
- int n = param_id + (256 * style_id);
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = (int) value;
- set_sa_item(math_param_head, n, sa_value, lvl);
- if (tracing_assigns_par > 1) {
- begin_diagnostic();
- tprint("{assigning");
- print_char(' ');
- print_cmd_chr(set_math_param_cmd, param_id);
- print_cmd_chr(math_style_cmd, style_id);
- print_char('=');
- print_int(value);
- print_char('}');
- end_diagnostic(false);
- }
-}
-
-scaled get_math_param(int param_id, int style_id)
-{
- int n = param_id + (256 * style_id);
- return (scaled) get_sa_item(math_param_head, n).int_value;
-}
-
-static void unsave_math_param_data(int gl)
-{
- sa_stack_item st;
- if (math_param_head->stack == NULL)
- return;
- while (math_param_head->stack_ptr > 0 &&
- abs(math_param_head->stack[math_param_head->stack_ptr].level)
- >= (int) gl) {
- st = math_param_head->stack[math_param_head->stack_ptr];
- if (st.level > 0) {
- rawset_sa_item(math_param_head, st.code, st.value);
- /*tex Do a trace message, if requested. */
- if (tracing_restores_par > 1) {
- int param_id = st.code % 256;
- int style_id = st.code / 256;
- begin_diagnostic();
- tprint("{restoring");
- print_char(' ');
- print_cmd_chr(set_math_param_cmd, param_id);
- print_cmd_chr(math_style_cmd, style_id);
- print_char('=');
- print_int(get_math_param(param_id, style_id));
- print_char('}');
- end_diagnostic(false);
- }
- }
- (math_param_head->stack_ptr)--;
- }
-}
-
-/*tex Saving and unsaving of both: */
-
-void unsave_math_data(int gl)
-{
- unsave_math_fam_data(gl);
- unsave_math_param_data(gl);
-}
-
-/*tex Dumping and undumping: */
-
-void dump_math_data(void)
-{
- sa_tree_item sa_value = { 0 };
- if (math_fam_head == NULL) {
- sa_value.int_value = MATHFONTDEFAULT;
- math_fam_head = new_sa_tree(MATHFONTSTACK, 1, sa_value);
- }
- dump_sa_tree(math_fam_head, "mathfonts");
- if (math_param_head == NULL) {
- sa_value.int_value = MATHPARAMDEFAULT;
- math_param_head = new_sa_tree(MATHPARAMSTACK, 1, sa_value);
- }
- dump_sa_tree(math_param_head, "mathparameters");
-}
-
-void undump_math_data(void)
-{
- math_fam_head = undump_sa_tree("mathfonts");
- math_param_head = undump_sa_tree("mathparameters");
-}
-
-void initialize_math(void)
-{
- sa_tree_item sa_value = { 0 };
- if (math_fam_head == NULL) {
- sa_value.int_value = MATHFONTDEFAULT;
- math_fam_head = new_sa_tree(MATHFONTSTACK, 1, sa_value);
- }
- if (math_param_head == NULL) {
- sa_value.int_value = MATHPARAMDEFAULT;
- math_param_head = new_sa_tree(MATHPARAMSTACK, 1, sa_value);
- initialize_math_spacing();
- }
- return;
-}
-
-/*tex
-
- Each portion of a formula is classified as Ord, Op, Bin, Rel, Ope, Clo, Pun,
- or Inn, for purposes of spacing and line breaking. An |ord_noad|, |op_noad|,
- |bin_noad|, |rel_noad|, |open_noad|, |close_noad|, |punct_noad|, or
- |inner_noad| is used to represent portions of the various types. For example,
- an `\.=' sign in a formula leads to the creation of a |rel_noad| whose
- |nucleus| field is a representation of an equals sign (usually |fam=0|,
- |character=075|). A formula preceded by \.{\\mathrel} also results in a
- |rel_noad|. When a |rel_noad| is followed by an |op_noad|, say, and possibly
- separated by one or more ordinary nodes (not noads), \TeX\ will insert a
- penalty node (with the current |rel_penalty|) just after the formula that
- corresponds to the |rel_noad|, unless there already was a penalty immediately
- following; and a ``thick space'' will be inserted just before the formula
- that corresponds to the |op_noad|.
-
- A noad of type |ord_noad|, |op_noad|, \dots, |inner_noad| usually has a
- |subtype=normal|. The only exception is that an |op_noad| might have
- |subtype=limits| or |no_limits|, if the normal positioning of limits has been
- overridden for this operator.
-
- A |radical_noad| also has a |left_delimiter| field, which usually represents
- a square root sign.
-
- A |fraction_noad| has a |right_delimiter| field as well as a
- |left_delimiter|.
-
- Delimiter fields have four subfields called |small_fam|, |small_char|,
- |large_fam|, |large_char|. These subfields represent variable-size delimiters
- by giving the ``small'' and ``large'' starting characters, as explained in
- Chapter~17 of {\sl The \TeX book}.
-
- A |fraction_noad| is actually quite different from all other noads. It has
- |thickness|, |denominator|, and |numerator| fields instead of |nucleus|,
- |subscr|, and |supscr|. The |thickness| is a scaled value that tells how
- thick to make a fraction rule; however, the special value |default_code| is
- used to stand for the |default_rule_thickness| of the current size. The
- |numerator| and |denominator| point to mlists that define a fraction; we
- always have $$\hbox{|type(numerator)=type(denominator)=sub_mlist|}.$$ The
- |left_delimiter| and |right_delimiter| fields specify delimiters that will be
- placed at the left and right of the fraction. In this way, a |fraction_noad|
- is able to represent all of \TeX's operators \.{\\over}, \.{\\atop},
- \.{\\above}, \.{\\overwithdelims}, \.{\\atopwithdelims}, and
- \.{\\abovewithdelims}.
-
- The |new_noad| function creates an |ord_noad| that is completely null
-
-*/
-
-pointer new_noad(void)
-{
- pointer p;
- p = new_node(simple_noad, ord_noad_type);
- /*tex All noad fields are zero after this. */
- return p;
-}
-
-pointer new_sub_box(pointer curbox)
-{
- pointer p, q;
- p = new_noad();
- q = new_node(sub_box_node, 0);
- nucleus(p) = q;
- math_list(nucleus(p)) = curbox;
- return p;
-}
-
-/*tex
-
- A few more kinds of noads will complete the set: An |under_noad| has its
- nucleus underlined; an |over_noad| has it overlined. An |accent_noad| places
- an accent over its nucleus; the accent character appears as
- |math_fam(accent_chr(p))| and |math_character(accent_chr(p))|. A
- |vcenter_noad| centers its nucleus vertically with respect to the axis of the
- formula; in such noads we always have |type(nucleus(p))=sub_box|.
-
- And finally, we have the |fence_noad| type, to implement \TeX's \.{\\left}
- and \.{\\right} as well as eTeX's \.{\\middle}. The |nucleus| of such noads
- is replaced by a |delimiter| field; thus, for example, `\.{\\left(}' produces
- a |fence_noad| such that |delimiter(p)| holds the family and character codes
- for all left parentheses. A |fence_noad| of subtype |left_noad_side| never
- appears in an mlist except as the first element, and a |fence_noad| with
- subtype |right_noad_side| never appears in an mlist except as the last
- element; furthermore, we either have both a |left_noad_side| and a
- |right_noad_side|, or neither one is present.
-
- Math formulas can also contain instructions like \.{\\textstyle} that
- override \TeX's normal style rules. A |style_node| is inserted into the data
- structure to record such instructions; it is three words long, so it is
- considered a node instead of a noad. The |subtype| is either |display_style|
- or |text_style| or |script_style| or |script_script_style|. The second and
- third words of a |style_node| are not used, but they are present because a
- |choice_node| is converted to a |style_node|.
-
- \TeX\ uses even numbers 0, 2, 4, 6 to encode the basic styles
- |display_style|, \dots, |script_script_style|, and adds~1 to get the
- ``cramped'' versions of these styles. This gives a numerical order that is
- backwards from the convention of Appendix~G in {\sl The \TeX book\/}; i.e., a
- smaller style has a larger numerical value.
-
-*/
-
-const char *math_style_names[] = {
- "display", "crampeddisplay",
- "text", "crampedtext",
- "script", "crampedscript",
- "scriptscript", "crampedscriptscript",
- NULL
-};
-
-const char *math_param_names[] = {
- "quad", "axis", "operatorsize",
- "overbarkern", "overbarrule", "overbarvgap",
- "underbarkern", "underbarrule", "underbarvgap",
- "radicalkern", "radicalrule", "radicalvgap",
- "radicaldegreebefore", "radicaldegreeafter", "radicaldegreeraise",
- "stackvgap", "stacknumup", "stackdenomdown",
- "fractionrule", "fractionnumvgap", "fractionnumup",
- "fractiondenomvgap", "fractiondenomdown", "fractiondelsize",
- "skewedfractionhgap", "skewedfractionvgap",
- "limitabovevgap", "limitabovebgap", "limitabovekern",
- "limitbelowvgap", "limitbelowbgap", "limitbelowkern",
- "nolimitsubfactor", "nolimitsupfactor", /* bonus */
- "underdelimitervgap", "underdelimiterbgap",
- "overdelimitervgap", "overdelimiterbgap",
- "subshiftdrop", "supshiftdrop", "subshiftdown",
- "subsupshiftdown", "subtopmax", "supshiftup",
- "supbottommin", "supsubbottommax", "subsupvgap",
- "spaceafterscript", "connectoroverlapmin",
- "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing",
- "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing",
- "opordspacing", "opopspacing", "opbinspacing", "oprelspacing",
- "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing",
- "binordspacing", "binopspacing", "binbinspacing", "binrelspacing",
- "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing",
- "relordspacing", "relopspacing", "relbinspacing", "relrelspacing",
- "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing",
- "openordspacing", "openopspacing", "openbinspacing", "openrelspacing",
- "openopenspacing", "openclosespacing", "openpunctspacing",
- "openinnerspacing",
- "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing",
- "closeopenspacing", "closeclosespacing", "closepunctspacing",
- "closeinnerspacing",
- "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing",
- "punctopenspacing", "punctclosespacing", "punctpunctspacing",
- "punctinnerspacing",
- "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing",
- "inneropenspacing", "innerclosespacing", "innerpunctspacing",
- "innerinnerspacing",
- NULL
-};
-
-pointer new_style(small_number s)
-{
- m_style = s;
- return new_node(style_node, s);
-}
-
-/*tex
-
- Finally, the \.{\\mathchoice} primitive creates a |choice_node|, which has
- special subfields |display_mlist|, |text_mlist|, |script_mlist|, and
- |script_script_mlist| pointing to the mlists for each style.
-
-*/
-
-static pointer new_choice(void)
-{
- return new_node(choice_node, 0);
-}
-
-/*tex
-
- Let's consider now the previously unwritten part of |show_node_list| that
- displays the things that can only be present in mlists; this program
- illustrates how to access the data structures just defined.
-
- In the context of the following program, |p| points to a node or noad that
- should be displayed, and the current string contains the ``recursion
- history'' that leads to this point. The recursion history consists of a dot
- for each outer level in which |p| is subsidiary to some node, or in which |p|
- is subsidiary to the |nucleus| field of some noad; the dot is replaced by
- `\.\_' or `\.\^' or `\./' or `\.\\' if |p| is descended from the |subscr| or
- |supscr| or |denominator| or |numerator| fields of noads. For example, the
- current string would be `\.{.\^.\_/}' if |p| points to the |ord_noad| for |x|
- in the (ridiculous) formula `\.{\$\\sqrt\{a\^\{\\mathinner\{b\_\{c\\over
- x+y\}\}\}\}\$}'.
-
-*/
-
-void display_normal_noad(pointer p);
-void display_fence_noad(pointer p);
-void display_fraction_noad(pointer p);
-
-void show_math_node(pointer p)
-{
- switch (type(p)) {
- case style_node:
- print_cmd_chr(math_style_cmd, subtype(p));
- break;
- case choice_node:
- tprint_esc("mathchoice");
- append_char('D');
- show_node_list(display_mlist(p));
- flush_char();
- append_char('T');
- show_node_list(text_mlist(p));
- flush_char();
- append_char('S');
- show_node_list(script_mlist(p));
- flush_char();
- append_char('s');
- show_node_list(script_script_mlist(p));
- flush_char();
- break;
- case simple_noad:
- case radical_noad:
- case accent_noad:
- display_normal_noad(p);
- break;
- case fence_noad:
- display_fence_noad(p);
- break;
- case fraction_noad:
- display_fraction_noad(p);
- break;
- default:
- tprint("Unknown node type!");
- break;
- }
-}
-
-/*tex Here are some simple routines used in the display of noads. */
-
-static void print_fam_and_char(pointer p)
-{
- tprint_esc("fam");
- print_int(math_fam(p));
- print_char(' ');
- print(math_character(p));
-}
-
-static void print_delimiter(pointer p)
-{
- int a;
- if (delimiteroptionset(p)) {
- tprint(" [ ");
- if (delimiteraxis(p))
- tprint("axis ");
- if (delimiternoaxis(p))
- tprint("noaxis ");
- if (delimiterexact(p))
- tprint("exact ");
- tprint("]");
- }
- if (delimiterheight(p)) {
- tprint("height=");
- print_scaled(delimiterheight(p));
- tprint(" ");
- }
- if (delimiterdepth(p)) {
- tprint("depth=");
- print_scaled(delimiterdepth(p));
- tprint(" ");
- }
- if (delimiterclass(p)) {
- tprint("class=");
- print_int(delimiterclass(p));
- tprint(" ");
- }
- if (small_fam(p) < 0) {
- /*tex This should never happen. */
- print_int(-1);
- } else if (small_fam(p) < 16 && large_fam(p) < 16 && small_char(p) < 256 && large_char(p) < 256) {
- /*tex Traditional tex style. */
- a = small_fam(p) * 256 + small_char(p);
- a = a * 0x1000 + large_fam(p) * 256 + large_char(p);
- print_qhex(a);
- } else if ((large_fam(p) == 0 && large_char(p) == 0) || small_char(p) > 65535 || large_char(p) > 65535) {
- /*tex \LUATEX\ style. */
- print_qhex(small_fam(p));
- print_qhex(small_char(p));
- }
-}
-
-/*tex
-
- The next subroutine will descend to another level of recursion when a
- subsidiary mlist needs to be displayed. The parameter |c| indicates what
- character is to become part of the recursion history. An empty mlist is
- distinguished from a missing field, because these are not equivalent (as
- explained above).
-
-*/
-
-static void print_subsidiary_data(pointer p, ASCII_code c)
-{
- if ((int) cur_length >= depth_threshold) {
- if (p != null)
- tprint(" []");
- } else {
- /*tex Include |c| in the recursion history. */
- append_char(c);
- if (p != null) {
- switch (type(p)) {
- case math_char_node:
- print_ln();
- print_current_string();
- print_fam_and_char(p);
- break;
- case sub_box_node:
- show_node_list(math_list(p));
- break;
- case sub_mlist_node:
- if (math_list(p) == null) {
- print_ln();
- print_current_string();
- tprint("{}");
- } else {
- show_node_list(math_list(p));
- }
- break;
- }
- }
- /*tex Remove |c| from the recursion history. */
- flush_char();
- }
-}
-
-void display_normal_noad(pointer p)
-{
- switch (type(p)) {
- case simple_noad:
- switch (subtype(p)) {
- case ord_noad_type:
- tprint_esc("mathord");
- break;
- case op_noad_type_normal:
- case op_noad_type_limits:
- case op_noad_type_no_limits:
- tprint_esc("mathop");
- if (subtype(p) == op_noad_type_limits)
- tprint_esc("limits");
- else if (subtype(p) == op_noad_type_no_limits)
- tprint_esc("nolimits");
- break;
- case bin_noad_type:
- tprint_esc("mathbin");
- break;
- case rel_noad_type:
- tprint_esc("mathrel");
- break;
- case open_noad_type:
- tprint_esc("mathopen");
- break;
- case close_noad_type:
- tprint_esc("mathclose");
- break;
- case punct_noad_type:
- tprint_esc("mathpunct");
- break;
- case inner_noad_type:
- tprint_esc("mathinner");
- break;
- case over_noad_type:
- tprint_esc("overline");
- break;
- case under_noad_type:
- tprint_esc("underline");
- break;
- case vcenter_noad_type:
- tprint_esc("vcenter");
- break;
- default:
- tprint("<unknown noad type!>");
- break;
- }
- break;
- case radical_noad:
- if (subtype(p) == 7)
- tprint_esc("Uhextensible");
- else if (subtype(p) == 6)
- tprint_esc("Udelimiterover");
- else if (subtype(p) == 5)
- tprint_esc("Udelimiterunder");
- else if (subtype(p) == 4)
- tprint_esc("Uoverdelimiter");
- else if (subtype(p) == 3)
- tprint_esc("Uunderdelimiter");
- else if (subtype(p) == 2)
- tprint_esc("Uroot");
- else
- tprint_esc("radical");
- print_delimiter(left_delimiter(p));
- if (degree(p) != null) {
- print_subsidiary_data(degree(p), '/');
- }
- if (radicalwidth(p)) {
- tprint("width=");
- print_scaled(radicalwidth(p));
- tprint(" ");
- }
- if (radicaloptionset(p)) {
- tprint(" [ ");
- if (radicalexact(p))
- tprint("exact ");
- if (radicalleft(p))
- tprint("left ");
- if (radicalmiddle(p))
- tprint("middle ");
- if (radicalright(p))
- tprint("right ");
- tprint("]");
- }
- break;
- case accent_noad:
- if (top_accent_chr(p) != null) {
- if (bot_accent_chr(p) != null) {
- tprint_esc("Umathaccent both");
- } else {
- tprint_esc("Umathaccent");
- }
- } else if (bot_accent_chr(p) != null) {
- tprint_esc("Umathaccent bottom");
- } else {
- tprint_esc("Umathaccent overlay");
- }
- if (accentfraction(p)) {
- tprint(" fraction=");
- print_int(accentfraction(p));
- tprint(" ");
- }
- switch (subtype(p)) {
- case 0:
- if (top_accent_chr(p) != null) {
- if (bot_accent_chr(p) != null) {
- print_fam_and_char(top_accent_chr(p));
- print_fam_and_char(bot_accent_chr(p));
- } else {
- print_fam_and_char(top_accent_chr(p));
- }
- } else if (bot_accent_chr(p) != null) {
- print_fam_and_char(bot_accent_chr(p));
- } else {
- print_fam_and_char(overlay_accent_chr(p));
- }
- break;
- case 1:
- if (top_accent_chr(p) != null) {
- tprint(" fixed ");
- print_fam_and_char(top_accent_chr(p));
- if (bot_accent_chr(p) != null) {
- print_fam_and_char(bot_accent_chr(p));
- }
- } else {
- confusion("display_accent_noad");
- }
- break;
- case 2:
- if (bot_accent_chr(p) != null) {
- if (top_accent_chr(p) != null) {
- print_fam_and_char(top_accent_chr(p));
- }
- tprint(" fixed ");
- print_fam_and_char(bot_accent_chr(p));
- } else{
- confusion("display_accent_noad");
- }
- break;
- case 3:
- if (top_accent_chr(p) != null && bot_accent_chr(p) != null) {
- tprint(" fixed ");
- print_fam_and_char(top_accent_chr(p));
- tprint(" fixed ");
- print_fam_and_char(bot_accent_chr(p));
- } else {
- confusion("display_accent_noad");
- }
- break;
- }
- break;
- }
- print_subsidiary_data(nucleus(p), '.');
- print_subsidiary_data(supscr(p), '^');
- print_subsidiary_data(subscr(p), '_');
-}
-
-void display_fence_noad(pointer p)
-{
- if (subtype(p) == right_noad_side)
- tprint_esc("right");
- else if (subtype(p) == left_noad_side)
- tprint_esc("left");
- else
- tprint_esc("middle");
- print_delimiter(delimiter(p));
-}
-
-void display_fraction_noad(pointer p)
-{
- tprint_esc("fraction, thickness ");
- if (thickness(p) == default_code)
- tprint("= default");
- else
- print_scaled(thickness(p));
- if ((left_delimiter(p) != null) &&
- ((small_fam(left_delimiter(p)) != 0) || (small_char(left_delimiter(p)) != 0) ||
- (large_fam(left_delimiter(p)) != 0) || (large_char(left_delimiter(p)) != 0))) {
- tprint(", left-delimiter ");
- print_delimiter(left_delimiter(p));
- }
- if ((right_delimiter(p) != null) &&
- ((small_fam(right_delimiter(p)) != 0) || (small_char(right_delimiter(p)) != 0) ||
- (large_fam(right_delimiter(p)) != 0) || (large_char(right_delimiter(p)) != 0))) {
- tprint(", right-delimiter ");
- print_delimiter(right_delimiter(p));
- }
- print_subsidiary_data(numerator(p), '\\');
- print_subsidiary_data(denominator(p), '/');
-}
-
-/*tex
-
- The routines that \TeX\ uses to create mlists are similar to those we have
- just seen for the generation of hlists and vlists. But it is necessary to
- make ``noads'' as well as nodes, so the reader should review the discussion
- of math mode data structures before trying to make sense out of the following
- program.
-
- Here is a little routine that needs to be done whenever a subformula is about
- to be processed. The parameter is a code like |math_group|.
-
-*/
-
-static void new_save_level_math(group_code c)
-{
- set_saved_record(0, saved_textdir, 0, text_dir_ptr);
- text_dir_ptr = new_dir(math_direction_par);
- incr(save_ptr);
- new_save_level(c);
- eq_word_define(int_base + body_direction_code, math_direction_par);
- eq_word_define(int_base + par_direction_code, math_direction_par);
- eq_word_define(int_base + text_direction_code, math_direction_par);
-}
-
-static void push_math(group_code c, int mstyle)
-{
- if (math_direction_par != text_direction_par)
- dir_math_save = true;
- push_nest();
- mode = -mmode;
- incompleat_noad_par = null;
- m_style = mstyle;
- new_save_level_math(c);
-}
-
-static void enter_ordinary_math(void)
-{
- push_math(math_shift_group, text_style);
- eq_word_define(int_base + cur_fam_code, -1);
- if (every_math_par != null)
- begin_token_list(every_math_par, every_math_text);
-}
-
-void enter_display_math(void);
-
-/*tex
-
- We get into math mode from horizontal mode when a `\.\$' (i.e., a
- |math_shift| character) is scanned. We must check to see whether this `\.\$'
- is immediately followed by another, in case display math mode is called for.
-
-*/
-
-void init_math(void)
-{
- if (cur_cmd == math_shift_cmd) {
- /*tex |get_x_token| would fail on \.{\\ifmmode}\thinspace! */
- get_token();
- if ((cur_cmd == math_shift_cmd) && (mode > 0)) {
- enter_display_math();
- } else {
- back_input();
- enter_ordinary_math();
- }
- } else if (cur_cmd == math_shift_cs_cmd && cur_chr == display_style && (mode > 0)) {
- enter_display_math();
- } else if (cur_cmd == math_shift_cs_cmd && cur_chr == text_style) {
- enter_ordinary_math();
- } else {
- you_cant();
- }
-}
-
-/*tex
-
- We get into ordinary math mode from display math mode when `\.{\\eqno}' or
- `\.{\\leqno}' appears. In such cases |cur_chr| will be 0 or~1, respectively;
- the value of |cur_chr| is placed onto |save_stack| for safe keeping.
-
- When \TeX\ is in display math mode, |cur_group=math_shift_group|, so it is
- not necessary for the |start_eq_no| procedure to test for this condition.
-
-*/
-
-void start_eq_no(void)
-{
- set_saved_record(0, saved_eqno, 0, cur_chr);
- incr(save_ptr);
- enter_ordinary_math();
-}
-
-/*tex
-
- Subformulas of math formulas cause a new level of math mode to be entered, on
- the semantic nest as well as the save stack. These subformulas arise in
- several ways: (1)~A left brace by itself indicates the beginning of a
- subformula that will be put into a box, thereby freezing its glue and
- preventing line breaks. (2)~A subscript or superscript is treated as a
- subformula if it is not a single character; the same applies to the nucleus
- of things like \.{\\underline}. (3)~The \.{\\left} primitive initiates a
- subformula that will be terminated by a matching \.{\\right}. The group codes
- placed on |save_stack| in these three cases are |math_group|, |math_group|,
- and |math_left_group|, respectively.
-
- Here is the code that handles case (1); the other cases are not quite as
- trivial, so we shall consider them later.
-
-*/
-
-void math_left_brace(void)
-{
- pointer q;
- tail_append(new_noad());
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- back_input();
- (void) scan_math(nucleus(tail), m_style);
-}
-
-/*tex
-
- If the inline directions of \.{\\pardir} and \.{\\mathdir} are opposite, then
- this function will return true. Discovering that fact is somewhat odd because
- it needs traversal of the |save_stack|. The occurance of displayed equations
- is weird enough that this is probably still better than having yet another
- field in the |input_stack| structures.
-
- None of this makes much sense if the inline direction of either one of
- \.{\\pardir} or \.{\\mathdir} is vertical, but in that case the current math
- machinery is ill suited anyway so I do not bother to test that.
-
-*/
-
-static boolean math_and_text_reversed_p(void)
-{
- int i = save_ptr - 1;
- while (save_type(i) != level_boundary)
- i--;
- while (i < save_ptr) {
- if (save_type(i) == restore_old_value &&
- save_value(i) == int_base + par_direction_code) {
- if (textdir_opposite(math_direction_par, save_value(i - 1)))
- return true;
- }
- i++;
- }
- return false;
-}
-
-/*tex
-
- When we enter display math mode, we need to call |line_break| to process the
- partial paragraph that has just been interrupted by the display. Then we can
- set the proper values of |display_width| and |display_indent| and
- |pre_display_size|.
-
-*/
-
-void enter_display_math(void)
-{
- /*tex new or partial |pre_display_size| */
- scaled w;
- /*tex new |display_width| */
- scaled l;
- /*tex new |display_indent| */
- scaled s;
- pointer p;
- /*tex scope of paragraph shape specification */
- int n;
- /*tex
-
- `\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}' or the 2nd of \.{\$\${ }\$\$}
- \.{\$\${ }\$\$}
-
- */
- if (head == tail ||
- (vlink(head) == tail &&
- type(tail) == local_par_node && vlink(tail) == null)) {
- if (vlink(head) == tail) {
- /*tex
-
- |resume_after_display| inserts a |local_par_node|, but if there
- is another display immediately following, we have to get rid of
- that node.
-
- */
- flush_node(tail);
- }
- pop_nest();
- w = -max_dimen;
- } else {
- line_break(true, math_shift_group);
- w = actual_box_width(just_box, x_over_n(quad(get_cur_font()),1000) * math_pre_display_gap_factor_par);
- }
- /*tex
-
- Now we are in vertical mode, working on the list that will contain the
- display. A displayed equation is considered to be three lines long, so we
- calculate the length and offset of line number |prev_graf+2|.
-
- */
- if (par_shape_par_ptr == null) {
- if ((hang_indent_par != 0) && (((hang_after_par >= 0) && (prev_graf_par + 2 > hang_after_par)) || (prev_graf_par + 1 < -hang_after_par))) {
- halfword used_hang_indent = swap_hang_indent(hang_indent_par);
- l = hsize_par - abs(used_hang_indent);
- if (used_hang_indent > 0)
- s = used_hang_indent;
- else
- s = 0;
- } else {
- l = hsize_par;
- s = 0;
- }
- } else {
- n = vinfo(par_shape_par_ptr + 1);
- if (prev_graf_par + 2 >= n)
- p = par_shape_par_ptr + 2 * n + 1;
- else
- p = par_shape_par_ptr + 2 * (prev_graf_par + 2) + 1;
- s = varmem[(p - 1)].cint;
- l = varmem[p].cint;
- s = swap_parshape_indent(s,l);
- }
- push_math(math_shift_group, display_style);
- mode = mmode;
- eq_word_define(int_base + cur_fam_code, -1);
- eq_word_define(dimen_base + pre_display_size_code, w);
- eq_word_define(dimen_base + display_width_code, l);
- eq_word_define(dimen_base + display_indent_code, s);
- eq_word_define(int_base + pre_display_direction_code, (math_and_text_reversed_p() ? -1 : 0));
- if (every_display_par != null)
- begin_token_list(every_display_par, every_display_text);
- if (nest_ptr == 1) {
- checked_page_filter(before_display);
- build_page();
- }
-}
-
-/*tex
-
- The next routine parses all variations of a delimiter code. The |extcode|
- tells what syntax form to use (\TeX, XeTeX, XeTeXnum, ...) , the |doclass|
- tells whether or not read a math class also (for \.{\\delimiter} c.s.). (the
- class is passed on for conversion to \.{\\mathchar}).
-
-*/
-
-static delcodeval do_scan_extdef_del_code(int extcode, boolean doclass)
-{
- const char *hlp[] = {
- "I'm going to use 0 instead of that illegal code value.",
- NULL
- };
- delcodeval d;
- int mcls = 0, msfam = 0, mschr = 0, mlfam = 0, mlchr = 0;
- if (extcode == tex_mathcode) {
- /*tex
-
- \.{\\delcode}, this is the easiest
-
- */
- scan_int();
- /*tex "MFCCFCC or "FCCFCC */
- if (doclass) {
- mcls = (cur_val / 0x1000000);
- cur_val = (cur_val & 0xFFFFFF);
- }
- if (cur_val > 0xFFFFFF) {
- tex_error("Invalid delimiter code", hlp);
- cur_val = 0;
- }
- msfam = (cur_val / 0x100000);
- mschr = (cur_val % 0x100000) / 0x1000;
- mlfam = (cur_val & 0xFFF) / 0x100;
- mlchr = (cur_val % 0x100);
- } else if (extcode == umath_mathcode) {
- /*tex
-
- \.{\\Udelcode}: <0-7>,<0-0xFF>,<0-0x10FFFF> or <0-0xFF>,<0-0x10FFFF>
-
- */
- if (doclass) {
- scan_int();
- mcls = cur_val;
- }
- scan_int();
- msfam = cur_val;
- scan_char_num();
- mschr = cur_val;
- if (msfam < 0 || msfam > 255) {
- tex_error("Invalid delimiter code", hlp);
- msfam = 0;
- mschr = 0;
- }
- mlfam = 0;
- mlchr = 0;
- } else if (extcode == umathnum_mathcode) {
- /*tex
-
- \.{\\Udelcodenum}:"FF<21bits>; the largest numeric value is $2^29-1$,
- but the top of bit 21 can't be used as it contains invalid USV's.
-
- */
- if (doclass) { /* such a primitive doesn't exist */
- confusion("umathnum_mathcode");
- }
- scan_int();
- msfam = (cur_val / 0x200000);
- mschr = cur_val & 0x1FFFFF;
- if (msfam < 0 || msfam > 255 || mschr > 0x10FFFF) {
- tex_error("Invalid delimiter code", hlp);
- msfam = 0;
- mschr = 0;
- }
- mlfam = 0;
- mlchr = 0;
- } else {
- /*tex Something's gone wrong! */
- confusion("unknown_extcode");
- }
- d.class_value = mcls;
- d.small_family_value = msfam;
- d.small_character_value = mschr;
- d.large_family_value = mlfam;
- d.large_character_value = mlchr;
- return d;
-}
-
-void scan_extdef_del_code(int level, int extcode)
-{
- delcodeval d;
- int p;
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- d = do_scan_extdef_del_code(extcode, false);
- set_del_code(p, d.small_family_value, d.small_character_value,
- d.large_family_value, d.large_character_value, (quarterword) (level));
-}
-
-mathcodeval scan_mathchar(int extcode)
-{
- char errstr[255] = { 0 };
- const char *hlp[] = {
- "I'm going to use 0 instead of that illegal code value.",
- NULL
- };
- mathcodeval d;
- int mcls = 0, mfam = 0, mchr = 0;
- if (extcode == tex_mathcode) {
- /*tex \.{\\mathcode}: "TFCC */
- scan_int();
- if (cur_val > 0x8000) {
- /*tex Needed for latex: fallback to umathnum_mathcode. */
- mfam = (cur_val / 0x200000) & 0x7FF;
- mcls = mfam % 0x08;
- mfam = mfam / 0x08;
- mchr = cur_val & 0x1FFFFF;
- if (mchr > 0x10FFFF) {
- tex_error("Invalid math code during > 0x8000 mathcode fallback", hlp);
- mcls = 0;
- mfam = 0;
- mchr = 0;
- }
- } else {
- if (cur_val < 0) {
- snprintf(errstr, 255, "Bad mathchar (%d)", (int)cur_val);
- tex_error(errstr, hlp);
- cur_val = 0;
- }
- mcls = (cur_val / 0x1000);
- mfam = ((cur_val % 0x1000) / 0x100);
- mchr = (cur_val % 0x100);
- }
- } else if (extcode == umath_mathcode) {
- /*tex <0-0x7> <0-0xFF> <0-0x10FFFF> */
- scan_int();
- mcls = cur_val;
- scan_int();
- mfam = cur_val;
- scan_char_num();
- mchr = cur_val;
- if (mcls < 0 || mcls > 7 || mfam > 255) {
- tex_error("Invalid math code", hlp);
- mchr = 0;
- mfam = 0;
- mcls = 0;
- }
- } else if (extcode == umathnum_mathcode) {
- /*tex
-
- "FFT<21bits>: the largest numeric value is $2^32-1$, but the top of
- bit 21 can't be used as it contains invalid USV's
-
- Note: |scan_int| won't accept families 128-255 because these use bit 32
-
- */
- scan_int();
- mfam = (cur_val / 0x200000) & 0x7FF;
- mcls = mfam % 0x08;
- mfam = mfam / 0x08;
- mchr = cur_val & 0x1FFFFF;
- if (mchr > 0x10FFFF) {
- tex_error("Invalid math code", hlp);
- mcls = 0;
- mfam = 0;
- mchr = 0;
- }
- } else {
- /*tex Something's gone wrong. */
- confusion("unknown_extcode");
- }
- d.class_value = mcls;
- d.family_value = mfam;
- d.character_value = mchr;
- return d;
-}
-
-void scan_extdef_math_code(int level, int extcode)
-{
- mathcodeval d;
- int p;
- scan_char_num();
- p = cur_val;
- scan_optional_equals();
- d = scan_mathchar(extcode);
- set_math_code(p, d.class_value, d.family_value, d.character_value, (quarterword) (level));
-}
-
-/*tex This reads in a delcode when actually a mathcode is needed. */
-
-mathcodeval scan_delimiter_as_mathchar(int extcode)
-{
- delcodeval dval;
- mathcodeval mval;
- dval = do_scan_extdef_del_code(extcode, true);
- mval.class_value = dval.class_value;
- mval.family_value = dval.small_family_value;
- mval.character_value = dval.small_character_value;
- return mval;
-}
-
-/*tex
-
- Recall that the |nucleus|, |subscr|, and |supscr| fields in a noad are broken
- down into subfields called |type| and either |math_list| or
- |(math_fam,math_character)|. The job of |scan_math| is to figure out what to
- place in one of these principal fields; it looks at the subformula that comes
- next in the input, and places an encoding of that subformula into a given
- word of |mem|.
-
-*/
-
-#define get_next_nb_nr() do { get_x_token(); } while (cur_cmd==spacer_cmd||cur_cmd==relax_cmd)
-
-int scan_math_style(pointer p, int mstyle)
-{
- get_next_nb_nr();
- back_input();
- scan_left_brace();
- set_saved_record(0, saved_math, 0, p);
- incr(save_ptr);
- push_math(math_group, mstyle);
- return 1;
-}
-
-int scan_math(pointer p, int mstyle)
-{
- mathcodeval mval = { 0, 0, 0 };
- assert(p != null);
- RESTART:
- get_next_nb_nr();
- RESWITCH:
- switch (cur_cmd) {
- case letter_cmd:
- case other_char_cmd:
- case char_given_cmd:
- mval = get_math_code(cur_chr);
- if (mval.class_value == 8) {
- /*tex An active character that is an |outer_call| is allowed here. */
- cur_cs = active_to_cs(cur_chr, true);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- x_token();
- back_input();
- goto RESTART;
- }
- break;
- case char_num_cmd:
- scan_char_num();
- cur_chr = cur_val;
- cur_cmd = char_given_cmd;
- goto RESWITCH;
- break;
- case math_char_num_cmd:
- if (cur_chr == 0)
- mval = scan_mathchar(tex_mathcode);
- else if (cur_chr == 1)
- mval = scan_mathchar(umath_mathcode);
- else if (cur_chr == 2)
- mval = scan_mathchar(umathnum_mathcode);
- else
- confusion("scan_math");
- break;
- case math_given_cmd:
- mval = mathchar_from_integer(cur_chr, tex_mathcode);
- break;
- case xmath_given_cmd:
- mval = mathchar_from_integer(cur_chr, umath_mathcode);
- break;
- case delim_num_cmd:
- if (cur_chr == 0)
- mval = scan_delimiter_as_mathchar(tex_mathcode);
- else if (cur_chr == 1)
- mval = scan_delimiter_as_mathchar(umath_mathcode);
- else
- confusion("scan_math");
- break;
- default:
- /*tex
-
- The pointer |p| is placed on |save_stack| while a complex subformula
- is being scanned.
-
- */
- back_input();
- scan_left_brace();
- set_saved_record(0, saved_math, 0, p);
- incr(save_ptr);
- push_math(math_group, mstyle);
- return 1;
- }
- type(p) = math_char_node;
- math_character(p) = mval.character_value;
- if ((mval.class_value == math_use_current_family_code) && cur_fam_par_in_range)
- math_fam(p) = cur_fam_par;
- else
- math_fam(p) = mval.family_value;
- return 0;
-}
-
-/*tex
-
- The |set_math_char| procedure creates a new noad appropriate to a given math
- code, and appends it to the current mlist. However, if the math code is
- sufficiently large, the |cur_chr| is treated as an active character and
- nothing is appended.
-
-*/
-
-#define math_class_to_type(target,source) \
- switch (source) { \
- case 0: target = ord_noad_type; break; \
- case 1: target = op_noad_type_normal; break; \
- case 2: target = bin_noad_type; break; \
- case 3: target = rel_noad_type; break; \
- case 4: target = open_noad_type; break; \
- case 5: target = close_noad_type; break; \
- case 6: target = punct_noad_type; break; \
- }
-
-void set_math_char(mathcodeval mval)
-{
- pointer p;
- if (mval.class_value == 8) {
- /*tex An active character that is an |outer_call| is allowed here */
- cur_cs = active_to_cs(cur_chr, true);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- x_token();
- back_input();
- } else {
- pointer q;
- p = new_noad();
- q = new_node(math_char_node, 0);
- nucleus(p) = q;
- math_character(nucleus(p)) = mval.character_value;
- math_fam(nucleus(p)) = mval.family_value;
- if (mval.class_value == math_use_current_family_code) {
- if (cur_fam_par_in_range)
- math_fam(nucleus(p)) = cur_fam_par;
- subtype(p) = ord_noad_type;
- } else {
- math_class_to_type(subtype(p),mval.class_value);
- }
- tail_append(p);
- }
-}
-
-/*tex
-
- The |math_char_in_text| procedure creates a new node representing a math char
- in text code, and appends it to the current list. However, if the math code
- is sufficiently large, the |cur_chr| is treated as an active character and
- nothing is appended.
-
-*/
-
-void math_char_in_text(mathcodeval mval)
-{
- pointer p;
- if (mval.class_value == 8) {
- /*tex An active character that is an |outer_call| is allowed here */
- cur_cs = active_to_cs(cur_chr, true);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- x_token();
- back_input();
- } else {
- p = new_char(fam_fnt(mval.family_value, text_size), mval.character_value);
- tail_append(p);
- }
-}
-
-void math_math_comp(void)
-{
- pointer q;
- tail_append(new_noad());
- subtype(tail) = (quarterword) cur_chr;
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- if (cur_chr == over_noad_type)
- (void) scan_math(nucleus(tail), cramped_style(m_style));
- else
- (void) scan_math(nucleus(tail), m_style);
-}
-
-void math_limit_switch(void)
-{
- const char *hlp[] = {
- "I'm ignoring this misplaced \\limits or \\nolimits command.",
- NULL
- };
- if (head != tail) {
- if (type(tail) == simple_noad &&
- (subtype(tail) == op_noad_type_normal ||
- subtype(tail) == op_noad_type_limits ||
- subtype(tail) == op_noad_type_no_limits)) {
- subtype(tail) = (quarterword) cur_chr;
- return;
- }
- }
- tex_error("Limit controls must follow a math operator", hlp);
-}
-
-/*tex
-
- Delimiter fields of noads are filled in by the |scan_delimiter| routine. The
- first parameter of this procedure is the |mem| address where the delimiter
- is to be placed; the second tells if this delimiter follows \.{\\radical} or
- not.
-
-*/
-
-static void scan_delimiter(pointer p, int r)
-{
- delcodeval dval = { 0, 0, 0, 0, 0 };
- if (r == tex_mathcode) {
- /*tex \.{\\radical} */
- dval = do_scan_extdef_del_code(tex_mathcode, true);
- } else if (r == umath_mathcode) {
- /*tex \.{\\Uradical} */
- dval = do_scan_extdef_del_code(umath_mathcode, false);
- } else if (r == no_mathcode) {
- get_next_nb_nr();
- switch (cur_cmd) {
- case letter_cmd:
- case other_char_cmd:
- dval = get_del_code(cur_chr);
- break;
- case delim_num_cmd:
- if (cur_chr == 0) {
- /*tex \.{\\delimiter} */
- dval = do_scan_extdef_del_code(tex_mathcode, true);
- } else if (cur_chr == 1) {
- /*tex \.{\\Udelimiter} */
- dval = do_scan_extdef_del_code(umath_mathcode, true);
- } else {
- confusion("scan_delimiter1");
- }
- break;
- default:
- dval.small_family_value = -1;
- break;
- }
- } else {
- confusion("scan_delimiter2");
- }
- if (p == null)
- return;
- if (dval.small_family_value < 0) {
- const char *hlp[] = {
- "I was expecting to see something like `(' or `\\{' or",
- "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
- "should probably delete the `{' by typing `1' now, so that",
- "braces don't get unbalanced. Otherwise just proceed",
- "Acceptable delimiters are characters whose \\delcode is",
- "nonnegative, or you can use `\\delimiter <delimiter code>'.",
- NULL
- };
- back_error("Missing delimiter (. inserted)", hlp);
- small_fam(p) = 0;
- small_char(p) = 0;
- large_fam(p) = 0;
- large_char(p) = 0;
- } else {
- small_fam(p) = dval.small_family_value;
- small_char(p) = dval.small_character_value;
- large_fam(p) = dval.large_family_value;
- large_char(p) = dval.large_character_value;
- }
- return;
-}
-
-void math_radical(void)
-{
- halfword q;
- int chr_code = cur_chr;
- halfword options = 0;
- tail_append(new_node(radical_noad, chr_code));
- q = new_node(delim_node, 0);
- left_delimiter(tail) = q;
- while (1) {
- if (scan_keyword("width")) {
- scan_dimen(false,false,false);
- radicalwidth(tail) = cur_val ;
- } else if (scan_keyword("left")) {
- options = options | noad_option_left ;
- } else if (scan_keyword("middle")) {
- options = options | noad_option_middle ;
- } else if (scan_keyword("right")) {
- options = options | noad_option_right ;
- } else {
- break;
- }
- }
- radicaloptions(tail) = options;
- if (chr_code == 0)
- /*tex \.{\\radical} */
- scan_delimiter(left_delimiter(tail), tex_mathcode);
- else if (chr_code == 1)
- /*tex \.{\\Uradical} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 2)
- /*tex \.{\\Uroot} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 3)
- /*tex \.{\\Uunderdelimiter} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 4)
- /*tex \.{\\Uoverdelimiter} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 5)
- /*tex \.{\\Udelimiterunder} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 6)
- /*tex \.{\\Udelimiterover} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else if (chr_code == 7)
- /*tex \.{\\Uhextensible} */
- scan_delimiter(left_delimiter(tail), umath_mathcode);
- else
- confusion("math_radical");
- if (chr_code == 7) {
- /*tex type will change */
- q = new_node(sub_box_node, 0);
- nucleus(tail) = q;
- return;
- } else if (chr_code == 2) {
- /*tex
-
- The trick with the |vlink(q)| is used by |scan_math| to decide
- whether it needs to go on.
-
- */
- q = new_node(math_char_node, 0);
- vlink(q) = tail;
- degree(tail) = q;
- if (!scan_math(degree(tail), sup_sup_style(m_style))) {
- vlink(degree(tail)) = null;
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- (void) scan_math(nucleus(tail), cramped_style(m_style));
- }
- } else {
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- (void) scan_math(nucleus(tail), cramped_style(m_style));
- }
-}
-
-void math_ac(void)
-{
- halfword q;
- mathcodeval t = { 0, 0, 0 };
- mathcodeval b = { 0, 0, 0 };
- mathcodeval o = { 0, 0, 0 };
- if (cur_cmd == accent_cmd) {
- const char *hlp[] = {
- "I'm changing \\accent to \\mathaccent here; wish me luck.",
- "(Accents are not the same in formulas as they are in text.)",
- NULL
- };
- tex_error("Please use \\mathaccent for accents in math mode", hlp);
- }
- tail_append(new_node(accent_noad, 0));
- if (cur_chr == 0) {
- /*tex \.{\\mathaccent} */
- t = scan_mathchar(tex_mathcode);
- } else if (cur_chr == 1) {
- /*tex \.{\\Umathaccent} */
- if (scan_keyword("fixed")) {
- /*tex top */
- subtype(tail) = 1;
- t = scan_mathchar(umath_mathcode);
- } else if (scan_keyword("both")) {
- /*tex top bottom */
- if (scan_keyword("fixed")) {
- subtype(tail) = 1;
- }
- t = scan_mathchar(umath_mathcode);
- if (scan_keyword("fixed")) {
- subtype(tail) += 2;
- }
- b = scan_mathchar(umath_mathcode);
- } else if (scan_keyword("bottom")) {
- /*tex bottom */
- if (scan_keyword("fixed")) {
- subtype(tail) = 2;
- }
- b = scan_mathchar(umath_mathcode);
- } else if (scan_keyword("top")) {
- /*tex top */
- if (scan_keyword("fixed")) {
- subtype(tail) = 1;
- }
- t = scan_mathchar(umath_mathcode);
- } else if (scan_keyword("overlay")) {
- /* overlay */
- if (scan_keyword("fixed")) {
- subtype(tail) = 1;
- }
- o = scan_mathchar(umath_mathcode);
- } else {
- /*tex top */
- t = scan_mathchar(umath_mathcode);
- }
- if (scan_keyword("fraction")) {
- scan_int();
- accentfraction(tail) = cur_val;
- }
- } else {
- confusion("mathaccent");
- }
- if (!(t.character_value == 0 && t.family_value == 0)) {
- q = new_node(math_char_node, 0);
- top_accent_chr(tail) = q;
- math_character(top_accent_chr(tail)) = t.character_value;
- if ((t.class_value == math_use_current_family_code) && cur_fam_par_in_range)
- math_fam(top_accent_chr(tail)) = cur_fam_par;
- else
- math_fam(top_accent_chr(tail)) = t.family_value;
- }
- if (!(b.character_value == 0 && b.family_value == 0)) {
- q = new_node(math_char_node, 0);
- bot_accent_chr(tail) = q;
- math_character(bot_accent_chr(tail)) = b.character_value;
- if ((b.class_value == math_use_current_family_code) && cur_fam_par_in_range)
- math_fam(bot_accent_chr(tail)) = cur_fam_par;
- else
- math_fam(bot_accent_chr(tail)) = b.family_value;
- }
- if (!(o.character_value == 0 && o.family_value == 0)) {
- q = new_node(math_char_node, 0);
- overlay_accent_chr(tail) = q;
- math_character(overlay_accent_chr(tail)) = o.character_value;
- if ((o.class_value == math_use_current_family_code) && cur_fam_par_in_range)
- math_fam(overlay_accent_chr(tail)) = cur_fam_par;
- else
- math_fam(overlay_accent_chr(tail)) = o.family_value;
- }
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- (void) scan_math(nucleus(tail), cramped_style(m_style));
-}
-
-pointer math_vcenter_group(pointer p)
-{
- pointer q, r;
- q = new_noad();
- subtype(q) = vcenter_noad_type;
- r = new_node(sub_box_node, 0);
- nucleus(q) = r;
- math_list(nucleus(q)) = p;
- return q;
-}
-
-/*tex
-
- The routine that scans the four mlists of a \.{\\mathchoice} is very much
- like the routine that builds discretionary nodes.
-
-*/
-
-void append_choices(void)
-{
- tail_append(new_choice());
- incr(save_ptr);
- set_saved_record(-1, saved_choices, 0, 0);
- push_math(math_choice_group, display_style);
- scan_left_brace();
-}
-
-void build_choices(void)
-{
- pointer p;
- int prev_style;
- prev_style = m_style;
- unsave_math();
- p = fin_mlist(null);
- assert(saved_type(-1) == saved_choices);
- switch (saved_value(-1)) {
- case 0:
- display_mlist(tail) = p;
- break;
- case 1:
- text_mlist(tail) = p;
- break;
- case 2:
- script_mlist(tail) = p;
- break;
- case 3:
- script_script_mlist(tail) = p;
- decr(save_ptr);
- return;
- break;
- }
- set_saved_record(-1, saved_choices, 0, (saved_value(-1) + 1));
- push_math(math_choice_group, (prev_style + 2));
- scan_left_brace();
-}
-
-/*tex
-
- Subscripts and superscripts are attached to the previous nucleus by the
- action procedure called |sub_sup|.
-
-*/
-
-static void do_sub_sup(int no)
-{
- pointer q;
- if (tail == head || (!scripts_allowed(tail))) {
- tail_append(new_noad());
- q = new_node(sub_mlist_node, 0);
- nucleus(tail) = q;
- }
- if (cur_cmd == sup_mark_cmd || cur_chr == sup_mark_cmd) {
- /*tex |super_sub_script| */
- if (supscr(tail) != null) {
- const char *hlp[] = {
- "I treat `x^1^2' essentially like `x^1{}^2'.", NULL
- };
- tail_append(new_noad());
- q = new_node(sub_mlist_node, 0);
- nucleus(tail) = q;
- tex_error("Double superscript", hlp);
- }
- if (no) {
- noadoptions(tail) = noadoptions(tail) | noad_option_no_super_script ;
- }
- q = new_node(math_char_node, 0);
- supscr(tail) = q;
- (void) scan_math(supscr(tail), sup_style(m_style));
- } else if (cur_cmd == sub_mark_cmd || cur_chr == sub_mark_cmd) {
- if (subscr(tail) != null) {
- const char *hlp[] = {
- "I treat `x_1_2' essentially like `x_1{}_2'.", NULL
- };
- tail_append(new_noad());
- q = new_node(sub_mlist_node, 0);
- nucleus(tail) = q;
- tex_error("Double subscript", hlp);
- }
- if (no) {
- noadoptions(tail) = noadoptions(tail) | noad_option_no_sub_script ;
- }
- q = new_node(math_char_node, 0);
- subscr(tail) = q;
- (void) scan_math(subscr(tail), sub_style(m_style));
- }
-}
-
-void sub_sup(void)
-{
- do_sub_sup(0);
-}
-
-void no_sub_sup(void)
-{
- do_sub_sup(1);
-}
-
-/*tex
-
- An operation like `\.{\\over}' causes the current mlist to go into a state of
- suspended animation: |incompleat_noad| points to a |fraction_noad| that
- contains the mlist-so-far as its numerator, while the denominator is yet to
- come. Finally when the mlist is finished, the denominator will go into the
- incompleat fraction noad, and that noad will become the whole formula, unless
- it is surrounded by `\.{\\left}' and `\.{\\right}' delimiters.
-
-*/
-
-void math_fraction(void)
-{
- /*tex The type of generalized fraction we are scanning: */
- halfword c;
- pointer q;
- halfword options = 0;
- halfword temp_value;
- c = cur_chr;
- if (incompleat_noad_par != null) {
- const char *hlp[] = {
- "I'm ignoring this fraction specification, since I don't",
- "know whether a construction like `x \\over y \\over z'",
- "means `{x \\over y} \\over z' or `x \\over {y \\over z}'.",
- NULL
- };
- if (c >= delimited_code) {
- scan_delimiter(null, no_mathcode);
- scan_delimiter(null, no_mathcode);
- }
- if ((c % delimited_code) == above_code)
- scan_normal_dimen();
- tex_error("Ambiguous; you need another { and }", hlp);
- } else {
- incompleat_noad_par = new_node(fraction_noad, 0);
- temp_value = new_node(sub_mlist_node, 0);
- numerator(incompleat_noad_par) = temp_value;
- math_list(numerator(incompleat_noad_par)) = vlink(head);
- vlink(head) = null;
- tail = head;
- m_style = cramped_style(m_style);
-
- if ((c % delimited_code) == skewed_code) {
- q = new_node(delim_node, 0);
- middle_delimiter(incompleat_noad_par) = q;
- scan_delimiter(middle_delimiter(incompleat_noad_par), no_mathcode);
- }
- if (c >= delimited_code) {
- q = new_node(delim_node, 0);
- left_delimiter(incompleat_noad_par) = q;
- q = new_node(delim_node, 0);
- right_delimiter(incompleat_noad_par) = q;
- scan_delimiter(left_delimiter(incompleat_noad_par), no_mathcode);
- scan_delimiter(right_delimiter(incompleat_noad_par), no_mathcode);
- }
- switch (c % delimited_code) {
- case above_code:
- while (1) {
- if (scan_keyword("exact")) {
- options = options | noad_option_exact ;
- } else if (scan_keyword("norule")) {
- options = options | noad_option_no_rule ;
- } else {
- break;
- }
- }
- fractionoptions(incompleat_noad_par) = options;
- scan_normal_dimen();
- thickness(incompleat_noad_par) = cur_val;
- break;
- case over_code:
- thickness(incompleat_noad_par) = default_code;
- break;
- case atop_code:
- thickness(incompleat_noad_par) = 0;
- break;
- case skewed_code:
- while (1) {
- if (scan_keyword("exact")) {
- options = options | noad_option_exact ;
- } else if (scan_keyword("noaxis")) {
- options = options | noad_option_no_axis ;
- } else {
- break;
- }
- }
- fractionoptions(incompleat_noad_par) = options;
- thickness(incompleat_noad_par) = 0;
- break;
- }
- }
-}
-
-/*tex
-
- At the end of a math formula or subformula, the |fin_mlist| routine is called
- upon to return a pointer to the newly completed mlist, and to pop the nest
- back to the enclosing semantic level. The parameter to |fin_mlist|, if not
- null, points to a |fence_noad| that ends the current mlist; this |fence_noad|
- has not yet been appended.
-
-*/
-
-pointer fin_mlist(pointer p)
-{
- pointer q;
- if (incompleat_noad_par != null) {
- if (denominator(incompleat_noad_par) != null) {
- type(denominator(incompleat_noad_par)) = sub_mlist_node;
- } else {
- q = new_node(sub_mlist_node, 0);
- denominator(incompleat_noad_par) = q;
- }
- math_list(denominator(incompleat_noad_par)) = vlink(head);
- if (p == null) {
- q = incompleat_noad_par;
- } else {
- q = math_list(numerator(incompleat_noad_par));
- if ((type(q) != fence_noad) || (subtype(q) != left_noad_side) || (delim_par == null))
- confusion("right");
- math_list(numerator(incompleat_noad_par)) = vlink(delim_par);
- vlink(delim_par) = incompleat_noad_par;
- vlink(incompleat_noad_par) = p;
- }
- } else {
- vlink(tail) = p;
- q = vlink(head);
- }
- pop_nest();
- return q;
-}
-
-/*tex
-
- Now at last we're ready to see what happens when a right brace occurs in a
- math formula. Two special cases are simplified here: Braces are effectively
- removed when they surround a single Ord without sub/superscripts, or when
- they surround an accent that is the nucleus of an Ord atom.
-
-*/
-
-void close_math_group(pointer p)
-{
- int old_style = m_style;
- unsave_math();
- decr(save_ptr);
- assert(saved_type(0) == saved_math);
- type(saved_value(0)) = sub_mlist_node;
- p = fin_mlist(null);
- math_list(saved_value(0)) = p;
- if (p != null && vlink(p) == null) {
- if (type(p) == simple_noad) {
- if (subscr(p) == null && supscr(p) == null) {
- /*tex (subtype(p) == ord_noad_type) */
- int flatten = 0;
- int modepar = math_flatten_mode_par;
- switch (subtype(p)) {
- case ord_noad_type :
- flatten = (modepar & 1) == 1;
- break;
- case bin_noad_type :
- flatten = (modepar & 2) == 2;
- break;
- case rel_noad_type :
- flatten = (modepar & 4) == 4;
- break;
- case punct_noad_type :
- flatten = (modepar & 8) == 8;
- break;
- case inner_noad_type :
- flatten = (modepar & 16) == 16;
- break;
- default:
- break;
- }
- if (flatten) {
- type(saved_value(0)) = type(nucleus(p));
- if (type(nucleus(p)) == math_char_node) {
- math_fam(saved_value(0)) = math_fam(nucleus(p));
- math_character(saved_value(0)) =
- math_character(nucleus(p));
- } else {
- math_list(saved_value(0)) = math_list(nucleus(p));
- math_list(nucleus(p)) = null;
- }
- delete_attribute_ref(node_attr(saved_value(0)));
- node_attr(saved_value(0)) = node_attr(nucleus(p));
- node_attr(nucleus(p)) = null;
- flush_node(p);
- }
- }
- } else if (type(p) == accent_noad) {
- if (saved_value(0) == nucleus(tail) && type(tail) == simple_noad && subtype(tail) == ord_noad_type) {
- pointer q = head;
- while (vlink(q) != tail)
- q = vlink(q);
- vlink(q) = p;
- nucleus(tail) = null;
- subscr(tail) = null;
- supscr(tail) = null;
- delete_attribute_ref(node_attr(p));
- node_attr(p) = node_attr(tail);
- node_attr(tail) = null;
- flush_node(tail);
- tail = p;
- }
- }
- }
- if (vlink(saved_value(0)) > 0) {
- pointer q;
- q = new_node(math_char_node, 0);
- nucleus(vlink(saved_value(0))) = q;
- vlink(saved_value(0)) = null;
- saved_value(0) = q;
- (void) scan_math(saved_value(0), old_style);
- /*tex restart */
- }
-}
-
-/*tex
-
- We have dealt with all constructions of math mode except `\.{\\left}' and
- `\.{\\right}', so the picture is completed by the following sections of the
- program. The |middle| feature of eTeX allows one ore several \.{\\middle}
- delimiters to appear between \.{\\left} and \.{\\right}.
-
-*/
-
-void math_left_right(void)
-{
- /*tex |left_noad_side| .. |right_noad_side| */
- halfword t;
- /*tex new noad */
- pointer p;
- /*tex resulting mlist */
- pointer q;
- /*tex temporary */
- pointer r;
- halfword ht = 0;
- halfword dp = 0;
- halfword options = 0;
- halfword type = -1 ;
- t = cur_chr;
- if (t > 10) {
- /*tex we have \Uleft \Uright \Umiddle */
- t = t - 10;
- while (1) {
- if (scan_keyword("height")) {
- scan_dimen(false,false,false);
- ht = cur_val ;
- } else if (scan_keyword("depth")) {
- scan_dimen(false,false,false);
- dp = cur_val ;
- } else if (scan_keyword("axis")) {
- options = options | noad_option_axis ;
- } else if (scan_keyword("noaxis")) {
- options = options | noad_option_no_axis ;
- } else if (scan_keyword("exact")) {
- options = options | noad_option_exact ;
- } else if (scan_keyword("class")) {
- scan_int();
- math_class_to_type(type,cur_val);
- } else {
- break;
- }
- }
- }
- if ((t != no_noad_side) && (t != left_noad_side) && (cur_group != math_left_group)) {
- if (cur_group == math_shift_group) {
- scan_delimiter(null, no_mathcode);
- if (t == middle_noad_side) {
- const char *hlp[] = {
- "I'm ignoring a \\middle that had no matching \\left.",
- NULL
- };
- tex_error("Extra \\middle", hlp);
- } else {
- const char *hlp[] = {
- "I'm ignoring a \\right that had no matching \\left.",
- NULL
- };
- tex_error("Extra \\right", hlp);
- }
- } else {
- off_save();
- }
- } else {
- p = new_noad();
- type(p) = fence_noad;
- subtype(p) = (quarterword) t;
- r = new_node(delim_node, 0);
- delimiter(p) = r;
- delimiterheight(p) = ht;
- delimiterdepth(p) = dp;
- delimiteroptions(p) = options;
- delimiterclass(p) = type;
- delimiteritalic(p) = 0;
- delimitersamesize(p) = 0;
- scan_delimiter(delimiter(p), no_mathcode);
- if (t == no_noad_side) {
- tail_append(new_noad());
- subtype(tail) = inner_noad_type;
- r = new_node(sub_mlist_node, 0);
- nucleus(tail) = r;
- math_list(nucleus(tail)) = p;
- return ;
- }
- if (t == left_noad_side) {
- q = p;
- } else {
- q = fin_mlist(p);
- unsave_math();
- }
- if (t != right_noad_side) {
- push_math(math_left_group, m_style);
- vlink(head) = q;
- tail = p;
- delim_par = p;
- } else {
- tail_append(new_noad());
- subtype(tail) = inner_noad_type;
- r = new_node(sub_mlist_node, 0);
- nucleus(tail) = r;
- math_list(nucleus(tail)) = q;
- }
- }
-}
-
-/*tex
-
- \TeX\ gets to the following part of the program when the first `\.\$' ending
- a display has been scanned.
-
-*/
-
-static void check_second_math_shift(void)
-{
- get_x_token();
- if (cur_cmd != math_shift_cmd) {
- const char *hlp[] = {
- "The `$' that I just saw supposedly matches a previous `$$'.",
- "So I shall assume that you typed `$$' both times.",
- NULL
- };
- back_error("Display math should end with $$", hlp);
- }
-}
-
-static void check_display_math_end(void)
-{
- if (cur_chr != cramped_display_style) {
- const char *hlp[] = {
- "I shall assume that you typed that.",
- NULL
- };
- tex_error("Display math should end with \\Ustopdisplaymath", hlp);
- }
-}
-
-static void check_inline_math_end(void)
-{
- if (cur_chr != cramped_text_style) {
- const char *hlp[] = {
- "I shall assume that you typed that.",
- NULL
- };
- tex_error("Inline math should end with \\Ustopmath", hlp);
- }
-}
-
-static void resume_after_display(void)
-{
- if (cur_group != math_shift_group)
- confusion("display");
- unsave_math();
- prev_graf_par = prev_graf_par + 3;
- push_nest();
- mode = hmode;
- space_factor_par = 1000;
- /*tex This needs to be intercepted in the display math start! */
- tail_append(make_local_par_node(penalty_par_code));
- get_x_token();
- if (cur_cmd != spacer_cmd)
- back_input();
- if (nest_ptr == 1) {
- normal_page_filter(after_display);
- build_page();
- }
-}
-
-/*tex
-
- The fussiest part of math mode processing occurs when a displayed formula is
- being centered and placed with an optional equation number.
-
- At this time we are in vertical mode (or internal vertical mode).
-
- \starttabulate
- \NC \type {p} \NC points to the mlist for the formula \NC \NR
- \NC \type {a} \NC is either |null| or it points to a box containing the equation number \NC \NR
- \NC \type {l} \NC is true if there was an \.{\\leqno}/ (so |a| is a horizontal box) \NC \NR
- \stoptabulate
-
-*/
-
-#define inject_display_skip_before(g) \
- if (g > 0) { \
- switch (display_skip_mode_par) { \
- case 0 : \
- /*tex normal tex | always */ \
- case 1 : \
- /*tex always */ \
- tail_append(new_param_glue(g)); \
- break; \
- case 2 : \
- /*tex non-zero */ \
- if (! glue_is_zero(glue_par(g))) \
- tail_append(new_param_glue(g)); \
- break; \
- case 3: \
- /*tex ignore */ \
- break; \
- default: \
- /*tex > 3 reserved for future use */ \
- tail_append(new_param_glue(g)); \
- break; \
- } \
- }
-
-#define inject_display_skip_after(g) \
- if (g > 0) { \
- switch (display_skip_mode_par) { \
- case 0 : \
- /*tex normal tex | always */ \
- case 1 : \
- /*tex always */ \
- tail_append(new_param_glue(g)); \
- break; \
- case 2 : \
- /*tex non-zero */ \
- if (! glue_is_zero(glue_par(g))) \
- tail_append(new_param_glue(g)); \
- break; \
- case 3: \
- /*tex ignore */ \
- break; \
- default: \
- /*tex > 3 reserved for future use */ \
- tail_append(new_param_glue(g)); \
- break; \
- } \
- }
-
-static void finish_displayed_math(boolean l, pointer eqno_box, pointer p)
-{
- /*tex box containing the equation */
- pointer eq_box;
- /*tex width of the equation */
- scaled eq_w;
- /*tex width of the line */
- scaled line_w;
- /*tex width of equation number */
- scaled eqno_w;
- /*tex width of equation number plus space to separate from equation */
- scaled eqno_w2;
- /*tex move the line right this much */
- scaled line_s;
- /*tex displacement of equation in the line */
- scaled d;
- /*tex glue parameter codes for before and after */
- small_number g1, g2;
- /*tex kern nodes used to position the display */
- pointer r,s;
- /*tex tail of adjustment list */
- pointer t;
- /*tex tail of pre-adjustment list */
- pointer pre_t;
- /*tex true if the math and surrounding text dirs are opposed */
- boolean swap_dir;
- scaled eqno_width;
- swap_dir = (pre_display_direction_par < 0 ? true : false );
- if (eqno_box != null && swap_dir)
- l = !l;
- adjust_tail = adjust_head;
- pre_adjust_tail = pre_adjust_head;
- eq_box = hpack(p, 0, additional, -1);
- subtype(eq_box) = equation_list;
- build_attribute_list(eq_box);
- p = list_ptr(eq_box);
- t = adjust_tail;
- adjust_tail = null;
- pre_t = pre_adjust_tail;
- pre_adjust_tail = null;
- eq_w = width(eq_box);
- line_w = display_width_par;
- line_s = display_indent_par;
- if (eqno_box == null) {
- eqno_w = 0;
- eqno_width = 0;
- eqno_w2 = 0;
- } else {
- eqno_w = width(eqno_box);
- eqno_width = eqno_w;
- eqno_w2 = eqno_w + round_xn_over_d(math_eqno_gap_step_par, get_math_quad_style(text_style), 1000);
- subtype(eqno_box) = equation_number_list;
- /*tex build_attribute_list(eqno_box); */
- }
- if (eq_w + eqno_w2 > line_w) {
- /*tex
-
- The user can force the equation number to go on a separate line by
- causing its width to be zero.
-
- */
- if ((eqno_w != 0) && ((eq_w - total_shrink[normal] + eqno_w2 <= line_w)
- || (total_shrink[sfi] != 0) || (total_shrink[fil] != 0)
- || (total_shrink[fill] != 0) || (total_shrink[filll] != 0))) {
- list_ptr(eq_box) = null;
- flush_node(eq_box);
- eq_box = hpack(p, line_w - eqno_w2, exactly, -1);
- subtype(eq_box) = equation_list;
- build_attribute_list(eq_box);
- } else {
- eqno_w = 0;
- if (eq_w > line_w) {
- list_ptr(eq_box) = null;
- flush_node(eq_box);
- eq_box = hpack(p, line_w, exactly, -1);
- subtype(eq_box) = equation_list;
- build_attribute_list(eq_box);
- }
- }
- eq_w = width(eq_box);
- }
- /*tex
-
- We try first to center the display without regard to the existence of the
- equation number. If that would make it too close (where ``too close''
- means that the space between display and equation number is less than the
- width of the equation number), we either center it in the remaining space
- or move it as far from the equation number as possible. The latter
- alternative is taken only if the display begins with glue, since we
- assume that the user put glue there to control the spacing precisely.
-
- */
- d = half(line_w - eq_w);
- if ((eqno_w > 0) && (d < 2 * eqno_w)) {
- /*tex too close */
- d = half(line_w - eq_w - eqno_w);
- if (p != null)
- if (!is_char_node(p))
- if (type(p) == glue_node)
- d = 0;
- }
- tail_append(new_penalty(pre_display_penalty_par,after_display_penalty));
- if ((d + line_s <= pre_display_size_par) || l) {
- /*tex not enough clearance */
- g1 = above_display_skip_code;
- g2 = below_display_skip_code;
- } else {
- g1 = above_display_short_skip_code;
- g2 = below_display_short_skip_code;
- }
- /*tex
-
- If the equation number is set on a line by itself, either before or after
- the formula, we append an infinite penalty so that no page break will
- separate the display from its number; and we use the same size and
- displacement for all three potential lines of the display, even though
- `\.{\\parshape}' may specify them differently.
-
- \.{\\leqno} on a forced single line due to |width=0|; it follows that |type(a)=hlist_node|
-
- */
- if (eqno_box && l && (eqno_w == 0)) {
- /* if (math_direction_par==dir_TLT) { */
- shift_amount(eqno_box) = 0;
- /* } else { */
- /* } */
- append_to_vlist(eqno_box,lua_key_index(equation_number));
- tail_append(new_penalty(inf_penalty,equation_number_penalty));
- } else {
- inject_display_skip_before(g1);
- }
- if (eqno_w != 0) {
- r = new_kern(line_w - eq_w - eqno_w - d);
- if (l) {
- if (swap_dir) {
- if (math_direction_par==dir_TLT) {
- /*tex TRT + TLT + \eqno: (swap_dir=true, math_direction_par=TLT, l=true) */
- s = new_kern(width(r) + eqno_w);
- try_couple_nodes(eqno_box,r);
- try_couple_nodes(r,eq_box);
- try_couple_nodes(eq_box,s);
- } else {
- /*tex TLT + TRT + \eqno: (swap_dir=true, math_direction_par=TRT, l=true) */
- try_couple_nodes(eqno_box,r);
- try_couple_nodes(r,eq_box);
- }
- } else {
- if (math_direction_par==dir_TLT) {
- /*tex TLT + TLT + \leqno: (swap_dir=false, math_direction_par=TLT, l=true) */
- s = new_kern(width(r) + eqno_w);
- } else {
- /*tex TRT + TRT + \leqno: (swap_dir=false, math_direction_par=TRT, l=true) */
- s = new_kern(width(r));
- }
- try_couple_nodes(eqno_box,r);
- try_couple_nodes(r,eq_box);
- try_couple_nodes(eq_box,s);
- }
- eq_box = eqno_box;
- } else {
- if (swap_dir) {
- if (math_direction_par==dir_TLT) {
- /*tex TRT + TLT + \leqno: (swap_dir=true, math_direction_par=TLT, l=false) */
- } else {
- /*tex TLT + TRT + \leqno: (swap_dir=true, math_direction_par=TRT, l=false) */
- }
- try_couple_nodes(eq_box,r);
- try_couple_nodes(r,eqno_box);
- } else {
- if (math_direction_par==dir_TLT) {
- /*tex TLT + TLT + \eqno: (swap_dir=false, math_direction_par=TLT, l=false) */
- s = new_kern(d);
- } else {
- /*tex TRT + TRT + \eqno: (swap_dir=false, math_direction_par=TRT, l=false) */
- s = new_kern(width(r) + eqno_w);
- }
- try_couple_nodes(s,eq_box);
- try_couple_nodes(eq_box,r);
- try_couple_nodes(r,eqno_box);
- eq_box = s;
- }
- }
- eq_box = hpack(eq_box, 0, additional, -1);
- subtype(eq_box) = equation_list; /* new */
- build_attribute_list(eq_box);
- shift_amount(eq_box) = line_s;
- } else {
- shift_amount(eq_box) = line_s + d;
- }
- /*tex check for prev: */
- append_to_vlist(eq_box,lua_key_index(equation));
- if ((eqno_box != null) && (eqno_w == 0) && !l) {
- tail_append(new_penalty(inf_penalty,equation_number_penalty));
- /* if (math_direction_par==dir_TLT) { */
- shift_amount(eqno_box) = line_s + line_w - eqno_width ;
- /* } else { */
- /* } */
- append_to_vlist(eqno_box,lua_key_index(equation_number));
- g2 = 0;
- }
- if (t != adjust_head) {
- /*tex migrating material comes after equation number */
- vlink(tail) = vlink(adjust_head);
- alink(adjust_tail) = alink(tail);
- tail = t;
- }
- if (pre_t != pre_adjust_head) {
- vlink(tail) = vlink(pre_adjust_head);
- alink(pre_adjust_tail) = alink(tail);
- tail = pre_t;
- }
- tail_append(new_penalty(post_display_penalty_par,after_display_penalty));
- inject_display_skip_after(g2);
- resume_after_display();
-}
-
-void after_math(void)
-{
- /*tex |mmode| or |-mmode| */
- int m;
- /*tex the formula */
- pointer p;
- /*tex box containing equation number */
- pointer a = null;
- /*tex `\.{\\leqno}' instead of `\.{\\eqno}' */
- boolean l = false;
- m = mode;
- /*tex this pops the nest */
- p = fin_mlist(null);
- if (cur_cmd == math_shift_cs_cmd &&
- (cur_chr == text_style || cur_chr == display_style)) {
- you_cant();
- }
- if (mode == -m) {
- /*tex end of equation number */
- if (cur_cmd == math_shift_cmd) {
- check_second_math_shift();
- } else {
- check_display_math_end();
- }
- run_mlist_to_hlist(p, false, text_style);
- a = hpack(vlink(temp_head), 0, additional, -1);
- build_attribute_list(a);
- unsave_math();
- /*tex now |cur_group=math_shift_group| */
- decr(save_ptr);
- assert(saved_type(0) == saved_eqno);
- if (saved_value(0) == 1)
- l = true;
- m = mode;
- p = fin_mlist(null);
-
- }
- if (m < 0) {
- /*tex
-
- The |unsave| is done after everything else here; hence an appearance
- of `\.{\\mathsurround}' inside of `\.{\$...\$}' affects the spacing
- at these particular \.\$'s. This is consistent with the conventions
- of `\.{\$\$...\$\$}', since `\.{\\abovedisplayskip}' inside a display
- affects the space above that display.
-
- */
- if (cur_cmd == math_shift_cs_cmd) {
- check_inline_math_end();
- }
- tail_append(new_math(math_surround_par, before));
- /*tex begin mathskip code */
- switch (math_skip_mode) {
- case 0 :
- /*tex obey mathsurround when zero glue */
- if (! glue_is_zero(math_skip_par)) {
- copy_glue_values(tail,math_skip_par);
- surround(tail) = 0;
- }
- break ;
- case 1 :
- /*tex always left */
- case 3 :
- /*tex always both */
- case 6 :
- /*tex only when skip */
- copy_glue_values(tail,math_skip_par);
- surround(tail) = 0;
- break ;
- case 2 :
- /*tex only right */
- surround(tail) = 0;
- break ;
- case 4 :
- /*tex ignore, obey marthsurround */
- break ;
- case 5:
- /*tex all spacing disabled */
- surround(tail) = 0;
- break ;
- }
- /*tex end mathskip code */
- if (dir_math_save) {
- tail_append(new_dir(math_direction_par));
- }
- run_mlist_to_hlist(p, (mode > 0), text_style);
- try_couple_nodes(tail,vlink(temp_head));
-
- while (vlink(tail) != null) {
- tail = vlink(tail);
- }
- if (dir_math_save) {
- tail_append(new_dir(math_direction_par));
- subtype(tail) = cancel_dir;
- }
- dir_math_save = false;
- tail_append(new_math(math_surround_par, after));
- /*tex begin mathskip code */
- switch (math_skip_mode) {
- case 0 :
- /*tex obey mathsurround when zero glue */
- if (! glue_is_zero(math_skip_par)) {
- copy_glue_values(tail,math_skip_par);
- surround(tail) = 0;
- }
- break ;
- case 2 :
- /*tex always right */
- case 3 :
- /*tex always both */
- case 6 :
- /*tex only when skip */
- copy_glue_values(tail,math_skip_par);
- surround(tail) = 0;
- break ;
- case 1 :
- /*tex only left */
- surround(tail) = 0;
- break ;
- case 4 :
- /*tex ignore, obey marthsurround */
- break ;
- case 5:
- /*tex all spacing disabled */
- surround(tail) = 0;
- break ;
- }
- /*tex end mathskip code */
- space_factor_par = 1000;
- unsave_math();
- } else {
- if (a == null) {
- if (cur_cmd == math_shift_cmd) {
- check_second_math_shift();
- } else {
- check_display_math_end();
- }
- }
- run_mlist_to_hlist(p, false, display_style);
- finish_displayed_math(l, a, vlink(temp_head));
- }
-}
-
-/*tex
-
- When \.{\\halign} appears in a display, the alignment routines operate
- essentially as they do in vertical mode. Then the following program is
- activated, with |p| and |q| pointing to the beginning and end of the
- resulting list, and with |aux_save| holding the |prev_depth| value.
-
-*/
-
-void finish_display_alignment(pointer p, pointer q, halfword saved_prevdepth)
-{
- do_assignments();
- if (cur_cmd == math_shift_cmd) {
- check_second_math_shift();
- } else {
- check_display_math_end();
- }
- pop_nest();
- tail_append(new_penalty(pre_display_penalty_par,before_display_penalty));
- inject_display_skip_before(above_display_skip_code);
- vlink(tail) = p;
- if (p != null)
- tail = q;
- tail_append(new_penalty(post_display_penalty_par,after_display_penalty));
- inject_display_skip_after(below_display_skip_code);
- cur_list.prev_depth_field = saved_prevdepth;
- resume_after_display();
-}
-
-/*tex Interface to \.{\\Umath} and \.{\\mathstyle}: */
-
-void setup_math_style(void)
-{
- pointer q;
- tail_append(new_noad());
- q = new_node(math_char_node, 0);
- nucleus(tail) = q;
- (void) scan_math_style(nucleus(tail), num_style(m_style));
-}
-
-void print_math_style(void)
-{
- if (abs(mode) == mmode)
- print_int(m_style);
- else
- print_int(-1);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.h b/Build/source/texk/web2c/luatexdir/tex/texmath.h
deleted file mode 100644
index 23fc5a0e42e..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texmath.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/* texmath.h
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef TEXMATH_H
-# define TEXMATH_H 1
-
-# define empty 0
-
-extern pointer new_noad(void);
-
-extern void show_math_node(halfword);
-extern void flush_math(void);
-extern void math_left_brace(void);
-extern void finish_display_alignment(halfword, halfword, halfword);
-extern halfword new_sub_box(halfword);
-
-# define math_reset(p) do { if (p!=null) flush_node(p); p = null; } while (0)
-
-# define scripts_allowed(A) ((type((A))>=simple_noad)&&(type((A))<fence_noad))
-
-# define default_code 010000000000 /* denotes |default_rule_thickness| */
-
-extern void initialize_math(void);
-extern void initialize_math_spacing(void);
-extern halfword math_vcenter_group(halfword);
-extern void build_choices(void);
-extern void close_math_group(halfword);
-extern void init_math(void);
-extern void start_eq_no(void);
-extern void set_math_char(mathcodeval);
-extern void math_char_in_text(mathcodeval);
-extern void math_math_comp(void);
-extern void math_limit_switch(void);
-extern void math_radical(void);
-extern void math_ac(void);
-extern pointer new_style(small_number);
-extern void append_choices(void);
-extern void sub_sup(void);
-extern void no_sub_sup(void);
-extern void math_fraction(void);
-extern void math_left_right(void);
-extern void after_math(void);
-
-extern void scan_extdef_del_code(int level, int extcode);
-extern void scan_extdef_math_code(int level, int extcode);
-
-extern int fam_fnt(int fam_id, int size_id);
-extern void def_fam_fnt(int fam_id, int size_id, int f, int lvl);
-extern void dump_math_data(void);
-extern void undump_math_data(void);
-void unsave_math_data(int lvl);
-
-/*
- @ We also need to compute the change in style between mlists and their
- subsidiaries. The following macros define the subsidiary style for
- an overlined nucleus (|cramped_style|), for a subscript or a superscript
- (|sub_style| or |sup_style|), or for a numerator or denominator (|num_style|
- or |denom_style|).
-*/
-
-extern const char *math_style_names[];
-
-# define cramped 1 /* add this to an uncramped style if you want to cramp it */
-
-# define cramped_style(A) 2*((A)/2)+cramped /* cramp the style */
-# define sub_style(A) 2*((A)/4)+script_style+cramped /* smaller and cramped */
-# define sup_style(A) 2*((A)/4)+script_style+((A)%2) /* smaller */
-# define num_style(A) (A)+2-2*((A)/6) /* smaller unless already script-script */
-# define denom_style(A) 2*((A)/2)+cramped+2-2*((A)/6) /* smaller, cramped */
-# define sup_sup_style(A) sup_style(sup_style((A))) /* smaller */
-
-void setup_math_style(void);
-void print_math_style(void);
-
-# define text_size 0
-# define script_size 1
-# define script_script_size 2
-
-# define dir_math_save cur_list.math_field
-# define m_style cur_list.math_style_field
-# define init_math_fields() do { \
- dir_math_save=false; \
- m_style=-1; \
- } while (0)
-
-
-# define null_font 0
-# define min_quarterword 0
-
-# define undefined_math_parameter max_dimen
-
-typedef enum {
- math_param_quad,
- math_param_axis,
- math_param_operator_size,
- math_param_overbar_kern,
- math_param_overbar_rule,
- math_param_overbar_vgap,
- math_param_underbar_kern,
- math_param_underbar_rule,
- math_param_underbar_vgap,
- math_param_radical_kern,
- math_param_radical_rule,
- math_param_radical_vgap,
- math_param_radical_degree_before,
- math_param_radical_degree_after,
- math_param_radical_degree_raise,
- math_param_stack_vgap,
- math_param_stack_num_up,
- math_param_stack_denom_down,
- math_param_fraction_rule,
- math_param_fraction_num_vgap,
- math_param_fraction_num_up,
- math_param_fraction_denom_vgap,
- math_param_fraction_denom_down,
- math_param_fraction_del_size,
- math_param_skewed_fraction_hgap,
- math_param_skewed_fraction_vgap,
- math_param_limit_above_vgap,
- math_param_limit_above_bgap,
- math_param_limit_above_kern,
- math_param_limit_below_vgap,
- math_param_limit_below_bgap,
- math_param_limit_below_kern,
- math_param_nolimit_sub_factor, /* bonus */
- math_param_nolimit_sup_factor, /* bonus */
- math_param_under_delimiter_vgap,
- math_param_under_delimiter_bgap,
- math_param_over_delimiter_vgap,
- math_param_over_delimiter_bgap,
- math_param_sub_shift_drop,
- math_param_sup_shift_drop,
- math_param_sub_shift_down,
- math_param_sub_sup_shift_down,
- math_param_sub_top_max,
- math_param_sup_shift_up,
- math_param_sup_bottom_min,
- math_param_sup_sub_bottom_max,
- math_param_subsup_vgap,
- math_param_space_after_script,
- math_param_connector_overlap_min,
- math_param_ord_ord_spacing,
- math_param_ord_op_spacing,
- math_param_ord_bin_spacing,
- math_param_ord_rel_spacing,
- math_param_ord_open_spacing,
- math_param_ord_close_spacing,
- math_param_ord_punct_spacing,
- math_param_ord_inner_spacing,
- math_param_op_ord_spacing,
- math_param_op_op_spacing,
- math_param_op_bin_spacing,
- math_param_op_rel_spacing,
- math_param_op_open_spacing,
- math_param_op_close_spacing,
- math_param_op_punct_spacing,
- math_param_op_inner_spacing,
- math_param_bin_ord_spacing,
- math_param_bin_op_spacing,
- math_param_bin_bin_spacing,
- math_param_bin_rel_spacing,
- math_param_bin_open_spacing,
- math_param_bin_close_spacing,
- math_param_bin_punct_spacing,
- math_param_bin_inner_spacing,
- math_param_rel_ord_spacing,
- math_param_rel_op_spacing,
- math_param_rel_bin_spacing,
- math_param_rel_rel_spacing,
- math_param_rel_open_spacing,
- math_param_rel_close_spacing,
- math_param_rel_punct_spacing,
- math_param_rel_inner_spacing,
- math_param_open_ord_spacing,
- math_param_open_op_spacing,
- math_param_open_bin_spacing,
- math_param_open_rel_spacing,
- math_param_open_open_spacing,
- math_param_open_close_spacing,
- math_param_open_punct_spacing,
- math_param_open_inner_spacing,
- math_param_close_ord_spacing,
- math_param_close_op_spacing,
- math_param_close_bin_spacing,
- math_param_close_rel_spacing,
- math_param_close_open_spacing,
- math_param_close_close_spacing,
- math_param_close_punct_spacing,
- math_param_close_inner_spacing,
- math_param_punct_ord_spacing,
- math_param_punct_op_spacing,
- math_param_punct_bin_spacing,
- math_param_punct_rel_spacing,
- math_param_punct_open_spacing,
- math_param_punct_close_spacing,
- math_param_punct_punct_spacing,
- math_param_punct_inner_spacing,
- math_param_inner_ord_spacing,
- math_param_inner_op_spacing,
- math_param_inner_bin_spacing,
- math_param_inner_rel_spacing,
- math_param_inner_open_spacing,
- math_param_inner_close_spacing,
- math_param_inner_punct_spacing,
- math_param_inner_inner_spacing,
- math_param_last
-} math_parameters;
-
-extern const char *math_param_names[];
-
-# define math_param_first_mu_glue math_param_ord_ord_spacing
-
-extern void def_math_param(int param_code, int style_code, scaled value,
- int lvl);
-extern scaled get_math_param(int param_code, int style_code);
-
-
-typedef enum {
- ScriptPercentScaleDown = 1,
- ScriptScriptPercentScaleDown,
- DelimitedSubFormulaMinHeight,
- DisplayOperatorMinHeight,
- MathLeading,
- AxisHeight,
- AccentBaseHeight,
- FlattenedAccentBaseHeight,
- SubscriptShiftDown,
- SubscriptTopMax,
- SubscriptBaselineDropMin,
- SuperscriptShiftUp,
- SuperscriptShiftUpCramped,
- SuperscriptBottomMin,
- SuperscriptBaselineDropMax,
- SubSuperscriptGapMin,
- SuperscriptBottomMaxWithSubscript,
- SpaceAfterScript,
- UpperLimitGapMin,
- UpperLimitBaselineRiseMin,
- LowerLimitGapMin,
- LowerLimitBaselineDropMin,
- StackTopShiftUp,
- StackTopDisplayStyleShiftUp,
- StackBottomShiftDown,
- StackBottomDisplayStyleShiftDown,
- StackGapMin,
- StackDisplayStyleGapMin,
- StretchStackTopShiftUp,
- StretchStackBottomShiftDown,
- StretchStackGapAboveMin,
- StretchStackGapBelowMin,
- FractionNumeratorShiftUp,
- FractionNumeratorDisplayStyleShiftUp,
- FractionDenominatorShiftDown,
- FractionDenominatorDisplayStyleShiftDown,
- FractionNumeratorGapMin,
- FractionNumeratorDisplayStyleGapMin,
- FractionRuleThickness,
- FractionDenominatorGapMin,
- FractionDenominatorDisplayStyleGapMin,
- SkewedFractionHorizontalGap,
- SkewedFractionVerticalGap,
- OverbarVerticalGap,
- OverbarRuleThickness,
- OverbarExtraAscender,
- UnderbarVerticalGap,
- UnderbarRuleThickness,
- UnderbarExtraDescender,
- RadicalVerticalGap,
- RadicalDisplayStyleVerticalGap,
- RadicalRuleThickness,
- RadicalExtraAscender,
- RadicalKernBeforeDegree,
- RadicalKernAfterDegree,
- RadicalDegreeBottomRaisePercent,
- MinConnectorOverlap,
- SubscriptShiftDownWithSuperscript,
- FractionDelimiterSize,
- FractionDelimiterDisplayStyleSize,
- NoLimitSubFactor,
- NoLimitSupFactor,
- MATH_param_last,
-} MATH_param_codes;
-
-# define MATH_param_max MATH_param_last
-
-extern const char *MATH_param_names[];
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.c b/Build/source/texk/web2c/luatexdir/tex/texnodes.c
deleted file mode 100644
index 02e117a876b..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.c
+++ /dev/null
@@ -1,4840 +0,0 @@
-/*
-
-Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-#include "lua/luatex-api.h"
-
-/*tex
-
- This module started out using NDEBUG to trigger checking invalid node usage,
- something that is needed because users can mess up nodes in Lua. At some
- point that code was always enabled so it is now always on but still can be
- recognized as additional code. And as the performance hit is close to zero so
- disabling makes no sense, not even to make it configureable. There is a
- little more memory used but that is neglectable compared to other memory
- usage.
-
-*/
-
-#define MAX_CHAIN_SIZE 13 /* why not a bit larger */
-#define CHECK_NODE_USAGE 1 /* this triggers checking */
-
-memory_word *volatile varmem = NULL;
-
-#ifdef CHECK_NODE_USAGE
- char *varmem_sizes = NULL;
-#endif
-
-halfword var_mem_max = 0;
-halfword rover = 0;
-
-halfword free_chain[MAX_CHAIN_SIZE] = { null };
-
-static int my_prealloc = 0;
-
-/*tex Used in font and lang: */
-
-int fix_node_lists = 1;
-
-/*tex Defined below. */
-
-halfword slow_get_node(int s);
-
-#define fake_node 100
-#define fake_node_size 2
-#define fake_node_name "fake"
-
-#define variable_node_size 2
-
-/*tex
-
- The following definitions are used for keys at the \LUA\ end and
- provide an efficient way to share hashed strings.
-
-*/
-
-# define init_node_key(target,n,key) \
- target[n].lua = luaS_##key##_index; \
- target[n].name = luaS_##key##_ptr;
-
-# define init_field_key(target,n,key) \
- target[n].lua = luaS_##key##_index; \
- target[n].name = luaS_##key##_ptr;
-
-# define init_field_nop(target,n) \
- target[n].lua = 0; \
- target[n].name = NULL;
-
-/*tex The fields of nodes. */
-
-field_info node_fields_accent[10];
-field_info node_fields_adjust[3];
-field_info node_fields_attribute[3];
-field_info node_fields_attribute_list[1];
-field_info node_fields_boundary[3];
-field_info node_fields_choice[6];
-field_info node_fields_delim[6];
-field_info node_fields_dir[4];
-field_info node_fields_disc[6];
-field_info node_fields_fence[8];
-field_info node_fields_fraction[10];
-field_info node_fields_glue[8];
-field_info node_fields_glue_spec[6];
-field_info node_fields_glyph[16];
-field_info node_fields_insert[7];
-field_info node_fields_inserting[9];
-field_info node_fields_kern[4];
-field_info node_fields_list[11];
-field_info node_fields_local_par[9];
-field_info node_fields_margin_kern[4];
-field_info node_fields_mark[4];
-field_info node_fields_math[8];
-field_info node_fields_math_char[4];
-field_info node_fields_math_text_char[4];
-field_info node_fields_noad[5];
-field_info node_fields_penalty[3];
-field_info node_fields_radical[9];
-field_info node_fields_rule[9];
-field_info node_fields_splitup[6];
-field_info node_fields_style[3];
-field_info node_fields_sub_box[3];
-field_info node_fields_sub_mlist[3];
-field_info node_fields_unset[12];
-
-/*tex The fields of whatsit nodes. */
-
-field_info node_fields_whatsit_close[3];
-field_info node_fields_whatsit_late_lua[6];
-field_info node_fields_whatsit_open[6];
-field_info node_fields_whatsit_save_pos[2];
-field_info node_fields_whatsit_special[3];
-field_info node_fields_whatsit_user_defined[5];
-field_info node_fields_whatsit_write[4];
-
-field_info node_fields_whatsit_pdf_action[7];
-field_info node_fields_whatsit_pdf_annot[7];
-field_info node_fields_whatsit_pdf_colorstack[5];
-field_info node_fields_whatsit_pdf_dest[10];
-field_info node_fields_whatsit_pdf_end_link[2];
-field_info node_fields_whatsit_pdf_end_thread[2];
-field_info node_fields_whatsit_pdf_literal[4];
-field_info node_fields_whatsit_pdf_refobj[3];
-field_info node_fields_whatsit_pdf_restore[2];
-field_info node_fields_whatsit_pdf_link_state[3];
-field_info node_fields_whatsit_pdf_save[2];
-field_info node_fields_whatsit_pdf_setmatrix[3];
-field_info node_fields_whatsit_pdf_start_link[8];
-field_info node_fields_whatsit_pdf_start_thread[8];
-field_info node_fields_whatsit_pdf_thread[8];
-
-
-/*tex The values of fields. */
-
-subtype_info node_values_dir[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { 3, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_pdf_destination[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { 3, NULL, 0 },
- { 4, NULL, 0 },
- { 5, NULL, 0 },
- { 6, NULL, 0 },
- { 7, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_pdf_action[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { 3, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_pdf_window[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_color_stack[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { 3, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_fill[] = {
- { normal, NULL, 0 },
- { sfi, NULL, 0 },
- { fil, NULL, 0 },
- { fill, NULL, 0 },
- { filll, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_values_pdf_literal[] = {
- { set_origin, NULL, 0 },
- { direct_page, NULL, 0 },
- { direct_always, NULL, 0 },
- { direct_raw, NULL, 0 },
- { direct_text, NULL, 0 },
- { direct_font, NULL, 0 },
- { scan_special, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info other_values_page_states[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { 2, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-/*tex The subtypes of nodes (most have one). */
-
-subtype_info node_subtypes_dir[] = {
- { normal_dir, NULL, 0 },
- { cancel_dir, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_glue[] = {
- { user_skip_glue, NULL, 0 },
- { line_skip_glue, NULL, 0 },
- { baseline_skip_glue, NULL, 0 },
- { par_skip_glue, NULL, 0 },
- { above_display_skip_glue, NULL, 0 },
- { below_display_skip_glue, NULL, 0 },
- { above_display_short_skip_glue, NULL, 0 },
- { below_display_short_skip_glue, NULL, 0 },
- { left_skip_glue, NULL, 0 },
- { right_skip_glue, NULL, 0 },
- { top_skip_glue, NULL, 0 },
- { split_top_skip_glue, NULL, 0 },
- { tab_skip_glue, NULL, 0 },
- { space_skip_glue, NULL, 0 },
- { xspace_skip_glue, NULL, 0 },
- { par_fill_skip_glue, NULL, 0 },
- { math_skip_glue, NULL, 0 },
- { thin_mu_skip_glue, NULL, 0 },
- { med_mu_skip_glue, NULL, 0 },
- { thick_mu_skip_glue, NULL, 0 },
- /* math */
- { cond_math_glue, NULL, 0 },
- { mu_glue, NULL, 0 },
- /* leaders */
- { a_leaders, NULL, 0 },
- { c_leaders, NULL, 0 },
- { x_leaders, NULL, 0 },
- { g_leaders, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-/*tex
-
- Math glue and leaders have special numbers. At some point we might decide to
- move them down so best don't use hard coded numbers!
-
-*/
-
-subtype_info node_subtypes_mathglue[] = { /* 98+ */
- { cond_math_glue, NULL, 0 },
- { mu_glue, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_leader[] = { /* 100+ */
- { a_leaders, NULL, 0 },
- { c_leaders, NULL, 0 },
- { x_leaders, NULL, 0 },
- { g_leaders, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_boundary[] = {
- { cancel_boundary, NULL, 0 },
- { user_boundary, NULL, 0 },
- { protrusion_boundary, NULL, 0 },
- { word_boundary, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_penalty[] = {
- { user_penalty, NULL, 0 },
- { linebreak_penalty, NULL, 0 },
- { line_penalty, NULL, 0 },
- { word_penalty, NULL, 0 },
- { final_penalty, NULL, 0 },
- { noad_penalty, NULL, 0 },
- { before_display_penalty, NULL, 0 },
- { after_display_penalty, NULL, 0 },
- { equation_number_penalty, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_kern[] = {
- { font_kern, NULL, 0 },
- { explicit_kern, NULL, 0 },
- { accent_kern, NULL, 0 },
- { italic_kern, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_rule[] = {
- { normal_rule, NULL, 0 },
- { box_rule, NULL, 0 },
- { image_rule, NULL, 0 },
- { empty_rule, NULL, 0 },
- { user_rule, NULL, 0 },
- { math_over_rule, NULL, 0 },
- { math_under_rule, NULL, 0 },
- { math_fraction_rule, NULL, 0 },
- { math_radical_rule, NULL, 0 },
- { outline_rule, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_glyph[] = {
- { glyph_unset, NULL, 0 },
- { glyph_character, NULL, 0 },
- { glyph_ligature, NULL, 0 },
- { glyph_ghost, NULL, 0 },
- { glyph_left, NULL, 0 },
- { glyph_right, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_disc[] = {
- { discretionary_disc, NULL, 0 },
- { explicit_disc, NULL, 0 },
- { automatic_disc, NULL, 0 },
- { syllable_disc, NULL, 0 },
- { init_disc, NULL, 0 },
- { select_disc, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_marginkern[] = {
- { left_side, NULL, 0 },
- { right_side, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_list[] = {
- { unknown_list, NULL, 0 },
- { line_list, NULL, 0 },
- { hbox_list, NULL, 0 },
- { indent_list, NULL, 0 },
- { align_row_list, NULL, 0 },
- { align_cell_list, NULL, 0 },
- { equation_list, NULL, 0 },
- { equation_number_list, NULL, 0 },
- { math_list_list, NULL, 0 },
- { math_char_list, NULL, 0 },
- { math_h_extensible_list, NULL, 0 },
- { math_v_extensible_list, NULL, 0 },
- { math_h_delimiter_list, NULL, 0 },
- { math_v_delimiter_list, NULL, 0 },
- { math_over_delimiter_list, NULL, 0 },
- { math_under_delimiter_list, NULL, 0 },
- { math_numerator_list, NULL, 0 },
- { math_denominator_list, NULL, 0 },
- { math_limits_list, NULL, 0 },
- { math_fraction_list, NULL, 0 },
- { math_nucleus_list, NULL, 0 },
- { math_sup_list, NULL, 0 },
- { math_sub_list, NULL, 0 },
- { math_degree_list, NULL, 0 },
- { math_scripts_list, NULL, 0 },
- { math_over_list, NULL, 0 },
- { math_under_list, NULL, 0 },
- { math_accent_list, NULL, 0 },
- { math_radical_list, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_adjust[] = {
- { 0, NULL, 0 },
- { 1, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_math[] = {
- { before, NULL, 0 },
- { after, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_noad[] = {
- { ord_noad_type, NULL, 0 },
- { op_noad_type_normal, NULL, 0 },
- { op_noad_type_limits, NULL, 0 },
- { op_noad_type_no_limits, NULL, 0 },
- { bin_noad_type, NULL, 0 },
- { rel_noad_type, NULL, 0 },
- { open_noad_type, NULL, 0 },
- { close_noad_type, NULL, 0 },
- { punct_noad_type, NULL, 0 },
- { inner_noad_type, NULL, 0 },
- { under_noad_type, NULL, 0 },
- { over_noad_type, NULL, 0 },
- { vcenter_noad_type, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_radical[] = {
- { radical_noad_type, NULL, 0 },
- { uradical_noad_type, NULL, 0 },
- { uroot_noad_type, NULL, 0 },
- { uunderdelimiter_noad_type, NULL, 0 },
- { uoverdelimiter_noad_type, NULL, 0 },
- { udelimiterunder_noad_type, NULL, 0 },
- { udelimiterover_noad_type, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_accent[] = {
- { bothflexible_accent, NULL, 0 },
- { fixedtop_accent, NULL, 0 },
- { fixedbottom_accent, NULL, 0 },
- { fixedboth_accent, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-subtype_info node_subtypes_fence[] = {
- { unset_noad_side, NULL, 0 },
- { left_noad_side, NULL, 0 },
- { middle_noad_side, NULL, 0 },
- { right_noad_side, NULL, 0 },
- { no_noad_side, NULL, 0 },
- { -1, NULL, 0 },
-};
-
-/*tes This brings all together */
-
-node_info node_data[] = {
- { hlist_node, box_node_size, node_subtypes_list, node_fields_list, NULL, 1, 0 },
- { vlist_node, box_node_size, node_subtypes_list, node_fields_list, NULL, 2, 0 },
- { rule_node, rule_node_size, node_subtypes_rule, node_fields_rule, NULL, 3, 0 },
- { ins_node, ins_node_size, NULL, node_fields_insert, NULL, 4, 0 },
- { mark_node, mark_node_size, NULL, node_fields_mark, NULL, 5, 0 },
- { adjust_node, adjust_node_size, node_subtypes_adjust, node_fields_adjust, NULL, 6, 0 },
- { boundary_node, boundary_node_size, node_subtypes_boundary, node_fields_boundary, NULL, -1, 0 },
- { disc_node, disc_node_size, node_subtypes_disc, node_fields_disc, NULL, 8, 0 },
- { whatsit_node, -1, NULL, NULL, NULL, 9, 0 },
- { local_par_node, local_par_size, NULL, node_fields_local_par, NULL, -1, 0 },
- { dir_node, dir_node_size, node_subtypes_dir, node_fields_dir, NULL, -1, 0 },
- { math_node, math_node_size, node_subtypes_math, node_fields_math, NULL, 10, 0 },
- { glue_node, glue_node_size, node_subtypes_glue, node_fields_glue, NULL, 11, 0 },
- { kern_node, kern_node_size, node_subtypes_kern, node_fields_kern, NULL, 12, 0 },
- { penalty_node, penalty_node_size, node_subtypes_penalty, node_fields_penalty, NULL, 13, 0 },
- { unset_node, box_node_size, NULL, node_fields_unset, NULL, 14, 0 },
- { style_node, style_node_size, NULL, node_fields_style, NULL, 15, 0 },
- { choice_node, style_node_size, NULL, node_fields_choice, NULL, 15, 0 },
- { simple_noad, noad_size, node_subtypes_noad, node_fields_noad, NULL, 15, 0 },
- { radical_noad, radical_noad_size, node_subtypes_radical, node_fields_radical, NULL, 15, 0 },
- { fraction_noad, fraction_noad_size, NULL, node_fields_fraction, NULL, 15, 0 },
- { accent_noad, accent_noad_size, node_subtypes_accent, node_fields_accent, NULL, 15, 0 },
- { fence_noad, fence_noad_size, node_subtypes_fence, node_fields_fence, NULL, 15, 0 },
- { math_char_node, math_kernel_node_size, NULL, node_fields_math_char, NULL, 15, 0 },
- { sub_box_node, math_kernel_node_size, NULL, node_fields_sub_box, NULL, 15, 0 },
- { sub_mlist_node, math_kernel_node_size, NULL, node_fields_sub_mlist, NULL, 15, 0 },
- { math_text_char_node, math_kernel_node_size, NULL, node_fields_math_text_char, NULL, 15, 0 },
- { delim_node, math_shield_node_size, NULL, node_fields_delim, NULL, 15, 0 },
- { margin_kern_node, margin_kern_node_size, node_subtypes_marginkern, node_fields_margin_kern, NULL, -1, 0 },
- { glyph_node, glyph_node_size, node_subtypes_glyph, node_fields_glyph, NULL, 0, 0 },
- { align_record_node, box_node_size, NULL, NULL, NULL, -1, 0 },
- { pseudo_file_node, pseudo_file_node_size, NULL, NULL, NULL, -1, 0 },
- { pseudo_line_node, variable_node_size, NULL, NULL, NULL, -1, 0 },
- { inserting_node, page_ins_node_size, NULL, node_fields_inserting, NULL, -1, 0 },
- { split_up_node, page_ins_node_size, NULL, node_fields_splitup, NULL, -1, 0 },
- { expr_node, expr_node_size, NULL, NULL, NULL, -1, 0 },
- { nesting_node, nesting_node_size, NULL, NULL, NULL, -1, 0 },
- { span_node, span_node_size, NULL, NULL, NULL, -1, 0 },
- { attribute_node, attribute_node_size, NULL, node_fields_attribute, NULL, -1, 0 },
- { glue_spec_node, glue_spec_size, NULL, node_fields_glue_spec, NULL, -1, 0 },
- { attribute_list_node, attribute_node_size, NULL, node_fields_attribute_list, NULL, -1, 0 },
- { temp_node, temp_node_size, NULL, NULL, NULL, -1, 0 },
- { align_stack_node, align_stack_node_size, NULL, NULL, NULL, -1, 0 },
- { movement_node, movement_node_size, NULL, NULL, NULL, -1, 0 },
- { if_node, if_node_size, NULL, NULL, NULL, -1, 0 },
- { unhyphenated_node, active_node_size, NULL, NULL, NULL, -1, 0 },
- { hyphenated_node, active_node_size, NULL, NULL, NULL, -1, 0 },
- { delta_node, delta_node_size, NULL, NULL, NULL, -1, 0 },
- { passive_node, passive_node_size, NULL, NULL, NULL, -1, 0 },
- { shape_node, variable_node_size, NULL, NULL, NULL, -1, 0 },
- { -1, -1, NULL, NULL, NULL, -1, 0 }
-};
-
-void l_set_node_data(void) {
- init_node_key(node_data, hlist_node, hlist)
- init_node_key(node_data, vlist_node, vlist)
- init_node_key(node_data, rule_node, rule)
- init_node_key(node_data, ins_node, ins)
- init_node_key(node_data, mark_node, mark)
- init_node_key(node_data, adjust_node, adjust)
- init_node_key(node_data, boundary_node, boundary)
- init_node_key(node_data, disc_node, disc)
- init_node_key(node_data, whatsit_node, whatsit)
- init_node_key(node_data, local_par_node, local_par)
- init_node_key(node_data, dir_node, dir)
- init_node_key(node_data, math_node, math)
- init_node_key(node_data, glue_node, glue)
- init_node_key(node_data, kern_node, kern)
- init_node_key(node_data, penalty_node, penalty)
- init_node_key(node_data, unset_node, unset)
- init_node_key(node_data, style_node, style)
- init_node_key(node_data, choice_node, choice)
- init_node_key(node_data, simple_noad, noad)
- init_node_key(node_data, radical_noad, radical)
- init_node_key(node_data, fraction_noad, fraction)
- init_node_key(node_data, accent_noad, accent)
- init_node_key(node_data, fence_noad, fence)
- init_node_key(node_data, math_char_node, math_char)
- init_node_key(node_data, sub_box_node, sub_box)
- init_node_key(node_data, sub_mlist_node, sub_mlist)
- init_node_key(node_data, math_text_char_node, math_text_char)
- init_node_key(node_data, delim_node, delim)
- init_node_key(node_data, margin_kern_node, margin_kern)
- init_node_key(node_data, glyph_node, glyph)
- init_node_key(node_data, align_record_node, align_record)
- init_node_key(node_data, pseudo_file_node, pseudo_file)
- init_node_key(node_data, pseudo_line_node, pseudo_line)
- init_node_key(node_data, inserting_node, page_insert)
- init_node_key(node_data, split_up_node, split_insert)
- init_node_key(node_data, expr_node, expr_stack)
- init_node_key(node_data, nesting_node, nested_list)
- init_node_key(node_data, span_node, span)
- init_node_key(node_data, attribute_node, attribute)
- init_node_key(node_data, glue_spec_node, glue_spec)
- init_node_key(node_data, attribute_list_node, attribute_list)
- init_node_key(node_data, temp_node, temp)
- init_node_key(node_data, align_stack_node, align_stack)
- init_node_key(node_data, movement_node, movement_stack)
- init_node_key(node_data, if_node, if_stack)
- init_node_key(node_data, unhyphenated_node, unhyphenated)
- init_node_key(node_data, hyphenated_node, hyphenated)
- init_node_key(node_data, delta_node, delta)
- init_node_key(node_data, passive_node, passive)
- init_node_key(node_data, shape_node, shape)
-
- init_node_key(node_subtypes_dir, normal_dir, normal)
- init_node_key(node_subtypes_dir, cancel_dir, cancel)
-
- init_node_key(node_subtypes_glue, user_skip_glue, userskip)
- init_node_key(node_subtypes_glue, line_skip_glue, lineskip)
- init_node_key(node_subtypes_glue, baseline_skip_glue, baselineskip)
- init_node_key(node_subtypes_glue, par_skip_glue, parskip)
- init_node_key(node_subtypes_glue, above_display_skip_glue, abovedisplayskip)
- init_node_key(node_subtypes_glue, below_display_skip_glue, belowdisplayskip)
- init_node_key(node_subtypes_glue, above_display_short_skip_glue, abovedisplayshortskip)
- init_node_key(node_subtypes_glue, below_display_short_skip_glue, belowdisplayshortskip)
- init_node_key(node_subtypes_glue, left_skip_glue, leftskip)
- init_node_key(node_subtypes_glue, right_skip_glue, rightskip)
- init_node_key(node_subtypes_glue, top_skip_glue, topskip)
- init_node_key(node_subtypes_glue, split_top_skip_glue, splittopskip)
- init_node_key(node_subtypes_glue, tab_skip_glue, tabskip)
- init_node_key(node_subtypes_glue, space_skip_glue, spaceskip)
- init_node_key(node_subtypes_glue, xspace_skip_glue, xspaceskip)
- init_node_key(node_subtypes_glue, par_fill_skip_glue, parfillskip)
- init_node_key(node_subtypes_glue, math_skip_glue, mathskip)
- init_node_key(node_subtypes_glue, thin_mu_skip_glue, thinmuskip)
- init_node_key(node_subtypes_glue, med_mu_skip_glue, medmuskip)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue, thickmuskip)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 1, conditionalmathskip)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 2, muglue)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 3, leaders)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 4, cleaders)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 5, xleaders)
- init_node_key(node_subtypes_glue, thick_mu_skip_glue + 6, gleaders)
-
- init_node_key(node_subtypes_mathglue, 0, conditionalmathskip)
- init_node_key(node_subtypes_mathglue, 1, muglue)
-
- init_node_key(node_subtypes_leader, 0, leaders)
- init_node_key(node_subtypes_leader, 1, cleaders)
- init_node_key(node_subtypes_leader, 2, xleaders)
- init_node_key(node_subtypes_leader, 3, gleaders)
-
- init_node_key(node_subtypes_boundary, cancel_boundary, cancel)
- init_node_key(node_subtypes_boundary, user_boundary, user)
- init_node_key(node_subtypes_boundary, protrusion_boundary, protrusion)
- init_node_key(node_subtypes_boundary, word_boundary, word)
-
- init_node_key(node_subtypes_penalty, user_penalty, userpenalty)
- init_node_key(node_subtypes_penalty, linebreak_penalty, linebreakpenalty)
- init_node_key(node_subtypes_penalty, line_penalty, linepenalty)
- init_node_key(node_subtypes_penalty, word_penalty, wordpenalty)
- init_node_key(node_subtypes_penalty, final_penalty, finalpenalty)
- init_node_key(node_subtypes_penalty, noad_penalty, noadpenalty)
- init_node_key(node_subtypes_penalty, before_display_penalty, beforedisplaypenalty)
- init_node_key(node_subtypes_penalty, after_display_penalty, afterdisplaypenalty)
- init_node_key(node_subtypes_penalty, equation_number_penalty, equationnumberpenalty)
-
- init_node_key(node_subtypes_kern, font_kern, fontkern)
- init_node_key(node_subtypes_kern, explicit_kern, userkern)
- init_node_key(node_subtypes_kern, accent_kern, accentkern)
- init_node_key(node_subtypes_kern, italic_kern, italiccorrection)
-
- init_node_key(node_subtypes_rule, normal_rule, normal)
- init_node_key(node_subtypes_rule, box_rule, box)
- init_node_key(node_subtypes_rule, image_rule, image)
- init_node_key(node_subtypes_rule, empty_rule, empty)
- init_node_key(node_subtypes_rule, user_rule, user)
- init_node_key(node_subtypes_rule, math_over_rule, over)
- init_node_key(node_subtypes_rule, math_under_rule, under)
- init_node_key(node_subtypes_rule, math_fraction_rule, fraction)
- init_node_key(node_subtypes_rule, math_radical_rule, radical)
- init_node_key(node_subtypes_rule, outline_rule, outline)
-
- init_node_key(node_subtypes_glyph, 0, unset)
- init_node_key(node_subtypes_glyph, 1, character)
- init_node_key(node_subtypes_glyph, 2, ligature)
- init_node_key(node_subtypes_glyph, 3, ghost)
- init_node_key(node_subtypes_glyph, 4, left)
- init_node_key(node_subtypes_glyph, 5, right)
-
- init_node_key(node_subtypes_disc, discretionary_disc, discretionary)
- init_node_key(node_subtypes_disc, explicit_disc, explicit)
- init_node_key(node_subtypes_disc, automatic_disc, automatic)
- init_node_key(node_subtypes_disc, syllable_disc, regular)
- init_node_key(node_subtypes_disc, init_disc, first)
- init_node_key(node_subtypes_disc, select_disc, second)
-
- init_node_key(node_subtypes_fence, unset_noad_side, unset)
- init_node_key(node_subtypes_fence, left_noad_side, left)
- init_node_key(node_subtypes_fence, middle_noad_side, middle)
- init_node_key(node_subtypes_fence, right_noad_side, right)
- init_node_key(node_subtypes_fence, no_noad_side, no)
-
- init_node_key(node_subtypes_list, unknown_list, unknown)
- init_node_key(node_subtypes_list, line_list, line)
- init_node_key(node_subtypes_list, hbox_list, box)
- init_node_key(node_subtypes_list, indent_list, indent)
- init_node_key(node_subtypes_list, align_row_list, alignment)
- init_node_key(node_subtypes_list, align_cell_list, cell)
- init_node_key(node_subtypes_list, equation_list, equation)
- init_node_key(node_subtypes_list, equation_number_list, equationnumber)
- init_node_key(node_subtypes_list, math_list_list, math)
- init_node_key(node_subtypes_list, math_char_list, mathchar)
- init_node_key(node_subtypes_list, math_h_extensible_list, hextensible)
- init_node_key(node_subtypes_list, math_v_extensible_list, vextensible)
- init_node_key(node_subtypes_list, math_h_delimiter_list, hdelimiter)
- init_node_key(node_subtypes_list, math_v_delimiter_list, vdelimiter)
- init_node_key(node_subtypes_list, math_over_delimiter_list, overdelimiter)
- init_node_key(node_subtypes_list, math_under_delimiter_list, underdelimiter)
- init_node_key(node_subtypes_list, math_numerator_list, numerator)
- init_node_key(node_subtypes_list, math_denominator_list, denominator)
- init_node_key(node_subtypes_list, math_limits_list, limits)
- init_node_key(node_subtypes_list, math_fraction_list, fraction)
- init_node_key(node_subtypes_list, math_nucleus_list, nucleus)
- init_node_key(node_subtypes_list, math_sup_list, sup)
- init_node_key(node_subtypes_list, math_sub_list, sub)
- init_node_key(node_subtypes_list, math_degree_list, degree)
- init_node_key(node_subtypes_list, math_scripts_list, scripts)
- init_node_key(node_subtypes_list, math_over_list, over)
- init_node_key(node_subtypes_list, math_under_list, under)
- init_node_key(node_subtypes_list, math_accent_list, accent)
- init_node_key(node_subtypes_list, math_radical_list, radical)
-
- init_node_key(node_subtypes_math, before, beginmath)
- init_node_key(node_subtypes_math, after, endmath)
-
- init_node_key(node_subtypes_marginkern, left_side, left)
- init_node_key(node_subtypes_marginkern, right_side, right)
-
- init_node_key(node_subtypes_adjust, 0, normal)
- init_node_key(node_subtypes_adjust, 1, pre)
-
- init_node_key(node_subtypes_noad, ord_noad_type, ord)
- init_node_key(node_subtypes_noad, op_noad_type_normal, opdisplaylimits)
- init_node_key(node_subtypes_noad, op_noad_type_limits, oplimits)
- init_node_key(node_subtypes_noad, op_noad_type_no_limits, opnolimits)
- init_node_key(node_subtypes_noad, bin_noad_type, bin)
- init_node_key(node_subtypes_noad, rel_noad_type, rel)
- init_node_key(node_subtypes_noad, open_noad_type, open)
- init_node_key(node_subtypes_noad, close_noad_type, close)
- init_node_key(node_subtypes_noad, punct_noad_type, punct)
- init_node_key(node_subtypes_noad, inner_noad_type, inner)
- init_node_key(node_subtypes_noad, under_noad_type, under)
- init_node_key(node_subtypes_noad, over_noad_type, over)
- init_node_key(node_subtypes_noad, vcenter_noad_type, vcenter)
-
- init_node_key(node_subtypes_radical, radical_noad_type, radical)
- init_node_key(node_subtypes_radical, uradical_noad_type, uradical)
- init_node_key(node_subtypes_radical, uroot_noad_type, uroot)
- init_node_key(node_subtypes_radical, uunderdelimiter_noad_type, uunderdelimiter)
- init_node_key(node_subtypes_radical, uoverdelimiter_noad_type, uoverdelimiter)
- init_node_key(node_subtypes_radical, udelimiterunder_noad_type, udelimiterunder)
- init_node_key(node_subtypes_radical, udelimiterover_noad_type, udelimiterover)
-
- init_node_key(node_subtypes_accent, bothflexible_accent, bothflexible)
- init_node_key(node_subtypes_accent, fixedtop_accent, fixedtop)
- init_node_key(node_subtypes_accent, fixedbottom_accent, fixedbottom)
- init_node_key(node_subtypes_accent, fixedboth_accent, fixedboth)
-
- init_node_key(node_values_fill, normal, normal)
- init_node_key(node_values_fill, sfi, fi)
- init_node_key(node_values_fill, fil, fil)
- init_node_key(node_values_fill, fill, fill)
- init_node_key(node_values_fill, filll, filll)
-
- init_node_key(node_values_dir, 0, TLT)
- init_node_key(node_values_dir, 1, TRT)
- init_node_key(node_values_dir, 2, LTL)
- init_node_key(node_values_dir, 3, RTT)
-
- init_node_key(other_values_page_states, 0, empty)
- init_node_key(other_values_page_states, 1, box_there)
- init_node_key(other_values_page_states, 2, inserts_only)
-
- init_field_key(node_fields_accent, 0, attr);
- init_field_key(node_fields_accent, 1, nucleus);
- init_field_key(node_fields_accent, 2, sub);
- init_field_key(node_fields_accent, 3, sup);
- init_field_key(node_fields_accent, 4, accent);
- init_field_key(node_fields_accent, 5, bot_accent);
- init_field_key(node_fields_accent, 6, top_accent);
- init_field_key(node_fields_accent, 7, overlay_accent);
- init_field_key(node_fields_accent, 8, fraction);
- init_field_nop(node_fields_accent, 9);
-
- init_field_key(node_fields_adjust, 0, attr);
- init_field_key(node_fields_adjust, 1, head);
- init_field_nop(node_fields_adjust, 2);
-
- init_field_key(node_fields_attribute, 0, number);
- init_field_key(node_fields_attribute, 1, value);
- init_field_nop(node_fields_attribute, 2);
-
- init_field_nop(node_fields_attribute_list,0);
-
- init_field_key(node_fields_boundary, 0, attr);
- init_field_key(node_fields_boundary, 1, value);
- init_field_nop(node_fields_boundary, 2);
-
- init_field_key(node_fields_choice, 0, attr);
- init_field_key(node_fields_choice, 1, display);
- init_field_key(node_fields_choice, 2, text);
- init_field_key(node_fields_choice, 3, script);
- init_field_key(node_fields_choice, 4, scriptscript);
- init_field_nop(node_fields_choice, 5);
-
- init_field_key(node_fields_delim, 0, attr);
- init_field_key(node_fields_delim, 1, small_fam);
- init_field_key(node_fields_delim, 2, small_char);
- init_field_key(node_fields_delim, 3, large_fam);
- init_field_key(node_fields_delim, 4, large_char);
- init_field_nop(node_fields_delim, 5);
-
- init_field_key(node_fields_dir, 0, attr);
- init_field_key(node_fields_dir, 1, dir);
- init_field_key(node_fields_dir, 2, level);
- init_field_nop(node_fields_dir, 3);
-
- init_field_key(node_fields_disc, 0, attr);
- init_field_key(node_fields_disc, 1, pre);
- init_field_key(node_fields_disc, 2, post);
- init_field_key(node_fields_disc, 3, replace);
- init_field_key(node_fields_disc, 4, penalty);
- init_field_nop(node_fields_disc, 5);
-
- init_field_key(node_fields_fence, 0, attr);
- init_field_key(node_fields_fence, 1, delim);
- init_field_key(node_fields_fence, 2, italic);
- init_field_key(node_fields_fence, 3, height);
- init_field_key(node_fields_fence, 4, depth);
- init_field_key(node_fields_fence, 5, options);
- init_field_key(node_fields_fence, 6, class);
- init_field_nop(node_fields_fence, 7);
-
- init_field_key(node_fields_fraction, 0, attr);
- init_field_key(node_fields_fraction, 1, width);
- init_field_key(node_fields_fraction, 2, num);
- init_field_key(node_fields_fraction, 3, denom);
- init_field_key(node_fields_fraction, 4, left);
- init_field_key(node_fields_fraction, 5, right);
- init_field_key(node_fields_fraction, 6, middle);
- init_field_key(node_fields_fraction, 7, fam);
- init_field_key(node_fields_fraction, 8, options);
- init_field_nop(node_fields_fraction, 9);
-
- init_field_key(node_fields_glue, 0, attr);
- init_field_key(node_fields_glue, 1, leader);
- init_field_key(node_fields_glue, 2, width);
- init_field_key(node_fields_glue, 3, stretch);
- init_field_key(node_fields_glue, 4, shrink);
- init_field_key(node_fields_glue, 5, stretch_order);
- init_field_key(node_fields_glue, 6, shrink_order);
- init_field_nop(node_fields_glue, 7);
-
- init_field_key(node_fields_glue_spec, 0, width);
- init_field_key(node_fields_glue_spec, 1, stretch);
- init_field_key(node_fields_glue_spec, 2, shrink);
- init_field_key(node_fields_glue_spec, 3, stretch_order);
- init_field_key(node_fields_glue_spec, 4, shrink_order);
- init_field_nop(node_fields_glue_spec, 5);
-
- init_field_key(node_fields_glyph, 0, attr);
- init_field_key(node_fields_glyph, 1, char);
- init_field_key(node_fields_glyph, 2, font);
- init_field_key(node_fields_glyph, 3, lang);
- init_field_key(node_fields_glyph, 4, left);
- init_field_key(node_fields_glyph, 5, right);
- init_field_key(node_fields_glyph, 6, uchyph);
- init_field_key(node_fields_glyph, 7, components);
- init_field_key(node_fields_glyph, 8, xoffset);
- init_field_key(node_fields_glyph, 9, yoffset);
- init_field_key(node_fields_glyph, 10, width);
- init_field_key(node_fields_glyph, 11, height);
- init_field_key(node_fields_glyph, 12, depth);
- init_field_key(node_fields_glyph, 13, expansion_factor);
- init_field_key(node_fields_glyph, 14, data);
- init_field_nop(node_fields_glyph, 15);
-
- init_field_key(node_fields_insert, 0, attr);
- init_field_key(node_fields_insert, 1, cost);
- init_field_key(node_fields_insert, 2, depth);
- init_field_key(node_fields_insert, 3, height);
- init_field_key(node_fields_insert, 4, spec);
- init_field_key(node_fields_insert, 5, head);
- init_field_nop(node_fields_insert, 6);
-
- init_field_key(node_fields_inserting, 0, height);
- init_field_key(node_fields_inserting, 1, last_ins_ptr);
- init_field_key(node_fields_inserting, 2, best_ins_ptr);
- init_field_key(node_fields_inserting, 3, width);
- init_field_key(node_fields_inserting, 4, stretch);
- init_field_key(node_fields_inserting, 5, shrink);
- init_field_key(node_fields_inserting, 6, stretch_order);
- init_field_key(node_fields_inserting, 7, shrink_order);
- init_field_nop(node_fields_inserting, 8);
-
- init_field_key(node_fields_kern, 0, attr);
- init_field_key(node_fields_kern, 1, kern);
- init_field_key(node_fields_kern, 2, expansion_factor);
- init_field_nop(node_fields_kern, 3);
-
- init_field_key(node_fields_list, 0, attr);
- init_field_key(node_fields_list, 1, width);
- init_field_key(node_fields_list, 2, depth);
- init_field_key(node_fields_list, 3, height);
- init_field_key(node_fields_list, 4, dir);
- init_field_key(node_fields_list, 5, shift);
- init_field_key(node_fields_list, 6, glue_order);
- init_field_key(node_fields_list, 7, glue_sign);
- init_field_key(node_fields_list, 8, glue_set);
- init_field_key(node_fields_list, 9, head);
- init_field_nop(node_fields_list, 10);
-
- init_field_key(node_fields_local_par, 0, attr);
- init_field_key(node_fields_local_par, 1, pen_inter);
- init_field_key(node_fields_local_par, 2, pen_broken);
- init_field_key(node_fields_local_par, 3, dir);
- init_field_key(node_fields_local_par, 4, box_left);
- init_field_key(node_fields_local_par, 5, box_left_width);
- init_field_key(node_fields_local_par, 6, box_right);
- init_field_key(node_fields_local_par, 7, box_right_width);
- init_field_nop(node_fields_local_par, 8);
-
- init_field_key(node_fields_margin_kern, 0, attr);
- init_field_key(node_fields_margin_kern, 1, width);
- init_field_key(node_fields_margin_kern, 2, glyph);
- init_field_nop(node_fields_margin_kern, 3);
-
- init_field_key(node_fields_mark, 0, attr);
- init_field_key(node_fields_mark, 1, class);
- init_field_key(node_fields_mark, 2, mark);
- init_field_nop(node_fields_mark, 3);
-
- init_field_key(node_fields_math, 0, attr);
- init_field_key(node_fields_math, 1, surround);
- init_field_key(node_fields_math, 2, width);
- init_field_key(node_fields_math, 3, stretch);
- init_field_key(node_fields_math, 4, shrink);
- init_field_key(node_fields_math, 5, stretch_order);
- init_field_key(node_fields_math, 6, shrink_order);
- init_field_nop(node_fields_math, 7);
-
- init_field_key(node_fields_math_char, 0, attr);
- init_field_key(node_fields_math_char, 1, fam);
- init_field_key(node_fields_math_char, 2, char);
- init_field_nop(node_fields_math_char, 3);
-
- init_field_key(node_fields_math_text_char, 0, attr);
- init_field_key(node_fields_math_text_char, 1, fam);
- init_field_key(node_fields_math_text_char, 2, char);
- init_field_nop(node_fields_math_text_char, 3);
-
- init_field_key(node_fields_noad, 0, attr);
- init_field_key(node_fields_noad, 1, nucleus);
- init_field_key(node_fields_noad, 2, sub);
- init_field_key(node_fields_noad, 3, sup);
- init_field_nop(node_fields_noad, 4);
-
- init_field_key(node_fields_penalty, 0, attr);
- init_field_key(node_fields_penalty, 1, penalty);
- init_field_nop(node_fields_penalty, 2);
-
- init_field_key(node_fields_radical, 0, attr);
- init_field_key(node_fields_radical, 1, nucleus);
- init_field_key(node_fields_radical, 2, sub);
- init_field_key(node_fields_radical, 3, sup);
- init_field_key(node_fields_radical, 4, left);
- init_field_key(node_fields_radical, 5, degree);
- init_field_key(node_fields_radical, 6, width);
- init_field_key(node_fields_radical, 7, options);
- init_field_nop(node_fields_radical, 8);
-
- init_field_key(node_fields_rule, 0, attr);
- init_field_key(node_fields_rule, 1, width);
- init_field_key(node_fields_rule, 2, depth);
- init_field_key(node_fields_rule, 3, height);
- init_field_key(node_fields_rule, 4, dir);
- init_field_key(node_fields_rule, 5, index);
- init_field_key(node_fields_rule, 6, left);
- init_field_key(node_fields_rule, 7, right);
- init_field_nop(node_fields_rule, 8);
-
- init_field_key(node_fields_splitup, 0, height);
- init_field_key(node_fields_splitup, 1, last_ins_ptr);
- init_field_key(node_fields_splitup, 2, best_ins_ptr);
- init_field_key(node_fields_splitup, 3, broken_ptr);
- init_field_key(node_fields_splitup, 4, broken_ins);
- init_field_nop(node_fields_splitup, 5);
-
- init_field_key(node_fields_style, 0, attr);
- init_field_key(node_fields_style, 1, style);
- init_field_nop(node_fields_style, 2);
-
- init_field_key(node_fields_sub_box, 0, attr);
- init_field_key(node_fields_sub_box, 1, head);
- init_field_nop(node_fields_sub_box, 2);
-
- init_field_key(node_fields_sub_mlist, 0, attr);
- init_field_key(node_fields_sub_mlist, 1, head);
- init_field_nop(node_fields_sub_mlist, 2);
-
- init_field_key(node_fields_unset, 0, attr);
- init_field_key(node_fields_unset, 1, width);
- init_field_key(node_fields_unset, 2, depth);
- init_field_key(node_fields_unset, 3, height);
- init_field_key(node_fields_unset, 4, dir);
- init_field_key(node_fields_unset, 5, shrink);
- init_field_key(node_fields_unset, 6, glue_order);
- init_field_key(node_fields_unset, 7, glue_sign);
- init_field_key(node_fields_unset, 8, stretch);
- init_field_key(node_fields_unset, 9, span);
- init_field_key(node_fields_unset, 10, head);
- init_field_nop(node_fields_unset, 11);
-
-}
-
-node_info whatsit_node_data[] = {
-
- /*tex These are always there. The fake nodes are historical. */
-
- { open_node, open_node_size, NULL, node_fields_whatsit_open, NULL, -1, 0 },
- { write_node, write_node_size, NULL, node_fields_whatsit_write, NULL, -1, 0 },
- { close_node, close_node_size, NULL, node_fields_whatsit_close, NULL, -1, 0 },
- { special_node, special_node_size, NULL, node_fields_whatsit_special, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { save_pos_node, save_pos_node_size, NULL, node_fields_whatsit_save_pos, NULL, -1, 0 },
- { late_lua_node, late_lua_node_size, NULL, node_fields_whatsit_late_lua, NULL, -1, 0 },
- { user_defined_node, user_defined_node_size, NULL, node_fields_whatsit_user_defined, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
- { fake_node, fake_node_size, NULL, NULL, NULL, -1, 0 },
-
- /*tex Here starts the \DVI\ backend section, todo: a separate list. */
-
- /*tex {\em There is nothing here.} */
-
- /*tex Here starts the \PDF\ backend section, todo: a separate list. */
-
- { pdf_literal_node, write_node_size, NULL, node_fields_whatsit_pdf_literal, NULL, -1, 0 },
- { pdf_refobj_node, pdf_refobj_node_size, NULL, node_fields_whatsit_pdf_refobj, NULL, -1, 0 },
- { pdf_annot_node, pdf_annot_node_size, NULL, node_fields_whatsit_pdf_annot, NULL, -1, 0 },
- { pdf_start_link_node, pdf_annot_node_size, NULL, node_fields_whatsit_pdf_start_link, NULL, -1, 0 },
- { pdf_end_link_node, pdf_end_link_node_size, NULL, node_fields_whatsit_pdf_end_link, NULL, -1, 0 },
- { pdf_dest_node, pdf_dest_node_size, NULL, node_fields_whatsit_pdf_dest, NULL, -1, 0 },
- { pdf_action_node, pdf_action_size, NULL, node_fields_whatsit_pdf_action, NULL, -1, 0 },
- { pdf_thread_node, pdf_thread_node_size, NULL, node_fields_whatsit_pdf_thread, NULL, -1, 0 },
- { pdf_start_thread_node, pdf_thread_node_size, NULL, node_fields_whatsit_pdf_start_thread, NULL, -1, 0 },
- { pdf_end_thread_node, pdf_end_thread_node_size, NULL, node_fields_whatsit_pdf_end_thread, NULL, -1, 0 },
- { pdf_thread_data_node, pdf_thread_node_size, NULL, NULL, NULL, -1, 0 },
- { pdf_link_data_node, pdf_annot_node_size, NULL, NULL, NULL, -1, 0 },
- { pdf_colorstack_node, pdf_colorstack_node_size, NULL, node_fields_whatsit_pdf_colorstack, NULL, -1, 0 },
- { pdf_setmatrix_node, pdf_setmatrix_node_size, NULL, node_fields_whatsit_pdf_setmatrix, NULL, -1, 0 },
- { pdf_save_node, pdf_save_node_size, NULL, node_fields_whatsit_pdf_save, NULL, -1, 0 },
- { pdf_restore_node, pdf_restore_node_size, NULL, node_fields_whatsit_pdf_restore, NULL, -1, 0 },
- { pdf_link_state_node, pdf_link_state_node_size, NULL, node_fields_whatsit_pdf_link_state, NULL, -1, 0 },
-
- /*tex That's it. */
-
- { -1, -1, NULL, NULL, NULL, -1, 0 },
-
-};
-
-void l_set_whatsit_data(void) {
- init_node_key(whatsit_node_data, open_node, open)
- init_node_key(whatsit_node_data, write_node, write)
- init_node_key(whatsit_node_data, close_node, close)
- init_node_key(whatsit_node_data, special_node, special)
- init_node_key(whatsit_node_data, save_pos_node, save_pos)
- init_node_key(whatsit_node_data, late_lua_node, late_lua)
- init_node_key(whatsit_node_data, user_defined_node, user_defined)
-
- init_field_key(node_fields_whatsit_close, 0, attr);
- init_field_key(node_fields_whatsit_close, 1, stream);
- init_field_nop(node_fields_whatsit_close, 2);
-
- init_field_key(node_fields_whatsit_late_lua, 0, attr);
- init_field_key(node_fields_whatsit_late_lua, 1, reg);
- init_field_key(node_fields_whatsit_late_lua, 2, data);
- init_field_key(node_fields_whatsit_late_lua, 3, name);
- init_field_key(node_fields_whatsit_late_lua, 4, string);
- init_field_nop(node_fields_whatsit_late_lua, 5);
-
- init_field_key(node_fields_whatsit_open, 0, attr);
- init_field_key(node_fields_whatsit_open, 1, stream);
- init_field_key(node_fields_whatsit_open, 2, name);
- init_field_key(node_fields_whatsit_open, 3, area);
- init_field_key(node_fields_whatsit_open, 4, ext);
- init_field_nop(node_fields_whatsit_open, 5);
-
- init_field_key(node_fields_whatsit_save_pos, 0, attr);
- init_field_nop(node_fields_whatsit_save_pos, 1);
-
- init_field_key(node_fields_whatsit_special, 0, attr);
- init_field_key(node_fields_whatsit_special, 1, data);
- init_field_nop(node_fields_whatsit_special, 2);
-
- init_field_key(node_fields_whatsit_user_defined, 0, attr);
- init_field_key(node_fields_whatsit_user_defined, 1, user_id);
- init_field_key(node_fields_whatsit_user_defined, 2, type);
- init_field_key(node_fields_whatsit_user_defined, 3, value);
- init_field_nop(node_fields_whatsit_user_defined, 4);
-
- init_field_key(node_fields_whatsit_write, 0, attr);
- init_field_key(node_fields_whatsit_write, 1, stream);
- init_field_key(node_fields_whatsit_write, 2, data);
- init_field_nop(node_fields_whatsit_write, 3);
-
- init_node_key(whatsit_node_data, pdf_literal_node, pdf_literal)
- init_node_key(whatsit_node_data, pdf_refobj_node, pdf_refobj)
- init_node_key(whatsit_node_data, pdf_annot_node, pdf_annot)
- init_node_key(whatsit_node_data, pdf_start_link_node, pdf_start_link)
- init_node_key(whatsit_node_data, pdf_end_link_node, pdf_end_link)
- init_node_key(whatsit_node_data, pdf_dest_node, pdf_dest)
- init_node_key(whatsit_node_data, pdf_action_node, pdf_action)
- init_node_key(whatsit_node_data, pdf_thread_node, pdf_thread)
- init_node_key(whatsit_node_data, pdf_start_thread_node,pdf_start_thread)
- init_node_key(whatsit_node_data, pdf_end_thread_node, pdf_end_thread)
- init_node_key(whatsit_node_data, pdf_thread_data_node, pdf_thread_data)
- init_node_key(whatsit_node_data, pdf_link_data_node, pdf_link_data)
- init_node_key(whatsit_node_data, pdf_colorstack_node, pdf_colorstack)
- init_node_key(whatsit_node_data, pdf_setmatrix_node, pdf_setmatrix)
- init_node_key(whatsit_node_data, pdf_save_node, pdf_save)
- init_node_key(whatsit_node_data, pdf_restore_node, pdf_restore)
- init_node_key(whatsit_node_data, pdf_link_state_node, pdf_link_state)
-
- init_node_key(node_values_pdf_destination, 0, xyz)
- init_node_key(node_values_pdf_destination, 1, fit)
- init_node_key(node_values_pdf_destination, 2, fith)
- init_node_key(node_values_pdf_destination, 3, fitv)
- init_node_key(node_values_pdf_destination, 4, fitb)
- init_node_key(node_values_pdf_destination, 5, fitbh)
- init_node_key(node_values_pdf_destination, 6, fitbv)
- init_node_key(node_values_pdf_destination, 7, fitr)
-
- init_node_key(node_values_pdf_literal, set_origin, origin)
- init_node_key(node_values_pdf_literal, direct_page, page)
- init_node_key(node_values_pdf_literal, direct_always, always)
- init_node_key(node_values_pdf_literal, direct_raw, raw)
- init_node_key(node_values_pdf_literal, direct_text, text)
- init_node_key(node_values_pdf_literal, direct_font, font)
- init_node_key(node_values_pdf_literal, scan_special, special)
-
- init_node_key(node_values_pdf_action, 0, page)
- init_node_key(node_values_pdf_action, 1, goto)
- init_node_key(node_values_pdf_action, 2, thread)
- init_node_key(node_values_pdf_action, 3, user)
-
- init_node_key(node_values_pdf_window, 0, unset)
- init_node_key(node_values_pdf_window, 1, new)
- init_node_key(node_values_pdf_window, 2, nonew)
-
- init_node_key(node_values_color_stack, 0, set)
- init_node_key(node_values_color_stack, 1, push)
- init_node_key(node_values_color_stack, 2, pop)
- init_node_key(node_values_color_stack, 3, current)
-
- init_field_key(node_fields_whatsit_pdf_action, 0, action_type);
- init_field_key(node_fields_whatsit_pdf_action, 1, named_id);
- init_field_key(node_fields_whatsit_pdf_action, 2, action_id);
- init_field_key(node_fields_whatsit_pdf_action, 3, file);
- init_field_key(node_fields_whatsit_pdf_action, 4, new_window);
- init_field_key(node_fields_whatsit_pdf_action, 5, data);
- init_field_nop(node_fields_whatsit_pdf_action, 6);
-
- init_field_key(node_fields_whatsit_pdf_annot, 0, attr);
- init_field_key(node_fields_whatsit_pdf_annot, 1, width);
- init_field_key(node_fields_whatsit_pdf_annot, 2, depth);
- init_field_key(node_fields_whatsit_pdf_annot, 3, height);
- init_field_key(node_fields_whatsit_pdf_annot, 4, objnum);
- init_field_key(node_fields_whatsit_pdf_annot, 5, data);
- init_field_nop(node_fields_whatsit_pdf_annot, 6);
-
- init_field_key(node_fields_whatsit_pdf_colorstack, 0, attr);
- init_field_key(node_fields_whatsit_pdf_colorstack, 1, stack);
- init_field_key(node_fields_whatsit_pdf_colorstack, 2, cmd);
- init_field_key(node_fields_whatsit_pdf_colorstack, 3, data);
- init_field_nop(node_fields_whatsit_pdf_colorstack, 4);
-
- init_field_key(node_fields_whatsit_pdf_dest, 0, attr);
- init_field_key(node_fields_whatsit_pdf_dest, 1, width);
- init_field_key(node_fields_whatsit_pdf_dest, 2, depth);
- init_field_key(node_fields_whatsit_pdf_dest, 3, height);
- init_field_key(node_fields_whatsit_pdf_dest, 4, named_id);
- init_field_key(node_fields_whatsit_pdf_dest, 5, dest_id);
- init_field_key(node_fields_whatsit_pdf_dest, 6, dest_type);
- init_field_key(node_fields_whatsit_pdf_dest, 7, xyz_zoom);
- init_field_key(node_fields_whatsit_pdf_dest, 8, objnum);
- init_field_nop(node_fields_whatsit_pdf_dest, 9);
-
- init_field_key(node_fields_whatsit_pdf_end_link, 0, attr);
- init_field_nop(node_fields_whatsit_pdf_end_link, 1);
-
- init_field_key(node_fields_whatsit_pdf_link_state, 0, attr);
- init_field_key(node_fields_whatsit_pdf_link_state, 1, value);
- init_field_nop(node_fields_whatsit_pdf_link_state, 2);
-
- init_field_key(node_fields_whatsit_pdf_end_thread, 0, attr);
- init_field_nop(node_fields_whatsit_pdf_end_thread, 1);
-
- init_field_key(node_fields_whatsit_pdf_literal, 0, attr);
- init_field_key(node_fields_whatsit_pdf_literal, 1, mode);
- init_field_key(node_fields_whatsit_pdf_literal, 2, data);
- init_field_nop(node_fields_whatsit_pdf_literal, 3);
-
- init_field_key(node_fields_whatsit_pdf_refobj, 0, attr);
- init_field_key(node_fields_whatsit_pdf_refobj, 1, objnum);
- init_field_nop(node_fields_whatsit_pdf_refobj, 2);
-
- init_field_key(node_fields_whatsit_pdf_restore, 0, attr);
- init_field_nop(node_fields_whatsit_pdf_restore, 1);
-
- init_field_key(node_fields_whatsit_pdf_save, 0, attr);
- init_field_nop(node_fields_whatsit_pdf_save, 1);
-
- init_field_key(node_fields_whatsit_pdf_setmatrix, 0, attr);
- init_field_key(node_fields_whatsit_pdf_setmatrix, 1, data);
- init_field_nop(node_fields_whatsit_pdf_setmatrix, 2);
-
- init_field_key(node_fields_whatsit_pdf_start_link, 0, attr);
- init_field_key(node_fields_whatsit_pdf_start_link, 1, width);
- init_field_key(node_fields_whatsit_pdf_start_link, 2, depth);
- init_field_key(node_fields_whatsit_pdf_start_link, 3, height);
- init_field_key(node_fields_whatsit_pdf_start_link, 4, objnum);
- init_field_key(node_fields_whatsit_pdf_start_link, 5, link_attr);
- init_field_key(node_fields_whatsit_pdf_start_link, 6, action);
- init_field_nop(node_fields_whatsit_pdf_start_link, 7);
-
- init_field_key(node_fields_whatsit_pdf_start_thread, 0, attr);
- init_field_key(node_fields_whatsit_pdf_start_thread, 1, width);
- init_field_key(node_fields_whatsit_pdf_start_thread, 2, depth);
- init_field_key(node_fields_whatsit_pdf_start_thread, 3, height);
- init_field_key(node_fields_whatsit_pdf_start_thread, 4, named_id);
- init_field_key(node_fields_whatsit_pdf_start_thread, 5, thread_id);
- init_field_key(node_fields_whatsit_pdf_start_thread, 6, thread_attr);
- init_field_nop(node_fields_whatsit_pdf_start_thread, 7);
-
- init_field_key(node_fields_whatsit_pdf_thread, 0, attr);
- init_field_key(node_fields_whatsit_pdf_thread, 1, width);
- init_field_key(node_fields_whatsit_pdf_thread, 2, depth);
- init_field_key(node_fields_whatsit_pdf_thread, 3, height);
- init_field_key(node_fields_whatsit_pdf_thread, 4, named_id);
- init_field_key(node_fields_whatsit_pdf_thread, 5, thread_id);
- init_field_key(node_fields_whatsit_pdf_thread, 6, thread_attr);
- init_field_nop(node_fields_whatsit_pdf_thread, 7);
-
-}
-
-#define last_whatsit_node pdf_restore_node
-
-/*tex
-
- When we copy a node list, there are several possibilities: we do the same as
- a new node, we copy the entry to the table in properties (a reference), we do
- a deep copy of a table in the properties, we create a new table and give it
- the original one as a metatable. After some experiments (that also included
- timing) with these scenarios I decided that a deep copy made no sense, nor
- did nilling. In the end both the shallow copy and the metatable variant were
- both ok, although the second ons is slower. The most important aspect to keep
- in mind is that references to other nodes in properties no longer can be
- valid for that copy. We could use two tables (one unique and one shared) or
- metatables but that only complicates matters.
-
- When defining a new node, we could already allocate a table but it is rather
- easy to do that at the lua end e.g. using a metatable __index method. That
- way it is under macro package control.
-
- When deleting a node, we could keep the slot (e.g. setting it to false) but
- it could make memory consumption raise unneeded when we have temporary large
- node lists and after that only small lists.
-
- So, in the end this is what we ended up with. For the record, I also
- experimented with the following:
-
- \startitemize
-
- \startitem
- Copy attributes to the properties so that we have fast access at the
- lua end: in the end the overhead is not compensated by speed and
- convenience, in fact, attributes are not that slow when it comes to
- accessing them.
- \stopitem
-
- \startitem
- A bitset in the node but again the gain compared to attributes is
- neglectable and it also demands a pretty string agreement over what
- bit represents what, and this is unlikely to succeed in the tex
- community (I could use it for font handling, which is cross package,
- but decided that it doesn't pay off.
- \stopitem
-
- \stopitemize
-
- In case one wonders why properties make sense then, well, it is not so much
- speed that we gain, but more convenience: storing all kind of (temporary)
- data in attributes is no fun and this mechanism makes sure that properties
- are cleaned up when a node is freed. Also, the advantage of a more or less
- global properties table is that we stay at the lua end. An alternative is to
- store a reference in the node itself but that is complicated by the fact that
- the register has some limitations (no numeric keys) and we also don't want to
- mess with it too much.
-
-*/
-
-int lua_properties_level = 0 ;
-int lua_properties_enabled = 0 ;
-int lua_properties_use_metatable = 0 ;
-
-/*tex
-
- We keep track of nesting so that we don't oveflow the stack, and, what is
- more important, don't keep resolving the registry index.
-
-*/
-
-#define lua_properties_push do { \
- if (lua_properties_enabled) { \
- lua_properties_level = lua_properties_level + 1 ; \
- if (lua_properties_level == 1) { \
- lua_get_metatablelua_l(Luas,node_properties); \
- } \
- } \
-} while(0)
-
-#define lua_properties_pop do { \
- if (lua_properties_enabled) { \
- if (lua_properties_level == 1) \
- lua_pop(Luas,1); \
- lua_properties_level = lua_properties_level - 1 ; \
- } \
-} while(0)
-
-/*tex No setting is needed: */
-
-#define lua_properties_set(target) do { \
-} while(0)
-
-/*tex Resetting boils down to nilling. */
-
-#define lua_properties_reset(target) do { \
- if (lua_properties_enabled) { \
- if (lua_properties_level == 0) { \
- lua_get_metatablelua_l(Luas,node_properties); \
- lua_pushnil(Luas); \
- lua_rawseti(Luas,-2,target); \
- lua_pop(Luas,1); \
- } else { \
- lua_pushnil(Luas); \
- lua_rawseti(Luas,-2,target); \
- } \
- } \
-} while(0)
-
-/*tex
-
- For a moment I considered supporting all kind of data types but in practice
- that makes no sense. So we stick to a cheap shallow copy with as option a
- metatable. BTW, a deep copy would look like this:
-
- \starttyping
- static void copy_lua_table(lua_State* L, int index) {
- lua_newtable(L);
- lua_pushnil(L);
- while(lua_next(L, index-1) != 0) {
- lua_pushvalue(L, -2);
- lua_insert(L, -2);
- if (lua_type(L,-1)==LUA_TTABLE)
- copy_lua_table(L,-1);
- lua_settable(L, -4);
- }
- lua_pop(L,1);
- }
-
- #define lua_properties_copy(target, source) do { \
- if (lua_properties_enabled) { \
- lua_pushinteger(Luas,source); \
- lua_rawget(Luas,-2); \
- if (lua_type(Luas,-1)==LUA_TTABLE) { \
- copy_lua_table(Luas,-1); \
- lua_pushinteger(Luas,target); \
- lua_insert(Luas,-2); \
- lua_rawset(Luas,-3); \
- } else { \
- lua_pop(Luas,1); \
- } \
- } \
- } while(0)
- \stoptyping
-
-*/
-
-/*tex Isn't there a faster way to metatable? */
-
-/*tex
-
- \starttyping
- #define lua_properties_copy(target,source) do { \
- if (lua_properties_enabled) { \
- if (lua_properties_level == 0) { \
- lua_get_metatablelua_l(Luas,node_properties); \
- lua_rawgeti(Luas,-1,source); \
- if (lua_type(Luas,-1)==LUA_TTABLE) { \
- if (lua_properties_use_metatable) { \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setfield(Luas,-2,"__index"); \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setmetatable(Luas,-2); \
- } \
- lua_rawseti(Luas,-2,target); \
- } else { \
- lua_pop(Luas,1); \
- } \
- lua_pop(Luas,1); \
- } else { \
- lua_rawgeti(Luas,-1,source); \
- if (lua_type(Luas,-1)==LUA_TTABLE) { \
- if (lua_properties_use_metatable) { \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setfield(Luas,-2,"__index"); \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setmetatable(Luas,-2); \
- } \
- lua_rawseti(Luas,-2,target); \
- } else { \
- lua_pop(Luas,1); \
- } \
- } \
- } \
- } while(0)
- \stoptyping
-
-*/
-
-/*tex
-
- A simple testrun on many pages of dumb text shows 1% gain (of course it
- depends on how properties are used but some other tests confirm it).
-
-*/
-
-#define lua_properties_copy(target,source) do { \
- if (lua_properties_enabled) { \
- if (lua_properties_level == 0) { \
- lua_get_metatablelua_l(Luas,node_properties); \
- lua_rawgeti(Luas,-1,source); \
- if (lua_type(Luas,-1)==LUA_TTABLE) { \
- if (lua_properties_use_metatable) { \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_push_string_by_name(Luas,__index); \
- lua_insert(Luas,-2); \
- lua_rawset(Luas, -3); \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setmetatable(Luas,-2); \
- } \
- lua_rawseti(Luas,-2,target); \
- } else { \
- lua_pop(Luas,1); \
- } \
- lua_pop(Luas,1); \
- } else { \
- lua_rawgeti(Luas,-1,source); \
- if (lua_type(Luas,-1)==LUA_TTABLE) { \
- if (lua_properties_use_metatable) { \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_push_string_by_name(Luas,__index); \
- lua_insert(Luas,-2); \
- lua_rawset(Luas, -3); \
- lua_newtable(Luas); \
- lua_insert(Luas,-2); \
- lua_setmetatable(Luas,-2); \
- } \
- lua_rawseti(Luas,-2,target); \
- } else { \
- lua_pop(Luas,1); \
- } \
- } \
- } \
-} while(0)
-
-/*tex Here end the property handlers. */
-
-int valid_node(halfword p)
-{
- if (p > my_prealloc && p < var_mem_max) {
-#ifdef CHECK_NODE_USAGE
- if (varmem_sizes[p] > 0) {
- return 1;
- }
-#else
- return 1;
-#endif
- }
- return 0;
-}
-
-static int test_count = 1;
-
-#define dorangetest(a,b,c) do { \
- if (!(b>=0 && b<c)) { \
- fprintf(stdout,"For node p:=%d, 0<=%d<%d (l.%d,r.%d)\n", \
- (int)a, (int)b, (int)c, __LINE__,test_count); \
- confusion("node range test failed"); \
- } } while (0)
-
-#define dotest(a,b,c) do { \
- if (b!=c) { \
- fprintf(stdout,"For node p:=%d, %d==%d (l.%d,r.%d)\n", \
- (int)a, (int)b, (int)c, __LINE__,test_count); \
- confusion("node test failed"); \
- } } while (0)
-
-#define check_action_ref(a) { dorangetest(p,a,var_mem_max); }
-#define check_attribute_ref(a) { dorangetest(p,a,var_mem_max); }
-
-/*tex hm, we can just pass |p| then. */
-
-#define check_token_ref(p) { \
- if (type(p) == whatsit_node) { \
- formatted_error("nodes","fuzzy token cleanup in whatsit node with type %s and subtype %i",node_data[type(p)].name,subtype(p)); \
- } else { \
- formatted_error("nodes","fuzzy token cleanup in node with type %s",node_data[type(p)].name); \
- } \
-}
-
-#ifdef CHECK_NODE_USAGE
-
-static void check_static_node_mem(void)
-{
- dotest(zero_glue, width(zero_glue), 0);
- dotest(zero_glue, type(zero_glue), glue_spec_node);
- dotest(zero_glue, vlink(zero_glue), null);
- dotest(zero_glue, stretch(zero_glue), 0);
- dotest(zero_glue, stretch_order(zero_glue), normal);
- dotest(zero_glue, shrink(zero_glue), 0);
- dotest(zero_glue, shrink_order(zero_glue), normal);
-
- dotest(sfi_glue, width(sfi_glue), 0);
- dotest(sfi_glue, type(sfi_glue), glue_spec_node);
- dotest(sfi_glue, vlink(sfi_glue), null);
- dotest(sfi_glue, stretch(sfi_glue), 0);
- dotest(sfi_glue, stretch_order(sfi_glue), sfi);
- dotest(sfi_glue, shrink(sfi_glue), 0);
- dotest(sfi_glue, shrink_order(sfi_glue), normal);
-
- dotest(fil_glue, width(fil_glue), 0);
- dotest(fil_glue, type(fil_glue), glue_spec_node);
- dotest(fil_glue, vlink(fil_glue), null);
- dotest(fil_glue, stretch(fil_glue), unity);
- dotest(fil_glue, stretch_order(fil_glue), fil);
- dotest(fil_glue, shrink(fil_glue), 0);
- dotest(fil_glue, shrink_order(fil_glue), normal);
-
- dotest(fill_glue, width(fill_glue), 0);
- dotest(fill_glue, type(fill_glue), glue_spec_node);
- dotest(fill_glue, vlink(fill_glue), null);
- dotest(fill_glue, stretch(fill_glue), unity);
- dotest(fill_glue, stretch_order(fill_glue), fill);
- dotest(fill_glue, shrink(fill_glue), 0);
- dotest(fill_glue, shrink_order(fill_glue), normal);
-
- dotest(ss_glue, width(ss_glue), 0);
- dotest(ss_glue, type(ss_glue), glue_spec_node);
- dotest(ss_glue, vlink(ss_glue), null);
- dotest(ss_glue, stretch(ss_glue), unity);
- dotest(ss_glue, stretch_order(ss_glue), fil);
- dotest(ss_glue, shrink(ss_glue), unity);
- dotest(ss_glue, shrink_order(ss_glue), fil);
-
- dotest(fil_neg_glue, width(fil_neg_glue), 0);
- dotest(fil_neg_glue, type(fil_neg_glue), glue_spec_node);
- dotest(fil_neg_glue, vlink(fil_neg_glue), null);
- dotest(fil_neg_glue, stretch(fil_neg_glue), -unity);
- dotest(fil_neg_glue, stretch_order(fil_neg_glue), fil);
- dotest(fil_neg_glue, shrink(fil_neg_glue), 0);
- dotest(fil_neg_glue, shrink_order(fil_neg_glue), normal);
-}
-
-static void node_mem_dump(halfword p)
-{
- halfword r;
- for (r = my_prealloc + 1; r < var_mem_max; r++) {
- if (vlink(r) == p) {
- halfword s = r;
- while (s > my_prealloc && varmem_sizes[s] == 0) {
- s--;
- }
- if (s != null
- && s != my_prealloc
- && s != var_mem_max
- && (r - s) < get_node_size(type(s), subtype(s))
- && alink(s) != p) {
- if (type(s) == disc_node) {
- fprintf(stdout," pointed to from %s node %d (vlink %d, alink %d): ",
- get_node_name(type(s), subtype(s)), (int) s,
- (int) vlink(s), (int) alink(s));
- fprintf(stdout, "pre_break(%d,%d,%d), ",
- (int) vlink_pre_break(s), (int) tlink(pre_break(s)),
- (int) alink(pre_break(s)));
- fprintf(stdout, "post_break(%d,%d,%d), ",
- (int) vlink_post_break(s),
- (int) tlink(post_break(s)),
- (int) alink(post_break(s)));
- fprintf(stdout, "no_break(%d,%d,%d)",
- (int) vlink_no_break(s), (int) tlink(no_break(s)),
- (int) alink(no_break(s)));
- fprintf(stdout, "\n");
- } else {
- if (vlink(s) == p
- || (type(s) == glyph_node && lig_ptr (s) == p)
- || (type(s) == vlist_node && list_ptr(s) == p)
- || (type(s) == hlist_node && list_ptr(s) == p)
- || (type(s) == unset_node && list_ptr(s) == p)
- || (type(s) == ins_node && ins_ptr (s) == p)
- ) {
- fprintf(stdout," pointed to from %s node %d (vlink %d, alink %d): ",
- get_node_name(type(s), subtype(s)), (int) s,
- (int) vlink(s), (int) alink(s));
- if (type(s) == glyph_node) {
- fprintf(stdout, "lig_ptr(%d)", (int) lig_ptr(s));
- } else if (type(s) == vlist_node || type(s) == hlist_node) {
- fprintf(stdout, "list_ptr(%d)", (int) list_ptr(s));
- }
- fprintf(stdout, "\n");
- } else {
- if ((type(s) != penalty_node) && (type(s) != math_node) && (type(s) != kern_node)) {
- fprintf(stdout, " pointed to from %s node %d\n",
- get_node_name(type(s), subtype(s)), (int) s);
- }
- }
- }
- }
- }
- }
-}
-
-#endif
-
-static int free_error(halfword p)
-{
- if (p > my_prealloc && p < var_mem_max) {
-#ifdef CHECK_NODE_USAGE
- int i;
- if (varmem_sizes[p] == 0) {
- check_static_node_mem();
- for (i = (my_prealloc + 1); i < var_mem_max; i++) {
- if (varmem_sizes[i] > 0) {
- check_node(i);
- }
- }
- test_count++;
- if (type(p) == glyph_node) {
- formatted_error("nodes", "attempt to double-free glyph (%c) node %d, ignored", (int) character(p), (int) p);
- } else {
- formatted_error("nodes", "attempt to double-free %s node %d, ignored", get_node_name(type(p), subtype(p)), (int) p);
- }
- node_mem_dump(p);
- return 1;
- }
-#endif
- } else {
- formatted_error("nodes", "attempt to free an impossible node %d", (int) p);
- return 1;
- }
- return 0;
-}
-
-static int copy_error(halfword p)
-{
- if (p >= 0 && p < var_mem_max) {
-#ifdef CHECK_NODE_USAGE
- if (p > my_prealloc && varmem_sizes[p] == 0) {
- if (type(p) == glyph_node) {
- formatted_warning("nodes", "attempt to copy free glyph (%c) node %d, ignored", (int) character(p), (int) p);
- } else {
- formatted_warning("nodes", "attempt to copy free %s node %d, ignored", get_node_name(type(p), subtype(p)), (int) p);
- }
- return 1;
- }
-#endif
- } else {
- formatted_error("nodes", "attempt to copy an impossible node %d", (int) p);
- return 1;
- }
- return 0;
-}
-
-/*tex
-
- Because of the 5-10\% overhead that \SYNTEX\ creates some options have been
- implemented controlled by |synctex_anyway_mode|.
-
- \startabulate
- \NC \type {1} \NC all but glyphs \NC \NR
- \NC \type {2} \NC also glyphs \NC \NR
- \NC \type {3} \NC glyphs and glue \NC \NR
- \NC \type {4} \NC only glyphs \NC \NR
- \stoptabulate
-
-*/
-
-static halfword synctex_anyway_mode = 0;
-static halfword synctex_line_field = 0;
-static halfword synctex_no_files = 0;
-
-void synctex_set_mode(int m)
-{
- synctex_anyway_mode = m;
-};
-
-int synctex_get_mode(void)
-{
- return synctex_anyway_mode;
-};
-
-void synctex_set_no_files(int f)
-{
- synctex_no_files = f;
-};
-
-int synctex_get_no_files(void)
-{
- return (int) synctex_no_files ;
-};
-
-void synctex_set_tag(int t)
-{
- cur_input.synctex_tag_field = t;
-};
-
-int synctex_get_tag(void)
-{
- return (int) cur_input.synctex_tag_field;
-};
-
-int synctex_get_line(void)
-{
- return (int) synctex_line_field;
-};
-
-static int forced_tag = 0;
-static int forced_line = 0;
-
-void synctex_force_tag(int t)
-{
- forced_tag = t;
-};
-
-void synctex_force_line(int t)
-{
- forced_line = t;
-};
-
-void synctex_set_line(int l)
-{
- synctex_line_field = l;
-};
-
-/*tex |if_stack| is called a lot so maybe optimize that one. */
-
-halfword new_node(int i, int j)
-{
- int s = get_node_size(i, j);
- halfword n = get_node(s);
- /*tex
-
- It should be possible to do this memset at |free_node()|. Both type() and
- subtype() will be set below, and vlink() is set to null by |get_node()|,
- so we can do we clearing one word less than |s|.
-
- */
- (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * ((unsigned) s - 1)));
- switch (i) {
- case glyph_node:
- init_lang_data(n);
- break;
- case hlist_node:
- case vlist_node:
- box_dir(n) = -1;
- break;
- case disc_node:
- pre_break(n) = pre_break_head(n);
- type(pre_break(n)) = nesting_node;
- subtype(pre_break(n)) = pre_break_head(0);
- post_break(n) = post_break_head(n);
- type(post_break(n)) = nesting_node;
- subtype(post_break(n)) = post_break_head(0);
- no_break(n) = no_break_head(n);
- type(no_break(n)) = nesting_node;
- subtype(no_break(n)) = no_break_head(0);
- break;
- case rule_node:
- depth(n) = null_flag;
- height(n) = null_flag;
- width(n) = null_flag;
- rule_dir(n) = -1;
- rule_index(n) = 0;
- rule_transform(n) = 0;
- break;
- case whatsit_node:
- if (j == open_node) {
- open_name(n) = get_nullstr();
- open_area(n) = open_name(n);
- open_ext(n) = open_name(n);
- }
- break;
- case unset_node:
- width(n) = null_flag;
- break;
- case pseudo_line_node:
- case shape_node:
- /*tex
-
- This is a trick that makes |pseudo_files| slightly slower, but
- the overall allocation faster then an explicit test at the top of
- |new_node()|.
-
- */
- if (j>0) {
- free_node(n, variable_node_size);
- n = slow_get_node(j);
- (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * ((unsigned) j - 1)));
- }
- break;
- case fraction_noad:
- fraction_fam(n) = -1;
- break;
- case simple_noad:
- noad_fam(n) = -1;
- break;
- default:
- break;
- }
- if (synctex_anyway_mode) {
- /*tex See table above. */
- switch (i) {
- case glyph_node:
- if (synctex_anyway_mode > 1) {
- synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- case glue_node:
- if (synctex_anyway_mode < 4) {
- synctex_tag_glue(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_glue(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- case kern_node:
- if (synctex_anyway_mode < 3) {
- synctex_tag_kern(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_kern(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- case hlist_node:
- case vlist_node:
- case unset_node:
- /*tex Rather useless: */
- if (synctex_anyway_mode < 3) {
- synctex_tag_box(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_box(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- case rule_node:
- if (synctex_anyway_mode < 3) {
- synctex_tag_rule(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_rule(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- case math_node:
- /*tex Noads probably make more sense but let's not change that. */
- if (synctex_anyway_mode < 3) {
- synctex_tag_math(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_math(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- break;
- }
- } else if (synctex_par) {
- /*tex Handle the \SYNTEX\ extension. */
- switch (i) {
- case glue_node:
- synctex_tag_glue(n) = cur_input.synctex_tag_field;
- synctex_line_glue(n) = line;
- break;
- case kern_node:
- if (j != 0) {
- synctex_tag_kern(n) = cur_input.synctex_tag_field;
- synctex_line_kern(n) = line;
- }
- break;
- case hlist_node:
- case vlist_node:
- case unset_node:
- synctex_tag_box(n) = cur_input.synctex_tag_field;
- synctex_line_box(n) = line;
- break;
- case rule_node:
- synctex_tag_rule(n) = cur_input.synctex_tag_field;
- synctex_line_rule(n) = line;
- break;
- case math_node:
- synctex_tag_math(n) = cur_input.synctex_tag_field;
- synctex_line_math(n) = line;
- break;
- }
- }
- /*tex Take care of attributes. */
- if (nodetype_has_attributes(i)) {
- build_attribute_list(n);
- /*tex No need for |lua_properties_set|. */
- }
- type(n) = (quarterword) i;
- subtype(n) = (quarterword) j;
- return n;
-}
-
-halfword raw_glyph_node(void)
-{
- register halfword n = get_node(glyph_node_size);
- (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1)));
- if (synctex_anyway_mode > 1) {
- synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- type(n) = glyph_node;
- subtype(n) = 0;
- return n;
-}
-
-halfword new_glyph_node(void)
-{
- register halfword n = get_node(glyph_node_size);
- (void) memset((void *) (varmem + n + 1), 0, (sizeof(memory_word) * (glyph_node_size - 1)));
- if (synctex_anyway_mode > 1) {
- synctex_tag_glyph(n) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_glyph(n) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- type(n) = glyph_node;
- subtype(n) = 0;
- build_attribute_list(n);
- /*tex No need for |lua_properties_set|. */
- return n;
-}
-
-/*tex
-
- This makes a duplicate of the node list that starts at |p| and returns a
- pointer to the new list.
-
-*/
-
-halfword do_copy_node_list(halfword p, halfword end)
-{
- /*tex previous position in new list */
- halfword q = null;
- /*tex head of the list */
- halfword h = null;
- register halfword s ;
- /*tex saves stack and time */
- lua_properties_push;
- while (p != end) {
- s = copy_node(p);
- if (h == null) {
- h = s;
- } else {
- couple_nodes(q, s);
- }
- q = s;
- p = vlink(p);
- }
- /*tex saves stack and time */
- lua_properties_pop;
- return h;
-}
-
-halfword copy_node_list(halfword p)
-{
- return do_copy_node_list(p, null);
-}
-
-#define copy_sub_list(target,source) do { \
- if (source != null) { \
- s = do_copy_node_list(source, null); \
- target = s; \
- } else { \
- target = null; \
- } \
- } while (0)
-
-#define copy_sub_node(target,source) do { \
- if (source != null) { \
- s = copy_node(source); \
- target = s ; \
- } else { \
- target = null; \
- } \
-} while (0)
-
-/*tex Make a dupe of a single node. */
-
-static void copy_node_wrapup_core(halfword p, halfword r)
-{
- halfword s ;
- switch (subtype(p)) {
- case write_node:
- case special_node:
- add_token_ref(write_tokens(p));
- break;
- case late_lua_node:
- copy_late_lua(r, p);
- break;
- case user_defined_node:
- switch (user_node_type(p)) {
- case 'a':
- add_node_attr_ref(user_node_value(p));
- break;
- case 'l':
- copy_user_lua(r, p);
- break;
- case 'n':
- s = copy_node_list(user_node_value(p));
- user_node_value(r) = s;
- break;
- case 's':
- /* |add_string_ref(user_node_value(p));| */
- break;
- case 't':
- add_token_ref(user_node_value(p));
- break;
- }
- break;
- default:
- break ;
- }
-}
-
-void copy_node_wrapup_dvi(halfword p, halfword r)
-{
-}
-
-void copy_node_wrapup_pdf(halfword p, halfword r)
-{
- switch(subtype(p)) {
- case pdf_literal_node:
- copy_pdf_literal(r, p);
- break;
- case pdf_colorstack_node:
- if (pdf_colorstack_cmd(p) <= colorstack_data)
- add_token_ref(pdf_colorstack_data(p));
- break;
- case pdf_setmatrix_node:
- add_token_ref(pdf_setmatrix_data(p));
- break;
- case pdf_annot_node:
- add_token_ref(pdf_annot_data(p));
- break;
- case pdf_start_link_node:
- if (pdf_link_attr(r) != null)
- add_token_ref(pdf_link_attr(r));
- add_action_ref(pdf_link_action(r));
- break;
- case pdf_dest_node:
- if (pdf_dest_named_id(p) > 0)
- add_token_ref(pdf_dest_id(p));
- break;
- case pdf_thread_node:
- case pdf_start_thread_node:
- if (pdf_thread_named_id(p) > 0)
- add_token_ref(pdf_thread_id(p));
- if (pdf_thread_attr(p) != null)
- add_token_ref(pdf_thread_attr(p));
- break;
- default:
- break;
- }
-}
-
-halfword copy_node(const halfword p)
-{
- /*tex current node being fabricated for new list */
- halfword r;
- /*tex whatsit subtype */
- halfword w;
- /*tex type of node */
- halfword t;
- /*tex a helper variable for copying into variable mem */
- register halfword s;
- register int i;
- if (copy_error(p)) {
- r = new_node(temp_node, 0);
- return r;
- }
- t = type(p);
- i = get_node_size(t,subtype(p));
- r = get_node(i);
- (void) memcpy((void *) (varmem + r), (void *) (varmem + p), (sizeof(memory_word) * (unsigned) i));
- /*tex A possible speedup:
-
- \starttyping
- if t == glue_spec) {
- return r;
- }
- \stoptyping
-
- */
- if (synctex_anyway_mode) {
- /*tex Not:
-
- \starttyping
- if (t == glyph_node) {
- if (synctex_anyway_mode > 1) {
- synctex_tag_glyph(r) = forced_tag ? forced_tag : cur_input.synctex_tag_field;
- synctex_line_glyph(r) = forced_line ? forced_line : synctex_line_field ? synctex_line_field : line;
- }
- }
- \stoptyping
- */
- } else if (synctex_par) {
- /*tex Handle synctex extension. */
- switch (t) {
- case math_node:
- synctex_tag_math(r) = cur_input.synctex_tag_field;
- synctex_line_math(r) = line;
- break;
- case kern_node:
- synctex_tag_kern(r) = cur_input.synctex_tag_field;
- synctex_line_kern(r) = line;
- break;
- }
- }
- if (nodetype_has_attributes(t)) {
- add_node_attr_ref(node_attr(p));
- alink(r) = null;
- lua_properties_copy(r,p);
- }
- vlink(r) = null;
- switch (t) {
- case glyph_node:
- copy_sub_list(lig_ptr(r),lig_ptr(p)) ;
- break;
- case glue_node:
- copy_sub_list(leader_ptr(r),leader_ptr(p)) ;
- break;
- case hlist_node:
- case vlist_node:
- case unset_node:
- copy_sub_list(list_ptr(r),list_ptr(p)) ;
- break;
- case disc_node:
- pre_break(r) = pre_break_head(r);
- if (vlink_pre_break(p) != null) {
- s = copy_node_list(vlink_pre_break(p));
- alink(s) = pre_break(r);
- tlink_pre_break(r) = tail_of_list(s);
- vlink_pre_break(r) = s;
- } else {
- assert(tlink(pre_break(r)) == null);
- }
- post_break(r) = post_break_head(r);
- if (vlink_post_break(p) != null) {
- s = copy_node_list(vlink_post_break(p));
- alink(s) = post_break(r);
- tlink_post_break(r) = tail_of_list(s);
- vlink_post_break(r) = s;
- } else {
- assert(tlink_post_break(r) == null);
- }
- no_break(r) = no_break_head(r);
- if (vlink(no_break(p)) != null) {
- s = copy_node_list(vlink_no_break(p));
- alink(s) = no_break(r);
- tlink_no_break(r) = tail_of_list(s);
- vlink_no_break(r) = s;
- } else {
- assert(tlink_no_break(r) == null);
- }
- break;
- case math_node:
- break;
- case ins_node:
- copy_sub_list(ins_ptr(r),ins_ptr(p)) ;
- break;
- case margin_kern_node:
- copy_sub_node(margin_char(r),margin_char(p));
- break;
- case mark_node:
- add_token_ref(mark_ptr(p));
- break;
- case adjust_node:
- copy_sub_list(adjust_ptr(r),adjust_ptr(p));
- break;
- case choice_node:
- copy_sub_list(display_mlist(r),display_mlist(p)) ;
- copy_sub_list(text_mlist(r),text_mlist(p)) ;
- copy_sub_list(script_mlist(r),script_mlist(p)) ;
- copy_sub_list(script_script_mlist(r),script_script_mlist(p)) ;
- break;
- case simple_noad:
- copy_sub_list(nucleus(r),nucleus(p)) ;
- copy_sub_list(subscr(r),subscr(p)) ;
- copy_sub_list(supscr(r),supscr(p)) ;
- break;
- case radical_noad:
- copy_sub_list(nucleus(r),nucleus(p)) ;
- copy_sub_list(subscr(r),subscr(p)) ;
- copy_sub_list(supscr(r),supscr(p)) ;
- copy_sub_node(left_delimiter(r),left_delimiter(p)) ;
- copy_sub_list(degree(r),degree(p)) ;
- break;
- case accent_noad:
- copy_sub_list(nucleus(r),nucleus(p)) ;
- copy_sub_list(subscr(r),subscr(p)) ;
- copy_sub_list(supscr(r),supscr(p)) ;
- copy_sub_list(top_accent_chr(r),top_accent_chr(p)) ;
- copy_sub_list(bot_accent_chr(r),bot_accent_chr(p)) ;
- copy_sub_list(overlay_accent_chr(r),overlay_accent_chr(p)) ;
- break;
- case fence_noad:
- copy_sub_node(delimiter(r),delimiter(p)) ;
- break;
- case sub_box_node:
- case sub_mlist_node:
- copy_sub_list(math_list(r),math_list(p)) ;
- break;
- case fraction_noad:
- copy_sub_list(numerator(r),numerator(p)) ;
- copy_sub_list(denominator(r),denominator(p)) ;
- copy_sub_node(left_delimiter(r),left_delimiter(p)) ;
- copy_sub_node(right_delimiter(r),right_delimiter(p)) ;
- break;
- case glue_spec_node:
- break;
- case dir_node:
- break;
- case local_par_node:
- copy_sub_list(local_box_left(r),local_box_left(p));
- copy_sub_list(local_box_right(r),local_box_right(p));
- case boundary_node:
- break;
- case whatsit_node:
- w = subtype(p) ;
- if (w >= backend_first_pdf_whatsit) {
- copy_node_wrapup_pdf(p,r);
- } else if (w >= backend_first_dvi_whatsit) {
- copy_node_wrapup_dvi(p,r);
- } else {
- copy_node_wrapup_core(p,r);
- }
- break;
- }
- return r;
-}
-
-#define free_sub_list(source) if (source != null) flush_node_list(source);
-#define free_sub_node(source) if (source != null) flush_node(source);
-
-static void flush_node_wrapup_core(halfword p)
-{
- switch (subtype(p)) {
- case open_node:
- case write_node:
- case close_node:
- case save_pos_node:
- break;
- case special_node:
- delete_token_ref(write_tokens(p));
- break;
- case late_lua_node:
- free_late_lua(p);
- break;
- case user_defined_node:
- switch (user_node_type(p)) {
- case 'a':
- delete_attribute_ref(user_node_value(p));
- break;
- case 'd':
- break;
- case 'l':
- free_user_lua(p);
- break;
- case 'n':
- flush_node_list(user_node_value(p));
- break;
- case 's':
- /*tex |delete_string_ref(user_node_value(p));| *//* if this was mpost .. */
- break;
- case 't':
- delete_token_ref(user_node_value(p));
- break;
- default:
- {
- const char *hlp[] = {
- "The type of the value in a user defined whatsit node should be one",
- "of 'a' (attribute list), 'd' (number), 'n' (node list), 's' (string),",
- "or 't' (tokenlist). Yours has an unknown type, and therefore I don't",
- "know how to free the node's value. A memory leak may result.",
- NULL
- };
- tex_error("Unidentified user defined whatsit", hlp);
- }
- break;
- }
- break;
- }
-}
-
-void flush_node_wrapup_dvi(halfword p)
-{
-}
-
-void flush_node_wrapup_pdf(halfword p)
-{
- switch(subtype(p)) {
- case pdf_save_node:
- case pdf_restore_node:
- case pdf_link_state_node:
- case pdf_refobj_node:
- case pdf_end_link_node:
- case pdf_end_thread_node:
- break;
- case pdf_literal_node:
- free_pdf_literal(p);
- break;
- case pdf_colorstack_node:
- if (pdf_colorstack_cmd(p) <= colorstack_data)
- delete_token_ref(pdf_colorstack_data(p));
- break;
- case pdf_setmatrix_node:
- delete_token_ref(pdf_setmatrix_data(p));
- break;
- case pdf_annot_node:
- delete_token_ref(pdf_annot_data(p));
- break;
- case pdf_link_data_node:
- break;
- case pdf_start_link_node:
- if (pdf_link_attr(p) != null)
- delete_token_ref(pdf_link_attr(p));
- delete_action_ref(pdf_link_action(p));
- break;
- case pdf_dest_node:
- if (pdf_dest_named_id(p) > 0)
- delete_token_ref(pdf_dest_id(p));
- break;
- case pdf_action_node:
- if (pdf_action_type(p) == pdf_action_user) {
- delete_token_ref(pdf_action_tokens(p));
- } else {
- if (pdf_action_file(p) != null)
- delete_token_ref(pdf_action_file(p));
- if (pdf_action_type(p) == pdf_action_page)
- delete_token_ref(pdf_action_tokens(p));
- else if (pdf_action_named_id(p) > 0)
- delete_token_ref(pdf_action_id(p));
- }
- break;
- case pdf_thread_data_node:
- break;
- case pdf_thread_node:
- case pdf_start_thread_node:
- if (pdf_thread_named_id(p) > 0)
- delete_token_ref(pdf_thread_id(p));
- if (pdf_thread_attr(p) != null)
- delete_token_ref(pdf_thread_attr(p));
- break;
- }
-}
-
-void flush_node(halfword p)
-{
- halfword w;
- if (p == null){
- /*tex legal, but no-op. */
- return;
- }
- if (free_error(p))
- return;
- switch (type(p)) {
- case glyph_node:
- free_sub_list(lig_ptr(p));
- break;
- case glue_node:
- free_sub_list(leader_ptr(p));
- break;
- case hlist_node:
- case vlist_node:
- case unset_node:
- free_sub_list(list_ptr(p));
- break;
- case disc_node:
- /*tex Watch the start at temp node hack! */
- free_sub_list(vlink(pre_break(p)));
- free_sub_list(vlink(post_break(p)));
- free_sub_list(vlink(no_break(p)));
- break;
- case rule_node:
- case kern_node:
- case penalty_node:
- case math_node:
- break;
- case glue_spec_node:
- /*tex This allows free-ing of lua-allocated glue specs. */
- break ;
- case dir_node:
- break;
- case local_par_node:
- free_sub_list(local_box_left(p));
- free_sub_list(local_box_right(p));
- break;
- case boundary_node:
- break;
- case whatsit_node:
- w = subtype(p) ;
- if (w >= backend_first_pdf_whatsit) {
- flush_node_wrapup_pdf(p);
- } else if (w >= backend_first_dvi_whatsit) {
- flush_node_wrapup_dvi(p);
- } else {
- flush_node_wrapup_core(p);
- }
- break;
- case ins_node:
- flush_node_list(ins_ptr(p));
- break;
- case margin_kern_node:
- flush_node(margin_char(p));
- break;
- case mark_node:
- delete_token_ref(mark_ptr(p));
- break;
- case adjust_node:
- flush_node_list(adjust_ptr(p));
- break;
- case style_node:
- /*tex Nothing to do. */
- break;
- case choice_node:
- free_sub_list(display_mlist(p));
- free_sub_list(text_mlist(p));
- free_sub_list(script_mlist(p));
- free_sub_list(script_script_mlist(p));
- break;
- case simple_noad:
- free_sub_list(nucleus(p));
- free_sub_list(subscr(p));
- free_sub_list(supscr(p));
- break;
- case radical_noad:
- free_sub_list(nucleus(p));
- free_sub_list(subscr(p));
- free_sub_list(supscr(p));
- free_sub_node(left_delimiter(p));
- free_sub_list(degree(p));
- break;
- case accent_noad:
- free_sub_list(nucleus(p));
- free_sub_list(subscr(p));
- free_sub_list(supscr(p));
- free_sub_list(top_accent_chr(p));
- free_sub_list(bot_accent_chr(p));
- free_sub_list(overlay_accent_chr(p));
- break;
- case fence_noad:
- free_sub_list(delimiter(p));
- break;
- case delim_node:
- case math_char_node:
- case math_text_char_node:
- /*tex Nothing to do. */
- break;
- case sub_box_node:
- case sub_mlist_node:
- free_sub_list(math_list(p));
- break;
- case fraction_noad:
- free_sub_list(numerator(p));
- free_sub_list(denominator(p));
- free_sub_node(left_delimiter(p));
- free_sub_node(right_delimiter(p));
- break;
- case pseudo_file_node:
- free_sub_list(pseudo_lines(p));
- break;
- case pseudo_line_node:
- case shape_node:
- free_node(p, subtype(p));
- return;
- break;
- case align_stack_node:
- case span_node:
- case movement_node:
- case if_node:
- case nesting_node:
- case unhyphenated_node:
- case hyphenated_node:
- case delta_node:
- case passive_node:
- case inserting_node:
- case split_up_node:
- case expr_node:
- case attribute_node:
- case attribute_list_node:
- case temp_node:
- break;
- default:
- formatted_error("nodes","flushing weird node type %d", type(p));
- return;
- }
- if (nodetype_has_attributes(type(p))) {
- delete_attribute_ref(node_attr(p));
- lua_properties_reset(p);
- }
- free_node(p, get_node_size(type(p), subtype(p)));
- return;
-}
-
-/*tex Erase the list of nodes starting at |pp|. */
-
-void flush_node_list(halfword pp)
-{
- register halfword p = pp;
- if (p == null) {
- /*tex Legal, but no-op. */
- return;
- }
- if (free_error(p))
- return;
- /*tex Saves stack and time. */
- lua_properties_push;
- while (p != null) {
- register halfword q = vlink(p);
- flush_node(p);
- p = q;
- }
- /*tex Saves stack and time. */
- lua_properties_pop;
-}
-
-static void check_node_wrapup_core(halfword p)
-{
- switch (subtype(p)) {
- /*tex Frontend code. */
- case special_node:
- check_token_ref(p);
- break;
- case user_defined_node:
- switch (user_node_type(p)) {
- case 'a':
- check_attribute_ref(user_node_value(p));
- break;
- case 't':
- check_token_ref(p);
- break;
- case 'n':
- dorangetest(p, user_node_value(p), var_mem_max);
- break;
- case 's':
- case 'd':
- case 'l':
- break;
- default:
- confusion("unknown user node type");
- break;
- }
- break;
- case open_node:
- case write_node:
- case close_node:
- case save_pos_node:
- break;
- }
-}
-
-void check_node_wrapup_dvi(halfword p)
-{
-}
-
-void check_node_wrapup_pdf(halfword p)
-{
- switch (subtype(p)) {
- case pdf_literal_node:
- if (pdf_literal_type(p) == normal)
- check_token_ref(p);
- break;
- case pdf_colorstack_node:
- if (pdf_colorstack_cmd(p) <= colorstack_data)
- check_token_ref(p);
- break;
- case pdf_setmatrix_node:
- check_token_ref(p);
- break;
- case late_lua_node:
- if (late_lua_name(p) > 0)
- check_token_ref(p);
- if (late_lua_type(p) == normal)
- check_token_ref(p);
- break;
- case pdf_annot_node:
- check_token_ref(p);
- break;
- case pdf_start_link_node:
- if (pdf_link_attr(p) != null)
- check_token_ref(p);
- check_action_ref(pdf_link_action(p));
- break;
- case pdf_dest_node:
- if (pdf_dest_named_id(p) > 0)
- check_token_ref(p);
- break;
- case pdf_thread_node:
- case pdf_start_thread_node:
- if (pdf_thread_named_id(p) > 0)
- check_token_ref(p);
- if (pdf_thread_attr(p) != null)
- check_token_ref(p);
- break;
- case pdf_save_node:
- case pdf_restore_node:
- case pdf_link_state_node:
- case pdf_refobj_node:
- case pdf_end_link_node:
- case pdf_end_thread_node:
- break;
- default:
- confusion("wrapup pdf nodes");
- break;
- }
-}
-
-void check_node(halfword p)
-{
- halfword w ;
- switch (type(p)) {
- case glyph_node:
- dorangetest(p, lig_ptr(p), var_mem_max);
- break;
- case glue_node:
- dorangetest(p, leader_ptr(p), var_mem_max);
- break;
- case hlist_node:
- case vlist_node:
- case unset_node:
- case align_record_node:
- dorangetest(p, list_ptr(p), var_mem_max);
- break;
- case ins_node:
- dorangetest(p, ins_ptr(p), var_mem_max);
- break;
- case whatsit_node:
- w = subtype(p) ;
- if (w >= backend_first_pdf_whatsit) {
- check_node_wrapup_pdf(p);
- } else if (w >= backend_first_dvi_whatsit) {
- check_node_wrapup_dvi(p);
- } else {
- check_node_wrapup_core(p);
- }
- break;
- case margin_kern_node:
- check_node(margin_char(p));
- break;
- case math_node:
- break;
- case disc_node:
- dorangetest(p, vlink(pre_break(p)), var_mem_max);
- dorangetest(p, vlink(post_break(p)), var_mem_max);
- dorangetest(p, vlink(no_break(p)), var_mem_max);
- break;
- case adjust_node:
- dorangetest(p, adjust_ptr(p), var_mem_max);
- break;
- case pseudo_file_node:
- dorangetest(p, pseudo_lines(p), var_mem_max);
- break;
- case pseudo_line_node:
- case shape_node:
- break;
- case choice_node:
- dorangetest(p, display_mlist(p), var_mem_max);
- dorangetest(p, text_mlist(p), var_mem_max);
- dorangetest(p, script_mlist(p), var_mem_max);
- dorangetest(p, script_script_mlist(p), var_mem_max);
- break;
- case fraction_noad:
- dorangetest(p, numerator(p), var_mem_max);
- dorangetest(p, denominator(p), var_mem_max);
- dorangetest(p, left_delimiter(p), var_mem_max);
- dorangetest(p, right_delimiter(p), var_mem_max);
- break;
- case simple_noad:
- dorangetest(p, nucleus(p), var_mem_max);
- dorangetest(p, subscr(p), var_mem_max);
- dorangetest(p, supscr(p), var_mem_max);
- break;
- case radical_noad:
- dorangetest(p, nucleus(p), var_mem_max);
- dorangetest(p, subscr(p), var_mem_max);
- dorangetest(p, supscr(p), var_mem_max);
- dorangetest(p, degree(p), var_mem_max);
- dorangetest(p, left_delimiter(p), var_mem_max);
- break;
- case accent_noad:
- dorangetest(p, nucleus(p), var_mem_max);
- dorangetest(p, subscr(p), var_mem_max);
- dorangetest(p, supscr(p), var_mem_max);
- dorangetest(p, top_accent_chr(p), var_mem_max);
- dorangetest(p, bot_accent_chr(p), var_mem_max);
- dorangetest(p, overlay_accent_chr(p), var_mem_max);
- break;
- case fence_noad:
- dorangetest(p, delimiter(p), var_mem_max);
- break;
- case local_par_node:
- dorangetest(p, local_box_left(p), var_mem_max);
- dorangetest(p, local_box_right(p), var_mem_max);
- break;
- /*tex
-
- There is no need for useless cases:
-
- \starttyping
- case rule_node:
- case kern_node:
- case penalty_node:
- case mark_node:
- case style_node:
- case attribute_list_node:
- case attribute_node:
- case glue_spec_node:
- case temp_node:
- case align_stack_node:
- case movement_node:
- case if_node:
- case nesting_node:
- case span_node:
- case unhyphenated_node:
- case hyphenated_node:
- case delta_node:
- case passive_node:
- case expr_node:
- case dir_node:
- case boundary_node:
- break;
- default:
- fprintf(stdout, "check_node: type is %d\n", type(p));
- \stoptyping
-
- */
- }
-}
-
-halfword fix_node_list(halfword head)
-{
- halfword next, tail;
- if (head == null)
- return null;
- tail = head;
- next = vlink(head);
- while (next != null) {
- alink(next) = tail;
- tail = next;
- next = vlink(tail);
- }
- return tail;
-}
-
-halfword get_node(int s)
-{
- register halfword r;
-
- if (s < MAX_CHAIN_SIZE) {
- r = free_chain[s];
- if (r != null) {
- free_chain[s] = vlink(r);
-#ifdef CHECK_NODE_USAGE
- varmem_sizes[r] = (char) s;
-#endif
- vlink(r) = null;
- /*tex Maintain usage statistics. */
- var_used += s;
- return r;
- }
- /*tex This is the end of the \quote {inner loop}. */
- return slow_get_node(s);
- } else {
- normal_error("nodes","there is a problem in getting a node, case 1");
- return null;
- }
-}
-
-void free_node(halfword p, int s)
-{
- if (p <= my_prealloc) {
- formatted_error("nodes", "node number %d of type %d should not be freed", (int) p, type(p));
- return;
- }
-#ifdef CHECK_NODE_USAGE
- varmem_sizes[p] = 0;
-#endif
- if (s < MAX_CHAIN_SIZE) {
- vlink(p) = free_chain[s];
- free_chain[s] = p;
- } else {
- /*tex Todo: it is perhaps possible to merge this node with an existing rover? */
- node_size(p) = s;
- vlink(p) = rover;
- while (vlink(rover) != vlink(p)) {
- rover = vlink(rover);
- }
- vlink(rover) = p;
- }
- /*tex Maintain statistics. */
- var_used -= s;
-}
-
-static void free_node_chain(halfword q, int s)
-{
- register halfword p = q;
- while (vlink(p) != null) {
-#ifdef CHECK_NODE_USAGE
- varmem_sizes[p] = 0;
-#endif
- var_used -= s;
- p = vlink(p);
- }
- var_used -= s;
-#ifdef CHECK_NODE_USAGE
- varmem_sizes[p] = 0;
-#endif
- vlink(p) = free_chain[s];
- free_chain[s] = q;
-}
-
-/*tex
-
- At the start of the node memory area we reserve some special nodes, for
- instance frequently used glue specifications. We could as well just use
- new_glue here but for the moment we stick to the traditional approach.
-
-*/
-
-#define initialize_glue(n,wi,st,sh,sto,sho) \
- vlink(n) = null; \
- type(n) = glue_spec_node; \
- width(n) = wi; \
- stretch(n) = st; \
- shrink(n) = sh; \
- stretch_order(n) = sto; \
- shrink_order(n) = sho;
-
-#define initialize_whatever(n,t) \
- vinfo(n) = 0; \
- type(n) = t; \
- vlink(n) = null; \
- alink(n) = null;
-
-#define initialize_point(n) \
- type(n) = glyph_node; \
- subtype(n) = 0; \
- vlink(n) = null; \
- vinfo(n + 1) = null; \
- alink(n) = null; \
- font(n) = 0; \
- character(n) = '.'; \
- vinfo(n + 3) = 0; \
- vlink(n + 3) = 0; \
- vinfo(n + 4) = 0; \
- vlink(n + 4) = 0;
-
-void init_node_mem(int t)
-{
- my_prealloc = var_mem_stat_max;
-
- varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * (unsigned) t);
- if (varmem == NULL) {
- overflow("node memory size", (unsigned) var_mem_max);
- }
- memset((void *) (varmem), 0, (unsigned) t * sizeof(memory_word));
-#ifdef CHECK_NODE_USAGE
- varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * (unsigned) t);
- if (varmem_sizes == NULL) {
- overflow("node memory size", (unsigned) var_mem_max);
- }
- memset((void *) varmem_sizes, 0, sizeof(char) * (unsigned) t);
-#endif
- var_mem_max = t;
- rover = var_mem_stat_max + 1;
- vlink(rover) = rover;
- node_size(rover) = (t - rover);
- var_used = 0;
-
- /*tex Initialize static glue specs. */
-
- initialize_glue(zero_glue,0,0,0,0,0);
- initialize_glue(sfi_glue,0,0,0,sfi,0);
- initialize_glue(fil_glue,0,unity,0,fil,0);
- initialize_glue(fill_glue,0,unity,0,fill,0);
- initialize_glue(ss_glue,0,unity,unity,fil,fil);
- initialize_glue(fil_neg_glue,0,-unity,0,fil,0);
-
- /*tex Initialize node list heads. */
-
- initialize_whatever(page_ins_head,temp_node);
- initialize_whatever(contrib_head,temp_node);
- initialize_whatever(page_head,temp_node);
- initialize_whatever(temp_head,temp_node);
- initialize_whatever(hold_head,temp_node);
- initialize_whatever(adjust_head,temp_node);
- initialize_whatever(pre_adjust_head,temp_node);
- initialize_whatever(align_head,temp_node);
-
- initialize_whatever(active,unhyphenated_node);
- initialize_whatever(end_span,span_node);
-
- initialize_point(begin_point);
- initialize_point(end_point);
-}
-
-void dump_node_mem(void)
-{
- dump_int(var_mem_max);
- dump_int(rover);
- dump_things(varmem[0], var_mem_max);
-#ifdef CHECK_NODE_USAGE
- dump_things(varmem_sizes[0], var_mem_max);
-#endif
- dump_things(free_chain[0], MAX_CHAIN_SIZE);
- dump_int(var_used);
- dump_int(my_prealloc);
-}
-
-/*tex
-
- It makes sense to enlarge the varmem array immediately.
-
-*/
-
-void undump_node_mem(void)
-{
- int x;
- undump_int(x);
- undump_int(rover);
- var_mem_max = (x < 100000 ? 100000 : x);
- varmem = xmallocarray(memory_word, (unsigned) var_mem_max);
- undump_things(varmem[0], x);
-#ifdef CHECK_NODE_USAGE
- varmem_sizes = xmallocarray(char, (unsigned) var_mem_max);
- memset((void *) varmem_sizes, 0, (unsigned) var_mem_max * sizeof(char));
- undump_things(varmem_sizes[0], x);
-#endif
- undump_things(free_chain[0], MAX_CHAIN_SIZE);
- undump_int(var_used);
- undump_int(my_prealloc);
- if (var_mem_max > x) {
- /*tex Todo: is it perhaps possible to merge the new node with an existing rover? */
- vlink(x) = rover;
- node_size(x) = (var_mem_max - x);
- while (vlink(rover) != vlink(x)) {
- rover = vlink(rover);
- }
- vlink(rover) = x;
- }
-}
-
-halfword slow_get_node(int s)
-{
- register int t;
-
- RETRY:
- t = node_size(rover);
- if (vlink(rover) < var_mem_max && vlink(rover) != 0) {
- if (t > s) {
- /*tex Allocating from the bottom helps decrease page faults. */
- register halfword r = rover;
- rover += s;
- vlink(rover) = vlink(r);
- node_size(rover) = node_size(r) - s;
- if (vlink(rover) != r) {
- /*tex The list is longer than one. */
- halfword q = r;
- while (vlink(q) != r) {
- q = vlink(q);
- }
- vlink(q) += s;
- } else {
- vlink(rover) += s;
- }
- if (vlink(rover) < var_mem_max) {
-#ifdef CHECK_NODE_USAGE
- varmem_sizes[r] = (char) (s > 127 ? 127 : s);
-#endif
- vlink(r) = null;
- /*tex Maintain usage statistics. */
- var_used += s;
- /*tex This is the only exit. */
- return r;
- } else {
- normal_error("nodes","there is a problem in getting a node, case 2");
- return null;
- }
- } else {
- /*tex Attempt to keep the free list small. */
- int x;
- if (vlink(rover) != rover) {
- if (t < MAX_CHAIN_SIZE) {
- halfword l = vlink(rover);
- vlink(rover) = free_chain[t];
- free_chain[t] = rover;
- rover = l;
- while (vlink(l) != free_chain[t]) {
- l = vlink(l);
- }
- vlink(l) = rover;
- goto RETRY;
- } else {
- halfword l = rover;
- while (vlink(rover) != l) {
- if (node_size(rover) > s) {
- goto RETRY;
- }
- rover = vlink(rover);
- }
- }
- }
- /*tex If we are still here, it was apparently impossible to get a match. */
- x = (var_mem_max >> 2) + s;
- varmem = (memory_word *) realloc((void *) varmem, sizeof(memory_word) * (unsigned) (var_mem_max + x));
- if (varmem == NULL) {
- overflow("node memory size", (unsigned) var_mem_max);
- }
- memset((void *) (varmem + var_mem_max), 0, (unsigned) x * sizeof(memory_word));
-#ifdef CHECK_NODE_USAGE
- varmem_sizes = (char *) realloc(varmem_sizes, sizeof(char) * (unsigned) (var_mem_max + x));
- if (varmem_sizes == NULL) {
- overflow("node memory size", (unsigned) var_mem_max);
- }
- memset((void *) (varmem_sizes + var_mem_max), 0, (unsigned) (x) * sizeof(char));
-#endif
- /*tex Todo: is it perhaps possible to merge the new memory with an existing rover? */
- vlink(var_mem_max) = rover;
- node_size(var_mem_max) = x;
- while (vlink(rover) != vlink(var_mem_max)) {
- rover = vlink(rover);
- }
- vlink(rover) = var_mem_max;
- rover = var_mem_max;
- var_mem_max += x;
- goto RETRY;
- }
- } else {
- normal_error("nodes","there is a problem in getting a node, case 3");
- return null;
- }
-}
-
-char *sprint_node_mem_usage(void)
-{
- char *s;
-#ifdef CHECK_NODE_USAGE
- char *ss;
- int i;
- int b = 0;
- char msg[256];
- int node_counts[last_normal_node + last_whatsit_node + 2] = { 0 };
- s = strdup("");
- for (i = (var_mem_max - 1); i > my_prealloc; i--) {
- if (varmem_sizes[i] > 0) {
- if (type(i) > last_normal_node + last_whatsit_node) {
- node_counts[last_normal_node + last_whatsit_node + 1]++;
- } else if (type(i) == whatsit_node) {
- node_counts[(subtype(i) + last_normal_node + 1)]++;
- } else {
- node_counts[type(i)]++;
- }
- }
- }
- for (i = 0; i < last_normal_node + last_whatsit_node + 2; i++) {
- if (node_counts[i] > 0) {
- int j =
- (i > (last_normal_node + 1) ? (i - last_normal_node - 1) : 0);
- snprintf(msg, 255, "%s%d %s", (b ? ", " : ""), (int) node_counts[i],
- get_node_name((i > last_normal_node ? whatsit_node : i), j));
- ss = xmalloc((unsigned) (strlen(s) + strlen(msg) + 1));
- strcpy(ss, s);
- strcat(ss, msg);
- free(s);
- s = ss;
- b = 1;
- }
- }
-#else
- s = strdup("");
-#endif
- return s;
-}
-
-halfword list_node_mem_usage(void)
-{
- halfword q = null;
-#ifdef CHECK_NODE_USAGE
- halfword p = null;
- halfword i, j;
- char *saved_varmem_sizes = xmallocarray(char, (unsigned) var_mem_max);
- memcpy(saved_varmem_sizes, varmem_sizes, (size_t) var_mem_max);
- for (i = my_prealloc + 1; i < (var_mem_max - 1); i++) {
- if (saved_varmem_sizes[i] > 0) {
- j = copy_node(i);
- if (p == null) {
- q = j;
- } else {
- vlink(p) = j;
- }
- p = j;
- }
- }
- free(saved_varmem_sizes);
-#endif
- return q;
-}
-
-void print_node_mem_stats(void)
-{
- int i, b;
- halfword j;
- char msg[256];
- char *s;
- int free_chain_counts[MAX_CHAIN_SIZE] = { 0 };
- snprintf(msg, 255, " %d words of node memory still in use:", (int) (var_used + my_prealloc));
- tprint_nl(msg);
- s = sprint_node_mem_usage();
- tprint_nl(" ");
- tprint(s);
- free(s);
- tprint(" nodes");
- tprint_nl(" avail lists: ");
- b = 0;
- for (i = 1; i < MAX_CHAIN_SIZE; i++) {
- for (j = free_chain[i]; j != null; j = vlink(j))
- free_chain_counts[i]++;
- if (free_chain_counts[i] > 0) {
- snprintf(msg, 255, "%s%d:%d", (b ? "," : ""), i, (int) free_chain_counts[i]);
- tprint(msg);
- b = 1;
- }
- }
- /*tex A newline, if needed: */
- print_nlp();
-}
-
-halfword new_span_node(halfword n, int s, scaled w)
-{
- halfword p = new_node(span_node, 0);
- span_link(p) = n;
- span_span(p) = s;
- width(p) = w;
- return p;
-}
-
-/* Now comes some attribute stuff. */
-
-static halfword new_attribute_node(unsigned int i, int v)
-{
- register halfword r = get_node(attribute_node_size);
- type(r) = attribute_node;
- attribute_id(r) = (halfword) i;
- attribute_value(r) = v;
- /* not used but nicer in print */
- subtype(r) = 0;
- return r;
-}
-
-halfword copy_attribute_list(halfword n)
-{
- halfword q = get_node(attribute_node_size);
- register halfword p = q;
- type(p) = attribute_list_node;
- attr_list_ref(p) = 0;
- n = vlink(n);
- while (n != null) {
- register halfword r = get_node(attribute_node_size);
- /*tex The link will be fixed automatically in the next loop. */
- (void) memcpy((void *) (varmem + r), (void *) (varmem + n), (sizeof(memory_word) * attribute_node_size));
- vlink(p) = r;
- p = r;
- n = vlink(n);
- }
- return q;
-}
-
-void update_attribute_cache(void)
-{
- halfword p;
- register int i;
- attr_list_cache = get_node(attribute_node_size);
- type(attr_list_cache) = attribute_list_node;
- attr_list_ref(attr_list_cache) = 0;
- p = attr_list_cache;
- for (i = 0; i <= max_used_attr; i++) {
- register int v = attribute(i);
- if (v > UNUSED_ATTRIBUTE) {
- register halfword r = new_attribute_node((unsigned) i, v);
- vlink(p) = r;
- p = r;
- }
- }
- if (vlink(attr_list_cache) == null) {
- free_node(attr_list_cache, attribute_node_size);
- attr_list_cache = null;
- }
- return;
-}
-
-void build_attribute_list(halfword b)
-{
- if (max_used_attr >= 0) {
- if (attr_list_cache == cache_disabled|| attr_list_cache == null) {
- update_attribute_cache();
- if (attr_list_cache == null)
- return;
- }
- attr_list_ref(attr_list_cache)++;
- node_attr(b) = attr_list_cache;
- }
-}
-
-halfword current_attribute_list(void)
-{
- if (max_used_attr >= 0) {
- if (attr_list_cache == cache_disabled) {
- update_attribute_cache();
- }
- return attr_list_cache ;
- }
- return null ;
-}
-
-void reassign_attribute(halfword n, halfword new)
-{
- halfword old;
- old = node_attr(n);
- if (new == null) {
- /*tex There is nothing to assign but we need to check for an old value. */
- if (old != null) {
- /*tex This also nulls |attr| field of |n|. */
- delete_attribute_ref(old);
- }
- } else if (old == null) {
- /*tex Nothing is assigned so we just do that now. */
- assign_attribute_ref(n,new);
- } else if (old != new) {
- /*tex Something is assigned so we need to clean up and assign then. */
- delete_attribute_ref(old);
- assign_attribute_ref(n,new);
- }
- /*tex The same value so there is no need to assign and change the refcount. */
- node_attr(n) = new ;
-}
-
-void delete_attribute_ref(halfword b)
-{
- if (b != null) {
- if (type(b) == attribute_list_node){
- attr_list_ref(b)--;
- if (attr_list_ref(b) == 0) {
- if (b == attr_list_cache)
- attr_list_cache = cache_disabled;
- free_node_chain(b, attribute_node_size);
- }
- /*tex Maintain sanity. */
- if (attr_list_ref(b) < 0) {
- attr_list_ref(b) = 0;
- }
- } else {
- normal_error("nodes","trying to delete an attribute reference of a non attribute node");
- }
- }
-}
-
-void reset_node_properties(halfword b)
-{
- if (b != null) {
- lua_properties_reset(b);
- }
-}
-
-/*tex Here |p| is an attr list head, or zero. */
-
-halfword do_set_attribute(halfword p, int i, int val)
-{
- register halfword q;
- register int j = 0;
- if (p == null) {
- /*tex Add a new head \& node. */
- q = get_node(attribute_node_size);
- type(q) = attribute_list_node;
- attr_list_ref(q) = 1;
- p = new_attribute_node((unsigned) i, val);
- vlink(q) = p;
- return q;
- }
- q = p;
- if (vlink(p) != null) {
- while (vlink(p) != null) {
- int t = attribute_id(vlink(p));
- if (t == i && attribute_value(vlink(p)) == val) {
- /*tex There is no need to do anything. */
- return q;
- }
- if (t >= i)
- break;
- j++;
- p = vlink(p);
- }
- p = q;
- while (j-- > 0)
- p = vlink(p);
- if (attribute_id(vlink(p)) == i) {
- attribute_value(vlink(p)) = val;
- } else {
- /*tex Add a new node. */
- halfword r = new_attribute_node((unsigned) i, val);
- vlink(r) = vlink(p);
- vlink(p) = r;
- }
- return q;
- } else {
- normal_error("nodes","trying to set an attribute fails, case 1");
- return null ;
- }
-}
-
-void set_attribute(halfword n, int i, int val)
-{
- register halfword p;
- register int j = 0;
- /*tex Not all nodes can have an attribute list. */
- if (!nodetype_has_attributes(type(n)))
- return;
- /*tex If we have no list, we create one and quit. */
- p = node_attr(n);
- if (p == null) { /* add a new head \& node */
- p = get_node(attribute_node_size);
- type(p) = attribute_list_node;
- attr_list_ref(p) = 1;
- node_attr(n) = p;
- p = new_attribute_node((unsigned) i, val);
- vlink(node_attr(n)) = p;
- return;
- }
- /*tex We check if we have this attribute already and quit if the value stays the same. */
- if (vlink(p) != null) {
- while (vlink(p) != null) {
- int t = attribute_id(vlink(p));
- if (t == i && attribute_value(vlink(p)) == val)
- return;
- if (t >= i)
- break;
- j++;
- p = vlink(p);
- }
- /*tex If found |j| has now the position and we assume a sorted list ! */
- p = node_attr(n);
- if (attr_list_ref(p) == 0 ) {
- /*tex The list is invalid i.e. freed already. */
- formatted_warning("nodes","node %d has an attribute list that is free already, case 1",(int) n);
- /*tex The still dangling list gets ref count 1. */
- attr_list_ref(p) = 1;
- } else if (attr_list_ref(p) == 1) {
- /*tex This can really happen! */
- if (p == attr_list_cache) {
- /*tex
-
- We can invalidate the cache setting with |attr_list_cache =
- cache_disabled| or or save the list, as done below.
-
- */
- p = copy_attribute_list(p);
- node_attr(n) = p;
- /*tex The copied list gets ref count 1. */
- attr_list_ref(p) = 1;
- }
- } else {
- /*tex The list is used multiple times so we make a copy. */
- p = copy_attribute_list(p);
- /*tex We decrement the ref count or the original. */
- delete_attribute_ref(node_attr(n));
- node_attr(n) = p;
- /*tex The copied list gets ref count 1. */
- attr_list_ref(p) = 1;
- }
- /*tex We go to position |j| in the list. */
- while (j-- > 0)
- p = vlink(p);
- /*tex If we have a hit we just set the value otherwise we add a new node. */
- if (attribute_id(vlink(p)) == i) {
- attribute_value(vlink(p)) = val;
- } else {
- /*tex Add a new node. */
- halfword r = new_attribute_node((unsigned) i, val);
- vlink(r) = vlink(p);
- vlink(p) = r;
- }
- } else {
- normal_error("nodes","trying to set an attribute fails, case 2");
- }
-}
-
-int unset_attribute(halfword n, int i, int val)
-{
- register halfword p;
- register int t;
- register int j = 0;
- if (!nodetype_has_attributes(type(n)))
- return null;
- p = node_attr(n);
- if (p == null)
- return UNUSED_ATTRIBUTE;
- if (attr_list_ref(p) == 0) {
- formatted_warning("nodes","node %d has an attribute list that is free already, case 2", (int) n);
- return UNUSED_ATTRIBUTE;
- }
- if (vlink(p) != null) {
- while (vlink(p) != null) {
- t = attribute_id(vlink(p));
- if (t > i)
- return UNUSED_ATTRIBUTE;
- if (t == i) {
- p = vlink(p);
- break;
- }
- j++;
- p = vlink(p);
- }
- if (attribute_id(p) != i)
- return UNUSED_ATTRIBUTE;
- /*tex If we are still here, the attribute exists. */
- p = node_attr(n);
- if (attr_list_ref(p) > 1 || p == attr_list_cache) {
- halfword q = copy_attribute_list(p);
- if (attr_list_ref(p) > 1) {
- delete_attribute_ref(node_attr(n));
- }
- attr_list_ref(q) = 1;
- node_attr(n) = q;
- }
- p = vlink(node_attr(n));
- while (j-- > 0)
- p = vlink(p);
- t = attribute_value(p);
- if (val == UNUSED_ATTRIBUTE || t == val) {
- attribute_value(p) = UNUSED_ATTRIBUTE;
- }
- return t;
- } else {
- normal_error("nodes","trying to unset an attribute fails");
- return null;
- }
-}
-
-int has_attribute(halfword n, int i, int val)
-{
- register halfword p;
- if (!nodetype_has_attributes(type(n)))
- return UNUSED_ATTRIBUTE;
- p = node_attr(n);
- if (p == null || vlink(p) == null)
- return UNUSED_ATTRIBUTE;
- p = vlink(p);
- while (p != null) {
- if (attribute_id(p) == i) {
- int ret = attribute_value(p);
- if (val == UNUSED_ATTRIBUTE || val == ret)
- return ret;
- return UNUSED_ATTRIBUTE;
- } else if (attribute_id(p) > i) {
- return UNUSED_ATTRIBUTE;
- }
- p = vlink(p);
- }
- return UNUSED_ATTRIBUTE;
-}
-
-void print_short_node_contents(halfword p)
-{
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case ins_node:
- case whatsit_node:
- case mark_node:
- case adjust_node:
- case unset_node:
- print_char('[');
- print_char(']');
- break;
- case rule_node:
- print_char('|');
- break;
- case glue_node:
- if (! glue_is_zero(p))
- print_char(' ');
- break;
- case math_node:
- print_char('$');
- break;
- case disc_node:
- short_display(vlink(pre_break(p)));
- short_display(vlink(post_break(p)));
- break;
- }
-}
-
-static void show_pdftex_whatsit_rule_spec(int p)
-{
- tprint("(");
- print_rule_dimen(height(p));
- print_char('+');
- print_rule_dimen(depth(p));
- tprint(")x");
- print_rule_dimen(width(p));
-}
-
-/*tex
-
- Each new type of node that appears in our data structure must be capable of
- being displayed, copied, destroyed, and so on. The routines that we need for
- write-oriented whatsits are somewhat like those for mark nodes; other
- extensions might, of course, involve more subtlety here.
-
-*/
-
-static void print_write_whatsit(const char *s, pointer p)
-{
- tprint_esc(s);
- if (write_stream(p) < 16)
- print_int(write_stream(p));
- else if (write_stream(p) == 16)
- print_char('*');
- else
- print_char('-');
-}
-
-static void show_node_wrapup_core(int p)
-{
- switch (subtype(p)) {
- case open_node:
- print_write_whatsit("openout", p);
- print_char('=');
- print_file_name(open_name(p), open_area(p), open_ext(p));
- break;
- case write_node:
- print_write_whatsit("write", p);
- print_mark(write_tokens(p));
- break;
- case close_node:
- print_write_whatsit("closeout", p);
- break;
- case special_node:
- tprint_esc("special");
- print_mark(write_tokens(p));
- break;
- case late_lua_node:
- show_late_lua(p);
- break;
- case save_pos_node:
- tprint_esc("savepos");
- break;
- case user_defined_node:
- tprint_esc("whatsit");
- print_int(user_node_id(p));
- print_char('=');
- switch (user_node_type(p)) {
- case 'a':
- tprint("<>");
- break;
- case 'n':
- tprint("[");
- show_node_list(user_node_value(p));
- tprint("]");
- break;
- case 's':
- print_char('"');
- print(user_node_value(p));
- print_char('"');
- break;
- case 't':
- print_mark(user_node_value(p));
- break;
- default: /* only 'd' */
- print_int(user_node_value(p));
- break;
- }
- break;
- }
-}
-
-void show_node_wrapup_dvi(int p)
-{
-}
-
-void show_node_wrapup_pdf(int p)
-{
- switch (subtype(p)) {
- case pdf_literal_node:
- show_pdf_literal(p);
- break;
- case pdf_colorstack_node:
- tprint_esc("pdfcolorstack ");
- print_int(pdf_colorstack_stack(p));
- switch (pdf_colorstack_cmd(p)) {
- case colorstack_set:
- tprint(" set ");
- break;
- case colorstack_push:
- tprint(" push ");
- break;
- case colorstack_pop:
- tprint(" pop");
- break;
- case colorstack_current:
- tprint(" current");
- break;
- default:
- confusion("colorstack");
- break;
- }
- if (pdf_colorstack_cmd(p) <= colorstack_data)
- print_mark(pdf_colorstack_data(p));
- break;
- case pdf_setmatrix_node:
- tprint_esc("pdfsetmatrix");
- print_mark(pdf_setmatrix_data(p));
- break;
- case pdf_save_node:
- tprint_esc("pdfsave");
- break;
- case pdf_restore_node:
- tprint_esc("pdfrestore");
- break;
- case pdf_link_state_node:
- tprint_esc("pdflinkstate ");
- print_int(pdf_link_state(p));
- break;
- case pdf_refobj_node:
- tprint_esc("pdfrefobj");
- if (obj_obj_is_stream(static_pdf, pdf_obj_objnum(p))) {
- if (obj_obj_stream_attr(static_pdf, pdf_obj_objnum(p)) != LUA_NOREF) {
- tprint(" attr");
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, obj_obj_stream_attr(static_pdf, pdf_obj_objnum(p)));
- print_char(' ');
- tprint((const char *) lua_tostring(Luas, -1));
- lua_pop(Luas, 1);
- }
- tprint(" stream");
- }
- if (obj_obj_is_file(static_pdf, pdf_obj_objnum(p)))
- tprint(" file");
- if (obj_obj_data(static_pdf, pdf_obj_objnum(p)) != LUA_NOREF) {
- lua_rawgeti(Luas, LUA_REGISTRYINDEX, obj_obj_data(static_pdf, pdf_obj_objnum(p)));
- print_char(' ');
- tprint((const char *) lua_tostring(Luas, -1));
- lua_pop(Luas, 1);
- }
- break;
- case pdf_annot_node:
- tprint_esc("pdfannot");
- show_pdftex_whatsit_rule_spec(p);
- print_mark(pdf_annot_data(p));
- break;
- case pdf_start_link_node:
- tprint_esc("pdfstartlink");
- show_pdftex_whatsit_rule_spec(p);
- if (pdf_link_attr(p) != null) {
- tprint(" attr");
- print_mark(pdf_link_attr(p));
- }
- tprint(" action");
- if (pdf_action_type(pdf_link_action(p)) == pdf_action_user) {
- tprint(" user");
- print_mark(pdf_action_tokens(pdf_link_action(p)));
- return;
- }
- if (pdf_action_file(pdf_link_action(p)) != null) {
- tprint(" file");
- print_mark(pdf_action_file(pdf_link_action(p)));
- }
- switch (pdf_action_type(pdf_link_action(p))) {
- case pdf_action_goto:
- if (pdf_action_named_id(pdf_link_action(p)) > 0) {
- tprint(" goto name");
- print_mark(pdf_action_id(pdf_link_action(p)));
- } else {
- tprint(" goto num");
- print_int(pdf_action_id(pdf_link_action(p)));
- }
- break;
- case pdf_action_page:
- tprint(" page");
- print_int(pdf_action_id(pdf_link_action(p)));
- print_mark(pdf_action_tokens(pdf_link_action(p)));
- break;
- case pdf_action_thread:
- if (pdf_action_named_id(pdf_link_action(p)) > 0) {
- tprint(" thread name");
- print_mark(pdf_action_id(pdf_link_action(p)));
- } else {
- tprint(" thread num");
- print_int(pdf_action_id(pdf_link_action(p)));
- }
- break;
- default:
- normal_error("pdf backend", "unknown action type for link");
- break;
- }
- break;
- case pdf_end_link_node:
- tprint_esc("pdfendlink");
- break;
- case pdf_dest_node:
- tprint_esc("pdfdest");
- if (pdf_dest_named_id(p) > 0) {
- tprint(" name");
- print_mark(pdf_dest_id(p));
- } else {
- tprint(" num");
- print_int(pdf_dest_id(p));
- }
- print_char(' ');
- switch (pdf_dest_type(p)) {
- case pdf_dest_xyz:
- tprint("xyz");
- if (pdf_dest_xyz_zoom(p) != null) {
- tprint(" zoom");
- print_int(pdf_dest_xyz_zoom(p));
- }
- break;
- case pdf_dest_fitbh:
- tprint("fitbh");
- break;
- case pdf_dest_fitbv:
- tprint("fitbv");
- break;
- case pdf_dest_fitb:
- tprint("fitb");
- break;
- case pdf_dest_fith:
- tprint("fith");
- break;
- case pdf_dest_fitv:
- tprint("fitv");
- break;
- case pdf_dest_fitr:
- tprint("fitr");
- show_pdftex_whatsit_rule_spec(p);
- break;
- case pdf_dest_fit:
- tprint("fit");
- break;
- default:
- tprint("unknown!");
- break;
- }
- break;
- case pdf_thread_node:
- case pdf_start_thread_node:
- if (subtype(p) == pdf_thread_node)
- tprint_esc("pdfthread");
- else
- tprint_esc("pdfstartthread");
- tprint("(");
- print_rule_dimen(height(p));
- print_char('+');
- print_rule_dimen(depth(p));
- tprint(")x");
- print_rule_dimen(width(p));
- if (pdf_thread_attr(p) != null) {
- tprint(" attr");
- print_mark(pdf_thread_attr(p));
- }
- if (pdf_thread_named_id(p) > 0) {
- tprint(" name");
- print_mark(pdf_thread_id(p));
- } else {
- tprint(" num");
- print_int(pdf_thread_id(p));
- }
- break;
- case pdf_end_thread_node:
- tprint_esc("pdfendthread");
- break;
- default:
- break;
- }
-}
-
-/*tex
-
- Now we are ready for |show_node_list| itself. This procedure has been written
- to be ``extra robust'' in the sense that it should not crash or get into a
- loop even if the data structures have been messed up by bugs in the rest of
- the program. You can safely call its parent routine |show_box(p)| for
- arbitrary values of |p| when you are debugging \TeX. However, in the presence
- of bad data, the procedure may fetch a |memory_word| whose variant is
- different from the way it was stored; for example, it might try to read
- |mem[p].hh| when |mem[p]| contains a scaled integer, if |p| is a pointer that
- has been clobbered or chosen at random.
-
-*/
-
-#define node_list_display(A) do { \
- append_char('.'); \
- show_node_list(A); \
- flush_char(); \
-} while (0)
-
-#define node_list_display_x(A,B) do { \
- if ((B) != null) { \
- append_char('.'); \
- append_char(A); \
- append_char(' '); \
- show_node_list(B); \
- flush_char(); \
- flush_char(); \
- flush_char(); \
- } \
-} while (0)
-
-/*tex Print a node list symbolically: */
-
-void show_node_list(int p)
-{
- /*tex The number of items already printed at this level: */
- int n = 0;
- halfword w;
- /*tex A glue ratio, as a floating point number: */
- real g;
- if ((int) cur_length > depth_threshold) {
- if (p > null) {
- /*tex Indicate that there's been some truncation. */
- tprint(" []");
- }
- return;
- }
- while (p != null) {
- print_ln();
- print_current_string();
- /*tex Display the nesting history. */
- if (tracing_online_par < -2)
- print_int(p);
- incr(n);
- if (n > breadth_max) {
- /*tex Time to stop. */
- tprint("etc.");
- return;
- }
- /*tex Display node |p|. */
- if (is_char_node(p)) {
- print_font_and_char(p);
- if (is_ligature(p)) {
- /*tex Display ligature |p|. */
- tprint(" (ligature ");
- if (is_leftboundary(p))
- print_char('|');
- font_in_short_display = font(p);
- short_display(lig_ptr(p));
- if (is_rightboundary(p))
- print_char('|');
- print_char(')');
- }
- } else {
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case unset_node:
- /*tex Display box |p|. */
- if (type(p) == hlist_node)
- tprint_esc("h");
- else if (type(p) == vlist_node)
- tprint_esc("v");
- else
- tprint_esc("unset");
- tprint("box(");
- print_scaled(height(p));
- print_char('+');
- print_scaled(depth(p));
- tprint(")x");
- print_scaled(width(p));
- if (type(p) == unset_node) {
- /*tex Display special fields of the unset node |p|. */
- if (span_count(p) != min_quarterword) {
- tprint(" (");
- print_int(span_count(p) + 1);
- tprint(" columns)");
- }
- if (glue_stretch(p) != 0) {
- tprint(", stretch ");
- print_glue(glue_stretch(p), glue_order(p), NULL);
- }
- if (glue_shrink(p) != 0) {
- tprint(", shrink ");
- print_glue(glue_shrink(p), glue_sign(p), NULL);
- }
- } else {
- /*tex
-
- Display the value of |glue_set(p)|. The code will
- have to change in this place if |glue_ratio| is a
- structured type instead of an ordinary |real|. Note
- that this routine should avoid arithmetic errors even
- if the |glue_set| field holds an arbitrary random
- value. The following code assumes that a properly
- formed nonzero |real| number has absolute value
- $2^{20}$ or more when it is regarded as an integer;
- this precaution was adequate to prevent floating
- point underflow on the author's computer.
-
- */
- g = (real) (glue_set(p));
- if ((g != 0.0) && (glue_sign(p) != normal)) {
- tprint(", glue set ");
- if (glue_sign(p) == shrinking)
- tprint("- ");
- if (g > 20000.0 || g < -20000.0) {
- if (g > 0.0)
- print_char('>');
- else
- tprint("< -");
- print_glue(20000 * unity, glue_order(p), NULL);
- } else {
- print_glue(round(unity * g), glue_order(p), NULL);
- }
- }
- if (shift_amount(p) != 0) {
- tprint(", shifted ");
- print_scaled(shift_amount(p));
- }
- tprint(", direction ");
- print_dir_par(box_dir(p));
- }
- /*tex Recursive call: */
- node_list_display(list_ptr(p));
- break;
- case rule_node:
- /*tex Display rule |p|. */
- if (subtype(p) == normal_rule) {
- tprint_esc("rule(");
- } else if (subtype(p) == empty_rule) {
- tprint_esc("norule(");
- } else if (subtype(p) == user_rule) {
- tprint_esc("userrule(");
- } else if (subtype(p) == box_rule) {
- tprint_esc("box(");
- } else if (subtype(p) == image_rule) {
- tprint_esc("image(");
- }
- print_rule_dimen(height(p));
- print_char('+');
- print_rule_dimen(depth(p));
- tprint(")x");
- print_rule_dimen(width(p));
- break;
- case ins_node:
- /*tex Display insertion |p|. */
- tprint_esc("insert");
- print_int(subtype(p));
- tprint(", natural size ");
- print_scaled(height(p));
- tprint("; split(");
- print_spec(split_top_ptr(p), NULL);
- print_char(',');
- print_scaled(depth(p));
- tprint("); float cost ");
- print_int(float_cost(p));
- /*tex Recursive call. */
- node_list_display(ins_ptr(p));
- break;
- case dir_node:
- if (subtype(p) == cancel_dir) {
- tprint_esc("enddir");
- } else {
- tprint_esc("begindir");
- }
- print_char(' ');
- print_dir_par(dir_dir(p));
- break;
- case local_par_node:
- tprint_esc("localpar");
- append_char('.');
- print_ln();
- print_current_string();
- tprint_esc("localinterlinepenalty");
- print_char('=');
- print_int(local_pen_inter(p));
- print_ln();
- print_current_string();
- tprint_esc("localbrokenpenalty");
- print_char('=');
- print_int(local_pen_broken(p));
- print_ln();
- print_current_string();
- tprint_esc("localleftbox");
- if (local_box_left(p) == null) {
- tprint("=null");
- } else {
- append_char('.');
- show_node_list(local_box_left(p));
- decr(cur_length);
- }
- print_ln();
- print_current_string();
- tprint_esc("localrightbox");
- if (local_box_right(p) == null) {
- tprint("=null");
- } else {
- append_char('.');
- show_node_list(local_box_right(p));
- decr(cur_length);
- }
- decr(cur_length);
- break;
- case boundary_node:
- if (subtype(p)==0) {
- tprint_esc("noboundary");
- } else {
- switch (subtype(p)) {
- case 1:
- tprint_esc("boundary");
- break;
- case 2:
- tprint_esc("protrusionboundary");
- break;
- case 3:
- tprint_esc("wordboundary");
- break;
- default:
- tprint_esc("boundary");
- print_char(':');
- print_int(subtype(p));
- break;
- }
- print_char('=');
- print_int(boundary_value(p));
- }
- break;
- case whatsit_node:
- w = subtype(p) ;
- if (w >= backend_first_pdf_whatsit) {
- show_node_wrapup_pdf(p);
- } else if (w >= backend_first_dvi_whatsit) {
- show_node_wrapup_dvi(p);
- } else {
- show_node_wrapup_core(p);
- }
- break;
- case glue_node:
- /*tex Display glue |p|. */
- if (subtype(p) >= a_leaders) {
- /*tex Display leaders |p|. */
- tprint_esc("");
- switch (subtype(p)) {
- case a_leaders:
- break;
- case c_leaders:
- print_char('c');
- break;
- case x_leaders:
- print_char('x');
- break;
- case g_leaders:
- print_char('g');
- break;
- default:
- normal_warning("nodes","weird glue leader subtype ignored");
- }
- tprint("leaders ");
- print_spec(p, NULL);
- /*tex Recursive call: */
- node_list_display(leader_ptr(p));
- } else {
- tprint_esc("glue");
- if (subtype(p) != normal) {
- print_char('(');
- if ((subtype(p) - 1) < thin_mu_skip_code) {
- print_cmd_chr(assign_glue_cmd, glue_base + (subtype(p) - 1));
- } else if (subtype(p) < cond_math_glue) {
- print_cmd_chr(assign_mu_glue_cmd, glue_base + (subtype(p) - 1));
- } else if (subtype(p) == cond_math_glue) {
- tprint_esc("nonscript");
- } else {
- tprint_esc("mskip");
- }
- print_char(')');
- }
- if (subtype(p) != cond_math_glue) {
- print_char(' ');
- if (subtype(p) < cond_math_glue)
- print_spec(p, NULL);
- else
- print_spec(p, "mu");
- }
- }
- break;
- case margin_kern_node:
- tprint_esc("kern");
- print_scaled(width(p));
- if (subtype(p) == left_side)
- tprint(" (left margin)");
- else
- tprint(" (right margin)");
- break;
- case kern_node:
- /*tex Display kern |p| */
- if (subtype(p) != mu_glue) {
- tprint_esc("kern");
- /*tex
-
- \starttyping
- if (subtype(p) != normal) {
- print_char(' ');
- }
- \stoptyping
-
- */
- print_scaled(width(p));
- if (subtype(p) == font_kern)
- tprint(" (font)");
- else if (subtype(p) == italic_kern)
- tprint(" (italic)");
- else if (subtype(p) == accent_kern)
- tprint(" (accent)");
- } else {
- tprint_esc("mkern");
- print_scaled(width(p));
- tprint("mu");
- }
- break;
- case math_node:
- /*tex Display math node |p|. */
- tprint_esc("math");
- if (subtype(p) == before)
- tprint("on");
- else
- tprint("off");
- if (!glue_is_zero(p)) {
- tprint(", glued ");
- print_spec(p, NULL);
- } else if (surround(p) != 0) {
- tprint(", surrounded ");
- print_scaled(surround(p));
- }
- break;
- case penalty_node:
- /*tex Display penalty |p|. */
- tprint_esc("penalty ");
- print_int(penalty(p));
- break;
- case disc_node:
- /*tex
-
- Display discretionary |p|. The |post_break| list of a
- discretionary node is indicated by a prefixed
- `\.{\char'174}' instead of the `\..' before the
- |pre_break| list.
-
- We're not compatible anyway so ...
-
- \starttyping
- tprint_esc("discretionary");
- print_int(disc_penalty(p));
- print_char('|');
- if (vlink(no_break(p)) != null) {
- tprint(" replacing ");
- node_list_display(vlink(no_break(p)));
- }
- node_list_display(vlink(pre_break(p)));
- append_char('|');
- show_node_list(vlink(post_break(p)));
- flush_char();
- \stoptyping
-
- has become:
-
- */
- tprint_esc("discretionary");
- tprint(" (penalty ");
- print_int(disc_penalty(p));
- print_char(')');
- node_list_display_x('<',vlink(pre_break(p)));
- node_list_display_x('>',vlink(post_break(p)));
- node_list_display_x('=',vlink(no_break(p)));
- break;
- case mark_node:
- /*tex Display mark |p|. */
- tprint_esc("mark");
- if (mark_class(p) != 0) {
- print_char('s');
- print_int(mark_class(p));
- }
- print_mark(mark_ptr(p));
- break;
- case adjust_node:
- /*tex Display adjustment |p|. */
- tprint_esc("vadjust");
- if (subtype(p) != 0)
- tprint(" pre ");
- /*tex Recursive call. */
- node_list_display(adjust_ptr(p));
- break;
- case glue_spec_node:
- tprint("<glue_spec ");
- print_spec(p, NULL);
- tprint(">");
- break;
- default:
- show_math_node(p);
- break;
- }
- }
- p = vlink(p);
- }
-}
-
-/*tex
-
- This routine finds the 'base' width of a horizontal box, using the same logic
- that \TeX82 used for \.{\\predisplaywidth}.
-
-*/
-
-static pointer get_actual_box_width(pointer r,pointer p, scaled initial_width)
-{
- /*tex increment to |v| */
- scaled d;
- /*tex calculated |size| */
- scaled w = -max_dimen;
- /*tex |w| plus possible glue amount */
- scaled v = initial_width;
- while (p != null) {
- if (is_char_node(p)) {
- d = glyph_width(p);
- goto FOUND;
- }
- switch (type(p)) {
- case hlist_node:
- case vlist_node:
- case rule_node:
- d = width(p);
- goto FOUND;
- break;
- case margin_kern_node:
- d = width(p);
- break;
- case kern_node:
- d = width(p);
- break;
- case disc_node:
- /*tex At the end of the line we should actually take the |pre|. */
- if (no_break(p) != null) {
- d = get_actual_box_width(r,vlink_no_break(p),0);
- if (d <= -max_dimen || d >= max_dimen) {
- d = 0;
- }
- } else {
- d = 0;
- }
- goto FOUND;
- break;
- case math_node:
- /*tex Begin mathskip code. */
- if (glue_is_zero(p)) {
- d = surround(p);
- break;
- } else {
- /*tex Fall through. */
- }
- /*tex End mathskip code. */
- case glue_node:
- /*tex
-
- We need to be careful that |w|, |v|, and |d| do not depend on
- any |glue_set| values, since such values are subject to
- system-dependent rounding. System-dependent numbers are not
- allowed to infiltrate parameters like |pre_display_size|,
- since \TeX82 is supposed to make the same decisions on all
- machines.
-
- */
- d = width(p);
- if (glue_sign(r) == stretching) {
- if ((glue_order(r) == stretch_order(p)) && (stretch(p) != 0))
- v = max_dimen;
- } else if (glue_sign(r) == shrinking) {
- if ((glue_order(r) == shrink_order(p)) && (shrink(p) != 0))
- v = max_dimen;
- }
- if (subtype(p) >= a_leaders)
- goto FOUND;
- break;
- default:
- d = 0;
- break;
- }
- if (v < max_dimen)
- v = v + d;
- goto NOT_FOUND;
- FOUND:
- if (v < max_dimen) {
- v = v + d;
- w = v;
- } else {
- w = max_dimen;
- break;
- }
- NOT_FOUND:
- p = vlink(p);
- }
- return w;
-}
-
-pointer actual_box_width(pointer r, scaled base_width)
-{
- /*tex
-
- Often this is the same as:
-
- \starttyping
- return + shift_amount(r) + base_width +
- natural_sizes(list_ptr(r),null,(glue_ratio) glue_set(r),glue_sign(r),glue_order(r),box_dir(r));
- \stoptyping
- */
- return get_actual_box_width(r,list_ptr(r),shift_amount(r) + base_width);
-}
-
-halfword tail_of_list(halfword p)
-{
- halfword q = p;
- while (vlink(q) != null)
- q = vlink(q);
- return q;
-}
-
-int var_used;
-
-/*tex
-
- Attribute lists need two extra globals to increase processing efficiency.
- |max_used_attr| limits the test loop that checks for set attributes, and
- |attr_list_cache| contains a pointer to an already created attribute list. It
- is set to the special value |cache_disabled| when the current value can no
- longer be trusted: after an assignment to an attribute register, and after a
- group has ended.
-
-*/
-
-/*tex The maximum assigned attribute id: */
-
-int max_used_attr;
-halfword attr_list_cache;
-
-/*tex
-
- From the computer's standpoint, \TeX's chief mission is to create horizontal
- and vertical lists. We shall now investigate how the elements of these lists
- are represented internally as nodes in the dynamic memory.
-
- A horizontal or vertical list is linked together by |link| fields in the
- first word of each node. Individual nodes represent boxes, glue, penalties,
- or special things like discretionary hyphens; because of this variety, some
- nodes are longer than others, and we must distinguish different kinds of
- nodes. We do this by putting a `|type|' field in the first word, together
- with the link and an optional `|subtype|'.
-
- Character nodes appear only in horizontal lists, never in vertical lists.
-
- An |hlist_node| stands for a box that was made from a horizontal list. Each
- |hlist_node| is seven words long, and contains the following fields (in
- addition to the mandatory |type| and |link|, which we shall not mention
- explicitly when discussing the other node types): The |height| and |width|
- and |depth| are scaled integers denoting the dimensions of the box. There is
- also a |shift_amount| field, a scaled integer indicating how much this box
- should be lowered (if it appears in a horizontal list), or how much it should
- be moved to the right (if it appears in a vertical list). There is a
- |list_ptr| field, which points to the beginning of the list from which this
- box was fabricated; if |list_ptr| is |null|, the box is empty. Finally, there
- are three fields that represent the setting of the glue: |glue_set(p)| is a
- word of type |glue_ratio| that represents the proportionality constant for
- glue setting; |glue_sign(p)| is |stretching| or |shrinking| or |normal|
- depending on whether or not the glue should stretch or shrink or remain
- rigid; and |glue_order(p)| specifies the order of infinity to which glue
- setting applies (|normal|, |sfi|, |fil|, |fill|, or |filll|). The |subtype|
- field is not used.
-
- The |new_null_box| function returns a pointer to an |hlist_node| in which all
- subfields have the values corresponding to `\.{\\hbox\{\}}'. The |subtype|
- field is set to |min_quarterword|, since that's the desired |span_count|
- value if this |hlist_node| is changed to an |unset_node|.
-
-*/
-
-/*tex Create a new box node. */
-
-halfword new_null_box(void)
-{
- halfword p = new_node(hlist_node, min_quarterword);
- box_dir(p) = text_direction_par;
- return p;
-}
-
-/*tex
-
- A |vlist_node| is like an |hlist_node| in all respects except that it
- contains a vertical list.
-
- A |rule_node| stands for a solid black rectangle; it has |width|, |depth|,
- and |height| fields just as in an |hlist_node|. However, if any of these
- dimensions is $-2^{30}$, the actual value will be determined by running the
- rule up to the boundary of the innermost enclosing box. This is called a
- ``running dimension.'' The |width| is never running in an hlist; the |height|
- and |depth| are never running in a~vlist.
-
- A new rule node is delivered by the |new_rule| function. It makes all the
- dimensions ``running,'' so you have to change the ones that are not allowed
- to run.
-
-*/
-
-halfword new_rule(int s)
-{
- halfword p = new_node(rule_node,s);
- return p;
-}
-
-/*tex
-
- Insertions are represented by |ins_node| records, where the |subtype|
- indicates the corresponding box number. For example, `\.{\\insert 250}' leads
- to an |ins_node| whose |subtype| is |250+min_quarterword|. The |height| field
- of an |ins_node| is slightly misnamed; it actually holds the natural height
- plus depth of the vertical list being inserted. The |depth| field holds the
- |split_max_depth| to be used in case this insertion is split, and the
- |split_top_ptr| points to the corresponding |split_top_skip|. The
- |float_cost| field holds the |floating_penalty| that will be used if this
- insertion floats to a subsequent page after a split insertion of the same
- class. There is one more field, the |ins_ptr|, which points to the beginning
- of the vlist for the insertion.
-
- A |mark_node| has a |mark_ptr| field that points to the reference count of a
- token list that contains the user's \.{\\mark} text. In addition there is a
- |mark_class| field that contains the mark class.
-
- An |adjust_node|, which occurs only in horizontal lists, specifies material
- that will be moved out into the surrounding vertical list; i.e., it is used
- to implement \TeX's `\.{\\vadjust}' operation. The |adjust_ptr| field points
- to the vlist containing this material.
-
- A |glyph_node|, which occurs only in horizontal lists, specifies a glyph in a
- particular font, along with its attribute list. Older versions of \TeX\ could
- use token memory for characters, because the font,char combination would fit
- in a single word (both values were required to be strictly less than
- $2^{16}$). In LuaTeX, room is needed for characters that are larger than
- that, as well as a pointer to a potential attribute list, and the two
- displacement values.
-
- In turn, that made the node so large that it made sense to merge ligature
- glyphs as well, as that requires only one extra pointer. A few extra classes
- of glyph nodes will be introduced later. The unification of all those types
- makes it easier to manipulate lists of glyphs. The subtype differentiates
- various glyph kinds.
-
- First, here is a function that returns a pointer to a glyph node for a given
- glyph in a given font. If that glyph doesn't exist, |null| is returned
- instead. Nodes of this subtype are directly created only for accents and
- their base (through |make_accent|), and math nucleus items (in the conversion
- from |mlist| to |hlist|).
-
-*/
-
-halfword new_glyph(int f, int c)
-{
- halfword p = null;
- if ((f == 0) || (char_exists(f, c))) {
- p = new_glyph_node();
- set_to_glyph(p);
- font(p) = f;
- character(p) = c;
- }
- return p;
-}
-
-/*tex
-
- A subset of the glyphs nodes represent ligatures: characters fabricated from
- the interaction of two or more actual characters. The characters that
- generated the ligature have not been forgotten, since they are needed for
- diagnostic messages; the |lig_ptr| field points to a linked list of character
- nodes for all original characters that have been deleted. (This list might be
- empty if the characters that generated the ligature were retained in other
- nodes.)
-
- The |subtype| field of these |glyph_node|s is 1, plus 2 and/or 1 if the
- original source of the ligature included implicit left and/or right
- boundaries. These nodes are created by the C function |new_ligkern|.
-
- A third general type of glyphs could be called a character, as it only
- appears in lists that are not yet processed by the ligaturing and kerning
- steps of the program.
-
- |main_control| inserts these, and they are later converted to
- |subtype_normal| by |new_ligkern|.
-
-*/
-
-quarterword norm_min(int h)
-{
- if (h <= 0)
- return 1;
- else if (h >= 255)
- return 255;
- else
- return (quarterword) h;
-}
-
-halfword new_char(int f, int c)
-{
- halfword p;
- p = new_glyph_node();
- set_to_character(p);
- font(p) = f;
- character(p) = c;
- lang_data(p) = make_lang_data(uc_hyph_par, cur_lang_par, left_hyphen_min_par, right_hyphen_min_par);
- return p;
-}
-
-/*tex
-
- Left and right ghost glyph nodes are the result of \.{\\leftghost} and
- \.{\\rightghost}, respectively. They are going to be removed by
- |new_ligkern|, at the end of which they are no longer needed.
-
- Here are a few handy helpers used by the list output routines. The yoffset
- has some history but we now give some control over its treatment:
-
- 0: what we had before
- 1: compensate height and depth
- 2: compensate height and depth, take max
- 3: we keep height and depth
-
- The modes are controlled by a variable because we need to retain downward
- compatibility.
-
-*/
-
-scaled glyph_width(halfword p)
-{
- scaled w = char_width(font(p), character(p));
- return w;
-}
-
-scaled glyph_height(halfword p)
-{
- scaled h = char_height(font(p), character(p));
- scaled y = y_displace(p);
- if ((glyph_dimensions_par == 0) || (glyph_dimensions_par == 1) || (glyph_dimensions_par == 2 && y > 0))
- h += y;
- if (h < 0)
- h = 0;
- return h;
-}
-
-scaled glyph_depth(halfword p) /* not used */
-{
- scaled d = char_depth(font(p), character(p));
- scaled y = y_displace(p);
- if ((glyph_dimensions_par == 0 && y > 0) || (glyph_dimensions_par == 1) || (glyph_dimensions_par == 2 && y < 0))
- d -= y;
- if (d < 0)
- d = 0;
- return d;
-}
-
-/*tex
-
- A |disc_node|, which occurs only in horizontal lists, specifies a
- ``dis\-cretion\-ary'' line break. If such a break occurs at node |p|, the
- text that starts at |pre_break(p)| will precede the break, the text that
- starts at |post_break(p)| will follow the break, and text that appears in
- |no_break(p)| nodes will be ignored. For example, an ordinary discretionary
- hyphen, indicated by `\.{\\-}', yields a |disc_node| with |pre_break|
- pointing to a |char_node| containing a hyphen, |post_break=null|, and
- |no_break=null|.
-
- If |subtype(p)=automatic_disc|, the |ex_hyphen_penalty| will be charged for
- this break. Otherwise the |hyphen_penalty| will be charged. The texts will
- actually be substituted into the list by the line-breaking algorithm if it
- decides to make the break, and the discretionary node will disappear at that
- time; thus, the output routine sees only discretionaries that were not
- chosen.
-
-*/
-
-halfword new_disc(void)
-{
- halfword p = new_node(disc_node, 0);
- disc_penalty(p) = hyphen_penalty_par;
- return p;
-}
-
-/*
-
- A |whatsit_node| is a wild card reserved for extensions to \TeX. The
- |subtype| field in its first word says what `\\{whatsit}' it is, and
- implicitly determines the node size (which must be 2 or more) and the format
- of the remaining words. When a |whatsit_node| is encountered in a list,
- special actions are invoked; knowledgeable people who are careful not to mess
- up the rest of \TeX\ are able to make \TeX\ do new things by adding code at
- the end of the program. For example, there might be a `\TeX nicolor'
- extension to specify different colors of ink, and the whatsit node might
- contain the desired parameters.
-
- The present implementation of \TeX\ treats the features associated with
- `\.{\\write}' and `\.{\\special}' as if they were extensions, in order to
- illustrate how such routines might be coded. We shall defer further
- discussion of extensions until the end of this program.
-
- A |math_node|, which occurs only in horizontal lists, appears before and
- after mathematical formulas. The |subtype| field is |before| before the
- formula and |after| after it. There is a |surround| field, which represents
- the amount of surrounding space inserted by \.{\\mathsurround}.
-
-*/
-
-halfword new_math(scaled w, int s)
-{
- halfword p = new_node(math_node, s);
- surround(p) = w;
- return p;
-}
-
-/*tex
-
- \TeX\ makes use of the fact that |hlist_node|, |vlist_node|, |rule_node|,
- |ins_node|, |mark_node|, |adjust_node|, |disc_node|, |whatsit_node|, and
- |math_node| are at the low end of the type codes, by permitting a break at
- glue in a list if and only if the |type| of the previous node is less than
- |math_node|. Furthermore, a node is discarded after a break if its type is
- |math_node| or~more.
-
- A |glue_node| represents glue in a list. However, it is really only a pointer
- to a separate glue specification, since \TeX\ makes use of the fact that many
- essentially identical nodes of glue are usually present. If |p| points to a
- |glue_node|, |glue_ptr(p)| points to another packet of words that specify the
- stretch and shrink components, etc.
-
- Glue nodes also serve to represent leaders; the |subtype| is used to
- distinguish between ordinary glue (which is called |normal|) and the three
- kinds of leaders (which are called |a_leaders|, |c_leaders|, and
- |x_leaders|). The |leader_ptr| field points to a rule node or to a box node
- containing the leaders; it is set to |null| in ordinary glue nodes.
-
- Many kinds of glue are computed from \TeX's ``skip'' parameters, and it is
- helpful to know which parameter has led to a particular glue node. Therefore
- the |subtype| is set to indicate the source of glue, whenever it originated
- as a parameter. We will be defining symbolic names for the parameter numbers
- later (e.g., |line_skip_code=0|, |baseline_skip_code=1|, etc.); it suffices
- for now to say that the |subtype| of parametric glue will be the same as the
- parameter number, plus~one.
-
- In math formulas there are two more possibilities for the |subtype| in a glue
- node: |mu_glue| denotes an \.{\\mskip} (where the units are scaled \.{mu}
- instead of scaled \.{pt}); and |cond_math_glue| denotes the `\.{\\nonscript}'
- feature that cancels the glue node immediately following if it appears in a
- subscript.
-
- A glue specification has a halfword reference count in its first word,
- representing |null| plus the number of glue nodes that point to it (less
- one). Note that the reference count appears in the same position as the
- |link| field in list nodes; this is the field that is initialized to |null|
- when a node is allocated, and it is also the field that is flagged by
- |empty_flag| in empty nodes.
-
- Glue specifications also contain three |scaled| fields, for the |width|,
- |stretch|, and |shrink| dimensions. Finally, there are two one-byte fields
- called |stretch_order| and |shrink_order|; these contain the orders of
- infinity (|normal|, |sfi|, |fil|, |fill|, or |filll|) corresponding to the
- stretch and shrink values.
-
- Here is a function that returns a pointer to a copy of a glue spec. The
- reference count in the copy is |null|, because there is assumed to be exactly
- one reference to the new specification.
-
-*/
-
-halfword new_spec(halfword q)
-{
- if (q == null) {
- return copy_node(zero_glue);
- } else if (type(q) == glue_spec_node) {
- return copy_node(q);
- } else if (type(q) == glue_node) {
- halfword p = copy_node(zero_glue);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
- return p;
- } else {
- /*tex Alternatively we can issue a warning. */
- return copy_node(zero_glue);
- }
-}
-
-/*tex
-
- And here's a function that creates a glue node for a given parameter
- identified by its code number; for example, |new_param_glue(line_skip_code)|
- returns a pointer to a glue node for the current \.{\\lineskip}.
-
-*/
-
-halfword new_param_glue(int n)
-{
- halfword p = new_node(glue_node, n + 1);
- halfword q = glue_par(n);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
- return p;
-}
-
-/*tex
-
- Glue nodes that are more or less anonymous are created by |new_glue|, whose
- argument points to a glue specification.
-
-*/
-
-halfword new_glue(halfword q)
-{
- halfword p = new_node(glue_node, normal);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
- return p;
-}
-
-/*tex
-
- Still another subroutine is needed: This one is sort of a combination of
- |new_param_glue| and |new_glue|. It creates a glue node for one of the
- current glue parameters, but it makes a fresh copy of the glue specification,
- since that specification will probably be subject to change, while the
- parameter will stay put.
-
- The global variable |temp_ptr| is set to the address of the new spec.
-
-*/
-
-halfword new_skip_param(int n)
-{
- halfword p = new_node(glue_node, n + 1);
- halfword q = glue_par(n);
- width(p) = width(q);
- stretch(p) = stretch(q);
- shrink(p) = shrink(q);
- stretch_order(p) = stretch_order(q);
- shrink_order(p) = shrink_order(q);
- return p;
-}
-
-/*tex
-
- A |kern_node| has a |width| field to specify a (normally negative) amount of
- spacing. This spacing correction appears in horizontal lists between letters
- like A and V when the font designer said that it looks better to move them
- closer together or further apart. A kern node can also appear in a vertical
- list, when its `|width|' denotes additional spacing in the vertical
- direction. The |subtype| is either |normal| (for kerns inserted from font
- information or math mode calculations) or |explicit| (for kerns inserted from
- \.{\\kern} and \.{\\/} commands) or |acc_kern| (for kerns inserted from
- non-math accents) or |mu_glue| (for kerns inserted from \.{\\mkern}
- specifications in math formulas).
-
- The |new_kern| function creates a kern node having a given width.
-
-*/
-
-halfword new_kern(scaled w)
-{
- halfword p = new_node(kern_node, normal);
- width(p) = w;
- return p;
-}
-
-/*tex
-
- A |penalty_node| specifies the penalty associated with line or page breaking,
- in its |penalty| field. This field is a fullword integer, but the full range
- of integer values is not used: Any penalty |>=10000| is treated as infinity,
- and no break will be allowed for such high values. Similarly, any penalty
- |<=-10000| is treated as negative infinity, and a break will be forced.
-
- Anyone who has been reading the last few sections of the program will be able
- to guess what comes next.
-
-*/
-
-halfword new_penalty(int m, int s)
-{
- halfword p = new_node(penalty_node, 0);
- penalty(p) = m;
- subtype(p) = s;
- return p;
-}
-
-/*tex
-
- You might think that we have introduced enough node types by now. Well,
- almost, but there is one more: An |unset_node| has nearly the same format as
- an |hlist_node| or |vlist_node|; it is used for entries in \.{\\halign} or
- \.{\\valign} that are not yet in their final form, since the box dimensions
- are their ``natural'' sizes before any glue adjustment has been made. The
- |glue_set| word is not present; instead, we have a |glue_stretch| field,
- which contains the total stretch of order |glue_order| that is present in the
- hlist or vlist being boxed. Similarly, the |shift_amount| field is replaced
- by a |glue_shrink| field, containing the total shrink of order |glue_sign|
- that is present. The |subtype| field is called |span_count|; an unset box
- typically contains the data for |qo(span_count)+1| columns. Unset nodes will
- be changed to box nodes when alignment is completed.
-
- In fact, there are still more types coming. When we get to math formula
- processing we will see that a |style_node| has |type=14|; and a number of
- larger type codes will also be defined, for use in math mode only.
-
- Warning: If any changes are made to these data structure layouts, such as
- changing any of the node sizes or even reordering the words of nodes, the
- |copy_node_list| procedure and the memory initialization code below may have
- to be changed. Such potentially dangerous parts of the program are listed in
- the index under `data structure assumptions'. However, other references to
- the nodes are made symbolically in terms of the \.{WEB} macro definitions
- above, so that format changes will leave \TeX's other algorithms intact.
-
-*/
-
-halfword make_local_par_node(int mode)
-{
- int callback_id;
- halfword q;
- halfword p = new_node(local_par_node,mode);
- local_pen_inter(p) = local_inter_line_penalty_par;
- local_pen_broken(p) = local_broken_penalty_par;
- if (local_left_box_par != null) {
- q = copy_node_list(local_left_box_par);
- local_box_left(p) = q;
- local_box_left_width(p) = width(local_left_box_par);
- }
- if (local_right_box_par != null) {
- q = copy_node_list(local_right_box_par);
- local_box_right(p) = q;
- local_box_right_width(p) = width(local_right_box_par);
- }
- local_par_dir(p) = par_direction_par;
- /*tex Callback with node passed: */
- callback_id = callback_defined(insert_local_par_callback);
- if (callback_id > 0) {
- /*tex Todo: use general mechanism/wrapper. */
- int sfix = lua_gettop(Luas);
- if (!get_callback(Luas, callback_id)) {
- lua_settop(Luas, sfix);
- } else {
- int i;
- nodelist_to_lua(Luas, p);
- lua_push_local_par_mode(Luas,mode)
- /*tex 2 arg, 0 result */
- i = lua_pcall(Luas, 2, 0, 0);
- if (i != 0) {
- lua_gc(Luas, LUA_GCCOLLECT, 0);
- Luas = luatex_error(Luas, (i == LUA_ERRRUN ? 0 : 1));
- }
- lua_settop(Luas, sfix);
- }
- }
- return p;
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/texnodes.h b/Build/source/texk/web2c/luatexdir/tex/texnodes.h
deleted file mode 100644
index 9742ca4966c..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/texnodes.h
+++ /dev/null
@@ -1,1188 +0,0 @@
-/* texnodes.h
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#include <stdarg.h>
-
-#ifndef __NODES_H__
-# define __NODES_H__
-
-# define varmemcast(a) (memory_word *)(a)
-
-extern memory_word *volatile varmem;
-extern halfword var_mem_max;
-
-extern halfword get_node(int s);
-extern void free_node(halfword p, int s);
-extern void init_node_mem(int s);
-extern void dump_node_mem(void);
-extern void undump_node_mem(void);
-
-# define max_halfword 0x3FFFFFFF
-# define max_dimen 0x3FFFFFFF
-# ifndef null
-# define null 0
-# endif
-# define null_flag -0x40000000
-# define zero_glue 0
-# define normal 0
-
-# define vinfo(a) varmem[(a)].hh.v.LH
-# define vlink(a) varmem[(a)].hh.v.RH
-# define type(a) varmem[(a)].hh.u.B0
-# define subtype(a) varmem[(a)].hh.u.B1
-# define node_attr(a) vinfo((a)+1)
-# define alink(a) vlink((a)+1)
-
-# define node_size(a) varmem[(a)].hh.v.LH
-
-# define rlink(a) vlink((a)+1) /* aka alink() */
-# define tlink(a) vinfo((a)+1) /* overlaps with node_attr() */
-
-/* really special head node pointers that only need links */
-
-# define temp_node_size 2
-
-/* attribute lists */
-
-# define UNUSED_ATTRIBUTE -0x7FFFFFFF /* as low as it goes */
-
-/* it is convenient to have attribute list nodes and attribute node
- * be the same size
- */
-
-# define attribute_node_size 2
-# define cache_disabled max_halfword
-
-# define attr_list_ref(a) vinfo((a)+1) /* the reference count */
-# define attribute_id(a) vinfo((a)+1)
-# define attribute_value(a) vlink((a)+1)
-
-# define assign_attribute_ref(n,p) do { \
- node_attr(n) = p;attr_list_ref(p)++; \
-} while (0)
-
-# define add_node_attr_ref(a) do { \
- if (a!=null) attr_list_ref((a))++; \
-} while (0)
-
-# define replace_attribute_list(a,b) do { \
- delete_attribute_ref(node_attr(a)); \
- node_attr(a)=b; \
-} while (0)
-
-extern void update_attribute_cache(void);
-extern halfword copy_attribute_list(halfword n);
-extern halfword do_set_attribute(halfword p, int i, int val);
-
-# define width_offset 2
-# define depth_offset 3
-# define height_offset 4
-# define list_offset 6
-
-typedef enum {
- user_skip_glue,
- line_skip_glue,
- baseline_skip_glue,
- par_skip_glue,
- above_display_skip_glue,
- below_display_skip_glue,
- above_display_short_skip_glue,
- below_display_short_skip_glue,
- left_skip_glue,
- right_skip_glue,
- top_skip_glue,
- split_top_skip_glue,
- tab_skip_glue,
- space_skip_glue,
- xspace_skip_glue,
- par_fill_skip_glue,
- math_skip_glue,
- thin_mu_skip_glue,
- med_mu_skip_glue,
- thick_mu_skip_glue,
- /* math */
- cond_math_glue = 98, /* special |subtype| to suppress glue in the next node */
- mu_glue, /* |subtype| for math glue */
- /* leaders */
- a_leaders, /* |subtype| for aligned leaders */
- c_leaders, /* |subtype| for centered leaders */
- x_leaders, /* |subtype| for expanded leaders */
- g_leaders /* |subtype| for global (page) leaders */
-} glue_subtypes;
-
-/* normal nodes */
-
-# define inf_bad 10000 /* infinitely bad value */
-# define inf_penalty inf_bad /* ``infinite'' penalty value */
-# define eject_penalty -(inf_penalty) /* ``negatively infinite'' penalty value */
-
-# define penalty_node_size 3
-# define penalty(a) vlink((a)+2)
-
-typedef enum {
- user_penalty,
- linebreak_penalty, /* includes widow, club, broken ect */
- line_penalty,
- word_penalty,
- final_penalty,
- noad_penalty,
- before_display_penalty,
- after_display_penalty,
- equation_number_penalty,
-} penalty_subtypes ;
-
-/*
-# define glue_node_size 4
-# define glue_ptr(a) vinfo((a)+2)
-# define leader_ptr(a) vlink((a)+2)
-# define synctex_tag_glue(a) vinfo((a)+3)
-# define synctex_line_glue(a) vlink((a)+3)
-*/
-
-# define glue_node_size 7
-# define glue_spec_size 5
-/* define width(a) vinfo((a)+2) */
-/* define leader_ptr(a) vlink((a)+2) */
-# define shrink(a) vinfo((a)+3)
-# define stretch(a) vlink((a)+3)
-# define stretch_order(a) vinfo((a)+4)
-# define shrink_order(a) vlink((a)+4)
-# define leader_ptr(a) vlink((a)+5) /* should be in vlink((a)+2) but fails */
-# define synctex_tag_glue(a) vinfo((a)+6)
-# define synctex_line_glue(a) vlink((a)+6)
-
-#define glue_is_zero(p) \
- ((p == null) || (width(p) == 0 && stretch(p) == 0 && shrink(p) == 0))
-
-#define glue_is_positive(p) \
- ((p == null) || (width(p) > 0))
-
-#define reset_glue_to_zero(p) \
- if (p != null) { \
- width(p) = 0; \
- stretch(p) = 0; \
- shrink(p) = 0; \
- stretch_order(p) = 0; \
- shrink_order(p) = 0; \
- }
-
-#define copy_glue_values(p,q) \
- if (q == null) { \
- width(p) = 0; \
- stretch(p) = 0; \
- shrink(p) = 0; \
- stretch_order(p) = 0; \
- shrink_order(p) = 0; \
- } else { \
- width(p) = width(q); \
- stretch(p) = stretch(q); \
- shrink(p) = shrink(q); \
- stretch_order(p) = stretch_order(q); \
- shrink_order(p) = shrink_order(q); \
- }
-
-
-/*
- disc nodes could eventually be smaller, because the indirect
- pointers are not really needed (8 instead of 10).
-*/
-
-typedef enum {
- discretionary_disc = 0,
- explicit_disc,
- automatic_disc,
- syllable_disc,
- init_disc, /* first of a duo of syllable_discs */
- select_disc, /* second of a duo of syllable_discs */
-} discretionary_subtypes;
-
-# define disc_node_size 11
-# define pre_break_head(a) ((a)+5)
-# define post_break_head(a) ((a)+7)
-# define no_break_head(a) ((a)+9)
-
-# define disc_penalty(a) vlink((a)+2)
-# define pre_break(a) vinfo((a)+3)
-# define post_break(a) vlink((a)+3)
-# define no_break(a) vlink((a)+4) /* we have vinfo((a)+4) for later usage */
-
-# define vlink_pre_break(a) vlink(pre_break_head(a))
-# define vlink_post_break(a) vlink(post_break_head(a))
-# define vlink_no_break(a) vlink(no_break_head(a))
-
-# define tlink_pre_break(a) tlink(pre_break_head(a))
-# define tlink_post_break(a) tlink(post_break_head(a))
-# define tlink_no_break(a) tlink(no_break_head(a))
-
-typedef enum {
- font_kern = 0,
- explicit_kern, /* |subtype| of kern nodes from \.{\\kern} and \.{\\/} */
- accent_kern, /* |subtype| of kern nodes from accents */
- italic_kern,
-} kern_subtypes;
-
-# define kern_node_size 5
-# define ex_kern(a) vinfo((a)+3) /* expansion factor (hz) */
-# define synctex_tag_kern(a) vinfo((a)+4)
-# define synctex_line_kern(a) vlink((a)+4)
-
-# define box_node_size 9
-
-/* todo, make an enum of this */
-
-typedef enum {
- unknown_list = 0,
- line_list = 1, /* paragraph lines */
- hbox_list = 2, /* \.{\\hbox} */
- indent_list = 3, /* indentation box */
- align_row_list = 4, /* row from a \.{\\halign} or \.{\\valign} */
- align_cell_list = 5, /* cell from a \.{\\halign} or \.{\\valign} */
- equation_list = 6, /* display equation */
- equation_number_list = 7, /* display equation number */
- math_list_list = 8,
- math_char_list = 9,
- math_h_extensible_list = 10,
- math_v_extensible_list = 11,
- math_h_delimiter_list = 12,
- math_v_delimiter_list = 13,
- math_over_delimiter_list = 14,
- math_under_delimiter_list = 15,
- math_numerator_list = 16,
- math_denominator_list = 17,
- math_limits_list = 18,
- math_fraction_list = 19,
- math_nucleus_list = 20,
- math_sup_list = 21,
- math_sub_list = 22,
- math_degree_list = 23,
- math_scripts_list = 24,
- math_over_list = 25,
- math_under_list = 26,
- math_accent_list = 27,
- math_radical_list = 28,
-} list_subtypes ;
-
-# define width(a) varmem[(a)+2].cint
-# define depth(a) varmem[(a)+3].cint
-# define height(a) varmem[(a)+4].cint
-# define shift_amount(a) vlink((a)+5)
-# define box_dir(a) vinfo((a)+5)
-# define list_ptr(a) vlink((a)+6)
-# define glue_order(a) subtype((a)+6)
-# define glue_sign(a) type((a)+6)
-# define glue_set(a) varmem[(a)+7].gr
-# define synctex_tag_box(a) vinfo((a)+8)
-# define synctex_line_box(a) vlink((a)+8)
-
-/* unset nodes */
-
-# define glue_stretch(a) varmem[(a)+7].cint
-# define glue_shrink shift_amount
-# define span_count subtype
-
-typedef enum {
- normal_rule = 0,
- box_rule,
- image_rule,
- empty_rule,
- user_rule,
- math_over_rule,
- math_under_rule,
- math_fraction_rule,
- math_radical_rule,
- outline_rule,
-} rule_subtypes;
-
-# define rule_node_size 9
-# define rule_dir(a) vlink((a)+5)
-# define rule_index(a) vinfo((a)+6)
-# define rule_transform(a) vlink((a)+6)
-# define rule_left(a) vinfo((a)+7)
-# define rule_right(a) vlink((a)+7)
-# define synctex_tag_rule(a) vinfo((a)+8)
-# define synctex_line_rule(a) vlink((a)+8)
-
-# define rule_math_size rule_index
-# define rule_math_font rule_transform
-
-# define mark_node_size 3
-# define mark_ptr(a) vlink((a)+2)
-# define mark_class(a) vinfo((a)+2)
-
-# define adjust_node_size 3
-# define adjust_pre subtype
-# define adjust_ptr(a) vlink(a+2)
-
-# define glyph_node_size 7
-# define character(a) vinfo((a)+2)
-# define font(a) vlink((a)+2)
-# define lang_data(a) vinfo((a)+3)
-# define lig_ptr(a) vlink((a)+3)
-# define x_displace(a) vinfo((a)+4)
-# define y_displace(a) vlink((a)+4)
-# define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */
-# define glyph_node_data(a) vlink((a)+5)
-# define synctex_tag_glyph(a) vinfo((a)+6)
-# define synctex_line_glyph(a) vlink((a)+6)
-
-# define is_char_node(a) (a!=null && type(a)==glyph_node)
-
-# define char_lang(a) ((const int)(signed short)(((signed int)((unsigned)lang_data(a)&0x7FFF0000)<<1)>>17))
-# define char_lhmin(a) ((const int)(((unsigned)lang_data(a) & 0x0000FF00)>>8))
-# define char_rhmin(a) ((const int)(((unsigned)lang_data(a) & 0x000000FF)))
-# define char_uchyph(a) ((const int)(((unsigned)lang_data(a) & 0x80000000)>>31))
-
-# define make_lang_data(a,b,c,d) (a>0 ? (1<<31): 0)+ \
- (b<<16)+ (((c>0 && c<256) ? c : 255)<<8)+(((d>0 && d<256) ? d : 255))
-
-# define init_lang_data(a) lang_data(a)=256+1
-
-# define set_char_lang(a,b) lang_data(a)=make_lang_data(char_uchyph(a),b,char_lhmin(a),char_rhmin(a))
-# define set_char_lhmin(a,b) lang_data(a)=make_lang_data(char_uchyph(a),char_lang(a),b,char_rhmin(a))
-# define set_char_rhmin(a,b) lang_data(a)=make_lang_data(char_uchyph(a),char_lang(a),char_lhmin(a),b)
-# define set_char_uchyph(a,b) lang_data(a)=make_lang_data(b,char_lang(a),char_lhmin(a),char_rhmin(a))
-
-# define margin_kern_node_size 4
-# define margin_char(a) vlink((a)+3)
-
-/*@# {|subtype| of marginal kerns}*/
-
-typedef enum {
- left_side = 0,
- right_side
-} margin_kern_subtypes ;
-
-typedef enum {
- before = 0,
- after
-} math_subtypes ;
-
-# define math_node_size 7
-/* define width(a) vinfo((a)+2) */
-/* overlaps width */
-/* define shrink(a) vinfo((a)+3) */
-/* define stretch(a) vlink((a)+3) */
-/* define stretch_order(a) vinfo((a)+4) */
-/* define shrink_order(a) vlink((a)+4) */
-/* leader_ptr slot */
-# define surround(a) vinfo((a)+5)
-# define synctex_tag_math(a) vinfo((a)+6)
-# define synctex_line_math(a) vlink((a)+6)
-
-# define ins_node_size 6
-# define float_cost(a) varmem[(a)+2].cint
-# define ins_ptr(a) vinfo((a)+5)
-# define split_top_ptr(a) vlink((a)+5)
-
-# define page_ins_node_size 5
-
-/* height = 4 */
-
-typedef enum {
- hlist_node = 0,
- vlist_node,
- rule_node,
- ins_node,
- mark_node,
- adjust_node,
- boundary_node,
- disc_node,
- whatsit_node,
-#define last_preceding_break_node whatsit_node
- local_par_node,
- dir_node,
-#define last_non_discardable_node dir_node
- math_node,
- glue_node,
- kern_node,
- penalty_node,
- unset_node,
- style_node,
- choice_node,
- simple_noad,
- radical_noad,
- fraction_noad,
- accent_noad,
- fence_noad,
- math_char_node, /* kernel fields */
- sub_box_node,
- sub_mlist_node,
- math_text_char_node,
- delim_node, /* shield fields */
- margin_kern_node,
- glyph_node, /* this and below have attributes */
- align_record_node,
- pseudo_file_node,
- pseudo_line_node,
- inserting_node,
- split_up_node,
- expr_node,
- nesting_node,
- span_node,
- attribute_node,
- glue_spec_node,
- attribute_list_node,
- temp_node,
- align_stack_node,
- movement_node,
- if_node,
- unhyphenated_node,
- hyphenated_node,
- delta_node,
- passive_node,
- shape_node,
-} node_types;
-
-# define MAX_NODE_TYPE shape_node /* 60 */
-
-/*
- TH: these two defines still need checking. The node ordering in luatex is not
- quite the same as in tex82, HH: but it's probably ok
-*/
-
-/*
-
- # define precedes_break(a) \
- # (type(a)<math_node && \
- # (type(a)!=whatsit_node || (subtype(a)!=dir_node && subtype(a)!=local_par_node)))
-
-*/
-
-/*
- # define precedes_break(a) (type(a)<math_node)
- # define non_discardable(a) (type(a)<math_node || type(a) == dir_node || type(a) == local_par_node)
-*/
-
-# define precedes_break(a) (type(a)<=last_preceding_break_node)
-# define precedes_kern(a) ((type(a) == kern_node) && (subtype(a) == font_kern || subtype(a) == accent_kern))
-# define precedes_dir(a) ((type(a) == dir_node) && (break_after_dir_mode_par == 1))
-# define non_discardable(a) (type(a)<=last_non_discardable_node)
-
-# define known_node_type(i) ( i >= 0 && i <= MAX_NODE_TYPE)
-
-# define last_known_node temp_node /* used by \lastnodetype */
-
-# define movement_node_size 3
-# define if_node_size 2
-# define align_stack_node_size 6
-# define nesting_node_size 2
-
-# define expr_node_size 3
-# define expr_type(A) type((A)+1)
-# define expr_state(A) subtype((A)+1) /* enum defined in scanning.w */
-# define expr_e_field(A) vlink((A)+1) /* saved expression so far */
-# define expr_t_field(A) vlink((A)+2) /* saved term so far */
-# define expr_n_field(A) vinfo((A)+2) /* saved numerator */
-
-# define span_node_size 3
-# define span_span(a) vlink((a)+1)
-# define span_link(a) vinfo((a)+1)
-
-# define pseudo_file_node_size 2
-# define pseudo_lines(a) vlink((a)+1)
-
-# define nodetype_has_attributes(t) (((t)<=glyph_node) && ((t)!=unset_node))
-
-# define nodetype_has_subtype(t) ((t)!=attribute_list_node && (t)!=attribute_node && (t)!=glue_spec_node)
-# define nodetype_has_prev(t) nodetype_has_subtype((t))
-
-/*
- style and choice nodes; style nodes can be smaller, the information is encoded in
- |subtype|, but choice nodes are on-the-spot converted to style nodes
-*/
-
-# define style_node_size 4
-# define display_mlist(a) vinfo((a)+2) /* mlist to be used in display style */
-# define text_mlist(a) vlink((a)+2) /* mlist to be used in text style */
-# define script_mlist(a) vinfo((a)+3) /* mlist to be used in script style */
-# define script_script_mlist(a) vlink((a)+3) /* mlist to be used in scriptscript style */
-
-/*
- because noad types get changed when processing we need to make sure some if the node
- sizes match and that we don't share slots with different properties
-
- once it's sorted out we can go smaller and also adapt the flush etc code to it
-*/
-
-/* regular noads */
-
-# define noad_size 8
-# define new_hlist(a) vlink((a)+2) /* the translation of an mlist */
-# define nucleus(a) vinfo((a)+2) /* the |nucleus| field of a noad */
-# define supscr(a) vlink((a)+3) /* the |supscr| field of a noad */
-# define subscr(a) vinfo((a)+3) /* the |subscr| field of a noad */
-# define noaditalic(a) vlink((a)+4)
-# define noadwidth(a) vinfo((a)+4)
-# define noadheight(a) vlink((a)+5)
-# define noaddepth(a) vinfo((a)+5)
-# define noadextra1(a) vlink((a)+6) /* we need to match delimiter (saves copy) */
-# define noadoptions(a) vinfo((a)+6)
-# define noadextra3(a) vlink((a)+7) /* see (!) below */
-# define noadextra4(a) vinfo((a)+7) /* used to store samesize */
-
-# define noad_fam(a) vlink((a)+6) /* noadextra1 */
-
-typedef enum {
- ord_noad_type = 0,
- op_noad_type_normal,
- op_noad_type_limits,
- op_noad_type_no_limits,
- bin_noad_type,
- rel_noad_type,
- open_noad_type,
- close_noad_type,
- punct_noad_type,
- inner_noad_type,
- under_noad_type,
- over_noad_type,
- vcenter_noad_type,
-} noad_types;
-
-/* accent noads */
-
-# define accent_noad_size 8
-# define top_accent_chr(a) vinfo((a)+6) /* the |top_accent_chr| field of an accent noad */
-# define bot_accent_chr(a) vlink((a)+6) /* the |bot_accent_chr| field of an accent noad */
-# define overlay_accent_chr(a) vinfo((a)+7) /* the |overlay_accent_chr| field of an accent noad */
-# define accentfraction(a) vlink((a)+7)
-
-typedef enum {
- bothflexible_accent,
- fixedtop_accent,
- fixedbottom_accent,
- fixedboth_accent,
-} math_accent_subtypes ;
-
-/* left and right noads */
-
-# define fence_noad_size 8 /* needs to match noad size */
-# define delimiteritalic(a) vlink((a)+4)
-/* define delimiterwidth(a) vinfo((a)+4) */
-# define delimiterheight(a) vlink((a)+5)
-# define delimiterdepth(a) vinfo((a)+5)
-# define delimiter(a) vlink((a)+6) /* |delimiter| field in left and right noads */
-# define delimiteroptions(a) vinfo((a)+6)
-# define delimiterclass(a) vlink((a)+7) /* (!) we could probably pack some more in 6 */
-# define delimitersamesize(a) vinfo((a)+7) /* set by engine */
-
-/* when dimensions then axis else noaxis */
-
-typedef enum {
- noad_option_set = 0x08,
- noad_option_unused_1 = 0x00 + 0x08,
- noad_option_unused_2 = 0x01 + 0x08,
- noad_option_axis = 0x02 + 0x08,
- noad_option_no_axis = 0x04 + 0x08,
- noad_option_exact = 0x10 + 0x08,
- noad_option_left = 0x11 + 0x08,
- noad_option_middle = 0x12 + 0x08,
- noad_option_right = 0x14 + 0x08,
- noad_option_no_sub_script = 0x21 + 0x08,
- noad_option_no_super_script = 0x22 + 0x08,
- noad_option_no_script = 0x23 + 0x08,
- noad_option_no_rule = 0x24 + 0x08,
-} delimiter_options ;
-
-# define delimiteroptionset(a) ((delimiteroptions(a) & noad_option_set ) == noad_option_set )
-# define delimiteraxis(a) ((delimiteroptions(a) & noad_option_axis ) == noad_option_axis )
-# define delimiternoaxis(a) ((delimiteroptions(a) & noad_option_no_axis) == noad_option_no_axis)
-# define delimiterexact(a) ((delimiteroptions(a) & noad_option_exact ) == noad_option_exact )
-
-# define noadoptionnosubscript(a) ( (type(a) == simple_noad) && ( \
- ((delimiteroptions(a) & noad_option_no_sub_script ) == noad_option_no_sub_script) || \
- ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) ))
-# define noadoptionnosupscript(a) ( (type(a) == simple_noad) && ( \
- ((delimiteroptions(a) & noad_option_no_super_script) == noad_option_no_super_script) || \
- ((delimiteroptions(a) & noad_option_no_script ) == noad_option_no_script ) ))
-
-typedef enum {
- noad_delimiter_mode_noshift = 0x01,
- noad_delimiter_mode_italics = 0x02,
- noad_delimiter_mode_ordinal = 0x04,
- noad_delimiter_mode_samenos = 0x08,
- noad_delimiter_mode_charnos = 0x10,
-} delimiter_modes ;
-
-# define delimitermodenoshift ((math_delimiters_mode_par & noad_delimiter_mode_noshift) == noad_delimiter_mode_noshift)
-# define delimitermodeitalics ((math_delimiters_mode_par & noad_delimiter_mode_italics) == noad_delimiter_mode_italics)
-# define delimitermodeordinal ((math_delimiters_mode_par & noad_delimiter_mode_ordinal) == noad_delimiter_mode_ordinal)
-# define delimitermodesamenos ((math_delimiters_mode_par & noad_delimiter_mode_samenos) == noad_delimiter_mode_samenos)
-# define delimitermodecharnos ((math_delimiters_mode_par & noad_delimiter_mode_charnos) == noad_delimiter_mode_charnos)
-
-/* subtype of fence noads */
-
-/*
-# define left_noad_side 1
-# define middle_noad_side 2
-# define right_noad_side 3
-# define no_noad_side 4
-*/
-
-typedef enum {
- unset_noad_side = 0,
- left_noad_side = 1,
- middle_noad_side = 2,
- right_noad_side = 3,
- no_noad_side = 4,
-} fence_subtypes ;
-
-/* fraction noads */
-
-# define fraction_noad_size 8
-# define thickness(a) vlink((a)+2) /* |thickness| field in a fraction noad */
-# define numerator(a) vlink((a)+3) /* |numerator| field in a fraction noad */
-# define denominator(a) vinfo((a)+3) /* |denominator| field in a fraction noad */
-# define left_delimiter(a) vlink((a)+5) /* first delimiter field of a noad */
-# define right_delimiter(a) vinfo((a)+5) /* second delimiter field of a fraction noad */
-# define middle_delimiter(a) vlink((a)+6)
-# define fractionoptions(a) vinfo((a)+6)
-# define fraction_fam(a) vlink((a)+7)
-
-# define fractionoptionset(a) ((fractionoptions(a) & noad_option_set ) == noad_option_set )
-# define fractionexact(a) ((fractionoptions(a) & noad_option_exact ) == noad_option_exact )
-# define fractionnoaxis(a) ((fractionoptions(a) & noad_option_no_axis) == noad_option_no_axis)
-# define fractionnorule(a) ((fractionoptions(a) & noad_option_no_rule) == noad_option_no_rule)
-
-/* radical noads */
-/* this is like a fraction, but it only stores a |left_delimiter| */
-
-# define radical_noad_size 7
-# define radicalwidth(a) vinfo((a)+4)
-# define degree(a) vlink((a)+6) /* the root degree in a radical noad */
-# define radicaloptions(a) vinfo((a)+6)
-
-# define radicaloptionset(a) ((radicaloptions(a) & noad_option_set ) == noad_option_set)
-# define radicalexact(a) ((radicaloptions(a) & noad_option_exact ) == noad_option_exact)
-# define radicalleft(a) ((radicaloptions(a) & noad_option_left ) == noad_option_left)
-# define radicalmiddle(a) ((radicaloptions(a) & noad_option_middle) == noad_option_middle)
-# define radicalright(a) ((radicaloptions(a) & noad_option_right ) == noad_option_right)
-
-typedef enum {
- radical_noad_type,
- uradical_noad_type,
- uroot_noad_type,
- uunderdelimiter_noad_type,
- uoverdelimiter_noad_type,
- udelimiterunder_noad_type,
- udelimiterover_noad_type,
-} radical_subtypes;
-
-/* accessors for the |nucleus|-style node fields */
-
-# define math_kernel_node_size 3
-# define math_fam(a) vinfo((a)+2)
-# define math_character(a) vlink((a)+2)
-# define math_list(a) vlink((a)+2)
-
-/* accessors for the |delimiter|-style two-word subnode fields */
-
-# define math_shield_node_size 4 /* not used yet */
-
-# define small_fam(A) vinfo((A)+2) /* |fam| for ``small'' delimiter */
-# define small_char(A) vlink((A)+2) /* |character| for ``small'' delimiter */
-# define large_fam(A) vinfo((A)+3) /* |fam| for ``large'' delimiter */
-# define large_char(A) vlink((A)+3) /* |character| for ``large'' delimiter */
-
-/* we should have the codes in a separate enum: extension_codes */
-
-/* be careful: must be in sync with whatsit_node_data[] ! (at least) */
-
-typedef enum {
- /* core */
- open_node = 0,
- write_node,
- close_node,
- special_node,
- use_box_resource_node,
- use_image_resource_node,
- save_pos_node,
- late_lua_node,
- user_defined_node,
- /* dvi backend */
- dvi_literal_node = 15,
- /* pdf backend */
- pdf_literal_node = 16,
- pdf_refobj_node,
- pdf_annot_node,
- pdf_start_link_node,
- pdf_end_link_node,
- pdf_dest_node,
- pdf_action_node,
- pdf_thread_node,
- pdf_start_thread_node,
- pdf_end_thread_node,
- pdf_thread_data_node,
- pdf_link_data_node,
- pdf_colorstack_node,
- pdf_setmatrix_node,
- pdf_save_node,
- pdf_restore_node,
- pdf_link_state_node,
-} whatsit_types;
-
-# define first_common_whatsit 0
-# define last_common_whatsit user_defined_node
-# define backend_first_dvi_whatsit 15
-# define backend_last_dvi_whatsit 15
-# define backend_first_pdf_whatsit 16
-# define backend_last_pdf_whatsit 32
-
-/* add some slack for the future */
-
-# define MAX_WHATSIT_TYPE 34
-
-# define known_whatsit_type(i) ( \
- (i >= first_common_whatsit && i <= last_common_whatsit) || \
- (i >= backend_first_dvi_whatsit && i <= backend_last_dvi_whatsit) || \
- (i >= backend_first_pdf_whatsit && i <= backend_last_pdf_whatsit) \
-)
-
-# define get_node_size(i,j) (i!=whatsit_node ? node_data[i].size : whatsit_node_data[j].size)
-# define get_node_name(i,j) (i!=whatsit_node ? node_data[i].name : whatsit_node_data[j].name)
-# define get_etex_code(i) (node_data[i].etex)
-
-# define GLYPH_CHARACTER (1 << 0)
-# define GLYPH_LIGATURE (1 << 1)
-# define GLYPH_GHOST (1 << 2)
-# define GLYPH_LEFT (1 << 3)
-# define GLYPH_RIGHT (1 << 4)
-
-typedef enum {
- glyph_unset = 0,
- glyph_character = GLYPH_CHARACTER,
- glyph_ligature = GLYPH_LIGATURE,
- glyph_ghost = GLYPH_GHOST,
- glyph_left = GLYPH_LEFT,
- glyph_right = GLYPH_RIGHT,
-} glyph_subtypes;
-
-# define is_character(p) ((subtype(p)) & GLYPH_CHARACTER)
-# define is_ligature(p) ((subtype(p)) & GLYPH_LIGATURE )
-# define is_ghost(p) ((subtype(p)) & GLYPH_GHOST )
-
-# define is_simple_character(p) (is_character(p) && !is_ligature(p) && !is_ghost(p))
-
-# define is_leftboundary(p) (is_ligature(p) && ((subtype(p)) & GLYPH_LEFT ))
-# define is_rightboundary(p) (is_ligature(p) && ((subtype(p)) & GLYPH_RIGHT ))
-# define is_leftghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_LEFT ))
-# define is_rightghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_RIGHT ))
-
-
-# define set_is_glyph(p) subtype(p) = (quarterword) (subtype(p) & ~GLYPH_CHARACTER)
-# define set_is_character(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_CHARACTER)
-# define set_is_ligature(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_LIGATURE)
-# define set_is_ghost(p) subtype(p) = (quarterword) (subtype(p) |GLYPH_GHOST)
-
-# define set_to_glyph(p) subtype(p) = (quarterword)(subtype(p) & 0xFF00)
-# define set_to_character(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_CHARACTER)
-# define set_to_ligature(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_LIGATURE)
-# define set_to_ghost(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_GHOST)
-
-# define set_is_leftboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_LEFT; }
-# define set_is_rightboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_RIGHT; }
-# define set_is_leftghost(p) { set_to_ghost(p); subtype(p) |= GLYPH_LEFT; }
-# define set_is_rightghost(p) { set_to_ghost(p); subtype(p) |= GLYPH_RIGHT; }
-
-typedef enum {
- cancel_boundary = 0,
- user_boundary,
- protrusion_boundary,
- word_boundary,
-} boundary_subtypes ;
-
-# define boundary_node_size 3
-# define boundary_value(a) vinfo((a)+2)
-
-# define special_node_size 3
-
-typedef enum {
- normal_dir = 0,
- cancel_dir,
-} dir_subtypes ;
-
-# define dir_node_size 5
-# define dir_dir(a) vinfo((a)+2)
-# define dir_level(a) vlink((a)+2)
-# define dir_refpos_h(a) vinfo((a)+3)
-# define dir_refpos_v(a) vlink((a)+3)
-# define dir_cur_h(a) vinfo((a)+4)
-# define dir_cur_v(a) vlink((a)+4)
-
-# define write_node_size 3
-# define close_node_size 3
-# define write_tokens(a) vlink(a+2)
-# define write_stream(a) vinfo(a+2)
-
-# define open_node_size 4
-# define open_name(a) vlink((a)+2)
-# define open_area(a) vinfo((a)+3)
-# define open_ext(a) vlink((a)+3)
-
-# define late_lua_node_size 4
-# define late_lua_data(a) vlink((a)+2)
-# define late_lua_reg(a) vinfo((a)+2)
-# define late_lua_name(a) vlink((a)+3)
-# define late_lua_type(a) subtype((a)+3)
-
-# define save_pos_node_size 3
-
-# define local_par_size 6
-
-# define local_pen_inter(a) vinfo((a)+2)
-# define local_pen_broken(a) vlink((a)+2)
-# define local_box_left(a) vlink((a)+3)
-# define local_box_left_width(a) vinfo((a)+3)
-# define local_box_right(a) vlink((a)+4)
-# define local_box_right_width(a) vinfo((a)+4)
-# define local_par_dir(a) vinfo((a)+5)
-
-/* type of literal data */
-
-# define lua_refid_literal 1 /* not a |normal| string */
-# define lua_refid_call 2 /* not a |normal| string */
-
-/* begin of pdf backend nodes */
-
-/* literal ctm types */
-
-typedef enum {
- set_origin = 0,
- direct_page,
- direct_always,
- direct_raw,
- direct_text,
- direct_font,
- scan_special,
-} ctm_transform_modes;
-
-# define pdf_refobj_node_size 3
-
-# define pdf_obj_objnum(a) vinfo((a) + 2)
-
-# define pdf_annot_node_size 8
-# define pdf_dest_node_size 8
-# define pdf_thread_node_size 8
-
-/*
- when a whatsit node representing annotation is created, words |1..3| are
- width, height and depth of this annotation; after shipping out words |1..4|
- are rectangle specification of annotation. For whatsit node representing
- destination |pdf_ann_left| and |pdf_ann_top| are used for some types of destinations
-*/
-
-/*
- coordinates of destinations/threads/annotations (in whatsit node)
-*/
-
-# define pdf_ann_left(a) varmem[(a) + 2].cint
-# define pdf_ann_top(a) varmem[(a) + 3].cint
-# define pdf_ann_right(a) varmem[(a) + 4].cint
-# define pdf_ann_bottom(a) varmem[(a) + 5].cint
-
-# define pdf_literal_data(a) vlink((a)+2)
-# define pdf_literal_mode(a) type((a)+2)
-# define pdf_literal_type(a) subtype((a)+2)
-
-# define pdf_annot_data(a) vinfo((a) + 6)
-# define pdf_link_attr(a) vinfo((a) + 6)
-# define pdf_link_action(a) vlink((a) + 6)
-# define pdf_annot_objnum(a) varmem[(a) + 7].cint
-# define pdf_link_objnum(a) varmem[(a) + 7].cint
-
-# define pdf_dest_type(a) type((a) + 6)
-# define pdf_dest_named_id(a) subtype((a) + 6)
-# define pdf_dest_id(a) vlink((a) + 6)
-# define pdf_dest_xyz_zoom(a) vinfo((a) + 7)
-# define pdf_dest_objnum(a) vlink((a) + 7)
-
-# define pdf_thread_named_id(a) subtype((a) + 6)
-# define pdf_thread_id(a) vlink((a) + 6)
-# define pdf_thread_attr(a) vinfo((a) + 7)
-
-# define pdf_end_link_node_size 3
-# define pdf_end_thread_node_size 3
-
-# define pdf_setmatrix_node_size 3
-# define pdf_save_node_size 3
-# define pdf_restore_node_size 3
-
-# define pdf_link_state_node_size 3
-
-# define pdf_link_state(a) vinfo((a) + 2)
-
-# define pdf_colorstack_node_size 4
-# define pdf_colorstack_stack(a) vlink((a)+2)
-# define pdf_colorstack_cmd(a) vinfo((a)+2)
-# define pdf_colorstack_data(a) vlink((a)+3)
-# define pdf_setmatrix_data(a) vlink((a)+2)
-
-typedef enum {
- pdf_action_page = 0,
- pdf_action_goto,
- pdf_action_thread,
- pdf_action_user
-} pdf_action_type;
-
-typedef enum {
- pdf_window_notset,
- pdf_window_new,
- pdf_window_nonew,
-} pdf_window_type;
-
-# define pdf_action_size 6
-
-# define pdf_action_type(a) vlink((a)+2) /* enum pdf_action_type */
-# define pdf_action_named_id(a) vinfo((a)+2) /* boolean */
-# define pdf_action_id(a) vlink((a)+3) /* number or toks */
-# define pdf_action_file(a) vinfo((a)+3) /* toks */
-# define pdf_action_new_window(a) vlink((a)+4) /* enum pdf_window_type */
-# define pdf_action_tokens(a) vinfo((a)+4) /* toks */
-# define pdf_action_refcount(a) vlink((a)+5) /* number */
-
-typedef enum {
- colorstack_set = 0,
- colorstack_push,
- colorstack_pop,
- colorstack_current
-} colorstack_commands;
-
-# define colorstack_data colorstack_push /* last value where data field is set */
-
-/* end of pdf backend nodes */
-
-/* user defined nodes */
-
-# define user_defined_node_size 4
-# define user_node_type(a) vinfo((a)+2)
-# define user_node_id(a) vlink((a)+2)
-# define user_node_value(a) vinfo((a)+3)
-
-/* node sused in the parbuilder */
-
-# define active_node_size 4 /*number of words in extended active nodes */
-# define fitness subtype /*|very_loose_fit..tight_fit| on final line for this break */
-# define break_node(a) vlink((a)+1) /*pointer to the corresponding passive node */
-# define line_number(a) vinfo((a)+1) /*line that begins at this breakpoint */
-# define total_demerits(a) varmem[(a)+2].cint /* the quantity that \TeX\ minimizes */
-# define active_short(a) vinfo(a+3) /* |shortfall| of this line */
-# define active_glue(a) vlink(a+3) /*corresponding glue stretch or shrink */
-
-# define passive_node_size 7
-# define cur_break(a) vlink((a)+1) /*in passive node, points to position of this breakpoint */
-# define prev_break(a) vinfo((a)+1) /*points to passive node that should precede this one */
-# define passive_pen_inter(a) vinfo((a)+2)
-# define passive_pen_broken(a) vlink((a)+2)
-# define passive_left_box(a) vlink((a)+3)
-# define passive_left_box_width(a) vinfo((a)+3)
-# define passive_last_left_box(a) vlink((a)+4)
-# define passive_last_left_box_width(a) vinfo((a)+4)
-# define passive_right_box(a) vlink((a)+5)
-# define passive_right_box_width(a) vinfo((a)+5)
-# define serial(a) vlink((a)+6) /* serial number for symbolic identification */
-
-# define delta_node_size 10 /* 8 fields, stored in a+1..9 */
-
-/* helpers */
-
-# define couple_nodes(a,b) {assert(b!=null);vlink(a)=b;alink(b)=a;}
-# define try_couple_nodes(a,b) if (b==null) vlink(a)=b; else {couple_nodes(a,b);}
-# define uncouple_node(a) {assert(a!=null);vlink(a)=null;alink(a)=null;}
-
-# define cache_disabled max_halfword
-
-extern void delete_attribute_ref(halfword b);
-extern void reset_node_properties(halfword b);
-extern void reassign_attribute(halfword n,halfword new);
-extern void build_attribute_list(halfword b);
-extern halfword current_attribute_list(void);
-
-extern int unset_attribute(halfword n, int c, int w);
-extern void set_attribute(halfword n, int c, int w);
-extern int has_attribute(halfword n, int c, int w);
-
-extern halfword new_span_node(halfword n, int c, scaled w);
-
-extern void print_short_node_contents(halfword n);
-extern void show_node_list(int i);
-extern pointer actual_box_width(pointer r, scaled base_width);
-
-typedef struct _subtype_info {
- int id;
- const char *name;
- int lua;
-} subtype_info;
-
-typedef struct _field_info {
- const char *name;
- int lua;
-} field_info;
-
-typedef struct _node_info {
- int id;
- int size;
- subtype_info *subtypes;
- field_info *fields;
- const char *name;
- int etex;
- int lua;
-} node_info;
-
-extern node_info node_data[];
-extern node_info whatsit_node_data[];
-
-extern subtype_info node_subtypes_dir[];
-extern subtype_info node_subtypes_glue[];
-extern subtype_info node_subtypes_mathglue[];
-extern subtype_info node_subtypes_leader[];
-extern subtype_info node_subtypes_boundary[];
-extern subtype_info node_subtypes_penalty[];
-extern subtype_info node_subtypes_kern[];
-extern subtype_info node_subtypes_rule[];
-extern subtype_info node_subtypes_glyph[];
-extern subtype_info node_subtypes_disc[];
-extern subtype_info node_subtypes_marginkern[];
-extern subtype_info node_subtypes_list[];
-extern subtype_info node_subtypes_adjust[];
-extern subtype_info node_subtypes_math[];
-extern subtype_info node_subtypes_noad[];
-extern subtype_info node_subtypes_radical[];
-extern subtype_info node_subtypes_accent[];
-extern subtype_info node_subtypes_fence[];
-
-extern subtype_info node_values_pdf_destination[];
-extern subtype_info node_values_pdf_literal[];
-extern subtype_info node_values_pdf_literal[];
-extern subtype_info node_values_pdf_action[];
-extern subtype_info node_values_pdf_window[];
-
-extern subtype_info node_values_fill[];
-extern subtype_info node_values_dir[];
-extern subtype_info node_values_color_stack[];
-
-extern subtype_info other_values_page_states[];
-
-extern halfword new_node(int i, int j);
-extern void flush_node_list(halfword);
-extern void flush_node(halfword);
-extern halfword do_copy_node_list(halfword, halfword);
-extern halfword copy_node_list(halfword);
-extern halfword copy_node(const halfword);
-extern void check_node(halfword);
-extern halfword fix_node_list(halfword);
-extern int fix_node_lists;
-extern char *sprint_node_mem_usage(void);
-extern halfword raw_glyph_node(void);
-extern halfword new_glyph_node(void);
-extern int valid_node(halfword);
-
-extern void flush_node_wrapup_dvi(halfword);
-extern void flush_node_wrapup_pdf(halfword);
-extern void copy_node_wrapup_dvi(halfword, halfword); /* original target */
-extern void copy_node_wrapup_pdf(halfword, halfword); /* original target */
-extern void check_node_wrapup_dvi(halfword); /* DEBUG_NODES mode */
-extern void check_node_wrapup_pdf(halfword); /* DEBUG_NODES mode */
-extern void show_node_wrapup_dvi(halfword);
-extern void show_node_wrapup_pdf(halfword);
-
-typedef enum {
- normal_g = 0, /* normal */
- sfi,
- fil,
- fill,
- filll
-} glue_orders;
-
-# define zero_glue 0
-# define sfi_glue zero_glue+glue_spec_size
-# define fil_glue sfi_glue+glue_spec_size
-# define fill_glue fil_glue+glue_spec_size
-# define ss_glue fill_glue+glue_spec_size
-# define fil_neg_glue ss_glue+glue_spec_size
-# define page_ins_head fil_neg_glue+glue_spec_size
-
-# define contrib_head page_ins_head+temp_node_size
-# define page_head contrib_head+temp_node_size
-# define temp_head page_head+temp_node_size
-# define hold_head temp_head+temp_node_size
-# define adjust_head hold_head+temp_node_size
-# define pre_adjust_head adjust_head+temp_node_size
-# define active pre_adjust_head+temp_node_size
-# define align_head active+active_node_size
-# define end_span align_head+temp_node_size
-# define begin_point end_span+span_node_size
-# define end_point begin_point+glyph_node_size
-# define var_mem_stat_max (end_point+glyph_node_size-1)
-
-# define stretching 1
-# define shrinking 2
-
-# define last_normal_node shape_node
-# define last_whatsit_node pdf_restore_node
-
-# define is_running(A) ((A)==null_flag) /* tests for a running dimension */
-
-extern halfword tail_of_list(halfword p);
-
-extern int var_used;
-
-# define cache_disabled max_halfword
-
-extern int max_used_attr;
-extern halfword attr_list_cache;
-
-extern halfword new_null_box(void);
-extern halfword new_rule(int s);
-extern halfword new_glyph(int f, int c);
-extern quarterword norm_min(int h);
-extern halfword new_char(int f, int c);
-extern scaled glyph_width(halfword p);
-extern scaled glyph_height(halfword p);
-extern scaled glyph_depth(halfword p);
-extern halfword new_disc(void);
-extern halfword new_math(scaled w, int s);
-extern halfword new_spec(halfword p);
-extern halfword new_param_glue(int n);
-extern halfword new_glue(halfword q);
-extern halfword new_skip_param(int n);
-extern halfword new_kern(scaled w);
-extern halfword new_penalty(int m, int s);
-
-extern int lua_properties_enabled ;
-extern int lua_properties_level ;
-extern int lua_properties_use_metatable ;
-
-extern halfword make_local_par_node(int mode);
-
-extern void synctex_set_mode(int mode);
-extern int synctex_get_mode(void);
-extern void synctex_set_tag(int tag);
-extern void synctex_set_line(int line);
-extern void synctex_force_tag(int tag);
-extern void synctex_force_line(int tag);
-extern int synctex_get_tag(void);
-extern void synctex_set_no_files(int flag);
-extern int synctex_get_no_files(void);
-extern int synctex_get_line(void);
-
-extern void l_set_node_data(void) ;
-extern void l_set_whatsit_data(void) ;
-
-#endif
-
diff --git a/Build/source/texk/web2c/luatexdir/tex/textcodes.c b/Build/source/texk/web2c/luatexdir/tex/textcodes.c
deleted file mode 100644
index a6a0b3a55e3..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/textcodes.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
-
-textcodes.w
-
-Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2 of the License, or (at your
-option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-License for more details.
-
-You should have received a copy of the GNU General Public License along
-with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-/*tex
-
-Contrary to traditional \TEX\ we have catcode tables so that we can switch
-catcode regimes very fast. We can have many such regimes and they're stored in
-trees.
-
-*/
-
-#define CATCODESTACK 8
-#define CATCODEDEFAULT 12
-#define CATCODE_MAX 32767
-
-static sa_tree *catcode_heads = NULL;
-static int catcode_max = 0;
-static unsigned char *catcode_valid = NULL;
-
-void set_cat_code(int h, int n, halfword v, quarterword gl)
-{
- sa_tree_item sa_value = { 0 };
- sa_tree s = catcode_heads[h];
- if (h > catcode_max)
- catcode_max = h;
- if (s == NULL) {
- sa_value.int_value = CATCODEDEFAULT;
- s = new_sa_tree(CATCODESTACK, 1, sa_value);
- catcode_heads[h] = s;
- }
- sa_value.int_value = (int) v;
- set_sa_item(s, n, sa_value, gl);
-}
-
-halfword get_cat_code(int h, int n)
-{
- sa_tree_item sa_value = { 0 };
- sa_tree s = catcode_heads[h];
- if (h > catcode_max)
- catcode_max = h;
- if (s == NULL) {
- sa_value.int_value = CATCODEDEFAULT;
- s = new_sa_tree(CATCODESTACK, 1, sa_value);
- catcode_heads[h] = s;
- }
- return (halfword) get_sa_item(s, n).int_value;
-}
-
-void unsave_cat_codes(int h, quarterword gl)
-{
- int k;
- if (h > catcode_max)
- catcode_max = h;
- for (k = 0; k <= catcode_max; k++) {
- if (catcode_heads[k] != NULL)
- restore_sa_stack(catcode_heads[k], gl);
- }
-}
-
-static void initializecatcodes(void)
-{
- sa_tree_item sa_value = { 0 };
- catcode_max = 0;
- catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
- catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1));
- memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1));
- memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1));
- catcode_valid[0] = 1;
- sa_value.int_value = CATCODEDEFAULT;
- catcode_heads[0] = new_sa_tree(CATCODESTACK, 1, sa_value);
-}
-
-static void dumpcatcodes(void)
-{
- int total = 0;
- int k;
- for (k = 0; k <= catcode_max; k++) {
- if (catcode_valid[k]) {
- total++;
- }
- }
- dump_int(catcode_max);
- dump_int(total);
- for (k = 0; k <= catcode_max; k++) {
- if (catcode_valid[k]) {
- dump_int(k);
- dump_sa_tree(catcode_heads[k],"catcodes");
- }
- }
-}
-
-static void undumpcatcodes(void)
-{
- int total, k, x;
- xfree(catcode_heads);
- xfree(catcode_valid);
- catcode_heads = Mxmalloc_array(sa_tree, (CATCODE_MAX + 1));
- catcode_valid = Mxmalloc_array(unsigned char, (CATCODE_MAX + 1));
- memset(catcode_heads, 0, sizeof(sa_tree) * (CATCODE_MAX + 1));
- memset(catcode_valid, 0, sizeof(unsigned char) * (CATCODE_MAX + 1));
- undump_int(catcode_max);
- undump_int(total);
- for (k = 0; k < total; k++) {
- undump_int(x);
- catcode_heads[x] = undump_sa_tree("catcodes");
- catcode_valid[x] = 1;
- }
-}
-
-int valid_catcode_table(int h)
-{
- if (h <= CATCODE_MAX && h >= 0 && catcode_valid[h]) {
- return 1;
- }
- return 0;
-}
-
-void copy_cat_codes(int from, int to)
-{
- if (from < 0 || from > CATCODE_MAX || catcode_valid[from] == 0) {
- uexit(1);
- }
- if (to > catcode_max)
- catcode_max = to;
- destroy_sa_tree(catcode_heads[to]);
- catcode_heads[to] = copy_sa_tree(catcode_heads[from]);
- catcode_valid[to] = 1;
-}
-
-void initex_cat_codes(int h)
-{
- int k;
- if (h > catcode_max)
- catcode_max = h;
- destroy_sa_tree(catcode_heads[h]);
- catcode_heads[h] = NULL;
- set_cat_code(h, '\r', car_ret_cmd, 1);
- set_cat_code(h, ' ', spacer_cmd, 1);
- set_cat_code(h, '\\', escape_cmd, 1);
- set_cat_code(h, '%', comment_cmd, 1);
- set_cat_code(h, 127, invalid_char_cmd, 1);
- set_cat_code(h, 0, ignore_cmd, 1);
- set_cat_code(h, 0xFEFF, ignore_cmd, 1);
- for (k = 'A'; k <= 'Z'; k++) {
- set_cat_code(h, k, letter_cmd, 1);
- set_cat_code(h, k + 'a' - 'A', letter_cmd, 1);
- }
- catcode_valid[h] = 1;
-}
-
-static void freecatcodes(void)
-{
- int k;
- for (k = 0; k <= catcode_max; k++) {
- if (catcode_valid[k]) {
- destroy_sa_tree(catcode_heads[k]);
- }
- }
- xfree(catcode_heads);
- xfree(catcode_valid);
-}
-
-/*tex
-
-The lowercase mapping codes are also stored in a tree.
-
-*/
-
-#define LCCODESTACK 8
-#define LCCODEDEFAULT 0
-
-static sa_tree lccode_head = NULL;
-
-void set_lc_code(int n, halfword v, quarterword gl)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = (int) v;
- set_sa_item(lccode_head, n, sa_value, gl);
-}
-
-halfword get_lc_code(int n)
-{
- return (halfword) get_sa_item(lccode_head, n).int_value;
-}
-
-static void unsavelccodes(quarterword gl)
-{
- restore_sa_stack(lccode_head, gl);
-}
-
-static void initializelccodes(void)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = LCCODEDEFAULT;
- lccode_head = new_sa_tree(LCCODESTACK, 1, sa_value);
-}
-
-static void dumplccodes(void)
-{
- dump_sa_tree(lccode_head,"lccodes");
-}
-
-static void undumplccodes(void)
-{
- lccode_head = undump_sa_tree("lccodes");
-}
-
-static void freelccodes(void)
-{
- destroy_sa_tree(lccode_head);
-}
-
-/*tex
-
-And the uppercase mapping codes are again stored in a tree.
-
-*/
-
-#define UCCODESTACK 8
-#define UCCODEDEFAULT 0
-
-static sa_tree uccode_head = NULL;
-
-void set_uc_code(int n, halfword v, quarterword gl)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = (int) v;
- set_sa_item(uccode_head, n, sa_value, gl);
-}
-
-halfword get_uc_code(int n)
-{
- return (halfword) get_sa_item(uccode_head, n).int_value;
-}
-
-static void unsaveuccodes(quarterword gl)
-{
- restore_sa_stack(uccode_head, gl);
-}
-
-static void initializeuccodes(void)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = UCCODEDEFAULT;
- uccode_head = new_sa_tree(UCCODESTACK, 1, sa_value);
-}
-
-static void dumpuccodes(void)
-{
- dump_sa_tree(uccode_head,"uccodes");
-}
-
-static void undumpuccodes(void)
-{
- uccode_head = undump_sa_tree("uccodes");
-}
-
-static void freeuccodes(void)
-{
- destroy_sa_tree(uccode_head);
-}
-
-/*tex
-
-By now it will be no surprise that the space factors get stored in a tree.
-
-*/
-
-#define SFCODESTACK 8
-#define SFCODEDEFAULT 1000
-
-static sa_tree sfcode_head = NULL;
-
-void set_sf_code(int n, halfword v, quarterword gl)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = (int) v;
- set_sa_item(sfcode_head, n, sa_value, gl);
-}
-
-halfword get_sf_code(int n)
-{
- return (halfword) get_sa_item(sfcode_head, n).int_value;
-}
-
-static void unsavesfcodes(quarterword gl)
-{
- restore_sa_stack(sfcode_head, gl);
-}
-
-static void initializesfcodes(void)
-{
- sa_tree_item sa_value = { 0 };
- sa_value.int_value = SFCODEDEFAULT;
- sfcode_head = new_sa_tree(SFCODESTACK, 1, sa_value);
-}
-
-static void dumpsfcodes(void)
-{
- dump_sa_tree(sfcode_head,"sfcodes");
-}
-
-static void undumpsfcodes(void)
-{
- sfcode_head = undump_sa_tree("sfcodes");
-}
-
-static void freesfcodes(void)
-{
- destroy_sa_tree(sfcode_head);
-}
-
-/*tex
-
-The hyphenation codes are indeed stored in a tree and are used instead of
-lowercase codes when deciding what characters to take into acccount when
-hyphenating. They are bound to upto |HJCODE_MAX| languages.
-
-*/
-
-#define HJCODESTACK 8
-#define HJCODEDEFAULT 0
-#define HJCODE_MAX 16383
-
-static sa_tree *hjcode_heads = NULL;
-static int hjcode_max = 0;
-static unsigned char *hjcode_valid = NULL;
-
-/*tex
-
-Here we set codes but we don't initialize from lccodes.
-
-*/
-
-void set_hj_code(int h, int n, halfword v, quarterword gl)
-{
- sa_tree_item sa_value = { 0 };
- sa_tree s = hjcode_heads[h];
- if (h > hjcode_max)
- hjcode_max = h;
- if (s == NULL) {
- sa_value.int_value = HJCODEDEFAULT;
- s = new_sa_tree(HJCODESTACK, 1, sa_value);
- hjcode_heads[h] = s;
- }
- sa_value.int_value = (int) v;
- set_sa_item(s, n, sa_value, gl);
-}
-
-/*tex
-
-We just return the lccodes when nothing is set.
-
-*/
-
-halfword get_hj_code(int h, int n)
-{
- sa_tree s = hjcode_heads[h];
- if (s == NULL) {
- s = lccode_head;
- }
- return (halfword) get_sa_item(s, n).int_value;
-}
-
-/*tex
-
-We don't restore as we can have more languages in a paragraph and hyphenation
-takes place at a later stage so we would get weird grouping side effects .. so,
-one can overload settings but management is then upto the used, so no:
-
-*/
-
-/*
- static void unsavehjcodes(quarterword gl) { }
-*/
-
-static void initializehjcodes(void)
-{
- /*
- sa_tree_item sa_value = { 0 };
- */
- hjcode_max = 0;
- hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1));
- hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1));
- memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1));
- memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1));
- /*
- hjcode_valid[0] = 1;
- sa_value.int_value = HJCODEDEFAULT;
- hjcode_heads[0] = new_sa_tree(HJCODESTACK, 1, sa_value);
- */
-}
-
-void hj_codes_from_lc_codes(int h)
-{
- sa_tree_item sa_value = { 0 };
- sa_tree s = hjcode_heads[h];
- if (s != NULL) {
- destroy_sa_tree(s);
- } else if (h > hjcode_max) {
- hjcode_max = h;
- }
- if (s == NULL) {
- sa_value.int_value = HJCODEDEFAULT;
- s = new_sa_tree(HJCODESTACK, 1, sa_value);
- hjcode_heads[h] = s;
- }
- hjcode_heads[h] = copy_sa_tree(lccode_head);
- hjcode_valid[h] = 1;
-}
-
-static void dumphjcodes(void)
-{
- int total = 0;
- int k;
- for (k = 0; k <= hjcode_max; k++) {
- if (hjcode_valid[k]) {
- total++;
- }
- }
- dump_int(hjcode_max);
- dump_int(total);
- for (k = 0; k <= hjcode_max; k++) {
- if (hjcode_valid[k]) {
- dump_int(k);
- dump_sa_tree(hjcode_heads[k],"hjcodes");
- }
- }
-}
-
-static void undumphjcodes(void)
-{
- int total, k, x;
- xfree(hjcode_heads);
- xfree(hjcode_valid);
- hjcode_heads = Mxmalloc_array(sa_tree, (HJCODE_MAX + 1));
- hjcode_valid = Mxmalloc_array(unsigned char, (HJCODE_MAX + 1));
- memset(hjcode_heads, 0, sizeof(sa_tree) * (HJCODE_MAX + 1));
- memset(hjcode_valid, 0, sizeof(unsigned char) * (HJCODE_MAX + 1));
- undump_int(hjcode_max);
- undump_int(total);
- for (k = 0; k < total; k++) {
- undump_int(x);
- hjcode_heads[x] = undump_sa_tree("hjcodes");
- hjcode_valid[x] = 1;
- }
-}
-
-static void freehjcodes(void)
-{
- int k;
- for (k = 0; k <= hjcode_max; k++) {
- if (hjcode_valid[k]) {
- destroy_sa_tree(hjcode_heads[k]);
- }
- }
- xfree(hjcode_heads);
- xfree(hjcode_valid);
-}
-
-/*tex
-
-The public management functions.
-
-*/
-
-void unsave_text_codes(quarterword grouplevel)
-{
- unsavelccodes(grouplevel);
- unsaveuccodes(grouplevel);
- unsavesfcodes(grouplevel);
-}
-
-void initialize_text_codes(void)
-{
- initializecatcodes();
- initializelccodes();
- initializeuccodes();
- initializesfcodes();
- initializehjcodes();
-}
-
-void free_text_codes(void)
-{
- freecatcodes();
- freelccodes();
- freeuccodes();
- freesfcodes();
- freehjcodes();
-}
-
-void dump_text_codes(void)
-{
- dumpcatcodes();
- dumplccodes();
- dumpuccodes();
- dumpsfcodes();
- dumphjcodes();
-}
-
-void undump_text_codes(void)
-{
- undumpcatcodes();
- undumplccodes();
- undumpuccodes();
- undumpsfcodes();
- undumphjcodes();
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/textcodes.h b/Build/source/texk/web2c/luatexdir/tex/textcodes.h
deleted file mode 100644
index 759d9ee740e..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/textcodes.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* textcodes.h
-
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef TEXTCODES_H
-# define TEXTCODES_H
-
-void set_cat_code(int h, int n, halfword v, quarterword gl);
-halfword get_cat_code(int h, int n);
-int valid_catcode_table(int h);
-void unsave_cat_codes(int h, quarterword gl);
-void copy_cat_codes(int from, int to);
-void initex_cat_codes(int h);
-
-void set_lc_code(int n, halfword v, quarterword gl);
-halfword get_lc_code(int n);
-
-void set_uc_code(int n, halfword v, quarterword gl);
-halfword get_uc_code(int n);
-
-void set_sf_code(int n, halfword v, quarterword gl);
-halfword get_sf_code(int n);
-
-void set_hj_code(int l, int n, halfword v, quarterword gl);
-halfword get_hj_code(int l, int n);
-void hj_codes_from_lc_codes(int h);
-
-void initialize_text_codes(void);
-void unsave_text_codes(quarterword grouplevel);
-
-void dump_text_codes(void);
-void undump_text_codes(void);
-
-void free_math_codes(void);
-void free_text_codes(void);
-
-#endif
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.c b/Build/source/texk/web2c/luatexdir/tex/textoken.c
deleted file mode 100644
index e28626bbd26..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/textoken.c
+++ /dev/null
@@ -1,3920 +0,0 @@
-/*
-
-Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
-
-This file is part of LuaTeX.
-
-LuaTeX is free software; you can redistribute it and/or modify it under the terms
-of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "ptexlib.h"
-
-#define detokenized_line() (line_catcode_table==NO_CAT_TABLE)
-
-#define do_get_cat_code(a,b) do { \
- if (line_catcode_table==DEFAULT_CAT_TABLE) \
- a=get_cat_code(cat_code_table_par,b); \
- else if (line_catcode_table>-0xFF) \
- a=get_cat_code(line_catcode_table,b); \
- else \
- a= - line_catcode_table - 0xFF ; \
- } while (0)
-
-
-/*tex
-
- The \TeX\ system does nearly all of its own memory allocation, so that it can
- readily be transported into environments that do not have automatic
- facilities for strings, garbage collection, etc., and so that it can be in
- control of what error messages the user receives. The dynamic storage
- requirements of \TeX\ are handled by providing two large arrays called
- |fixmem| and |varmem| in which consecutive blocks of words are used as nodes
- by the \TeX\ routines.
-
- Pointer variables are indices into this array, or into another array called
- |eqtb| that will be explained later. A pointer variable might also be a
- special flag that lies outside the bounds of |mem|, so we allow pointers to
- assume any |halfword| value. The minimum halfword value represents a null
- pointer. \TeX\ does not assume that |mem[null]| exists.
-
- Locations in |fixmem| are used for storing one-word records; a conventional
- \.{AVAIL} stack is used for allocation in this array.
-
-*/
-
-/*tex the big dynamic storage area */
-
-smemory_word *fixmem;
-
-/*tex the smallest location of one-word memory in use */
-
-unsigned fix_mem_min;
-
-/*tex the largest location of one-word memory in use */
-
-unsigned fix_mem_max;
-
-/*tex
-
- In order to study the memory requirements of particular applications, it is
- possible to prepare a version of \TeX\ that keeps track of current and
- maximum memory usage. When code between the delimiters |stat| $\ldots$
- |tats| is not commented out, \TeX\ will run a bit slower but it will report
- these statistics when |tracing_stats| is sufficiently large.
-
-*/
-
-/*tex how much memory is in use */
-
-int dyn_used;
-
-/*tex head of the list of available one-word nodes */
-
-halfword avail;
-
-/*tex the last one-word node used in |mem| */
-
-unsigned fix_mem_end;
-
-/*tex head of a junk list, write only */
-
-halfword garbage;
-
-/*tex head of a temporary list of some kind */
-
-halfword temp_token_head;
-
-/*tex head of a temporary list of another kind */
-
-halfword hold_token_head;
-
-/*tex a constant token list */
-
-halfword omit_template;
-
-/*tex permanently empty list */
-
-halfword null_list;
-
-/*tex head of token list built by |scan_keyword| */
-
-halfword backup_head;
-
-void initialize_tokens(void)
-{
- halfword p;
- avail = null;
- fix_mem_end = 0;
- p = get_avail();
- temp_token_head = p;
- set_token_info(temp_token_head, 0);
- p = get_avail();
- hold_token_head = p;
- set_token_info(hold_token_head, 0);
- p = get_avail();
- omit_template = p;
- set_token_info(omit_template, 0);
- p = get_avail();
- null_list = p;
- set_token_info(null_list, 0);
- p = get_avail();
- backup_head = p;
- set_token_info(backup_head, 0);
- p = get_avail();
- garbage = p;
- set_token_info(garbage, 0);
- dyn_used = 0;
-}
-
-/*tex
-
- The function |get_avail| returns a pointer to a new one-word node whose
- |link| field is null. However, \TeX\ will halt if there is no more room left.
-
- If the available-space list is empty, i.e., if |avail=null|, we try first to
- increase |fix_mem_end|. If that cannot be done, i.e., if
- |fix_mem_end=fix_mem_max|, we try to reallocate array |fixmem|. If, that
- doesn't work, we have to quit.
-
- Single-word node allocation:
-*/
-
-halfword get_avail(void)
-{
- /*tex The new node being got: */
- unsigned p;
- unsigned t;
- /*tex Get top location in the |avail| stack. */
- p = (unsigned) avail;
- if (p != null) {
- /*tex Pop it off. */
- avail = token_link(avail);
- } else if (fix_mem_end < fix_mem_max) {
- /*tex Go into virgin territory. */
- incr(fix_mem_end);
- p = fix_mem_end;
- } else {
- /*tex The big dynamic storage area. */
- smemory_word *new_fixmem;
- t = (fix_mem_max / 5);
- new_fixmem = fixmemcast(realloc(fixmem, sizeof(smemory_word) * (fix_mem_max + t + 1)));
- if (new_fixmem == NULL) {
- /*tex If memory is exhausted, display possible runaway text. */
- runaway();
- overflow("token memory size", fix_mem_max);
- } else {
- fixmem = new_fixmem;
- }
- memset(voidcast(fixmem + fix_mem_max + 1), 0, t * sizeof(smemory_word));
- fix_mem_max += t;
- p = ++fix_mem_end;
- }
- /*tex Provide an oft-desired initialization of the new node. */
- token_link(p) = null;
- /*tex Maintain statistics. */
- incr(dyn_used);
- return (halfword) p;
-}
-
-/*tex
-
- The procedure |flush_list(p)| frees an entire linked list of one-word nodes
- that starts at position |p|.
-
- This makes list of single-word nodes available:
-
-*/
-
-void flush_list(halfword p)
-{
- halfword q, r;
- if (p != null) {
- r = p;
- do {
- q = r;
- r = token_link(r);
- decr(dyn_used);
- } while (r != null);
- /*tex Now |q| is the last node on the list. */
- token_link(q) = avail;
- avail = p;
- }
-}
-
-/*tex
-
- A \TeX\ token is either a character or a control sequence, and it is
- represented internally in one of two ways: (1)~A character whose ASCII code
- number is |c| and whose command code is |m| is represented as the number
- $2^{21}m+c$; the command code is in the range |1<=m<=14|. (2)~A control
- sequence whose |eqtb| address is |p| is represented as the number
- |cs_token_flag+p|. Here |cs_token_flag=t=| $2^{25}-1$ is larger than
- $2^{21}m+c$, yet it is small enough that |cs_token_flag+p< max_halfword|;
- thus, a token fits comfortably in a halfword.
-
- A token |t| represents a |left_brace| command if and only if
- |t<left_brace_limit|; it represents a |right_brace| command if and only if we
- have |left_brace_limit<=t<right_brace_limit|; and it represents a |match| or
- |end_match| command if and only if |match_token<=t<=end_match_token|. The
- following definitions take care of these token-oriented constants and a few
- others.
-
- A token list is a singly linked list of one-word nodes in |mem|, where each
- word contains a token and a link. Macro definitions, output-routine
- definitions, marks, \.{\\write} texts, and a few other things are remembered
- by \TeX\ in the form of token lists, usually preceded by a node with a
- reference count in its |token_ref_count| field. The token stored in location
- |p| is called |info(p)|.
-
- Three special commands appear in the token lists of macro definitions. When
- |m=match|, it means that \TeX\ should scan a parameter for the current macro;
- when |m=end_match|, it means that parameter matching should end and \TeX\
- should start reading the macro text; and when |m=out_param|, it means that
- \TeX\ should insert parameter number |c| into the text at this point.
-
- The enclosing \.{\char'173} and \.{\char'175} characters of a macro
- definition are omitted, but the final right brace of an output routine is
- included at the end of its token list.
-
- Here is an example macro definition that illustrates these conventions. After
- \TeX\ processes the text
-
- \starttyping
- \def\mac a#1#2 \b {#1\-a ##1#2 \#2\}
- \stoptyping
-
- the definition of \.{\\mac} is represented as a token list containing
-
- \starttyping
- (reference count) |letter|a |match|# |match|# |spacer| \b |end_match|
- |out_param|1 \- |letter|a |spacer|, |mac_param|# |other_char|1
- |out_param|2 |spacer| |out_param|2
- \stoptyping
-
- The procedure |scan_toks| builds such token lists, and |macro_call| does the
- parameter matching.
-
- Examples such as \type{\def\m{\def\m{a} b}} explain why reference
- counts would be needed even if \TeX\ had no \.{\\let} operation: When the
- token list for \.{\\m} is being read, the redefinition of \.{\\m} changes the
- |eqtb| entry before the token list has been fully consumed, so we dare not
- simply destroy a token list when its control sequence is being redefined.
-
- If the parameter-matching part of a definition ends with `\.{\#\{}', the
- corresponding token list will have `\.\{' just before the `|end_match|' and
- also at the very end. The first `\.\{' is used to delimit the parameter; the
- second one keeps the first from disappearing.
-
- The |print_meaning| subroutine displays |cur_cmd| and |cur_chr| in symbolic
- form, including the expansion of a macro or mark.
-
-*/
-
-void print_meaning(void)
-{
- /*tex
-
- This would make sense but some macro packages don't like it:
-
- \starttyping
- if (cur_cmd == math_given_cmd) {
- cur_cmd = xmath_given_cmd ;
- }
- \stoptyping
-
- */
- print_cmd_chr((quarterword) cur_cmd, cur_chr);
- if (cur_cmd >= call_cmd) {
- print_char(':');
- print_ln();
- token_show(cur_chr);
- } else {
- /*tex Show the meaning of a mark node. */
- if ((cur_cmd == top_bot_mark_cmd) && (cur_chr < marks_code)) {
- print_char(':');
- print_ln();
- switch (cur_chr) {
- case first_mark_code:
- token_show(first_mark(0));
- break;
- case bot_mark_code:
- token_show(bot_mark(0));
- break;
- case split_first_mark_code:
- token_show(split_first_mark(0));
- break;
- case split_bot_mark_code:
- token_show(split_bot_mark(0));
- break;
- default:
- token_show(top_mark(0));
- break;
- }
- }
- }
-}
-
-/*tex
-
- The procedure |show_token_list|, which prints a symbolic form of the token
- list that starts at a given node |p|, illustrates these conventions. The
- token list being displayed should not begin with a reference count. However,
- the procedure is intended to be robust, so that if the memory links are awry
- or if |p| is not really a pointer to a token list, nothing catastrophic will
- happen.
-
- An additional parameter |q| is also given; this parameter is either null or
- it points to a node in the token list where a certain magic computation takes
- place that will be explained later. (Basically, |q| is non-null when we are
- printing the two-line context information at the time of an error message;
- |q| marks the place corresponding to where the second line should begin.)
-
- For example, if |p| points to the node containing the first \.a in the token
- list above, then |show_token_list| will print the string $$\hbox{`\.{a\#1\#2\
- \\b\ ->\#1\\-a\ \#\#1\#2\ \#2}';}$$ and if |q| points to the node containing
- the second \.a, the magic computation will be performed just before the
- second \.a is printed.
-
- The generation will stop, and `\.{\\ETC.}' will be printed, if the length of
- printing exceeds a given limit~|l|. Anomalous entries are printed in the form
- of control sequences that are not followed by a blank space, e.g.,
- `\.{\\BAD.}'; this cannot be confused with actual control sequences because a
- real control sequence named \.{BAD} would come out `\.{\\BAD\ }'.
-
-*/
-
-#define not_so_bad(p) \
- switch (m) { \
- case assign_int_cmd: \
- if (c >= (backend_int_base) && c <= (backend_int_last)) \
- p("[internal backend integer]"); \
- break; \
- case assign_dimen_cmd: \
- if (c >= (backend_dimen_base) && c <= (backend_dimen_last)) \
- p("[internal backend dimension]"); \
- break; \
- case assign_toks_cmd: \
- if (c >= (backend_toks_base) && c <= (backend_toks_last)) \
- p("[internal backend tokenlist]"); \
- break; \
- case node_cmd: \
- p("[internal node pointer]"); \
- break; \
- case lua_call_cmd: \
- p("[internal lua function call]"); \
- break; \
- case lua_expandable_call_cmd: \
- p("[internal expandable lua function call]"); \
- break; \
- case lua_local_call_cmd: \
- p("[internal local lua function call]"); \
- break; \
- default: \
- p("BAD"); \
- break; \
- }
-
-void show_token_list(int p, int q, int l)
-{
- /*tex pieces of a token */
- int m, c;
- /*tex character used in a `|match|' */
- ASCII_code match_chr = '#';
- /*tex the highest parameter number, as an ASCII digit */
- ASCII_code n = '0';
- tally = 0;
- if (l < 0)
- l = 0x3FFFFFFF;
- while ((p != null) && (tally < l)) {
- if (p == q) {
- /*tex Do magic computation. */
- set_trick_count();
- }
- /*tex Display token |p|, and |return| if there are problems. */
- if ((p < (int) fix_mem_min) || (p > (int) fix_mem_end)) {
- tprint_esc("CLOBBERED.");
- return;
- }
- if (token_info(p) >= cs_token_flag) {
- if (!((inhibit_par_tokens) && (token_info(p) == par_token)))
- print_cs(token_info(p) - cs_token_flag);
- } else {
- m = token_cmd(token_info(p));
- c = token_chr(token_info(p));
- if (token_info(p) < 0) {
- tprint_esc("BAD");
- } else {
- /*
- Display the token \type {(|m|,|c|)}. The procedure usually
- ``learns'' the character code used for macro parameters by
- seeing one in a |match| command before it runs into any
- |out_param| commands.
-
- */
- switch (m) {
- case left_brace_cmd:
- case right_brace_cmd:
- case math_shift_cmd:
- case tab_mark_cmd:
- case sup_mark_cmd:
- case sub_mark_cmd:
- case spacer_cmd:
- case letter_cmd:
- case other_char_cmd:
- print(c);
- break;
- case mac_param_cmd:
- if (!in_lua_escape && (is_in_csname==0))
- print(c);
- print(c);
- break;
- case out_param_cmd:
- print(match_chr);
- if (c <= 9) {
- print_char(c + '0');
- } else {
- print_char('!');
- return;
- }
- break;
- case match_cmd:
- match_chr = c;
- print(c);
- incr(n);
- print_char(n);
- if (n > '9')
- return;
- break;
- case end_match_cmd:
- if (c == 0)
- tprint("->");
- break;
- default:
- not_so_bad(tprint);
- break;
- }
- }
- }
- p = token_link(p);
- }
- if (p != null)
- tprint_esc("ETC.");
-}
-
-#define do_buffer_to_unichar(a,b) do { \
- a = (halfword)str2uni(buffer+b); \
- b += utf8_size(a); \
-} while (0)
-
-/*tex
-
- Here's the way we sometimes want to display a token list, given a pointer to
- its reference count; the pointer may be null.
-
-*/
-
-void token_show(halfword p)
-{
- if (p != null)
- show_token_list(token_link(p), null, 10000000);
-}
-
-/*tex
-
- |delete_token_ref|, is called when a pointer to a token list's reference
- count is being removed. This means that the token list should disappear if
- the reference count was |null|, otherwise the count should be decreased by
- one.
-
- |p| points to the reference count of a token list that is losing one
- reference.
-
-*/
-
-void delete_token_ref(halfword p)
-{
- if (token_ref_count(p) == 0)
- flush_list(p);
- else
- decr(token_ref_count(p));
-}
-
-int get_char_cat_code(int curchr)
-{
- int a;
- do_get_cat_code(a,curchr);
- return a;
-}
-
-static void invalid_character_error(void)
-{
- const char *hlp[] = {
- "A funny symbol that I can't read has just been input.",
- "Continue, and I'll forget that it ever happened.",
- NULL
- };
- deletions_allowed = false;
- tex_error("Text line contains an invalid character", hlp);
- deletions_allowed = true;
-}
-
-static boolean process_sup_mark(void);
-
-static int scan_control_sequence(void);
-
-typedef enum {
- next_line_ok,
- next_line_return,
- next_line_restart
-} next_line_retval;
-
-static next_line_retval next_line(void);
-
-/*tex
-
- In case you are getting bored, here is a slightly less trivial routine: Given
- a string of lowercase letters, like `\.{pt}' or `\.{plus}' or `\.{width}',
- the |scan_keyword| routine checks to see whether the next tokens of input
- match this string. The match must be exact, except that uppercase letters
- will match their lowercase counterparts; uppercase equivalents are determined
- by subtracting |"a"-"A"|, rather than using the |uc_code| table, since \TeX\
- uses this routine only for its own limited set of keywords.
-
- If a match is found, the characters are effectively removed from the input
- and |true| is returned. Otherwise |false| is returned, and the input is left
- essentially unchanged (except for the fact that some macros may have been
- expanded, etc.).
-
-*/
-
-boolean scan_keyword(const char *s)
-{
- /*tex tail of the backup list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex index into |str_pool| */
- const char *k;
- halfword save_cur_cs = cur_cs;
- if (strlen(s) == 0) {
- /*tex but not with newtokenlib zero keyword simply doesn't match */
- return false ;
- }
- p = backup_head;
- token_link(p) = null;
- k = s;
- while (*k) {
- /*tex Recursion is possible here! */
- get_x_token();
- if ((cur_cs == 0) && ((cur_chr == *k) || (cur_chr == *k - 'a' + 'A'))) {
- store_new_token(cur_tok);
- k++;
- } else if ((cur_cmd != spacer_cmd) || (p != backup_head)) {
- back_input();
- if (p != backup_head) {
- begin_token_list(token_link(backup_head), backed_up);
- }
- cur_cs = save_cur_cs;
- return false;
- }
- }
- if (token_link(backup_head) != null)
- flush_list(token_link(backup_head));
- cur_cs = save_cur_cs;
- return true;
-}
-
-boolean scan_keyword_case_sensitive(const char *s)
-{
- halfword p;
- halfword q;
- const char *k;
- halfword save_cur_cs = cur_cs;
- if (strlen(s) == 0)
- return false ;
- p = backup_head;
- token_link(p) = null;
- k = s;
- while (*k) {
- get_x_token();
- if ((cur_cs == 0) && (cur_chr == *k)) {
- store_new_token(cur_tok);
- k++;
- } else if ((cur_cmd != spacer_cmd) || (p != backup_head)) {
- back_input();
- if (p != backup_head) {
- begin_token_list(token_link(backup_head), backed_up);
- }
- cur_cs = save_cur_cs;
- return false;
- }
- }
- if (token_link(backup_head) != null)
- flush_list(token_link(backup_head));
- cur_cs = save_cur_cs;
- return true;
-}
-
-/*tex
-
- We can not return |undefined_control_sequence| under some conditions (inside
- |shift_case|, for example). This needs thinking.
-
-*/
-
-/*static char * FFFF = "\xEF\xBF\xBF";*/ /* 0xFFFF */
-
-halfword active_to_cs(int curchr, int force)
-{
- halfword curcs;
- int nncs = no_new_control_sequence;
- if (force) {
- no_new_control_sequence = false;
- }
- if (curchr > 0) {
- char *b = (char *) uni2str((unsigned) curchr);
- char *utfbytes = xmalloc(8);
- utfbytes = strcpy(utfbytes, "\xEF\xBF\xBF");
- utfbytes = strcat(utfbytes, b);
- free(b);
- curcs = string_lookup(utfbytes, utf8_size(curchr)+3);
- free(utfbytes);
- } else {
- /*tex 0xFFFF ... why not 3 ? */
- curcs = string_lookup("\xEF\xBF\xBF", 4);
- }
- no_new_control_sequence = nncs;
- return curcs;
-}
-
-/*
-
- static unsigned char *uni2csstr(unsigned unic)
- {
- unsigned char *buf = xmalloc(8);
- unsigned char *pt = buf;
- *pt++ = 239; *pt++ = 191; *pt++ = 191; // 0xFFFF
- if (unic < 0x80)
- *pt++ = (unsigned char) unic;
- else if (unic < 0x800) {
- *pt++ = (unsigned char) (0xc0 | (unic >> 6));
- *pt++ = (unsigned char) (0x80 | (unic & 0x3f));
- } else if (unic >= 0x110000) {
- *pt++ = (unsigned char) (unic - 0x110000);
- } else if (unic < 0x10000) {
- *pt++ = (unsigned char) (0xe0 | (unic >> 12));
- *pt++ = (unsigned char) (0x80 | ((unic >> 6) & 0x3f));
- *pt++ = (unsigned char) (0x80 | (unic & 0x3f));
- } else {
- int u, z, y, x;
- unsigned val = unic - 0x10000;
- u = (int) (((val & 0xf0000) >> 16) + 1);
- z = (int) ((val & 0x0f000) >> 12);
- y = (int) ((val & 0x00fc0) >> 6);
- x = (int) (val & 0x0003f);
- *pt++ = (unsigned char) (0xf0 | (u >> 2));
- *pt++ = (unsigned char) (0x80 | ((u & 3) << 4) | z);
- *pt++ = (unsigned char) (0x80 | y);
- *pt++ = (unsigned char) (0x80 | x);
- }
- *pt = '\0';
- return buf;
- }
-
- halfword active_to_cs(int curchr, int force)
- {
- halfword curcs;
- int nncs = no_new_control_sequence;
- if (force) {
- no_new_control_sequence = false;
- }
- if (curchr > 0) {
- char * utfbytes = (char *) uni2csstr((unsigned) curchr);
- curcs = string_lookup(utfbytes, utf8_size(curchr)+3);
- free(utfbytes);
- } else {
- curcs = string_lookup(FFFF, 4); // 0xFFFF ... why not 3 ?
- }
- no_new_control_sequence = nncs;
- return curcs;
- }
-
-*/
-
-/*tex
-
- Maybe this function should listen to \.{\\escapechar} but we can do without.
-
-*/
-
-static char *cs_to_string(halfword p)
-{
- const char *s;
- char *sh;
- int k = 0;
- static char ret[256] = { 0 };
- if (p == 0 || p == null_cs) {
- ret[k++] = '\\';
- s = "csname";
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k++] = '\\';
- s = "endcsname";
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
-
- } else {
- str_number txt = cs_text(p);
- sh = makecstring(txt);
- s = sh;
- if (is_active_cs(txt)) {
- s = s + 3;
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
- } else {
- ret[k++] = '\\';
- while (*s) {
- ret[k++] = *s++;
- }
- ret[k] = 0;
- }
- free(sh);
- }
- return (char *) ret;
-}
-
-/*tex This is sort of a hack. */
-
-static char *cmd_chr_to_string(int cmd, int chr)
-{
- char *s;
- str_number str;
- int sel = selector;
- selector = new_string;
- print_cmd_chr((quarterword) cmd, chr);
- str = make_string();
- s = makecstring(str);
- selector = sel;
- flush_str(str);
- return s;
-}
-
-/*tex
-
- The heart of \TeX's input mechanism is the |get_next| procedure, which we
- shall develop in the next few sections of the program. Perhaps we shouldn't
- actually call it the ``heart,'' however, because it really acts as \TeX's
- eyes and mouth, reading the source files and gobbling them up. And it also
- helps \TeX\ to regurgitate stored token lists that are to be processed again.
-
- The main duty of |get_next| is to input one token and to set |cur_cmd| and
- |cur_chr| to that token's command code and modifier. Furthermore, if the
- input token is a control sequence, the |eqtb| location of that control
- sequence is stored in |cur_cs|; otherwise |cur_cs| is set to zero.
-
- Underlying this simple description is a certain amount of complexity because
- of all the cases that need to be handled. However, the inner loop of
- |get_next| is reasonably short and fast.
-
- When |get_next| is asked to get the next token of a \.{\\read} line, it sets
- |cur_cmd=cur_chr=cur_cs=0| in the case that no more tokens appear on that
- line. (There might not be any tokens at all, if the |end_line_char| has
- |ignore| as its catcode.)
-
- The value of |par_loc| is the |eqtb| address of `\.{\\par}'. This quantity is
- needed because a blank line of input is supposed to be exactly equivalent to
- the appearance of \.{\\par}; we must set |cur_cs:=par_loc| when detecting a
- blank line.
-
-*/
-
-/*tex
-
- The location of `\.{\\par}' in |eqtb| adn the token representing `\.{\\par}.
-
-*/
-
-halfword par_loc;
-halfword par_token;
-
-/*tex
-
- Parts |get_next| are executed more often than any other instructions of \TeX.
-
- The global variable |force_eof| is normally |false|; it is set |true| by an
- \.{\\endinput} command. |luacstrings| is the number of lua print statements
- waiting to be input, it is changed by |luatokencall|.
-
-
-*/
-
-/*tex Should the next \.{\\input} be aborted early? */
-boolean force_eof;
-
-/*tex How many lua strings are waiting to be input? */
-
-int luacstrings;
-
-/*tex
-
- If the user has set the |pausing| parameter to some positive value, and if
- nonstop mode has not been selected, each line of input is displayed on the
- terminal and the transcript file, followed by `\.{=>}'. \TeX\ waits for a
- response. If the response is simply |carriage_return|, the line is accepted
- as it stands, otherwise the line typed is used instead of the line in the
- file.
-
-*/
-
-void firm_up_the_line(void)
-{
- int k;
- ilimit = last;
- if (pausing_par > 0) {
- if (interaction > nonstop_mode) {
- wake_up_terminal();
- print_ln();
- if (istart < ilimit) {
- for (k = istart; k <= ilimit - 1; k++)
- print_char(buffer[k]);
- }
- first = ilimit;
- prompt_input("=>");
- if (last > first) {
- /*tex Move line down in buffer. */
- for (k = first; k < +last - 1; k++)
- buffer[k + istart - first] = buffer[k];
- ilimit = istart + last - first;
- }
- }
- }
-}
-
-/*tex
-
- Before getting into |get_next|, let's consider the subroutine that is called
- when an `\.{\\outer}' control sequence has been scanned or when the end of a
- file has been reached. These two cases are distinguished by |cur_cs|, which
- is zero at the end of a file.
-
-*/
-
-void check_outer_validity(void)
-{
- /*tex points to inserted token list */
- halfword p;
- /*tex auxiliary pointer */
- halfword q;
- if (suppress_outer_error_par)
- return;
- if (scanner_status != normal) {
- deletions_allowed = false;
- /*tex
-
- Back up an outer control sequence so that it can be reread. An
- outer control sequence that occurs in a \.{\\read} will not be
- reread, since the error recovery for \.{\\read} is not very powerful.
-
- */
- if (cur_cs != 0) {
- if ((istate == token_list) || (iname < 1) || (iname > 17)) {
- p = get_avail();
- token_info(p) = cs_token_flag + cur_cs;
- /*tex prepare to read the control sequence again */
- begin_token_list(p, backed_up);
- }
- /*tex replace it by a space */
- cur_cmd = spacer_cmd;
- cur_chr = ' ';
- }
- if (scanner_status > skipping) {
- const char *errhlp[] = {
- "I suspect you have forgotten a `}', causing me",
- "to read past where you wanted me to stop.",
- "I'll try to recover; but if the error is serious,",
- "you'd better type `E' or `X' now and fix your file.",
- NULL
- };
- char errmsg[318];
- const char *startmsg;
- const char *scannermsg;
- /*tex
-
- Tell the user what has run away and try to recover Print a
- definition, argument, or preamble.
-
- */
- runaway();
- if (cur_cs == 0) {
- startmsg = "File ended";
- } else {
- cur_cs = 0;
- startmsg = "Forbidden control sequence found";
- }
- /*tex
-
- Print either `\.{definition}' or `\.{use}' or `\.{preamble}' or
- `\.{text}', and insert tokens that should lead to recovery. The
- recovery procedure can't be fully understood without knowing more
- about the \TeX\ routines that should be aborted, but we can
- sketch the ideas here: For a runaway definition we will insert a
- right brace; for a runaway preamble, we will insert a special
- \.{\\cr} token and a right brace; and for a runaway argument, we
- will set |long_state| to |outer_call| and insert \.{\\par}.
-
- */
- p = get_avail();
- switch (scanner_status) {
- case defining:
- scannermsg = "definition";
- token_info(p) = right_brace_token + '}';
- break;
- case matching:
- scannermsg = "use";
- token_info(p) = par_token;
- long_state = outer_call_cmd;
- break;
- case aligning:
- scannermsg = "preamble";
- token_info(p) = right_brace_token + '}';
- q = p;
- p = get_avail();
- token_link(p) = q;
- token_info(p) = cs_token_flag + frozen_cr;
- align_state = -1000000;
- break;
- case absorbing:
- scannermsg = "text";
- token_info(p) = right_brace_token + '}';
- break;
- default:
- scannermsg = "unknown";
- break;
- }
- begin_token_list(p, inserted);
- snprintf(errmsg, 318, "%s while scanning %s of %s", startmsg, scannermsg, cs_to_string(warning_index));
- tex_error(errmsg, errhlp);
- } else {
- char errmsg[256];
- const char *errhlp_no[] = {
- "The file ended while I was skipping conditional text.",
- "This kind of error happens when you say `\\if...' and forget",
- "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
- NULL
- };
- const char *errhlp_cs[] = {
- "A forbidden control sequence occurred in skipped text.",
- "This kind of error happens when you say `\\if...' and forget",
- "the matching `\\fi'. I've inserted a `\\fi'; this might work.",
- NULL
- };
- const char **errhlp = (const char **) errhlp_no;
- char *ss;
- if (cur_cs != 0) {
- errhlp = errhlp_cs;
- cur_cs = 0;
- }
- ss = cmd_chr_to_string(if_test_cmd, cur_if);
- snprintf(errmsg, 255, "Incomplete %s; all text was ignored after line %d",
- ss, (int) skip_line);
- free(ss);
- /*tex Incomplete |\if...| */
- cur_tok = cs_token_flag + frozen_fi;
- /*tex back up one inserted token and call |error|. */
- {
- OK_to_interrupt = false;
- back_input();
- token_type = inserted;
- OK_to_interrupt = true;
- tex_error(errmsg, errhlp);
- }
- }
- deletions_allowed = true;
- }
-}
-
-#if 0
-
-/*tex
-
- The other variant gives less clutter in tracing cache usage when profiling
- and for some files (like the manual) also a bit of a speedup.
-
-*/
-
-static boolean get_next_file(void)
-{
- SWITCH:
- if (iloc <= ilimit) {
- /*tex current line not yet finished */
- do_buffer_to_unichar(cur_chr, iloc);
- RESWITCH:
- if (detokenized_line()) {
- cur_cmd = (cur_chr == ' ' ? 10 : 12);
- } else {
- do_get_cat_code(cur_cmd, cur_chr);
- }
- /*tex
-
- Change state if necessary, and |goto switch| if the current
- character should be ignored, or |goto reswitch| if the current
- character changes to another;
-
- The following 48-way switch accomplishes the scanning quickly,
- assuming that a decent C compiler has translated the code. Note that
- the numeric values for |mid_line|, |skip_blanks|, and |new_line| are
- spaced apart from each other by |max_char_code+1|, so we can add a
- character's command code to the state to get a single number that
- characterizes both.
-
- Remark [ls/hh]: checking performance indicated that this switch was
- the cause of many branch prediction errors but changing it to:
-
- \starttyping
- c = istate + cur_cmd;
- if (c == (mid_line + letter_cmd) || c == (mid_line + other_char_cmd)) {
- return true;
- } else if (c >= new_line) {
- switch (c) {
- }
- } else if (c >= skip_blanks) {
- switch (c) {
- }
- } else if (c >= mid_line) {
- switch (c) {
- }
- } else {
- istate = mid_line;
- return true;
- }
- \stoptyping
-
- gives as many prediction errors. So, we can indeed assume that the
- compiler does the right job, or that there is simply no other way.
-
- */
-
- switch (istate + cur_cmd) {
- case mid_line + ignore_cmd:
- case skip_blanks + ignore_cmd:
- case new_line + ignore_cmd:
- case skip_blanks + spacer_cmd:
- case new_line + spacer_cmd:
- /*tex Cases where character is ignored. */
- goto SWITCH;
- break;
- case mid_line + escape_cmd:
- case new_line + escape_cmd:
- case skip_blanks + escape_cmd:
- /*tex Scan a control sequence. */
- istate = (unsigned char) scan_control_sequence();
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case mid_line + active_char_cmd:
- case new_line + active_char_cmd:
- case skip_blanks + active_char_cmd:
- /*tex Process an active-character. */
- cur_cs = active_to_cs(cur_chr, false);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- istate = mid_line;
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case mid_line + sup_mark_cmd:
- case new_line + sup_mark_cmd:
- case skip_blanks + sup_mark_cmd:
- /*tex If this |sup_mark| starts. */
- if (process_sup_mark())
- goto RESWITCH;
- else
- istate = mid_line;
- break;
- case mid_line + invalid_char_cmd:
- case new_line + invalid_char_cmd:
- case skip_blanks + invalid_char_cmd:
- /*tex Decry the invalid character and |goto restart|. */
- invalid_character_error();
- /*tex Because state may be |token_list| now: */
- return false;
- break;
- case mid_line + spacer_cmd:
- /*tex Enter |skip_blanks| state, emit a space. */
- istate = skip_blanks;
- cur_chr = ' ';
- break;
- case mid_line + car_ret_cmd:
- /*tex
-
- Finish line, emit a space. When a character of type |spacer|
- gets through, its character code is changed to $\.{"\
- "}=040$. This means that the ASCII codes for tab and space,
- and for the space inserted at the end of a line, will be
- treated alike when macro parameters are being matched. We do
- this since such characters are indistinguishable on most
- computer terminal displays.
-
- */
- iloc = ilimit + 1;
- cur_cmd = spacer_cmd;
- cur_chr = ' ';
- break;
- case skip_blanks + car_ret_cmd:
- case mid_line + comment_cmd:
- case new_line + comment_cmd:
- case skip_blanks + comment_cmd:
- /*tex Finish line, |goto switch|; */
- iloc = ilimit + 1;
- goto SWITCH;
- break;
- case new_line + car_ret_cmd:
- /*tex Finish line, emit a \.{\\par}; */
- iloc = ilimit + 1;
- cur_cs = par_loc;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- break;
- case skip_blanks + left_brace_cmd:
- case new_line + left_brace_cmd:
- istate = mid_line;
- /*tex Fall through. */
- case mid_line + left_brace_cmd:
- align_state++;
- break;
- case skip_blanks + right_brace_cmd:
- case new_line + right_brace_cmd:
- istate = mid_line;
- /*tex Fall through. */
- case mid_line + right_brace_cmd:
- align_state--;
- break;
- case mid_line + math_shift_cmd:
- case mid_line + tab_mark_cmd:
- case mid_line + mac_param_cmd:
- case mid_line + sub_mark_cmd:
- case mid_line + letter_cmd:
- case mid_line + other_char_cmd:
- break;
- /*
- case skip_blanks + math_shift:
- case skip_blanks + tab_mark:
- case skip_blanks + mac_param:
- case skip_blanks + sub_mark:
- case skip_blanks + letter:
- case skip_blanks + other_char:
- case new_line + math_shift:
- case new_line + tab_mark:
- case new_line + mac_param:
- case new_line + sub_mark:
- case new_line + letter:
- case new_line + other_char:
- */
- default:
- istate = mid_line;
- break;
- }
- } else {
- if (iname != 21)
- istate = new_line;
- /*tex
-
- Move to next line of file, or |goto restart| if there is no next line,
- or |return| if a \.{\\read} line has finished;
-
- */
- do {
- next_line_retval r = next_line();
- if (r == next_line_return) {
- return true;
- } else if (r == next_line_restart) {
- return false;
- }
- } while (0);
- check_interrupt();
- goto SWITCH;
- }
- return true;
-}
-
-#else
-
-/*tex
-
- This variant gives 10 times less Bim in vallgrind!
-
-*/
-
-static boolean get_next_file(void)
-{
- int c = 0;
- SWITCH:
- if (iloc <= ilimit) {
- /*tex current line not yet finished */
- do_buffer_to_unichar(cur_chr, iloc);
- RESWITCH:
- if (detokenized_line()) {
- cur_cmd = (cur_chr == ' ' ? 10 : 12);
- } else {
- do_get_cat_code(cur_cmd, cur_chr);
- }
- /*tex
-
- Change state if necessary, and |goto switch| if the current character
- should be ignored, or |goto reswitch| if the current character changes
- to another.
-
- */
- c = istate + cur_cmd;
- if (c == (mid_line + letter_cmd) || c == (mid_line + other_char_cmd)) {
- return true;
- } else if (c >= new_line) {
- switch (c-new_line) {
- case escape_cmd:
- istate = (unsigned char) scan_control_sequence();
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case left_brace_cmd:
- istate = mid_line;
- align_state++;
- return true;
- case right_brace_cmd:
- istate = mid_line;
- align_state--;
- return true;
- case math_shift_cmd:
- istate = mid_line;
- return true;
- case tab_mark_cmd:
- istate = mid_line;
- return true;
- case car_ret_cmd:
- /*tex Finish line, emit a \.{\\par}. */
- iloc = ilimit + 1;
- cur_cs = par_loc;
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case mac_param_cmd:
- istate = mid_line;
- return true;
- case sup_mark_cmd:
- if (process_sup_mark())
- goto RESWITCH;
- else
- istate = mid_line;
- return true;
- case sub_mark_cmd:
- istate = mid_line;
- return true;
- case ignore_cmd:
- goto SWITCH;
- return true;
- case spacer_cmd:
- /*tex Cases where character is ignored. */
- goto SWITCH;
- case letter_cmd:
- istate = mid_line;
- return true;
- case other_char_cmd:
- istate = mid_line;
- return true;
- case active_char_cmd:
- cur_cs = active_to_cs(cur_chr, false);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- istate = mid_line;
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case comment_cmd:
- iloc = ilimit + 1;
- goto SWITCH;
- case invalid_char_cmd:
- /*tex Because state may be |token_list| now. */
- invalid_character_error();
- return false;
- default:
- istate = mid_line;
- return true;
- }
- } else if (c >= skip_blanks) {
- switch (c-skip_blanks) {
- case escape_cmd:
- /*tex Scan a control sequence. */
- istate = (unsigned char) scan_control_sequence();
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case left_brace_cmd:
- istate = mid_line;
- align_state++;
- return true;
- case right_brace_cmd:
- istate = mid_line;
- align_state--;
- return true;
- case math_shift_cmd:
- istate = mid_line;
- return true;
- case tab_mark_cmd:
- istate = mid_line;
- return true;
- case car_ret_cmd:
- iloc = ilimit + 1;
- goto SWITCH;
- case mac_param_cmd:
- istate = mid_line;
- return true;
- case sup_mark_cmd:
- if (process_sup_mark())
- goto RESWITCH;
- else
- istate = mid_line;
- return true;
- case sub_mark_cmd:
- istate = mid_line;
- return true;
- case ignore_cmd:
- goto SWITCH;
- case spacer_cmd:
- goto SWITCH;
- case letter_cmd:
- istate = mid_line;
- return true;
- case other_char_cmd:
- istate = mid_line;
- return true;
- case active_char_cmd:
- cur_cs = active_to_cs(cur_chr, false);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- istate = mid_line;
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case comment_cmd:
- /*tex Finish line, |goto switch|. */
- iloc = ilimit + 1;
- goto SWITCH;
- case invalid_char_cmd:
- /*tex Decry the invalid character and |goto restart|. */
- invalid_character_error();
- /*tex Because state may be |token_list| now. */
- return false;
- default:
- istate = mid_line;
- return true;
- }
- } else if (c >= mid_line) {
- switch (c-mid_line) {
- case escape_cmd:
- istate = (unsigned char) scan_control_sequence();
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case left_brace_cmd:
- align_state++;
- return true;
- case right_brace_cmd:
- align_state--;
- return true;
- case math_shift_cmd:
- return true;
- case tab_mark_cmd:
- return true;
- case car_ret_cmd:
- /*tex
-
- Finish line, emit a space. When a character of type
- |spacer| gets through, its character code is changed to
- $\.{"\ "}=040$. This means that the ASCII codes for tab
- and space, and for the space inserted at the end of a
- line, will be treated alike when macro parameters are
- being matched. We do this since such characters are
- indistinguishable on most computer terminal displays.
-
- */
- iloc = ilimit + 1;
- cur_cmd = spacer_cmd;
- cur_chr = ' ';
- return true;
- case mac_param_cmd:
- return true;
- case sup_mark_cmd:
- if (process_sup_mark())
- goto RESWITCH;
- else
- istate = mid_line;
- return true;
- case sub_mark_cmd:
- return true;
- case ignore_cmd:
- goto SWITCH;
- case spacer_cmd:
- /*tex Enter |skip_blanks| state, emit a space. */
- istate = skip_blanks;
- cur_chr = ' ';
- return true;
- case letter_cmd:
- istate = mid_line;
- return true;
- case other_char_cmd:
- istate = mid_line;
- return true;
- case active_char_cmd:
- cur_cs = active_to_cs(cur_chr, false);
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- istate = mid_line;
- if (! suppress_outer_error_par && cur_cmd >= outer_call_cmd)
- check_outer_validity();
- return true;
- case comment_cmd:
- iloc = ilimit + 1;
- goto SWITCH;
- case invalid_char_cmd:
- /*tex Because state may be |token_list| now. */
- invalid_character_error();
- return false;
- default:
- istate = mid_line;
- return true;
- }
- } else {
- istate = mid_line;
- return true;
- }
- } else {
- if (iname != 21) {
- istate = new_line;
- }
- /*tex
-
- Move to next line of file, or |goto restart| if there is no next
- line, or |return| if a \.{\\read} line has finished;
-
- */
- do {
- next_line_retval r = next_line();
- if (r == next_line_return) {
- return true;
- } else if (r == next_line_restart) {
- return false;
- }
- } while (0);
- check_interrupt();
- goto SWITCH;
- }
- return true;
-}
-
-#endif
-
-/*tex
-
- Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit.
- We only support a limited set:
-
- \starttyping
- ^^^^^^XXXXXX
- ^^^^XXXXXX
- ^^XX ^^<char>
- \stoptyping
-
-*/
-
-#define is_hex(a) ((a>='0'&&a<='9')||(a>='a'&&a<='f'))
-
-#define add_nybble(c) \
- if (c<='9') { \
- cur_chr=(cur_chr<<4)+c-'0'; \
- } else { \
- cur_chr=(cur_chr<<4)+c-'a'+10; \
- }
-
-#define set_nybble(c) \
- if (c<='9') { \
- cur_chr=c-'0'; \
- } else { \
- cur_chr=c-'a'+10; \
- }
-
-#define one_hex_to_cur_chr(c1) \
- set_nybble(c1);
-
-#define two_hex_to_cur_chr(c1,c2) \
- set_nybble(c1); \
- add_nybble(c2);
-
-#define four_hex_to_cur_chr(c1,c2,c3,c4) \
- two_hex_to_cur_chr(c1,c2); \
- add_nybble(c3); \
- add_nybble(c4);
-
-#define six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6) \
- four_hex_to_cur_chr(c1,c2,c3,c4); \
- add_nybble(c5); \
- add_nybble(c6);
-
-static boolean process_sup_mark(void)
-{
- if (cur_chr == buffer[iloc]) {
- if (iloc < ilimit) {
- if ((cur_chr == buffer[iloc + 1]) && (cur_chr == buffer[iloc + 2])) {
- if ((cur_chr == buffer[iloc + 3]) && (cur_chr == buffer[iloc + 4])) {
- /*tex |^^^^^^XXXXXX| */
- if ((iloc + 10) <= ilimit) {
- int c1 = buffer[iloc + 5];
- int c2 = buffer[iloc + 6];
- int c3 = buffer[iloc + 7];
- int c4 = buffer[iloc + 8];
- int c5 = buffer[iloc + 9];
- int c6 = buffer[iloc + 10];
- if (is_hex(c1) && is_hex(c2) && is_hex(c3) &&
- is_hex(c4) && is_hex(c5) && is_hex(c6)) {
- iloc = iloc + 11;
- six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6);
- return true;
- } else {
- tex_error("^^^^^^ needs six hex digits", NULL);
- }
- } else {
- tex_error("^^^^^^ needs six hex digits, end of input", NULL);
- }
- } else {
- /*tex |^^^^XXXX| */
- if ((iloc + 6) <= ilimit) {
- int c1 = buffer[iloc + 3];
- int c2 = buffer[iloc + 4];
- int c3 = buffer[iloc + 5];
- int c4 = buffer[iloc + 6];
- if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) {
- iloc = iloc + 7;
- four_hex_to_cur_chr(c1,c2,c3,c4);
- return true;
- } else {
- tex_error("^^^^ needs four hex digits", NULL);
- }
- } else {
- tex_error("^^^^ needs four hex digits, end of input", NULL);
- }
- }
- } else {
- /*tex |^^XX| */
- if ((iloc + 2) <= ilimit) {
- int c1 = buffer[iloc + 1];
- int c2 = buffer[iloc + 2];
- if (is_hex(c1) && is_hex(c2)) {
- iloc = iloc + 3;
- two_hex_to_cur_chr(c1,c2);
- return true;
- }
- }
- /*tex Go on, no error, good old \TEX . */
- }
- }
- /*tex The rest. */
- {
- int c1 = buffer[iloc + 1];
- if (c1 < 0200) {
- iloc = iloc + 2;
- if (is_hex(c1) && (iloc <= ilimit)) {
- int c2 = buffer[iloc];
- if (is_hex(c2)) {
- incr(iloc);
- two_hex_to_cur_chr(c1,c2);
- return true;
- }
- }
- cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100);
- return true;
- }
- }
- }
- return false;
-}
-
-/*tex
-
- Control sequence names are scanned only when they appear in some line of a
- file; once they have been scanned the first time, their |eqtb| location
- serves as a unique identification, so \TeX\ doesn't need to refer to the
- original name any more except when it prints the equivalent in symbolic form.
-
- The program that scans a control sequence has been written carefully in order
- to avoid the blowups that might otherwise occur if a malicious user tried
- something like `\.{\\catcode\'15=0}'. The algorithm might look at
- |buffer[ilimit+1]|, but it never looks at |buffer[ilimit+2]|.
-
- If expanded characters like `\.{\^\^A}' or `\.{\^\^df}' appear in or just
- following a control sequence name, they are converted to single characters in
- the buffer and the process is repeated, slowly but surely.
-
-*/
-
-static boolean check_expanded_code(int *kk); /* below */
-
-static int scan_control_sequence(void)
-{
- int retval = mid_line;
- if (iloc > ilimit) {
- /*tex |state| is irrelevant in this case. */
- cur_cs = null_cs;
- } else {
- /*tex |cat_code(cur_chr)|, usually: */
- register int cat;
- while (1) {
- int k = iloc;
- do_buffer_to_unichar(cur_chr, k);
- do_get_cat_code(cat, cur_chr);
- if (cat != letter_cmd || k > ilimit) {
- retval = (cat == spacer_cmd ? skip_blanks : mid_line);
- /*tex If an expanded \unknown */
- if (cat == sup_mark_cmd && check_expanded_code(&k))
- continue;
- } else {
- retval = skip_blanks;
- do {
- do_buffer_to_unichar(cur_chr, k);
- do_get_cat_code(cat, cur_chr);
- } while (cat == letter_cmd && k <= ilimit);
- /*tex If an expanded \unknown */
- if (cat == sup_mark_cmd && check_expanded_code(&k))
- continue;
- if (cat != letter_cmd) {
- /*tex Backtrack one character which can be \UTF. */
- if (cur_chr <= 0x7F) {
- k -= 1; /* in most cases */
- } else if (cur_chr > 0xFFFF) {
- k -= 4;
- } else if (cur_chr > 0x7FF) {
- k -= 3;
- } else /* if (cur_chr > 0x7F) */ {
- k -= 2;
- }
- /*tex Now |k| points to first nonletter. */
- }
- }
- cur_cs = id_lookup(iloc, k - iloc);
- iloc = k;
- break;
- }
- }
- cur_cmd = eq_type(cur_cs);
- cur_chr = equiv(cur_cs);
- return retval;
-}
-
-/*tex
-
- Whenever we reach the following piece of code, we will have
- |cur_chr=buffer[k-1]| and |k<=ilimit+1| and
- |cat=get_cat_code(cat_code_table,cur_chr)|. If an expanded code like
- \.{\^\^A} or \.{\^\^df} appears in |buffer[(k-1)..(k+1)]| or
- |buffer[(k-1)..(k+2)]|, we will store the corresponding code in |buffer[k-1]|
- and shift the rest of the buffer left two or three places.
-
-*/
-
-static boolean check_expanded_code(int *kk)
-{
- int l;
- int k = *kk;
- int d = 1;
- if (buffer[k] == cur_chr && k < ilimit) {
- if ((cur_chr == buffer[k + 1]) && (cur_chr == buffer[k + 2])) {
- if ((cur_chr == buffer[k + 3]) && (cur_chr == buffer[k + 4])) {
- if ((k + 10) <= ilimit) {
- int c1 = buffer[k + 6 - 1];
- int c2 = buffer[k + 6];
- int c3 = buffer[k + 6 + 1];
- int c4 = buffer[k + 6 + 2];
- int c5 = buffer[k + 6 + 3];
- int c6 = buffer[k + 6 + 4];
- if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4) && is_hex(c5) && is_hex(c6)) {
- d = 6;
- six_hex_to_cur_chr(c1,c2,c3,c4,c5,c6);
- } else {
- tex_error("^^^^^^ needs six hex digits", NULL);
- }
- } else {
- tex_error("^^^^^^ needs six hex digits, end of input", NULL);
- }
- } else {
- if ((k + 6) <= ilimit) {
- int c1 = buffer[k + 4 - 1];
- int c2 = buffer[k + 4];
- int c3 = buffer[k + 4 + 1];
- int c4 = buffer[k + 4 + 2];
- if (is_hex(c1) && is_hex(c2) && is_hex(c3) && is_hex(c4)) {
- d = 4;
- four_hex_to_cur_chr(c1,c2,c3,c4);
- } else {
- tex_error("^^^^ needs four hex digits", NULL);
- }
- } else {
- tex_error("^^^^ needs four hex digits, end of input", NULL);
- }
- }
- } else {
- int c1 = buffer[k + 1];
- if (c1 < 0200) {
- d = 1;
- if (is_hex(c1) && (k + 2) <= ilimit) {
- int c2 = buffer[k + 2];
- if (is_hex(c2)) {
- d = 2;
- two_hex_to_cur_chr(c1,c2);
- } else {
- cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100);
- }
- } else {
- cur_chr = (c1 < 0100 ? c1 + 0100 : c1 - 0100);
- }
- }
- }
- if (d > 2)
- d = 2 * d - 1;
- else
- d++;
- if (cur_chr <= 0x7F) {
- buffer[k - 1] = (packed_ASCII_code) cur_chr;
- } else if (cur_chr <= 0x7FF) {
- buffer[k - 1] = (packed_ASCII_code) (0xC0 + cur_chr / 0x40);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + cur_chr % 0x40);
- } else if (cur_chr <= 0xFFFF) {
- buffer[k - 1] = (packed_ASCII_code) (0xE0 + cur_chr / 0x1000);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) / 0x40);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x1000) % 0x40);
- } else {
- buffer[k - 1] = (packed_ASCII_code) (0xF0 + cur_chr / 0x40000);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + (cur_chr % 0x40000) / 0x1000);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + ((cur_chr % 0x40000) % 0x1000) / 0x40);
- k++;
- d--;
- buffer[k - 1] = (packed_ASCII_code) (0x80 + ((cur_chr % 0x40000) % 0x1000) % 0x40);
- }
- l = k;
- ilimit = ilimit - d;
- while (l <= ilimit) {
- buffer[l] = buffer[l + d];
- l++;
- }
- *kk = k;
- return true;
- }
- return false;
-}
-
-/*tex
-
- All of the easy branches of |get_next| have now been taken care of. There is
- one more branch.
-
-*/
-
-static next_line_retval next_line(void)
-{
- /*tex A way to end a pseudo file without trailing space: */
- boolean inhibit_eol = false;
- if (iname > 17) {
- /*tex
-
- Read next line of file into |buffer|, or |goto restart| if the file
- has ended.
-
- */
- incr(line);
- first = istart;
- if (!force_eof) {
- if (iname <= 20) {
- if (pseudo_input()) {
- /*tex Not end of file; set |ilimit|. */
- firm_up_the_line();
- line_catcode_table = DEFAULT_CAT_TABLE;
- if ((iname == 19) && (pseudo_lines(pseudo_files) == null))
- inhibit_eol = true;
- } else if ((every_eof_par != null) && !eof_seen[iindex]) {
- ilimit = first - 1;
- /*tex Fake one empty line. */
- eof_seen[iindex] = true;
- if (iname != 19)
- begin_token_list(every_eof_par, every_eof_text);
- return next_line_restart;
- } else {
- force_eof = true;
- }
- } else {
- if (iname == 21) {
- halfword n = null;
- int t = luacstring_input(&n);
- switch (t) {
- case 0:
- force_eof = true;
- break;
- case 1:
- /*tex string */
- firm_up_the_line();
- line_catcode_table = (short) luacstring_cattable();
- line_partial = (signed char) luacstring_partial();
- if (luacstring_final_line() || line_partial || line_catcode_table == NO_CAT_TABLE)
- inhibit_eol = true;
- if (!line_partial)
- istate = new_line;
- break;
- case 2:
- /*tex token */
- cur_tok = n;
- back_input();
- /*tex Needs checking. */
- return next_line_restart;
- break;
- case 3:
- /*tex node */
- if (n < biggest_char) {
- /*tex |0x10FFFF == 1114111| */
- cur_tok = token_val(node_cmd, n);
- back_input();
- /*tex Needs checking. */
- return next_line_restart;
- } else {
- normal_warning("nodes","unable to store reference from lua in tex");
- force_eof = true;
- }
- break;
- default:
- force_eof = true;
- break;
- }
- } else if (lua_input_ln(cur_file, 0, true)) {
- /*tex Not end of file, set |ilimit|. */
- firm_up_the_line();
- line_catcode_table = DEFAULT_CAT_TABLE;
- } else if ((every_eof_par != null) && (!eof_seen[iindex])) {
- ilimit = first - 1;
- /* tex Fake one empty line. */
- eof_seen[iindex] = true;
- begin_token_list(every_eof_par, every_eof_text);
- return next_line_restart;
- } else {
- force_eof = true;
- }
- }
- }
- if (force_eof) {
- if (tracing_nesting_par > 0)
- if ((grp_stack[in_open] != cur_boundary) || (if_stack[in_open] != cond_ptr))
- if (!((iname == 19) || (iname == 21))) {
- /*tex Give warning for some unfinished groups and/or conditionals. */
- file_warning();
- }
- if ((iname > 21) || (iname == 20)) {
- report_stop_file(filetype_tex);
- decr(open_parens);
- }
- force_eof = false;
- /*tex \LUA\ input or \.{\\scantextokens} */
- if (iname == 21 || iname == 19) {
- end_file_reading();
- } else {
- end_file_reading();
- if (! suppress_outer_error_par)
- check_outer_validity();
- }
- return next_line_restart;
- }
- if (inhibit_eol || end_line_char_inactive)
- ilimit--;
- else
- buffer[ilimit] = (packed_ASCII_code) end_line_char_par;
- first = ilimit + 1;
- iloc = istart;
- /*tex We're ready to read. */
- } else {
- if (!terminal_input) {
- /*tex \.{\\read} line has ended */
- cur_cmd = 0;
- cur_chr = 0;
- return next_line_return;
- }
- if (input_ptr > 0) {
- /*tex Text was inserted during error recovery. */
- end_file_reading();
- /*tex Resume previous level. */
- return next_line_restart;
- }
- if (selector < log_only)
- open_log_file();
- if (interaction > nonstop_mode) {
- if (end_line_char_inactive)
- ilimit++;
- if (ilimit == istart) {
- /*tex Previous line was empty. */
- tprint_nl("(Please type a command or say `\\end')");
- }
- print_ln();
- first = istart;
- /*tex Input on-line into |buffer| */
- prompt_input("*");
- ilimit = last;
- if (end_line_char_inactive)
- ilimit--;
- else
- buffer[ilimit] = (packed_ASCII_code) end_line_char_par;
- first = ilimit + 1;
- iloc = istart;
- } else {
- /*tex
-
- Nonstop mode, which is intended for overnight batch processing,
- never waits for on-line input.
-
- */
- fatal_error("*** (job aborted, no legal \\end found)");
- }
- }
- return next_line_ok;
-}
-
-/*tex
-
- Let's consider now what happens when |get_next| is looking at a token list.
-
-*/
-
-static boolean get_next_tokenlist(void)
-{
- register halfword t = token_info(iloc);
- /*tex Move to next. */
- iloc = token_link(iloc);
- if (t >= cs_token_flag) {
- /*tex A control sequence token */
- cur_cs = t - cs_token_flag;
- cur_cmd = eq_type(cur_cs);
- if (cur_cmd >= outer_call_cmd) {
- if (cur_cmd == dont_expand_cmd) {
- /*tex
-
- Get the next token, suppressing expansion. The present point
- in the program is reached only when the |expand| routine has
- inserted a special marker into the input. In this special
- case, |token_info(iloc)| is known to be a control sequence
- token, and |token_link(iloc)=null|.
-
- */
- cur_cs = token_info(iloc) - cs_token_flag;
- iloc = null;
- cur_cmd = eq_type(cur_cs);
- if (cur_cmd > max_command_cmd) {
- cur_cmd = relax_cmd;
- cur_chr = no_expand_flag;
- return true;
- }
- } else if (! suppress_outer_error_par) {
- check_outer_validity();
- }
- }
- cur_chr = equiv(cur_cs);
- } else {
- cur_cmd = token_cmd(t);
- cur_chr = token_chr(t);
- switch (cur_cmd) {
- case left_brace_cmd:
- align_state++;
- break;
- case right_brace_cmd:
- align_state--;
- break;
- case out_param_cmd:
- /*tex Insert macro parameter and |goto restart|. */
- begin_token_list(param_stack[param_start + cur_chr - 1], parameter);
- return false;
- break;
- }
- }
- return true;
-}
-
-/*tex
-
- Now we're ready to take the plunge into |get_next| itself. Parts of this
- routine are executed more often than any other instructions of \TeX.
-
- This sets |cur_cmd|, |cur_chr|, |cur_cs| to next token:
-
-*/
-
-void get_next(void)
-{
- RESTART:
- cur_cs = 0;
- if (istate != token_list) {
- /*tex Input from external file, |goto restart| if no input found. */
- if (!get_next_file())
- goto RESTART;
- } else {
- if (iloc == null) {
- end_token_list();
- /*tex List exhausted, resume previous level. */
- goto RESTART;
- } else if (!get_next_tokenlist()) {
- /*tex Parameter needs to be expanded. */
- goto RESTART;
- }
- }
- /*tex If an alignment entry has just ended, take appropriate action. */
- if ((cur_cmd == tab_mark_cmd || cur_cmd == car_ret_cmd) && align_state == 0) {
- insert_vj_template();
- goto RESTART;
- }
-}
-
-/*tex
-
- Since |get_next| is used so frequently in \TeX, it is convenient to define
- three related procedures that do a little more:
-
- \startitemize
- \startitem
- |get_token| not only sets |cur_cmd| and |cur_chr|, it also sets
- |cur_tok|, a packed halfword version of the current token.
- \stopitem
- \startitem
- |get_x_token|, meaning ``get an expanded token,'' is like
- |get_token|, but if the current token turns out to be a user-defined
- control sequence (i.e., a macro call), or a conditional, or something
- like \.{\\topmark} or \.{\\expandafter} or \.{\\csname}, it is
- eliminated from the input by beginning the expansion of the macro or
- the evaluation of the conditional.
- \stopitem
- \startitem
- |x_token| is like |get_x_token| except that it assumes that
- |get_next| has already been called.
- \stopitem
- \stopitemize
-
- In fact, these three procedures account for almost every use of |get_next|.
- No new control sequences will be defined except during a call of |get_token|,
- or when \.{\\csname} compresses a token list, because
- |no_new_control_sequence| is always |true| at other times.
-
- This sets |cur_cmd|, |cur_chr|, |cur_tok|:
-
-*/
-
-void get_token(void)
-{
- no_new_control_sequence = false;
- get_next();
- no_new_control_sequence = true;
- if (cur_cs == 0)
- cur_tok = token_val(cur_cmd, cur_chr);
- else
- cur_tok = cs_token_flag + cur_cs;
-}
-
-/*tex This changes the string |s| to a token list. */
-
-halfword string_to_toks(const char *ss)
-{
- /*tex tail of the token list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex token being appended */
- halfword t;
- const char *s = ss;
- const char *se = ss + strlen(s);
- p = temp_token_head;
- set_token_link(p, null);
- while (s < se) {
- t = (halfword) str2uni((const unsigned char *) s);
- s += utf8_size(t);
- if (t == ' ')
- t = space_token;
- else
- t = other_token + t;
- fast_store_new_token(t);
- }
- return token_link(temp_token_head);
-}
-
-/*tex
-
- The token lists for macros and for other things like \.{\\mark} and
- \.{\\output} and \.{\\write} are produced by a procedure called |scan_toks|.
-
- Before we get into the details of |scan_toks|, let's consider a much simpler
- task, that of converting the current string into a token list. The |str_toks|
- function does this; it classifies spaces as type |spacer| and everything else
- as type |other_char|.
-
- The token list created by |str_toks| begins at |link(temp_token_head)| and
- ends at the value |p| that is returned. (If |p=temp_token_head|, the list is
- empty.)
-
- |lua_str_toks| is almost identical, but it also escapes the three symbols
- that |lua| considers special while scanning a literal string.
-
- This changes the string |str_pool[b..pool_ptr]| to a token list:
-
-*/
-
-halfword lua_str_toks(lstring b)
-{
- /*tex tail of the token list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex token being appended */
- halfword t;
- /*tex index into string */
- unsigned char *k;
- p = temp_token_head;
- set_token_link(p, null);
- k = (unsigned char *) b.s;
- while (k < (unsigned char *) b.s + b.l) {
- t = pool_to_unichar(k);
- k += utf8_size(t);
- if (t == ' ') {
- t = space_token;
- } else {
- if ((t == '\\') || (t == '"') || (t == '\'') || (t == 10) || (t == 13))
- fast_store_new_token(other_token + '\\');
- if (t == 10)
- t = 'n';
- if (t == 13)
- t = 'r';
- t = other_token + t;
- }
- fast_store_new_token(t);
- }
- return p;
-}
-
-/*tex
-
- Incidentally, the main reason for wanting |str_toks| is the function
- |the_toks|, which has similar input/output characteristics.
-
- This changes the string |str_pool[b..pool_ptr]| to a token list:
-
-*/
-
-halfword str_toks(lstring s)
-{
- /*tex tail of the token list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex token being appended */
- halfword t;
- /*tex index into string */
- unsigned char *k, *l;
- p = temp_token_head;
- set_token_link(p, null);
- k = s.s;
- l = k + s.l;
- while (k < l) {
- t = pool_to_unichar(k);
- k += utf8_size(t);
- if (t == ' ')
- t = space_token;
- else
- t = other_token + t;
- fast_store_new_token(t);
- }
- return p;
-}
-
-/*tex
-
- Most of the converter is similar to the one i made for macro so at some point
- I can make a helper; also todo: there is no need to go through the pool.
-
-*/
-
-/*tex Change the string |str_pool[b..pool_ptr]| to a token list. */
-
-halfword str_scan_toks(int ct, lstring s)
-{
- /*tex tail of the token list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex token being appended */
- halfword t;
- /*tex index into string */
- unsigned char *k, *l;
- int cc;
- p = temp_token_head;
- set_token_link(p, null);
- k = s.s;
- l = k + s.l;
- while (k < l) {
- t = pool_to_unichar(k);
- k += utf8_size(t);
- cc = get_cat_code(ct,t);
- if (cc == 0) {
- /*tex We have a potential control sequence so we check for it. */
- int _lname = 0 ;
- int _s = 0 ;
- int _c = 0 ;
- halfword _cs = null ;
- unsigned char *_name = k ;
- while (k < l) {
- t = (halfword) str2uni((const unsigned char *) k);
- _s = utf8_size(t);
- _c = get_cat_code(ct,t);
- if (_c == 11) {
- k += _s ;
- _lname = _lname + _s ;
- } else if (_c == 10) {
- /*tex We ignore a trailing space like normal scanning does. */
- k += _s ;
- break ;
- } else {
- break ;
- }
- }
- if (_s > 0) {
- /*tex We have a potential |\cs|. */
- _cs = string_lookup((const char *) _name, _lname);
- if (_cs == undefined_control_sequence) {
- /* let's play safe and backtrack */
- t = cc * (1<<21) + t ;
- k = _name ;
- } else {
- t = cs_token_flag + _cs;
- }
- } else {
- /*tex
-
- Just a character with some meaning, so |\unknown| becomes
- effectively |\unknown| assuming that |\\| has some useful
- meaning of course.
-
- */
- t = cc * (1<<21) + t ;
- k = _name ;
- }
-
- } else {
- /*tex
-
- Whatever token, so for instance $x^2$ just works given a \TEX\
- catcode regime.
-
- */
- t = cc * (1<<21) + t ;
- }
- fast_store_new_token(t);
-
- }
- return p;
-}
-
-/*tex
-
- Here's part of the |expand| subroutine that we are now ready to complete:
-
-*/
-
-void ins_the_toks(void)
-{
- (void) the_toks();
- ins_list(token_link(temp_token_head));
-}
-
-#define set_toks_register(n,t,g) do { \
- int a = (g>0) ? 4 : 0; \
- halfword ref = get_avail(); \
- set_token_ref_count(ref, 0); \
- set_token_link(ref, token_link(t)); \
- define(n + toks_base, call_cmd, ref); \
-} while (0)
-
-#define append_copied_toks_list(s,t) do { \
- halfword p; \
- halfword q; \
- p = temp_token_head; \
- set_token_link(p, null); \
- while (s != null) { \
- fast_store_new_token(token_info(s)); \
- s = token_link(s); \
- } \
- while (t != null) { \
- fast_store_new_token(token_info(t)); \
- t = token_link(t); \
- } \
- } while (0)
-
-
-/*tex
-
- \starttabulate[|T||T||]
- \NC 0 \NC \type {toksapp} \NC 1 \NC \type {etoksapp} \NC \NR
- \NC 2 \NC \type {tokspre} \NC 3 \NC \type {etokspre} \NC \NR
- \NC 4 \NC \type {gtoksapp} \NC 5 \NC \type {xtoksapp} \NC \NR
- \NC 6 \NC \type {gtokspre} \NC 7 \NC \type {xtokspre} \NC \NR
- \stoptabulate
-
-*/
-
-# define immediate_permitted(n,target) ((eq_level(toks_base + n) == cur_level) && (token_ref_count(target) == 0))
-
-void combine_the_toks(void)
-{
- halfword how = cur_chr;
- halfword source = null;
- halfword target = null;
- halfword append = (how == 0) || (how == 1) || (how == 4) || (how == 5);
- halfword expand = odd(how);
- halfword global = how > 3;
- halfword nt, ns, s, t, p, q, h;
- get_x_token();
- /*tex The target. */
- if (cur_cmd == assign_toks_cmd) {
- /*tex Check range. */
- nt = equiv(cur_cs) - toks_base;
- } else {
- back_input();
- scan_register_num();
- nt = cur_val;
- }
- /*tex The source. */
- do {
- get_x_token();
- } while (cur_cmd == spacer_cmd);
- if (cur_cmd == left_brace_cmd) {
- back_input();
- scan_toks(false,expand);
- source = def_ref;
- /*tex The action. */
- if (source != null) {
- target = toks(nt);
- if (target == null) {
- set_toks_register(nt,source,global);
- token_link(source) = null;
- } else {
- s = token_link(source);
- if (s != null) {
- t = token_link(target);
- if (t == null) {
- /*tex Can this happen? */
- set_token_link(target, s);
- token_link(source) = null;
- } else if (append) {
- /*tex Append. */
- if (immediate_permitted(nt,target)) {
- p = t;
- while (token_link(p) != null) {
- p = token_link(p);
- }
- while (s != null) {
- fast_store_new_token(token_info(s));
- s = token_link(s);
- }
- } else {
- append_copied_toks_list(t,s);
- set_toks_register(nt,temp_token_head,global);
- }
- } else {
- /* prepend */
- if (immediate_permitted(nt,target)) {
- h = null;
- p = null ;
- while (s != null) {
- fast_store_new_token(token_info(s));
- if (h == null) {
- h = p;
- }
- s = token_link(s);
- }
- set_token_link(p,t);
- set_token_link(target,h);
- } else {
- append_copied_toks_list(s,t);
- set_toks_register(nt,temp_token_head,global);
- }
- }
- }
- }
- flush_list(source);
- }
- } else {
- if (cur_cmd == assign_toks_cmd) {
- ns = equiv(cur_cs) - toks_base;
- /*tex Check range. */
- } else {
- scan_register_num();
- ns = cur_val;
- }
- /*tex The action. */
- source = toks(ns);
- if (source != null) {
- target = toks(nt);
- if (target == null) {
- /*tex The assign. */
- token_ref_count(source)++;
- equiv(toks_base+nt) = source;
- return;
- }
- s = token_link(source);
- t = token_link(target);
- if (append) {
- /*tex Append. */
- if (immediate_permitted(nt,target)) {
- p = t;
- while (token_link(p) != null) {
- p = token_link(p);
- }
- while (s != null) {
- fast_store_new_token(token_info(s));
- s = token_link(s);
- }
- } else {
- append_copied_toks_list(t,s);
- set_toks_register(nt,temp_token_head,global);
- }
- } else {
- /*tex Prepend. */
- if (immediate_permitted(nt,target)) {
- h = null;
- p = null;
- while (s != null) {
- fast_store_new_token(token_info(s));
- if (h == null) {
- h = p;
- }
- s = token_link(s);
- }
- set_token_link(p,t);
- set_token_link(target,h);
- } else {
- append_copied_toks_list(s,t);
- set_toks_register(nt,temp_token_head,global);
- }
- }
- }
- }
-}
-
-/*tex
-
- This routine, used in the next one, prints the job name, possibly modified by
- the |process_jobname| callback.
-
-*/
-
-static void print_job_name(void)
-{
- if (job_name) {
- /*tex C strings for jobname before and after processing. */
- char *s, *ss;
- int callback_id, lua_retval;
- s = (char*)str_string(job_name);
- callback_id = callback_defined(process_jobname_callback);
- if (callback_id > 0) {
- lua_retval = run_callback(callback_id, "S->S", s, &ss);
- if ((lua_retval == true) && (ss != NULL))
- s = ss;
- }
- tprint(s);
- } else {
- print(job_name);
- }
-}
-
-/*tex
-
- Here is a routine that print the result of a convert command, using the
- argument |i|. It returns |false | if it does not know to print the code |c|.
- The function exists because lua code and tex code can both call it to convert
- something.
-
- Parse optional \LUA\ state integer, or an instance name to be stored in |sn|
- and get the next non-blank non-relax non-call token.
-
-*/
-
-int scan_lua_state(void)
-{
- int sn = 0;
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- back_input();
- if (cur_cmd != left_brace_cmd) {
- if (scan_keyword("name")) {
- (void) scan_toks(false, true);
- sn = def_ref;
- } else {
- scan_register_num();
- if (get_lua_name(cur_val))
- sn = (cur_val - 65536);
- }
- }
- return sn;
-}
-
-/*tex
-
- The procedure |conv_toks| uses |str_toks| to insert the token list for
- |convert| functions into the scanner; `\.{\\outer}' control sequences are
- allowed to follow `\.{\\string}' and `\.{\\meaning}'.
-
- The extra temp string |u| is needed because |pdf_scan_ext_toks| incorporates
- any pending string in its output. In order to save such a pending string, we
- have to create a temporary string that is destroyed immediately after.
-
-*/
-
-#define push_selector { \
- old_setting = selector; \
- selector = new_string; \
-}
-
-#define pop_selector { \
- selector = old_setting; \
-}
-
-static int do_variable_dvi(halfword c)
-{
- return 0;
-}
-
-#define do_variable_backend_int(i) \
- cur_cmd = assign_int_cmd; \
- cur_val = backend_int_base + i; \
- cur_tok = token_val(cur_cmd, cur_val); \
- back_input();
-
-#define do_variable_backend_dimen(i) \
- cur_cmd = assign_dimen_cmd; \
- cur_val = backend_dimen_base + i; \
- cur_tok = token_val(cur_cmd, cur_val); \
- back_input();
-
-#define do_variable_backend_toks(i) \
- cur_cmd = assign_toks_cmd; \
- cur_val = backend_toks_base + i ; \
- cur_tok = token_val(cur_cmd, cur_val); \
- back_input();
-
-static int do_variable_pdf(halfword c)
-{
- if (scan_keyword("compresslevel")) { do_variable_backend_int(c_pdf_compress_level); }
- else if (scan_keyword("decimaldigits")) { do_variable_backend_int(c_pdf_decimal_digits); }
- else if (scan_keyword("imageresolution")) { do_variable_backend_int(c_pdf_image_resolution); }
- else if (scan_keyword("pkresolution")) { do_variable_backend_int(c_pdf_pk_resolution); }
- else if (scan_keyword("uniqueresname")) { do_variable_backend_int(c_pdf_unique_resname); }
- else if (scan_keyword("majorversion")) { do_variable_backend_int(c_pdf_major_version); }
- else if (scan_keyword("minorversion")) { do_variable_backend_int(c_pdf_minor_version); }
- else if (scan_keyword("pagebox")) { do_variable_backend_int(c_pdf_pagebox); }
- else if (scan_keyword("inclusionerrorlevel")) { do_variable_backend_int(c_pdf_inclusion_errorlevel); }
- else if (scan_keyword("ignoreunknownimages")) { do_variable_backend_int(c_pdf_ignore_unknown_images); }
- else if (scan_keyword("gamma")) { do_variable_backend_int(c_pdf_gamma); }
- else if (scan_keyword("imageapplygamma")) { do_variable_backend_int(c_pdf_image_apply_gamma); }
- else if (scan_keyword("imagegamma")) { do_variable_backend_int(c_pdf_image_gamma); }
- else if (scan_keyword("imagehicolor")) { do_variable_backend_int(c_pdf_image_hicolor); }
- else if (scan_keyword("imageaddfilename")) { do_variable_backend_int(c_pdf_image_addfilename); }
- else if (scan_keyword("objcompresslevel")) { do_variable_backend_int(c_pdf_obj_compress_level); }
- else if (scan_keyword("inclusioncopyfonts")) { do_variable_backend_int(c_pdf_inclusion_copy_font); }
- else if (scan_keyword("gentounicode")) { do_variable_backend_int(c_pdf_gen_tounicode); }
- else if (scan_keyword("pkfixeddpi")) { do_variable_backend_int(c_pdf_pk_fixed_dpi); }
- else if (scan_keyword("suppressoptionalinfo")) { do_variable_backend_int(c_pdf_suppress_optional_info); }
- else if (scan_keyword("omitcidset")) { do_variable_backend_int(c_pdf_omit_cidset); }
- else if (scan_keyword("omitcharset")) { do_variable_backend_int(c_pdf_omit_charset); }
- else if (scan_keyword("recompress")) { do_variable_backend_int(c_pdf_recompress); }
-
- else if (scan_keyword("horigin")) { do_variable_backend_dimen(d_pdf_h_origin); }
- else if (scan_keyword("vorigin")) { do_variable_backend_dimen(d_pdf_v_origin); }
- else if (scan_keyword("threadmargin")) { do_variable_backend_dimen(d_pdf_thread_margin); }
- else if (scan_keyword("destmargin")) { do_variable_backend_dimen(d_pdf_dest_margin); }
- else if (scan_keyword("linkmargin")) { do_variable_backend_dimen(d_pdf_link_margin); }
- else if (scan_keyword("xformmargin")) { do_variable_backend_dimen(d_pdf_xform_margin); }
-
- else if (scan_keyword("pageattr")) { do_variable_backend_toks(t_pdf_page_attr); }
- else if (scan_keyword("pageresources")) { do_variable_backend_toks(t_pdf_page_resources); }
- else if (scan_keyword("pagesattr")) { do_variable_backend_toks(t_pdf_pages_attr); }
- else if (scan_keyword("xformattr")) { do_variable_backend_toks(t_pdf_xform_attr); }
- else if (scan_keyword("xformresources")) { do_variable_backend_toks(t_pdf_xform_resources); }
- else if (scan_keyword("pkmode")) { do_variable_backend_toks(t_pdf_pk_mode); }
- else if (scan_keyword("trailerid")) { do_variable_backend_toks(t_pdf_trailer_id); }
-
- else
- return 0;
- return 1;
-}
-
-static int do_feedback_dvi(halfword c)
-{
- return 0;
-}
-
-/*tex Codes not really needed but cleaner when testing */
-
-#define pdftex_version 140 /* these values will not change any more */
-#define pdftex_revision "0" /* these values will not change any more */
-
-static int do_feedback_pdf(halfword c)
-{
- /*tex holds |selector| setting */
- int old_setting;
- /*tex |scanner_status| upon entry */
- int save_scanner_status;
- /*tex |def_ref| upon entry, important if inside `\.{\\message}' */
- halfword save_def_ref;
- halfword save_warning_index;
- /*tex temp boolean */
- boolean bool;
- /*tex first temp string */
- str_number s;
- /*tex for use with |set_ff| */
- int ff;
- /*tex third temp string, will become non-nil if a string is already being built */
- str_number u = 0;
- /*tex color stack init str */
- char *str;
- if (scan_keyword("lastlink")) {
- push_selector;
- print_int(pdf_last_link);
- pop_selector;
- } else if (scan_keyword("retval")) {
- push_selector;
- print_int(pdf_retval);
- pop_selector;
- } else if (scan_keyword("lastobj")) {
- push_selector;
- print_int(pdf_last_obj);
- pop_selector;
- } else if (scan_keyword("lastannot")) {
- push_selector;
- print_int(pdf_last_annot);
- pop_selector;
- } else if (scan_keyword("xformname")) {
- scan_int();
- check_obj_type(static_pdf, obj_type_xform, cur_val);
- push_selector;
- print_int(obj_info(static_pdf, cur_val));
- pop_selector;
- } else if (scan_keyword("creationdate")) {
- ins_list(string_to_toks(getcreationdate(static_pdf)));
- /*tex No further action. */
- return 2;
- } else if (scan_keyword("fontname")) {
- scan_font_ident();
- if (cur_val == null_font)
- normal_error("pdf backend", "invalid font identifier when asking 'fontname'");
- pdf_check_vf(cur_val);
- if (!font_used(cur_val))
- pdf_init_font(static_pdf, cur_val);
- push_selector;
- set_ff(cur_val);
- print_int(obj_info(static_pdf, pdf_font_num(ff)));
- pop_selector;
- } else if (scan_keyword("fontobjnum")) {
- scan_font_ident();
- if (cur_val == null_font)
- normal_error("pdf backend", "invalid font identifier when asking 'objnum'");
- pdf_check_vf(cur_val);
- if (!font_used(cur_val))
- pdf_init_font(static_pdf, cur_val);
- push_selector;
- set_ff(cur_val);
- print_int(pdf_font_num(ff));
- pop_selector;
- } else if (scan_keyword("fontsize")) {
- scan_font_ident();
- if (cur_val == null_font)
- normal_error("pdf backend", "invalid font identifier when asking 'fontsize'");
- push_selector;
- print_scaled(font_size(cur_val));
- tprint("pt");
- pop_selector;
- } else if (scan_keyword("pageref")) {
- scan_int();
- if (cur_val <= 0)
- normal_error("pdf backend", "invalid page number when asking 'pageref'");
- push_selector;
- print_int(pdf_get_obj(static_pdf, obj_type_page, cur_val, false));
- pop_selector;
- } else if (scan_keyword("colorstackinit")) {
- bool = scan_keyword("page");
- if (scan_keyword("direct"))
- cur_val = direct_always;
- else if (scan_keyword("page"))
- cur_val = direct_page;
- else if (scan_keyword("text"))
- cur_val = direct_text;
- else if (scan_keyword("raw"))
- cur_val = direct_raw;
- else if (scan_keyword("origin"))
- cur_val = set_origin;
- else
- cur_val = set_origin;
- save_scanner_status = scanner_status;
- save_warning_index = warning_index;
- save_def_ref = def_ref;
- u = save_cur_string();
- scan_toks(false, true);
- s = tokens_to_string(def_ref);
- delete_token_ref(def_ref);
- def_ref = save_def_ref;
- warning_index = save_warning_index;
- scanner_status = save_scanner_status;
- str = makecstring(s);
- cur_val = newcolorstack(str, cur_val, bool);
- free(str);
- flush_str(s);
- cur_val_level = int_val_level;
- if (cur_val < 0) {
- print_err("Too many color stacks");
- help2("The number of color stacks is limited to 32768.",
- "I'll use the default color stack 0 here.");
- error();
- cur_val = 0;
- restore_cur_string(u);
- }
- push_selector;
- print_int(cur_val);
- pop_selector;
- } else if (scan_keyword("version")) {
- push_selector;
- print_int(pdftex_version);
- pop_selector;
- } else if (scan_keyword("revision")) {
- ins_list(string_to_toks(pdftex_revision));
- return 2;
- } else {
- return 0;
- }
- return 1;
-}
-
-void conv_toks(void)
-{
- /*tex holds |selector| setting */
- int old_setting;
- halfword p, q;
- /*tex |scanner_status| upon entry */
- int save_scanner_status;
- /*tex |def_ref| upon entry, important if inside `\.{\\message}' */
- halfword save_def_ref;
- halfword save_warning_index;
- /*tex temp boolean */
- boolean bool;
- /*tex first temp string */
- str_number s;
- /*tex lua chunk name */
- int sn;
- /*tex third temp string, will become non-nil if a string is already being built */
- str_number u = 0;
- /*tex desired type of conversion */
- int c = cur_chr;
- str_number str;
- int i = 0;
- /*tex Scan the argument for command |c|. */
- switch (c) {
- case number_code:
- scan_int();
- push_selector;
- print_int(cur_val);
- pop_selector;
- break;
- case lua_function_code:
- scan_int();
- if (cur_val <= 0) {
- normal_error("luafunction", "invalid number");
- } else {
- u = save_cur_string();
- luacstrings = 0;
- luafunctioncall(cur_val);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
- return;
- break;
- case lua_bytecode_code:
- scan_int();
- if (cur_val < 0 || cur_val > 65535) {
- normal_error("luabytecode", "invalid number");
- } else {
- u = save_cur_string();
- luacstrings = 0;
- luabytecodecall(cur_val);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- }
- return;
- break;
- case lua_code:
- u = save_cur_string();
- save_scanner_status = scanner_status;
- save_def_ref = def_ref;
- save_warning_index = warning_index;
- sn = scan_lua_state();
- scan_toks(false, true);
- s = def_ref;
- warning_index = save_warning_index;
- def_ref = save_def_ref;
- scanner_status = save_scanner_status;
- luacstrings = 0;
- luatokencall(s, sn);
- delete_token_ref(s);
- restore_cur_string(u);
- if (luacstrings > 0)
- lua_string_start();
- /*tex No further action. */
- return;
- break;
- case expanded_code:
- save_scanner_status = scanner_status;
- save_warning_index = warning_index;
- save_def_ref = def_ref;
- u = save_cur_string();
- scan_toks(false, true);
- warning_index = save_warning_index;
- scanner_status = save_scanner_status;
- ins_list(token_link(def_ref));
- token_link(def_ref) = null;
- free_avail(def_ref);
- def_ref = save_def_ref;
- restore_cur_string(u);
- /*tex No further action. */
- return;
- break;
- case immediate_assignment_code:
- case immediate_assigned_code:
- /*tex
-
- This is on-the-road-to-bachotex brain-wave but it needs a bit
- more testing. A first variant did more in sequence till a relax
- of spacer was seen (like do_assignments). It permits for instance
- setting counters in full expansion.
-
- */
- save_scanner_status = scanner_status;
- save_warning_index = warning_index;
- save_def_ref = def_ref;
- u = save_cur_string();
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (c == immediate_assignment_code) {
- /*tex one-step do_assignment */
- if (cur_cmd > max_non_prefixed_command) {
- set_box_allowed = false;
- prefixed_command();
- set_box_allowed = true;
- }
- /*tex done */
- } else {
- /*tex pseudo token list do_assignment */
- if (cur_cmd == left_brace_cmd) {
- while (1) {
- do {
- get_x_token();
- } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
- if (cur_cmd == right_brace_cmd) {
- break;
- } else {
- set_box_allowed = false;
- prefixed_command();
- set_box_allowed = true;
- }
- }
- }
- /*tex done */
- }
- warning_index = save_warning_index;
- scanner_status = save_scanner_status;
- def_ref = save_def_ref;
- restore_cur_string(u);
- return;
- break;
- case math_style_code:
- push_selector;
- print_math_style();
- pop_selector;
- break;
- case string_code:
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- push_selector;
- if (cur_cs != 0)
- sprint_cs(cur_cs);
- else
- print(cur_chr);
- pop_selector;
- break;
- case cs_string_code:
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- push_selector;
- if (cur_cs != 0)
- sprint_cs_name(cur_cs);
- else
- print(cur_chr);
- pop_selector;
- break;
- case roman_numeral_code:
- scan_int();
- push_selector;
- print_roman_int(cur_val);
- pop_selector;
- break;
- case meaning_code:
- save_scanner_status = scanner_status;
- scanner_status = normal;
- get_token();
- scanner_status = save_scanner_status;
- push_selector;
- print_meaning();
- pop_selector;
- break;
- case uchar_code:
- scan_char_num();
- push_selector;
- print(cur_val);
- pop_selector;
- break;
- case lua_escape_string_code:
- {
- lstring escstr;
- int l = 0;
- save_scanner_status = scanner_status;
- save_def_ref = def_ref;
- save_warning_index = warning_index;
- scan_toks(false, true);
- bool = in_lua_escape;
- in_lua_escape = true;
- escstr.s = (unsigned char *) tokenlist_to_cstring(def_ref, false, &l);
- escstr.l = (unsigned) l;
- in_lua_escape = bool;
- delete_token_ref(def_ref);
- def_ref = save_def_ref;
- warning_index = save_warning_index;
- scanner_status = save_scanner_status;
- (void) lua_str_toks(escstr);
- ins_list(token_link(temp_token_head));
- free(escstr.s);
- return;
- }
- /*tex no further action */
- break;
- case font_id_code:
- scan_font_ident();
- push_selector;
- print_int(cur_val);
- pop_selector;
- break;
- case font_name_code:
- scan_font_ident();
- push_selector;
- append_string((unsigned char *) font_name(cur_val),(unsigned) strlen(font_name(cur_val)));
- if (font_size(cur_val) != font_dsize(cur_val)) {
- tprint(" at ");
- print_scaled(font_size(cur_val));
- tprint("pt");
- }
- pop_selector;
- break;
- case left_margin_kern_code:
- scan_int();
- if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node))
- normal_error("marginkern", "a non-empty hbox expected");
- push_selector;
- p = list_ptr(box(cur_val));
- while ((p != null) && (type(p) == glue_node)) {
- p = vlink(p);
- }
- if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == left_side))
- print_scaled(width(p));
- else
- print_char('0');
- tprint("pt");
- pop_selector;
- break;
- case right_margin_kern_code:
- scan_int();
- if ((box(cur_val) == null) || (type(box(cur_val)) != hlist_node))
- normal_error("marginkern", "a non-empty hbox expected");
- push_selector;
- p = list_ptr(box(cur_val));
- if (p != null) {
- p = tail_of_list(p);
- /*tex
-
- There can be a leftskip, rightskip, penalty and yes, also a
- disc node with a nesting node that points to glue spec ...
- and we don't want to analyze that messy lot.
-
- */
- while ((p != null) && (type(p) == glue_node)) {
- p = alink(p);
- }
- if ((p != null) && ! ((type(p) == margin_kern_node) && (subtype(p) == right_side))) {
- if (type(p) == disc_node) {
- q = alink(p);
- if ((q != null) && ((type(q) == margin_kern_node) && (subtype(q) == right_side))) {
- p = q;
- } else {
- /*tex
-
- Officially we should look in the replace but
- currently protrusion doesn't work anyway with
- "foo\discretionary{}{}{bar-} " (no following
- char) so we don't need it now.
- */
- }
- }
- }
- }
- if ((p != null) && (type(p) == margin_kern_node) && (subtype(p) == right_side))
- print_scaled(width(p));
- else
- print_char('0');
- tprint("pt");
- pop_selector;
- break;
- case uniform_deviate_code:
- scan_int();
- push_selector;
- print_int(unif_rand(cur_val));
- pop_selector;
- break;
- case normal_deviate_code:
- push_selector;
- print_int(norm_rand());
- pop_selector;
- break;
- case math_char_class_code:
- {
- mathcodeval mval;
- scan_int();
- mval = get_math_code(cur_val);
- push_selector;
- print_int(mval.class_value);
- pop_selector;
- }
- break;
- case math_char_fam_code:
- {
- mathcodeval mval;
- scan_int();
- mval = get_math_code(cur_val);
- push_selector;
- print_int(mval.family_value);
- pop_selector;
- }
- break;
- case math_char_slot_code:
- {
- mathcodeval mval;
- scan_int();
- mval = get_math_code(cur_val);
- push_selector;
- print_int(mval.character_value);
- pop_selector;
- }
- break;
- case insert_ht_code:
- scan_register_num();
- push_selector;
- i = cur_val;
- p = page_ins_head;
- while (i >= subtype(vlink(p)))
- p = vlink(p);
- if (subtype(p) == i)
- print_scaled(height(p));
- else
- print_char('0');
- tprint("pt");
- pop_selector;
- break;
- case job_name_code:
- if (job_name == 0)
- open_log_file();
- push_selector;
- print_job_name();
- pop_selector;
- break;
- case format_name_code:
- if (job_name == 0)
- open_log_file();
- push_selector;
- print(format_name);
- pop_selector;
- break;
- case luatex_banner_code:
- push_selector;
- tprint(luatex_banner);
- pop_selector;
- break;
- case luatex_revision_code:
- push_selector;
- print(get_luatexrevision());
- pop_selector;
- break;
- case etex_code:
- push_selector;
- tprint(eTeX_version_string);
- pop_selector;
- break;
- case eTeX_revision_code:
- push_selector;
- tprint(eTeX_revision);
- pop_selector;
- break;
- case font_identifier_code:
- confusion("convert");
- break;
- default:
- confusion("convert");
- break;
- }
- str = make_string();
- (void) str_toks(str_lstring(str));
- flush_str(str);
- ins_list(token_link(temp_token_head));
-}
-
-void do_feedback(void)
-{
- int c = cur_chr;
- str_number str;
- int done = 1;
- switch (c) {
- case dvi_feedback_code:
- if (get_o_mode() == OMODE_DVI) {
- done = do_feedback_dvi(c);
- } else {
- tex_error("unexpected use of \\dvifeedback",null);
- return ;
- }
- if (done==0) {
- /* we recover */
- normal_warning("dvi backend","unexpected use of \\dvifeedback");
- return;
- } else if (done==2) {
- return;
- }
- break;
- case pdf_feedback_code:
- if (get_o_mode() == OMODE_PDF) {
- done = do_feedback_pdf(c);
- } else {
- tex_error("unexpected use of \\pdffeedback",null);
- return ;
- }
- if (done==0) {
- /*tex We recover. */
- normal_warning("pdf backend","unexpected use of \\pdffeedback");
- return;
- } else if (done==2) {
- return;
- }
- break;
- default:
- confusion("feedback");
- break;
- }
- str = make_string();
- (void) str_toks(str_lstring(str));
- flush_str(str);
- ins_list(token_link(temp_token_head));
-}
-
-void do_variable(void)
-{
- int c = cur_chr;
- int done = 1;
- switch (c) {
- case dvi_variable_code:
- done = do_variable_dvi(c);
- if (done==0) {
- /*tex We recover. */
- normal_warning("dvi backend","unexpected use of \\dvivariable");
- }
- return;
- break;
- case pdf_variable_code:
- done = do_variable_pdf(c);
- if (done==0) {
- /*tex We recover. */
- normal_warning("pdf backend","unexpected use of \\pdfvariable");
- }
- return;
- break;
- default:
- confusion("variable");
- break;
- }
-}
-
-/*tex This boolean is keeping track of the lua string escape state */
-
-boolean in_lua_escape;
-
-static int the_convert_string_dvi(halfword c, int i)
-{
- return 0 ;
-}
-
-static int the_convert_string_pdf(halfword c, int i)
-{
- int ff;
- if (get_o_mode() != OMODE_PDF) {
- return 0;
- } else if (scan_keyword("lastlink")) {
- print_int(pdf_last_link);
- } else if (scan_keyword("retval")) {
- print_int(pdf_retval);
- } else if (scan_keyword("lastobj")) {
- print_int(pdf_last_obj);
- } else if (scan_keyword("lastannot")) {
- print_int(pdf_last_annot);
- } else if (scan_keyword("xformname")) {
- print_int(obj_info(static_pdf, i));
- } else if (scan_keyword("creationdate")) {
- return 0;
- } else if (scan_keyword("fontname")) {
- set_ff(i);
- print_int(obj_info(static_pdf, pdf_font_num(ff)));
- } else if (scan_keyword("fontobjnum")) {
- set_ff(i);
- print_int(pdf_font_num(ff));
- } else if (scan_keyword("fontsize")) {
- print_scaled(font_size(i));
- tprint("pt");
- } else if (scan_keyword("pageref")) {
- print_int(pdf_get_obj(static_pdf, obj_type_page, i, false));
- } else if (scan_keyword("colorstackinit")) {
- return 0;
- } else {
- return 0;
- }
- return 1;
-}
-
-str_number the_convert_string(halfword c, int i)
-{
- int old_setting;
- str_number ret = 0;
- boolean done = true ;
- old_setting = selector;
- selector = new_string;
- switch (c) {
- case number_code:
- print_int(i);
- break;
- /* case lua_function_code: */
- /* case lua_code: */
- /* case expanded_code: */
- case math_style_code:
- print_math_style();
- break;
- /* case string_code: */
- /* case cs_string_code: */
- case roman_numeral_code:
- print_roman_int(i);
- break;
- /* case meaning_code: */
- case uchar_code:
- print(i);
- break;
- /* lua_escape_string_code: */
- case font_id_code:
- print_int(i);
- break;
- case font_name_code:
- append_string((unsigned char *) font_name(i),(unsigned) strlen(font_name(i)));
- if (font_size(i) != font_dsize(i)) {
- tprint(" at ");
- print_scaled(font_size(i));
- tprint("pt");
- }
- break;
- /* left_margin_kern_code: */
- /* right_margin_kern_code: */
- case uniform_deviate_code:
- print_int(unif_rand(i));
- break;
- case normal_deviate_code:
- print_int(norm_rand());
- break;
- /* math_char_class_code: */
- /* math_char_fam_code: */
- /* math_char_slot_code: */
- /* insert_ht_code: */
- case job_name_code:
- print_job_name();
- break;
- case format_name_code:
- print(format_name);
- break;
- case luatex_banner_code:
- tprint(luatex_banner);
- break;
- case luatex_revision_code:
- print(get_luatexrevision());
- break;
- case etex_code:
- tprint(eTeX_version_string);
- break;
- case eTeX_revision_code:
- tprint(eTeX_revision);
- break;
- case font_identifier_code:
- print_font_identifier(i);
- break;
- /*tex Backend: this might become obsolete! */
- case dvi_feedback_code:
- done = the_convert_string_dvi(c,i);
- break;
- case pdf_feedback_code:
- done = the_convert_string_pdf(c,i);
- break;
- /*tex done */
- default:
- done = false;
- break;
- }
- if (done) {
- ret = make_string();
- }
- selector = old_setting;
- return ret;
-}
-
-/*tex
-
- Another way to create a token list is via the \.{\\read} command. The sixteen
- files potentially usable for reading appear in the following global
- variables. The value of |read_open[n]| will be |closed| if stream number |n|
- has not been opened or if it has been fully read; |just_open| if an
- \.{\\openin} but not a \.{\\read} has been done; and |normal| if it is open
- and ready to read the next line.
-
-*/
-
-/*tex used for \.{\\read} */
-
-FILE *read_file[16];
-
-/*tex state of |read_file[n]| */
-
-int read_open[17];
-
-void initialize_read(void)
-{
- int k;
- for (k = 0; k <= 16; k++)
- read_open[k] = closed;
-}
-
-/*tex
-
- The |read_toks| procedure constructs a token list like that for any macro
- definition, and makes |cur_val| point to it. Parameter |r| points to the
- control sequence that will receive this token list.
-
-*/
-
-void read_toks(int n, halfword r, halfword j)
-{
- /*tex tail of the token list */
- halfword p;
- /*tex new node being added to the token list via |store_new_token| */
- halfword q;
- /*tex saved value of |align_state| */
- int s;
- /*tex stream number */
- int m;
- scanner_status = defining;
- warning_index = r;
- p = get_avail();
- def_ref = p;
- set_token_ref_count(def_ref, 0);
- /*tex the reference count */
- p = def_ref;
- store_new_token(end_match_token);
- if ((n < 0) || (n > 15))
- m = 16;
- else
- m = n;
- s = align_state;
- /*tex disable tab marks, etc. */
- align_state = 1000000;
- do {
- /*tex Input and store tokens from the next line of the file. */
- begin_file_reading();
- iname = m + 1;
- if (read_open[m] == closed) {
- /*tex
-
- Input for \.{\\read} from the terminal. We input on-line into the
- |buffer| array, prompting the user explicitly if |n>=0|. The
- value of |n| is set negative so that additional prompts will not
- be given in the case of multi-line input.
-
- */
- if (interaction > nonstop_mode) {
- if (n < 0) {
- prompt_input("");
- } else {
- wake_up_terminal();
- print_ln();
- sprint_cs(r);
- prompt_input(" =");
- n = -1;
- }
- } else {
- fatal_error
- ("*** (cannot \\read from terminal in nonstop modes)");
- }
-
- } else if (read_open[m] == just_open) {
- /*tex
-
- Input the first line of |read_file[m]|. The first line of a file
- must be treated specially, since |lua_input_ln| must be told not
- to start with |get|.
-
- */
- if (lua_input_ln(read_file[m], (m + 1), false)) {
- read_open[m] = normal;
- } else {
- lua_a_close_in(read_file[m], (m + 1));
- read_open[m] = closed;
- }
-
- } else {
- /*tex
-
- Input the next line of |read_file[m]|. An empty line is appended
- at the end of a |read_file|.
-
- */
- if (!lua_input_ln(read_file[m], (m + 1), true)) {
- lua_a_close_in(read_file[m], (m + 1));
- read_open[m] = closed;
- if (align_state != 1000000) {
- runaway();
- print_err("File ended within \\read");
- help1("This \\read has unbalanced braces.");
- align_state = 1000000;
- error();
- }
- }
-
- }
- ilimit = last;
- if (end_line_char_inactive)
- decr(ilimit);
- else
- buffer[ilimit] = (packed_ASCII_code) end_line_char_par;
- first = ilimit + 1;
- iloc = istart;
- istate = new_line;
- /*tex Handle \.{\\readline} and |goto done|. */
- if (j == 1) {
- while (iloc <= ilimit) {
- /*tex Current line not yet finished. */
- do_buffer_to_unichar(cur_chr, iloc);
- if (cur_chr == ' ')
- cur_tok = space_token;
- else
- cur_tok = cur_chr + other_token;
- store_new_token(cur_tok);
- }
- } else {
- while (1) {
- get_token();
- if (cur_tok == 0) {
- /*tex |cur_cmd=cur_chr=0| will occur at the end of the line. */
- break;
- }
- if (align_state < 1000000) {
- /*tex Unmatched right brace aborts the line. */
- do {
- get_token();
- } while (cur_tok != 0);
- align_state = 1000000;
- break;
- }
- store_new_token(cur_tok);
- }
- }
- end_file_reading();
-
- } while (align_state != 1000000);
- cur_val = def_ref;
- scanner_status = normal;
- align_state = s;
-}
-
-/*tex Return a string from tokens list: */
-
-str_number tokens_to_string(halfword p)
-{
- int old_setting;
- if (selector == new_string)
- normal_error("tokens","tokens_to_string() called while selector = new_string");
- old_setting = selector;
- selector = new_string;
- show_token_list(token_link(p), null, -1);
- selector = old_setting;
- return make_string();
-}
-
-/*tex
-
- Values like 512 and 128 also work ok. There is not much to gain in
- optimization here.
-
-*/
-
-#define alloci_default 1024
-#define alloci_step 256
-
-#define make_room(a) \
- if ((unsigned)i+a+1>alloci) { \
- ret = xrealloc(ret,(alloci+alloci_step)); \
- alloci = alloci + alloci_step; \
- }
-
-#define append_i_byte(a) ret[i++] = (char)(a)
-
-#define Print_char(a) make_room(1); append_i_byte(a)
-
-#define Print_uchar(s) { \
- make_room(4); \
- if (s<=0x7F) { \
- append_i_byte(s); \
- } else if (s<=0x7FF) { \
- append_i_byte(0xC0 + (s / 0x40)); \
- append_i_byte(0x80 + (s % 0x40)); \
- } else if (s<=0xFFFF) { \
- append_i_byte(0xE0 + (s / 0x1000)); \
- append_i_byte(0x80 + ((s % 0x1000) / 0x40)); \
- append_i_byte(0x80 + ((s % 0x1000) % 0x40)); \
- } else if (s>=0x110000) { \
- append_i_byte(s-0x11000); \
- } else { \
- append_i_byte(0xF0 + (s / 0x40000)); \
- append_i_byte(0x80 + ((s % 0x40000) / 0x1000)); \
- append_i_byte(0x80 + (((s % 0x40000) % 0x1000) / 0x40)); \
- append_i_byte(0x80 + (((s % 0x40000) % 0x1000) % 0x40)); \
- } }
-
-#define Print_esc(b) { \
- const char *v = b; \
- if (e>0 && e<STRING_OFFSET) { \
- Print_uchar (e); \
- } \
- make_room(strlen(v)); \
- while (*v) { append_i_byte(*v); v++; } \
- }
-
-#define Print_str(b) { \
- const char *v = b; \
- make_room(strlen(v)); \
- while (*v) { append_i_byte(*v); v++; } \
- }
-
-#define is_cat_letter(a) \
- (get_char_cat_code(pool_to_unichar(str_string((a)))) == 11)
-
-/*tex
-
- The actual token conversion in this function is now functionally equivalent
- to |show_token_list|, except that it always prints the whole token list.
- TODO: check whether this causes problems in the lua library.
-
-*/
-
-char *tokenlist_to_cstring(int pp, int inhibit_par, int *siz)
-{
- register int p, c, m;
- int q;
- int infop;
- char *s, *sh;
- int e = 0;
- char *ret;
- int match_chr = '#';
- int n = '0';
- unsigned alloci = alloci_default;
- int i = 0;
- p = pp;
- if (p == null) {
- if (siz != NULL)
- *siz = 0;
- return NULL;
- }
- ret = xmalloc(alloci);
- /*tex Skip refcount. */
- p = token_link(p);
- if (p != null) {
- e = escape_char_par;
- }
- while (p != null) {
- if (p < (int) fix_mem_min || p > (int) fix_mem_end) {
- Print_esc("CLOBBERED.");
- break;
- }
- infop = token_info(p);
- if (infop >= cs_token_flag) {
- if (!(inhibit_par && infop == par_token)) {
- q = infop - cs_token_flag;
- if (q < hash_base) {
- if (q == null_cs) {
- Print_esc("csname");
- Print_esc("endcsname");
- } else {
- Print_esc("IMPOSSIBLE.");
- }
- } else if ((q >= undefined_control_sequence) && ((q <= eqtb_size) || (q > eqtb_size + hash_extra))) {
- Print_esc("IMPOSSIBLE.");
- } else if ((cs_text(q) < 0) || (cs_text(q) >= str_ptr)) {
- Print_esc("NONEXISTENT.");
- } else {
- str_number txt = cs_text(q);
- sh = makecstring(txt);
- s = sh;
- if (is_active_cs(txt)) {
- s = s + 3;
- while (*s) {
- Print_char(*s);
- s++;
- }
- } else {
- if (e>=0 && e<0x110000) Print_uchar(e);
- while (*s) {
- Print_char(*s);
- s++;
- }
- if ((!single_letter(txt)) || is_cat_letter(txt)) {
- Print_char(' ');
- }
- }
- free(sh);
- }
- }
- } else {
- if (infop < 0) {
- Print_esc("BAD");
- } else {
- m = token_cmd(infop);
- c = token_chr(infop);
- switch (m) {
- case left_brace_cmd:
- case right_brace_cmd:
- case math_shift_cmd:
- case tab_mark_cmd:
- case sup_mark_cmd:
- case sub_mark_cmd:
- case spacer_cmd:
- case letter_cmd:
- case other_char_cmd:
- Print_uchar(c);
- break;
- case mac_param_cmd:
- if (!in_lua_escape && (is_in_csname==0))
- Print_uchar(c);
- Print_uchar(c);
- break;
- case out_param_cmd:
- Print_uchar(match_chr);
- if (c <= 9) {
- Print_char(c + '0');
- } else {
- Print_char('!');
- goto EXIT;
- }
- break;
- case match_cmd:
- match_chr = c;
- Print_uchar(c);
- n++;
- Print_char(n);
- if (n > '9')
- goto EXIT;
- break;
- case end_match_cmd:
- if (c == 0) {
- Print_char('-');
- Print_char('>');
- }
- break;
- default:
- not_so_bad(Print_esc);
- break;
- }
- }
- }
- p = token_link(p);
- }
- EXIT:
- ret[i] = '\0';
- if (siz != NULL)
- *siz = i;
- return ret;
-}
-
-char *tokenlist_to_xstring(int pp, int inhibit_par, int *siz)
-{
- register int p, c, m;
- int q;
- int infop;
- char *s, *sh;
- int e = 0;
- char *ret;
- int match_chr = '#';
- int n = '0';
- unsigned alloci = alloci_default;
- int i = 0;
- int skipping = 1;
- p = pp;
- if (p == null) {
- if (siz != NULL)
- *siz = 0;
- return NULL;
- }
- ret = xmalloc(alloci);
- /*tex Skip refcount. */
- p = token_link(p);
- if (p != null) {
- e = escape_char_par;
- }
- while (p != null) {
- if (p < (int) fix_mem_min || p > (int) fix_mem_end) {
- /*tex Nothing done. */
- break;
- }
- infop = token_info(p);
- if (infop >= cs_token_flag) {
- if (!(inhibit_par && infop == par_token)) {
- q = infop - cs_token_flag;
- if (q < hash_base) {
- /*tex Nothing done. */
- } else if ((q >= undefined_control_sequence) && ((q <= eqtb_size) || (q > eqtb_size + hash_extra))) {
- /*tex Nothing done. */
- } else if ((cs_text(q) < 0) || (cs_text(q) >= str_ptr)) {
- /*tex Nothing done. */
- } else if (!skipping) {
- str_number txt = cs_text(q);
- sh = makecstring(txt);
- s = sh;
- if (is_active_cs(txt)) {
- s = s + 3;
- while (*s) {
- Print_char(*s);
- s++;
- }
- } else {
- if (e>=0 && e<0x110000) Print_uchar(e);
- while (*s) {
- Print_char(*s);
- s++;
- }
- if ((!single_letter(txt)) || is_cat_letter(txt)) {
- Print_char(' ');
- }
- }
- free(sh);
- }
- }
- } else {
- if (infop < 0) {
- /*tex Nothing done. */
- } else {
- m = token_cmd(infop);
- c = token_chr(infop);
- switch (m) {
- case left_brace_cmd:
- case right_brace_cmd:
- case math_shift_cmd:
- case tab_mark_cmd:
- case sup_mark_cmd:
- case sub_mark_cmd:
- case spacer_cmd:
- case letter_cmd:
- case other_char_cmd:
- if (!skipping) {
- Print_uchar(c);
- }
- break;
- case mac_param_cmd:
- if (!skipping) {
- if (!in_lua_escape && (is_in_csname==0))
- Print_uchar(c);
- Print_uchar(c);
- }
- break;
- case out_param_cmd:
- if (!skipping) {
- Print_uchar(match_chr);
- }
- if (c <= 9) {
- if (!skipping) {
- Print_char(c + '0');
- }
- } else {
- /*tex Nothing done. */
- goto EXIT;
- }
- break;
- case match_cmd:
- match_chr = c;
- if (!skipping) {
- Print_uchar(c);
- }
- n++;
- if (!skipping) {
- Print_char(n);
- }
- if (n > '9')
- goto EXIT;
- break;
- case end_match_cmd:
- if (c == 0) {
- if (!skipping) {
- Print_char('-');
- Print_char('>');
- }
- i = 0;
- skipping = 0 ;
- }
- break;
- default:
- /*tex Nothing done. */
- break;
- }
- }
- }
- p = token_link(p);
- }
- EXIT:
- ret[i] = '\0';
- if (siz != NULL)
- *siz = i;
- return ret;
-}
-
-lstring *tokenlist_to_lstring(int pp, int inhibit_par)
-{
- int siz;
- lstring *ret = xmalloc(sizeof(lstring));
- ret->s = (unsigned char *) tokenlist_to_cstring(pp, inhibit_par, &siz);
- ret->l = (size_t) siz;
- return ret;
-}
-
-void free_lstring(lstring * ls)
-{
- if (ls == NULL)
- return;
- if (ls->s != NULL)
- free(ls->s);
- free(ls);
-}
diff --git a/Build/source/texk/web2c/luatexdir/tex/textoken.h b/Build/source/texk/web2c/luatexdir/tex/textoken.h
deleted file mode 100644
index 248a12168cf..00000000000
--- a/Build/source/texk/web2c/luatexdir/tex/textoken.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/* textoken.h
-
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
-
- This file is part of LuaTeX.
-
- LuaTeX is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- LuaTeX is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License along
- with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef TEXTOKEN_H
-# define TEXTOKEN_H
-
-# define token_list 0
-# define null 0
-# define cs_token_flag 0x1FFFFFFF
-
-# define left_brace_token 0x0200000 /* $2^{21}\cdot|left_brace|$ */
-# define right_brace_token 0x0400000 /* $2^{21}\cdot|right_brace|$ */
-# define left_brace_limit 0x0400000 /* $2^{21}\cdot(|left_brace|+1)$ */
-# define right_brace_limit 0x0600000 /* $2^{21}\cdot(|right_brace|+1)$ */
-# define math_shift_token 0x0600000 /* $2^{21}\cdot|math_shift|$ */
-# define tab_token 0x0800000 /* $2^{21}\cdot|tab_mark|$ */
-# define out_param_token 0x0A00000 /* $2^{21}\cdot|out_param|$ */
-# define space_token 0x1400020 /* $2^{21}\cdot|spacer|+|" "|$ */
-# define letter_token 0x1600000 /* $2^{21}\cdot|letter|$ */
-# define other_token 0x1800000 /* $2^{21}\cdot|other_char|$ */
-# define match_token 0x1A00000 /* $2^{21}\cdot|match|$ */
-# define end_match_token 0x1C00000 /* $2^{21}\cdot|end_match|$ */
-# define protected_token 0x1C00001 /* $2^{21}\cdot|end_match|+1$ */
-
-# include "tex/stringpool.h"
-
-typedef struct smemory_word_ {
-# ifdef WORDS_BIGENDIAN
- halfword hhrh;
- halfword hhlh;
-# else
- halfword hhlh;
- halfword hhrh;
-# endif
-} smemory_word;
-
-# define fix_mem_init 10000
-
-extern smemory_word *fixmem;
-extern unsigned fix_mem_min;
-extern unsigned fix_mem_max;
-
-extern halfword garbage; /* head of a junk list, write only */
-extern halfword temp_token_head; /* head of a temporary list of some kind */
-extern halfword hold_token_head; /* head of a temporary list of another kind */
-extern halfword omit_template; /* a constant token list */
-extern halfword null_list; /* permanently empty list */
-extern halfword backup_head; /* head of token list built by |scan_keyword| */
-
-extern void initialize_tokens(void);
-
-extern int dyn_used;
-
-# define token_info(a) fixmem[(a)].hhlh
-# define token_link(a) fixmem[(a)].hhrh
-# define set_token_info(a,b) fixmem[(a)].hhlh=(b)
-# define set_token_link(a,b) fixmem[(a)].hhrh=(b)
-
-extern halfword avail; /* head of the list of available one-word nodes */
-extern unsigned fix_mem_end; /* the last one-word node used in |mem| */
-
-extern halfword get_avail(void);
-
-/* A one-word node is recycled by calling |free_avail|.
-This routine is part of \TeX's ``inner loop,'' so we want it to be fast.
-*/
-
-# define free_avail(A) do { /* single-word node liberation */ \
- token_link(A)=avail; avail=(A); decr(dyn_used); \
- } while (0)
-
-/*
-There's also a |fast_get_avail| routine, which saves the procedure-call
-overhead at the expense of extra programming. This routine is used in
-the places that would otherwise account for the most calls of |get_avail|.
-*/
-
-# define fast_get_avail(A) do { \
- (A)=avail; /* avoid |get_avail| if possible, to save time */ \
- if ((A)==null) { (A)=get_avail(); } \
- else { avail=token_link((A)); token_link((A))=null; incr(dyn_used); } \
- } while (0)
-
-extern void print_meaning(void);
-
-extern void flush_list(halfword p);
-extern void show_token_list(int p, int q, int l);
-extern void token_show(halfword p);
-
-# define token_ref_count(a) token_info((a)) /* reference count preceding a token list */
-# define set_token_ref_count(a,b) token_info((a))=b
-# define add_token_ref(a) token_ref_count(a)++ /* new reference to a token list */
-
-# define store_new_token(a) do { \
- q=get_avail(); token_link(p)=q; token_info(q)=(a); p=q; \
- } while (0)
-
-# define fast_store_new_token(a) do { \
- fast_get_avail(q); token_link(p)=q; token_info(q)=(a); p=q; \
- } while (0)
-
-extern void delete_token_ref(halfword p);
-
-extern void make_token_table(lua_State * L, int cmd, int chr, int cs);
-
-# define NO_CAT_TABLE -2
-# define DEFAULT_CAT_TABLE -1
-
-extern void get_next(void);
-extern void check_outer_validity(void);
-extern boolean scan_keyword(const char *);
-extern boolean scan_keyword_case_sensitive(const char *);
-extern halfword active_to_cs(int, int);
-extern void get_token_lua(void);
-halfword string_to_toks(const char *);
-extern int get_char_cat_code(int);
-
-/*
-|no_expand_flag| is a special character value that is inserted by
-|get_next| if it wants to suppress expansion.
-*/
-
-# define no_expand_flag special_char
-
-extern halfword par_loc;
-extern halfword par_token;
-extern boolean force_eof;
-extern int luacstrings;
-
-extern void firm_up_the_line(void);
-extern void get_token(void);
-
-extern halfword str_toks(lstring b);
-extern halfword str_scan_toks(int c, lstring b);
-extern void ins_the_toks(void);
-extern void combine_the_toks(void);
-
-extern int scan_lua_state(void);
-
-extern void conv_toks(void);
-extern str_number the_convert_string(halfword c, int i);
-extern void do_variable(void);
-extern void do_feedback(void);
-extern void do_mathoption(void);
-
-extern halfword lua_str_toks(lstring b);
-extern boolean in_lua_escape;
-
-# define closed 2 /* not open, or at end of file */
-# define just_open 1 /* newly opened, first line not yet read */
-
-extern FILE *read_file[16]; /* used for \.{\\read} */
-extern int read_open[17]; /* state of |read_file[n]| */
-
-extern void initialize_read(void);
-
-extern void read_toks(int n, halfword r, halfword j);
-
-extern str_number tokens_to_string(halfword p); /* return a string from tokens list */
-
-extern char *tokenlist_to_xstring(int p, int inhibit_par, int *siz);
-extern char *tokenlist_to_cstring(int p, int inhibit_par, int *siz);
-extern lstring *tokenlist_to_lstring(int pp, int inhibit_par);
-extern void free_lstring(lstring * ls);
-
-# define token_cmd(A) ((A) >> STRING_OFFSET_BITS)
-# define token_chr(A) ((A) & (STRING_OFFSET - 1))
-# define token_val(A,B) (((A)<<STRING_OFFSET_BITS)+(B))
-
-extern void l_set_token_data(void) ;
-
-#endif