basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/mmx_texmacs.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : mmx_texmacs.cpp
00004 * DESCRIPTION: Conversion into TeXmacs markup
00005 * COPYRIGHT  : (C) 2000  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #include <basix/string.hpp>
00014 #include <basix/table.hpp>
00015 #include <basix/literal.hpp>
00016 #include <basix/compound.hpp>
00017 #include <basix/row_tuple.hpp>
00018 #include <basix/lisp_syntax.hpp>
00019 namespace mmx {
00020 
00021 #define DATA_BEGIN   ((char) 2)
00022 #define DATA_END     ((char) 5)
00023 #define DATA_ESCAPE  ((char) 27)
00024 #define DATA_COMMAND '\20'
00025 
00026 generic print_mmx (const generic& g);
00027 string as_texmacs_snippet (const generic& g);
00028 
00029 /******************************************************************************
00030 * Handling auxiliary TeXmacs commands
00031 ******************************************************************************/
00032 
00033 static string texmacs_pending= "";
00034 
00035 void
00036 texmacs_command (const string& cmd) {
00037   texmacs_pending << " " << cmd << "\n";
00038 }
00039 
00040 string
00041 texmacs_flush_commands () {
00042   if (texmacs_pending == "") return "";
00043   string s=
00044     string (DATA_BEGIN) *
00045     "command:(begin" * texmacs_pending * ")" *
00046     string (DATA_END);
00047   texmacs_pending= "";
00048   return s;
00049 }
00050 
00051 void
00052 texmacs_dynamic_event (const string& id, const generic& val) {
00053   string v= as_texmacs_snippet (as_generic (flatten (val)));
00054   texmacs_command ("(locus-set \"" * id * "\" '" * v * ")");
00055 }
00056 
00057 /******************************************************************************
00058 * Mode annotation
00059 ******************************************************************************/
00060 
00061 generic add_modes (const generic& g, int mode);
00062 
00063 generic
00064 add_modes (const generic& g, int mode, int new_mode) {
00065   // mmerr << as_lisp (g) << ", " << mode << ", " << new_mode << "\n";
00066   generic r= add_modes (g, new_mode);
00067   if (is_func (r, "$concat", 1)) r= r[1];
00068   if (mode == new_mode) return r;
00069   else if (is_func (r, "$math", 1)) return r;
00070   else if (is_func (r, "$text", 1)) return r;
00071   else if (new_mode == 1) return gen ("$math", r);
00072   else if (new_mode == 2) return gen ("$text", r);
00073   else return r;
00074 }
00075 
00076 generic
00077 add_modes (const generic& g, int mode) {
00078   // mmerr << as_lisp (g) << ", " << mode << "\n";
00079   if (!is<compound> (g) || !is<literal> (g[0])) return g;
00080   if (is_func (g, "$math", 1)) return add_modes (g[1], mode, 1);
00081   if (is_func (g, "$text", 1)) return add_modes (g[1], mode, 2);
00082   if (is_func (g, "$inmath", 1)) return add_modes (g[1], 1);
00083   if (is_func (g, "$intext", 1)) return add_modes (g[1], 2);
00084   vector<generic> v= copy (compound_to_vector (g));
00085   for (nat i=1; i<N(v); i++) v[i]= add_modes (v[i], mode);
00086   return vector_to_compound (v);
00087 }
00088 
00089 /******************************************************************************
00090 * Initialize tables
00091 ******************************************************************************/
00092 
00093 static void
00094 init (table<generic,generic>& t, const generic& key, const generic& val) {
00095   t[key]= val;
00096 }
00097 
00098 static table<generic,generic>
00099 texmacs_symbol_table () {
00100   table<generic,generic> t;
00101 
00102   init (t, "/\\", "tm$wedge");
00103   init (t, "mathcatalan", "tm$mathcatalan");
00104   init (t, "@", "tm$circ");
00105   init (t, "><", "tm$join");
00106   init (t, "derivative", "D");
00107   init (t, "mathe", "tm$mathe");
00108   init (t, "<=>", "tm$Leftrightarrow");
00109   init (t, "matheuler", "tm$matheuler");
00110   init (t, ">", "tm$gtr");
00111   init (t, ">=", "tm$geqslant");
00112   init (t, ">>", "tm$gg");
00113   init (t, "mathi", "tm$mathi");
00114   init (t, "=>", "tm$Rightarrow");
00115   init (t, "Infty", "tm$infty");
00116   init (t, "->", "tm$rightarrow");
00117   init (t, "<", "tm$less");
00118   init (t, "<=", "tm$leqslant");
00119   init (t, "<<", "tm$ll");
00120   init (t, ":->", "tm$mapsto");
00121   init (t, ".!", "!");
00122   init (t, "!", "tm$neg");
00123   init (t, "\\/", "tm$vee");
00124   init (t, "partial", "tm$partial");
00125   init (t, "mathpi", "tm$mathpi");
00126   init (t, ".'", "'");
00127   init (t, ".`", "`");
00128   init (t, "..", "tm$ldots");
00129   init (t, "::", "tm$colons");
00130   init (t, ":>", "tm$transtype");
00131   init (t, "!=", "tm$neq");
00132   init (t, "|", "|");
00133   init (t, "||", "tm$||");
00134   init (t, "xor", "tm$veebar");
00135   init (t, ":=", "tm$assign");
00136   init (t, "+=", "tm$plusassign");
00137   init (t, "-=", "tm$minusassign");
00138   init (t, "*=", "tm$astassign");
00139   init (t, "/=", "tm$overassign");
00140 
00141   init (t, "alpha", "tm$alpha");
00142   init (t, "beta", "tm$beta");
00143   init (t, "gamma", "tm$gamma");
00144   init (t, "delta", "tm$delta");
00145   init (t, "epsilon", "tm$varepsilon");
00146   init (t, "zeta", "tm$zeta");
00147   init (t, "eta", "tm$eta");
00148   init (t, "theta", "tm$theta");
00149   init (t, "iota", "tm$iota");
00150   init (t, "kappa", "tm$kappa");
00151   init (t, "lambda", "tm$lambda");
00152   init (t, "mu", "tm$mu");
00153   init (t, "nu", "tm$nu");
00154   init (t, "xi", "tm$xi");
00155   init (t, "omicron", "tm$omicron");
00156   init (t, "pi", "tm$pi");
00157   init (t, "rho", "tm$rho");
00158   init (t, "sigma", "tm$sigma");
00159   init (t, "tau", "tm$tau");
00160   init (t, "upsilon", "tm$upsilon");
00161   init (t, "phi", "tm$varphi");
00162   init (t, "chi", "tm$chi");
00163   init (t, "psi", "tm$psi");
00164   init (t, "omega", "tm$omega");
00165 
00166   init (t, "Alpha", "tm$Alpha");
00167   init (t, "Beta", "tm$Beta");
00168   init (t, "Gamma", "tm$Gamma");
00169   init (t, "Delta", "tm$Delta");
00170   init (t, "Epsilon", "tm$Epsilon");
00171   init (t, "Zeta", "tm$Zeta");
00172   init (t, "Eta", "tm$Eta");
00173   init (t, "Theta", "tm$Theta");
00174   init (t, "Iota", "tm$Iota");
00175   init (t, "Kappa", "tm$Kappa");
00176   init (t, "Lambda", "tm$Lambda");
00177   init (t, "Mu", "tm$Mu");
00178   init (t, "Nu", "tm$Nu");
00179   init (t, "Xi", "tm$Xi");
00180   init (t, "Omicron", "tm$Omicron");
00181   init (t, "Pi", "tm$Pi");
00182   init (t, "Rho", "tm$Rho");
00183   init (t, "Sigma", "tm$Sigma");
00184   init (t, "Tau", "tm$Tau");
00185   init (t, "Upsilon", "tm$Upsilon");
00186   init (t, "Phi", "tm$Phi");
00187   init (t, "Chi", "tm$Chi");
00188   init (t, "Psi", "tm$Psi");
00189   init (t, "Omega", "tm$Omega");
00190 
00191   return t;
00192 }
00193 
00194 /******************************************************************************
00195 * TeXmacs conversion routines
00196 ******************************************************************************/
00197 
00198 bool
00199 is_infix (const generic& g, const generic& op) {
00200   return is_func (g, "$infix", 3) && g[2] == op;
00201 }
00202 
00203 generic
00204 unbracket (const generic& g) {
00205   if (is_func (g, "$bracket", 3)) return g[2];
00206   else return g;
00207 }
00208 
00209 bool
00210 is_alpha (const generic& g) {
00211   if (!is<literal> (g)) return false;
00212   string s= literal_to_string (g);
00213   for (nat i=0; i<N(s); i++)
00214     if ((s[i] < 'a' || s[i] > 'z') &&
00215         (s[i] < 'A' || s[i] > 'Z'))
00216       return false;
00217   return true;
00218 }
00219 
00220 void
00221 concat_append (vector<generic>& v, const generic& g) {
00222   if (g == "");
00223   else if (is_func (g, "$concat")) {
00224     vector<generic> w= compound_to_vector (g);
00225     for (nat i=1; i<N(w); i++) concat_append (v, w[i]);
00226   }
00227   else if (N(v) == 0) v << g;
00228   else if (is<literal> (v[N(v)-1]) && is<literal> (g))
00229     v[N(v)-1]= generic (literal_to_string (v[N(v)-1]) * literal_to_string (g));
00230   else if (is_func (v[N(v)-1], "$lprime", 1) && is_func (g, "$lprime", 1)) {
00231     generic p (literal_to_string (v[N(v)-1][1]) * literal_to_string (g[1]));
00232     v[N(v)-1]= gen ("$lprime", p);
00233   }
00234   else if (is_func (v[N(v)-1], "$rprime", 1) && is_func (g, "$rprime", 1)) {
00235     generic p (literal_to_string (v[N(v)-1][1]) * literal_to_string (g[1]));
00236     v[N(v)-1]= gen ("$rprime", p);
00237   }
00238   else v << g;
00239 }
00240 
00241 generic
00242 as_texmacs (const generic& g) {
00243   if (is<literal> (g)) {
00244     if (g == "$lf") return gen ("$lf");
00245     if (g == "$cr") return gen ("$cr");
00246     if (g == "$spc") return gen (" ");
00247     static table<generic,generic> t= texmacs_symbol_table ();
00248     generic h= g;
00249     if (contains (t, h)) h= t[h];
00250     if (!is<literal> (h)) return h;
00251     string s= literal_to_string (h);
00252     if (starts (s, "tm$"))
00253       return generic ("<" * s (3, N(s)) * ">");
00254     string r;
00255     for (nat i=0; i<N(s); i++)
00256       if (s[i] == '<') r << "<less>";
00257       else if (s[i] == '>') r << "<gtr>";
00258       else r << s[i];
00259     return r;
00260   }
00261   else if (is_func (g, "$concat")) {
00262     vector<generic> v;
00263     for (nat i=1; i<N(g); i++)
00264       concat_append (v, as_texmacs (g[i]));
00265     if (N(v) == 0) return generic ("");
00266     else if (N(v) == 1) return v[0];
00267     else return gen ("$concat", v);
00268   }
00269   else if (is_func (g, "$keyword", 1))
00270     return as_texmacs (gen ("$strong", g[1]));
00271   else if (is_func (g, "$keyword", 2))
00272     return as_texmacs (gen ("$concat", gen ("$strong", g[1]), "$spc", g[2]));
00273   else if (is_func (g, "$bracket", 3))
00274     return as_texmacs (gen ("$around*", g[1], g[2], g[3]));
00275   else if (is_func (g, "$prefix", 2)) {
00276     if (g[1] == "'" || g[1] == "`")
00277       return as_texmacs (gen ("$concat", gen ("$lprime", g[1]), g[2]));
00278     else return as_texmacs (gen ("$concat", g[1], g[2]));
00279   }
00280   else if (is_func (g, "$postfix", 2)) {
00281     if (g[2] == "'" || g[2] == "`")
00282       return as_texmacs (gen ("$concat", g[1], gen ("$lprime", g[2])));
00283     else return as_texmacs (gen ("$concat", g[1], g[2]));
00284   }
00285   else if (is_func (g, "$infix", 3)) {
00286     if (g[2] == "/")
00287       return as_texmacs (gen ("$frac", unbracket (g[1]), unbracket (g[3])));
00288     else if (g[2] == "^")
00289       return as_texmacs (gen ("$concat",
00290                               g[1], gen ("$rsup", unbracket (g[3]))));
00291     else if (g[2] == "|" || g[2] == "||")
00292       return as_texmacs (gen ("$concat", g[1], gen ("$mid", g[2]), g[3]));
00293     else {
00294       generic op= as_texmacs (g[2]);
00295       if (is_alpha (op))
00296         op= gen ("$concat", "$spc", gen ("$strong", op), "$spc");
00297       return as_texmacs (gen ("$concat", g[1], g[2], g[3]));
00298     }
00299   }
00300   else if (is_func (g, "$bigop") && N(g) >= 3) {
00301     vector<generic> v;
00302     if (g[1] == GEN_PLUS && is_func (g[2], GEN_MINUS, 1))
00303       v << generic ("-") << g[2][1];
00304     else v << g[2];
00305     for (nat i=3; i<N(g); i++) {
00306       if (g[1] == GEN_PLUS && is_func (g[i], GEN_MINUS, 1))
00307         v << generic ("-") << g[i][1];
00308       else
00309         v << g[1] << g[i];
00310     }
00311     return as_texmacs (gen ("$concat", v));
00312   }
00313   else if (is_func (g, "$operate", 2)) {
00314     if (is_func (g[2], "$bracket", 3) && g[2][1] == "[")
00315       return as_texmacs (gen ("$concat",
00316                               g[1], gen ("$rsub", unbracket (g[2]))));
00317     else return as_texmacs (gen ("$concat", g[1], g[2]));
00318   }
00319   else if (is_func (g, "$hlist")) {
00320     if (N(g) == 1) return generic ("");
00321     vector<generic> v= vec (g[1]);
00322     for (nat i=2; i<N(g); i++) v << generic (",") << g[i];
00323     return as_texmacs (gen ("$concat", v));
00324   }
00325   else if (is_func (g, "$vlist")) {
00326     vector<generic> v;
00327     for (nat i=1; i<N(g); i++)
00328       if (is_func (g[i], "$hlist"))
00329         v << gen ("$row", cdr (compound_to_vector (g[i])));
00330     if (N(v) == 0) return generic ("");
00331     return as_texmacs (gen ("$tabular*", gen ("$table", v)));
00332   }
00333   else if (is_func (g, "$indent")) {
00334     vector<generic> v;
00335     for (nat i=1; i<N(g); i++)
00336       concat_append (v, as_texmacs (g[i]));
00337     return gen ("$concat", gen ("$indent", gen ("$concat", v)), gen ("$lf"));
00338   }
00339   else if (is_func (g, "$text", 1))
00340     return gen ("$text", as_texmacs (g[1]));
00341   else if (is_func (g, "$math", 1))
00342     return gen ("$math", as_texmacs (g[1]));
00343   else if (is_func (g, "$dynamic"))
00344     return gen ("$locus", gen ("$id", as_texmacs (g[1])), as_texmacs (g[2]));
00345   else if (is<compound> (g)) {
00346     vector<generic> v;
00347     for (nat i=1; i<N(g); i++)
00348       v << as_texmacs (g[i]);
00349     return gen (g[0], v);
00350   }
00351   else ERROR ("not implemented");
00352 }
00353 
00354 /******************************************************************************
00355 * Replace line feeds
00356 ******************************************************************************/
00357 
00358 generic
00359 replace_lf (const generic& g) {
00360   if (is<literal> (g)) return g;
00361   else if (is_func (g, "$concat")) {
00362     bool block= false;
00363     vector<generic> d;
00364     vector<generic> c;
00365     for (nat i=1; i<N(g); i++) {
00366       if (is_func (g[i], "$lf", 0)) {
00367         if (N(c) == 0) d << generic ("");
00368         else if (N(c) == 1) d << c;
00369         else if (N(c) > 1) d << gen ("$concat", c);
00370         c= vector<generic> ();
00371       }
00372       else if (is_func (g[i], "$cr", 0)) block= true;
00373       else c << replace_lf (g[i]);
00374     }
00375     if (N(c) == 1) d << c;
00376     else if (N(c) != 0) d << gen ("$concat", c);
00377     if (N(d) != 1 || block) return gen ("$document", d);
00378     return d[0];
00379   }
00380   else if (is<compound> (g)) {
00381     vector<generic> v;
00382     for (nat i=1; i<N(g); i++)
00383       v << replace_lf (g[i]);
00384     return gen (g[0], v);
00385   }
00386   else {
00387     mmout << "g= " << g << ": " << type_name (g) << "\n";
00388     ERROR ("TeXmacs document expected");
00389   }
00390 }
00391 
00392 /******************************************************************************
00393 * Expand TeXmacs (FIXME: should be replaced by something less ad hoc)
00394 ******************************************************************************/
00395 
00396 generic
00397 texmacs_expand (const generic& g) {
00398   if (is_func (g, "tm$with"))
00399     return texmacs_expand (g[N(g)-1]);
00400   else if (is_func (g, "tm$itemize", 1) || is_func (g, "tm$enumerate", 1))
00401     return gen ("$indent", texmacs_expand (g[1]));
00402   else if (is_func (g, "tm$item", 0))
00403     return generic ("* ");
00404   else if (is_func (g, "tm$folded", 2))
00405     return gen ("$varindent",
00406                 gen ("$concat",
00407                      generic ("o "), texmacs_expand (g[1])));
00408   else if (is_func (g, "tm$unfolded", 2))
00409     return gen ("$varindent",
00410                 gen ("$concat",
00411                      generic ("* "), texmacs_expand (g[1]),
00412                      generic ("$lf"), texmacs_expand (g[2])));
00413   else if (is_func (g, "tm$folded-explain", 2))
00414     return texmacs_expand (g[1]);
00415   else if (is_func (g, "tm$unfolded-explain", 2))
00416     return gen ("$concat", texmacs_expand (g[1]),
00417                 generic ("$lf"), generic ("$lf"), texmacs_expand (g[2]));
00418   else if (is_func (g, "tm$explain", 2))
00419     return gen ("$concat", texmacs_expand (g[1]), generic ("$lf"),
00420                 gen ("$indent", texmacs_expand (g[2])));
00421   else if (is_func (g, "tm$explain-synopsis", 1))
00422     return gen ("$concat", generic (" --- "), texmacs_expand (g[1]));
00423   else if (is<compound> (g)) {
00424     vector<generic> v;
00425     for (nat i=1; i<N(g); i++) v << texmacs_expand (g[i]);
00426     if (is<literal> (g[0]) && starts (literal_to_string (g[0]), "tm$")) {
00427       if (N(v) == 1) return v[0];
00428       else return gen ("$concat", v);
00429     }
00430     else return gen (g[0], v);
00431   }
00432   else return g;
00433 }
00434 
00435 /******************************************************************************
00436 * TeXmacs to Scheme
00437 ******************************************************************************/
00438 
00439 static void
00440 texmacs_to_scheme (string& s, const generic& g) {
00441   //mmerr << "g= " << as_lisp (g) << "\n";
00442   if (is<literal> (g)) s << quote (literal_to_string (g));
00443   else if (is<compound> (g) && is<literal> (g[0]) &&
00444            literal_to_string (g[0]) == " ")
00445     s << "\" \"";
00446   else if (is<compound> (g) && is<literal> (g[0])) {
00447     string op= literal_to_string (g[0]);
00448     if (starts (op, "tm$")) op= op (2, N(op));
00449     if (!starts (op, "$")) {
00450       mmerr << "op  = " << op << "\n";
00451       mmerr << "args= " << compound_to_vector (g) << "\n";
00452     }
00453     ASSERT (starts (op, "$"), "invalid TeXmacs markup");
00454     s << "(" << op (1, N(op));
00455     for (nat i=1; i<N(g); i++) {
00456       s << " ";
00457       texmacs_to_scheme (s, g[i]);
00458     }
00459     s << ")";
00460   }
00461   else ERROR ("invalid TeXmacs markup");
00462 }
00463 
00464 string
00465 as_texmacs_snippet (const generic& g) {
00466   string  r= "";
00467   generic h= print_mmx (g);
00468   generic m= add_modes (h, 0, 1);
00469   generic t= as_texmacs (m);
00470   generic l= replace_lf (t);
00471   texmacs_to_scheme (r, l);
00472   return r;
00473 }
00474 
00475 string
00476 as_texmacs_scheme (const generic& g) {
00477   string  r= "(document ";
00478   generic h= print_mmx (g);
00479   generic m= add_modes (h, 0, 1);
00480   generic t= as_texmacs (m);
00481   generic l= replace_lf (t);
00482   texmacs_to_scheme (r, l);
00483   r << ")";
00484   return r;
00485 }
00486 
00487 /******************************************************************************
00488 * Scheme to tm
00489 ******************************************************************************/
00490 
00491 static string
00492 spaces (nat indent) {
00493   string s;
00494   for (nat i=0; i<indent; i++)
00495     s << " ";
00496   return s;
00497 }
00498 
00499 static void
00500 write (string& r, const string& s) {
00501   nat i, n=N(s);
00502   for (i=0; i<n; i++) {
00503     char c= s[i];
00504     if (c == ' ' && ends (r, " ")) r << "\\ ";
00505     else if (c == '\n') r << "\\n";
00506     else if (c == '\t') r << "\\t";
00507     else if (c == '\0') r << "\\0";
00508     else if (c == '\\') r << "\\\\";
00509     else if (c == '<') r << "\\<";
00510     else if (c == '|') r << "\\|";
00511     else if (c == '>') r << "\\>";
00512     else if (c == '\34') r << c;
00513     else if (((unsigned char) c) < ' ') r << '\\' << (c+'@');
00514     else r << c;
00515   }
00516 }
00517 
00518 static void
00519 scheme_to_tm (string& s, const generic& g, int indent) {
00520   //mmout << "Converting " << g << "\n";
00521   if (is<literal> (g))
00522     write (s, unquote (literal_to_string (g)));
00523   else if (is_func (g, "concat")) {
00524     for (nat i=1; i<N(g); i++)
00525       scheme_to_tm (s, g[i], indent);
00526   }
00527   else if (is_func (g, "document")) {
00528     for (nat i=1; i<N(g); i++) {
00529       if (i>1) {
00530         if (ends (s, "\n")) s << "\\;";
00531         s << "\n\n" << spaces (indent);
00532       }
00533       scheme_to_tm (s, g[i], indent);
00534     }
00535   }
00536   else if (is<compound> (g) && N(g) > 0 && is<literal> (g[0])) {
00537     string func= literal_to_string (g[0]);
00538     vector<generic> args= cdr (compound_to_vector (g));
00539     int i, last, n=N(args);
00540     for (i=n-1; i>=0; i--)
00541       if (is_func (args[i], "document"))
00542         break;
00543     last= i;
00544     if (last >= 0) {
00545       for (i=0; i<=n; i++) {
00546         bool flag= (i<n) && is_func (args[i], "document");
00547         if (i==0) s << "<\\" << func;
00548         else if (i==last+1) s << "</" << func;
00549         else if (is_func (args[i-1], "document")) s << "<|" << func;
00550         if (i==n) { s << ">"; break; }
00551 
00552         if (flag) {
00553           s << ">";
00554           if (!ends (s, "\n")) s << "\n" << spaces (indent + 2);
00555           scheme_to_tm (s, args[i], indent + 2);
00556           if (!ends (s, "\n")) s << "\n" << spaces (indent);
00557         }
00558         else {
00559           s << "|";
00560           scheme_to_tm (s, args[i], indent);
00561         }
00562       }
00563     }
00564     else {
00565       s << "<" << func;
00566       for (i=0; i<n; i++) {
00567         s << "|";
00568         scheme_to_tm (s, args[i], indent);
00569       }
00570       s << ">";
00571     }    
00572   }
00573   else ERROR ("invalid scheme markup");
00574 }
00575 
00576 static string
00577 as_snippet (const generic& g) {
00578   string  r= "";
00579   generic h= print_mmx (g);
00580   generic m= h;//add_modes (h, 0, 1);
00581   generic t= as_texmacs (m);
00582   generic l= replace_lf (t);
00583   texmacs_to_scheme (r, l);
00584   return r;
00585 }
00586 
00587 string
00588 flatten_as_tm (const generic& x) {
00589   string r;
00590   generic g= as_generic (flatten (x));
00591   g= parse_lisp (as_snippet (g), true);
00592   if (is_func (g, "text", 1)) g= g[1];
00593   scheme_to_tm (r, g, 0);
00594   return r;
00595 }
00596 
00597 string
00598 flatten_as_tm (const generic& x, const string& style) {
00599   string r;
00600   generic g= as_generic (flatten (x));
00601   g= parse_lisp (as_snippet (g), true);
00602   if (is_func (g, "text", 1)) g= g[1];
00603   if (!is_func (g, "document")) g= gen ("document", g);
00604   g= gen ("document", gen ("TeXmacs", string ("1.0.7.8")),
00605           gen ("style", style), gen ("body", g));
00606   scheme_to_tm (r, g, 0);
00607   return r;
00608 }
00609 
00610 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines