]> git.lyx.org Git - lyx.git/blob - src/buffer.h
partial fix for '\n' output problem, still needs fixing of output before/after a...
[lyx.git] / src / buffer.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor         
6  *           Copyright 1995 Matthias Ettrich
7  *
8  *           This file is Copyleft 1996
9  *           Lars Gullik Bjønnes
10  *
11  * ====================================================== */
12  
13 // Change Log:
14 // =========== 
15 // 23/03/98   Heinrich Bauer (heinrich.bauer@t-mobil.de)
16 // Spots marked "changed Heinrich Bauer, 23/03/98" modified due to the
17 // following bug: dvi file export did not work after printing (or previewing)
18 // and vice versa as long as the same file was concerned. This happened
19 // every time the LyX-file was left unchanged between the two actions mentioned
20 // above.
21
22 #ifndef BUFFER_H
23 #define BUFFER_H
24
25 #ifdef __GNUG__
26 #pragma interface
27 #endif
28
29 #include "LString.h"
30
31 #include "BufferView.h"
32 #include "lyxvc.h"
33 #include "bufferparams.h"
34 #include "texrow.h"
35
36
37 class LyXRC;
38 class TeXErrors;
39 class LaTeXFeatures;
40 class auto_mem_buffer;
41
42 ///
43 struct DEPCLEAN {
44         ///
45         bool clean;
46         ///
47         string master;
48         ///
49         DEPCLEAN * next;
50 };
51
52 /** The buffer object.
53   The is is the buffer object. It contains all the informations about
54   a document loaded into LyX. I am not sure if the class is complete or
55   minimal, probably not.
56   */
57 class Buffer {
58 public:
59         ///
60         explicit Buffer(string const & file, bool b = false);
61         
62         ///
63         ~Buffer();
64
65         /** save the buffer's parameters as user default
66             This function saves a file #user_lyxdir/templates/defaults.lyx# 
67             which parameters are those of the current buffer. This file
68             is used as a default template when creating a new
69             file. Returns #true# on success.
70         */
71         bool saveParamsAsDefaults();
72
73         /** High-level interface to buffer functionality.
74             This function parses a command string and executes it
75         */
76         bool Dispatch(string const & command);
77
78         /// Maybe we know the function already by number...
79         bool Dispatch(int ac, string const & argument);
80
81         /// and have an xtl buffer to work with.
82         bool Dispatch(int, auto_mem_buffer &);
83
84         /// should be changed to work for a list.
85         void resize();
86         ///
87         void resizeInsets(BufferView *);
88
89         /// Update window titles of all users
90         void updateTitles() const;
91
92         /// Reset autosave timers for all users
93         void resetAutosaveTimers() const;
94
95         /** Adds the BufferView to the users list.
96             Later this func will insert the #BufferView# into a real list,
97             not just setting a pointer.
98         */
99         void addUser(BufferView * u) { users = u; }
100
101         /** Removes the #BufferView# from the users list.
102             Since we only can have one at the moment, we just reset it.
103         */
104         void delUser(BufferView *) { users = 0; }
105         
106         ///
107         void redraw() {
108                 users->redraw(); 
109                 users->fitCursor(); 
110                 //users->updateScrollbar();
111         }
112
113         ///
114         void loadAutoSaveFile();
115         
116         /** Reads a file. 
117             @param par if != 0 insert the file.
118             @return #false# if method fails.
119         */
120         bool readFile(LyXLex &, LyXParagraph * par = 0);
121         
122         /** Reads a file without header.
123             @param par if != 0 insert the file.
124             @return false if file is not completely read.
125         */
126         bool readLyXformat2(LyXLex &, LyXParagraph * par = 0);
127
128         /// This parses a single LyXformat-Token.
129         bool parseSingleLyXformat2Token(LyXLex &, LyXParagraph *& par,
130                                         LyXParagraph *& return_par,
131                                         string const & token, int & pos,
132                                         char & depth, LyXFont &
133 #ifndef NEW_INSETS
134                                         ,LyXParagraph::footnote_flag &,
135                                         LyXParagraph::footnote_kind &
136 #endif
137                 );
138 private:
139         /// Parse a single inset.
140         void readInset(LyXLex &, LyXParagraph *& par, int & pos, LyXFont &);
141 public:
142         /** Save file
143             Takes care of auto-save files and backup file if requested.
144             Returns #true# if the save is successful, #false# otherwise.
145         */
146         bool save() const;
147         
148         /// Write file. Returns #false# if unsuccesful.
149         bool writeFile(string const &, bool) const;
150         
151         ///
152         void writeFileAscii(string const & , int);
153         ///
154         void writeFileAscii(std::ostream &, int);
155         ///
156         string const asciiParagraph(LyXParagraph const *,
157                                     unsigned int linelen) const;
158         ///
159         void makeLaTeXFile(string const & filename,
160                            string const & original_path,
161                            bool nice, bool only_body = false);
162         /** LaTeX all paragraphs from par to endpar.
163             @param endpar if == 0 then to the end
164         */
165         void latexParagraphs(std::ostream & os, LyXParagraph * par,
166                              LyXParagraph * endpar, TexRow & texrow) const;
167
168         ///
169         int runLiterate();
170
171         ///
172         int buildProgram();
173
174         ///
175         int runChktex();
176
177         ///
178         void makeLinuxDocFile(string const & filename,
179                               bool nice, bool only_body = false);
180         ///
181         void makeDocBookFile(string const & filename,
182                              bool nice, bool only_body = false);
183
184         /// returns the main language for the buffer (document)
185         string const GetLanguage() const {
186                 return params.language;
187         }
188         
189         ///
190         bool isLyxClean() const { return lyx_clean; }
191         
192         ///
193         bool isNwClean() const { return nw_clean; }
194        
195         ///
196         bool isBakClean() const { return bak_clean; }
197         
198         ///
199         bool isDepClean(string const & name) const;
200         
201         ///
202         void markLyxClean() const { 
203                 if (!lyx_clean) {
204                         lyx_clean = true; 
205                         updateTitles();
206                 }
207                 // if the .lyx file has been saved, we don't need an
208                 // autosave 
209                 bak_clean = true;
210         }
211
212         ///
213         void markNwClean() { nw_clean = true; }
214        
215         ///
216         void markBakClean() { bak_clean = true; }
217         
218         ///
219         void markDepClean(string const & name);
220         
221         ///
222         void markNwDirty() { nw_clean = false; }
223
224         ///
225         void setUnnamed(bool flag=true) { unnamed = flag; }
226
227         ///
228         bool isUnnamed() { return unnamed; }
229
230         ///
231         void markDirty() {
232                 if (lyx_clean) {
233                         lyx_clean = false;
234                         updateTitles();
235                 }
236                 nw_clean = false;
237                 bak_clean = false;
238                 DEPCLEAN * tmp = dep_clean;
239                 while (tmp) {
240                         tmp->clean = false;
241                         tmp = tmp->next;
242                 }
243         }
244
245         ///
246         string const & fileName() const { return filename; }
247
248         /** A transformed version of the file name, adequate for LaTeX  
249             The path is stripped if no_path is true (default)
250         */
251         string const getLatexName(bool no_path = true) const;
252
253         /// Change name of buffer. Updates "read-only" flag.
254         void fileName(string const & newfile);
255
256         /// Name of the document's parent
257         void setParentName(string const &);
258
259         /// Is buffer read-only?
260         bool isReadonly() const { return read_only; }
261
262         /// Set buffer read-only flag
263         void setReadonly(bool flag = true);
264
265         /// returns #true# if the buffer contains a LaTeX document
266         bool isLatex() const;
267         /// returns #true# if the buffer contains a LinuxDoc document
268         bool isLinuxDoc() const;
269         /// returns #true# if the buffer contains a DocBook document
270         bool isDocBook() const;
271         /** returns #true# if the buffer contains either a LinuxDoc
272             or DocBook document */
273         bool isSGML() const;
274         /// returns #true# if the buffer contains a Wed document
275         bool isLiterate() const;
276
277         ///
278         void setPaperStuff();
279
280         /** Validate a buffer for LaTeX.
281             This validates the buffer, and returns a struct for use by
282             #makeLaTeX# and others. Its main use is to figure out what
283             commands and packages need to be included in the LaTeX file.
284             It (should) also check that the needed constructs are there
285             (i.e. that the \refs points to coresponding \labels). It
286             should perhaps inset "error" insets to help the user correct
287             obvious mistakes.
288         */
289         void validate(LaTeXFeatures &) const;
290
291         ///
292         string const getIncludeonlyList(char delim = ',');
293         ///
294         std::vector<std::pair<string,string> > const getBibkeyList();
295         ///
296         struct TocItem {
297                 ///
298                 LyXParagraph * par;
299                 ///
300                 int depth;
301                 ///
302                 string str;
303         };
304         ///
305         enum TocType {
306                 ///
307                 TOC_TOC = 0,
308                 ///
309                 TOC_LOF,
310                 ///
311                 TOC_LOT,
312                 ///
313                 TOC_LOA
314         };
315         ///
316         std::vector<std::vector<TocItem> > const getTocList();
317         ///
318         std::vector<string> const getLabelList();
319
320         /** This will clearly have to change later. Later we can have more
321             than one user per buffer. */
322         BufferView * getUser() const { return users; }
323
324         ///
325         void ChangeLanguage(Language const * from, Language const * to);
326         ///
327         bool isMultiLingual();
328
329         /// Does this mean that this is buffer local?
330         UndoStack undostack;
331         
332         /// Does this mean that this is buffer local? 
333         UndoStack redostack;
334         
335         ///
336         BufferParams params;
337         
338         /** is a list of paragraphs.
339          */
340         LyXParagraph * paragraph;
341
342         /// RCS object
343         LyXVC lyxvc;
344
345         /// where the temporaries go if we want them
346         string tmppath;
347
348         ///
349         string filepath;
350
351         /** While writing as LaTeX, tells whether we are
352             doing a 'nice' LaTeX file */
353         bool niceFile;
354
355         /// Used when typesetting to place errorboxes.
356         TexRow texrow;
357 private:
358 #ifndef NEW_INSETS
359         ///
360         void linuxDocHandleFootnote(std::ostream & os,
361                                     LyXParagraph * & par, int const depth);
362 #endif
363         ///
364         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
365                                   int const depth, int desc_on,
366                                   LyXParagraph * & par);
367 #ifndef NEW_INSETS
368         ///
369         void DocBookHandleFootnote(std::ostream & os,
370                                    LyXParagraph * & par, int const depth);
371 #endif
372         ///
373         void sgmlOpenTag(std::ostream & os, int depth,
374                          string const & latexname) const;
375         ///
376         void sgmlCloseTag(std::ostream & os, int depth,
377                           string const & latexname) const;
378         ///
379         void LinuxDocError(LyXParagraph * par, int pos,
380                            string const & message);
381         ///
382         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
383                                   int desc_on, int const depth);
384         ///
385         void SimpleDocBookOnePar(std::ostream &, string & extra,
386                                  LyXParagraph * par, int & desc_on,
387                                  int const depth);
388
389         /// LinuxDoc.
390         void push_tag(std::ostream & os, string const & tag,
391                       int & pos, char stack[5][3]);
392         
393         /// LinuxDoc.
394         void pop_tag(std::ostream & os, string const & tag,
395                      int & pos, char stack[5][3]);
396
397         /// is save needed
398         mutable bool lyx_clean;
399         
400         /// is autosave needed
401         mutable bool bak_clean;
402         
403         /// do we need to run weave/tangle
404         bool nw_clean;
405
406         /// is this a unnamed file (New...)
407         bool unnamed;
408
409         /// is regenerating #.tex# necessary
410         DEPCLEAN * dep_clean;
411
412         /// buffer is r/o
413         bool read_only;
414
415         /// name of the file the buffer is associated with.
416         string filename;
417
418         /// Format number of buffer
419         float format;
420         
421         /** A list of views using this buffer.
422             Why not keep a list of the BufferViews that use this buffer?
423
424             At least then we don't have to do a lot of magic like:
425             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
426             of the buffers in the list of users to do a #updateLayoutChoice#.
427         */
428         BufferView * users;
429
430 public:
431         ///
432         class inset_iterator {
433         public:
434                 ///
435                 inset_iterator() : par(0) /*, it(0)*/ {}
436                 //
437                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
438                         SetParagraph();
439                 }
440                 ///
441                 inset_iterator(LyXParagraph * paragraph,
442                                LyXParagraph::size_type pos);
443                 ///
444                 inset_iterator & operator++() {
445                         if (par) {
446                                 ++it;
447                                 if (it == par->inset_iterator_end()) {
448                                         par = par->next;
449                                         SetParagraph();
450                                 }
451                         }
452                         return *this;
453                 }
454                 ///
455                 Inset * operator*() {return *it; }
456                 ///
457                 LyXParagraph * getPar() { return par; }
458                 ///
459                 LyXParagraph::size_type getPos() {return it.getPos(); }
460                 ///
461                 friend
462                 bool operator==(inset_iterator const & iter1,
463                                 inset_iterator const & iter2);
464                 //
465                 //friend
466                 //bool operator!=(inset_iterator const & iter1,
467                 //              inset_iterator const & iter2);
468         private:
469                 ///
470                 void SetParagraph();
471                 ///
472                 LyXParagraph * par;
473                 ///
474                 LyXParagraph::inset_iterator it;
475         };
476
477         ///
478         inset_iterator inset_iterator_begin() {
479                 return inset_iterator(paragraph);
480         }
481         ///
482         inset_iterator inset_iterator_end() {
483                 return inset_iterator();
484         }
485 };
486
487
488 inline  
489 void Buffer::setParentName(string const & name)
490 {
491         params.parentname = name;    
492 }
493
494 ///
495 inline
496 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
497         return a.par == b.par && a.str == b.str;
498         // No need to compare depth.
499 }
500
501
502 ///
503 inline
504 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
505         return !(a == b);
506         // No need to compare depth.
507 }
508
509 ///
510 inline
511 bool operator==(Buffer::inset_iterator const & iter1,
512                 Buffer::inset_iterator const & iter2) {
513         return iter1.par == iter2.par
514                 && (iter1.par == 0 || iter1.it == iter2.it);
515 }
516
517 ///
518 inline
519 bool operator!=(Buffer::inset_iterator const & iter1,
520                 Buffer::inset_iterator const & iter2) {
521         return !(iter1 == iter2);
522 }
523 #endif
524