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