1
4
5# include "luametatex.h"
6
7
8
9# define page_goal lmt_page_builder_state.goal
10
11
55
56const char *tex_string_mode(int m)
57{
58 switch (m) {
59 case nomode : return "no mode";
60 case vmode : return "vertical mode";
61 case hmode : return "horizontal mode";
62 case mmode : return "display math mode";
63 case internal_vmode : return "internal vertical mode";
64 case restricted_hmode: return "restricted horizontal mode";
65 case inline_mmode : return "inline math mode";
66 default : return "unknown mode";
67 }
68}
69
70
146
147nest_state_info lmt_nest_state = {
148 .nest = NULL,
149 .nest_data = {
150 .minimum = min_nest_size,
151 .maximum = max_nest_size,
152 .size = siz_nest_size,
153 .step = stp_nest_size,
154 .allocated = 0,
155 .itemsize = sizeof(list_state_record),
156 .top = 0,
157 .ptr = 0,
158 .initial = memory_data_unset,
159 .offset = 0,
160 },
161 .shown_mode = 0,
162 .math_mode = 0,
163};
164
165
175
176# define reserved_nest_slots 0
177
178void tex_initialize_nest_state(void)
179{
180 int size = lmt_nest_state.nest_data.minimum;
181 lmt_nest_state.nest = aux_allocate_clear_array(sizeof(list_state_record), size, reserved_nest_slots);
182 if (lmt_nest_state.nest) {
183 lmt_nest_state.nest_data.allocated = size;
184 } else {
185 tex_overflow_error("nest", size);
186 }
187}
188
189static int tex_aux_room_on_nest_stack(void)
190{
191 int top = lmt_nest_state.nest_data.ptr;
192 if (top > lmt_nest_state.nest_data.top) {
193 lmt_nest_state.nest_data.top = top;
194 if (top > lmt_nest_state.nest_data.allocated) {
195 list_state_record *tmp = NULL;
196 top = lmt_nest_state.nest_data.allocated + lmt_nest_state.nest_data.step;
197 if (top > lmt_nest_state.nest_data.size) {
198 top = lmt_nest_state.nest_data.size;
199 }
200 if (top > lmt_nest_state.nest_data.allocated) {
201 lmt_nest_state.nest_data.allocated = top;
202 tmp = aux_reallocate_array(lmt_nest_state.nest, sizeof(list_state_record), top, reserved_nest_slots);
203 lmt_nest_state.nest = tmp;
204 }
205 lmt_run_memory_callback("nest", tmp ? 1 : 0);
206 if (! tmp) {
207 tex_overflow_error("nest", top);
208 return 0;
209 }
210 }
211 }
212 return 1;
213}
214
215void tex_initialize_nesting(void)
216{
217 lmt_nest_state.nest_data.ptr = 0;
218 lmt_nest_state.nest_data.top = 0;
219
220
221 cur_list.mode = vmode;
222 cur_list.head = contribute_head;
223 cur_list.tail = contribute_head;
224 cur_list.delimiter = null;
225 cur_list.prev_graf = 0;
226 cur_list.mode_line = 0;
227 cur_list.prev_depth = ignore_depth;
228 cur_list.space_factor = default_space_factor;
229 cur_list.incomplete_noad = null;
230 cur_list.direction_stack = null;
231 cur_list.math_dir = 0;
232 cur_list.math_style = -1;
233 cur_list.math_flatten = 1;
234 cur_list.math_begin = unset_noad_class;
235 cur_list.math_end = unset_noad_class;
236 cur_list.math_mode = 0;
237}
238
239halfword tex_pop_tail(void)
240{
241 if (cur_list.tail != cur_list.head) {
242 halfword r = cur_list.tail;
243 halfword n = node_prev(r);
244 if (node_next(n) != r) {
245 n = cur_list.head;
246 while (node_next(n) != r) {
247 n = node_next(n);
248 }
249 }
250 cur_list.tail = n;
251 node_prev(r) = null;
252 node_next(n) = null;
253 return r;
254 } else {
255 return null;
256 }
257}
258
259
266
267void tex_push_nest(void)
268{
269 list_state_record *top = &lmt_nest_state.nest[lmt_nest_state.nest_data.ptr];
270 lmt_nest_state.nest_data.ptr += 1;
271
272 lmt_nest_state.math_mode = 0;
273 if (tex_aux_room_on_nest_stack()) {
274 cur_list.mode = top->mode;
275 cur_list.head = tex_new_temp_node();
276 cur_list.tail = cur_list.head;
277 cur_list.delimiter = null;
278 cur_list.prev_graf = 0;
279 cur_list.mode_line = lmt_input_state.input_line;
280 cur_list.prev_depth = top->prev_depth;
281 cur_list.space_factor = top->space_factor;
282 cur_list.incomplete_noad = top->incomplete_noad;
283 cur_list.direction_stack = null;
284 cur_list.math_dir = 0;
285 cur_list.math_style = -1;
286 cur_list.math_flatten = 1;
287 cur_list.math_begin = unset_noad_class;
288 cur_list.math_end = unset_noad_class;
289
290
291 cur_list.math_mode = 0;
292 } else {
293 tex_overflow_error("semantic nest size", lmt_nest_state.nest_data.size);
294 }
295}
296
297
304
305void tex_pop_nest(void)
306{
307 if (cur_list.head) {
308
309 tex_flush_node(cur_list.head);
310
311
312
313 }
314 --lmt_nest_state.nest_data.ptr;
315}
316
317
318
319void tex_show_activities(void)
320{
321 tex_print_nlp();
322 for (int p = lmt_nest_state.nest_data.ptr; p >= 0; p--) {
323 list_state_record n = lmt_nest_state.nest[p];
324 tex_print_format("%l[%M entered at line %i%s]", n.mode, abs(n.mode_line), n.mode_line < 0 ? " (output routine)" : "");
325 if (p == 0) {
326
327 if (page_head != lmt_page_builder_state.page_tail) {
328 tex_print_format("%l[current page:%s]", lmt_page_builder_state.output_active ? " (held over for next output)" : "");
329 tex_show_box(node_next(page_head));
330 if (lmt_page_builder_state.contents != contribute_nothing) {
331 halfword r;
332 tex_print_format("%l[total height %P, goal height %p]",
333 page_total, page_stretch, page_filstretch, page_fillstretch, page_filllstretch, page_shrink,
334 page_goal
335 );
336 r = node_next(page_insert_head);
337 while (r != page_insert_head) {
338 halfword index = insert_index(r);
339 halfword multiplier = tex_get_insert_multiplier(index);
340 halfword size = multiplier == scaling_factor ? insert_total_height(r) : tex_x_over_n(insert_total_height(r), scaling_factor) * multiplier;
341 if (node_type(r) == split_node && node_subtype(r) == insert_split_subtype) {
342 halfword q = page_head;
343 halfword n = 0;
344 do {
345 q = node_next(q);
346 if (node_type(q) == insert_node && split_insert_index(q) == insert_index(r)) {
347 ++n;
348 }
349 } while (q != split_broken_insert(r));
350 tex_print_format("%l[insert %i adds %p, might split to %i]", index, size, n);
351 } else {
352 tex_print_format("%l[insert %i adds %p]", index, size);
353 }
354 r = node_next(r);
355 }
356 }
357 }
358 if (node_next(contribute_head)) {
359 tex_print_format("%l[recent contributions:]");
360 }
361 }
362 tex_print_format("%l[begin list]");
363 tex_show_box(node_next(n.head));
364 tex_print_format("%l[end list]");
365
366 switch (n.mode) {
367 case vmode:
368 case internal_vmode:
369 {
370 if (n.prev_depth <= ignore_depth_criterion_par) {
371 tex_print_format("%l[prevdepth ignored");
372 } else {
373 tex_print_format("%l[prevdepth %p", n.prev_depth);
374 }
375 if (n.prev_graf != 0) {
376 tex_print_format(", prevgraf %i line%s", n.prev_graf, n.prev_graf == 1 ? "" : "s");
377 }
378 tex_print_char(']');
379 break;
380 }
381 case mmode:
382 case inline_mmode:
383 {
384 if (n.incomplete_noad) {
385 tex_print_format("%l[this will be denominator of:]");
386 tex_print_format("%l[begin list]");
387 tex_show_box(n.incomplete_noad);
388 tex_print_format("%l[end list]");
389 }
390 break;
391 }
392 }
393 }
394}
395
396int tex_vmode_nest_index(void)
397{
398 int p = lmt_nest_state.nest_data.ptr;
399 while (! is_v_mode(lmt_nest_state.nest[p].mode)) {
400 --p;
401 }
402 return p;
403}
404
405void tex_tail_prepend(halfword n)
406{
407 tex_couple_nodes(node_prev(cur_list.tail), n);
408 tex_couple_nodes(n, cur_list.tail);
409 if (cur_list.tail == cur_list.head) {
410 cur_list.head = n;
411 }
412}
413
414void tex_tail_append(halfword p)
415{
416 node_next(cur_list.tail) = p;
417 node_prev(p) = cur_list.tail;
418 cur_list.tail = p;
419}
420
421void tex_tail_append_list(halfword p)
422{
423 node_next(cur_list.tail) = p;
424 node_prev(p) = cur_list.tail;
425 cur_list.tail = tex_tail_of_node_list(p);
426}
427
428 |