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