]> git.lyx.org Git - lyx.git/blob - src/lyxparagraph.h
97a43ce6b8028f90994e65eaa0f23d13310dc992
[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 "table.h"
24 #include "vspace.h"
25 #include "layout.h"
26 #include "support/block.h"
27 #include "language.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         typedef int size_type;
129
130         ///
131         LyXParagraph();
132         /// this konstruktor inserts the new paragraph in a list
133         explicit
134         LyXParagraph(LyXParagraph * par);
135         /// the destruktors removes the new paragraph from the list
136         ~LyXParagraph();
137
138         ///
139         Language const * getParLanguage(BufferParams const &) const;
140         ///
141         bool isRightToLeftPar(BufferParams const &) const;
142         ///
143         void ChangeLanguage(BufferParams const & bparams,
144                             Language const * from, Language const * to);
145         ///
146         bool isMultiLingual(BufferParams const &);
147         ///
148
149         string String(Buffer const *, bool label);
150         ///
151         string String(Buffer const *, size_type beg, size_type end);
152         
153         ///
154         void writeFile(Buffer const *, std::ostream &, BufferParams const &,
155                        char, char) const;
156         ///
157         void validate(LaTeXFeatures &) const;
158         
159         ///
160         int id() const {
161                 return id_;
162         }
163         ///
164         void id(int id_arg) {
165                 id_ = id_arg;
166         }
167
168         ///
169         void read();
170
171         ///
172         LyXParagraph * TeXOnePar(Buffer const *, BufferParams const &,
173                                  std::ostream &, TexRow & texrow,
174                                  bool moving_arg
175 #ifndef NEW_INSETS
176                                  ,
177                                  std::ostream & foot, TexRow & foot_texrow,
178                                  int & foot_count
179 #endif
180                 );
181         ///
182         bool SimpleTeXOnePar(Buffer const *, BufferParams const &,
183                              std::ostream &, TexRow & texrow, bool moving_arg);
184
185         ///
186         LyXParagraph * TeXEnvironment(Buffer const *, BufferParams const &,
187                                       std::ostream &, TexRow & texrow,
188                                       std::ostream & foot, TexRow & foot_texrow,
189                                       int & foot_count);
190         ///
191         LyXParagraph * Clone() const;
192         
193         ///
194         bool HasSameLayout(LyXParagraph const * par) const;
195         
196         ///
197         void MakeSameLayout(LyXParagraph const * par);
198
199         /// Is it the first par with same depth and layout?
200         bool IsFirstInSequence() const {
201                 LyXParagraph const * dhook = DepthHook(GetDepth());
202                 return (dhook == this
203                         || dhook->GetLayout() != GetLayout()
204                         || dhook->GetDepth() != GetDepth());
205         }
206
207         /** Check if the current paragraph is the last paragraph in a
208             proof environment */
209         int GetEndLabel(BufferParams const &) const;
210         ///
211         Inset * InInset() { return inset_owner; }
212         ///
213         void SetInsetOwner(Inset * i);
214         ///
215         void deleteInsetsLyXText(BufferView *);
216         void resizeInsetsLyXText(BufferView *);
217 private:
218         ///
219         TextContainer text;
220         ///
221         Inset * inset_owner;
222
223 public:
224         ///
225         size_type size() const { return text.size(); }
226         ///
227         void fitToSize() {
228                 text.resize(text.size());
229         }
230         ///
231         void setContentsFromPar(LyXParagraph * par) {
232                 text = par->text;
233         }
234         ///
235         void clearContents() {
236                 text.clear();
237         }
238         
239         /// 
240         VSpace added_space_top;
241         
242         /// 
243         VSpace added_space_bottom;
244
245         ///
246         Spacing spacing;
247         
248         ///
249         LyXTextClass::LayoutList::size_type layout;
250 #ifndef NEW_INSETS
251         /**
252           \begin{itemize}
253           \item no footnote, closed footnote, 
254           \item open footnote, where footnote
255           \item means footnote-environment
256           \end{itemize}
257          */
258         footnote_flag footnoteflag;
259
260         /// footnote, margin, fig, tab
261         footnote_kind footnotekind;
262 #endif
263         //@Man: the LyX- DTP-switches
264         //@{
265         ///
266         bool line_top;
267         
268         ///
269         bool line_bottom;
270         
271         ///
272         bool pagebreak_top;
273         
274         ///
275         bool pagebreak_bottom;
276         
277         ///
278         LyXAlignment align;
279         
280         ///
281         char depth;
282         
283         ///
284         bool noindent;
285         
286 private:
287         ///
288         block<int, 10> counter_;
289 public:
290         ///
291         void setCounter(int i, int v) { counter_[i] = v; }
292         int getCounter(int i) const { return counter_[i]; }
293         void incCounter(int i) { counter_[i]++; }
294         ///
295         bool start_of_appendix;
296
297         ///
298         bool appendix;
299
300         ///
301         char enumdepth;
302         
303         ///
304         char itemdepth;
305
306         /* This is for the paragraph extra stuff */
307         ///
308         int pextra_type;
309         ///
310         string pextra_width;
311         ///
312         string pextra_widthp;
313         ///
314         int pextra_alignment;
315         ///
316         bool pextra_hfill;
317         ///
318         bool pextra_start_minipage;
319         
320         ///
321         string labelstring;
322         
323         ///
324         string labelwidthstring;
325         //@}
326         
327         ///
328         LyXParagraph * next;
329         ///
330         LyXParagraph * previous;
331
332         /* table stuff -- begin*/
333         ///
334         LyXTable * table;
335         /* table stuff -- end*/
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 #endif
368
369         /// returns the physical paragraph
370         LyXParagraph * ParFromPos(size_type pos);
371         /// returns the position in the physical par
372         int PositionInParFromPos(size_type pos) const;
373
374         /// for the environments
375         LyXParagraph * DepthHook(int depth);
376         /// for the environments
377         LyXParagraph const * DepthHook(int depth) const;
378         ///
379         int BeginningOfMainBody() const;
380         ///
381         string const & GetLabelstring() const;
382         
383         /// the next two functions are for the manual labels
384         string GetLabelWidthString() const;
385         ///
386         void SetLabelWidthString(string const & s);
387         ///
388         LyXTextClass::LayoutList::size_type GetLayout() const;
389         ///
390         char GetAlign() const;
391         ///
392         char GetDepth() const;
393         ///
394         void SetLayout(BufferParams const &,
395                        LyXTextClass::LayoutList::size_type new_layout);
396         ///
397         void SetOnlyLayout(BufferParams const &,
398                            LyXTextClass::LayoutList::size_type new_layout);
399         ///
400         int GetFirstCounter(int i) const;
401         ///
402         size_type Last() const;
403         ///
404         void Erase(size_type pos);
405         /** the flag determines wether the layout should be copied
406          */ 
407         void BreakParagraph(BufferParams const &, size_type pos, int flag);
408         ///
409         void BreakParagraphConservative(BufferParams const &, size_type pos);
410         /** Get unistantiated font setting. Returns the difference
411           between the characters font and the layoutfont.
412           This is what is stored in the fonttable
413          */
414         LyXFont GetFontSettings(BufferParams const &, size_type pos) const;
415         ///
416         LyXFont 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 getFont(BufferParams const &, size_type pos) const;
426         ///
427         value_type GetChar(size_type pos);
428         ///
429         value_type GetChar(size_type pos) const;
430         /// The position must already exist.
431         void SetChar(size_type pos, value_type c) {
432                 text[pos] = c;
433         }
434         
435         ///
436         void SetFont(size_type pos, LyXFont const & font);
437         ///
438         string GetWord(size_type &) const;
439         /// Returns the height of the highest font in range
440         LyXFont::FONT_SIZE HighestFontInRange(size_type startpos,
441                                               size_type endpos) const;
442         ///
443         void InsertChar(size_type pos, value_type c);
444         ///
445         void InsertChar(size_type pos, value_type c, LyXFont const &);
446         ///
447         void InsertInset(size_type pos, Inset * inset);
448         ///
449         void InsertInset(size_type pos, Inset * inset, LyXFont const &);
450         ///
451         bool InsertInsetAllowed(Inset * inset);
452         ///
453         Inset * GetInset(size_type pos);
454         ///
455         Inset const * GetInset(size_type pos) const;
456 #ifndef NEW_INSETS
457         ///
458         void OpenFootnote(size_type pos);
459         ///
460         void CloseFootnote(size_type pos);
461 #endif
462         /// important for cut and paste
463         void CopyIntoMinibuffer(BufferParams const &, size_type pos) const;
464         ///
465         void CutIntoMinibuffer(BufferParams const &, size_type pos);
466         ///
467         bool InsertFromMinibuffer(size_type pos);
468
469         ///
470         bool IsHfill(size_type pos) const;
471         ///
472         bool IsInset(size_type pos) const;
473 #ifndef NEW_INSETS
474         ///
475         bool IsFloat(size_type pos) const;
476 #endif
477         ///
478         bool IsNewline(size_type pos) const;
479         ///
480         bool IsSeparator(size_type pos) const;
481         ///
482         bool IsLineSeparator(size_type pos) const;
483         ///
484         bool IsKomma(size_type pos) const;
485         /// Used by the spellchecker
486         bool IsLetter(size_type pos) const;
487         /// 
488         bool IsWord(size_type pos) const;
489
490         /** This one resets all layout and dtp switches but not the font
491          of the single characters
492          */ 
493         void Clear();
494
495         /** paste this paragraph with the next one
496           be carefull, this doesent make any check at all
497           */ 
498         void PasteParagraph(BufferParams const &);
499
500         /// used to remove the error messages
501         int AutoDeleteInsets();
502
503         /// returns -1 if inset not found
504         int GetPositionOfInset(Inset * inset) const;
505
506 #ifndef NEW_INSETS
507         /// ok and now some footnote functions
508         void OpenFootnotes();
509
510         ///
511         void CloseFootnotes();
512         ///
513         LyXParagraph * FirstSelfrowPar();
514 #endif
515
516         ///
517         int StripLeadingSpaces(LyXTextClassList::size_type tclass); 
518
519 #ifndef NEW_INSETS
520         /** A paragraph following a footnote is a "dummy". A paragraph
521           with a footnote in it is stored as three paragraphs:
522           First a paragraph with the text up to the footnote, then
523           one (or more) paragraphs with the footnote, and finally
524           the a paragraph with the text after the footnote. Only the
525           first paragraph keeps information  about layoutparameters, */
526         bool IsDummy() const;
527 #endif
528         /* If I set a PExtra Indent on one paragraph of a ENV_LIST-TYPE
529            I have to set it on each of it's elements */
530         ///
531         void SetPExtraType(BufferParams const &,
532                            int type, char const * width, char const * widthp);
533         ///
534         void UnsetPExtraType(BufferParams const &);
535         ///
536         bool linuxDocConvertChar(char c, string & sgml_string);
537         ///
538         void DocBookContTableRows(Buffer const *,
539                                   std::ostream &, string & extra,
540                                   int & desc_on, size_type i,
541                                   int current_cell_number, int & column);
542         ///
543         void SimpleDocBookOneTablePar(Buffer const *,
544                                       std::ostream &, string & extra,
545                                       int & desc_on, int depth);
546 private:
547         ///
548         struct InsetTable {
549                 ///
550                 size_type pos;
551                 ///
552                 Inset * inset;
553                 ///
554                 InsetTable(size_type p, Inset * i) { pos = p; inset = i;}
555         };
556         ///
557         friend struct matchIT;
558         ///
559         struct matchIT {
560                 /// used by lower_bound and upper_bound
561                 inline
562                 int operator()(LyXParagraph::InsetTable const & a,
563                                LyXParagraph::InsetTable const & b) const {
564                         return a.pos < b.pos;
565                 }
566         };
567         /** A font entry covers a range of positions. Notice that the
568           entries in the list are inserted in random order.
569           I don't think it's worth the effort to implement a more effective
570           datastructure, because the number of different fonts in a paragraph
571           is limited. (Asger)
572           Nevertheless, I decided to store fontlist using a sorted vector:
573           fontlist = { {pos_1,font_1} , {pos_2,font_2} , ... } where
574           pos_1 < pos_2 < ..., font_{i-1} != font_i for all i,
575           and font_i covers the chars in positions pos_{i-1}+1,...,pos_i
576           (font_1 covers the chars 0,...,pos_1) (Dekel)
577         */
578         struct FontTable  {
579                 /// End position of paragraph this font attribute covers
580                 size_type pos;
581                 /** Font. Interpretation of the font values:
582                 If a value is LyXFont::INHERIT_*, it means that the font 
583                 attribute is inherited from either the layout of this
584                 paragraph or, in the case of nested paragraphs, from the 
585                 layout in the environment one level up until completely 
586                 resolved.
587                 The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT 
588                 allowed in these font tables.
589                 */
590                 LyXFont font;
591                 ///
592                 FontTable(size_type p, LyXFont const & f) {pos = p; font = f;}
593         };
594         friend struct matchFT;
595         ///
596         struct matchFT {
597                 /// used by lower_bound and upper_bound
598                 inline
599                 int operator()(LyXParagraph::FontTable const & a,
600                                LyXParagraph::FontTable const & b) const {
601                         return a.pos < b.pos;
602                 }
603         };
604
605         ///
606         typedef std::vector<FontTable> FontList;
607         ///
608         FontList fontlist;
609         ///
610         typedef std::vector<InsetTable> InsetList;
611         ///
612         InsetList insetlist;
613         ///
614         LyXParagraph * TeXDeeper(Buffer const *, BufferParams const &,
615                                  std::ostream &, TexRow & texrow,
616                                  std::ostream & foot, TexRow & foot_texrow,
617                                  int & foot_count);
618 #ifndef NEW_INSETS
619         ///
620         LyXParagraph * TeXFootnote(Buffer const *, BufferParams const &,
621                                    std::ostream &, TexRow & texrow,
622                                    std::ostream & foot, TexRow & foot_texrow,
623                                    int & foot_count,
624                                    bool parent_is_rtl);
625 #endif
626         ///
627         bool SimpleTeXOneTablePar(Buffer const *, BufferParams const &,
628                                   std::ostream &, TexRow & texrow);
629         ///
630         bool TeXContTableRows(Buffer const *, BufferParams const &,
631                               std::ostream &, size_type i,
632                               int current_cell_number,
633                               int & column, TexRow & texrow);
634         ///
635         void SimpleTeXBlanks(std::ostream &, TexRow & texrow,
636                              size_type const i,
637                              int & column, LyXFont const & font,
638                              LyXLayout const & style);
639         ///
640         void SimpleTeXSpecialChars(Buffer const *, BufferParams const &,
641                                    std::ostream &, TexRow & texrow,
642                                    bool moving_arg,
643                                    LyXFont & font, LyXFont & running_font,
644                                    LyXFont & basefont, bool & open_font,
645                                    LyXLayout const & style,
646                                    size_type & i,
647                                    int & column, value_type const c);
648         ///
649         unsigned int id_;
650         ///
651         static unsigned int paragraph_id;
652 public:
653         class inset_iterator {
654         public:
655                 inset_iterator() {}
656                 inset_iterator(InsetList::iterator const & iter) : it(iter) {};
657                 inset_iterator & operator++() {
658                         ++it;
659                         return *this;
660                 }
661                 Inset * operator*() { return (*it).inset; }
662                 size_type getPos() {return (*it).pos; }
663                 bool operator==(inset_iterator const & iter) const {
664                         return it == iter.it;
665                 }
666                 bool operator!=(inset_iterator const & iter) const {
667                         return it != iter.it;
668                 }
669         private:
670                 InsetList::iterator it;
671         };
672         ///
673         inset_iterator inset_iterator_begin() {
674                 return inset_iterator(insetlist.begin());
675         }
676         ///
677         inset_iterator inset_iterator_end() {
678                 return inset_iterator(insetlist.end());
679         }
680         ///
681         inset_iterator InsetIterator(size_type pos);
682 };
683
684 #endif