Back to index

texmacs  1.0.7.15
bridge_locus.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : bridge_locus.cpp
00004 * DESCRIPTION: Bridge between logical and physical local enviroment changes
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_locus_rep: public bridge_rep {
00015 protected:
00016   int    last;
00017   bridge body;
00018 
00019 public:
00020   bridge_locus_rep (typesetter ttt, tree st, path ip);
00021   void initialize ();
00022 
00023   void notify_assign (path p, tree u);
00024   void notify_insert (path p, tree u);
00025   void notify_remove (path p, int nr);
00026   bool notify_macro  (int type, string var, int level, path p, tree u);
00027   void notify_change ();
00028 
00029   void my_exec_until (path p);
00030   bool my_typeset_will_be_complete ();
00031   void my_typeset (int desired_status);
00032 };
00033 
00034 bridge_locus_rep::bridge_locus_rep (typesetter ttt, tree st, path ip):
00035   bridge_rep (ttt, st, ip)
00036 {
00037   initialize ();
00038 }
00039 
00040 void
00041 bridge_locus_rep::initialize () {
00042   last= N(st)-1;
00043   if (is_nil(body)) body= make_bridge (ttt, st[last], descend (ip, last));
00044   else replace_bridge (body, st[last], descend (ip, last));
00045 }
00046 
00047 bridge
00048 bridge_locus (typesetter ttt, tree st, path ip) {
00049   return tm_new<bridge_locus_rep> (ttt, st, ip);
00050 }
00051 
00052 /******************************************************************************
00053 * Event notification
00054 ******************************************************************************/
00055 
00056 void
00057 bridge_locus_rep::notify_assign (path p, tree u) {
00058   // cout << "Assign " << p << ", " << u << " in " << st << "\n";
00059   ASSERT (!is_nil (p) || is_func (u, LOCUS), "nil path");
00060   if (is_nil (p)) {
00061     st= u;
00062     initialize ();
00063   }
00064   else {
00065     bool mp_flag= is_multi_paragraph (st);
00066     if (p->item == last) {
00067       if (is_atom (p)) body= make_bridge (ttt, u, descend (ip, last));
00068       else body->notify_assign (p->next, u);
00069       st= substitute (st, p->item, body->st);
00070     }
00071     else {
00072       st= substitute (st, p, u);
00073       body->notify_change ();
00074     }
00075     if (mp_flag != is_multi_paragraph (st)) initialize ();
00076   }
00077   status= CORRUPTED;
00078 }
00079 
00080 void
00081 bridge_locus_rep::notify_insert (path p, tree u) {
00082   // cout << "Insert " << p << ", " << u << " in " << st << "\n";
00083   ASSERT (!is_nil (p), "nil path");
00084   if (is_atom (p) || (p->item != last)) bridge_rep::notify_insert (p, u);
00085   else {
00086     bool mp_flag= is_multi_paragraph (st);
00087     body->notify_insert (p->next, u);
00088     st= substitute (st, last, body->st);
00089     if (mp_flag != is_multi_paragraph (st)) initialize ();
00090   }
00091   status= CORRUPTED;
00092 }
00093 
00094 void
00095 bridge_locus_rep::notify_remove (path p, int nr) {
00096   // cout << "Remove " << p << ", " << nr << " in " << st << "\n";
00097   ASSERT (!is_nil (p), "nil path");
00098   if (is_atom (p) || (p->item != last)) bridge_rep::notify_remove (p, nr);
00099   else {
00100     bool mp_flag= is_multi_paragraph (st);
00101     body->notify_remove (p->next, nr);
00102     st= substitute (st, last, body->st);
00103     if (mp_flag != is_multi_paragraph (st)) initialize ();
00104   }
00105   status= CORRUPTED;
00106 }
00107 
00108 bool
00109 bridge_locus_rep::notify_macro (int type, string var, int l, path p, tree u) {
00110   bool flag= body->notify_macro (type, var, l, p, u);
00111   if (flag) status= CORRUPTED;
00112   return flag;
00113 }
00114 
00115 void
00116 bridge_locus_rep::notify_change () {
00117   status= CORRUPTED;
00118   body->notify_change ();
00119 }
00120 
00121 /******************************************************************************
00122 * Typesetting
00123 ******************************************************************************/
00124 
00125 void
00126 bridge_locus_rep::my_exec_until (path p) {
00127   if (p->item == last) body->exec_until (p->next);
00128   else env->exec_until (st, p);
00129 }
00130 
00131 bool
00132 bridge_locus_rep::my_typeset_will_be_complete () {
00133   if (status != CORRUPTED) return false;
00134   return body->my_typeset_will_be_complete ();
00135 }
00136 
00137 void
00138 bridge_locus_rep::my_typeset (int desired_status) {
00139   extern bool build_locus (edit_env env, tree t, list<string>& ids, string& c);
00140   list<string> ids;
00141   string col;
00142   if (!build_locus (env, st, ids, col))
00143     system_warning ("Ignored unaccessible loci");
00144   tree old_col= env->read (COLOR);
00145   env->write_update (COLOR, col);
00146   ttt->insert_marker (st, ip);
00147   body->typeset (desired_status);
00148   env->write_update (COLOR, old_col);
00149 }