Back to index

texmacs  1.0.7.15
tm_file.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_file.cpp
00004 * DESCRIPTION: Loading and saving TeXmacs files
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 "tm_data.hpp"
00013 #include "tm_buffer.hpp"
00014 #include "file.hpp"
00015 #include "convert.hpp"
00016 #include "merge_sort.hpp"
00017 #include "drd_std.hpp"
00018 #include "new_style.hpp"
00019 
00020 /******************************************************************************
00021 * Loading files
00022 ******************************************************************************/
00023 
00024 static void
00025 notify_recent_buffer (string name) {
00026   if (ends (name, "~") || ends (name, "#")) name= name (0, N(name) - 1);
00027   object a= call ("assoc-set!", null_object (), object ("0"), object (name));
00028   call ("learn-interactive", object ("recent-buffer"), a);
00029 }
00030 
00031 tree
00032 load_tree (url u, string fm) {
00033   string s, suf= suffix (u);
00034   string action= "load " * fm * " file";
00035   u= resolve (u);
00036   set_file_focus (u);
00037   if (is_none (u) || load_string (u, s, false)) {
00038     tree vname= verbatim (as_string (u));
00039     set_message (concat ("Error: file ", vname, " not found"), action);
00040     return "error";
00041   }
00042   if (fm == "generic" || fm == "help") fm= get_format (s, suf);
00043   tree t= generic_to_tree (s, fm * "-document");
00044   tree links= extract (t, "links");
00045   if (N (links) != 0)
00046     (void) call ("register-link-locations", object (u), object (links));
00047   return t;
00048 }
00049 
00050 void
00051 load_buffer (url u, string fm, int where, bool autosave_flag) {
00052   // cout << "Load= " << u << ", " << fm << "\n";
00053   string name= as_string (tail (u));
00054   tree vname= verbatim (name);
00055   string action= "load " * fm * " file";
00056   if (fm == "generic")
00057     action= "load " * suffix_to_format (suffix (u)) * " file";
00058   
00059   url v= u;
00060   u= resolve (u);
00061   if (is_none (u)) {
00062     if (fm == "generic" || fm == "texmacs")
00063       if (is_name (v) || (is_rooted_name (v) && is_rooted (v, "default"))) {
00064         tree doc (DOCUMENT,
00065                   compound ("style", "generic"),
00066                   compound ("body", tree (DOCUMENT, "")));
00067         switch (where) {
00068           case 0: new_buffer_in_this_window (v, doc); break;
00069           case 1: new_buffer_in_new_window (v, doc); break;
00070           case 2: ::create_buffer (v, doc); break;
00071           default: FAILED ("bad value for 'where'");
00072         }
00073       }
00074     if (!no_bufs ())
00075       set_message (concat ("Error: file ", vname, " not found"), action);
00076     return;
00077   }
00078   
00079   if (fm == "help") {
00080     extern string get_help_title (url name, tree t);
00081     tree doc= load_tree (u, fm);
00082     if (doc == "error") return;
00083     if (where == 1)
00084       new_buffer_in_new_window (get_help_title (u, doc), doc);
00085     set_help_buffer (u, doc);
00086     return;
00087   }
00088   
00089   v= u;
00090   if (autosave_flag) v= unglue (v, 1);
00091   int nr= find_buffer (v);
00092   tree doc= ((nr == -1)? load_tree (u, fm): tree (DOCUMENT));
00093   if (doc == "error") return;
00094   switch (where) {
00095     case 0: new_buffer_in_this_window (v, doc); break;
00096     case 1: new_buffer_in_new_window (v, doc); break;
00097     case 2: ::create_buffer (v, doc); break;
00098     default: FAILED ("bad value for 'where'");
00099   }
00100   nr= find_buffer (v);
00101   if (nr != -1) {
00102     tm_buffer buf= bufs[nr];
00103     if (autosave_flag && N(buf->vws) == 1 && buf->vws[0]->ed != NULL)
00104       buf->vws[0]->ed->require_save();
00105     buf->buf->fm= fm;
00106     if (fm == "help" || is_rooted_web (v)) {
00107       tm_buffer buf= get_buffer ();
00108       buf->buf->read_only= true;
00109     }
00110   }
00111   if (fm == "generic" || fm == "texmacs")
00112     notify_recent_buffer (as_string (u));
00113 }
00114 
00115 tm_buffer
00116 load_passive_buffer (url u) {
00117   int nr= find_buffer (u);
00118   if (nr != -1) return bufs[nr];
00119   load_buffer (u, "texmacs", 2, false);
00120   nr= find_buffer (u);
00121   if (nr != -1) return bufs[nr];
00122   return NULL;
00123 }
00124 
00125 /******************************************************************************
00126 * Loading inclusions
00127 ******************************************************************************/
00128 
00129 static hashmap<string,tree> document_inclusions ("");
00130 
00131 void
00132 reset_inclusions () {
00133   document_inclusions= hashmap<string,tree> ("");
00134 }
00135 
00136 void
00137 reset_inclusion (url name) {
00138   string name_s= as_string (name);
00139   document_inclusions->reset (name_s);
00140 }
00141 
00142 tree
00143 load_inclusion (url name) {
00144   // url name= relative (base_file_name, file_name);
00145   string name_s= as_string (name);
00146   if (document_inclusions->contains (name_s))
00147     return document_inclusions [name_s];
00148   tree doc= extract_document (load_tree (name, "generic"));
00149   if (!is_func (doc, ERROR)) document_inclusions (name_s)= doc;
00150   return doc;
00151 }
00152 
00153 /******************************************************************************
00154 * Saving files
00155 ******************************************************************************/
00156 
00157 tree
00158 make_document (tm_view vw, string fm) {
00159   tree body= subtree (the_et, vw->buf->rp);
00160   if (fm == "verbatim")
00161     body= vw->ed->exec_verbatim (body);
00162   if (fm == "html")
00163     body= vw->ed->exec_html (body);
00164   if (fm == "latex")
00165     body= vw->ed->exec_latex (body);
00166 
00167   vw->ed->get_data (vw->buf->data);
00168   tree doc= attach_data (body, vw->buf->data, !vw->ed->get_save_aux());
00169 
00170   object arg1 (vw->buf->buf->name);
00171   object arg2 (body);
00172   tree links= as_tree (call ("get-link-locations", arg1, arg2));
00173   if (N (links) != 0)
00174     doc << compound ("links", links);
00175 
00176   return doc;
00177 }
00178 
00179 void
00180 save_buffer (url u, string fm) {
00181   string name= as_string (u);
00182   tree vname= verbatim (name);
00183   if (fm == "generic") {
00184     fm= suffix_to_format (suffix (u));
00185     if (fm == "generic") fm= "verbatim";
00186   }
00187   string action= "save " * fm * " file";
00188   u= resolve (u, "");
00189   if (is_none (u)) {
00190     set_message (concat ("Error: can't save file ", vname), action);
00191     return;
00192   }
00193 
00194   tm_buffer buf= get_buffer ();
00195   if ((u == buf->buf->name && buf->buf->read_only) ||
00196       (u == buf->buf->name && has_permission (u,"r") && !has_permission (u,"w")) ||
00197       (!is_none (buf->buf->extra) && buf->buf->name != "* Aux *")) {
00198     set_message ("Error: file is read only", action);
00199     return;
00200   }
00201   if ((fm == "texmacs") && (!buf->needs_to_be_saved ()))
00202     if (buf->buf->name == u) {
00203       set_message ("No changes need to be saved", action);
00204       return;
00205     }
00206 
00207   tm_view vw= get_view ();
00208   tree doc= make_document (vw, fm);
00209   string s= tree_to_generic (doc, fm * "-document");
00210   if (s != "* error: unknown format *") {
00211     if (save_string (u, s))
00212       set_message (concat ("Error: ", vname, " did not open"), action);
00213     else {
00214       set_message (concat ("saved ", vname), action);
00215       if (fm == "texmacs") {
00216         if (no_name () && exists (get_name_buffer ()))
00217           remove (get_name_buffer ());
00218         set_name_buffer (u);
00219         pretend_save_buffer ();
00220         if (suffix (u) == "ts") get_server () -> style_clear_cache ();
00221         if ((fm == "generic") || (fm == "texmacs"))
00222           if (!no_name ())
00223             notify_recent_buffer (as_string (u));
00224       }
00225     }
00226   }
00227   else set_message ("Error: unknown format", action);
00228 }
00229 
00230 void
00231 auto_save () {
00232   int i, n= N(bufs);
00233   for (i=0; i<n; i++) {
00234     tm_buffer buf= bufs[i];
00235     if ((buf->needs_to_be_autosaved () && (!buf->buf->read_only))) {
00236       url name= buf->buf->name;
00237       tree vname= verbatim (as_string (name));
00238       if (!is_scratch (name))
00239         name= glue (buf->buf->name, rescue_mode? "#": "~");
00240       if (N(buf->vws)!=0) {
00241         tree doc= make_document (buf->vws[0]);
00242         bool err= save_string (name, tree_to_texmacs (doc));
00243         if (!rescue_mode) {
00244           if (!err)
00245             call ("set-temporary-message",
00246                   "saved " * as_string (name), "save TeXmacs file", 2500);
00247           else
00248             set_message (concat ("Error: ", vname, " did not open"),
00249                          "save TeXmacs file");
00250         }
00251       }
00252       if (!rescue_mode)
00253         for (int j=0; j<N(buf->vws); j++)
00254           buf->vws[j]->ed->notify_save (false);
00255     }
00256   }
00257   call ("delayed-auto-save");
00258 }
00259 
00260 /******************************************************************************
00261 * Other routines concerning loading and saving buffers
00262 ******************************************************************************/
00263 
00264 bool
00265 no_name () {
00266   tm_buffer buf= get_buffer ();
00267   return is_scratch (buf->buf->name);
00268 }
00269 
00270 bool
00271 help_buffer () {
00272   tm_buffer buf= get_buffer ();
00273   return buf->buf->fm == "help";
00274 }
00275 
00276 bool
00277 buffer_unsaved () {
00278   tm_buffer buf= get_buffer ();
00279   return buf->needs_to_be_saved ();
00280 }
00281 
00282 bool
00283 exists_unsaved_buffer () {
00284   bool flag= false;
00285   int i, n= N(bufs);
00286   for (i=0; i<n; i++) {
00287     tm_buffer buf= bufs[i];
00288     flag = flag || buf->needs_to_be_saved ();
00289   }
00290   return flag;
00291 }
00292 
00293 void
00294 pretend_save_buffer () {
00295   tm_buffer buf= get_buffer ();
00296   for (int i=0; i<N(buf->vws); i++)
00297     buf->vws[i]->ed->notify_save ();
00298 }