w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ltexlib.c
Go to the documentation of this file.
1 /* ltexlib.c
2 
3  Copyright 2006-2012 Taco Hoekwater <taco@luatex.org>
4 
5  This file is part of LuaTeX.
6 
7  LuaTeX is free software; you can redistribute it and/or modify it under
8  the terms of the GNU General Public License as published by the Free
9  Software Foundation; either version 2 of the License, or (at your
10  option) any later version.
11 
12  LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License for more details.
16 
17  You should have received a copy of the GNU General Public License along
18  with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
19 
20 /* hh-ls: Because the lists start with a temp node, we have to set the prev link
21 to nil because otherwise at the lua end we expose temp which can create havoc. In the
22 setter no prev link is created so we can presume that it's not used later on. */
23 
24 #include "ptexlib.h"
25 #include "lua/luatex-api.h"
26 
27 /* tex random generators */
28 extern int unif_rand(int );
29 extern int norm_rand(void );
30 extern void init_randoms(int );
31 
32 typedef struct {
33  char *text;
34  unsigned int tsize;
35  void *next;
36  boolean partial;
37  int cattable;
40 } rope;
41 
42 typedef struct {
45  char complete; /* currently still writing ? */
46 } spindle;
47 
48 #define PARTIAL_LINE 1
49 #define FULL_LINE 0
50 
51 #define write_spindle spindles[spindle_index]
52 #define read_spindle spindles[(spindle_index-1)]
53 
54 static int spindle_size = 0;
55 static spindle *spindles = NULL;
56 static int spindle_index = 0;
57 
58 static int luac_store(lua_State * L, int i, int partial, int cattable)
59 {
60  char *st = NULL;
61  size_t tsize = 0;
62  rope *rn = NULL;
63  halfword tok = null;
64  halfword nod = null;
65  int t = lua_type(L, i);
66  if (t == LUA_TNUMBER || t == LUA_TSTRING) {
67  const char *sttemp;
68  sttemp = lua_tolstring(L, i, &tsize);
69  st = xmalloc((unsigned) (tsize + 1));
70  memcpy(st, sttemp, (tsize + 1));
71  } else if (t == LUA_TUSERDATA) {
72  void *p ;
73  p = lua_touserdata(L, i);
74  if (p == NULL) {
75  return 0;
76  } else if (lua_getmetatable(L, i)) {
77  lua_get_metatablelua(luatex_token);
78  if (lua_rawequal(L, -1, -2)) {
79  tok = (halfword) token_info((*((lua_token *)p)).token);
80  lua_pop(L, 2);
81  } else {
82  lua_get_metatablelua(luatex_node);
83  if (lua_rawequal(L, -1, -3)) {
84  nod = *((halfword *)p);
85  lua_pop(L, 3);
86  } else {
87  lua_pop(L, 3);
88  return 0;
89  }
90  }
91  } else {
92  return 0;
93  }
94  } else {
95  return 0;
96  }
97  /* common */
98  luacstrings++;
99  rn = (rope *) xmalloc(sizeof(rope));
100  rn->text = st;
101  rn->tsize = (unsigned) tsize;
102  rn->tok = tok;
103  rn->nod = nod;
104  rn->next = NULL;
105  rn->partial = partial;
106  rn->cattable = cattable;
107  /* add */
108  if (write_spindle.head == NULL) {
109  write_spindle.head = rn;
110  } else {
111  write_spindle.tail->next = rn;
112  }
113  write_spindle.tail = rn;
114  write_spindle.complete = 0;
115  return 1;
116 }
117 
118 static int do_luacprint(lua_State * L, int partial, int deftable)
119 {
120  int cattable = deftable;
121  int startstrings = 1;
122  int n = lua_gettop(L);
123  if (cattable != NO_CAT_TABLE) {
124  if (lua_type(L, 1) == LUA_TNUMBER && n > 1) {
125  cattable = lua_tointeger(L, 1);
126  startstrings = 2;
127  if (cattable != -1 && cattable != -2 && !valid_catcode_table(cattable)) {
128  cattable = DEFAULT_CAT_TABLE;
129  }
130  }
131  }
132  if (lua_type(L, startstrings) == LUA_TTABLE) {
133  int i;
134  for (i = 1;; i++) {
135  lua_rawgeti(L, startstrings, i);
136  if (luac_store(L, -1, partial, cattable)) {
137  lua_pop(L, 1);
138  } else {
139  lua_pop(L, 1);
140  break;
141  }
142  }
143  } else {
144  int i;
145  for (i = startstrings; i <= n; i++) {
146  luac_store(L, i, partial, cattable);
147  }
148  }
149  return 0;
150 }
151 
152 /* lua.write */
153 
154 static int luacwrite(lua_State * L)
155 {
157 }
158 
159 /* lua.print */
160 
161 static int luacprint(lua_State * L)
162 {
164 }
165 
166 /* lua.sprint */
167 
168 static int luacsprint(lua_State * L)
169 {
171 }
172 
173 /* lua.cprint */
174 
175 static int luaccprint(lua_State * L)
176 {
177  /* so a negative value is a specific catcode with offset 1 */
178  int cattable = lua_tointeger(L,1);
179  if (cattable < 0 || cattable > 15) {
180  cattable = - 12 - 0xFF ;
181  } else {
182  cattable = - cattable - 0xFF;
183  }
184  if (lua_type(L, 2) == LUA_TTABLE) {
185  int i;
186  for (i = 1;; i++) {
187  lua_rawgeti(L, 2, i);
188  if (luac_store(L, -1, PARTIAL_LINE, cattable)) {
189  lua_pop(L, 1);
190  } else {
191  lua_pop(L, 1);
192  break;
193  }
194  }
195  } else {
196  int i;
197  int n = lua_gettop(L);
198  for (i = 2; i <= n; i++) {
199  luac_store(L, i, PARTIAL_LINE, cattable);
200  }
201  }
202  return 0;
203 }
204 
205 /* lua.tprint */
206 
207 static int luactprint(lua_State * L)
208 {
209  int i, j;
210  int cattable, startstrings;
211  int n = lua_gettop(L);
212  for (i = 1; i <= n; i++) {
213  cattable = DEFAULT_CAT_TABLE;
214  startstrings = 1;
215  if (lua_type(L, i) != LUA_TTABLE) {
216  luaL_error(L, "no string to print");
217  }
218  lua_pushvalue(L, i); /* push the table */
219  lua_pushinteger(L, 1);
220  lua_gettable(L, -2);
221  if (lua_type(L, -1) == LUA_TNUMBER) {
222  cattable = lua_tointeger(L, -1);
223  startstrings = 2;
224  if (cattable != -1 && cattable != -2 && !valid_catcode_table(cattable)) {
225  cattable = DEFAULT_CAT_TABLE;
226  }
227  }
228  lua_pop(L, 1);
229  for (j = startstrings;; j++) {
230  lua_pushinteger(L, j);
231  lua_gettable(L, -2);
232  if (luac_store(L, -1, PARTIAL_LINE, cattable)) {
233  lua_pop(L, 1);
234  } else {
235  lua_pop(L, 1);
236  break;
237  }
238  }
239  lua_pop(L, 1); /* pop the table */
240  }
241  return 0;
242 }
243 
245 {
246  return (int) read_spindle.tail->cattable;
247 }
248 
250 {
251  return read_spindle.tail->partial;
252 }
253 
255 {
256  return (read_spindle.tail->next == NULL);
257 }
258 
260 {
261  rope *t = read_spindle.head;
262  int ret = 1 ;
263  if (!read_spindle.complete) {
264  read_spindle.complete = 1;
265  read_spindle.tail = NULL;
266  }
267  if (t == NULL) {
268  if (read_spindle.tail != NULL)
269  free(read_spindle.tail);
270  read_spindle.tail = NULL;
271  return 0;
272  }
273  if (t->text != NULL) {
274  /* put that thing in the buffer */
275  char *st = t->text;
276  int ret = first;
277  last = first;
278  check_buffer_overflow(last + (int) t->tsize);
279  while (t->tsize-- > 0)
280  buffer[last++] = (packed_ASCII_code) * st++;
281  if (!t->partial) {
282  while (last - 1 > ret && buffer[last - 1] == ' ')
283  last--;
284  }
285  free(t->text);
286  t->text = NULL;
287  } else if (t->tok > 0) {
288  *n = t->tok;
289  ret = 2;
290  } else if (t->nod > 0) {
291  *n = t->nod;
292  ret = 3;
293  }
294  if (read_spindle.tail != NULL) {
295  /* not a one-liner */
296  free(read_spindle.tail);
297  }
298  read_spindle.tail = t;
299  read_spindle.head = t->next;
300  return ret;
301 }
302 
303 /* open for reading, and make a new one for writing */
304 
306 {
307  (void) n; /* for -W */
308  spindle_index++;
309  if (spindle_size == spindle_index) {
310  /* add a new one */
311  spindles = xrealloc(spindles, (unsigned) (sizeof(spindle) * (unsigned) (spindle_size + 1)));
315  spindle_size++;
316  }
317 }
318 
319 /* close for reading */
320 
322 {
323  rope *next, *t;
324  (void) n; /* for -W */
325  next = read_spindle.head;
326  while (next != NULL) {
327  if (next->text != NULL)
328  free(next->text);
329  t = next;
330  next = next->next;
331  if (t==read_spindle.tail) {
332  read_spindle.tail = NULL;
333  }
334  free(t);
335  }
336  read_spindle.head = NULL;
337  if (read_spindle.tail != NULL)
338  free(read_spindle.tail);
339  read_spindle.tail = NULL;
340  read_spindle.complete = 0;
341  spindle_index--;
342 }
343 
344 /* local (static) versions */
345 
346 #define check_index_range(j,s) \
347  if (j<0 || j > 65535) { \
348  luaL_error(L, "incorrect index specification for tex.%s()", s); }
349 
350 #define check_register(base) do { \
351  int k = get_item_index(L, lua_gettop(L), base); \
352  if ((k>=0) && (k <= 65535)) { \
353  lua_pushinteger(L,k); \
354  } else { \
355  lua_pushboolean(L,false); \
356  } \
357  return 1; \
358 } while (1)
359 
360 static const char *scan_integer_part(lua_State * L, const char *ss, int *ret, int *radix_ret)
361 {
362  boolean negative = false; /* should the answer be negated? */
363  int m = 214748364; /* |$2^{31}$ / radix|, the threshold of danger */
364  int d; /* the digit just scanned */
365  boolean vacuous = true; /* have no digits appeared? */
366  boolean OK_so_far = true; /* has an error message been issued? */
367  int radix1 = 10; /* the radix of the integer */
368  int c = 0; /* the current character */
369  const char *s; /* where we stopped in the string |ss| */
370  integer val = 0; /* return value */
371  s = ss;
372  do {
373  do {
374  c = *s++;
375  } while (c && c == ' ');
376  if (c == '-') {
377  negative = !negative;
378  c = '+';
379  }
380  } while (c == '+');
381  if (c == '\'') {
382  radix1 = 8;
383  m = 02000000000;
384  c = *s++;
385  } else if (c == '"') {
386  radix1 = 16;
387  m = 01000000000;
388  c = *s++;
389  }
390  /* Accumulate the constant until |cur_tok| is not a suitable digit */
391  while (1) {
392  if ((c < '0' + radix1) && (c >= '0') && (c <= '0' + 9)) {
393  d = c - '0';
394  } else if (radix1 == 16) {
395  if ((c <= 'A' + 5) && (c >= 'A')) {
396  d = c - 'A' + 10;
397  } else if ((c <= 'a' + 5) && (c >= 'a')) {
398  d = c - 'a' + 10;
399  } else {
400  break;
401  }
402  } else {
403  break;
404  }
405  vacuous = false;
406  if ((val >= m) && ((val > m) || (d > 7) || (radix1 != 10))) {
407  if (OK_so_far) {
408  luaL_error(L, "Number too big");
409  val = infinity;
410  OK_so_far = false;
411  }
412  } else {
413  val = val * radix1 + d;
414  }
415  c = *s++;
416  }
417  if (vacuous) {
418  /* Express astonishment that no number was here */
419  luaL_error(L, "Missing number, treated as zero");
420  }
421  if (negative)
422  val = -val;
423  *ret = val;
424  *radix_ret = radix1;
425  if (c != ' ' && s > ss)
426  s--;
427  return s;
428 }
429 
430 #define set_conversion(A,B) do { num=(A); denom=(B); } while(0)
431 
432 /* sets |cur_val| to a dimension */
433 
434 static const char *scan_dimen_part(lua_State * L, const char *ss, int *ret)
435 {
436  boolean negative = false; /* should the answer be negated? */
437  int f = 0; /* numerator of a fraction whose denominator is $2^{16}$ */
438  int num, denom; /* conversion ratio for the scanned units */
439  int k; /* number of digits in a decimal fraction */
440  scaled v; /* an internal dimension */
441  int save_cur_val; /* temporary storage of |cur_val| */
442  int c; /* the current character */
443  const char *s = ss; /* where we are in the string */
444  int radix1 = 0; /* the current radix */
445  int rdig[18]; /* to save the |dig[]| array */
446  int saved_tex_remainder; /* to save |tex_remainder| */
447  int saved_arith_error; /* to save |arith_error| */
448  int saved_cur_val; /* to save the global |cur_val| */
449  saved_tex_remainder = tex_remainder;
450  saved_arith_error = arith_error;
451  saved_cur_val = cur_val;
452  /* get the next non-blank non-sign */
453  do {
454  /* get the next non-blank non-call token */
455  do {
456  c = *s++;
457  } while (c && c == ' ');
458  if (c == '-') {
459  negative = !negative;
460  c = '+';
461  }
462  } while (c == '+');
463  if (c == ',') {
464  c = '.';
465  }
466  if (c != '.') {
467  s = scan_integer_part(L, (s > ss ? (s - 1) : ss), &cur_val, &radix1);
468  c = *s;
469  } else {
470  radix1 = 10;
471  cur_val = 0;
472  c = *(--s);
473  }
474  if (c == ',')
475  c = '.';
476  if ((radix1 == 10) && (c == '.')) {
477  /* scan decimal fraction */
478  for (k = 0; k < 18; k++)
479  rdig[k] = dig[k];
480  k = 0;
481  s++;
482  /* get rid of the '.' */
483  while (1) {
484  c = *s++;
485  if ((c > '0' + 9) || (c < '0'))
486  break;
487  if (k < 17) {
488  /* digits for |k>=17| cannot affect the result */
489  dig[k++] = c - '0';
490  }
491  }
492  f = round_decimals(k);
493  if (c != ' ')
494  c = *(--s);
495  for (k = 0; k < 18; k++)
496  dig[k] = rdig[k];
497  }
498  if (cur_val < 0) { /* in this case |f=0| */
499  negative = !negative;
500  cur_val = -cur_val;
501  }
502  /*
503  Scan for (u)units that are internal dimensions; |goto attach_sign| with
504  |cur_val| set if found.
505  */
506  save_cur_val = cur_val;
507  /* Get the next non-blank non-call... */
508  do {
509  c = *s++;
510  } while (c && c == ' ');
511  if (c != ' ')
512  c = *(--s);
513  if (strncmp(s, "em", 2) == 0) {
514  s += 2;
515  v = (quad(get_cur_font()));
516  } else if (strncmp(s, "ex", 2) == 0) {
517  s += 2;
518  v = (x_height(get_cur_font()));
519  } else if (strncmp(s, "px", 2) == 0) {
520  s += 2;
521  v = px_dimen_par;
522  } else {
523  goto NOT_FOUND;
524  }
525  c = *s++;
526  if (c != ' ') {
527  c = *(--s);
528  }
529  cur_val = nx_plus_y(save_cur_val, v, xn_over_d(v, f, 0200000));
530  goto ATTACH_SIGN;
531  NOT_FOUND:
532  /* Scan for (m)\.{mu} units and |goto attach_fraction| */
533  if (strncmp(s, "mu", 2) == 0) {
534  s += 2;
535  goto ATTACH_FRACTION;
536  }
537  if (strncmp(s, "true", 4) == 0) {
538  /* Adjust (f)for the magnification ratio */
539  s += 4;
540  if (output_mode_used <= OMODE_DVI) {
541  prepare_mag();
542  if (mag_par != 1000) {
543  cur_val = xn_over_d(cur_val, 1000, mag_par);
544  f = (1000 * f + 0200000 * tex_remainder) / mag_par;
545  cur_val = cur_val + (f / 0200000);
546  f = f % 0200000;
547  }
548  }
549  do {
550  c = *s++;
551  } while (c && c == ' ');
552  c = *(--s);
553  }
554  if (strncmp(s, "pt", 2) == 0) {
555  s += 2;
556  goto ATTACH_FRACTION; /* the easy case */
557  }
558  /*
559  Scan for (a)all other units and adjust |cur_val| and |f| accordingly; |goto done|
560  in the case of scaled points
561  */
562  if (strncmp(s, "mm", 2) == 0) {
563  s += 2;
564  set_conversion(7227, 2540);
565  } else if (strncmp(s, "cm", 2) == 0) {
566  s += 2;
567  set_conversion(7227, 254);
568  } else if (strncmp(s, "sp", 2) == 0) {
569  s += 2;
570  goto DONE;
571  } else if (strncmp(s, "bp", 2) == 0) {
572  s += 2;
573  set_conversion(7227, 7200);
574  } else if (strncmp(s, "in", 2) == 0) {
575  s += 2;
576  set_conversion(7227, 100);
577  } else if (strncmp(s, "dd", 2) == 0) {
578  s += 2;
579  set_conversion(1238, 1157);
580  } else if (strncmp(s, "cc", 2) == 0) {
581  s += 2;
582  set_conversion(14856, 1157);
583  } else if (strncmp(s, "pc", 2) == 0) {
584  s += 2;
585  set_conversion(12, 1);
586  } else if (strncmp(s, "nd", 2) == 0) {
587  s += 2;
588  set_conversion(685, 642);
589  } else if (strncmp(s, "nc", 2) == 0) {
590  s += 2;
591  set_conversion(1370, 107);
592  } else {
593  /* Complain about unknown unit and |goto done2| */
594  luaL_error(L, "Illegal unit of measure (pt inserted)");
595  goto DONE2;
596  }
597  cur_val = xn_over_d(cur_val, num, denom);
598  f = (num * f + 0200000 * tex_remainder) / denom;
599  cur_val = cur_val + (f / 0200000);
600  f = f % 0200000;
601  DONE2:
602  ATTACH_FRACTION:
603  if (cur_val >= 040000)
604  arith_error = true;
605  else
606  cur_val = cur_val * 65536 + f;
607  DONE:
608  /* Scan an optional space */
609  c = *s++;
610  if (c != ' ')
611  s--;
612  ATTACH_SIGN:
613  if (arith_error || (abs(cur_val) >= 010000000000)) {
614  /* Report that this dimension is out of range */
615  luaL_error(L, "Dimension too large");
616  cur_val = max_dimen;
617  }
618  if (negative)
619  cur_val = -cur_val;
620  *ret = cur_val;
621  tex_remainder = saved_tex_remainder;
622  arith_error = saved_arith_error;
623  cur_val = saved_cur_val;
624  return s;
625 }
626 
627 int dimen_to_number(lua_State * L, const char *s)
628 {
629  int j = 0;
630  const char *d = scan_dimen_part(L, s, &j);
631  if (*d) {
632  luaL_error(L, "conversion failed (trailing junk?)");
633  j = 0;
634  }
635  return j;
636 }
637 
639 {
640  int sp;
641  int t = lua_type(L, 1);
642  if (t == LUA_TNUMBER) {
643  sp = lua_roundnumber(L, 1);
644  } else if (t == LUA_TSTRING) {
646  } else {
647  luaL_error(L, "argument must be a string or a number");
648  return 0;
649  }
650  lua_pushinteger(L, sp);
651  return 1;
652 }
653 
654 static int texerror (lua_State * L)
655 {
656  const char **errhlp = NULL;
657  const char *error = luaL_checkstring(L,1);
658  int n = lua_gettop(L);
659  if (n==2 && lua_type(L, n) == LUA_TTABLE) {
660  int i;
661  int l = 1; /* |errhlp| is terminated by a NULL entry */
662  for (i = 1;; i++) {
663  lua_rawgeti(L, n, i);
664  if (lua_type(L,-1) == LUA_TSTRING) {
665  l++;
666  lua_pop(L, 1);
667  } else {
668  lua_pop(L, 1);
669  break;
670  }
671  }
672  if (l>1) {
673  errhlp = xmalloc(l * sizeof(char *));
674  memset(errhlp,0,l * sizeof(char *));
675  for (i = 1;; i++) {
676  lua_rawgeti(L, n, i);
677  if (lua_type(L,-1) == LUA_TSTRING) {
678  errhlp[(i-1)] = lua_tostring(L,-1);
679  lua_pop(L, 1);
680  } else {
681  break;
682  }
683  }
684  }
685  }
686  deletions_allowed = false;
687  tex_error(error, errhlp);
688  if (errhlp)
689  xfree(errhlp);
690  deletions_allowed = true;
691  return 0;
692 }
693 
694 static int get_item_index(lua_State * L, int i, int base)
695 {
696  size_t kk;
697  int k;
698  int cur_cs1;
699  const char *s;
700  switch (lua_type(L, i)) {
701  case LUA_TSTRING:
702  s = lua_tolstring(L, i, &kk);
703  cur_cs1 = string_lookup(s, kk);
704  if (cur_cs1 == undefined_control_sequence || cur_cs1 == undefined_cs_cmd)
705  k = -1; /* guarandeed invalid */
706  else
707  k = (equiv(cur_cs1) - base);
708  break;
709  case LUA_TNUMBER:
710  k = luaL_checkinteger(L, i);
711  break;
712  default:
713  luaL_error(L, "argument must be a string or a number");
714  k = -1; /* not a valid index */
715  }
716  return k;
717 }
718 
719 #define check_item_global(L,top,isglobal) \
720  if (top == 3 && (lua_type(L,1) == LUA_TSTRING)) { \
721  const char *s = lua_tostring(L, 1); \
722  if (lua_key_eq(s,global)) { \
723  isglobal = 1; \
724  } \
725  }
726 
727 #define set_item_index_plus(L, where, base, what, value, is_global, is_assign, set_register, glue) { \
728  size_t len; \
729  const char *str; \
730  int key, err, cs; \
731  int save_global_defs = global_defs_par; \
732  if (is_global) { \
733  global_defs_par = 1; \
734  } \
735  switch (lua_type(L, where)) { \
736  case LUA_TSTRING: \
737  str = lua_tolstring(L, where, &len); \
738  cs = string_lookup(str, len); \
739  if (cs == undefined_control_sequence || cs == undefined_cs_cmd) { \
740  luaL_error(L, "incorrect %s name", what); \
741  } else { \
742  key = equiv(cs) - base; \
743  if (key >= 0 && key <= 65535) { \
744  err = set_register(key, value); \
745  if (err) { \
746  luaL_error(L, "incorrect %s value", what); \
747  } \
748  } else if (is_assign(eq_type(cs))) { \
749  if (glue) { \
750  int a = is_global; \
751  define(equiv(cs), assign_glue_cmd, value); \
752  } else { \
753  assign_internal_value((is_global ? 4 : 0), equiv(cs), value); \
754  } \
755  } else { \
756  luaL_error(L, "incorrect %s name", what); \
757  } \
758  } \
759  break; \
760  case LUA_TNUMBER: \
761  key = luaL_checkinteger(L, where); \
762  if (key>=0 && key <= 65535) { \
763  err = set_register(key, value); \
764  if (err) { \
765  luaL_error(L, "incorrect %s value", what); \
766  } \
767  } else { \
768  luaL_error(L, "incorrect %s index", what); \
769  } \
770  break; \
771  default: \
772  luaL_error(L, "argument of 'set%s' must be a string or a number", what); \
773  } \
774  global_defs_par = save_global_defs; \
775 }
776 
777 static int gettex(lua_State * L);
778 
779 #define get_item_index_plus(L, where, base, what, value, is_assign, get_register, texget) { \
780  size_t len; \
781  const char *str; \
782  int key, cs; \
783  switch (lua_type(L, where)) { \
784  case LUA_TSTRING: \
785  str = lua_tolstring(L, where, &len); \
786  cs = string_lookup(str, len); \
787  if (cs == undefined_control_sequence || cs == undefined_cs_cmd) { \
788  luaL_error(L, "incorrect %s name", what); \
789  } else { \
790  key = equiv(cs) - base; \
791  if (key >= 0 && key <= 65535) { \
792  value = get_register(key); \
793  } else if (is_assign(eq_type(cs))) { \
794  texget = gettex(L); /* lazy */ \
795  } else { \
796  luaL_error(L, "incorrect %s name", what); \
797  } \
798  } \
799  break; \
800  case LUA_TNUMBER: \
801  key = luaL_checkinteger(L, where); \
802  if (key>=0 && key <= 65535) { \
803  value = get_register(key); \
804  } else { \
805  luaL_error(L, "incorrect %s index", what); \
806  } \
807  break; \
808  default: \
809  luaL_error(L, "argument of 'get%s' must be a string or a number", what); \
810  } \
811 }
812 
813 static int isdimen(lua_State * L)
814 {
816 }
817 
818 static int setdimen(lua_State * L)
819 {
820  int isglobal = 0;
821  int value = 0;
822  int top = lua_gettop(L);
823  int t = lua_type(L, top);
824  check_item_global(L,top,isglobal);
825  if (t == LUA_TNUMBER) {
827  } else if (t == LUA_TSTRING) {
829  } else {
830  luaL_error(L, "unsupported %s value type","dimen");
831  }
833  return 0;
834 }
835 
836 static int getdimen(lua_State * L)
837 {
838  int value = 0;
839  int texget = 0;
841  if (texget > 0) {
842  return texget;
843  }
845  return 1;
846 }
847 
848 static int isskip(lua_State * L)
849 {
851 }
852 
853 static int setskip(lua_State * L)
854 {
855  int isglobal = 0;
856  halfword *value = NULL;
857  int top = lua_gettop(L);
858  check_item_global(L,top,isglobal);
859  value = check_isnode(L, top);
860  if (type(*value) == glue_spec_node) {
862  } else {
863  luaL_error(L, "glue_spec expected");
864  }
865  return 0;
866 }
867 
868 static int getskip(lua_State * L)
869 {
870  int value = 0;
871  int texget = 0;
873  if (texget > 0) {
874  return texget;
875  }
876  if (value == null) {
878  } else {
880  }
881  return 1;
882 }
883 
884 static int setglue(lua_State * L)
885 {
886  int isglobal = 0;
887  int index = 1;
889  int top = lua_gettop(L);
890  check_item_global(L,top,isglobal);
891  if (isglobal) {
892  index = 2;
893  top -= 1;
894  }
895  /* [global] slot [width] [stretch] [shrink] [stretch_order] [shrink_order] */
896  if (top > 1) { width(value) = lua_roundnumber(L,index+1); }
897  if (top > 2) { stretch(value) = lua_roundnumber(L,index+2); }
898  if (top > 3) { shrink(value) = lua_roundnumber(L,index+3); }
899  if (top > 4) { stretch_order(value) = lua_tointeger(L,index+4); }
900  if (top > 5) { shrink_order(value) = lua_tointeger(L,index+5); }
902  return 0;
903 }
904 
905 static int getglue(lua_State * L)
906 {
907  int value = 0;
908  int texget = 0;
909  int top = lua_gettop(L);
910  int dim = -1;
911  if (top > 1 && lua_type(L,top) == LUA_TBOOLEAN) {
912  dim = lua_toboolean(L,top);
913  top = top - 1;
914  } else {
915  lua_pushboolean(L,1);
916  dim = 1 ;
917  /* no top adaption. somewhat messy, but the gettex fallback checks itself */
918  }
919  /* checks itself for the boolean */
921  if (texget > 0) {
922  return texget;
923  }
924  if (dim == 0) {
925  /* false */
926  if (value == null) {
927  lua_pushinteger(L,0);
928  } else {
930  }
931  return 1;
932  } else {
933  /* true and nil */
934  if (value == null) {
935  lua_pushinteger(L,0);
936  lua_pushinteger(L,0);
937  lua_pushinteger(L,0);
938  lua_pushinteger(L,0);
939  lua_pushinteger(L,0);
940  } else {
946  }
947  return 5;
948  }
949 }
950 
951 static int ismuskip(lua_State * L)
952 {
954 }
955 
956 static int setmuskip(lua_State * L)
957 {
958  int isglobal = 0;
959  halfword *value = NULL;
960  int top = lua_gettop(L);
961  check_item_global(L,top,isglobal);
962  value = check_isnode(L, top);
964  return 0;
965 }
966 
967 static int getmuskip(lua_State * L)
968 {
969  int value = 0;
970  int texget = 0;
972  if (texget > 0) {
973  return texget;
974  }
976  return 1;
977 }
978 
979 static int setmuglue(lua_State * L)
980 {
981  int isglobal = 0;
982  int index = 1;
984  int top = lua_gettop(L);
985  check_item_global(L,top,isglobal);
986  if (isglobal) {
987  index = 2;
988  top -= 1;
989  }
990  /* [global] slot [width] [stretch] [shrink] [stretch_order] [shrink_order] */
991  if (top > 1) { width(value) = lua_roundnumber(L,index+1); }
992  if (top > 2) { stretch(value) = lua_roundnumber(L,index+2); }
993  if (top > 3) { shrink(value) = lua_roundnumber(L,index+3); }
994  if (top > 4) { stretch_order(value) = lua_tointeger(L,index+4); }
995  if (top > 5) { shrink_order(value) = lua_tointeger(L,index+5); }
997  return 0;
998 }
999 
1000 static int getmuglue(lua_State * L)
1001 {
1002  int value = 0;
1003  int texget = 0;
1004  int top = lua_gettop(L);
1005  int dim = -1;
1006  if (top > 1 && lua_type(L,top) == LUA_TBOOLEAN) {
1007  dim = lua_toboolean(L,top);
1008  top = top - 1;
1009  } else {
1010  lua_pushboolean(L,1);
1011  dim = 1 ;
1012  /* no top adaption. somewhat messy, but the gettex fallback checks itself */
1013  }
1014  /* checks itself for the boolean */
1016  if (texget > 0) {
1017  return texget;
1018  }
1019  if (dim == 0) {
1020  /* false */
1021  if (value == null) {
1022  lua_pushinteger(L,0);
1023  } else {
1025  }
1026  return 1;
1027  } else {
1028  /* true and nil */
1029  if (value == null) {
1030  lua_pushinteger(L,0);
1031  lua_pushinteger(L,0);
1032  lua_pushinteger(L,0);
1033  lua_pushinteger(L,0);
1034  lua_pushinteger(L,0);
1035  } else {
1041  }
1042  return 5;
1043  }
1044 }
1045 
1046 static int iscount(lua_State * L)
1047 {
1049 }
1050 
1051 static int setcount(lua_State * L)
1052 {
1053  int t;
1054  int isglobal = 0;
1055  int value = 0;
1056  int top = lua_gettop(L);
1057  check_item_global(L,top,isglobal);
1058  t = lua_type(L,top);
1059  if (t == LUA_TNUMBER) {
1060  value = lua_tointeger(L, top);
1061  } else {
1062  luaL_error(L, "unsupported %s value type","count");
1063  }
1064  set_item_index_plus(L, top-1, count_base, "count", value, isglobal, is_int_assign, set_tex_count_register, false);
1065  return 0;
1066 }
1067 
1068 static int getcount(lua_State * L)
1069 {
1070  int value = 0;
1071  int texget = 0;
1073  if (texget > 0) {
1074  return texget;
1075  }
1077  return 1;
1078 }
1079 
1080 static int isattribute(lua_State * L)
1081 {
1083 }
1084 
1085 /* there are no system set attributes so this is a bit overkill */
1086 
1087 static int setattribute(lua_State * L)
1088 {
1089  int t;
1090  int isglobal = 0;
1091  int value = 0;
1092  int top = lua_gettop(L);
1093  check_item_global(L,top,isglobal);
1094  t = lua_type(L,top);
1095  if (t == LUA_TNUMBER) {
1096  value = lua_tointeger(L, top);
1097  } else {
1098  luaL_error(L, "unsupported %s value type","attribute");
1099  }
1101  return 0;
1102 }
1103 
1104 static int getattribute(lua_State * L)
1105 {
1106  int value = 0;
1107  int texget = 0;
1109  if (texget > 0) {
1110  return texget;
1111  }
1113  return 1;
1114 }
1115 
1116 /* todo: we can avoid memcpy as there is no need to go through the pool */
1117 
1118 /* use string_to_toks */
1119 
1120 static int istoks(lua_State * L)
1121 {
1123 }
1124 
1125 static int settoks(lua_State * L)
1126 {
1127  int i, err, k;
1128  lstring str;
1129  char *s;
1130  const char *ss;
1131  int is_global = 0;
1132  int save_global_defs = global_defs_par;
1133  int n = lua_gettop(L);
1134  if (n == 3 && (lua_type(L,1) == LUA_TSTRING)) {
1135  const char *s = lua_tostring(L, 1);
1136  if (lua_key_eq(s,global))
1137  is_global = 1;
1138  }
1139  if (is_global)
1140  global_defs_par = 1;
1141  i = lua_gettop(L);
1142  if (lua_type(L,i) != LUA_TSTRING) {
1143  luaL_error(L, "unsupported value type");
1144  }
1145  ss = lua_tolstring(L, i, &str.l);
1146  s = xmalloc (str.l+1);
1147  memcpy (s, ss, str.l+1);
1148  str.s = (unsigned char *)s;
1149  k = get_item_index(L, (i - 1), toks_base);
1150  check_index_range(k, "settoks");
1152  xfree(str.s);
1153  global_defs_par = save_global_defs;
1154  if (err) {
1155  luaL_error(L, "incorrect value");
1156  }
1157  return 0;
1158 }
1159 
1160 static int scantoks(lua_State * L)
1161 {
1162  int i, err, k, c;
1163  lstring str;
1164  char *s;
1165  const char *ss;
1166  int is_global = 0;
1167  int save_global_defs = global_defs_par;
1168  int n = lua_gettop(L);
1169  if (n == 4 && (lua_type(L,1) == LUA_TSTRING)) {
1170  const char *s = lua_tostring(L, 1);
1171  if (lua_key_eq(s,global))
1172  is_global = 1;
1173  }
1174  /* action : vsettokscct(L, is_global); */
1175  if (is_global)
1176  global_defs_par = 1;
1177  i = lua_gettop(L);
1178  if (lua_type(L,i) != LUA_TSTRING) {
1179  luaL_error(L, "unsupported value type");
1180  }
1181  ss = lua_tolstring(L, i, &str.l);
1182  s = xmalloc (str.l+1);
1183  memcpy (s, ss, str.l+1);
1184  str.s = (unsigned char *)s;
1185  k = get_item_index(L, (i - 2), toks_base);
1186  c = luaL_checkinteger(L, i - 1);
1187  check_index_range(k, "settoks");
1189  xfree(str.s);
1190  global_defs_par = save_global_defs;
1191  if (err) {
1192  luaL_error(L, "incorrect value");
1193  }
1194  return 0;
1195 }
1196 
1197 static int gettoks(lua_State * L)
1198 {
1199  char *ss;
1200  str_number t;
1201  int k = get_item_index(L, lua_gettop(L), toks_base);
1202  check_index_range(k, "gettoks");
1204  ss = makecstring(t);
1205  lua_pushstring(L, ss);
1206  free(ss);
1207  flush_str(t);
1208  return 1;
1209 }
1210 
1211 static int getmark(lua_State *L)
1212 {
1213  if (lua_gettop(L) == 0) {
1215  return 1;
1216  } else if (lua_type(L, 1) == LUA_TSTRING) {
1217  int num = luaL_optinteger(L, 2, 0);
1218  if (num >= 0 && num <= biggest_used_mark) {
1219  int ptr = null;
1220  const char *s = lua_tostring(L, 1);
1221  if (lua_key_eq(s, top)) {
1222  ptr = top_marks_array[num];
1223  } else if (lua_key_eq(s, first)) {
1225  } else if (lua_key_eq(s, bottom)) {
1226  ptr = bot_marks_array[num];
1227  } else if (lua_key_eq(s, splitfirst)) {
1229  } else if (lua_key_eq(s, splitbottom)) {
1231  }
1232  if (ptr) {
1233  char *str = tokenlist_to_cstring(ptr, 1, NULL);
1234  lua_pushstring(L, str);
1235  free(str);
1236  return 1;
1237  }
1238  }
1239  }
1240  lua_pushnil(L);
1241  return 1;
1242 }
1243 
1244 static int get_box_id(lua_State * L, int i, boolean report)
1245 {
1246  const char *s;
1247  int cur_cs1, cur_cmd1;
1248  size_t k = 0;
1249  int j = -1;
1250  switch (lua_type(L, i)) {
1251  case LUA_TSTRING:
1252  s = lua_tolstring(L, i, &k);
1253  cur_cs1 = string_lookup(s, k);
1254  cur_cmd1 = eq_type(cur_cs1);
1255  if (cur_cmd1 == char_given_cmd ||
1256  cur_cmd1 == math_given_cmd) {
1257  j = equiv(cur_cs1);
1258  }
1259  break;
1260  case LUA_TNUMBER:
1261  j = lua_tointeger(L, (i));
1262  break;
1263  default:
1264  if (report) {
1265  luaL_error(L, "argument must be a string or a number");
1266  }
1267  j = -1; /* not a valid box id */
1268  }
1269  return j;
1270 }
1271 
1272 static int getbox(lua_State * L)
1273 {
1274  int t;
1275  int k = get_box_id(L, -1, true);
1276  check_index_range(k, "getbox");
1278  nodelist_to_lua(L, t);
1279  return 1;
1280 }
1281 
1282 static int splitbox(lua_State * L)
1283 {
1284  const char *s;
1285  int k = get_box_id(L, 1, true);
1286  check_index_range(k, "splitbox");
1287  if (lua_isnumber(L, 2)) {
1288  int m = 1;
1289  if (lua_type(L, 3) == LUA_TSTRING) {
1290  s = lua_tostring(L, 3);
1291  if (lua_key_eq(s, exactly)) {
1292  m = 0;
1293  } else if (lua_key_eq(s, additional)) {
1294  m = 1;
1295  }
1296  } else if (lua_type(L, 3) == LUA_TNUMBER) {
1297  m = (int) lua_tointeger(L, 3);
1298  }
1299  if ((m<0) || (m>1)) {
1300  luaL_error(L, "wrong mode in splitbox");
1301  }
1303  } else {
1304  /* maybe a warning */
1305  lua_pushnil(L);
1306  }
1307  return 1;
1308 }
1309 
1310 static int isbox(lua_State * L)
1311 {
1312  int k = get_box_id(L, -1, false);
1313  lua_pushboolean(L,(k>=0 && k<=65535));
1314  return 1;
1315 }
1316 
1317 static int vsetbox(lua_State * L, int is_global)
1318 {
1319  int j, k, err, t;
1320  int save_global_defs;
1321  k = get_box_id(L, -2, true);
1322  check_index_range(k, "setbox");
1323  t = lua_type(L, -1);
1324  if (t == LUA_TBOOLEAN) {
1325  j = lua_toboolean(L, -1);
1326  if (j == 0) {
1327  j = null;
1328  } else {
1329  return 0;
1330  }
1331  } else if (t == LUA_TNIL) {
1332  j = null;
1333  } else {
1334  j = nodelist_from_lua(L,-1);
1335  if (j != null && type(j) != hlist_node && type(j) != vlist_node) {
1336  luaL_error(L, "setbox: incompatible node type (%s)\n", get_node_name(type(j), subtype(j)));
1337  return 0;
1338  }
1339  }
1340  save_global_defs = global_defs_par;
1341  if (is_global) {
1342  global_defs_par = 1;
1343  }
1345  global_defs_par = save_global_defs;
1346  if (err) {
1347  luaL_error(L, "incorrect value");
1348  }
1349  return 0;
1350 }
1351 
1352 static int setbox(lua_State * L)
1353 {
1354  int isglobal = 0;
1355  int n = lua_gettop(L);
1356  if (n == 3 && (lua_type(L,1) == LUA_TSTRING)) {
1357  const char *s = lua_tostring(L, 1);
1358  if (lua_key_eq(s,global))
1359  isglobal = 1;
1360  }
1361  return vsetbox(L, isglobal);
1362 }
1363 
1364 #define check_char_range(j,s,lim) \
1365  if (j<0 || j >= lim) { \
1366  luaL_error(L, "incorrect character value %d for tex.%s()", (int) j, s); \
1367  }
1368 
1369 static int setcode (lua_State *L, void (*setone)(int,halfword,quarterword),
1370  void (*settwo)(int,halfword,quarterword), const char *name, int lim)
1371 {
1372  int ch;
1373  halfword val, ucval;
1374  int level = cur_level;
1375  int n = lua_gettop(L);
1376  int f = 1;
1377  if (n>1 && lua_type(L,1) == LUA_TTABLE)
1378  f++;
1379  if (n>2 && (lua_type(L,f) == LUA_TSTRING)) {
1380  const char *s = lua_tostring(L, f);
1381  if (lua_key_eq(s,global)) {
1382  level = level_one;
1383  f++;
1384  }
1385  }
1386  ch = luaL_checkinteger(L, f);
1387  check_char_range(ch, name, 65536*17);
1388  val = (halfword) luaL_checkinteger(L, f+1);
1389  check_char_range(val, name, lim);
1390  (setone)(ch, val, level);
1391  if (settwo != NULL && n-f == 2) {
1392  ucval = (halfword) luaL_checkinteger(L, f+2);
1393  check_char_range(ucval, name, lim);
1394  (settwo)(ch, ucval, level);
1395  }
1396  return 0;
1397 }
1398 
1399 static int setlccode(lua_State * L)
1400 {
1401  return setcode(L, &set_lc_code, &set_uc_code, "setlccode", 65536*17);
1402 }
1403 
1404 static int getlccode(lua_State * L)
1405 {
1406  int ch = luaL_checkinteger(L, -1);
1407  check_char_range(ch, "getlccode", 65536*17);
1409  return 1;
1410 }
1411 
1412 static int setuccode(lua_State * L)
1413 {
1414  return setcode(L, &set_uc_code, &set_lc_code, "setuccode", 65536*17);
1415 }
1416 
1417 static int getuccode(lua_State * L)
1418 {
1419  int ch = luaL_checkinteger(L, -1);
1420  check_char_range(ch, "getuccode", 65536*17);
1422  return 1;
1423 }
1424 
1425 static int setsfcode(lua_State * L)
1426 {
1427  return setcode(L, &set_sf_code, NULL, "setsfcode", 32768);
1428 }
1429 
1430 static int getsfcode(lua_State * L)
1431 {
1432  int ch = luaL_checkinteger(L, -1);
1433  check_char_range(ch, "getsfcode", 65536*17);
1435  return 1;
1436 }
1437 
1438 static int setcatcode(lua_State * L)
1439 {
1440  int ch;
1441  halfword val;
1442  int level = cur_level;
1443  int cattable = cat_code_table_par;
1444  int n = lua_gettop(L);
1445  int f = 1;
1446  if (n>1 && lua_type(L,1) == LUA_TTABLE)
1447  f++;
1448  if (n>2 && (lua_type(L,f) == LUA_TSTRING)) {
1449  const char *s = lua_tostring(L, f);
1450  if (lua_key_eq(s,global)) {
1451  level = level_one;
1452  f++;
1453  }
1454  }
1455  if (n-f == 2) {
1456  cattable = luaL_checkinteger(L, -3);
1457  }
1458  ch = luaL_checkinteger(L, -2);
1459  check_char_range(ch, "setcatcode", 65536*17);
1460  val = (halfword) luaL_checkinteger(L, -1);
1461  check_char_range(val, "setcatcode", 16);
1462  set_cat_code(cattable, ch, val, level);
1463  return 0;
1464 }
1465 
1466 static int getcatcode(lua_State * L)
1467 {
1468  int cattable = cat_code_table_par;
1469  int ch = luaL_checkinteger(L, -1);
1470  if (lua_gettop(L)>=2 && lua_type(L,-2)==LUA_TNUMBER) {
1471  cattable = luaL_checkinteger(L, -2);
1472  }
1473  check_char_range(ch, "getcatcode", 65536*17);
1474  lua_pushinteger(L, get_cat_code(cattable, ch));
1475  return 1;
1476 }
1477 
1478 /*
1479 
1480 static int setmathcode(lua_State * L)
1481 {
1482  int ch;
1483  halfword cval, fval, chval;
1484  int level = cur_level;
1485  int n = lua_gettop(L);
1486  int f = 1;
1487  if (n>1 && lua_type(L,1) == LUA_TTABLE)
1488  f++;
1489  if (n>2 && (lua_type(L,f) == LUA_TSTRING)) {
1490  const char *s = lua_tostring(L, f);
1491  if (lua_key_eq(s,global)) {
1492  level = level_one;
1493  f++;
1494  }
1495  }
1496  if (n-f!=1 || lua_type(L,f+1) != LUA_TTABLE) {
1497  luaL_error(L, "Bad arguments for tex.setmathcode()");
1498  }
1499  ch = luaL_checkinteger(L, -2);
1500  check_char_range(ch, "setmathcode", 65536*17);
1501 
1502  lua_rawgeti(L, -1, 1);
1503  cval = (halfword) luaL_checkinteger(L, -1);
1504  lua_rawgeti(L, -2, 2);
1505  fval = (halfword) luaL_checkinteger(L, -1);
1506  lua_rawgeti(L, -3, 3);
1507  chval = (halfword) luaL_checkinteger(L, -1);
1508  lua_pop(L,3);
1509 
1510  check_char_range(cval, "setmathcode", 8);
1511  check_char_range(fval, "setmathcode", 256);
1512  check_char_range(chval, "setmathcode", 65536*17);
1513  set_math_code(ch, cval,fval, chval, (quarterword) (level));
1514  return 0;
1515 }
1516 
1517 */
1518 
1519 /*
1520  [global] code { c f ch }
1521  [global] code c f ch (a bit easier on memory, counterpart of getter)
1522 */
1523 
1524 static int setmathcode(lua_State * L)
1525 {
1526  int ch;
1527  halfword cval, fval, chval;
1528  int level = cur_level;
1529  int f = 1;
1530  if (lua_type(L,1) == LUA_TSTRING) {
1531  const char *s = lua_tostring(L,1);
1532  if (lua_key_eq(s,global)) {
1533  level = level_one;
1534  f = 2;
1535  }
1536  }
1537  ch = luaL_checkinteger(L, f);
1538  check_char_range(ch, "setmathcode", 65536*17);
1539  f += 1 ;
1540  if (lua_type(L,f) == LUA_TNUMBER) {
1541  cval = luaL_checkinteger(L, f);
1542  fval = luaL_checkinteger(L, f+1);
1543  chval = luaL_checkinteger(L, f+2);
1544  } else if (lua_type(L,f) == LUA_TTABLE) {
1545  lua_rawgeti(L, f, 1);
1546  cval = (halfword) luaL_checkinteger(L, -1);
1547  lua_rawgeti(L, f, 2);
1548  fval = (halfword) luaL_checkinteger(L, -1);
1549  lua_rawgeti(L, f, 3);
1550  chval = (halfword) luaL_checkinteger(L, -1);
1551  lua_pop(L,3);
1552  } else {
1553  luaL_error(L, "Bad arguments for tex.setmathcode()");
1554  return 0;
1555  }
1556  check_char_range(cval, "setmathcode", 8);
1557  check_char_range(fval, "setmathcode", 256);
1558  check_char_range(chval, "setmathcode", 65536*17);
1559  set_math_code(ch, cval,fval, chval, (quarterword) (level));
1560  return 0;
1561 }
1562 
1563 static int getmathcode(lua_State * L)
1564 {
1565  mathcodeval mval = { 0, 0, 0 };
1566  int ch = luaL_checkinteger(L, -1);
1567  check_char_range(ch, "getmathcode", 65536*17);
1568  mval = get_math_code(ch);
1569  lua_newtable(L);
1571  lua_rawseti(L, -2, 1);
1573  lua_rawseti(L, -2, 2);
1575  lua_rawseti(L, -2, 3);
1576  return 1;
1577 }
1578 
1579 static int getmathcodes(lua_State * L)
1580 {
1581  mathcodeval mval = { 0, 0, 0 };
1582  int ch = luaL_checkinteger(L, -1);
1583  check_char_range(ch, "getmathcodes", 65536*17);
1584  mval = get_math_code(ch);
1588  return 3;
1589 }
1590 
1591 /*
1592 
1593 static int setdelcode(lua_State * L)
1594 {
1595  int ch;
1596  halfword sfval, scval, lfval, lcval;
1597  int level = cur_level;
1598  int n = lua_gettop(L);
1599  int f = 1;
1600  if (n>1 && lua_type(L,1) == LUA_TTABLE)
1601  f++;
1602  if (n>2 && (lua_type(L,f) == LUA_TSTRING)) {
1603  const char *s = lua_tostring(L, f);
1604  if (lua_key_eq(s,global)) {
1605  level = level_one;
1606  f++;
1607  }
1608  }
1609  if (n-f!=1 || lua_type(L,f+1) != LUA_TTABLE) {
1610  luaL_error(L, "Bad arguments for tex.setdelcode()");
1611  }
1612  ch = luaL_checkinteger(L, -2);
1613  check_char_range(ch, "setdelcode", 65536*17);
1614  lua_rawgeti(L, -1, 1);
1615  sfval = (halfword) luaL_checkinteger(L, -1);
1616  lua_rawgeti(L, -2, 2);
1617  scval = (halfword) luaL_checkinteger(L, -1);
1618  lua_rawgeti(L, -3, 3);
1619  lfval = (halfword) luaL_checkinteger(L, -1);
1620  lua_rawgeti(L, -4, 4);
1621  lcval = (halfword) luaL_checkinteger(L, -1);
1622  lua_pop(L,4);
1623 
1624  check_char_range(sfval, "setdelcode", 256);
1625  check_char_range(scval, "setdelcode", 65536*17);
1626  check_char_range(lfval, "setdelcode", 256);
1627  check_char_range(lcval, "setdelcode", 65536*17);
1628  set_del_code(ch, sfval, scval, lfval, lcval, (quarterword) (level));
1629 
1630  return 0;
1631 }
1632 
1633 */
1634 
1635 /*
1636  [global] code { c f ch }
1637  [global] code c f ch (a bit easier on memory, counterpart of getter)
1638 */
1639 
1640 static int setdelcode(lua_State * L)
1641 {
1642  int ch;
1643  halfword sfval, scval, lfval, lcval;
1644  int level = cur_level;
1645  int f = 1;
1646  if (lua_type(L,1) == LUA_TSTRING) {
1647  const char *s = lua_tostring(L,1);
1648  if (lua_key_eq(s,global)) {
1649  level = level_one;
1650  f = 2;
1651  }
1652  }
1653  ch = luaL_checkinteger(L, f);
1654  check_char_range(ch, "setdelcode", 65536*17);
1655  f += 1;
1656  if (lua_type(L,f) == LUA_TNUMBER) {
1657  sfval = luaL_checkinteger(L, f);
1658  scval = luaL_checkinteger(L, f+1);
1659  lfval = luaL_checkinteger(L, f+2);
1660  lcval = luaL_checkinteger(L, f+3);
1661  } else if (lua_type(L,f) == LUA_TTABLE) {
1662  lua_rawgeti(L, f, 1);
1663  sfval = (halfword) luaL_checkinteger(L, -1);
1664  lua_rawgeti(L, f, 2);
1665  scval = (halfword) luaL_checkinteger(L, -1);
1666  lua_rawgeti(L, f, 3);
1667  lfval = (halfword) luaL_checkinteger(L, -1);
1668  lua_rawgeti(L, f, 4);
1669  lcval = (halfword) luaL_checkinteger(L, -1);
1670  lua_pop(L,4);
1671  } else {
1672  luaL_error(L, "Bad arguments for tex.setdelcode()");
1673  return 0;
1674  }
1675  check_char_range(sfval, "setdelcode", 256);
1676  check_char_range(scval, "setdelcode", 65536*17);
1677  check_char_range(lfval, "setdelcode", 256);
1678  check_char_range(lcval, "setdelcode", 65536*17);
1679  set_del_code(ch, sfval, scval, lfval, lcval, (quarterword) (level));
1680  return 0;
1681 }
1682 
1683 static int getdelcode(lua_State * L)
1684 {
1685  delcodeval mval = { 0, 0, 0, 0, 0 };
1686  int ch = luaL_checkinteger(L, -1);
1687  check_char_range(ch, "getdelcode", 65536*17);
1688  mval = get_del_code(ch);
1689  lua_newtable(L);
1691  lua_rawseti(L, -2, 1);
1693  lua_rawseti(L, -2, 2);
1695  lua_rawseti(L, -2, 3);
1697  lua_rawseti(L, -2, 4);
1698  return 1;
1699 }
1700 
1701 static int getdelcodes(lua_State * L)
1702 {
1703  delcodeval mval = { 0, 0, 0, 0, 0 };
1704  int ch = luaL_checkinteger(L, -1);
1705  check_char_range(ch, "getdelcodes", 65536*17);
1706  mval = get_del_code(ch);
1711  return 4;
1712 }
1713 
1714 static int settex(lua_State * L)
1715 {
1716  const char *st;
1717  int texstr, isprim;
1718  size_t k;
1719  int cur_cs1, cur_cmd1;
1720  int isglobal = 0;
1721  int j = 0;
1722  int i = lua_gettop(L);
1723  if (lua_type(L,i-1) == LUA_TSTRING) {
1724  st = lua_tolstring(L, (i - 1), &k);
1725  if (lua_key_eq(st,prevdepth)) {
1726  if (lua_type(L, i) == LUA_TNUMBER) {
1727  cur_list.prev_depth_field = lua_roundnumber(L, i);
1728  } else if (lua_type(L, i) == LUA_TSTRING) {
1729  cur_list.prev_depth_field = dimen_to_number(L, lua_tostring(L, i));
1730  } else {
1731  luaL_error(L, "unsupported value type");
1732  }
1733  return 0;
1734  } else if (lua_key_eq(st,prevgraf)) {
1735  if (lua_type(L, i) == LUA_TNUMBER) {
1736  cur_list.pg_field = lua_tointeger(L, i);
1737  } else {
1738  luaL_error(L, "unsupported value type");
1739  }
1740  return 0;
1741  } else if (lua_key_eq(st,spacefactor)) {
1742  if (lua_type(L, i) == LUA_TNUMBER) {
1743  cur_list.space_factor_field = lua_roundnumber(L, i);
1744  } else {
1745  luaL_error(L, "unsupported value type");
1746  }
1747  return 0;
1748  }
1749  texstr = maketexlstring(st, k);
1750  isprim = is_primitive(texstr);
1751  flush_str(texstr);
1752  if (isprim) {
1753  if (i == 3 && (lua_type(L,1) == LUA_TSTRING)) {
1754  const char *s = lua_tostring(L, 1);
1755  if (lua_key_eq(s,global))
1756  isglobal = 1;
1757  }
1758  cur_cs1 = string_lookup(st, k);
1759  flush_str(texstr);
1760  cur_cmd1 = eq_type(cur_cs1);
1761  if (is_int_assign(cur_cmd1)) {
1762  if (lua_type(L, i) == LUA_TNUMBER) {
1763  int luai = lua_tointeger(L, i);
1764  assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs1), luai);
1765  } else {
1766  luaL_error(L, "unsupported value type");
1767  }
1768  } else if (is_dim_assign(cur_cmd1)) {
1769  if (lua_type(L, i) == LUA_TNUMBER) {
1770  j = lua_roundnumber(L, i);
1771  } else if (lua_type(L, i) == LUA_TSTRING) {
1773  } else {
1774  luaL_error(L, "unsupported value type");
1775  }
1776  assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs1), j);
1777  } else if (is_glue_assign(cur_cmd1)) {
1778  int a = isglobal;
1779  if (lua_type(L, i) == LUA_TNUMBER) {
1782  if (i > 1) { stretch(value) = lua_roundnumber(L,i+1); }
1783  if (i > 3) { shrink(value) = lua_roundnumber(L,i+2); }
1784  if (i > 4) { stretch_order(value) = lua_tointeger(L,i+3); }
1785  if (i > 5) { shrink_order(value) = lua_tointeger(L,i+4); }
1786  define(equiv(cur_cs1), assign_glue_cmd, value);
1787  } else {
1788  halfword *j1 = check_isnode(L, i); /* the value */
1789  define(equiv(cur_cs1), assign_glue_cmd, *j1);
1790  }
1791  } else if (is_toks_assign(cur_cmd1)) {
1792  if (lua_type(L,i) == LUA_TSTRING) {
1793  j = tokenlist_from_lua(L); /* uses stack -1 */
1794  assign_internal_value((isglobal ? 4 : 0), equiv(cur_cs1), j);
1795 
1796  } else {
1797  luaL_error(L, "unsupported value type");
1798  }
1799 
1800  } else if (lua_istable(L, (i - 2))) {
1801  /*
1802  people may want to add keys that are also primitives |tex.wd| for example)
1803  so creating an error is not right here
1804  */
1805  lua_rawset(L, (i - 2));
1806  }
1807  } else if (lua_istable(L, (i - 2))) {
1808  lua_rawset(L, (i - 2));
1809  }
1810  } else if (lua_istable(L, (i - 2))) {
1811  lua_rawset(L, (i - 2));
1812  }
1813  return 0;
1814 }
1815 
1816 /* todo: some will to the pdf namespace .. ignore > 31 */
1817 
1818 static int do_convert(lua_State * L, int cur_code)
1819 {
1820  int texstr;
1821  int i = -1;
1822  char *str = NULL;
1823  switch (cur_code) {
1824  /* ignored (yet) */
1825 
1826  case insert_ht_code: /* arg <register int> */
1827  case lua_code: /* arg complex */
1828  case lua_escape_string_code: /* arg token list */
1829  case left_margin_kern_code: /* arg box */
1830  case right_margin_kern_code: /* arg box */
1831  case string_code: /* arg token */
1832  case cs_string_code: /* arg token */
1833  case meaning_code: /* arg token */
1834  break;
1835 
1836  /* the next fall through, and come from 'official' indices! */
1837 
1838  case font_name_code: /* arg fontid */
1839  case font_identifier_code: /* arg fontid */
1840  case uniform_deviate_code: /* arg int */
1841  case number_code: /* arg int */
1842  case roman_numeral_code: /* arg int */
1843 
1844  if (lua_gettop(L) < 1) {
1845  /* error */
1846  }
1847  i = lua_tointeger(L, 1);
1848 
1849  /* these fall through! */
1850 
1851  default:
1852  /* no backend here */
1853  if (cur_code < 32) {
1854  texstr = the_convert_string(cur_code, i);
1855  if (texstr) {
1856  str = makecstring(texstr);
1857  flush_str(texstr);
1858  }
1859  }
1860  }
1861  /* end */
1862  if (str) {
1863  lua_pushstring(L, str);
1864  free(str);
1865  } else {
1866  lua_pushnil(L);
1867  }
1868  return 1;
1869 }
1870 
1871 static int do_scan_internal(lua_State * L, int cur_cmd1, int cur_code, int values)
1872 {
1873  int texstr;
1874  int retval = 1 ;
1875  char *str = NULL;
1876  int save_cur_val, save_cur_val_level;
1877  save_cur_val = cur_val;
1878  save_cur_val_level = cur_val_level;
1879  scan_something_simple(cur_cmd1, cur_code);
1880  switch (cur_val_level) {
1881  case int_val_level:
1882  case dimen_val_level:
1883  case attr_val_level:
1885  break;
1886  case glue_val_level:
1887  case mu_val_level:
1888  if (values == 0) {
1891  } else if (values == 1) {
1898  retval = 5;
1899  } else {
1901  }
1902  break;
1903  default:
1904  texstr = the_scanned_result();
1905  str = makecstring(texstr);
1906  if (str) {
1907  lua_pushstring(L, str);
1908  free(str);
1909  } else {
1910  lua_pushnil(L);
1911  }
1912  flush_str(texstr);
1913  break;
1914  }
1915  cur_val = save_cur_val;
1916  cur_val_level = save_cur_val_level;
1917  return retval;
1918 }
1919 
1920 static int do_lastitem(lua_State * L, int cur_code)
1921 {
1922  int retval = 1;
1923  switch (cur_code) {
1924  /* the next two do not actually exist */
1925  case lastattr_code:
1926  case attrexpr_code:
1927  lua_pushnil(L);
1928  break;
1929  /* the expressions do something complicated with arguments, yuck */
1930  case numexpr_code:
1931  case dimexpr_code:
1932  case glueexpr_code:
1933  case muexpr_code:
1934  lua_pushnil(L);
1935  break;
1936  /* these read a glue or muglue, todo */
1937  case mu_to_glue_code:
1938  case glue_to_mu_code:
1941  case glue_stretch_code:
1942  case glue_shrink_code:
1943  lua_pushnil(L);
1944  break;
1945  /* these read a fontid and a char, todo */
1946  case font_char_wd_code:
1947  case font_char_ht_code:
1948  case font_char_dp_code:
1949  case font_char_ic_code:
1950  lua_pushnil(L);
1951  break;
1952  /* these read an integer, todo */
1953  case par_shape_length_code:
1954  case par_shape_indent_code:
1955  case par_shape_dimen_code:
1956  lua_pushnil(L);
1957  break;
1958  case lastpenalty_code:
1959  case lastkern_code:
1960  case lastskip_code:
1961  case last_node_type_code:
1962  case input_line_no_code:
1963  case badness_code:
1967  case last_x_pos_code:
1968  case last_y_pos_code:
1969  case random_seed_code:
1970  case luatex_version_code:
1972  case eTeX_version_code:
1975  case current_if_level_code:
1976  case current_if_type_code:
1978  retval = do_scan_internal(L, last_item_cmd, cur_code, -1);
1979  break;
1980  default:
1981  lua_pushnil(L);
1982  break;
1983  }
1984  return retval;
1985 }
1986 
1988 {
1989  int i, j;
1990  int k;
1991  int l = cur_level;
1992  void *p;
1993  int n = lua_gettop(L);
1994  if ((n == 3) || (n == 4)) {
1995  if (n == 4 && (lua_type(L,1) == LUA_TSTRING)) {
1996  const char *s = lua_tostring(L, 1);
1997  if (lua_key_eq(s,global))
1998  l = 1;
1999  }
2000  i = luaL_checkoption(L, (n - 2), NULL, math_param_names);
2001  j = luaL_checkoption(L, (n - 1), NULL, math_style_names);
2002  if (i < 0 || j < 0) {
2003  /* invalid spec, just ignore it */
2004  } else if (i>=math_param_first_mu_glue) {
2005  p = lua_touserdata(L, n);
2006  k = *((halfword *)p);
2007  def_math_param(i, j, (scaled) k, l);
2008  } else if (lua_type(L, n) == LUA_TNUMBER) {
2009  k = lua_roundnumber(L, n);
2010  def_math_param(i, j, (scaled) k, l);
2011  } else {
2012  luaL_error(L, "argument must be a number");
2013  }
2014  }
2015  return 0;
2016 }
2017 
2019 {
2020  if (lua_gettop(L) == 2) {
2023  if (i < 0 || j < 0) {
2024  lua_pushnil(L);
2025  } else {
2026  scaled k = get_math_param(i, j);
2027  if (i >= math_param_first_mu_glue) {
2028  if (k <= thick_mu_skip_code) {
2029  k = glue_par(k);
2030  }
2032  } else {
2033  lua_pushinteger(L, k);
2034  }
2035  }
2036  } else {
2037  lua_pushnil(L);
2038  }
2039  return 1;
2040 }
2041 
2042 static int getfontname(lua_State * L)
2043 {
2044  return do_convert(L, font_name_code);
2045 }
2046 
2048 {
2050 }
2051 
2053 {
2055 }
2056 
2057 static int getnumber(lua_State * L)
2058 {
2059  return do_convert(L, number_code);
2060 }
2061 
2063 {
2064  return do_convert(L, roman_numeral_code);
2065 }
2066 
2067 static int get_parshape(lua_State * L)
2068 {
2070  if (ptr != null) {
2071  int m = 1;
2072  int n = vinfo(ptr + 1);
2073  lua_createtable(L, n, 0);
2074  while (m <= n) {
2075  lua_createtable(L, 2, 0);
2076  lua_pushinteger(L, vlink((ptr) + (2 * (m - 1)) + 2));
2077  lua_rawseti(L, -2, 1);
2078  lua_pushinteger(L, vlink((ptr) + (2 * (m - 1)) + 3));
2079  lua_rawseti(L, -2, 2);
2080  lua_rawseti(L, -2, m);
2081  m++;
2082  }
2083  } else {
2084  lua_pushnil(L);
2085  }
2086  return 1;
2087 }
2088 
2089 static int get_etex_parshape(lua_State * L, int code)
2090 {
2091  halfword ptr = null;
2092  switch (code) {
2095  break;
2096  case club_penalties_loc:
2098  break;
2099  case widow_penalties_loc:
2101  break;
2104  break;
2105  }
2106  if (ptr != null) {
2107  int m = 1;
2108  int n = vinfo(ptr + 1) + 1;
2109  lua_createtable(L, n, 0);
2110  while (m <= n) {
2111  lua_pushinteger(L, penalty(ptr + m));
2112  lua_rawseti(L, -2, m);
2113  m++;
2114  }
2115  } else {
2116  lua_pushnil(L);
2117  }
2118  return 1;
2119 }
2120 
2121 static int gettex(lua_State * L)
2122 {
2123  int cur_cs1 = -1;
2124  int retval = 1; /* default is to return nil */
2125  int t = lua_gettop(L);
2126  int b = -1 ;
2127  if (t > 1 && lua_type(L,t) == LUA_TBOOLEAN) {
2128  /*
2129  0 == flush width only
2130  1 == flush all glue parameters
2131  */
2132  b = lua_toboolean(L,t);
2133  t = t - 1;
2134  }
2135  if (lua_type(L,t) == LUA_TSTRING) {
2136  /*
2137  1 == tex
2138  2 == boxmaxdepth
2139  or
2140  1 == boxmaxdepth
2141  */
2142  int texstr;
2143  size_t k;
2144  const char *st = lua_tolstring(L, t, &k);
2145  if (lua_key_eq(st,prevdepth)) {
2146  lua_pushinteger(L, cur_list.prev_depth_field);
2147  return 1;
2148  } else if (lua_key_eq(st,prevgraf)) {
2149  lua_pushinteger(L, cur_list.pg_field);
2150  return 1;
2151  } else if (lua_key_eq(st,spacefactor)) {
2152  lua_pushinteger(L, cur_list.space_factor_field);
2153  return 1;
2154  }
2155  texstr = maketexlstring(st, k);
2156  cur_cs1 = prim_lookup(texstr); /* not found == relax == 0 */
2157  flush_str(texstr);
2158  }
2159  if (cur_cs1 > 0) {
2160  int cur_cmd1 = get_prim_eq_type(cur_cs1);
2161  int cur_code = get_prim_equiv(cur_cs1);
2162  switch (cur_cmd1) {
2163  case last_item_cmd:
2164  retval = do_lastitem(L, cur_code);
2165  break;
2166  case convert_cmd:
2167  retval = do_convert(L, cur_code);
2168  break;
2169  case assign_toks_cmd:
2170  case assign_int_cmd:
2171  case assign_attr_cmd:
2172  case assign_dir_cmd:
2173  case assign_direction_cmd:
2174  case assign_dimen_cmd:
2175  case set_aux_cmd:
2176  case set_prev_graf_cmd:
2177  case set_page_int_cmd:
2178  case set_page_dimen_cmd:
2179  case char_given_cmd:
2180  case math_given_cmd:
2181  retval = do_scan_internal(L, cur_cmd1, cur_code, -1);
2182  break;
2183  case assign_glue_cmd:
2184  case assign_mu_glue_cmd:
2185  retval = do_scan_internal(L, cur_cmd1, cur_code, b);
2186  break;
2187  case set_tex_shape_cmd:
2188  retval = get_parshape(L);
2189  break;
2190  case set_etex_shape_cmd:
2191  retval = get_etex_parshape(L, cur_code);
2192  break;
2193  default:
2194  lua_pushnil(L);
2195  break;
2196  }
2197  } else if ((t == 2) && (lua_type(L,2) == LUA_TSTRING)) {
2198  lua_rawget(L, 1);
2199  }
2200  return retval;
2201 }
2202 
2203 static int getlist(lua_State * L)
2204 {
2205  const char *str;
2206  int top = lua_gettop(L);
2207  if (lua_type(L,top) == LUA_TSTRING) {
2208  str = lua_tostring(L, top);
2209  if (lua_key_eq(str,page_ins_head)) {
2211  lua_pushinteger(L, null);
2212  else
2215  } else if (lua_key_eq(str,contrib_head)) {
2219  } else if (lua_key_eq(str,page_discards_head)) {
2220  alink(vlink(page_disc)) = null ;
2223  } else if (lua_key_eq(str,split_discards_head)) {
2224  alink(vlink(split_disc)) = null ;
2227  } else if (lua_key_eq(str,page_head)) {
2228  alink(vlink(page_head)) = null ;/*hh-ls */
2231  } else if (lua_key_eq(str,temp_head)) {
2232  alink(vlink(temp_head)) = null ;/*hh-ls */
2235  } else if (lua_key_eq(str,hold_head)) {
2236  alink(vlink(hold_head)) = null ;/*hh-ls */
2239  } else if (lua_key_eq(str,adjust_head)) {
2240  alink(vlink(adjust_head)) = null ;/*hh-ls */
2243  } else if (lua_key_eq(str,best_page_break)) {
2246  } else if (lua_key_eq(str,least_page_cost)) {
2248  } else if (lua_key_eq(str,best_size)) {
2250  } else if (lua_key_eq(str,pre_adjust_head)) {
2251  alink(vlink(pre_adjust_head)) = null ;/*hh-ls */
2254  } else if (lua_key_eq(str,align_head)) {
2255  alink(vlink(align_head)) = null ;/*hh-ls */
2258  } else {
2259  lua_pushnil(L);
2260  }
2261  } else {
2262  lua_pushnil(L);
2263  }
2264  return 1;
2265 }
2266 
2267 static int setlist(lua_State * L)
2268 {
2269  int top = (lua_type(L,1) == LUA_TTABLE) ? 2 : 1 ;
2270  if (lua_type(L,top) == LUA_TSTRING) {
2271  const char *str = lua_tostring(L, top);
2272  if (lua_key_eq(str,best_size)) {
2273  best_size = (int) lua_tointeger(L, top+1);
2274  } else if (lua_key_eq(str,least_page_cost)) {
2276  } else {
2277  halfword *n_ptr;
2278  halfword n = 0;
2279  if (!lua_isnil(L, top+1)) {
2280  n_ptr = check_isnode(L, top+1);
2281  n = *n_ptr;
2282  }
2283  if (lua_key_eq(str,page_ins_head)) {
2284  if (n == 0) {
2286  } else {
2287  halfword m;
2288  vlink(page_ins_head) = n;
2289  m = tail_of_list(n);
2290  vlink(m) = page_ins_head;
2291  }
2292  } else if (lua_key_eq(str,contrib_head)) {
2293  vlink(contrib_head) = n;
2294  if (n == 0) {
2296  }
2297  } else if (lua_key_eq(str,best_page_break)) {
2298  best_page_break = n;
2299  } else if (lua_key_eq(str,page_head)) {
2300  vlink(page_head) = n;
2301  page_tail = (n == 0 ? page_head : tail_of_list(n));
2302  } else if (lua_key_eq(str,temp_head)) {
2303  vlink(temp_head) = n;
2304  } else if (lua_key_eq(str,page_discards_head)) {
2305  page_disc = n;
2306  } else if (lua_key_eq(str,split_discards_head)) {
2307  split_disc = n;
2308  } else if (lua_key_eq(str,hold_head)) {
2309  vlink(hold_head) = n;
2310  } else if (lua_key_eq(str,adjust_head)) {
2311  vlink(adjust_head) = n;
2312  adjust_tail = (n == 0 ? adjust_head : tail_of_list(n));
2313  } else if (lua_key_eq(str,pre_adjust_head)) {
2314  vlink(pre_adjust_head) = n;
2316  } else if (lua_key_eq(str,align_head)) {
2317  vlink(align_head) = n;
2318  }
2319  }
2320  }
2321  return 0;
2322 }
2323 
2324 #define NEST_METATABLE "luatex.nest"
2325 
2327 {
2328  list_state_record *r, **rv = lua_touserdata(L, -2);
2329  const char *field = lua_tostring(L, -1);
2330  r = *rv;
2331  if (lua_key_eq(field,mode)) {
2332  lua_pushinteger(L, r->mode_field);
2333  } else if (lua_key_eq(field,head)) {
2334  lua_nodelib_push_fast(L, r->head_field);
2335  } else if (lua_key_eq(field,tail)) {
2336  lua_nodelib_push_fast(L, r->tail_field);
2337  } else if (lua_key_eq(field,delimptr)) {
2338  lua_pushinteger(L, r->eTeX_aux_field);
2340  } else if (lua_key_eq(field,prevgraf)) {
2341  lua_pushinteger(L, r->pg_field);
2342  } else if (lua_key_eq(field,modeline)) {
2343  lua_pushinteger(L, r->ml_field);
2344  } else if (lua_key_eq(field,prevdepth)) {
2345  lua_pushinteger(L, r->prev_depth_field);
2346  } else if (lua_key_eq(field,spacefactor)) {
2347  lua_pushinteger(L, r->space_factor_field);
2348  } else if (lua_key_eq(field,noad)) {
2349  lua_pushinteger(L, r->incompleat_noad_field);
2351  } else if (lua_key_eq(field,dirs)) {
2352  lua_pushinteger(L, r->dirs_field);
2354  } else if (lua_key_eq(field,mathdir)) {
2355  lua_pushboolean(L, r->math_field);
2356  } else if (lua_key_eq(field,mathstyle)) {
2357  lua_pushinteger(L, r->math_style_field);
2358  } else {
2359  lua_pushnil(L);
2360  }
2361  return 1;
2362 }
2363 
2365 {
2366  halfword *n;
2367  int i;
2368  list_state_record *r, **rv = lua_touserdata(L, -3);
2369  const char *field = lua_tostring(L, -2);
2370  r = *rv;
2371  if (lua_key_eq(field,mode)) {
2372  i = lua_tointeger(L, -1);
2373  r->mode_field = i;
2374  } else if (lua_key_eq(field,head)) {
2375  n = check_isnode(L, -1);
2376  r->head_field = *n;
2377  } else if (lua_key_eq(field,tail)) {
2378  n = check_isnode(L, -1);
2379  r->tail_field = *n;
2380  } else if (lua_key_eq(field,delimptr)) {
2381  n = check_isnode(L, -1);
2382  r->eTeX_aux_field = *n;
2383  } else if (lua_key_eq(field,prevgraf)) {
2384  i = lua_tointeger(L, -1);
2385  r->pg_field = i;
2386  } else if (lua_key_eq(field,modeline)) {
2387  i = lua_tointeger(L, -1);
2388  r->ml_field = i;
2389  } else if (lua_key_eq(field,prevdepth)) {
2390  i = lua_roundnumber(L, -1);
2391  r->prev_depth_field = i;
2392  } else if (lua_key_eq(field,spacefactor)) {
2393  i = lua_roundnumber(L, -1);
2394  r->space_factor_field = i;
2395  } else if (lua_key_eq(field,noad)) {
2396  n = check_isnode(L, -1);
2397  r->incompleat_noad_field = *n;
2398  } else if (lua_key_eq(field,dirs)) {
2399  n = check_isnode(L, -1);
2400  r->dirs_field = *n;
2401  } else if (lua_key_eq(field,mathdir)) {
2402  r->math_field = lua_toboolean(L, -1);
2403  } else if (lua_key_eq(field,mathstyle)) {
2404  i = lua_tointeger(L, -1);
2405  r->math_style_field = i;
2406  }
2407  return 0;
2408 }
2409 
2410 static const struct luaL_Reg nest_m[] = {
2411  {"__index", lua_nest_getfield},
2412  {"__newindex", lua_nest_setfield},
2413  {NULL, NULL} /* sentinel */
2414 };
2415 
2416 static void init_nest_lib(lua_State * L)
2417 {
2419  luaL_openlib(L, NULL, nest_m, 0);
2420  lua_pop(L, 1);
2421 }
2422 
2423 static int getnest(lua_State * L)
2424 {
2425  list_state_record **nestitem;
2426  int n = lua_gettop(L);
2427  int p = -1 ;
2428  if (n == 0) {
2429  p = nest_ptr;
2430  } else {
2431  int t = lua_type(L, n);
2432  if (t == LUA_TNUMBER) {
2433  int ptr = lua_tointeger(L, n);
2434  if (ptr >= 0 && ptr <= nest_ptr) {
2435  p = ptr;
2436  }
2437  } else if (t == LUA_TSTRING) {
2438  const char *s = lua_tostring(L, n);
2439  if (lua_key_eq(s,top)) {
2440  p = nest_ptr;
2441  } else if (lua_key_eq(s,ptr)) {
2443  return 1;
2444  }
2445  }
2446  }
2447  if (p > -1) {
2448  nestitem = lua_newuserdata(L, sizeof(list_state_record *));
2449  *nestitem = &nest[p];
2451  lua_setmetatable(L, -2);
2452  } else {
2453  lua_pushnil(L);
2454  }
2455  return 1;
2456 }
2457 
2458 static int setnest(lua_State * L)
2459 {
2460  luaL_error(L, "You can't modify the semantic nest array directly");
2461  return 0;
2462 }
2463 
2464 static int do_integer_error(double m)
2465 {
2466  const char *help[] = {
2467  "I can only go up to 2147483647='17777777777=" "7FFFFFFF,",
2468  "so I'm using that number instead of yours.",
2469  NULL
2470  };
2471  tex_error("Number too big", help);
2472  return (m > 0.0 ? infinity : -infinity);
2473 }
2474 
2476 {
2477  double m = (double) lua_tonumber(L, 1) + 0.5; /* integer or float */
2478  if (abs(m) > (double) infinity)
2480  else
2481  lua_pushinteger(L, floor(m));
2482  return 1;
2483 }
2484 
2486 {
2487  double delta = luaL_checknumber(L, 2);
2488  if (lua_istable(L, 1)) {
2489  lua_newtable(L); /* the new table is at index 3 */
2490  lua_pushnil(L);
2491  while (lua_next(L, 1) != 0) { /* numeric value */
2492  lua_pushvalue(L, -2);
2493  lua_insert(L, -2);
2494  if (lua_type(L,-2) == LUA_TNUMBER) {
2495  double m = (double) lua_tonumber(L, -1) * delta + 0.5; /* integer or float */
2496  lua_pop(L, 1);
2497  if (abs(m) > (double) infinity)
2499  else
2500  lua_pushinteger(L, floor(m));
2501  }
2502  lua_rawset(L, 3);
2503  }
2504  } else if (lua_type(L,1) == LUA_TNUMBER) {
2505  double m = (double) lua_tonumber(L, 1) * delta + 0.5; /* integer or float */
2506  if (abs(m) > (double) infinity)
2508  else
2509  lua_pushinteger(L, floor(m));
2510  } else {
2511  lua_pushnil(L);
2512  }
2513  return 1;
2514 }
2515 
2516 #define hash_text(A) hash[(A)].rh
2517 
2519 {
2520  const char *csname;
2521  int f, u;
2522  str_number t, d;
2523  size_t l;
2524  int i = 1;
2525  int a = 0;
2526  if (!no_new_control_sequence) {
2527  const char *help[] = { "You can't create a new font inside a \\csname\\endcsname pair", NULL };
2528  tex_error("Definition active", help);
2529  }
2530  if ((lua_gettop(L) == 3) && lua_isboolean(L, 1)) {
2531  a = lua_toboolean(L, 1);
2532  i = 2;
2533  }
2534  csname = luaL_checklstring(L, i, &l);
2535  f = luaL_checkinteger(L, (i + 1));
2537  u = string_lookup(csname, l);
2539  if (a)
2541  else
2543  eqtb[font_id_base + f] = eqtb[u];
2544  /*tex
2545 
2546  This is tricky: when we redefine a string we loose the old one. So this
2547  will change as it's only used to display the |\fontname| so we can store
2548  that with the font.
2549 
2550  */
2551  d = cs_text(font_id_base + f);
2552  t = maketexlstring(csname, l); /* the csname */
2553  if (!d) {
2554  /*tex We have a new string. */
2555  cs_text(font_id_base + f) = t;
2556  } else if ((d!=t) && str_eq_str(d,t)){
2557  /*tex We have a duplicate string. */
2558  flush_str(t);
2559  } else if(d!=t){
2560  d = search_string(t);
2561  if (d) {
2562  /*tex We have already such a string. */
2563  cs_text(font_id_base + f) = d;
2564  flush_str(t);
2565  } else {
2566  /*tex The old value is lost but still in the pool. */
2567  cs_text(font_id_base + f) = t;
2568  }
2569  }
2570  return 0;
2571 }
2572 
2573 /*
2574 static int tex_hashpairs(lua_State * L)
2575 {
2576  int cmd, chr;
2577  str_number s = 0;
2578  int cs = 1;
2579  lua_newtable(L);
2580  while (cs < hash_size) {
2581  s = hash_text(cs);
2582  if (s > 0) {
2583  char *ss = makecstring(s);
2584  lua_pushstring(L, ss);
2585  free(ss);
2586  cmd = eq_type(cs);
2587  chr = equiv(cs);
2588  make_token_table(L, cmd, chr, cs);
2589  lua_rawset(L, -3);
2590  cs++;
2591  }
2592  }
2593  return 1;
2594 }
2595 
2596 static int tex_primitives(lua_State * L)
2597 {
2598  int cmd, chr;
2599  str_number s = 0;
2600  int cs = 0;
2601  lua_newtable(L);
2602  while (cs < prim_size) {
2603  s = get_prim_text(cs);
2604  if (s > 0) {
2605  char *ss = makecstring(s);
2606  lua_pushstring(L, ss);
2607  free(ss);
2608  cmd = get_prim_eq_type(cs);
2609  chr = get_prim_equiv(cs);
2610  make_token_table(L, cmd, chr, 0);
2611  lua_rawset(L, -3);
2612  }
2613  cs++;
2614  }
2615  return 1;
2616 }
2617 
2618 static int tex_extraprimitives(lua_State * L)
2619 {
2620  int n, i;
2621  int mask = 0;
2622  int cs = 0;
2623  n = lua_gettop(L);
2624  if (n == 0) {
2625  mask = etex_command + luatex_command;
2626  } else {
2627  for (i = 1; i <= n; i++) {
2628  if (lua_type(L,i) == LUA_TSTRING) {
2629  const char *s = lua_tostring(L, i);
2630  if (lua_key_eq(s,etex)) {
2631  mask |= etex_command;
2632  } else if (lua_key_eq(s,tex)) {
2633  mask |= tex_command;
2634  } else if (lua_key_eq(s,core)) {
2635  mask |= core_command;
2636  } else if (lua_key_eq(s,luatex)) {
2637  mask |= luatex_command;
2638  }
2639  }
2640  }
2641  }
2642  lua_newtable(L);
2643  i = 1;
2644  while (cs < prim_size) {
2645  str_number s = 0;
2646  s = get_prim_text(cs);
2647  if (s > 0) {
2648  if (get_prim_origin(cs) & mask) {
2649  char *ss = makecstring(s);
2650  lua_pushstring(L, ss);
2651  free(ss);
2652  lua_rawseti(L, -2, i++);
2653  }
2654  }
2655  cs++;
2656  }
2657  return 1;
2658 }
2659 
2660 */
2661 
2663 {
2664  str_number s = 0;
2665  int cs = 1;
2666  int nt = 0;
2667  lua_newtable(L);
2668  while (cs < hash_size) {
2669  s = hash_text(cs);
2670  if (s > 0) {
2671  halfword n = cs_next(cs);
2672  char *ss = makecstring(s);
2673  lua_pushstring(L, ss);
2674  free(ss);
2675  lua_rawseti(L, -2, ++nt);
2676  while (n) {
2677  s = cs_text(n);
2678  if (s) {
2679  ss = makecstring(s);
2680  lua_pushstring(L, ss);
2681  free(ss);
2682  lua_rawseti(L, -2, ++nt);
2683  }
2684  n = cs_next(n);
2685  }
2686  }
2687  cs++;
2688  }
2689  return 1;
2690 }
2691 
2693 {
2694  str_number s = 0;
2695  int cs = 0;
2696  int nt = 0;
2697  lua_newtable(L);
2698  while (cs < prim_size) {
2699  s = get_prim_text(cs);
2700  if (s > 0) {
2701  char *ss = makecstring(s);
2702  lua_pushstring(L, ss);
2703  free(ss);
2704  lua_rawseti(L, -2, ++nt);
2705  }
2706  cs++;
2707  }
2708  return 1;
2709 }
2710 
2712 {
2713  int n, i;
2714  int mask = 0;
2715  int cs = 0;
2716  int nt = 0;
2717  n = lua_gettop(L);
2718  if (n == 0) {
2720  } else {
2721  for (i = 1; i <= n; i++) {
2722  if (lua_type(L,i) == LUA_TSTRING) {
2723  const char *s = lua_tostring(L, i);
2724  if (lua_key_eq(s,etex)) {
2725  mask |= etex_command;
2726  } else if (lua_key_eq(s,tex)) {
2727  mask |= tex_command;
2728  } else if (lua_key_eq(s,core)) {
2729  mask |= core_command;
2730  } else if (lua_key_eq(s,luatex)) {
2731  mask |= luatex_command;
2732  }
2733  }
2734  }
2735  }
2736  lua_newtable(L);
2737  while (cs < prim_size) {
2738  str_number s = 0;
2739  s = get_prim_text(cs);
2740  if (s > 0) {
2741  if (get_prim_origin(cs) & mask) {
2742  char *ss = makecstring(s);
2743  lua_pushstring(L, ss);
2744  free(ss);
2745  lua_rawseti(L, -2, ++nt);
2746  }
2747  }
2748  cs++;
2749  }
2750  return 1;
2751 }
2752 
2754 {
2755  int n = lua_gettop(L);
2756  if (n != 2) {
2757  luaL_error(L, "wrong number of arguments");
2758  } else {
2759  size_t l;
2760  int i;
2761  const char *pre = luaL_checklstring(L, 1, &l);
2762  if (lua_istable(L, 2)) {
2763  int nncs = no_new_control_sequence;
2764  no_new_control_sequence = true;
2765  i = 1;
2766  while (1) {
2767  lua_rawgeti(L, 2, i);
2768  if (lua_type(L,3) == LUA_TSTRING) {
2769  const char *prim = lua_tostring(L, 3);
2771  halfword prim_val = prim_lookup(s);
2772  if (prim_val != undefined_primitive) {
2773  char *newprim;
2774  int val;
2775  size_t newl;
2776  halfword cur_cmd1 = get_prim_eq_type(prim_val);
2777  halfword cur_chr1 = get_prim_equiv(prim_val);
2778  if (strncmp(pre, prim, l) != 0) { /* not a prefix */
2779  newl = strlen(prim) + l;
2780  newprim = (char *) xmalloc((unsigned) (newl + 1));
2781  strcpy(newprim, pre);
2782  strcat(newprim + l, prim);
2783  } else {
2784  newl = strlen(prim);
2785  newprim = (char *) xmalloc((unsigned) (newl + 1));
2786  strcpy(newprim, prim);
2787  }
2788  val = string_lookup(newprim, newl);
2791  primitive_def(newprim, newl, (quarterword) cur_cmd1, cur_chr1);
2792  }
2793  free(newprim);
2794  }
2795  flush_str(s);
2796  } else {
2797  lua_pop(L, 1);
2798  break;
2799  }
2800  lua_pop(L, 1);
2801  i++;
2802  }
2803  lua_pop(L, 1); /* the table */
2804  no_new_control_sequence = nncs;
2805  } else {
2806  luaL_error(L, "Expected an array of names as second argument");
2807  }
2808  }
2809  return 0;
2810 }
2811 
2812 #define get_int_par(A,B) do { \
2813  lua_key_rawgeti(A); \
2814  if (lua_type(L, -1) == LUA_TNUMBER) { \
2815  A = (int) lua_tointeger(L, -1); \
2816  } else { \
2817  A = (B); \
2818  } \
2819  lua_pop(L,1); \
2820 } while (0)
2821 
2822 #define get_intx_par(A,B,C,D) do { \
2823  lua_key_rawgeti(A); \
2824  if (lua_type(L, -1) == LUA_TNUMBER) { \
2825  A = (int) lua_tointeger(L, -1); \
2826  C = null; \
2827  } else if (lua_type(L, -1) == LUA_TTABLE){ \
2828  A = 0; \
2829  C = nodelib_topenalties(L, lua_gettop(L)); \
2830  } else { \
2831  A = (B); \
2832  C = (D); \
2833  } \
2834  lua_pop(L,1); \
2835 } while (0)
2836 
2837 #define get_dimen_par(A,B) do { \
2838  lua_key_rawgeti(A); \
2839  if (lua_type(L, -1) == LUA_TNUMBER) { \
2840  A = (int) lua_roundnumber(L, -1); \
2841  } else { \
2842  A = (B); \
2843  } \
2844  lua_pop(L,1); \
2845 } while (0)
2846 
2847 #define get_glue_par(A,B) do { \
2848  lua_key_rawgeti(A); \
2849  if (lua_type(L, -1) != LUA_TNIL) { \
2850  A = *check_isnode(L, -1); \
2851  } else { \
2852  A = (B); \
2853  } \
2854  lua_pop(L,1); \
2855 } while (0)
2856 
2858 {
2859  halfword p;
2860  int n = 0;
2861  int width, indent, j;
2862  /* find |n| */
2863  lua_pushnil(L);
2864  while (lua_next(L, i) != 0) {
2865  n++;
2866  lua_pop(L, 1);
2867  }
2868  if (n == 0)
2869  return null;
2870  p = new_node(shape_node, 2 * (n + 1) + 1);
2871  vinfo(p + 1) = n;
2872  /* fill |p| */
2873  lua_pushnil(L);
2874  j = 0;
2875  while (lua_next(L, i) != 0) {
2876  /* don't give an error for non-tables, we may add special syntaxes at some point */
2877  j++;
2878  if (lua_type(L, i) == LUA_TTABLE) {
2879  lua_rawgeti(L, -1, 1); /* indent */
2880  if (lua_type(L, -1) == LUA_TNUMBER) {
2881  indent = lua_roundnumber(L, -1);
2882  lua_pop(L, 1);
2883  lua_rawgeti(L, -1, 2); /* width */
2884  if (lua_type(L, -1) == LUA_TNUMBER) {
2885  width = lua_roundnumber(L, -1);
2886  lua_pop(L, 1);
2887  varmem[p + 2 * j].cint = indent;
2888  varmem[p + 2 * j + 1].cint = width;
2889  }
2890  }
2891  }
2892  lua_pop(L, 1);
2893  }
2894  return p;
2895 }
2896 
2897 /* penalties */
2898 
2900 {
2901  halfword p;
2902  int n = 0;
2903  int j;
2904  /* find |n| */
2905  lua_pushnil(L);
2906  while (lua_next(L, i) != 0) {
2907  n++;
2908  lua_pop(L, 1);
2909  }
2910  if (n == 0)
2911  return null;
2912  p = new_node(shape_node, 2 * ((n / 2) + 1) + 1 + 1);
2913  vinfo(p + 1) = (n / 2) + 1;
2914  varmem[p + 2].cint = n;
2915  lua_pushnil(L);
2916  j = 2;
2917  while (lua_next(L, i) != 0) {
2918  j++;
2919  if (lua_type(L, -1) == LUA_TNUMBER) {
2920  int pen = lua_tointeger(L, -1);
2921  varmem[p+j].cint = pen;
2922  }
2923  lua_pop(L, 1);
2924  }
2925  if (!odd(n))
2926  varmem[p+j+1].cint = 0;
2927  return p;
2928 }
2929 
2931 {
2932 
2933  halfword *j;
2934  halfword p;
2935  halfword final_par_glue;
2936  int paragraph_dir = 0;
2937  /* locally initialized parameters for line breaking */
2938  int pretolerance, tracingparagraphs, tolerance, looseness,
2939  adjustspacing, adjdemerits, protrudechars,
2940  linepenalty, lastlinefit, doublehyphendemerits, finalhyphendemerits,
2941  hangafter, interlinepenalty, widowpenalty, clubpenalty, brokenpenalty;
2942  halfword emergencystretch, hangindent, hsize, leftskip, rightskip,parshape;
2943  int fewest_demerits = 0, actual_looseness = 0;
2944  halfword clubpenalties, interlinepenalties, widowpenalties;
2945  int save_vlink_tmp_head;
2946  /* push a new nest level */
2947  push_nest();
2948  save_vlink_tmp_head = vlink(temp_head);
2949 
2950  j = check_isnode(L, 1); /* the value */
2951  vlink(temp_head) = *j;
2952  p = *j;
2953  if ((!is_char_node(vlink(*j))) && ((type(vlink(*j)) == local_par_node))) {
2954  paragraph_dir = local_par_dir(vlink(*j));
2955  }
2956 
2957  while (vlink(p) != null)
2958  p = vlink(p);
2959  final_par_glue = p;
2960 
2961  /* initialize local parameters */
2962 
2963  if (lua_gettop(L) != 2 || lua_type(L, 2) != LUA_TTABLE) {
2964  lua_checkstack(L, 3);
2965  lua_newtable(L);
2966  }
2967  lua_key_rawgeti(pardir);
2968  if (lua_type(L, -1) == LUA_TSTRING) {
2969  paragraph_dir = nodelib_getdir(L, -1);
2970  }
2971  lua_pop(L, 1);
2972 
2973  lua_key_rawgeti(parshape);
2974  if (lua_type(L, -1) == LUA_TTABLE) {
2975  parshape = nodelib_toparshape(L, lua_gettop(L));
2976  } else {
2977  parshape = equiv(par_shape_loc);
2978  }
2979  lua_pop(L, 1);
2980 
2982  get_int_par (tracingparagraphs, tracing_paragraphs_par);
2985  get_int_par (adjustspacing, adjust_spacing_par);
2986  get_int_par (adjdemerits, adj_demerits_par);
2987  get_int_par (protrudechars, protrude_chars_par);
2988  get_int_par (linepenalty, line_penalty_par);
2989  get_int_par (lastlinefit, last_line_fit_par);
2990  get_int_par (doublehyphendemerits, double_hyphen_demerits_par);
2991  get_int_par (finalhyphendemerits, final_hyphen_demerits_par);
2992  get_int_par (hangafter, hang_after_par);
2993  get_intx_par (interlinepenalty,inter_line_penalty_par, interlinepenalties, equiv(inter_line_penalties_loc));
2994  get_intx_par (clubpenalty, club_penalty_par, clubpenalties, equiv(club_penalties_loc));
2995  get_intx_par (widowpenalty, widow_penalty_par, widowpenalties, equiv(widow_penalties_loc));
2996  get_int_par (brokenpenalty, broken_penalty_par);
2997  get_dimen_par(emergencystretch, emergency_stretch_par);
2998  get_dimen_par(hangindent, hang_indent_par);
3000  get_glue_par (leftskip, left_skip_par);
3001  get_glue_par (rightskip, right_skip_par);
3002  ext_do_line_break(paragraph_dir,
3003  pretolerance,
3004  tracingparagraphs,
3005  tolerance,
3006  emergencystretch,
3007  looseness,
3008  adjustspacing,
3009  parshape,
3010  adjdemerits,
3011  protrudechars,
3012  linepenalty,
3013  lastlinefit,
3014  doublehyphendemerits,
3015  finalhyphendemerits,
3016  hangindent,
3017  hsize,
3018  hangafter,
3019  leftskip,
3020  rightskip,
3021  interlinepenalties,
3022  interlinepenalty,
3023  clubpenalty,
3024  clubpenalties,
3025  widowpenalties,
3026  widowpenalty,
3027  brokenpenalty,
3028  final_par_glue);
3029 
3030  /* return the generated list, and its prevdepth */
3032  lua_nodelib_push_fast(L, vlink(cur_list.head_field));
3033  lua_newtable(L);
3034  lua_push_key(demerits);
3036  lua_settable(L, -3);
3039  lua_settable(L, -3);
3040  lua_push_key(prevdepth);
3041  lua_pushinteger(L, cur_list.prev_depth_field);
3042  lua_settable(L, -3);
3043  lua_push_key(prevgraf);
3044  lua_pushinteger(L, cur_list.pg_field);
3045  lua_settable(L, -3);
3046 
3047  /* restore nest stack */
3048  vlink(temp_head) = save_vlink_tmp_head;
3049  pop_nest();
3050  if (parshape != equiv(par_shape_loc))
3051  flush_node(parshape);
3052  return 2;
3053 }
3054 
3056 {
3057  (void) L;
3058  normal_paragraph();
3059  return 0;
3060 }
3061 
3062 static int tex_shipout(lua_State * L)
3063 {
3064  int boxnum = get_box_id(L, 1, true);
3065  ship_out(static_pdf, box(boxnum), SHIPPING_PAGE);
3066  box(boxnum) = null;
3067  return 0;
3068 }
3069 
3070 static int tex_badness(lua_State * L)
3071 {
3072  scaled t = lua_tointeger(L,1);
3073  scaled s = lua_tointeger(L,2);
3075  return 1;
3076 }
3077 
3078 static int tex_run_boot(lua_State * L)
3079 {
3080  int n = lua_gettop(L);
3081  const char *format = NULL;
3082  if (n >= 1) {
3083  ini_version = 0;
3084  format = luaL_checkstring(L, 1);
3085  } else {
3086  ini_version = 1;
3087  }
3088  if (main_initialize()) { /* > 0 = failure */
3089  lua_pushboolean(L, 0); /* false */
3090  return 1;
3091  }
3092  if (format) {
3094  lua_pushboolean(L, 0); /* false */
3095  return 1;
3096  }
3097  if (!load_fmt_file(format)) {
3098  zwclose(fmt_file);
3099  lua_pushboolean(L, 0); /* false */
3100  return 1;
3101  }
3102  zwclose(fmt_file);
3103  }
3104  pdf_init_map_file("pdftex.map");
3105  /* */
3107  decr(ilimit);
3108  else
3111  random_seed = (microseconds * 1000) + (epochseconds % 1000000);
3113  initialize_math();
3116  text_dir_ptr = new_dir(0);
3117  history = spotless; /* ready to go! */
3118  /* Initialize synctex primitive */
3120  /* tex is ready to go, now */
3121  /*
3122  unhide_lua_table(Luas, "tex", tex_table_id);
3123  unhide_lua_table(Luas, "pdf", pdf_table_id);
3124  unhide_lua_table(Luas, "token", token_table_id);
3125  unhide_lua_table(Luas, "node", node_table_id);
3126  */
3127  lua_pushboolean(L, 1); /* true */
3128  return 1;
3129 }
3130 
3131 /* tex random generators */
3132 
3134 {
3135  int sp;
3136  if (lua_type(L, 1) != LUA_TNUMBER) {
3137  luaL_error(L, "argument must be a number");
3138  return 0;
3139  }
3140  sp = lua_roundnumber(L, 1);
3141  init_randoms(sp);
3142  return 0;
3143 }
3144 
3146 {
3147  int sp;
3148  if (lua_type(L, 1) != LUA_TNUMBER) {
3149  luaL_error(L, "argument must be a number");
3150  return 0;
3151  }
3152  sp = lua_roundnumber(L, 1);
3154  return 1;
3155 }
3156 
3158 {
3160  return 1;
3161 }
3162 
3163 /* Same as lua but with tex rng */
3164 
3166 {
3167  lua_Number rand_max = 0x7fffffff ;
3168  lua_Number r = unif_rand(rand_max) ;
3169  r = (r>=0 ? 0+r : 0-r) ;
3170  r = r / rand_max;
3171  switch (lua_gettop(L)) { /* check number of arguments */
3172  case 0: { /* no arguments */
3173  lua_pushnumber(L, r); /* float: [0, 1] */
3174  break;
3175  }
3176  case 1: { /* only upper limit */
3178  luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
3179  lua_pushnumber(L, floor(r*u) + (lua_Number)(1.0)); /* float: [1, u] */
3180  break;
3181  }
3182  case 2: { /* lower and upper limits */
3185  luaL_argcheck(L, l <= u, 2, "interval is empty");
3186  lua_pushnumber(L, floor(r*(u-l+1)) + l); /* float: [l, u] */
3187  break;
3188  }
3189  default:
3190  return luaL_error(L, "wrong number of arguments");
3191  }
3192  return 1;
3193 }
3194 
3195 static int tex_run_main(lua_State * L)
3196 {
3197  (void) L;
3198  main_control();
3199  return 0;
3200 }
3201 
3202 static int tex_run_end(lua_State * L)
3203 {
3204  (void) L;
3205  final_cleanup(); /* prepare for death */
3207  do_final_end();
3208  return 0;
3209 }
3210 
3212 {
3213  (void) L;
3214  show_context();
3215  return 0;
3216 }
3217 
3219 {
3220  halfword boxdata;
3221  int index = null;
3222  int attributes = null;
3223  int resources = null;
3224  int type = 0;
3225  int margin = pdf_xform_margin;
3226  boolean immediate = false;
3227  /* more or less same as scanner variant */
3228  if (lua_type(L,1) == LUA_TNUMBER) {
3229  halfword boxnumber = lua_tointeger(L,1);
3230  boxdata = box(boxnumber);
3231  box(boxnumber) = null;
3232  } else {
3233  boxdata = nodelist_from_lua(L,1);
3234  if (type(boxdata) != hlist_node && type(boxdata) != vlist_node) {
3235  normal_error("pdf backend", "xforms can only be used with a box or [h|v]list");
3236  }
3237  }
3238  if (boxdata == null) {
3239  normal_error("pdf backend", "xforms cannot be used with a void box or empty [h|v]list");
3240  }
3241  /* box attributes resources */
3242  if (lua_type(L,2) == LUA_TSTRING) {
3243  lua_pushvalue(L, 2);
3244  attributes = luaL_ref(L, LUA_REGISTRYINDEX);
3245  }
3246  if (lua_type(L,3) == LUA_TSTRING) {
3247  lua_pushvalue(L, 3);
3249  }
3250  if (lua_type(L,4) == LUA_TBOOLEAN) {
3251  immediate = lua_toboolean(L, 4);
3252  }
3253  if (lua_type(L,5) == LUA_TNUMBER) {
3254  type = lua_tointeger(L, 5);
3255  }
3256  if (lua_type(L,6) == LUA_TNUMBER) {
3257  margin = lua_tointeger(L, 6);
3258  }
3263  set_obj_xform_attr_str(static_pdf, index, attributes);
3266  set_obj_xform_box(static_pdf, index, (int) boxdata);
3274  if (immediate) {
3277  }
3278  return 1;
3279 }
3280 
3282 {
3283  halfword rule;
3284  int index = 0;
3285  scaled_whd alt, nat, dim;
3286  if (lua_type(L,1) != LUA_TNUMBER) {
3287  lua_pushnil(L);
3288  lua_pushnil(L);
3289  lua_pushnil(L);
3290  lua_pushnil(L);
3291  } else {
3292  index = lua_tointeger(L,1);
3293  alt.wd = null_flag;
3294  alt.ht = null_flag;
3295  alt.dp = null_flag;
3296  if (lua_type(L,2) == LUA_TNUMBER) {
3297  alt.wd = (scaled) lua_roundnumber(L,2);
3298  }
3299  if (lua_type(L,3) == LUA_TNUMBER) {
3300  alt.ht = (scaled) lua_roundnumber(L,3);
3301  }
3302  if (lua_type(L,4) == LUA_TNUMBER) {
3303  alt.dp = (scaled) lua_roundnumber(L,4);
3304  }
3305  /* sort of the same as backend */
3310  if (alt.wd != null_flag || alt.ht != null_flag || alt.dp != null_flag) {
3311  dim = tex_scale(nat, alt);
3312  } else {
3313  dim = nat;
3314  }
3315  rule = new_rule(box_rule);
3316  rule_index(rule) = index;
3317  width(rule) = dim.wd;
3318  height(rule) = dim.ht;
3319  depth(rule) = dim.dp;
3321  lua_pushinteger(L, (int) dim.wd);
3322  lua_pushinteger(L, (int) dim.ht);
3323  lua_pushinteger(L, (int) dim.dp);
3324  }
3325  return 4;
3326 }
3327 
3329 {
3330  int index = 0;
3331  if (lua_type(L,1) != LUA_TNUMBER) {
3332  lua_pushnil(L);
3333  lua_pushnil(L);
3334  lua_pushnil(L);
3335  lua_pushnil(L);
3336  } else {
3337  index = lua_tointeger(L,1);
3343  }
3344  return 4;
3345 }
3346 
3348 {
3349  /* no checking yet as this might go */
3350  halfword b;
3351  int index = lua_tointeger(L,1);
3354  nodelist_to_lua(L, b);
3355  return 1;
3356 }
3357 
3359 {
3360  build_page();
3361  return 0;
3362 }
3363 
3365 {
3367  return 1;
3368 }
3369 
3371 {
3373  return 1;
3374 }
3375 
3376 /* synctex */
3377 
3379 {
3380  halfword mode = lua_tointeger(L, 1);
3382  return 0;
3383 }
3385 {
3387  return 1;
3388 }
3389 
3391 {
3392  halfword tag = lua_tointeger(L, 1);
3394  return 0;
3395 }
3396 
3398 {
3400  return 1;
3401 }
3402 
3404 {
3405  halfword tag = lua_tointeger(L, 1);
3407  return 0;
3408 }
3409 
3411 {
3412  halfword line = lua_tointeger(L, 1);
3414  return 0;
3415 }
3416 
3418 {
3419  halfword line = lua_tointeger(L, 1);
3421  return 0;
3422 }
3423 
3425 {
3427  return 1;
3428 }
3429 
3431 {
3432  halfword flag = lua_tointeger(L, 1);
3434  return 0;
3435 }
3436 
3437 /*
3438  This is experimental and might change. In version 10 we hope to have the
3439  final version available. It actually took quite a bit of time to understand
3440  the implications of mixing lua prints in here. The current variant is (so far)
3441  the most robust (wrt crashes and side effects).
3442 */
3443 
3444 #define mode mode_par
3445 
3446 /*
3447  When we add save levels then we can get crashes when one flushed bad
3448  groups due to out of order flushing. So we play safe! But still we can
3449  have issues so best make sure you're in hmode.
3450 */
3451 
3452 static int forcehmode(lua_State * L)
3453 {
3454  if (abs(mode) == vmode) {
3455  if (lua_type(L,1) == LUA_TBOOLEAN) {
3456  new_graf(lua_toboolean(L,1));
3457  } else {
3458  new_graf(1);
3459  }
3460  }
3461  return 0;
3462 }
3463 
3464 static int runtoks(lua_State * L)
3465 {
3466  if (lua_type(L,1) == LUA_TFUNCTION) {
3467  int old_mode = mode;
3468  int ref;
3469  halfword r = get_avail();
3470  halfword t = get_avail();
3472  lua_pushvalue(L, 1);
3477  if (luacstrings > 0) {
3478  lua_string_start();
3479  }
3480  if (tracing_nesting_par > 2) {
3481  local_control_message("entering token scanner via function");
3482  }
3483  mode = -hmode;
3484  local_control();
3485  mode = old_mode;
3487  } else {
3488  halfword t;
3489  int k = get_item_index(L, 1, toks_base);
3490  check_index_range(k, "gettoks");
3491  t = toks(k);
3492  if (! t) {
3493  /* nothing to do */
3494  } else if ((scanner_status != defining) || (lua_toboolean(L,2))) {
3495  int grouped = lua_toboolean(L,3);
3496  int old_mode = mode;
3497  if (grouped) {
3498  halfword r = get_avail();
3501  }
3502  {
3503  halfword r = get_avail();
3506  }
3508  if (grouped) {
3509  halfword r = get_avail();
3512  }
3513  if (luacstrings > 0) {
3514  lua_string_start();
3515  }
3516  if (tracing_nesting_par > 2) {
3517  local_control_message("entering token scanner via register");
3518  }
3519  mode = -hmode;
3520  local_control();
3521  mode = old_mode;
3522  /* unsave(); */
3523  } else {
3524  halfword q;
3526  halfword r = token_link(t);
3527  set_token_link(p, null);
3528  while (r) {
3530  r = token_link(r);
3531  }
3533  }
3534  }
3535  return 0;
3536 }
3537 
3538 static int quittoks(lua_State * L)
3539 {
3540  (void) L;
3541  if (tracing_nesting_par > 2) {
3542  local_control_message("quitting token scanner");
3543  }
3545  return 0;
3546 }
3547 
3548 /*tex Negative values are internal and inline. */
3549 
3551 {
3552  lua_newtable(L);
3553  lua_pushinteger(L,0);
3554  lua_push_string_by_name(L,unset); /* 0 */
3555  lua_rawset(L, -3);
3557  lua_push_string_by_name(L,vertical); /* 1 */
3558  lua_rawset(L, -3);
3560  lua_push_string_by_name(L,horizontal); /* 127 */
3561  lua_rawset(L, -3);
3563  lua_push_string_by_name(L,math); /* 253 */
3564  lua_rawset(L, -3);
3565  return 1;
3566 }
3567 
3568 /* till here */
3569 
3571 {
3572  lua_createtable(L, 0, 3);
3574  lua_setfield(L, -2, "initialize");
3576  lua_setfield(L, -2, "run");
3578  lua_setfield(L, -2, "finish");
3579  lua_setglobal(L, "tex");
3580 }
3581 
3582 static const struct luaL_Reg texlib[] = {
3583  { "run", tex_run_main }, /* may be needed */
3584  { "finish", tex_run_end }, /* may be needed */
3585  { "write", luacwrite },
3586  { "print", luacprint },
3587  { "sprint", luacsprint },
3588  { "tprint", luactprint },
3589  { "cprint", luaccprint },
3590  { "error", texerror },
3591  { "set", settex },
3592  { "get", gettex },
3593  { "isdimen", isdimen },
3594  { "setdimen", setdimen },
3595  { "getdimen", getdimen },
3596  { "isskip", isskip },
3597  { "setskip", setskip },
3598  { "getskip", getskip },
3599  { "isglue", isskip },
3600  { "setglue", setglue },
3601  { "getglue", getglue },
3602  { "ismuskip", ismuskip },
3603  { "setmuskip", setmuskip },
3604  { "getmuskip", getmuskip },
3605  { "ismuglue", ismuskip },
3606  { "setmuglue", setmuglue },
3607  { "getmuglue", getmuglue },
3608  { "isattribute", isattribute },
3609  { "setattribute", setattribute },
3610  { "getattribute", getattribute },
3611  { "iscount", iscount },
3612  { "setcount", setcount },
3613  { "getcount", getcount },
3614  { "istoks", istoks },
3615  { "settoks", settoks },
3616  { "scantoks", scantoks },
3617  { "gettoks", gettoks },
3618  { "getmark", getmark },
3619  { "isbox", isbox },
3620  { "setbox", setbox },
3621  { "getbox", getbox },
3622  { "splitbox", splitbox },
3623  { "setlist", setlist },
3624  { "getlist", getlist },
3625  { "setnest", setnest }, /* only a message */
3626  { "getnest", getnest },
3627  { "setcatcode", setcatcode },
3628  { "getcatcode", getcatcode },
3629  { "setdelcode", setdelcode },
3630  { "getdelcode", getdelcode },
3631  { "getdelcodes", getdelcodes },
3632  { "setlccode", setlccode },
3633  { "getlccode", getlccode },
3634  { "setmathcode", setmathcode },
3635  { "getmathcode", getmathcode },
3636  { "getmathcodes", getmathcodes },
3637  { "setsfcode", setsfcode },
3638  { "getsfcode", getsfcode },
3639  { "setuccode", setuccode },
3640  { "getuccode", getuccode },
3641  { "round", tex_roundnumber },
3642  { "scale", tex_scaletable },
3643  { "sp", tex_scaledimen },
3644  { "fontname", getfontname },
3645  { "fontidentifier", getfontidentifier },
3646  { "uniformdeviate", getuniformdeviate },
3647  { "number", getnumber },
3648  { "romannumeral", getromannumeral },
3649  { "definefont", tex_definefont },
3650  { "hashtokens", tex_hashpairs },
3651  { "primitives", tex_primitives },
3652  { "extraprimitives", tex_extraprimitives },
3653  { "enableprimitives", tex_enableprimitives },
3654  { "shipout", tex_shipout },
3655  { "badness", tex_badness },
3656  { "setmath", tex_setmathparm },
3657  { "getmath", tex_getmathparm },
3658  { "linebreak", tex_run_linebreak },
3659  { "resetparagraph", tex_reset_paragraph },
3660  /* tex random generators */
3661  { "init_rand", tex_init_rand },
3662  { "uniform_rand",tex_unif_rand },
3663  { "normal_rand", tex_norm_rand },
3664  { "lua_math_randomseed", tex_init_rand }, /* syntactic sugar */
3665  { "lua_math_random", lua_math_random },
3666  { "show_context", tex_show_context },
3667  { "saveboxresource", tex_save_box_resource },
3668  { "useboxresource", tex_use_box_resource },
3669  { "getboxresourcedimensions", tex_get_box_resource_dimensions },
3670  /* might go, used when sanitizing backend */
3671  { "getboxresourcebox", tex_get_box_resource_box },
3672  /* just for testing: it will probably stay but maybe with options */
3673  { "triggerbuildpage", tex_build_page },
3674  { "getpagestate", lua_get_page_state },
3675  { "getlocallevel", lua_get_local_level },
3676  /* not the best place but better than in node */
3677  { "set_synctex_mode", lua_set_synctex_mode },
3678  { "get_synctex_mode", lua_get_synctex_mode },
3679  { "set_synctex_tag", lua_set_synctex_tag },
3680  { "get_synctex_tag", lua_get_synctex_tag },
3681  { "set_synctex_no_files", lua_set_synctex_no_files },
3682  { "force_synctex_tag", lua_force_synctex_tag },
3683  { "force_synctex_line", lua_force_synctex_line },
3684  { "set_synctex_line", lua_set_synctex_line },
3685  { "get_synctex_line", lua_get_synctex_line },
3686  /* test */
3687  { "runtoks", runtoks },
3688  { "quittoks", quittoks },
3689  { "forcehmode", forcehmode },
3690  { "getmodevalues", tex_getmodevalues },
3691  /* sentinel */
3692  { NULL, NULL }
3693 };
3694 
3696 {
3697  luaL_openlib(L, "tex", texlib, 0);
3698  /* *INDENT-OFF* */
3699  make_table(L, "attribute", "tex.attribute", "getattribute", "setattribute");
3700  make_table(L, "skip", "tex.skip", "getskip", "setskip");
3701  make_table(L, "glue", "tex.glue", "getglue", "setglue");
3702  make_table(L, "muskip", "tex.muskip", "getmuskip", "setmuskip");
3703  make_table(L, "muglue", "tex.muglue", "getmuglue", "setmuglue");
3704  make_table(L, "dimen", "tex.dimen", "getdimen", "setdimen");
3705  make_table(L, "count", "tex.count", "getcount", "setcount");
3706  make_table(L, "toks", "tex.toks", "gettoks", "settoks");
3707  make_table(L, "box", "tex.box", "getbox", "setbox");
3708  make_table(L, "sfcode", "tex.sfcode", "getsfcode", "setsfcode");
3709  make_table(L, "lccode", "tex.lccode", "getlccode", "setlccode");
3710  make_table(L, "uccode", "tex.uccode", "getuccode", "setuccode");
3711  make_table(L, "catcode", "tex.catcode", "getcatcode", "setcatcode");
3712  make_table(L, "mathcode", "tex.mathcode", "getmathcode", "setmathcode");
3713  make_table(L, "delcode", "tex.delcode", "getdelcode", "setdelcode");
3714  make_table(L, "lists", "tex.lists", "getlist", "setlist");
3715  make_table(L, "nest", "tex.nest", "getnest", "setnest");
3716  /* *INDENT-ON* */
3717  init_nest_lib(L);
3718  /* make the meta entries */
3719  /* fetch it back */
3720  luaL_newmetatable(L, "tex.meta");
3721  lua_pushstring(L, "__index");
3723  lua_settable(L, -3);
3724  lua_pushstring(L, "__newindex");
3726  lua_settable(L, -3);
3727  lua_setmetatable(L, -2); /* meta to itself */
3728  /* initialize the I/O stack: */
3729  spindles = xmalloc(sizeof(spindle));
3730  spindle_index = 0;
3731  spindles[0].head = NULL;
3732  spindles[0].tail = NULL;
3733  spindle_size = 1;
3734  /* a somewhat odd place for this assert, maybe */
3735  if (command_names[data_cmd].id != data_cmd) {
3736  fatal_error("mismatch between tex and lua command name tables");
3737  };
3738  return 1;
3739 }
q
Definition: afm2pl.c:2287
int level
Definition: afm2pl.c:1694
double quad
Definition: aftopl.c:71
double x_height
Definition: aftopl.c:63
void normal_paragraph(void)
Definition: aptex-src.c:30456
void close_files_and_terminate(void)
Definition: aptex-src.c:36094
void build_page(void)
Definition: aptex-src.c:29726
static int do_final_end(void)
void show_context(void)
Definition: aptex-src.c:13728
void main_control(void)
Definition: aptex-src.c:34958
#define page_ins_head
Definition: aptex-macros.h:319
#define toks(a)
Definition: aptex-macros.h:674
#define looseness
Definition: aptex-macros.h:804
#define align_head
Definition: aptex-macros.h:326
#define page_disc
#define max_dimen
#define shrink_order
Definition: aptex-macros.h:290
#define hold_head
Definition: aptex-macros.h:323
#define mu_skip_base
Definition: aptex-macros.h:587
#define penalty(a)
Definition: aptex-macros.h:305
#define contrib_head
Definition: aptex-macros.h:320
#define ins_list(a)
#define pretolerance
Definition: aptex-macros.h:785
#define width(a)
Definition: aptex-macros.h:198
#define skip_base
Definition: aptex-macros.h:586
#define widow_penalties_loc
Definition: aptex-macros.h:635
#define set_lc_code(a)
#define infinity
#define club_penalties_loc
Definition: aptex-macros.h:634
#define tolerance
Definition: aptex-macros.h:786
#define type(a)
Definition: aptex-macros.h:171
#define vmode
Definition: aptex-macros.h:504
#define depth(a)
Definition: aptex-macros.h:199
#define eq_type(a)
Definition: aptex-macros.h:536
#define level_one
Definition: aptex-macros.h:539
#define prim_size
Definition: aptex-macros.h:558
#define temp_head
Definition: aptex-macros.h:322
#define null_flag
Definition: aptex-macros.h:220
#define stretch_order
Definition: aptex-macros.h:289
#define box(a)
Definition: aptex-macros.h:675
#define glue_par(a)
Definition: aptex-macros.h:592
#define name
#define zero_glue
Definition: aptex-macros.h:312
#define scaled_base
Definition: aptex-macros.h:889
#define subtype(a)
Definition: aptex-macros.h:172
#define display_widow_penalties_loc
Definition: aptex-macros.h:636
#define par_shape_loc
Definition: aptex-macros.h:614
#define height(a)
Definition: aptex-macros.h:200
#define is_char_node(a)
Definition: aptex-macros.h:174
#define page_head
Definition: aptex-macros.h:321
#define count_base
Definition: aptex-macros.h:776
#define fast_store_new_token(a)
#define next(a)
Definition: aptex-macros.h:924
#define adjust_head
Definition: aptex-macros.h:324
#define define(p, t, e)
#define hmode
Definition: aptex-macros.h:505
#define end_line_char_inactive()
#define null
Definition: aptex-macros.h:127
#define contrib_tail
#define thick_mu_skip_code
Definition: aptex-macros.h:583
#define stretch(a)
Definition: aptex-macros.h:287
#define global
#define nx_plus_y(a, b, c)
Definition: aptex-macros.h:116
#define undefined_primitive
Definition: aptex-macros.h:940
#define inter_line_penalties_loc
Definition: aptex-macros.h:633
#define undefined_control_sequence
Definition: aptex-macros.h:561
#define toks_base
Definition: aptex-macros.h:630
#define tail
Definition: aptex-macros.h:514
#define font_id_base
Definition: aptex-macros.h:560
#define split_disc
#define mmode
Definition: aptex-macros.h:506
void pop_nest(void)
Definition: aptex-src.c:10759
static void ship_out(pointer p)
Definition: aptex-src.c:21011
static scaled round_decimals(small_number k)
Definition: aptex-src.c:8361
static pointer vsplit(halfword n, scaled h)
Definition: aptex-src.c:29201
static pointer new_rule(void)
Definition: aptex-src.c:8933
static halfword badness(scaled t, scaled s)
Definition: aptex-src.c:8499
static pointer prim_lookup(str_number s)
Definition: aptex-src.c:7081
static scaled xn_over_d(scaled x, integer n, integer d)
Definition: aptex-src.c:8461
static boolean load_fmt_file(void)
Definition: aptex-src.c:4249
static void push_nest(void)
Definition: aptex-src.c:10727
pointer get_avail(void)
Definition: aptex-src.c:8704
static void new_graf(boolean indented)
Definition: aptex-src.c:30808
static void final_cleanup(void)
Definition: aptex-src.c:4674
static void eq_define(pointer p, quarterword t, halfword e)
Definition: aptex-src.c:13387
static void prepare_mag(void)
Definition: aptex-src.c:13619
void begin_token_list(pointer p, quarterword t)
Definition: aptex-src.c:14007
static void geq_define(pointer p, quarterword t, halfword e)
Definition: aptex-src.c:13430
static pointer adjust_tail
Definition: aptex.h:552
static uint32_t dig[23+1]
Definition: aptex.h:306
static integer least_page_cost
Definition: aptex.h:686
integer str_number
Definition: aptex.h:196
static integer epochseconds
Definition: aptex.h:785
static memory_word eqtb[((((((((((((((((((((((((((((((((((((((((1+256)+256)+1)+hash_size)+10)+1)+2100+1)+font_max+2)+1)+21)+256)+256)+10)+1)+256)+4)+256)+1)+48)+1)+1)+1)+1)+1)+256)+512)+256)+256)+256)+10)+256)+256)+256)+256)+76)+256)+256)+27)+256)+255)+1]
Definition: aptex.h:384
static int scanner_status
Definition: aptex.h:424
static two_halves prim[2100+1]
Definition: aptex.h:393
static boolean arith_error
Definition: aptex.h:332
static boolean no_new_control_sequence
Definition: aptex.h:390
static integer nest_ptr
Definition: aptex.h:376
static scaled best_size
Definition: aptex.h:687
static pointer page_tail
Definition: aptex.h:682
static integer actual_looseness
Definition: aptex.h:609
static int page_contents
Definition: aptex.h:683
static integer fewest_demerits
Definition: aptex.h:607
static scaled random_seed
Definition: aptex.h:337
uint8_t packed_ASCII_code
Definition: aptex.h:112
static pointer best_page_break
Definition: aptex.h:685
static int cur_level
Definition: aptex.h:400
static int cur_val_level
Definition: aptex.h:448
static boolean deletions_allowed
Definition: aptex.h:320
@ hash_size
Definition: aptex.h:176
static word_file fmt_file
Definition: aptex.h:718
scaled tex_remainder
Definition: arithmetic.c:156
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define fatal_error(i, s, t)
Definition: ctie-k.c:22
@ pre
Definition: ctie-k.c:71
#define free(a)
Definition: decNumber.cpp:310
halfword new_dir(int s)
Definition: directions.c:85
halfword text_dir_ptr
Definition: directions.c:78
int v
Definition: dviconv.c:10
#define FOPEN_RBIN_MODE
Definition: dvips.h:86
unsigned short halfword
Definition: dvips.h:68
#define xfree(p)
Definition: ptexmac.h:85
char * strcpy()
#define error(a)
Definition: dviinfo.c:48
void flush_str(void)
Definition: dvispc.c:1768
#define adjust_spacing_par
Definition: equivalents.h:623
#define tracing_nesting_par
Definition: equivalents.h:747
#define club_penalties_par_ptr
Definition: equivalents.h:717
#define widow_penalty_par
Definition: equivalents.h:634
#define attribute_base
Definition: equivalents.h:340
#define global_defs_par
Definition: equivalents.h:739
#define hsize_par
Definition: equivalents.h:605
#define looseness_par
Definition: equivalents.h:622
#define display_widow_penalties_par_ptr
Definition: equivalents.h:719
#define tracing_paragraphs_par
Definition: equivalents.h:746
#define par_shape_par_ptr
Definition: equivalents.h:715
#define hang_after_par
Definition: equivalents.h:615
#define get_tex_attribute_register(j)
Definition: equivalents.h:832
#define line_penalty_par
Definition: equivalents.h:626
#define hang_indent_par
Definition: equivalents.h:614
#define get_tex_dimen_register(j)
Definition: equivalents.h:835
#define tolerance_par
Definition: equivalents.h:621
#define get_tex_mu_skip_register(j)
Definition: equivalents.h:836
#define widow_penalties_par_ptr
Definition: equivalents.h:718
#define inter_line_penalties_par_ptr
Definition: equivalents.h:716
#define adj_demerits_par
Definition: equivalents.h:624
#define px_dimen_par
Definition: equivalents.h:729
#define get_tex_skip_register(j)
Definition: equivalents.h:837
#define club_penalty_par
Definition: equivalents.h:631
#define mag_par
Definition: equivalents.h:737
#define emergency_stretch_par
Definition: equivalents.h:619
#define right_skip_par
Definition: equivalents.h:617
#define last_line_fit_par
Definition: equivalents.h:627
#define left_skip_par
Definition: equivalents.h:616
#define cat_code_table_par
Definition: equivalents.h:740
#define inter_line_penalty_par
Definition: equivalents.h:630
#define pretolerance_par
Definition: equivalents.h:620
#define get_tex_count_register(j)
Definition: equivalents.h:834
#define protrude_chars_par
Definition: equivalents.h:625
#define broken_penalty_par
Definition: equivalents.h:632
#define get_tex_box_register(j)
Definition: equivalents.h:833
#define final_hyphen_demerits_par
Definition: equivalents.h:629
#define double_hyphen_demerits_par
Definition: equivalents.h:628
#define end_line_char_par
Definition: equivalents.h:660
void fixup_selector(boolean logopened)
Definition: errors.c:154
int set_tex_mu_skip_register(int j, halfword v)
Definition: extensions.c:1015
int get_tex_toks_register(int j)
Definition: extensions.c:1064
int set_tex_box_register(int j, scaled v)
Definition: extensions.c:1039
int set_tex_attribute_register(int j, scaled v)
Definition: extensions.c:1050
int set_tex_dimen_register(int j, scaled v)
Definition: extensions.c:991
int set_tex_skip_register(int j, halfword v)
Definition: extensions.c:1002
int last_saved_box_index
Definition: extensions.c:116
int scan_tex_toks_register(int j, int c, lstring s)
Definition: extensions.c:1088
int set_tex_count_register(int j, scaled v)
Definition: extensions.c:1028
int set_tex_toks_register(int j, lstring s)
Definition: extensions.c:1073
@ end_local_code
Definition: extensions.h:139
struct rule_struct rule
Definition: dvistuff.c:785
long int flag
Definition: f2c.h:53
FcObject field
Definition: fcdefault.c:32
static void
Definition: fpif.c:118
Boolean_T str_eq_str(StrNumber_T s1, StrNumber_T s2)
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define a(n)
Definition: gpos-common.c:148
#define d(n)
Definition: gpos-common.c:151
static void * xrealloc(char *oldp, unsigned size)
Definition: gsftopk.c:643
int base
Definition: gsftopk.c:1502