4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * Full author contact details are available in file CREDITS.
13 #include "ColorCode.h"
15 #include "FloatList.h"
18 #include "LayoutEnums.h"
20 #include "insets/InsetLayout.h"
22 #include "support/docstring.h"
23 #include "support/types.h"
25 #include <boost/noncopyable.hpp>
34 namespace support { class FileName; }
42 /// Based upon ideas in boost::noncopyable, inheriting from this
43 /// class effectively makes the copy constructor protected but the
44 /// assignment constructor private.
50 ProtectCopy(const ProtectCopy &) {};
52 const ProtectCopy & operator=(const ProtectCopy &);
56 /// A TextClass represents a collection of layout information: At the
57 /// moment, this includes Layout's and InsetLayout's.
59 /// There are two major subclasses of TextClass: LayoutFile and
60 /// DocumentClass. These subclasses are what are actually used in LyX.
61 /// Simple TextClass objects are not directly constructed in the main
62 /// LyX code---the constructor is protected. (That said, in tex2lyx
63 /// there are what amount to simple TextClass objects.)
64 class TextClass : protected ProtectCopy {
67 virtual ~TextClass() {};
68 ///////////////////////////////////////////////////////////////////
70 ///////////////////////////////////////////////////////////////////
71 /// The individual paragraph layouts comprising the document class
72 // NOTE Do NOT try to make this a container of Layout pointers, e.g.,
73 // std::vector<Layout *>. This will lead to problems. The reason is
74 // that DocumentClass objects are generally created by copying a
75 // LayoutFile, which serves as a base for the DocumentClass. If the
76 // LayoutList is a container of pointers, then every DocumentClass
77 // that derives from a given LayoutFile (e.g., article) will SHARE
78 // a basic set of layouts. So if one Buffer were to modify a layout
79 // (say, Standard), that would modify that layout for EVERY Buffer
80 // that was based upon the same DocumentClass. (Of course, if you
81 // really, REALLY want to make LayoutList a vector<Layout *>, then
82 // you can implement custom assignment and copy constructors.)
83 typedef std::vector<Layout> LayoutList;
84 /// The inset layouts available to this class
85 typedef std::map<docstring, InsetLayout> InsetLayouts;
87 typedef LayoutList::const_iterator const_iterator;
89 ///////////////////////////////////////////////////////////////////
91 ///////////////////////////////////////////////////////////////////
93 const_iterator begin() const { return layoutlist_.begin(); }
95 const_iterator end() const { return layoutlist_.end(); }
98 ///////////////////////////////////////////////////////////////////
100 ///////////////////////////////////////////////////////////////////
102 Layout const & defaultLayout() const;
104 docstring const & defaultLayoutName() const;
106 bool isDefaultLayout(Layout const &) const;
108 bool isEmptyLayout(Layout const &) const;
109 /// returns a special layout for use when we don't really want one,
110 /// e.g., in table cells
111 Layout const & emptyLayout() const
112 { return operator[](emptylayout_); };
113 /// the name of the empty layout
114 docstring const & emptyLayoutName() const
115 { return emptylayout_; }
116 /// Enumerate the paragraph styles.
117 size_t layoutCount() const { return layoutlist_.size(); }
119 bool hasLayout(docstring const & name) const;
121 Layout const & operator[](docstring const & vname) const;
123 ///////////////////////////////////////////////////////////////////
125 ///////////////////////////////////////////////////////////////////
126 /// Enum used with TextClass::read
128 BASECLASS, //>This is a base class, i.e., top-level layout file
129 MERGE, //>This is a file included in a layout file
130 MODULE //>This is a layout module
132 /// Performs the read of the layout file.
133 /// \return true on success.
134 bool read(support::FileName const & filename, ReadType rt = BASECLASS);
136 ///////////////////////////////////////////////////////////////////
138 ///////////////////////////////////////////////////////////////////
139 /// Sees to it the textclass structure has been loaded
140 bool load(std::string const & path = std::string()) const;
141 /// Has this layout file been loaded yet?
142 /// Overridden by DocumentClass
143 virtual bool loaded() const { return loaded_; }
145 ///////////////////////////////////////////////////////////////////
147 ///////////////////////////////////////////////////////////////////
149 std::string const & name() const { return name_; };
151 std::string const & description() const { return description_; };
153 std::string const & latexname() const { return latexname_; }
155 /// Protect construction
158 Layout & operator[](docstring const & vname);
160 ///////////////////////////////////////////////////////////////////
161 // non-const iterators
162 ///////////////////////////////////////////////////////////////////
164 typedef LayoutList::iterator iterator;
166 iterator begin() { return layoutlist_.begin(); }
168 iterator end() { return layoutlist_.end(); }
170 ///////////////////////////////////////////////////////////////////
172 ///////////////////////////////////////////////////////////////////
173 /// Paragraph styles used in this layout
174 LayoutList layoutlist_;
177 /// document class name
178 std::string latexname_;
179 /// document class description
180 std::string description_;
181 /// available types of float, eg. figure, algorithm.
182 mutable FloatList floatlist_;
183 /// Types of counters, eg. sections, eqns, figures, avail. in document class.
184 mutable Counters counters_;
185 /// Has this layout file been loaded yet?
186 mutable bool loaded_;
187 /// Is the TeX class available?
190 std::string opt_fontsize_;
192 std::string opt_pagestyle_;
193 /// Specific class options
194 std::string options_;
196 std::string pagestyle_;
198 std::string class_header_;
200 docstring defaultlayout_;
201 /// name of empty layout
202 static const docstring emptylayout_;
203 /// preamble text to support layout styles
205 /// latex packages loaded by document class.
206 std::set<std::string> provides_;
207 /// latex packages requested by document class.
208 std::set<std::string> requires_;
210 unsigned int columns_;
213 /// header depth to have numbering
215 /// header depth to appear in table of contents
217 /// Can be LaTeX, DocBook, etc.
218 OutputType outputType_;
219 /** Base font. The paragraph and layout fonts are resolved against
220 this font. This has to be fully instantiated. Attributes
221 FONT_INHERIT, FONT_IGNORE, and FONT_TOGGLE are
224 FontInfo defaultfont_;
225 /// Text that dictates how wide the left margin is on the screen
226 docstring leftmargin_;
227 /// Text that dictates how wide the right margin is on the screen
228 docstring rightmargin_;
229 /// The type of command used to produce a title
230 TitleLatexType titletype_;
231 /// The name of the title command
232 std::string titlename_;
233 /// Input layouts available to this layout
234 InsetLayouts insetlayoutlist_;
235 /// The minimal TocLevel of sectioning layouts
237 /// The maximal TocLevel of sectioning layouts
240 ///////////////////////////////////////////////////////////////////
241 // helper routines for reading layout files
242 ///////////////////////////////////////////////////////////////////
244 bool deleteLayout(docstring const &);
245 /// \return true for success.
246 bool readStyle(Lexer &, Layout &);
248 void readOutputType(Lexer &);
250 void readTitleType(Lexer &);
252 void readMaxCounter(Lexer &);
254 void readClassOptions(Lexer &);
256 void readCharStyle(Lexer &, std::string const &);
258 void readFloat(Lexer &);
260 void readCounter(Lexer &);
264 /// A DocumentClass represents the layout information associated with a
265 /// Buffer. It is based upon a LayoutFile, but may be modified by loading
266 /// various Modules. It is thus a dynamic object, as opposed to LayoutFile's
267 /// which are pretty much static.
269 /// In the main LyX code, DocumentClass objects are created only by
270 /// DocumentClassBundle, for which see below.
271 class DocumentClass : public TextClass, boost::noncopyable {
274 virtual ~DocumentClass() {}
276 ///////////////////////////////////////////////////////////////////
278 ///////////////////////////////////////////////////////////////////
279 /// \return true if there is a Layout with latexname lay
280 bool hasLaTeXLayout(std::string const & lay) const;
281 /// A DocumentClass nevers count as loaded, since it is dynamic
282 virtual bool loaded() { return false; }
283 /// Inset layouts of this doc class
284 InsetLayouts const & insetLayouts() const { return insetlayoutlist_; };
285 /// \return the layout object of an inset given by name. If the name
286 /// is not found as such, the part after the ':' is stripped off, and
287 /// searched again. In this way, an error fallback can be provided:
288 /// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch)
289 /// will invoke the layout object defined by name = 'CharStyle'.
290 /// If that doesn't work either, an empty object returns (shouldn't
291 /// happen). -- Idea JMarc, comment MV
292 InsetLayout const & insetLayout(docstring const & name) const;
293 /// an empty inset layout for use as a default
294 static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; }
296 ///////////////////////////////////////////////////////////////////
298 ///////////////////////////////////////////////////////////////////
299 /// the list of floats defined in the document class
300 FloatList const & floats() const { return floatlist_; }
302 Counters & counters() const { return counters_; }
304 std::string const & opt_fontsize() const { return opt_fontsize_; }
306 std::string const & opt_pagestyle() const { return opt_pagestyle_; }
308 std::string const & options() const { return options_; }
310 std::string const & class_header() const { return class_header_; }
312 std::string const & pagestyle() const { return pagestyle_; }
314 docstring const & preamble() const { return preamble_; }
315 /// is this feature already provided by the class?
316 bool provides(std::string const & p) const;
317 /// features required by the class?
318 std::set<std::string> const & requires() const { return requires_; }
320 unsigned int columns() const { return columns_; }
322 PageSides sides() const { return sides_; }
324 int secnumdepth() const { return secnumdepth_; }
326 int tocdepth() const { return tocdepth_; }
328 FontInfo const & defaultfont() const { return defaultfont_; }
329 /// Text that dictates how wide the left margin is on the screen
330 docstring const & leftmargin() const { return leftmargin_; }
331 /// Text that dictates how wide the right margin is on the screen
332 docstring const & rightmargin() const { return rightmargin_; }
333 /// The type of command used to produce a title
334 TitleLatexType titletype() const { return titletype_; };
335 /// The name of the title command
336 std::string const & titlename() const { return titlename_; };
338 int size() const { return layoutlist_.size(); }
339 /// The minimal TocLevel of sectioning layouts
340 int min_toclevel() const { return min_toclevel_; }
341 /// The maximal TocLevel of sectioning layouts
342 int max_toclevel() const { return max_toclevel_; }
343 /// returns true if the class has a ToC structure
344 bool hasTocLevels() const;
345 /// Can be LaTeX, DocBook, etc.
346 OutputType outputType() const { return outputType_; }
348 /// Constructs a DocumentClass based upon a LayoutFile.
349 DocumentClass(LayoutFile const & tc);
350 /// Needed in tex2lyx
353 /// The only class that can create a DocumentClass is
354 /// DocumentClassBundle, which calls the protected constructor.
355 friend class DocumentClassBundle;
357 static InsetLayout empty_insetlayout_;
361 /// DocumentClassBundle is a container for DocumentClass objects, so that
362 /// they stay in memory for use by Insets, CutAndPaste, and the like, even
363 /// when their associated Buffers are destroyed.
364 /// FIXME Some sort of garbage collection or reference counting wouldn't
365 /// be a bad idea here. It might be enough to check when a Buffer is closed
366 /// (or makeDocumentClass is called) whether the old DocumentClass is in use
369 /// This is a singleton class. Its sole instance is accessed via
370 /// DocumentClassBundle::get().
371 class DocumentClassBundle : boost::noncopyable {
373 /// \return Pointer to a new class equal to baseClass
374 DocumentClass & newClass(LayoutFile const & baseClass);
375 /// \return The sole instance of this class.
376 static DocumentClassBundle & get();
378 /// control instantiation
379 DocumentClassBundle() {}
381 std::list<DocumentClass *> tc_list_;
385 /// convert page sides option to text 1 or 2
386 std::ostream & operator<<(std::ostream & os, PageSides p);