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