Back to index

texmacs  1.0.7.15
bridge_mark.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : bridge_mark.cpp
00004 * DESCRIPTION: Bridge between logical and physical paragraph markings
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "bridge.hpp"
00013 
00014 class bridge_mark_rep: public bridge_rep {
00015 protected:
00016   bridge body;
00017 
00018 public:
00019   bridge_mark_rep (typesetter ttt, tree st, path ip);
00020   void initialize ();
00021 
00022   void notify_assign (path p, tree u);
00023   void notify_insert (path p, tree u);
00024   void notify_remove (path p, int nr);
00025   bool notify_macro  (int type, string var, int level, path p, tree u);
00026   void notify_change ();
00027 
00028   void my_exec_until (path p);
00029   bool my_typeset_will_be_complete ();
00030   void my_typeset (int desired_status);
00031 };
00032 
00033 bridge_mark_rep::bridge_mark_rep (typesetter ttt, tree st, path ip):
00034   bridge_rep (ttt, st, ip)
00035 {
00036   initialize ();
00037 }
00038 
00039 void
00040 bridge_mark_rep::initialize () {
00041   if (is_nil (body)) body= make_bridge (ttt, st[1], descend (ip, 1));
00042   else replace_bridge (body, st[1], descend (ip, 1));
00043 }
00044 
00045 bridge
00046 bridge_mark (typesetter ttt, tree st, path ip) {
00047   return tm_new<bridge_mark_rep> (ttt, st, ip);
00048 }
00049 
00050 /******************************************************************************
00051 * Event notification
00052 ******************************************************************************/
00053 
00054 void
00055 bridge_mark_rep::notify_assign (path p, tree u) {
00056   // cout << "Assign " << p << ", " << u << " in " << st << "\n";
00057   ASSERT (!is_nil (p) || is_func (u, MARK), "nil path");
00058   if (is_nil (p) || (p->item != 1)) {
00059     st= substitute (st, p, u);
00060     initialize ();
00061   }
00062   else {
00063     // bool mp_flag= is_multi_paragraph (st);
00064     if (is_atom (p)) {
00065       body= make_bridge (ttt, u, descend (ip, 1));
00066       st= substitute (st, 1, body->st);
00067     }
00068     else {
00069       body->notify_assign (p->next, u);
00070       st= substitute (st, p->item, body->st);
00071     }
00072     // if (mp_flag != is_multi_paragraph (st)) initialize ();
00073   }
00074   status= CORRUPTED;
00075 }
00076 
00077 void
00078 bridge_mark_rep::notify_insert (path p, tree u) {
00079   // cout << "Insert " << p << ", " << u << " in " << st << "\n";
00080   ASSERT (!is_nil (p), "nil path");
00081   if (is_atom (p) || (p->item != 1)) bridge_rep::notify_insert (p, u);
00082   else {
00083     // bool mp_flag= is_multi_paragraph (st);
00084     body->notify_insert (p->next, u);
00085     st= substitute (st, 1, body->st);
00086     // if (mp_flag != is_multi_paragraph (st)) initialize ();
00087   }
00088   status= CORRUPTED;
00089 }
00090 
00091 void
00092 bridge_mark_rep::notify_remove (path p, int nr) {
00093   // cout << "Remove " << p << ", " << nr << " in " << st << "\n";
00094   ASSERT (!is_nil (p), "nil path");
00095   if (is_atom (p) || (p->item != 1)) bridge_rep::notify_remove (p, nr);
00096   else {
00097     // bool mp_flag= is_multi_paragraph (st);
00098     body->notify_remove (p->next, nr);
00099     st= substitute (st, 1, body->st);
00100     // if (mp_flag != is_multi_paragraph (st)) initialize ();
00101   }
00102   status= CORRUPTED;
00103 }
00104 
00105 bool
00106 bridge_mark_rep::notify_macro (int tp, string var, int l, path p, tree u) {
00107   /*
00108   cout << "Macro argument " << var << " [action=" << tp
00109        << ", level=" << l << "] " << p << ", " << u << " in " << st << "\n";
00110   */
00111 
00112   bool flag= env->depends (st[0], var, l) || env->depends (st[1], var, l);
00113   if (flag) initialize ();
00114   flag= body->notify_macro (tp, var, l, p, u) || flag;
00115   if (flag) status= CORRUPTED;
00116   return flag;
00117 }
00118 
00119 void
00120 bridge_mark_rep::notify_change () {
00121   status= CORRUPTED;
00122   body->notify_change ();
00123 }
00124 
00125 /******************************************************************************
00126 * Typesetting
00127 ******************************************************************************/
00128 
00129 void
00130 bridge_mark_rep::my_exec_until (path p) {
00131   if (p->item == 1) body->exec_until (p->next);
00132   else env->exec_until (st, p);
00133 }
00134 
00135 bool
00136 bridge_mark_rep::my_typeset_will_be_complete () {
00137   if (status != CORRUPTED) return false;
00138   return body->my_typeset_will_be_complete ();
00139 }
00140 
00141 void
00142 bridge_mark_rep::my_typeset (int desired_status) {
00143   // cout << "Argument " << t << ", " << ip << "\n";
00144   if (is_func (st[0], ARG) &&
00145       is_atomic (st[0][0]) &&
00146       (!is_nil (env->macro_arg)) &&
00147       env->macro_arg->item->contains (st[0][0]->label))
00148     {
00149       string name = st[0][0]->label;
00150       tree   value= env->macro_arg->item [name];
00151       path   valip= decorate_right (ip);
00152       if (!is_func (value, BACKUP)) {
00153        path new_valip= env->macro_src->item [name];
00154        if (is_accessible (new_valip)) valip= new_valip;
00155       }
00156 
00157       if (N(st[0]) > 1) {
00158        int i, n= N(st[0]);
00159        for (i=1; i<n; i++) {
00160          tree r= env->exec (st[0][i]);
00161          if (!is_int (r)) break;
00162          int nr= as_int (r);
00163          if ((!is_compound (value)) || (nr<0) || (nr>=N(value))) break;
00164          value= value[nr];
00165          valip= descend (valip, nr);
00166        }
00167       }
00168       if (is_compound (value))
00169        ttt->insert_marker (st, valip);
00170     }
00171 
00172   body->typeset (desired_status);
00173 }