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