]> git.lyx.org Git - lyx.git/blob - src/TextClass.h
e4067ffd20eae613f11a764d3f49cd123b39646f
[lyx.git] / src / TextClass.h
1 // -*- C++ -*-
2 /**
3  * \file TextClass.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * Full author contact details are available in file CREDITS.
8  */
9
10 #ifndef TEXTCLASS_H
11 #define TEXTCLASS_H
12
13 #include "ColorCode.h"
14 #include "FontInfo.h"
15 #include "LayoutEnums.h"
16 #include "LayoutPtr.h"
17
18 #include "insets/InsetLayout.h"
19
20 #include "support/docstring.h"
21 #include "support/types.h"
22
23 #include <boost/shared_ptr.hpp>
24
25 #include <list>
26 #include <map>
27 #include <set>
28 #include <vector>
29
30 namespace lyx {
31
32 namespace support { class FileName; }
33
34 class Counters;
35 class FloatList;
36 class Layout;
37 class LayoutFile;
38 class Lexer;
39
40
41 /// A TextClass represents a collection of layout information: At the 
42 /// moment, this includes Layout's and InsetLayout's.
43 ///
44 /// There are two major subclasses of TextClass: LayoutFile and
45 /// DocumentClass. These subclasses are what are actually used in LyX.
46 /// Simple TextClass objects are not directly constructed in the main 
47 /// LyX code---the constructor is protected. (That said, in tex2lyx
48 /// there are what amount to simple TextClass objects.)
49 class TextClass {
50 public:
51         ///
52         virtual ~TextClass() {};
53         ///////////////////////////////////////////////////////////////////
54         // typedefs
55         ///////////////////////////////////////////////////////////////////
56         /// The individual paragraph layouts comprising the document class
57         typedef std::vector<LayoutPtr> LayoutList;
58         /// The inset layouts available to this class
59         typedef std::map<docstring, InsetLayout> InsetLayouts;
60         ///
61         typedef LayoutList::const_iterator const_iterator;
62         
63         ///////////////////////////////////////////////////////////////////
64         // Iterators
65         ///////////////////////////////////////////////////////////////////
66         /// Note that this returns a (LayoutPtr *). We really need a custom
67         /// iterator here.
68         const_iterator begin() const { return layoutlist_.begin(); }
69         ///
70         const_iterator end() const { return layoutlist_.end(); }
71
72
73         ///////////////////////////////////////////////////////////////////
74         // Layout Info
75         ///////////////////////////////////////////////////////////////////
76         ///
77         LayoutPtr const & defaultLayout() const;
78         ///
79         docstring const & defaultLayoutName() const;
80         /// returns a special layout for use when we don't really want one,
81         /// e.g., in table cells
82         LayoutPtr const & emptyLayout() const 
83                         { return operator[](emptylayout_); };
84         /// the name of the empty layout
85         docstring const & emptyLayoutName() const 
86                         { return emptylayout_; }
87         /// Enumerate the paragraph styles.
88         size_t layoutCount() const { return layoutlist_.size(); }
89         ///
90         bool hasLayout(docstring const & name) const;
91         ///
92         LayoutPtr const & operator[](docstring const & vname) const;
93
94         ///////////////////////////////////////////////////////////////////
95         // reading routines
96         ///////////////////////////////////////////////////////////////////
97         /// Enum used with TextClass::read
98         enum ReadType { 
99                 BASECLASS, //>This is a base class, i.e., top-level layout file
100                 MERGE, //>This is a file included in a layout file
101                 MODULE //>This is a layout module
102         };
103         /// Performs the read of the layout file.
104         /// \return true on success.
105         bool read(support::FileName const & filename, ReadType rt = BASECLASS);
106
107         ///////////////////////////////////////////////////////////////////
108         // loading
109         ///////////////////////////////////////////////////////////////////
110         /// Sees to it the textclass structure has been loaded
111         bool load(std::string const & path = std::string()) const;
112         /// Has this layout file been loaded yet?
113         /// Overridden by DocumentClass
114         virtual bool loaded() const { return loaded_; }
115
116         ///////////////////////////////////////////////////////////////////
117         // accessors
118         ///////////////////////////////////////////////////////////////////
119         ///
120         std::string const & name() const { return name_; };
121         ///
122         std::string const & description() const {       return description_; };
123         ///
124         std::string const & latexname() const { return latexname_; }
125 protected:
126         /// Protect construction
127         TextClass();
128         ///////////////////////////////////////////////////////////////////
129         // members
130         ///////////////////////////////////////////////////////////////////
131         /// Paragraph styles used in this layout
132         LayoutList layoutlist_;
133         /// Layout file name
134         std::string name_;
135         /// document class name
136         std::string latexname_;
137         /// document class description
138         std::string description_;
139         /// available types of float, eg. figure, algorithm.
140         boost::shared_ptr<FloatList> floatlist_;
141         /// Types of counters, eg. sections, eqns, figures, avail. in document class.
142         boost::shared_ptr<Counters> counters_;
143         /// Has this layout file been loaded yet?
144         mutable bool loaded_;
145         /// Is the TeX class available?
146         bool texClassAvail_;
147         ///
148         std::string opt_fontsize_;
149         ///
150         std::string opt_pagestyle_;
151         /// Specific class options
152         std::string options_;
153         ///
154         std::string pagestyle_;
155         ///
156         std::string class_header_;
157         ///
158         docstring defaultlayout_;
159         /// name of empty layout
160         static const docstring emptylayout_;
161         /// preamble text to support layout styles
162         docstring preamble_;
163         /// latex packages loaded by document class.
164         std::set<std::string> provides_;
165         /// latex packages requested by document class.
166         std::set<std::string> requires_;
167         ///
168         unsigned int columns_;
169         ///
170         PageSides sides_;
171         /// header depth to have numbering
172         int secnumdepth_;
173         /// header depth to appear in table of contents
174         int tocdepth_;
175         /// Can be LaTeX, DocBook, etc.
176         OutputType outputType_;
177         /** Base font. The paragraph and layout fonts are resolved against
178             this font. This has to be fully instantiated. Attributes
179             FONT_INHERIT, FONT_IGNORE, and FONT_TOGGLE are
180             extremely illegal.
181         */
182         FontInfo defaultfont_;
183         /// Text that dictates how wide the left margin is on the screen
184         docstring leftmargin_;
185         /// Text that dictates how wide the right margin is on the screen
186         docstring rightmargin_;
187         /// The type of command used to produce a title
188         TitleLatexType titletype_;
189         /// The name of the title command
190         std::string titlename_;
191         /// Input layouts available to this layout
192         mutable InsetLayouts insetlayoutlist_;
193         /// The minimal TocLevel of sectioning layouts
194         int min_toclevel_;
195         /// The maximal TocLevel of sectioning layouts
196         int max_toclevel_;
197 private:
198         ///////////////////////////////////////////////////////////////////
199         // helper routines for reading layout files
200         ///////////////////////////////////////////////////////////////////
201         ///
202         bool deleteLayout(docstring const &);
203         /// \return true for success.
204         bool readStyle(Lexer &, Layout &);
205         ///
206         void readOutputType(Lexer &);
207         ///
208         void readTitleType(Lexer &);
209         ///
210         void readMaxCounter(Lexer &);
211         ///
212         void readClassOptions(Lexer &);
213         ///
214         void readCharStyle(Lexer &, std::string const &);
215         ///
216         void readFloat(Lexer &);
217         ///
218         void readCounter(Lexer &);
219 };
220
221
222 /// A DocumentClass represents the layout information associated with a
223 /// Buffer. It is based upon a LayoutFile, but may be modified by loading
224 /// various Modules. It is thus a dynamic object, as opposed to LayoutFile's
225 /// which are pretty much static. 
226 ///
227 /// In the main LyX code, DocumentClass objects are created only by
228 /// DocumentClassBundle, for which see below.
229 class DocumentClass : public TextClass {
230 public:
231         ///
232         virtual ~DocumentClass() {}
233
234         ///////////////////////////////////////////////////////////////////
235         // Layout Info
236         ///////////////////////////////////////////////////////////////////
237         /// \return true if there is a Layout with latexname lay
238         bool hasLaTeXLayout(std::string const & lay) const;
239         /// A DocumentClass nevers count as loaded, since it is dynamic
240         virtual bool loaded() { return false; }
241         /// Inset layouts of this doc class
242         InsetLayouts & insetLayouts() const { return insetlayoutlist_; };
243         /// \return the layout object of an inset given by name. If the name
244         /// is not found as such, the part after the ':' is stripped off, and
245         /// searched again. In this way, an error fallback can be provided:
246         /// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch)
247         /// will invoke the layout object defined by name = 'CharStyle'.
248         /// If that doesn't work either, an empty object returns (shouldn't
249         /// happen).  -- Idea JMarc, comment MV
250         ///
251         InsetLayout const & insetLayout(docstring const & name) const;
252         /// an empty inset layout for use as a default
253         static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; }
254
255         ///////////////////////////////////////////////////////////////////
256         // accessors
257         ///////////////////////////////////////////////////////////////////
258         /// the list of floats defined in the document class
259         FloatList & floats() { return *floatlist_.get(); }
260         /// the list of floats defined in the document class
261         FloatList const & floats() const { return *floatlist_.get(); }
262         /// The Counters present in this document class.
263         Counters & counters() const { return *counters_.get(); }
264         ///
265         std::string const & opt_fontsize() const { return opt_fontsize_; }
266         ///
267         std::string const & opt_pagestyle() const { return opt_pagestyle_; }
268         ///
269         std::string const & options() const { return options_; }
270         ///
271         std::string const & class_header() const { return class_header_; }
272         ///
273         std::string const & pagestyle() const { return pagestyle_; }
274         ///
275         docstring const & preamble() const { return preamble_; }
276         /// is this feature already provided by the class?
277         bool provides(std::string const & p) const;
278         /// features required by the class?
279         std::set<std::string> const & requires() const { return requires_; }
280         ///
281         unsigned int columns() const { return columns_; }
282         ///
283         PageSides sides() const { return sides_; }
284         ///
285         int secnumdepth() const { return secnumdepth_; }
286         ///
287         int tocdepth() const { return tocdepth_; }
288         ///
289         FontInfo const & defaultfont() const { return defaultfont_; }
290         /// Text that dictates how wide the left margin is on the screen
291         docstring const & leftmargin() const { return leftmargin_; }
292         /// Text that dictates how wide the right margin is on the screen
293         docstring const & rightmargin() const { return rightmargin_; }
294         /// The type of command used to produce a title
295         TitleLatexType titletype() const { return titletype_; };
296         /// The name of the title command
297         std::string const & titlename() const { return titlename_; };
298         ///
299         int size() const { return layoutlist_.size(); }
300         /// The minimal TocLevel of sectioning layouts
301         int min_toclevel() const { return min_toclevel_; }
302         /// The maximal TocLevel of sectioning layouts
303         int max_toclevel() const { return max_toclevel_; }
304         /// returns true if the class has a ToC structure
305         bool hasTocLevels() const;
306         /// Can be LaTeX, DocBook, etc.
307         OutputType outputType() const { return outputType_; }
308 protected:
309         /// Constructs a DocumentClass based upon a LayoutFile.
310         DocumentClass(LayoutFile const & tc);
311         /// Needed in tex2lyx
312         DocumentClass() {};
313 private:
314         /// The only class that can create a DocumentClass is
315         /// DocumentClassBundle, which calls the private constructor.
316         friend class DocumentClassBundle;
317         ///
318         static InsetLayout empty_insetlayout_;
319 };
320
321
322 /// DocumentClassBundle is a container for DocumentClass objects, so that 
323 /// they stay in memory for use by Insets, CutAndPaste, and the like, even
324 /// when their associated Buffers are destroyed.
325 /// FIXME Some sort of garbage collection or reference counting wouldn't
326 /// be a bad idea here. It might be enough to check when a Buffer is closed
327 /// (or makeDocumentClass is called) whether the old DocumentClass is in use 
328 /// anywhere.
329 ///
330 /// This is a singleton class. Its sole instance is accessed via 
331 /// DocumentClassBundle::get().
332 class DocumentClassBundle {
333 public:
334         /// \return Pointer to a new class equal to baseClass
335         DocumentClass & newClass(LayoutFile const & baseClass);
336         /// \return The sole instance of this class.
337         static DocumentClassBundle & get();
338 private:
339         /// control instantiation
340         DocumentClassBundle() {}
341         /// noncopyable
342         DocumentClassBundle(DocumentClassBundle const &);
343         ///
344         std::list<DocumentClass> tc_list_;
345 };
346
347
348 /// convert page sides option to text 1 or 2
349 std::ostream & operator<<(std::ostream & os, PageSides p);
350
351
352 } // namespace lyx
353
354 #endif