]> git.lyx.org Git - lyx.git/blob - src/lyxparagraph.h
remove Last when NEW_INSETS is defined
[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 #ifndef NEW_INSETS
342         ///
343         size_type Last() const;
344 #endif
345         ///
346         void Erase(size_type pos);
347         /** the flag determines wether the layout should be copied
348          */ 
349         void BreakParagraph(BufferParams const &, size_type pos, int flag);
350         ///
351         void BreakParagraphConservative(BufferParams const &, size_type pos);
352         /** Get unistantiated font setting. Returns the difference
353           between the characters font and the layoutfont.
354           This is what is stored in the fonttable
355          */
356         LyXFont const
357         GetFontSettings(BufferParams const &, size_type pos) const;
358         ///
359         LyXFont const GetFirstFontSettings() const;
360
361         /** Get fully instantiated font. If pos == -1, use the layout
362             font attached to this paragraph.
363             If pos == -2, use the label font of the layout attached here.
364             In all cases, the font is instantiated, i.e. does not have any
365             attributes with values LyXFont::INHERIT, LyXFont::IGNORE or 
366             LyXFont::TOGGLE.
367         */
368         LyXFont const getFont(BufferParams const &, size_type pos) const;
369         ///
370         value_type GetChar(size_type pos) const;
371         ///
372         value_type GetUChar(BufferParams const &, size_type pos) const;
373         /// The position must already exist.
374         void SetChar(size_type pos, value_type c);
375         ///
376         void SetFont(size_type pos, LyXFont const & font);
377         ///
378         string const GetWord(size_type &) const;
379         /// Returns the height of the highest font in range
380         LyXFont::FONT_SIZE HighestFontInRange(size_type startpos,
381                                               size_type endpos) const;
382         ///
383         void InsertChar(size_type pos, value_type c);
384         ///
385         void InsertChar(size_type pos, value_type c, LyXFont const &);
386         ///
387         void InsertInset(size_type pos, Inset * inset);
388         ///
389         void InsertInset(size_type pos, Inset * inset, LyXFont const &);
390         ///
391         bool InsertInsetAllowed(Inset * inset);
392         ///
393         Inset * GetInset(size_type pos);
394         ///
395         Inset const * GetInset(size_type pos) const;
396 #ifndef NEW_INSETS
397         ///
398         void OpenFootnote(size_type pos);
399         ///
400         void CloseFootnote(size_type pos);
401 #endif
402         /** important for cut and paste
403             Temporary change from BufferParams to Buffer. Will revert when we
404             get rid of the argument to Inset::Clone(Buffer const &) */
405         void CopyIntoMinibuffer(Buffer const &, size_type pos) const;
406         ///
407         void CutIntoMinibuffer(BufferParams const &, size_type pos);
408         ///
409         bool InsertFromMinibuffer(size_type pos);
410
411         ///
412         bool IsHfill(size_type pos) const;
413         ///
414         bool IsInset(size_type pos) const;
415 #ifndef NEW_INSETS
416         ///
417         bool IsFloat(size_type pos) const;
418 #endif
419         ///
420         bool IsNewline(size_type pos) const;
421         ///
422         bool IsSeparator(size_type pos) const;
423         ///
424         bool IsLineSeparator(size_type pos) const;
425         ///
426         bool IsKomma(size_type pos) const;
427         /// Used by the spellchecker
428         bool IsLetter(size_type pos) const;
429         /// 
430         bool IsWord(size_type pos) const;
431
432         /** This one resets all layout and dtp switches but not the font
433          of the single characters
434          */ 
435         void Clear();
436
437         /** paste this paragraph with the next one
438           be carefull, this doesent make any check at all
439           */ 
440         void PasteParagraph(BufferParams const &);
441
442         /// used to remove the error messages
443         int AutoDeleteInsets();
444
445         /// returns -1 if inset not found
446         int GetPositionOfInset(Inset * inset) const;
447
448 #ifndef NEW_INSETS
449         /// ok and now some footnote functions
450         void OpenFootnotes();
451
452         ///
453         void CloseFootnotes();
454         ///
455         LyXParagraph * FirstSelfrowPar();
456 #endif
457
458         ///
459         int StripLeadingSpaces(LyXTextClassList::size_type tclass); 
460
461 #ifndef NEW_INSETS
462         /** A paragraph following a footnote is a "dummy". A paragraph
463             with a footnote in it is stored as three paragraphs:
464             First a paragraph with the text up to the footnote, then
465             one (or more) paragraphs with the footnote, and finally
466             the a paragraph with the text after the footnote. Only the
467             first paragraph keeps information  about layoutparameters, */
468         bool IsDummy() const;
469 #endif
470         /* If I set a PExtra Indent on one paragraph of a ENV_LIST-TYPE
471            I have to set it on each of it's elements */
472         ///
473         void SetPExtraType(BufferParams const &, int type,
474                            string const & width, string const & widthp);
475         ///
476         void UnsetPExtraType(BufferParams const &);
477         ///
478         bool linuxDocConvertChar(char c, string & sgml_string);
479 private:
480         ///
481         struct InsetTable {
482                 ///
483                 size_type pos;
484                 ///
485                 Inset * inset;
486                 ///
487                 InsetTable(size_type p, Inset * i) : pos(p), inset(i) {}
488         };
489         ///
490         friend struct matchIT;
491         ///
492         struct matchIT {
493                 /// used by lower_bound and upper_bound
494                 inline
495                 int operator()(LyXParagraph::InsetTable const & a,
496                                LyXParagraph::InsetTable const & b) const {
497                         return a.pos < b.pos;
498                 }
499         };
500         /** A font entry covers a range of positions. Notice that the
501           entries in the list are inserted in random order.
502           I don't think it's worth the effort to implement a more effective
503           datastructure, because the number of different fonts in a paragraph
504           is limited. (Asger)
505           Nevertheless, I decided to store fontlist using a sorted vector:
506           fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
507           pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
508           and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
509           (font_1 covers the chars 0,...,pos_1) (Dekel)
510         */
511         struct FontTable  {
512                 ///
513                 FontTable(size_type p, LyXFont const & f)
514                         : pos_(p)
515                 {
516                         font_ = container.get(f);
517                 }
518                 ///
519                 size_type pos() const { return pos_; }
520                 ///
521                 void pos(size_type p) { pos_ = p; }
522                 ///
523                 LyXFont const & font() const { return *font_; }
524                 ///
525                 void font(LyXFont const & f) { font_ = container.get(f);}
526         private:
527                 /// End position of paragraph this font attribute covers
528                 size_type pos_;
529                 /** Font. Interpretation of the font values:
530                 If a value is LyXFont::INHERIT_*, it means that the font 
531                 attribute is inherited from either the layout of this
532                 paragraph or, in the case of nested paragraphs, from the 
533                 layout in the environment one level up until completely 
534                 resolved.
535                 The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT 
536                 allowed in these font tables.
537                 */
538                 boost::shared_ptr<LyXFont> font_;
539                 ///
540                 static ShareContainer<LyXFont> container;
541         };
542         ///
543         friend struct matchFT;
544         ///
545         struct matchFT {
546                 /// used by lower_bound and upper_bound
547                 inline
548                 int operator()(LyXParagraph::FontTable const & a,
549                                LyXParagraph::FontTable const & b) const {
550                         return a.pos() < b.pos();
551                 }
552         };
553
554         ///
555         typedef std::vector<FontTable> FontList;
556         ///
557         FontList fontlist;
558         ///
559         typedef std::vector<InsetTable> InsetList;
560         ///
561         InsetList insetlist;
562         ///
563         LyXParagraph * TeXDeeper(Buffer const *, BufferParams const &,
564                                  std::ostream &, TexRow & texrow
565 #ifndef NEW_INSETS
566                                  ,std::ostream & foot, TexRow & foot_texrow,
567                                  int & foot_count
568 #endif
569                 );
570 #ifndef NEW_INSETS
571         ///
572         LyXParagraph * TeXFootnote(Buffer const *, BufferParams const &,
573                                    std::ostream &, TexRow & texrow,
574                                    std::ostream & foot, TexRow & foot_texrow,
575                                    int & foot_count,
576                                    bool parent_is_rtl);
577 #endif
578         ///
579         void SimpleTeXBlanks(std::ostream &, TexRow & texrow,
580                              size_type const i,
581                              int & column, LyXFont const & font,
582                              LyXLayout const & style);
583         ///
584         void SimpleTeXSpecialChars(Buffer const *, BufferParams const &,
585                                    std::ostream &, TexRow & texrow,
586                                    bool moving_arg,
587                                    LyXFont & font, LyXFont & running_font,
588                                    LyXFont & basefont, bool & open_font,
589                                    LyXLayout const & style,
590                                    size_type & i,
591                                    int & column, value_type const c);
592         ///
593         unsigned int id_;
594         ///
595         static unsigned int paragraph_id;
596 public:
597         ///
598         class inset_iterator {
599         public:
600                 ///
601                 inset_iterator() {}
602                 //
603                 inset_iterator(InsetList::iterator const & iter) : it(iter) {};
604                 ///
605                 inset_iterator & operator++() {
606                         ++it;
607                         return *this;
608                 }
609                 ///
610                 Inset * operator*() { return (*it).inset; }
611                 ///
612                 size_type getPos() const {return (*it).pos; }
613                 ///
614                 bool operator==(inset_iterator const & iter) const {
615                         return it == iter.it;
616                 }
617                 ///
618                 bool operator!=(inset_iterator const & iter) const {
619                         return it != iter.it;
620                 }
621         private:
622                 ///
623                 InsetList::iterator it;
624         };
625         ///
626         inset_iterator inset_iterator_begin();
627         ///
628         inset_iterator inset_iterator_end();
629         ///
630         inset_iterator InsetIterator(size_type pos);
631 };
632
633
634 inline
635 int LyXParagraph::id() const
636 {
637         return id_;
638 }
639
640
641 inline
642 void  LyXParagraph::id(int id_arg)
643 {
644         id_ = id_arg;
645 }
646
647
648 inline
649 bool LyXParagraph::IsFirstInSequence() const
650 {
651         LyXParagraph const * dhook = DepthHook(GetDepth());
652         return (dhook == this
653                 || dhook->GetLayout() != GetLayout()
654                 || dhook->GetDepth() != GetDepth());
655 }
656
657
658 inline
659 Inset * LyXParagraph::InInset()
660 {
661         return inset_owner;
662 }
663
664
665 inline
666 LyXParagraph::size_type LyXParagraph::size() const
667 {
668         return text.size();
669 }
670
671
672 inline
673 void LyXParagraph::clearContents()
674 {
675         text.clear();
676 }
677
678
679 inline
680 void LyXParagraph::setCounter(int i, int v)
681 {
682         counter_[i] = v;
683 }
684
685
686 inline
687 int LyXParagraph::getCounter(int i) const
688 {
689         return counter_[i];
690 }
691
692
693 inline
694 void LyXParagraph::incCounter(int i)
695 {
696         counter_[i]++;
697 }
698
699
700 inline
701 void LyXParagraph::SetChar(size_type pos, value_type c)
702 {
703         text[pos] = c;
704 }
705
706
707 inline
708 LyXParagraph::inset_iterator LyXParagraph::inset_iterator_begin()
709 {
710         return inset_iterator(insetlist.begin());
711 }
712
713
714 inline
715 LyXParagraph::inset_iterator LyXParagraph::inset_iterator_end()
716 {
717         return inset_iterator(insetlist.end());
718 }
719 #endif