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