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