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