]> git.lyx.org Git - lyx.git/blob - src/lyxparagraph.h
dd84cf2210c61bbddbb9eef80a5550036a53f54a
[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 String(Buffer const *, bool label);
154         ///
155         string 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                                       std::ostream & foot, TexRow & foot_texrow,
193                                       int & foot_count);
194         ///
195         LyXParagraph * Clone() const;
196         
197         ///
198         bool HasSameLayout(LyXParagraph const * par) const;
199         
200         ///
201         void MakeSameLayout(LyXParagraph const * par);
202
203         /// Is it the first par with same depth and layout?
204         bool IsFirstInSequence() const {
205                 LyXParagraph const * dhook = DepthHook(GetDepth());
206                 return (dhook == this
207                         || dhook->GetLayout() != GetLayout()
208                         || dhook->GetDepth() != GetDepth());
209         }
210
211         /** Check if the current paragraph is the last paragraph in a
212             proof environment */
213         int GetEndLabel(BufferParams const &) const;
214         ///
215         Inset * InInset() { return inset_owner; }
216         ///
217         void SetInsetOwner(Inset * i);
218         ///
219         void deleteInsetsLyXText(BufferView *);
220         void resizeInsetsLyXText(BufferView *);
221 private:
222         ///
223         TextContainer text;
224         ///
225         Inset * inset_owner;
226
227 public:
228         ///
229         size_type size() const { return text.size(); }
230         ///
231         void fitToSize() {
232                 text.resize(text.size());
233         }
234         ///
235         void setContentsFromPar(LyXParagraph * par) {
236                 text = par->text;
237         }
238         ///
239         void clearContents() {
240                 text.clear();
241         }
242         
243         /// 
244         VSpace added_space_top;
245         
246         /// 
247         VSpace added_space_bottom;
248
249         ///
250         Spacing spacing;
251         
252         ///
253         LyXTextClass::LayoutList::size_type layout;
254 #ifndef NEW_INSETS
255         /**
256           \begin{itemize}
257           \item no footnote, closed footnote, 
258           \item open footnote, where footnote
259           \item means footnote-environment
260           \end{itemize}
261          */
262         footnote_flag footnoteflag;
263
264         /// footnote, margin, fig, tab
265         footnote_kind footnotekind;
266 #endif
267         //@Man: the LyX- DTP-switches
268         //@{
269         ///
270         bool line_top;
271         
272         ///
273         bool line_bottom;
274         
275         ///
276         bool pagebreak_top;
277         
278         ///
279         bool pagebreak_bottom;
280         
281         ///
282         LyXAlignment align;
283         
284         ///
285         char depth;
286         
287         ///
288         bool noindent;
289         
290 private:
291         ///
292         block<int, 10> counter_;
293 public:
294         ///
295         void setCounter(int i, int v) { counter_[i] = v; }
296         int getCounter(int i) const { return counter_[i]; }
297         void incCounter(int i) { counter_[i]++; }
298         ///
299         bool start_of_appendix;
300
301         ///
302         bool appendix;
303
304         ///
305         char enumdepth;
306         
307         ///
308         char itemdepth;
309
310         /* This is for the paragraph extra stuff */
311         ///
312         int pextra_type;
313         ///
314         string pextra_width;
315         ///
316         string pextra_widthp;
317         ///
318         int pextra_alignment;
319         ///
320         bool pextra_hfill;
321         ///
322         bool pextra_start_minipage;
323         
324         ///
325         string labelstring;
326         
327         ///
328         string labelwidthstring;
329         //@}
330         
331         ///
332         LyXParagraph * next;
333         ///
334         LyXParagraph * previous;
335
336 #ifndef NEW_TABULAR
337         /* table stuff -- begin*/
338         ///
339         LyXTable * table;
340         /* table stuff -- end*/
341 #endif
342         /// 
343         InsetBibKey * bibkey;  // ale970302
344
345         /** these function are able to hide closed footnotes
346          */
347         LyXParagraph * Next();
348         
349         ///
350         LyXParagraph * Previous();
351         ///
352         LyXParagraph const * Previous() const;
353
354 #ifndef NEW_INSETS
355         /** these function are able to hide open and closed footnotes
356          */ 
357         LyXParagraph * NextAfterFootnote();
358         ///
359         LyXParagraph const * NextAfterFootnote() const;
360         
361         ///
362         LyXParagraph * PreviousBeforeFootnote();
363         ///
364         LyXParagraph * LastPhysicalPar();
365         ///
366         LyXParagraph const * LastPhysicalPar() const;
367         
368         ///
369         LyXParagraph * FirstPhysicalPar();
370         ///
371         LyXParagraph const * FirstPhysicalPar() const;
372 #endif
373
374         /// returns the physical paragraph
375         LyXParagraph * ParFromPos(size_type pos);
376         /// returns the position in the physical par
377         int PositionInParFromPos(size_type pos) const;
378
379         /// for the environments
380         LyXParagraph * DepthHook(int depth);
381         /// for the environments
382         LyXParagraph const * DepthHook(int depth) const;
383         ///
384         int BeginningOfMainBody() const;
385         ///
386         string const & GetLabelstring() const;
387         
388         /// the next two functions are for the manual labels
389         string GetLabelWidthString() const;
390         ///
391         void SetLabelWidthString(string const & s);
392         ///
393         LyXTextClass::LayoutList::size_type GetLayout() const;
394         ///
395         char GetAlign() const;
396         ///
397         char GetDepth() const;
398         ///
399         void SetLayout(BufferParams const &,
400                        LyXTextClass::LayoutList::size_type new_layout);
401         ///
402         void SetOnlyLayout(BufferParams const &,
403                            LyXTextClass::LayoutList::size_type new_layout);
404         ///
405         int GetFirstCounter(int i) const;
406         ///
407         size_type Last() const;
408         ///
409         void Erase(size_type pos);
410         /** the flag determines wether the layout should be copied
411          */ 
412         void BreakParagraph(BufferParams const &, size_type pos, int flag);
413         ///
414         void BreakParagraphConservative(BufferParams const &, size_type pos);
415         /** Get unistantiated font setting. Returns the difference
416           between the characters font and the layoutfont.
417           This is what is stored in the fonttable
418          */
419         LyXFont GetFontSettings(BufferParams const &, size_type pos) const;
420         ///
421         LyXFont GetFirstFontSettings() const;
422
423         /** Get fully instantiated font. If pos == -1, use the layout
424           font attached to this paragraph.
425           If pos == -2, use the label font of the layout attached here.
426           In all cases, the font is instantiated, i.e. does not have any
427           attributes with values LyXFont::INHERIT, LyXFont::IGNORE or 
428           LyXFont::TOGGLE.
429           */
430         LyXFont getFont(BufferParams const &, size_type pos) const;
431         ///
432         value_type GetChar(size_type pos);
433         ///
434         value_type GetChar(size_type pos) const;
435         /// The position must already exist.
436         void SetChar(size_type pos, value_type c) {
437                 text[pos] = c;
438         }
439         
440         ///
441         void SetFont(size_type pos, LyXFont const & font);
442         ///
443         string GetWord(size_type &) const;
444         /// Returns the height of the highest font in range
445         LyXFont::FONT_SIZE HighestFontInRange(size_type startpos,
446                                               size_type endpos) const;
447         ///
448         void InsertChar(size_type pos, value_type c);
449         ///
450         void InsertChar(size_type pos, value_type c, LyXFont const &);
451         ///
452         void InsertInset(size_type pos, Inset * inset);
453         ///
454         void InsertInset(size_type pos, Inset * inset, LyXFont const &);
455         ///
456         bool InsertInsetAllowed(Inset * inset);
457         ///
458         Inset * GetInset(size_type pos);
459         ///
460         Inset const * GetInset(size_type pos) const;
461 #ifndef NEW_INSETS
462         ///
463         void OpenFootnote(size_type pos);
464         ///
465         void CloseFootnote(size_type pos);
466 #endif
467         /// important for cut and paste
468         void CopyIntoMinibuffer(BufferParams const &, size_type pos) const;
469         ///
470         void CutIntoMinibuffer(BufferParams const &, size_type pos);
471         ///
472         bool InsertFromMinibuffer(size_type pos);
473
474         ///
475         bool IsHfill(size_type pos) const;
476         ///
477         bool IsInset(size_type pos) const;
478 #ifndef NEW_INSETS
479         ///
480         bool IsFloat(size_type pos) const;
481 #endif
482         ///
483         bool IsNewline(size_type pos) const;
484         ///
485         bool IsSeparator(size_type pos) const;
486         ///
487         bool IsLineSeparator(size_type pos) const;
488         ///
489         bool IsKomma(size_type pos) const;
490         /// Used by the spellchecker
491         bool IsLetter(size_type pos) const;
492         /// 
493         bool IsWord(size_type pos) const;
494
495         /** This one resets all layout and dtp switches but not the font
496          of the single characters
497          */ 
498         void Clear();
499
500         /** paste this paragraph with the next one
501           be carefull, this doesent make any check at all
502           */ 
503         void PasteParagraph(BufferParams const &);
504
505         /// used to remove the error messages
506         int AutoDeleteInsets();
507
508         /// returns -1 if inset not found
509         int GetPositionOfInset(Inset * inset) const;
510
511 #ifndef NEW_INSETS
512         /// ok and now some footnote functions
513         void OpenFootnotes();
514
515         ///
516         void CloseFootnotes();
517         ///
518         LyXParagraph * FirstSelfrowPar();
519 #endif
520
521         ///
522         int StripLeadingSpaces(LyXTextClassList::size_type tclass); 
523
524 #ifndef NEW_INSETS
525         /** A paragraph following a footnote is a "dummy". A paragraph
526           with a footnote in it is stored as three paragraphs:
527           First a paragraph with the text up to the footnote, then
528           one (or more) paragraphs with the footnote, and finally
529           the a paragraph with the text after the footnote. Only the
530           first paragraph keeps information  about layoutparameters, */
531         bool IsDummy() const;
532 #endif
533         /* If I set a PExtra Indent on one paragraph of a ENV_LIST-TYPE
534            I have to set it on each of it's elements */
535         ///
536         void SetPExtraType(BufferParams const &,
537                            int type, char const * width, char const * widthp);
538         ///
539         void UnsetPExtraType(BufferParams const &);
540         ///
541         bool linuxDocConvertChar(char c, string & sgml_string);
542 #ifndef NEW_TABULAR
543         ///
544         void DocBookContTableRows(Buffer const *,
545                                   std::ostream &, string & extra,
546                                   int & desc_on, size_type i,
547                                   int current_cell_number, int & column);
548         ///
549         void SimpleDocBookOneTablePar(Buffer const *,
550                                       std::ostream &, string & extra,
551                                       int & desc_on, int depth);
552 #endif
553 private:
554         ///
555         struct InsetTable {
556                 ///
557                 size_type pos;
558                 ///
559                 Inset * inset;
560                 ///
561                 InsetTable(size_type p, Inset * i) { pos = p; inset = i;}
562         };
563         ///
564         friend struct matchIT;
565         ///
566         struct matchIT {
567                 /// used by lower_bound and upper_bound
568                 inline
569                 int operator()(LyXParagraph::InsetTable const & a,
570                                LyXParagraph::InsetTable const & b) const {
571                         return a.pos < b.pos;
572                 }
573         };
574         /** A font entry covers a range of positions. Notice that the
575           entries in the list are inserted in random order.
576           I don't think it's worth the effort to implement a more effective
577           datastructure, because the number of different fonts in a paragraph
578           is limited. (Asger)
579           Nevertheless, I decided to store fontlist using a sorted vector:
580           fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
581           pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
582           and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
583           (font_1 covers the chars 0,...,pos_1) (Dekel)
584         */
585         struct FontTable  {
586                 /// End position of paragraph this font attribute covers
587                 size_type pos;
588                 /** Font. Interpretation of the font values:
589                 If a value is LyXFont::INHERIT_*, it means that the font 
590                 attribute is inherited from either the layout of this
591                 paragraph or, in the case of nested paragraphs, from the 
592                 layout in the environment one level up until completely 
593                 resolved.
594                 The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT 
595                 allowed in these font tables.
596                 */
597                 LyXFont font;
598                 ///
599                 FontTable(size_type p, LyXFont const & f) {pos = p; font = f;}
600         };
601         friend struct matchFT;
602         ///
603         struct matchFT {
604                 /// used by lower_bound and upper_bound
605                 inline
606                 int operator()(LyXParagraph::FontTable const & a,
607                                LyXParagraph::FontTable const & b) const {
608                         return a.pos < b.pos;
609                 }
610         };
611
612         ///
613         typedef std::vector<FontTable> FontList;
614         ///
615         FontList fontlist;
616         ///
617         typedef std::vector<InsetTable> InsetList;
618         ///
619         InsetList insetlist;
620         ///
621         LyXParagraph * TeXDeeper(Buffer const *, BufferParams const &,
622                                  std::ostream &, TexRow & texrow,
623                                  std::ostream & foot, TexRow & foot_texrow,
624                                  int & foot_count);
625 #ifndef NEW_INSETS
626         ///
627         LyXParagraph * TeXFootnote(Buffer const *, BufferParams const &,
628                                    std::ostream &, TexRow & texrow,
629                                    std::ostream & foot, TexRow & foot_texrow,
630                                    int & foot_count,
631                                    bool parent_is_rtl);
632 #endif
633 #ifndef NEW_TABULAR
634         ///
635         bool SimpleTeXOneTablePar(Buffer const *, BufferParams const &,
636                                   std::ostream &, TexRow & texrow);
637         ///
638         bool TeXContTableRows(Buffer const *, BufferParams const &,
639                               std::ostream &, size_type i,
640                               int current_cell_number,
641                               int & column, TexRow & texrow);
642 #endif
643         ///
644         void SimpleTeXBlanks(std::ostream &, TexRow & texrow,
645                              size_type const i,
646                              int & column, LyXFont const & font,
647                              LyXLayout const & style);
648         ///
649         void SimpleTeXSpecialChars(Buffer const *, BufferParams const &,
650                                    std::ostream &, TexRow & texrow,
651                                    bool moving_arg,
652                                    LyXFont & font, LyXFont & running_font,
653                                    LyXFont & basefont, bool & open_font,
654                                    LyXLayout const & style,
655                                    size_type & i,
656                                    int & column, value_type const c);
657         ///
658         unsigned int id_;
659         ///
660         static unsigned int paragraph_id;
661 public:
662         class inset_iterator {
663         public:
664                 inset_iterator() {}
665                 inset_iterator(InsetList::iterator const & iter) : it(iter) {};
666                 inset_iterator & operator++() {
667                         ++it;
668                         return *this;
669                 }
670                 Inset * operator*() { return (*it).inset; }
671                 size_type getPos() {return (*it).pos; }
672                 bool operator==(inset_iterator const & iter) const {
673                         return it == iter.it;
674                 }
675                 bool operator!=(inset_iterator const & iter) const {
676                         return it != iter.it;
677                 }
678         private:
679                 InsetList::iterator it;
680         };
681         ///
682         inset_iterator inset_iterator_begin() {
683                 return inset_iterator(insetlist.begin());
684         }
685         ///
686         inset_iterator inset_iterator_end() {
687                 return inset_iterator(insetlist.end());
688         }
689         ///
690         inset_iterator InsetIterator(size_type pos);
691 };
692
693 #endif