Back to index

texmacs  1.0.7.15
input.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : input.cpp
00004 * DESCRIPTION: Generic TeXmacs input
00005 * COPYRIGHT  : (C) 2000  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 "path.hpp"
00013 #include "convert.hpp"
00014 #include "hashmap.hpp"
00015 #include "tm_link.hpp"
00016 #include "Generic/input.hpp"
00017 #include "scheme.hpp"
00018 #include "vars.hpp"
00019 
00020 #define STATUS_NORMAL 0
00021 #define STATUS_ESCAPE 1
00022 #define STATUS_BEGIN  2
00023 
00024 #define MODE_VERBATIM 0
00025 #define MODE_SCHEME   1
00026 #define MODE_LATEX    2
00027 #define MODE_HTML     3
00028 #define MODE_PS       4
00029 #define MODE_MATH     5
00030 #define MODE_CHANNEL  6
00031 #define MODE_COMMAND  7
00032 #define MODE_XFORMAT  8
00033 
00034 /******************************************************************************
00035 * Universal data input
00036 ******************************************************************************/
00037 
00038 texmacs_input_rep::texmacs_input_rep (string type2):
00039   type (type2),
00040   status (STATUS_NORMAL),
00041   buf (""),
00042   format ("verbatim"),
00043   mode (get_mode (format)),
00044   channel (type),
00045   stack (""),
00046   docs (tree (DOCUMENT, "")) { bof (); }
00047 
00048 texmacs_input::texmacs_input (string type):
00049   rep (tm_new<texmacs_input_rep> (type)) {}
00050 
00051 /******************************************************************************
00052 * Mode and channel handling
00053 ******************************************************************************/
00054 
00055 int
00056 texmacs_input_rep::get_mode (string s) {
00057   if (s == "verbatim")  return MODE_VERBATIM;
00058   if (s == "latex") return MODE_LATEX;
00059   if (s == "scheme") return MODE_SCHEME;
00060   if (s == "html")  return MODE_HTML;
00061   if (s == "ps")  return MODE_PS;
00062   if (s == "math")  return MODE_MATH;
00063   if (s == "channel")  return MODE_CHANNEL;
00064   if (s == "command")  return MODE_COMMAND;
00065   if (as_bool (call ("format?", s))) return MODE_XFORMAT;
00066   return MODE_VERBATIM;
00067 }
00068 
00069 void
00070 texmacs_input_rep::begin_mode (string s) {
00071   stack = tuple (format, channel, stack);
00072   format= s;
00073   mode  = get_mode (format);
00074 }
00075 
00076 void
00077 texmacs_input_rep::begin_channel (string s) {
00078   stack  = tuple (format, channel, stack);
00079   channel= s;
00080   if ((channel == "prompt") || (channel == "input"))
00081     docs (channel)= tree (DOCUMENT, "");
00082 }
00083 
00084 void
00085 texmacs_input_rep::end () {
00086   if (stack != "") {
00087     format = stack[0]->label;
00088     mode   = get_mode (format);
00089     channel= stack[1]->label;
00090     stack  = stack[2];
00091   }
00092 }
00093 
00094 /******************************************************************************
00095 * Main routines
00096 ******************************************************************************/
00097 
00098 bool
00099 texmacs_input_rep::put (char c) { // returns true when expecting input
00100   /*
00101   if (c == DATA_BEGIN) cout << "[BEGIN]";
00102   else if (c == DATA_END) cout << "[END]";
00103   else if (c == DATA_ESCAPE) cout << "[ESCAPE]";
00104   else cout << c;
00105   */
00106 
00107   bool block_done= false;
00108   switch (status) {
00109   case STATUS_NORMAL:
00110     if (c == DATA_ESCAPE) status= STATUS_ESCAPE;
00111     else if (c == DATA_BEGIN) {
00112       flush (true);
00113       status= STATUS_BEGIN;
00114     }
00115     else if (c == DATA_END) {
00116       flush (true);
00117       end ();
00118       block_done= (stack == "");
00119     }
00120     else buf << c;
00121     break;
00122   case STATUS_ESCAPE:
00123     buf << c;
00124     status= STATUS_NORMAL;
00125     break;
00126   case STATUS_BEGIN:
00127     if (c == ':') {
00128       begin_mode (buf);
00129       buf   = "";
00130       status= STATUS_NORMAL;
00131     }
00132     else if (c == '#') {
00133       begin_channel (buf);
00134       buf   = "";
00135       status= STATUS_NORMAL;
00136     }
00137     else buf << c;
00138     break;
00139   }
00140   if (status == STATUS_NORMAL) flush ();
00141   return block_done;
00142 }
00143 
00144 void
00145 texmacs_input_rep::bof () {
00146   format = "verbatim";
00147   channel= type;
00148   docs (channel)= tree (DOCUMENT, "");
00149 }
00150 
00151 void
00152 texmacs_input_rep::eof () {
00153   flush (true);
00154 }
00155 
00156 void
00157 texmacs_input_rep::write (tree u) {
00158   if (!docs->contains (channel))
00159     docs (channel)= tree (DOCUMENT, "");
00160   tree& t= docs (channel);
00161   if (!is_document (u)) u= tree (DOCUMENT, u);
00162   if (t[N(t)-1] == "") t[N(t)-1]= u[0];
00163   else if (u[0] != "") {
00164     if (!is_concat (t[N(t)-1])) t[N(t)-1]= tree (CONCAT, t[N(t)-1]);
00165     if (!is_concat (u[0])) u[0]= tree (CONCAT, u[0]);
00166     t[N(t)-1] << A(u[0]);
00167   }
00168   if (N(u)>1) t << A (u (1, N(u)));
00169 }
00170 
00171 tree
00172 texmacs_input_rep::get (string ch) {
00173   if (!docs->contains (channel))
00174     docs (channel)= tree (DOCUMENT, "");
00175   tree& doc= docs (ch);
00176   if (doc == tree (DOCUMENT, "")) return "";
00177   tree t= doc;
00178   doc= tree (DOCUMENT, "");
00179   return t;
00180 }
00181 
00182 /******************************************************************************
00183 * Flushing
00184 ******************************************************************************/
00185 
00186 void
00187 texmacs_input_rep::flush (bool force) {
00188   if ((!force) && (channel == "error") && (stack != "")) return;
00189   switch (mode) {
00190   case MODE_VERBATIM:
00191     verbatim_flush (force);
00192     break;
00193   case MODE_SCHEME:
00194     scheme_flush (force);
00195     break;
00196   case MODE_LATEX:
00197     latex_flush (force);
00198     break;
00199   case MODE_HTML:
00200     html_flush (force);
00201     break;
00202   case MODE_PS:
00203     ps_flush (force);
00204     break;
00205   case MODE_MATH:
00206     math_flush (force);
00207     break;
00208   case MODE_CHANNEL:
00209     channel_flush (force);
00210     break;
00211   case MODE_COMMAND:
00212     command_flush (force);
00213     break;
00214   case MODE_XFORMAT:
00215     xformat_flush (force);
00216     break;
00217   default:
00218     FAILED ("invalid mode");
00219     break;
00220   }
00221 }
00222 
00223 void
00224 texmacs_input_rep::verbatim_flush (bool force) {
00225   if (force || ends (buf, "\n")) {
00226     write (verbatim_to_tree (buf));
00227     buf= "";
00228   }
00229 }
00230 
00231 void
00232 texmacs_input_rep::scheme_flush (bool force) {
00233   if (force) {
00234     write (simplify_correct (scheme_to_tree (buf)));
00235     buf= "";
00236   }
00237 }
00238 
00239 void
00240 texmacs_input_rep::latex_flush (bool force) {
00241   if (force || ends (buf, "\n\n") || ends (buf, "\r\n\r\n")) {
00242     write (generic_to_tree (buf, "latex-snippet"));
00243     buf= "";
00244   }
00245 }
00246 
00247 void
00248 texmacs_input_rep::html_flush (bool force) {
00249   if (force || ends (buf, "</P>")) {
00250     write (compound ("html-text", generic_to_tree (buf, "html-snippet")));
00251     buf= "";
00252   }
00253 }
00254 
00255 void
00256 texmacs_input_rep::ps_flush (bool force) {
00257   if (force) {
00258     string w= "";
00259     string h= "";
00260     string b= copy (buf);
00261     while (true)
00262       if (starts (b, "width=") || starts (b, "height=")) {
00263        int i=0;
00264        for (i=0; i<N(b); i++)
00265          if (b[i] == '\n') break;
00266        if (i == N(b)) break;
00267        if (b[0] == 'w') w= b (6, i);
00268        else h= b (7, i);
00269        b= b (i+1, N(b));
00270       }
00271       else break;
00272     tree t (IMAGE, tuple (tree (RAW_DATA, b), "ps"));
00273     t << w << h << "" << "";
00274     write (t);
00275     buf= "";
00276   }
00277 }
00278 
00279 void
00280 texmacs_input_rep::math_flush (bool force) {
00281   if (force) {
00282     object obj= call ("string->object", buf);
00283     object cvr= call ("cas->stree", obj);
00284     tree t= as_tree (call ("tm->tree", cvr));
00285     write (tree (WITH, MODE, "math", t));
00286     buf= "";
00287   }
00288 }
00289 
00290 void
00291 texmacs_input_rep::channel_flush (bool force) {
00292   if (force) {
00293     if ((buf == "prompt") || (buf == "input"))
00294       docs (buf)= tree (DOCUMENT, "");
00295     stack[1]= buf;
00296     buf= "";
00297   }
00298 }
00299 
00300 void
00301 texmacs_input_rep::command_flush (bool force) {
00302   if (force) {
00303     eval ("(begin " * buf * ")");
00304     buf= "";
00305   }
00306 }
00307 
00308 void
00309 texmacs_input_rep::xformat_flush (bool force) {
00310   if (force) {
00311     write (generic_to_tree (buf, format * "-snippet"));
00312     buf= "";
00313   }
00314 }