Back to index

texmacs  1.0.7.15
env_inactive.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : env_inactive.cpp
00004 * DESCRIPTION: rewrite inactive markup
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 "env.hpp"
00013 
00014 static tree
00015 subvar (tree var, int i) {
00016   tree svar= copy (var);
00017   return svar << as_string (i);
00018 }
00019 
00020 /******************************************************************************
00021 * Test whether a tree (argument) should be rendered in compact format or not.
00022 ******************************************************************************/
00023 
00024 bool is_long (tree t);
00025 
00026 bool
00027 is_long_arg (tree t, int i) {
00028   // FIXME: should go into the DRD
00029   int n= N(t);
00030   switch (L(t)) {
00031   case DOCUMENT:
00032   case INCLUDE:
00033   case TFORMAT:
00034   case TABLE:
00035     return true;
00036   case CONCAT:
00037     return false;
00038   case SURROUND:
00039     if (i == 2) return true;
00040     break;
00041   case ROW:
00042     return is_long (t[i]);
00043   case ASSIGN:
00044   case DATOMS:
00045   case DLINES:
00046   case DPAGES:
00047   case WITH:
00048   case MARK:
00049   case MACRO:
00050   case XMACRO:
00051   case CELL:
00052   case EVAL:
00053   case QUOTE:
00054   case QUASI:
00055   case QUASIQUOTE:
00056   case UNQUOTE:
00057   case VAR_UNQUOTE:
00058     if (i == n-1) return is_long (t[i]);
00059     break;
00060   case STYLE_WITH:
00061   case VAR_STYLE_WITH:
00062     if (i == n-1) {
00063       for (i=0; i<n-1; i+=2)
00064        if (t[i] == SRC_COMPACT) {
00065          if (t[i+1] == "none") return true;
00066          if (t[i+1] == "all")  return false;
00067        }
00068       return is_long (t[i]);
00069     }
00070     break;
00071   case STYLE_ONLY:
00072   case VAR_STYLE_ONLY:
00073   case ACTIVE:
00074   case VAR_ACTIVE:
00075     return is_multi_paragraph (t[i]);
00076   case LOCUS:
00077   case CANVAS:
00078   case ORNAMENT:
00079     if (i == n-1) return is_long (t[i]);
00080     break;
00081   default:
00082     break;
00083   }
00084 
00085   tree u= t[i];
00086   switch (L(u)) {
00087   case TWITH:
00088   case CWITH:
00089   case ROW:
00090     return true;
00091   default:
00092     if (L(t) < START_EXTENSIONS) return false;
00093     return is_long (u);
00094   }
00095 }
00096 
00097 bool
00098 is_long (tree t) {
00099   if (is_compound (t)) {
00100     int i, n= N(t);
00101     for (i=0; i<n; i++)
00102       if (is_long_arg (t, i))
00103        return true;
00104   }
00105   return false;
00106 }
00107 
00108 /******************************************************************************
00109 * For syntactic coloring
00110 ******************************************************************************/
00111 
00112 static tree
00113 highlight (tree t, tree orig, int kind) {
00114   switch (kind) {
00115   case TYPE_INVALID:
00116     return compound ("src-unknown", t);
00117   case TYPE_REGULAR:
00118     return compound ("src-regular", t);
00119   case TYPE_ADHOC:
00120     return compound ("src-textual", t);
00121   case TYPE_RAW:
00122     return compound ("src-error", t);
00123   case TYPE_VARIABLE:
00124     return compound ("src-var", t);
00125   case TYPE_ARGUMENT:
00126     return compound ("src-arg", t);
00127   case TYPE_BINDING:
00128     return compound ("src-regular", t);
00129   case TYPE_BOOLEAN:
00130     return compound ("src-numeric", t);
00131   case TYPE_INTEGER:
00132     return compound ("src-numeric", t);
00133   case TYPE_STRING:
00134     return compound ("src-textual", t);
00135   case TYPE_LENGTH:
00136     return compound ("src-length", t);
00137   case TYPE_NUMERIC:
00138     return compound ("src-numeric", t);
00139   case TYPE_CODE:
00140     return compound ("src-tt", t);
00141   case TYPE_IDENTIFIER:
00142     return compound ("src-tt", t);
00143   case TYPE_URL:
00144     return compound ("src-tt", t);
00145   case TYPE_GRAPHICAL:
00146     return compound ("src-regular", t);
00147   case TYPE_POINT:
00148     return compound ("src-regular", t);
00149   case TYPE_CONSTRAINT:
00150     return compound ("src-regular", t);
00151   case TYPE_GRAPHICAL_ID:
00152     return compound ("src-var", t);
00153   case TYPE_ANIMATION:
00154     return compound ("src-regular", t);
00155   case TYPE_DURATION:
00156     return compound ("src-length", t);
00157   case TYPE_OBSOLETE:
00158     return compound ("src-unknown", t);
00159   case TYPE_UNKNOWN:
00160     return compound ("src-unknown", t);
00161   case TYPE_ERROR:
00162     return compound ("src-error", t);
00163   default:
00164     return compound ("src-error", t);
00165   }
00166 }
00167 
00168 /******************************************************************************
00169 * Compute rendering of inactive markup
00170 ******************************************************************************/
00171 
00172 tree
00173 edit_env_rep::rewrite_inactive_arg (
00174   tree t, tree var, int i, bool block, bool flush)
00175 {
00176   tree r= subvar (var, i);
00177   if ((inactive_mode == INACTIVE_INLINE_RECURSE) ||
00178       (inactive_mode == INACTIVE_BLOCK_RECURSE))
00179     {
00180       if (N (recover_env) > 0) {
00181        int j;
00182        tree recover= copy (recover_env), old_recover= recover_env;
00183        for (j=0; j<N(recover); j+=2) {
00184          string var= recover[j]->label;
00185          recover[j+1]= read (var);
00186          write_update (var, recover_env[j+1]);
00187        }
00188        recover_env= tuple ();
00189        r= rewrite_inactive (t[i], r, block, flush);
00190        recover_env= old_recover;
00191        for (j=0; j<N(recover); j+=2)
00192          write_update (recover[j]->label, recover[j+1]);
00193       }
00194       else r= rewrite_inactive (t[i], r, block, flush);
00195     }
00196   return highlight (r, t[i], drd->get_type_child (t, i));
00197 }
00198 
00199 tree
00200 edit_env_rep::rewrite_inactive_raw_data (
00201   tree t, tree var, bool block, bool flush)
00202 {
00203   (void) t; (void) block;
00204   return rewrite_inactive_default (tree (RAW_DATA), var, block, flush);
00205 }
00206 
00207 tree
00208 edit_env_rep::rewrite_inactive_document (
00209   tree t, tree var, bool block, bool flush)
00210 {
00211   if ((block || (src_compact == COMPACT_NONE)) &&
00212       (src_special > SPECIAL_RAW) &&
00213       (src_compact != COMPACT_ALL))
00214     {
00215       int i, n= N(t);
00216       tree r (DOCUMENT, n);
00217       for (i=0; i<n; i++)
00218        r[i]= rewrite_inactive_arg (t, var, i, true, flush || (i<n-1));
00219       return r;
00220     }
00221   return rewrite_inactive_default (t, var, block, flush);
00222 }
00223 
00224 tree
00225 edit_env_rep::rewrite_inactive_concat (
00226   tree t, tree var, bool block, bool flush)
00227 {
00228   if ((src_special > SPECIAL_RAW) && (src_compact != COMPACT_NONE)) {
00229     int i, n= N(t);
00230     tree r (CONCAT, n);
00231     for (i=0; i<n; i++)
00232       r[i]= rewrite_inactive_arg (t, var, i, false, false);
00233     return r;
00234   }
00235   return rewrite_inactive_default (t, var, block, flush);
00236 }
00237 
00238 tree
00239 edit_env_rep::rewrite_inactive_value (
00240   tree t, tree var, bool block, bool flush)
00241 {
00242   if ((N(t) == 1) && is_atomic (t[0]) &&
00243       src_style != STYLE_SCHEME && src_special >= SPECIAL_NORMAL)
00244     {
00245       tree r= highlight (subvar (var, 0), t[0],
00246         inactive_mode == INACTIVE_INLINE_ERROR ||
00247        inactive_mode == INACTIVE_BLOCK_ERROR ?
00248        TYPE_INVALID: TYPE_VARIABLE);
00249       return tree (MARK, var, r);
00250   }
00251   return rewrite_inactive_default (t, var, block, flush);
00252 }
00253 
00254 tree
00255 edit_env_rep::rewrite_inactive_arg (
00256   tree t, tree var, bool block, bool flush)
00257 {
00258   if ((N(t) == 1) && is_atomic (t[0]) &&
00259       src_style != STYLE_SCHEME && src_special >= SPECIAL_NORMAL)
00260     {
00261       tree r= highlight (subvar (var, 0), t[0],
00262         inactive_mode == INACTIVE_INLINE_ERROR ||
00263        inactive_mode == INACTIVE_BLOCK_ERROR ?
00264        TYPE_INVALID: TYPE_ARGUMENT);
00265       return tree (MARK, var, r);
00266   }
00267   return rewrite_inactive_default (t, var, block, flush);
00268 }
00269 
00270 tree
00271 edit_env_rep::rewrite_inactive_symbol (
00272   tree t, tree var, bool block, bool flush)
00273 {
00274   if ((N(t) == 1) && is_atomic (t[0]) && (src_special >= SPECIAL_NORMAL)) {
00275     tree r (INLINE_TAG, subvar (var, 0));
00276     return tree (MARK, var, r);
00277   }
00278   return rewrite_inactive_default (t, var, block, flush);
00279 }
00280 
00281 tree
00282 edit_env_rep::rewrite_inactive_style_with (
00283   tree t, tree var, bool block, bool flush, bool once)
00284 {
00285   int i, n= N(t);
00286   tree recover= tuple ();
00287   for (i=0; i<n-1; i+=2)
00288     if (is_atomic (t[i])) {
00289       recover << t[i] << read (t[i]->label);
00290       write_update (t[i]->label, t[i+1]);
00291     }
00292   if (once) recover_env= recover;
00293   tree r= rewrite_inactive (t[n-1], subvar (var, n-1), block, flush);
00294   for (i=0; i<N(recover); i+=2)
00295     write_update (recover[i]->label, recover[i+1]);
00296   if (once) recover_env= tuple ();
00297   return tree (MARK, var, r);
00298 }
00299 
00300 tree
00301 edit_env_rep::rewrite_inactive_active (
00302   tree t, tree var, bool block, bool flush)
00303 {
00304   tree st= t[0];
00305   tree svar= subvar (var, 0);
00306   int i, n= N(st);
00307   tree r (st, n);
00308   bool mp= is_multi_paragraph (st);
00309   for (i=0; i<n; i++) {
00310     bool smp= mp && is_long_arg (st, i);
00311     if (is_func (st, WITH) && (i<n-1)) r[i]= subvar (svar, i);
00312     else r[i]= rewrite_inactive_arg (st, svar, i, block && smp, flush && smp);
00313   }
00314   return tree (MARK, var, r);
00315 }
00316 
00317 tree
00318 edit_env_rep::rewrite_inactive_var_active (
00319   tree t, tree var, bool block, bool flush)
00320 {
00321   (void) block;
00322   tree r= tree (WITH, MODE, copy (env [MODE]), subvar (var, 0));
00323   if (flush &&
00324       (src_compact != COMPACT_ALL) &&
00325       (is_multi_paragraph (t[0]) || (src_compact == COMPACT_NONE)))
00326     r= tree (SURROUND, "", compound ("right-flush"), r);
00327   return tree (MARK, var, r);
00328 }
00329 
00330 tree
00331 edit_env_rep::rewrite_inactive_hybrid (
00332   tree t, tree var, bool block, bool flush)
00333 {
00334   if (is_atomic (t[0]) && (src_special >= SPECIAL_NORMAL)) {
00335     int i, n= N(t);
00336     tree r (INLINE_TAG, n);
00337     r[0]= tree (CONCAT, "\\",
00338               highlight (subvar (var, 0), t[0], TYPE_VARIABLE));
00339     for (i=1; i<n; i++)
00340       r[i]= rewrite_inactive_arg (t, var, i, false, false);
00341     return tree (MARK, var, r);
00342   }
00343   return rewrite_inactive_default (t, var, block, flush);
00344 }
00345 
00346 tree
00347 edit_env_rep::rewrite_inactive_default (
00348   tree t, tree var, bool block, bool flush)
00349 {
00350   int i, d= 0, n= N(t);
00351   tree op= as_string (L(t));
00352   if ((L(t) == COMPOUND) &&
00353       is_atomic (t[0]) &&
00354       (src_special >= SPECIAL_NORMAL))
00355     {
00356       d = 1;
00357       op= highlight (subvar (var, 0), t[0], TYPE_VARIABLE);
00358     }
00359   if (inactive_mode == INACTIVE_INLINE_ERROR ||
00360       inactive_mode == INACTIVE_BLOCK_ERROR)
00361     op= highlight (op, "", TYPE_INVALID);
00362 
00363   if ((N(t) == d) ||
00364       (src_compact == COMPACT_ALL) ||
00365       ((!block) && (src_compact != COMPACT_NONE)) ||
00366       ((!is_long (t)) && (src_compact != COMPACT_NONE)))
00367     {
00368       tree r (INLINE_TAG, n+1-d);
00369       r[0]= op;
00370       for (i=d; i<n; i++)
00371        r[i+1-d]= rewrite_inactive_arg (t, var, i, false, false);
00372       return tree (MARK, var, r);
00373     }
00374   else {
00375     tree doc (DOCUMENT);
00376     bool compact= (src_compact < COMPACT_INLINE);
00377  
00378     for (i=d; i<n; i++) {
00379       tree next;
00380       if ((!compact) || is_long_arg (t, i)) {
00381        if (i==d) doc << tree (OPEN_TAG, op);
00382        next= rewrite_inactive_arg (t, var, i, true, src_close >= CLOSE_LONG);
00383        next= compound ("indent*", next);
00384        i++;
00385       }
00386 
00387       int start= i;
00388       for (; i<n; i++)
00389        if ((!compact) || is_long_arg (t, i)) break;
00390       int end= i;
00391       tree_label l= MIDDLE_TAG;
00392       if (end == n) l= CLOSE_TAG;
00393       if (start == d) l= OPEN_TAG;
00394       tree u (l, end - start + 1);
00395       u[0]= op;
00396       for (i=0; i<end-start; i++)
00397        u[i+1]= rewrite_inactive_arg (t, var, start+i, false, false);
00398       i= end-1;
00399       compact= (src_compact < COMPACT_INLINE_START);
00400 
00401       if (start==d) doc << u;
00402       else {
00403        if (src_close < CLOSE_LONG)
00404          doc << tree (SURROUND, "", u, next);
00405        else doc << next << u;
00406       }
00407     }
00408 
00409     if (flush) doc= tree (SURROUND, "", compound ("right-flush"), doc);
00410     return tree (MARK, var, doc);
00411   }
00412 }
00413 
00414 tree
00415 edit_env_rep::rewrite_inactive (tree t, tree var, bool block, bool flush) {
00416   if (is_atomic (t)) {
00417     if (src_style == STYLE_SCHEME)
00418       return tree (CONCAT,
00419                  tree (WITH, COLOR, "blue", "``"),
00420                  var,
00421                  tree (WITH, COLOR, "blue", "''"));
00422     return var;
00423   }
00424   switch (L(t)) {
00425   case UNINIT:
00426     if (src_special >= SPECIAL_NORMAL)
00427       return tree (MARK, var, highlight ("?", "", TYPE_INVALID));
00428     else return rewrite_inactive_default (t, var, block, flush);
00429   case RAW_DATA:
00430     return rewrite_inactive_raw_data (t, var, block, flush);
00431   case DOCUMENT:
00432     return rewrite_inactive_document (t, var, block, flush);
00433   case CONCAT:
00434     return rewrite_inactive_concat (t, var, block, flush);
00435   case VALUE:
00436     return rewrite_inactive_value (t, var, block, flush);
00437   case ARG:
00438     return rewrite_inactive_arg (t, var, block, flush);
00439   case STYLE_WITH:
00440     return rewrite_inactive_style_with (t, var, block, flush, true);
00441   case VAR_STYLE_WITH:
00442     return rewrite_inactive_style_with (t, var, block, flush, false);
00443   case STYLE_ONLY:
00444     return rewrite_inactive_active (t, var, block, flush);
00445   case VAR_STYLE_ONLY:
00446     return rewrite_inactive_var_active (t, var, block, flush);
00447   case ACTIVE:
00448     return rewrite_inactive_active (t, var, block, flush);
00449   case VAR_ACTIVE:
00450     return rewrite_inactive_var_active (t, var, block, flush);
00451   case SYMBOL:
00452     return rewrite_inactive_symbol (t, var, block, flush);
00453   case HYBRID:
00454     return rewrite_inactive_hybrid (t, var, block, flush);
00455   default:
00456     return rewrite_inactive_default (t, var, block, flush);
00457   }
00458 }
00459 
00460 tree
00461 edit_env_rep::rewrite_inactive (tree t, tree var) {
00462   // cout << "Rewrite inactive " << t << ", " << var << "\n";
00463   recover_env= tuple ();
00464   bool block= (inactive_mode >= INACTIVE_BLOCK_RECURSE);
00465   tree r= rewrite_inactive (t, var, block, block);
00466   if (is_multi_paragraph (r)) {
00467     r= tree (WITH, PAR_PAR_SEP, "0fn", r);
00468     r= tree (SURROUND, "", tree (VSPACE, "0.5fn"), r);
00469   }
00470   if ((inactive_mode == INACTIVE_INLINE_RECURSE) ||
00471       (inactive_mode == INACTIVE_BLOCK_RECURSE))
00472     r= tree (WITH, MODE, "src", r);
00473   // cout << "---> " << r << "\n\n";
00474   return r;
00475 }