void tex::show_discretionary(ptr p) { print_esc("discretionary"); if (replace_count(p) > 0) { print(" replacing "); print_int(replace_count(p)); } node_list_display(pre_break(p)); append_char('|'); show_node_list(post_break(p)); flush_char(); }
void tex::delete_last () { int m; ptr p=0, q; if (mode == VMODE && tail == head) { if (cur_chr != GLUE_NODE || last_glue != null) { you_cant(); if (cur_chr == KERN_NODE) { help_delete_last_kern(); } else if (cur_chr == GLUE_NODE) { help_delete_last_skip(); } else { help_delete_last_pen(); } error(); } } else if (!is_char_node(tail) && type(tail) == cur_chr) { for (q = head; q != tail; q = link(p)) { p = q; if (!is_char_node(q) && type(q) == DISC_NODE) { for (m = 1; m <= replace_count(q); incr(m)) p = link(p); if (p == tail) return; } } link(p) = null; flush_node_list(tail); tail = p; } }
tex::disc_t::disc_t() { tex::type(this) = DISC_NODE; replace_count(this) = 0; pre_break(this) = 0; post_break(this) = 0; }
void hyphenate () { str t, u; ptr q, r, s; ptr hyf_node; int bchar; int c_loc; int r_count; ptr major_tail; ptr minor_tail; int c, h, i, j, l, v, z; for (j = 0; j <= hn; incr(j)) hyf[j] = 0; h = hc[1]; incr(hn); hc[hn] = cur_lang; for (j = 2; j <= hn; incr(j)) h = (h + h + hc[j]) % HYPH_SIZE; loop { t = hyph_word[h]; if (t == null_str) goto not_found; l = hyph_len[h]; if (l < hn) goto not_found; if (l == hn) { j = 1; u = t; while (j <= hn) { if (*u < hc[j]) goto not_found; if (*u > hc[j]) goto done; incr(u); incr(j); } for (s = hyph_list[h]; s != null; s = link(s)) hyf[info(s)] = 1; decr(hn); goto found; } done: if (h > 0) { decr(h); } else { h = HYPH_SIZE; } } not_found: decr(hn); if (trie_char(cur_lang + 1) != cur_lang) return; hc[0] = 0; hc[hn + 1] = 0; hc[hn + 2] = 256; for (j = 0; j <= hn - r_hyf + 1; incr(j)) { z = trie_link(cur_lang + 1) + hc[j]; l = j; while (hc[l] == trie_char(z)) { if (v = trie_op(z)) { while (v) { v += op_start[cur_lang]; i = l - hyf_distance[v]; if (hyf_num[v] > hyf[i]) hyf[i] = hyf_num[v]; v = hyf_next[v]; } } incr(l); z = trie_link(z) + hc[l]; } } found: for (j = 0; j < l_hyf; incr(j)) { hyf[j] = 0; } for (j = 0; j < r_hyf; incr(j)) { hyf[hn - j] = 0; } for (j = l_hyf; j <= hn - r_hyf; incr(j)) if (odd(hyf[j])) goto found1; return; found1: q = link(hb); link(hb) = null; r = link(ha); link(ha) = null; bchar = NON_CHAR; if (type(hb) == LIGATURE_NODE && odd(subtype(hb))) { bchar = font_bchar(hf); } if (is_char_node(ha)) { if (font(ha) != hf) { goto found2; } else { init_list = ha; init_lig = FALSE; hu[0] = character(ha); } } else if (type(ha) == LIGATURE_NODE) { if (font(lig_char(ha)) != hf) { goto found2; } else { init_list = lig_ptr(ha); init_lig = TRUE; init_lft = subtype(ha) > 1; hu[0] = character(lig_char(ha)); if (init_list == null && init_lft) { hu[0] = 256; init_lig = FALSE; } free_node(ha, SMALL_NODE_SIZE); } } else { if (type(r) == LIGATURE_NODE && subtype(r) > 1) { goto found2; } j = 1; s = ha; init_list = null; goto common_end; } s = cur_p; while (link(s) != ha) s = link(s); j = 0; goto common_end; found2: s = ha; j = 0; hu[0] = 256; init_lig = FALSE; init_list = null; common_end: flush_node_list(r); #define advance_major_tail() \ { major_tail = link(major_tail); \ incr(r_count); \ } #define put_pre_break() \ { minor_tail = null; \ pre_break(r) = null; \ hyf_node = new_character(hf, hyf_char); \ if (hyf_node != null) { \ incr(i); \ c = hu[i]; \ hu[i] = hyf_char; \ free_avail(hyf_node); \ } \ while (l <= i) { \ l = reconstitute(l, i, font_bchar(hf), NON_CHAR) + 1; \ if (link(hold_head) == null) { \ continue; \ } \ if (minor_tail == null) { \ pre_break(r) = link(hold_head); \ } else { \ link(minor_tail) = link(hold_head); \ } \ minor_tail = link(hold_head); \ while (link(minor_tail) != null) \ minor_tail = link(minor_tail); \ } \ if (hyf_node != null) { \ hu[i] = c; \ l = i; \ decr(i); \ } \ } #define put_post_break() \ { minor_tail = null; \ post_break(r) = null; \ c_loc = 0; \ if (bchar_label(hf) != NON_ADDRESS) { \ decr(l); \ c = hu[l]; \ c_loc = l; \ hu[l] = 256; \ } \ while (l < j) { \ do { \ l = reconstitute(l, hn, bchar, NON_CHAR) + 1; \ if (c_loc > 0) { \ hu[c_loc] = c; \ c_loc = 0; \ } \ if (link(hold_head) == null) { \ continue; \ } \ if (minor_tail == null) { \ post_break(r) = link(hold_head); \ } else { \ link(minor_tail) = link(hold_head); \ } \ minor_tail = link(hold_head); \ while (link(minor_tail) != null) \ minor_tail = link(minor_tail); \ } while (l < j); \ while (l > j) { \ j = reconstitute(j, hn, bchar, NON_CHAR) + 1; \ link(major_tail) = link(hold_head); \ while (link(major_tail) != null) { \ advance_major_tail(); \ } \ } \ } \ } do { l = j; j = reconstitute(j, hn, bchar, hyf_char) + 1; if (hyphen_passed == 0) { link(s) = link(hold_head); while (link(s) != null) s = link(s); if (odd(hyf[j - 1])) { l = j; hyphen_passed = j - 1; link(hold_head) = null; } } if (hyphen_passed > 0) { do { r = new_node(SMALL_NODE_SIZE); link(r) = link(hold_head); type(r) = DISC_NODE; major_tail = r; r_count = 0; while (link(major_tail) != null) { advance_major_tail(); } i = hyphen_passed; hyf[i] = 0; put_pre_break(); put_post_break(); if (r_count > 127) { link(s) = link(r); link(r) = null; flush_node_list(r); } else { link(s) = r; replace_count(r) = r_count; } s = major_tail; hyphen_passed = j - 1; link(hold_head) = null; } while (odd(hyf[j - 1])); } } while (j <= hn); link(s) = q; flush_list(init_list); }
void tex::build_discretionary () { int n; ptr p, q; unsave(); q = head; p = link(q); n = 0; while (p != null) { if (!is_char_node(p) && type(p) > RULE_NODE && type(p) != KERN_NODE && type(p) != LIGATURE_NODE) { print_err("Improper discretionary list"); help_discretionary(); error(); flush_discretionary(p); link(q) = null; break; } q = p; p = link(q); incr(n); } p = link(head); pop_nest(); switch (saved(-1)) { case 0: pre_break(tail) = p; break; case 1: post_break(tail) = p; break; case 2: if (n > 0 && abs(mode) == MMODE) { print_err("Illegal math "); print_esc("discretionary"); help_math_disc(); flush_node_list(p); n = 0; error(); } else { link(tail) = p; } if (n <= MAX_QUARTERWORD) { replace_count(tail) = n; } else { print_err("Discretionary list is too long"); help_disc(); error(); } if (n > 0) tail = q; decr(save_ptr); return; } incr(saved(-1)); scan_left_brace(); new_save_level(DISC_GROUP); push_nest(); mode = -HMODE; space_factor = 1000; }
void tex::begin_box(int box_context) { int k, m, n; ptr p=0, q; switch (cur_chr) { case BOX_CODE: scan_eight_bit_int(); cur_box = box(cur_val); box(cur_val) = null; break; case COPY_CODE: scan_eight_bit_int(); cur_box = copy_node_list(box(cur_val)); break; case LAST_BOX_CODE: cur_box = null; if (abs(mode) == MMODE) { you_cant(); help_lastbox_m(); error(); } else if (mode == VMODE && head == tail) { you_cant(); help_lastbox_v(); error(); } else if (type(tail) == HLIST_NODE || type(tail) == VLIST_NODE) { for (q = head; q != tail; q = link(p)) { p = q; if (type(q) == DISC_NODE) { m = 1; while (m <= replace_count(q)) { p = link(p); incr(m); } if (p == tail) { break; } } } cur_box = tail; shift_amount(cur_box) = 0; tail = p; link(p) = null; } break; case VSPLIT_CODE: scan_eight_bit_int(); n = cur_val; if (!scan_keyword("to")) { print_err("Missing `to' inserted"); help_vsplit(); error(); } scan_normal_dimen(); cur_box = vsplit(n, cur_val); break; default: k = cur_chr - VTOP_CODE; saved(0) = box_context; if (k == HMODE) { if (box_context < BOX_FLAG && abs(mode) == VMODE) { scan_spec(ADJUSTED_HBOX_GROUP, TRUE); } else { scan_spec(HBOX_GROUP, TRUE); } } else { if (k == VMODE) { scan_spec(VBOX_GROUP, TRUE); } else { scan_spec(VTOP_GROUP, TRUE); k = VMODE; } normal_paragraph(); } push_nest(); mode = -k; if (k == VMODE) { prev_depth = IGNORE_DEPTH; if (every_vbox != null) begin_token_list(every_vbox, EVERY_VBOX_TEXT); } else { space_factor = 1000; if (every_hbox != null) begin_token_list(every_hbox, EVERY_HBOX_TEXT); } return; } box_end(box_context); }
void tex::short_display(ptr p) { int n; for (; p != null; p = link(p)) { if (is_char_node(p)) { if (font(p) != font_in_short_display) { if (font(p) < FONT_BASE || font(p) > FONT_MAX) { print("*"); } else { print_esc(null_str); print(font_id_text(font(p))); } print(" "); font_in_short_display = font(p); } print_ASCII(character(p)); } else { switch (tex::type(p)) { case HLIST_NODE: case VLIST_NODE: case INS_NODE: case WHATSIT_NODE: case MARK_NODE: case ADJUST_NODE: case UNSET_NODE: print("[]"); break; case RULE_NODE: print("|"); break; case GLUE_NODE: if (glue_ptr(p) != zero_glue) print(" "); break; case MATH_NODE: print("$"); break; case LIGATURE_NODE: short_display(lig_ptr(p)); break; case DISC_NODE: short_display(pre_break(p)); short_display(post_break(p)); n = replace_count(p); while (n > 0) { if (link(p) != null) p = link(p); decr(n); } break; default: break; } } } }