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