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