]> git.lyx.org Git - lyx.git/blob - src/lyxparagraph.h
small patch from Dekel, begin introducing the real boost framework, get rid of the...
[lyx.git] / src / lyxparagraph.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *       
7  *          Copyright 1995 Matthias Ettrich
8  *          Copyright 1995-2000 The LyX Team.
9  *
10  * ====================================================== */
11
12 #ifndef LYXPARAGRAPH_H
13 #define LYXPARAGRAPH_H
14
15 #ifdef __GNUG__
16 #pragma interface
17 #endif
18
19 #include <vector>
20 #include <list>
21
22 #include "insets/lyxinset.h"
23 #include "vspace.h"
24 #include "layout.h"
25 #include <boost/array.hpp>
26 #include "language.h"
27
28 class BufferParams;
29 class LyXBuffer;
30 class TexRow;
31 struct LaTeXFeatures;
32 class InsetBibKey;
33 class BufferView;
34
35 // I dare you to enable this and help me find all the bugs that then show
36 // up. (Lgb)
37 //#define NEW_INSETS 1
38
39 /// A LyXParagraph holds all text, attributes and insets in a text paragraph
40 class LyXParagraph  {
41 public:
42         ///
43         enum PEXTRA_TYPE {
44                 ///
45                 PEXTRA_NONE,
46                 ///
47                 PEXTRA_INDENT,
48                 ///
49                 PEXTRA_MINIPAGE,
50                 ///
51                 PEXTRA_FLOATFLT
52         };
53         ///
54         enum MINIPAGE_ALIGNMENT {
55                 ///
56                 MINIPAGE_ALIGN_TOP,
57                 ///
58                 MINIPAGE_ALIGN_MIDDLE,
59                 ///
60                 MINIPAGE_ALIGN_BOTTOM
61         };
62         ///
63         enum META_KIND {
64 #ifndef NEW_INSETS
65                 ///
66                 META_FOOTNOTE = 1,
67                 ///
68                 META_MARGIN,
69                 ///
70                 META_FIG,
71                 ///
72                 META_TAB,
73                 ///
74                 META_ALGORITHM,
75                 ///
76                 META_WIDE_FIG,
77                 ///
78                 META_WIDE_TAB,
79                 ///
80                 META_HFILL,
81 #else
82                 ///
83                 META_HFILL = 1,
84 #endif
85                 ///
86                 META_NEWLINE,
87                 //
88                 //META_PROTECTED_SEPARATOR,
89                 ///
90                 META_INSET
91         };
92 #ifndef NEW_INSETS
93
94         /// The footnoteflag
95         enum footnote_flag {
96                 ///
97                 NO_FOOTNOTE,
98                 ///
99                 OPEN_FOOTNOTE,
100                 ///
101                 CLOSED_FOOTNOTE
102         };
103
104         /// The footnotekinds
105         enum footnote_kind {
106                 ///
107                 FOOTNOTE,
108                 ///
109                 MARGIN,
110                 ///
111                 FIG,
112                 ///
113                 TAB,
114                 ///
115                 ALGORITHM,  // Bernhard, 970807
116                 ///
117                 WIDE_FIG,   // CFO-G, 971106
118                 ///
119                 WIDE_TAB    // CFO-G, 971106
120         };
121 #endif
122         ///
123         typedef char value_type;
124         ///
125         typedef std::vector<value_type> TextContainer;
126         ///
127         typedef int size_type;
128
129         ///
130         LyXParagraph();
131         /// this konstruktor inserts the new paragraph in a list
132         explicit
133         LyXParagraph(LyXParagraph * par);
134         /// the destruktors removes the new paragraph from the list
135         ~LyXParagraph();
136
137         ///
138         Language const * getParLanguage(BufferParams const &) const;
139         ///
140         bool isRightToLeftPar(BufferParams const &) const;
141         ///
142         void ChangeLanguage(BufferParams const & bparams,
143                             Language const * from, Language const * to);
144         ///
145         bool isMultiLingual(BufferParams const &);
146         ///
147
148         string const String(Buffer const *, bool label);
149         ///
150         string const String(Buffer const *, size_type beg, size_type end);
151         
152         ///
153         void writeFile(Buffer const *, std::ostream &, BufferParams const &,
154                        char, char) const;
155         ///
156         void validate(LaTeXFeatures &) const;
157         
158         ///
159         int id() const {
160                 return id_;
161         }
162         ///
163         void id(int id_arg) {
164                 id_ = id_arg;
165         }
166
167         ///
168         void read();
169
170         ///
171         LyXParagraph * TeXOnePar(Buffer const *, BufferParams const &,
172                                  std::ostream &, TexRow & texrow,
173                                  bool moving_arg
174 #ifndef NEW_INSETS
175                                  ,
176                                  std::ostream & foot, TexRow & foot_texrow,
177                                  int & foot_count
178 #endif
179                 );
180         ///
181         bool SimpleTeXOnePar(Buffer const *, BufferParams const &,
182                              std::ostream &, TexRow & texrow, bool moving_arg);
183
184         ///
185         LyXParagraph * TeXEnvironment(Buffer const *, BufferParams const &,
186                                       std::ostream &, TexRow & texrow
187 #ifndef NEW_INSETS
188                                       ,std::ostream & foot, TexRow & foot_texrow,
189                                       int & foot_count
190 #endif
191                 );
192         ///
193         LyXParagraph * Clone() const;
194         
195         ///
196         bool HasSameLayout(LyXParagraph const * par) const;
197         
198         ///
199         void MakeSameLayout(LyXParagraph const * par);
200
201         /// Is it the first par with same depth and layout?
202         bool IsFirstInSequence() const {
203                 LyXParagraph const * dhook = DepthHook(GetDepth());
204                 return (dhook == this
205                         || dhook->GetLayout() != GetLayout()
206                         || dhook->GetDepth() != GetDepth());
207         }
208
209         /** Check if the current paragraph is the last paragraph in a
210             proof environment */
211         int GetEndLabel(BufferParams const &) const;
212         ///
213         Inset * InInset() { return inset_owner; }
214         ///
215         void SetInsetOwner(Inset * i);
216         ///
217         void deleteInsetsLyXText(BufferView *);
218         ///
219         void resizeInsetsLyXText(BufferView *);
220 private:
221         ///
222         TextContainer text;
223         ///
224         Inset * inset_owner;
225
226 public:
227         ///
228         size_type size() const { return text.size(); }
229         ///
230         void fitToSize() {
231                 text.resize(text.size());
232         }
233         ///
234         void setContentsFromPar(LyXParagraph * par) {
235                 text = par->text;
236         }
237         ///
238         void clearContents() {
239                 text.clear();
240         }
241         
242         /// 
243         VSpace added_space_top;
244         
245         /// 
246         VSpace added_space_bottom;
247
248         ///
249         Spacing spacing;
250         
251         ///
252         LyXTextClass::LayoutList::size_type layout;
253 #ifndef NEW_INSETS
254         /**
255           \begin{itemize}
256           \item no footnote, closed footnote, 
257           \item open footnote, where footnote
258           \item means footnote-environment
259           \end{itemize}
260          */
261         footnote_flag footnoteflag;
262
263         /// footnote, margin, fig, tab
264         footnote_kind footnotekind;
265 #endif
266         ///
267         bool line_top;
268         
269         ///
270         bool line_bottom;
271         
272         ///
273         bool pagebreak_top;
274         
275         ///
276         bool pagebreak_bottom;
277         
278         ///
279         LyXAlignment align;
280         
281         ///
282         char depth;
283         
284         ///
285         bool noindent;
286         
287 private:
288         ///
289         array<int, 10> counter_;
290 public:
291         ///
292         void setCounter(int i, int v) { counter_[i] = v; }
293         ///
294         int getCounter(int i) const { return counter_[i]; }
295         ///
296         void incCounter(int i) { counter_[i]++; }
297         ///
298         bool start_of_appendix;
299
300         ///
301         bool appendix;
302
303         ///
304         char enumdepth;
305         
306         ///
307         char itemdepth;
308
309         /* This is for the paragraph extra stuff */
310         ///
311         int pextra_type;
312         ///
313         string pextra_width;
314         ///
315         string pextra_widthp;
316         ///
317         int pextra_alignment;
318         ///
319         bool pextra_hfill;
320         ///
321         bool pextra_start_minipage;
322         
323         ///
324         string labelstring;
325         
326         ///
327         string labelwidthstring;
328         
329         ///
330         LyXParagraph * next;
331         ///
332         LyXParagraph * previous;
333
334         /// 
335         InsetBibKey * bibkey;  // ale970302
336
337         /** these function are able to hide closed footnotes
338          */
339         LyXParagraph * Next();
340         
341         ///
342         LyXParagraph * Previous();
343         ///
344         LyXParagraph const * Previous() const;
345
346 #ifndef NEW_INSETS
347         /** these function are able to hide open and closed footnotes
348          */ 
349         LyXParagraph * NextAfterFootnote();
350         ///
351         LyXParagraph const * NextAfterFootnote() const;
352         
353         ///
354         LyXParagraph * PreviousBeforeFootnote();
355         ///
356         LyXParagraph * LastPhysicalPar();
357         ///
358         LyXParagraph const * LastPhysicalPar() const;
359         
360         ///
361         LyXParagraph * FirstPhysicalPar();
362         ///
363         LyXParagraph const * FirstPhysicalPar() const;
364         /// returns the physical paragraph
365         LyXParagraph * ParFromPos(size_type pos);
366         /// returns the position in the physical par
367         int PositionInParFromPos(size_type pos) const;
368 #endif
369
370         /// for the environments
371         LyXParagraph * DepthHook(int depth);
372         /// for the environments
373         LyXParagraph const * DepthHook(int depth) const;
374         ///
375         int BeginningOfMainBody() const;
376         ///
377         string const & GetLabelstring() const;
378         
379         /// the next two functions are for the manual labels
380         string const GetLabelWidthString() const;
381         ///
382         void SetLabelWidthString(string const & s);
383         ///
384         LyXTextClass::LayoutList::size_type GetLayout() const;
385         ///
386         char GetAlign() const;
387         ///
388         char GetDepth() const;
389         ///
390         void SetLayout(BufferParams const &,
391                        LyXTextClass::LayoutList::size_type new_layout);
392         ///
393         void SetOnlyLayout(BufferParams const &,
394                            LyXTextClass::LayoutList::size_type new_layout);
395         ///
396         int GetFirstCounter(int i) const;
397         ///
398         size_type Last() const;
399         ///
400         void Erase(size_type pos);
401         /** the flag determines wether the layout should be copied
402          */ 
403         void BreakParagraph(BufferParams const &, size_type pos, int flag);
404         ///
405         void BreakParagraphConservative(BufferParams const &, size_type pos);
406         /** Get unistantiated font setting. Returns the difference
407           between the characters font and the layoutfont.
408           This is what is stored in the fonttable
409          */
410         LyXFont const
411         GetFontSettings(BufferParams const &, size_type pos) const;
412         ///
413         LyXFont const GetFirstFontSettings() const;
414
415         /** Get fully instantiated font. If pos == -1, use the layout
416             font attached to this paragraph.
417             If pos == -2, use the label font of the layout attached here.
418             In all cases, the font is instantiated, i.e. does not have any
419             attributes with values LyXFont::INHERIT, LyXFont::IGNORE or 
420             LyXFont::TOGGLE.
421         */
422         LyXFont const getFont(BufferParams const &, size_type pos) const;
423         ///
424         value_type GetChar(size_type pos) const;
425         /// The position must already exist.
426         void SetChar(size_type pos, value_type c) {
427                 text[pos] = c;
428         }
429         
430         ///
431         void SetFont(size_type pos, LyXFont const & font);
432         ///
433         string const GetWord(size_type &) const;
434         /// Returns the height of the highest font in range
435         LyXFont::FONT_SIZE HighestFontInRange(size_type startpos,
436                                               size_type endpos) const;
437         ///
438         void InsertChar(size_type pos, value_type c);
439         ///
440         void InsertChar(size_type pos, value_type c, LyXFont const &);
441         ///
442         void InsertInset(size_type pos, Inset * inset);
443         ///
444         void InsertInset(size_type pos, Inset * inset, LyXFont const &);
445         ///
446         bool InsertInsetAllowed(Inset * inset);
447         ///
448         Inset * GetInset(size_type pos);
449         ///
450         Inset const * GetInset(size_type pos) const;
451 #ifndef NEW_INSETS
452         ///
453         void OpenFootnote(size_type pos);
454         ///
455         void CloseFootnote(size_type pos);
456 #endif
457         /// important for cut and paste
458         void CopyIntoMinibuffer(BufferParams const &, size_type pos) const;
459         ///
460         void CutIntoMinibuffer(BufferParams const &, size_type pos);
461         ///
462         bool InsertFromMinibuffer(size_type pos);
463
464         ///
465         bool IsHfill(size_type pos) const;
466         ///
467         bool IsInset(size_type pos) const;
468 #ifndef NEW_INSETS
469         ///
470         bool IsFloat(size_type pos) const;
471 #endif
472         ///
473         bool IsNewline(size_type pos) const;
474         ///
475         bool IsSeparator(size_type pos) const;
476         ///
477         bool IsLineSeparator(size_type pos) const;
478         ///
479         bool IsKomma(size_type pos) const;
480         /// Used by the spellchecker
481         bool IsLetter(size_type pos) const;
482         /// 
483         bool IsWord(size_type pos) const;
484
485         /** This one resets all layout and dtp switches but not the font
486          of the single characters
487          */ 
488         void Clear();
489
490         /** paste this paragraph with the next one
491           be carefull, this doesent make any check at all
492           */ 
493         void PasteParagraph(BufferParams const &);
494
495         /// used to remove the error messages
496         int AutoDeleteInsets();
497
498         /// returns -1 if inset not found
499         int GetPositionOfInset(Inset * inset) const;
500
501 #ifndef NEW_INSETS
502         /// ok and now some footnote functions
503         void OpenFootnotes();
504
505         ///
506         void CloseFootnotes();
507         ///
508         LyXParagraph * FirstSelfrowPar();
509 #endif
510
511         ///
512         int StripLeadingSpaces(LyXTextClassList::size_type tclass); 
513
514 #ifndef NEW_INSETS
515         /** A paragraph following a footnote is a "dummy". A paragraph
516             with a footnote in it is stored as three paragraphs:
517             First a paragraph with the text up to the footnote, then
518             one (or more) paragraphs with the footnote, and finally
519             the a paragraph with the text after the footnote. Only the
520             first paragraph keeps information  about layoutparameters, */
521         bool IsDummy() const;
522 #endif
523         /* If I set a PExtra Indent on one paragraph of a ENV_LIST-TYPE
524            I have to set it on each of it's elements */
525         ///
526         void SetPExtraType(BufferParams const &, int type,
527                            string const & width, string const & widthp);
528         ///
529         void UnsetPExtraType(BufferParams const &);
530         ///
531         bool linuxDocConvertChar(char c, string & sgml_string);
532 private:
533         ///
534         struct InsetTable {
535                 ///
536                 size_type pos;
537                 ///
538                 Inset * inset;
539                 ///
540                 InsetTable(size_type p, Inset * i) { pos = p; inset = i;}
541         };
542         ///
543         friend struct matchIT;
544         ///
545         struct matchIT {
546                 /// used by lower_bound and upper_bound
547                 inline
548                 int operator()(LyXParagraph::InsetTable const & a,
549                                LyXParagraph::InsetTable const & b) const {
550                         return a.pos < b.pos;
551                 }
552         };
553         /** A font entry covers a range of positions. Notice that the
554           entries in the list are inserted in random order.
555           I don't think it's worth the effort to implement a more effective
556           datastructure, because the number of different fonts in a paragraph
557           is limited. (Asger)
558           Nevertheless, I decided to store fontlist using a sorted vector:
559           fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
560           pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
561           and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
562           (font_1 covers the chars 0,...,pos_1) (Dekel)
563         */
564         struct FontTable  {
565                 /// End position of paragraph this font attribute covers
566                 size_type pos;
567                 /** Font. Interpretation of the font values:
568                 If a value is LyXFont::INHERIT_*, it means that the font 
569                 attribute is inherited from either the layout of this
570                 paragraph or, in the case of nested paragraphs, from the 
571                 layout in the environment one level up until completely 
572                 resolved.
573                 The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT 
574                 allowed in these font tables.
575                 */
576                 LyXFont font;
577                 ///
578                 FontTable(size_type p, LyXFont const & f) {pos = p; font = f;}
579         };
580         ///
581         friend struct matchFT;
582         ///
583         struct matchFT {
584                 /// used by lower_bound and upper_bound
585                 inline
586                 int operator()(LyXParagraph::FontTable const & a,
587                                LyXParagraph::FontTable const & b) const {
588                         return a.pos < b.pos;
589                 }
590         };
591
592         ///
593         typedef std::vector<FontTable> FontList;
594         ///
595         FontList fontlist;
596         ///
597         typedef std::vector<InsetTable> InsetList;
598         ///
599         InsetList insetlist;
600         ///
601         LyXParagraph * TeXDeeper(Buffer const *, BufferParams const &,
602                                  std::ostream &, TexRow & texrow
603 #ifndef NEW_INSETS
604                                  ,std::ostream & foot, TexRow & foot_texrow,
605                                  int & foot_count
606 #endif
607                 );
608 #ifndef NEW_INSETS
609         ///
610         LyXParagraph * TeXFootnote(Buffer const *, BufferParams const &,
611                                    std::ostream &, TexRow & texrow,
612                                    std::ostream & foot, TexRow & foot_texrow,
613                                    int & foot_count,
614                                    bool parent_is_rtl);
615 #endif
616         ///
617         void SimpleTeXBlanks(std::ostream &, TexRow & texrow,
618                              size_type const i,
619                              int & column, LyXFont const & font,
620                              LyXLayout const & style);
621         ///
622         void SimpleTeXSpecialChars(Buffer const *, BufferParams const &,
623                                    std::ostream &, TexRow & texrow,
624                                    bool moving_arg,
625                                    LyXFont & font, LyXFont & running_font,
626                                    LyXFont & basefont, bool & open_font,
627                                    LyXLayout const & style,
628                                    size_type & i,
629                                    int & column, value_type const c);
630         ///
631         unsigned int id_;
632         ///
633         static unsigned int paragraph_id;
634 public:
635         ///
636         class inset_iterator {
637         public:
638                 ///
639                 inset_iterator() {}
640                 //
641                 inset_iterator(InsetList::iterator const & iter) : it(iter) {};
642                 ///
643                 inset_iterator & operator++() {
644                         ++it;
645                         return *this;
646                 }
647                 ///
648                 Inset * operator*() { return (*it).inset; }
649                 ///
650                 size_type getPos() {return (*it).pos; }
651                 ///
652                 bool operator==(inset_iterator const & iter) const {
653                         return it == iter.it;
654                 }
655                 ///
656                 bool operator!=(inset_iterator const & iter) const {
657                         return it != iter.it;
658                 }
659         private:
660                 ///
661                 InsetList::iterator it;
662         };
663         ///
664         inset_iterator inset_iterator_begin() {
665                 return inset_iterator(insetlist.begin());
666         }
667         ///
668         inset_iterator inset_iterator_end() {
669                 return inset_iterator(insetlist.end());
670         }
671         ///
672         inset_iterator InsetIterator(size_type pos);
673 };
674
675 #endif