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