Back to index

texmacs  1.0.7.15
concat_active.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : concat_active.cpp
00004 * DESCRIPTION: Typeset active 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 "concater.hpp"
00013 #include "file.hpp"
00014 #include "image_files.hpp"
00015 #include "sys_utils.hpp"
00016 #include "analyze.hpp"
00017 #include "scheme.hpp"
00018 #include "packrat.hpp"
00019 
00020 /******************************************************************************
00021 * Typesetting executable markup
00022 ******************************************************************************/
00023 
00024 void
00025 concater_rep::typeset_if (tree t, path ip) {
00026   // This method must be kept consistent with edit_env_rep::exec(tree)
00027   // in ../Env/env_exec.cpp
00028   if ((N(t)!=2) && (N(t)!=3)) {
00029     typeset_executable (t, ip);
00030     return;
00031   }
00032   tree tt= env->exec (t[0]);
00033   if (is_compound (tt) || ! is_bool (tt->label)) {
00034     typeset_executable (t, ip);
00035     return;
00036   }
00037   marker (descend (ip, 0));
00038   if (as_bool (tt->label)) typeset (t[1], descend (ip, 1));
00039   else if (N(t) == 3) typeset (t[2], descend (ip, 2));
00040   marker (descend (ip, 1));
00041 }
00042 
00043 void
00044 concater_rep::typeset_var_if (tree t, path ip) {
00045   if (N(t) != 2) { typeset_error (t, ip); return; }
00046   tree flag= env->exec (t[0]);
00047   box  b   = typeset_as_concat (env, attach_right (t[1], ip));
00048   marker (descend (ip, 0));
00049   if (flag == "true") print (b);
00050   else print (empty_box (b->ip, b->x1, b->y1, b->x2, b->y2));
00051   marker (descend (ip, 1));
00052 }
00053 
00054 void
00055 concater_rep::typeset_case (tree t, path ip) {
00056   // This method must be kept consistent with edit_env_rep::exec(tree)
00057   // in ../Env/env_exec.cpp
00058   if (N(t)<2) {
00059     typeset_executable (t, ip);
00060     return;
00061   }
00062   marker (descend (ip, 0));
00063   int i, n= N(t);
00064   for (i=0; i<(n-1); i+=2) {
00065     tree tt= env->exec (t[i]);
00066     if (is_compound (tt) || !is_bool (tt->label)) {
00067       typeset_executable (t, ip);
00068       i=n;
00069     }
00070     else if (as_bool (tt->label)) {
00071       typeset (t[i+1], descend (ip, i+1));
00072       i=n;
00073     }
00074   }
00075   if (i<n) typeset (t[i], descend (ip, i));
00076   marker (descend (ip, 1));
00077 }
00078 
00079 /******************************************************************************
00080 * Typesetting linking primitives
00081 ******************************************************************************/
00082 
00083 bool
00084 build_locus (edit_env env, tree t, list<string>& ids, string& col, string &ref, string &anchor) {
00085   //cout << "Typeset " << t << "\n";
00086   int last= N(t)-1;
00087   tree body= env->expand (t[last], true);
00088   //cout << "Typeset " << body << "\n";
00089   bool accessible= is_accessible (obtain_ip (body));
00090   bool visited= false;
00091   ref= "";
00092   anchor= "";
00093 
00094   if (!is_nil (env->link_env)) {
00095     int i, j;
00096     for (i=0; i<last; i++) {
00097       tree arg= env->exec (t[i]);
00098       if (is_compound (arg, "id", 1)) {
00099        string id= as_string (arg[0]);
00100        if (accessible) env->link_env->insert_locus (id, body);
00101        else if (N (obtain_ip (body)) > 1) {
00102          extern tree get_subtree (path p);
00103          path p= path_up (reverse (descend_decode (obtain_ip (body), 1)));
00104          env->link_env->insert_locus ("&" * id, get_subtree (p));
00105        }
00106        ids= list<string> (id, ids);
00107        visited= visited || has_been_visited ("id:" * id);
00108       }
00109       if (is_compound (arg, "link") && N(arg) >= 2) {
00110        if (is_func (arg[1], ATTR)) arg= copy (arg);
00111        else arg= arg (0, 1) * tree (LINK, tree (ATTR)) * arg (1, N(arg));
00112        arg[1] << tree ("secure")
00113               << (env->secure? tree ("true"): tree ("false"));
00114        env->link_env->insert_link (arg);
00115        for (j=2; j<N(arg); j++) {
00116          if (is_compound (arg[j], "id", 1) && is_atomic (arg[j][0])) {
00117            visited= visited || has_been_visited ("id:" * arg[j][0]->label);
00118            anchor = arg[j][0]->label;
00119          }
00120          if (is_compound (arg[j], "url", 1) && is_atomic (arg[j][0])) {
00121            visited= visited || has_been_visited ("url:" * arg[j][0]->label);
00122            ref = arg[j][0]->label;
00123          }
00124        }
00125       }
00126     }
00127   }
00128 
00129   bool on_paper= (env->get_string (PAGE_PRINTED) == "true");
00130   bool preserve= (get_locus_rendering ("locus-on-paper") == "preserve");
00131   string var= (visited? VISITED_COLOR: LOCUS_COLOR);
00132   string current_col= env->get_string (COLOR);
00133   string locus_col= env->get_string (var);
00134   if (locus_col == "preserve") col= current_col;
00135   else if (on_paper && preserve) col= current_col;
00136   else if (locus_col == "global") col= get_locus_rendering (var);
00137   else col= locus_col;
00138 
00139   return accessible;
00140 }
00141 
00142 bool
00143 build_locus (edit_env env, tree t, list<string>& ids, string& col) {
00144   string ref;
00145   string anchor;
00146   return build_locus(env, t, ids, col, ref, anchor);
00147 }
00148 
00149 void
00150 concater_rep::typeset_locus (tree t, path ip) {
00151   string ref;
00152   string anchor;
00153 
00154   if (N(t) == 0) { typeset_error (t, ip); return; }
00155   int last= N(t)-1;
00156   list<string> ids;
00157   string col;
00158   if (build_locus (env, t, ids, col, ref, anchor)) {
00159     marker (descend (ip, 0));
00160     tree old= env->local_begin (COLOR, col);
00161     typeset (t[last], descend (ip, last));
00162     env->local_end (COLOR, old);
00163     marker (descend (ip, 1));
00164   }
00165   else {
00166     tree old= env->local_begin (COLOR, col);
00167     box b= typeset_as_concat (env, t[last], descend (ip, last));
00168     env->local_end (COLOR, old);
00169     print (locus_box (ip, b, ids, env->get_int (SFACTOR) * PIXEL, ref, anchor));
00170   }
00171 }
00172 
00173 void
00174 concater_rep::typeset_set_binding (tree t, path ip) {
00175   tree keys= env->exec (t);
00176   if (L(keys) == HIDDEN) {
00177     keys= keys[0];
00178     flag ("set binding", ip, blue);
00179     if (N(keys) > 0) {
00180       path sip= ip;
00181       if (N(t) >= 3 && (!is_nil (env->macro_src))) {
00182        tree body= env->expand (tree (ARG, t[2]), true);
00183        sip= obtain_ip (body);
00184       }
00185       box b= tag_box (sip, empty_box (sip, 0, 0, 0, env->fn->yx), keys);
00186       a << line_item (CONTROL_ITEM, OP_SKIP, b, HYPH_INVALID, "label");
00187     }
00188   }
00189   else typeset_dynamic (keys, ip);
00190 }
00191 
00192 void
00193 concater_rep::typeset_write (tree t, path ip) {
00194   if (N(t) != 2) { typeset_error (t, ip); return; }
00195   string s= env->exec_string (t[0]);
00196   tree   r= copy (env->exec (t[1]));
00197   if (env->complete) {
00198     if (!env->local_aux->contains (s))
00199       env->local_aux (s)= tree (DOCUMENT);
00200     env->local_aux (s) << r;
00201   } 
00202   control ("write", ip);
00203 }
00204 
00205 /******************************************************************************
00206 * Typesetting other dynamic markup
00207 ******************************************************************************/
00208 
00209 void
00210 concater_rep::typeset_specific (tree t, path ip) {
00211   if (N(t) != 2) { typeset_error (t, ip); return; }
00212   string which= env->exec_string (t[0]);
00213   if (which == "texmacs" || which == "image") {
00214     marker (descend (ip, 0));
00215     typeset (t[1], descend (ip, 1));
00216     marker (descend (ip, 1));
00217     //typeset_dynamic (t[1], descend (ip, 1));
00218   }
00219   else if ((which == "screen") || (which == "printer")) {
00220     bool pr= (which != "screen");
00221     box  sb= typeset_as_concat (env, attach_middle (t[1], ip));
00222     box  b = specific_box (decorate_middle (ip), sb, pr, env->fn);
00223     marker (descend (ip, 0));
00224     print (b);
00225     marker (descend (ip, 1));
00226   }
00227   else control ("specific", ip);
00228 }
00229 
00230 void
00231 concater_rep::typeset_flag (tree t, path ip) {
00232   if (N(t) != 2 && N(t) != 3) { typeset_error (t, ip); return; }
00233   string name= env->exec_string (t[0]);
00234   string col = env->exec_string (t[1]);
00235   path sip= ip;
00236   if ((N(t) >= 3) && (!is_nil (env->macro_src))) {
00237     string var= env->exec_string (t[2]);
00238     sip= env->macro_src->item [var];
00239   }
00240   if (((N(t) == 2) || is_accessible (sip)) && (!env->read_only)) {
00241     marker (descend (ip, 0));
00242     flag_ok (name, ip, named_color (col));
00243     marker (descend (ip, 1));  
00244   }
00245 }
00246 
00247 /******************************************************************************
00248 * Typesetting images
00249 ******************************************************************************/
00250 
00251 #define error_image(t) { \
00252   typeset_dynamic (tree (ERROR, "bad image", t), ip); \
00253   return; \
00254 }
00255 
00256 void
00257 concater_rep::typeset_image (tree t, path ip) {
00258   // determine the image url
00259   if (N(t) != 5) error_image ("parameters");
00260   tree image_tree= env->exec (t[0]);
00261   url image= url_none ();
00262   if (is_atomic (image_tree)) {
00263     if (N (image_tree->label) == 0)
00264       error_image (tree (WITH, "color", "red", "no image"));
00265     url im= image_tree->label;
00266     image= resolve (relative (env->base_file_name, im));
00267     if (is_none (image)) image= "$TEXMACS_PATH/misc/pixmaps/unknown.ps";
00268   }
00269   else if (is_func (image_tree, TUPLE, 2) &&
00270             is_func (image_tree[0], RAW_DATA, 1) &&
00271             is_atomic (image_tree[0][0]) && is_atomic (image_tree[1])) {
00272     image= url_ramdisc (image_tree[0][0]->label) *
00273            url ("image." * image_tree[1]->label);
00274   }
00275   else error_image (image_tree);
00276 
00277   // determine the original size of the image
00278   int iw, ih;
00279   image_size (image, iw, ih);
00280   double pt= ((double) env->dpi*PIXEL) / 72.0;
00281   SI w= (SI) (((double) iw) * pt);
00282   SI h= (SI) (((double) ih) * pt);
00283 
00284   // determine the width and the height
00285   tree old_w= env->local_begin ("w-length", as_string (w) * "tmpt");
00286   tree old_h= env->local_begin ("h-length", as_string (h) * "tmpt");
00287   SI imw= (t[1] == ""? w: env->as_length (env->exec (t[1]), "w"));
00288   SI imh= (t[2] == ""? h: env->as_length (env->exec (t[2]), "h"));
00289   if (t[1] == "" && t[2] != "" && ih != 0)
00290     imw= (SI) ((iw * ((double) imh)) / ih);
00291   if (t[1] != "" && t[2] == "" && iw != 0)
00292     imh= (SI) ((ih * ((double) imw)) / iw);
00293   if (imw <= 0 || imh <= 0)
00294     error_image (tree (WITH, "color", "red", "null box"));
00295   env->local_end ("w-length", old_w);
00296   env->local_end ("h-length", old_h);
00297   
00298   // determine the offset
00299   old_w= env->local_begin ("w-length", as_string (imw) * "tmpt");
00300   old_h= env->local_begin ("h-length", as_string (imh) * "tmpt");
00301   SI imx= (t[3] == ""? 0: env->as_length (env->exec (t[3]), "w"));
00302   SI imy= (t[4] == ""? 0: env->as_length (env->exec (t[4]), "h"));
00303   env->local_end ("w-length", old_w);
00304   env->local_end ("h-length", old_h);
00305   
00306   // print the box
00307   box imb= image_box (ip, image, imw, imh, env->alpha);
00308   print (move_box (ip, imb, imx, imy, true));
00309 }
00310 
00311 #undef error_image