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