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