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