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