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