void notify_remove_node (typesetter ttt, path p) { // cout << "Remove node " << p << "\n"; tree t= subtree (ttt->br->st, p); if (is_nil (path_up (p))) ttt->br= make_bridge (ttt, t, ttt->br->ip); else ttt->br->notify_assign (path_up (p), t); }
bool edit_interface_rep::complete_keypress (string key) { set_message ("", ""); if (key == "space") key= " "; if ((key != "tab") && (key != "S-tab")) { set_input_normal (); return false; } tree st= subtree (et, path_up (tp)); if (is_compound (st)) { set_input_normal (); return false; } string s= st->label; int end= last_item (tp); string old_s= completions [completion_pos]; string test= completion_prefix * old_s; if ((end<N(test)) || (s (end-N(test), end) != test)) { set_input_normal (); return false; } if (key == "tab") completion_pos++; else completion_pos--; if (completion_pos < 0) completion_pos= N(completions)-1; if (completion_pos >= N(completions)) completion_pos= 0; string new_s= completions [completion_pos]; remove (path_up (tp) * (end-N(old_s)), N(old_s)); insert (path_up (tp) * (end-N(old_s)), new_s); complete_message (); return true; }
static path table_search_format (tree t, path p) { tree st= subtree (t, p); if (is_func (st, TFORMAT) && is_func (st[N(st)-1], TABLE)) return p; while ((!is_nil (p)) && (!is_func (subtree (t, p), TABLE))) p= path_up (p); if ((!is_nil (p)) && (is_func (subtree (t, path_up (p)), TFORMAT))) p= path_up (p); return p; }
void edit_interface_rep::set_right_footer () { tree cf= compute_compound_footer (et, path_up (tp)); tree st= subtree (et, path_up (tp)); tree lf; if (is_atomic (st)) lf= compute_text_footer (st); else lf= compute_operation_footer (st); if (N(focus_get (false))+1 >= N(tp)) cf= concat (cf, lf); set_right_footer (cf); }
void notify_insert_node (typesetter ttt, path p, tree t) { // cout << "Insert node " << p << ", " << t << "\n"; int i, pos= last_item (p), n= N(t); tree r (t, n+1); for (i=0; i<pos; i++) r[i]= t[i]; r[pos]= subtree (ttt->br->st, path_up (p)); for (i=pos; i<n; i++) r[i+1]= t[i]; if (is_nil (path_up (p))) ttt->br= make_bridge (ttt, r, ttt->br->ip); else ttt->br->notify_assign (path_up (p), r); }
void edit_select_rep::cut (path p1, path p2) { path p = common (p1, p2); tree st= subtree (et, p); raw_cut (p1, p2); if (!is_func (st, TFORMAT) && !is_func (st, TABLE) && !is_func (st, ROW) && !is_document (subtree (et, p)) && is_concat (subtree (et, path_up (p)))) correct_concat (path_up (p)); }
bool admissible_selection (gr_selection sel) { if (sel->type != "box" || N(sel->cp) != 1) return true; if (last_item (sel->cp[0]) < 0 || N(sel->cp[0]) <= 2) return true; path p= path_up (sel->cp[0]); if (!has_subtree (the_et, p)) return true; tree st= subtree (the_et, p); if (is_compound (st, "anim-edit")) return false; tree pt= subtree (the_et, path_up (p)); if (is_func (st, WITH) && is_compound (pt, "anim-edit")) return false; return true; }
vector < pair <int,int> > get_path(int v, int u) { int w=lca(v, u); auto ret=path_up(v, w); auto pom=path_up(u, w); for (auto &i : ret) swap(i.first, i.second); while(!pom.empty()) { ret.push_back(pom.back()); pom.pop_back(); } return ret; }
grid edit_graphics_rep::find_grid () { bool bp_found; path bp= eb->find_box_path (tp, bp_found); if (bp_found) return eb->find_grid (path_up (bp)); else return grid (); }
void edit_graphics_rep::find_limits (point& lim1, point& lim2) { lim1= point (); lim2= point (); bool bp_found; path bp= eb->find_box_path (tp, bp_found); if (bp_found) eb->find_limits (path_up (bp), lim1, lim2); }
bool edit_interface_rep::complete_try () { tree st= subtree (et, path_up (tp)); if (is_compound (st)) return false; string s= st->label, ss; int end= last_item (tp); array<string> a; if (inside (LABEL) || inside (REFERENCE) || inside (PAGEREF)) { if (end != N(s)) return false; ss= copy (s); tree t= get_labels (); int i, n= N(t); for (i=0; i<n; i++) if (is_atomic (t[i]) && starts (t[i]->label, s)) a << string (t[i]->label (N(s), N(t[i]->label))); } else { if ((end==0) || (!is_iso_alpha (s[end-1])) || ((end!=N(s)) && is_iso_alpha (s[end]))) return false; int start= end-1; while ((start>0) && is_iso_alpha (s[start-1])) start--; ss= s (start, end); a= find_completions (drd, et, ss); } if (N(a) == 0) return false; complete_start (ss, a); return true; }
void edit_interface_rep::complete_start (string prefix, array<string> compls) { // check consistency tree st= subtree (et, path_up (tp)); if (is_compound (st)) return; string s= st->label; int end= last_item (tp); if ((end<N(prefix)) || (s (end-N(prefix), end) != prefix)) return; // perform first completion and switch to completion mode if necessary if (N (compls) == 1) { string s= compls[0]; if (ends (s, "()")) // temporary fix for Pari insert_tree (s, path (N(s)-1)); else insert_tree (s); completions= array<string> (); } else { completion_prefix= prefix; completions = close_completions (compls); completion_pos = 0; insert_tree (completions[0]); complete_message (); beep (); set_input_mode (INPUT_COMPLETE); } }
bool edit_interface_rep::set_latex_footer (tree st) { if (is_atomic (st)) if (is_func (subtree (et, path_up (tp, 2)), LATEX, 1) || is_func (subtree (et, path_up (tp, 2)), HYBRID, 1)) { string s= st->label; string help; command cmd; if (sv->kbd_get_command (s, help, cmd)) { set_left_footer (concat (kbd ("return"), ": " * help)); set_right_footer ("latex command"); return true; } } return false; }
frame edit_graphics_rep::find_frame (bool last) { bool bp_found; path bp= eb->find_box_path (tp, bp_found); if (bp_found) return eb->find_frame (path_up (bp), last); else return frame (); }
bool edit_interface_rep::set_hybrid_footer (tree st) { // WARNING: update edit_dynamic_rep::activate_hybrid when updating this if (is_atomic (st)) if (is_func (subtree (et, path_up (tp, 2)), HYBRID, 1)) { string msg; // macro argument string name= st->label; path mp= search_upwards (MACRO); if (!is_nil (mp)) { tree mt= subtree (et, mp); int i, n= N(mt)-1; for (i=0; i<n; i++) if (mt[i] == name) { set_message (concat (kbd ("return"), ": insert argument ", name), "hybrid command"); return true; } } // macro application tree f= get_env_value (name); if (drd->contains (name) && (f == UNINIT)) set_message (concat (kbd ("return"), ": insert primitive ", name), "hybrid command"); else if (is_func (f, MACRO) || is_func (f, XMACRO)) set_message (concat (kbd ("return"), ": insert macro ", name), "hybrid command"); else if (f != UNINIT) set_message (concat (kbd ("return"), ": insert value ", name), "hybrid command"); else return false; return true; } return false; }
void edit_graphics_rep::back_in_text_at (tree t, path p, bool forward) { (void) forward; int i= last_item (p); if ((i == 0) && is_empty (t[0])) { p= path_up (p); if (is_func (subtree (et, path_up (p)), WITH)) p= path_up (p); tree st= subtree (et, path_up (p)); if (is_func (st, GRAPHICS)) { if (N(st) == 1) assign (p, ""); else { remove (p, 1); go_to_border (path_up (p) * 0, true); } } } }
path edit_select_rep::selection_get_path () { path start, end; selection_get (start, end); if (end == start && end_p != start_p) return path_up (start); return common (start, end); }
void edit_select_rep::select_enlarge () { path sp, sq; if (start_p == end_p) { sp= path_up (start_p); sq= sp; } else { sp= common (start_p, end_p); if (!(rp < sp)) { selection_cancel (); set_message ("", ""); return; } sq= path_up (sp); } path pp= sp, p1= start_p, p2= end_p; if (start_p == pp * 0 && end_p == pp * right_index (subtree (et, pp))) if (!is_nil (pp)) pp= path_up (pp); if (is_func (subtree (et, pp), TFORMAT)) pp= path_up (pp); if (semantic_select (pp, p1, p2, 1)) select (p1, p2); else { if (is_atomic (subtree (et, sp))) select_enlarge_text (); else select (sq * 0, sq * 1); } path p = common (start_p, end_p); tree st= subtree (et, p); if (drd->var_without_border (L(st)) || is_func (st, TFORMAT) || is_func (st, DOCUMENT, 1) || is_script (st) || incomplete_script_selection (st, start_p / p, end_p / p)) select_enlarge (); else { tree s; if (is_atomic (st)) s= "text"; else if (is_func (st, COMPOUND)) s= as_string (st[0]); else if (is_func (st, WITH)) s= concat ("with ", as_string (st[0])); else s= as_string (L(st)); set_message (concat ("selected ", s), "enlarge selection"); } selecting= shift_selecting= false; }
void edit_select_rep::select_enlarge_text () { path p= common (start_p, end_p); if (start_p == end_p) p= path_up (p); tree st= subtree (et, p); ASSERT (is_atomic (st), "non textual tree"); string s= st->label; string mode= get_env_string (MODE); int i1= last_item (start_p), j1= i1; int i2= last_item (end_p), j2= i2; path q= path_up (p); if (mode == "text" || mode == "src") { int i, f= 4; if (i1 > 0) { i= i1; tm_char_backwards (s, i); f= min (f, breaking_force (s[i])); } if (i2 < N(s)) f= min (f, breaking_force (s[i2])); while (i1 > 0) { i= i1; tm_char_backwards (s, i); if (breaking_force (s[i]) > f) break; i1= i; } while (i2 < N(s)) { if (breaking_force (s[i2]) > f) break; tm_char_forwards (s, i2); } if (i1 < i2 && (i1 != j1 || i2 != j2)) { if (is_concat (subtree (et, q)) && i1 == 0 && i2 == N(s)) select (q * 0, q * 1); else select (p * i1, p * i2); return; } } if (is_concat (subtree (et, q)) || (i1 == 0 && i2 == N(s))) select (q * 0, q * 1); else select (p * 0, p * N(s)); }
path edit_select_rep::focus_get (bool skip_flag) { //cout << "Search focus " << focus_p << ", " << skip_flag << "\n"; if (!is_nil (focus_p)) return focus_search (focus_p, skip_flag, false); if (selection_active_any ()) return focus_search (selection_get_path (), skip_flag, false); else return focus_search (path_up (tp), skip_flag, true); }
path edit_select_rep::semantic_root (path p) { while (p != rp) { tree st= subtree (et, path_up (p)); if (path_up (p) != rp && is_func (st, DOCUMENT, 1)) st= subtree (et, path_up (p, 2)); if (is_func (st, CELL)) break; if (is_compound (st) && N(st) == 1) { tree env= drd->get_env (L(st), 0); tree mt= drd_env_read (env, MODE); tree pt= drd_env_read (env, "prog-language"); if (mt == "math") break; if (mt == "prog" && pt == "minimal") break; if (mt == "text") return rp; } p= path_up (p); } return p; }
bool is_table_selection (tree et, path p1, path p2, bool strict) { if (p1 == p2) return false; path p= common (p1, p2); if ((p == p1 || p == p2) && !is_nil (p)) p= path_up (p); tree t= subtree (et, p); return is_func (t, TFORMAT) || is_func (t, TABLE) || is_func (t, ROW) || is_func (t, CELL) || (!strict && N(t) == 1 && is_func (t[0], TFORMAT)); }
bool edit_select_rep::selection_active_table (bool strict) { if (!selection_active_any ()) return false; path p= common (start_p, end_p); if ((p == start_p) || (p == end_p)) p= path_up (p); tree t= subtree (et, p); return is_func (t, TFORMAT) || is_func (t, TABLE) || is_func (t, ROW) || is_func (t, CELL) || (!strict && N(t) == 1 && is_func (t[0], TFORMAT)); }
tree edit_graphics_rep::get_graphics () { path p = path_up (tp); tree st = et; tree res = tree (); while (!is_nil (p)) { if (is_func (st, GRAPHICS)) res= st; st= st[p->item]; p = p->next; } return res; }
void edit_graphics_rep::find_limits (point& lim1, point& lim2) { path gp= graphics_path (); lim1= point (); lim2= point (); bool bp_found; path bp= eb->find_box_path (gp, bp_found); if (bp_found) eb->find_limits (path_up (bp), lim1, lim2); if (N(lim1) >= 2 && fabs (lim1[0]) <= 0.001) lim1[0]= 0.0; if (N(lim1) >= 2 && fabs (lim1[1]) <= 0.001) lim1[1]= 0.0; if (N(lim2) >= 2 && fabs (lim2[0]) <= 0.001) lim2[0]= 0.0; if (N(lim2) >= 2 && fabs (lim2[1]) <= 0.001) lim2[1]= 0.0; }
path edit_select_rep::focus_search (path p, bool skip_flag, bool up_flag) { //cout << "Search focus " << p << ", " << skip_flag << ", " << up_flag << "\n"; if (!(rp < p)) return rp; tree st= subtree (et, p); if (!skip_flag) return p; if (none_accessible (st) && p == path_up (tp) && last_item (tp) != 0) return p; if (is_atomic (st) || is_func (st, DOCUMENT) || is_func (st, CONCAT) || is_func (st, TFORMAT) || is_func (st, TABLE) || is_func (st, ROW) || is_func (st, CELL) || is_compound (st, "shown") || is_func (st, HIDDEN) || up_flag) return focus_search (path_up (p), skip_flag, false); return p; }
bool edit_graphics_rep::inside_graphics (bool b) { path p = path_up (tp); bool flag= false; tree st = et; while (!is_nil (p)) { if (is_func (st, GRAPHICS)) flag= true; if (b && is_func (st, TEXT_AT)) flag= false; if (is_atomic (st) || p->item < 0 || p->item >= N(st)) break; st= st[p->item]; p = p->next; } return flag || (L(st) == GRAPHICS); }
path find_innermost_scroll (box b, path p) { // Given a box b and a logical path p, this routine returns // the longest box path sp such that b[sp] is a scroll node path bp; while (true) { bool found= false; bp= b->find_box_path (p, found); if (found) break; p= path_up (p); if (is_nil (p)) return path (); } bp= path_up (bp); path cp, sp; while (!is_nil (bp)) { if (b->get_type () == SCROLL_BOX) sp= reverse (cp); b = b[bp->item]; cp= path (bp->item, cp); bp= bp->next; } if (is_nil (sp)) return sp; else return sp * 0; }
void edit_typeset_rep::typeset_exec_until (path p) { //time_t t1= texmacs_time (); if (has_changed (THE_TREE + THE_ENVIRONMENT)) if (p != correct_cursor (et, rp * 0)) { if (DEBUG_STD) std_warning << "resynchronizing for path " << p << "\n"; // apply_changes (); } if (p == tp && inside_graphics (true) && p != closest_inside (et, p)) { //cout << "TeXmacs] Warning: corrected cursor\n"; tp= closest_inside (et, tp); p = tp; } //cout << "Exec until " << p << LF; if (N(cur[p])!=0) return; if (N(cur)>=25) // avoids out of memory in weird cases typeset_invalidate_env (); typeset_prepare (); if (enable_fastenv) { if (!(rp < p)) { failed_error << "Erroneous path " << p << "\n"; FAILED ("invalid typesetting path"); } tree t= subtree (et, rp); path q= path_up (p / rp); while (!is_nil (q)) { int i= q->item; restricted_exec (env, t, i); tree w= drd->get_env_child (t, i, tree (ATTR)); if (w == "") break; //cout << "t= " << t << "\n"; //cout << "i= " << i << "\n"; //cout << "w= " << w << "\n"; for (int j=0; j<N(w); j+=2) { //cout << w[j] << " := " << env->exec (w[j+1]) << "\n"; env->write (w[j]->label, env->exec (w[j+1])); } t= t[i]; q= q->next; } if (env->read (PREAMBLE) == "true") env->write (MODE, "src"); } else exec_until (ttt, p / rp); env->read_env (cur (p)); //time_t t2= texmacs_time (); //if (t2 - t1 >= 10) cout << "typeset_exec_until took " << t2-t1 << "ms\n"; }
bool edit_select_rep::semantic_select (path p, path& q1, path& q2, int mode) { if (!semantic_active (p)) return false; if (mode < 2 && get_preference ("semantic selections") != "on") return false; p= semantic_root (p); while (p != rp && !(p <= q1 && p <= q2)) p= semantic_root (path_up (p)); tree mt= get_env_value (MODE, end (et, p)); tree lt= get_env_value (MODE_LANGUAGE (mt->label), end (et, p)); string lan= (is_atomic (lt)? lt->label: string ("std-math")); path p1= q1 / p, p2= q2 / p; path cp= (p <= tp? tp / p: path ()); tree st= subtree (et, p); bool ret= packrat_select (lan, "Main", st, cp, p1, p2, mode); if (ret) { q1= p * p1; q2= p * p2; } return ret; }