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