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