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>
33 namespace support { class FileName; }
41 /// Based upon ideas in boost::noncopyable, inheriting from this
42 /// class effectively makes the copy constructor protected but the
43 /// assignment constructor private.
49 ProtectCopy(const ProtectCopy &) {};
51 const ProtectCopy & operator=(const ProtectCopy &);
55 /// A TextClass represents a collection of layout information: At the
56 /// moment, this includes Layout's and InsetLayout's.
58 /// There are two major subclasses of TextClass: LayoutFile and
59 /// DocumentClass. These subclasses are what are actually used in LyX.
60 /// Simple TextClass objects are not directly constructed in the main
61 /// LyX code---the constructor is protected. (That said, in tex2lyx
62 /// there are what amount to simple TextClass objects.)
63 class TextClass : protected ProtectCopy {
66 virtual ~TextClass() {};
67 ///////////////////////////////////////////////////////////////////
69 ///////////////////////////////////////////////////////////////////
70 /// The individual paragraph layouts comprising the document class
71 // NOTE Do NOT try to make this a container of Layout pointers, e.g.,
72 // std::vector<Layout *>. This will lead to problems. The reason is
73 // that DocumentClass objects are generally created by copying a
74 // LayoutFile, which serves as a base for the DocumentClass. If the
75 // LayoutList is a container of pointers, then every DocumentClass
76 // that derives from a given LayoutFile (e.g., article) will SHARE
77 // a basic set of layouts. So if one Buffer were to modify a layout
78 // (say, Standard), that would modify that layout for EVERY Buffer
79 // that was based upon the same DocumentClass. (Of course, if you
80 // really, REALLY want to make LayoutList a vector<Layout *>, then
81 // you can implement custom assignment and copy constructors.)
82 typedef std::vector<Layout> LayoutList;
83 /// The inset layouts available to this class
84 typedef std::map<docstring, InsetLayout> InsetLayouts;
86 typedef LayoutList::const_iterator const_iterator;
88 ///////////////////////////////////////////////////////////////////
90 ///////////////////////////////////////////////////////////////////
92 const_iterator begin() const { return layoutlist_.begin(); }
94 const_iterator end() const { return layoutlist_.end(); }
97 ///////////////////////////////////////////////////////////////////
99 ///////////////////////////////////////////////////////////////////
101 Layout const & defaultLayout() const;
103 docstring const & defaultLayoutName() const;
105 bool isDefaultLayout(Layout const &) const;
107 bool isEmptyLayout(Layout const &) const;
108 /// returns a special layout for use when we don't really want one,
109 /// e.g., in table cells
110 Layout const & emptyLayout() const
111 { return operator[](emptylayout_); };
112 /// the name of the empty layout
113 docstring const & emptyLayoutName() const
114 { return emptylayout_; }
115 /// Enumerate the paragraph styles.
116 size_t layoutCount() const { return layoutlist_.size(); }
118 bool hasLayout(docstring const & name) const;
120 Layout const & operator[](docstring const & vname) const;
122 ///////////////////////////////////////////////////////////////////
124 ///////////////////////////////////////////////////////////////////
125 /// Enum used with TextClass::read
127 BASECLASS, //>This is a base class, i.e., top-level layout file
128 MERGE, //>This is a file included in a layout file
129 MODULE, //>This is a layout module
130 VALIDATION //>We're just validating
132 /// return values for read()
139 /// Performs the read of the layout file.
140 /// \return true on success.
141 bool read(support::FileName const & filename, ReadType rt = BASECLASS);
143 bool read(std::string const & str, ReadType rt = BASECLASS);
145 ReturnValues read(Lexer & lex, ReadType rt = BASECLASS);
146 /// validates the layout information passed in str
147 static bool validate(std::string const & str);
149 ///////////////////////////////////////////////////////////////////
151 ///////////////////////////////////////////////////////////////////
152 /// Sees to it the textclass structure has been loaded
153 bool load(std::string const & path = std::string()) const;
154 /// Has this layout file been loaded yet?
155 /// Overridden by DocumentClass
156 virtual bool loaded() const { return loaded_; }
158 ///////////////////////////////////////////////////////////////////
160 ///////////////////////////////////////////////////////////////////
162 std::string const & name() const { return name_; };
164 std::string const & description() const { return description_; };
166 std::string const & latexname() const { return latexname_; }
168 /// Protect construction
171 Layout & operator[](docstring const & vname);
173 ///////////////////////////////////////////////////////////////////
174 // non-const iterators
175 ///////////////////////////////////////////////////////////////////
177 typedef LayoutList::iterator iterator;
179 iterator begin() { return layoutlist_.begin(); }
181 iterator end() { return layoutlist_.end(); }
183 ///////////////////////////////////////////////////////////////////
185 ///////////////////////////////////////////////////////////////////
186 /// Paragraph styles used in this layout
187 LayoutList layoutlist_;
190 /// document class name
191 std::string latexname_;
192 /// document class description
193 std::string description_;
194 /// available types of float, eg. figure, algorithm.
195 mutable FloatList floatlist_;
196 /// Types of counters, eg. sections, eqns, figures, avail. in document class.
197 mutable Counters counters_;
198 /// Has this layout file been loaded yet?
199 mutable bool loaded_;
200 /// Is the TeX class available?
203 std::string opt_fontsize_;
205 std::string opt_pagestyle_;
206 /// Specific class options
207 std::string options_;
209 std::string pagestyle_;
211 std::string class_header_;
213 docstring defaultlayout_;
214 /// name of empty layout
215 static const docstring emptylayout_;
216 /// preamble text to support layout styles
218 /// latex packages loaded by document class.
219 std::set<std::string> provides_;
220 /// latex packages requested by document class.
221 std::set<std::string> requires_;
223 unsigned int columns_;
226 /// header depth to have numbering
228 /// header depth to appear in table of contents
230 /// Can be LaTeX, DocBook, etc.
231 OutputType outputType_;
232 /** Base font. The paragraph and layout fonts are resolved against
233 this font. This has to be fully instantiated. Attributes
234 FONT_INHERIT, FONT_IGNORE, and FONT_TOGGLE are
237 FontInfo defaultfont_;
238 /// Text that dictates how wide the left margin is on the screen
239 docstring leftmargin_;
240 /// Text that dictates how wide the right margin is on the screen
241 docstring rightmargin_;
242 /// The type of command used to produce a title
243 TitleLatexType titletype_;
244 /// The name of the title command
245 std::string titlename_;
246 /// Input layouts available to this layout
247 InsetLayouts insetlayoutlist_;
248 /// The minimal TocLevel of sectioning layouts
250 /// The maximal TocLevel of sectioning layouts
253 ///////////////////////////////////////////////////////////////////
254 // helper routines for reading layout files
255 ///////////////////////////////////////////////////////////////////
257 bool deleteLayout(docstring const &);
259 bool convertLayoutFormat(support::FileName const &, ReadType);
260 /// \return true for success.
261 bool readStyle(Lexer &, Layout &);
263 void readOutputType(Lexer &);
265 void readTitleType(Lexer &);
267 void readMaxCounter(Lexer &);
269 void readClassOptions(Lexer &);
271 void readCharStyle(Lexer &, std::string const &);
273 void readFloat(Lexer &);
275 void readCounter(Lexer &);
279 /// A DocumentClass represents the layout information associated with a
280 /// Buffer. It is based upon a LayoutFile, but may be modified by loading
281 /// various Modules. It is thus a dynamic object, as opposed to LayoutFile's
282 /// which are pretty much static.
284 /// In the main LyX code, DocumentClass objects are created only by
285 /// DocumentClassBundle, for which see below.
286 class DocumentClass : public TextClass, boost::noncopyable {
289 virtual ~DocumentClass() {}
291 ///////////////////////////////////////////////////////////////////
293 ///////////////////////////////////////////////////////////////////
294 /// \return true if there is a Layout with latexname lay
295 bool hasLaTeXLayout(std::string const & lay) const;
296 /// A DocumentClass nevers count as loaded, since it is dynamic
297 virtual bool loaded() { return false; }
298 /// Inset layouts of this doc class
299 InsetLayouts const & insetLayouts() const { return insetlayoutlist_; };
300 /// \return the layout object of an inset given by name. If the name
301 /// is not found as such, the part after the ':' is stripped off, and
302 /// searched again. In this way, an error fallback can be provided:
303 /// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch)
304 /// will invoke the layout object defined by name = 'CharStyle'.
305 /// If that doesn't work either, an empty object returns (shouldn't
306 /// happen). -- Idea JMarc, comment MV
307 InsetLayout const & insetLayout(docstring const & name) const;
308 /// an empty inset layout for use as a default
309 static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; }
311 ///////////////////////////////////////////////////////////////////
313 ///////////////////////////////////////////////////////////////////
314 /// the list of floats defined in the document class
315 FloatList const & floats() const { return floatlist_; }
317 Counters & counters() const { return counters_; }
319 std::string const & opt_fontsize() const { return opt_fontsize_; }
321 std::string const & opt_pagestyle() const { return opt_pagestyle_; }
323 std::string const & options() const { return options_; }
325 std::string const & class_header() const { return class_header_; }
327 std::string const & pagestyle() const { return pagestyle_; }
329 docstring const & preamble() const { return preamble_; }
330 /// is this feature already provided by the class?
331 bool provides(std::string const & p) const;
332 /// features required by the class?
333 std::set<std::string> const & requires() const { return requires_; }
335 unsigned int columns() const { return columns_; }
337 PageSides sides() const { return sides_; }
339 int secnumdepth() const { return secnumdepth_; }
341 int tocdepth() const { return tocdepth_; }
343 FontInfo const & defaultfont() const { return defaultfont_; }
344 /// Text that dictates how wide the left margin is on the screen
345 docstring const & leftmargin() const { return leftmargin_; }
346 /// Text that dictates how wide the right margin is on the screen
347 docstring const & rightmargin() const { return rightmargin_; }
348 /// The type of command used to produce a title
349 TitleLatexType titletype() const { return titletype_; };
350 /// The name of the title command
351 std::string const & titlename() const { return titlename_; };
353 int size() const { return layoutlist_.size(); }
354 /// The minimal TocLevel of sectioning layouts
355 int min_toclevel() const { return min_toclevel_; }
356 /// The maximal TocLevel of sectioning layouts
357 int max_toclevel() const { return max_toclevel_; }
358 /// returns true if the class has a ToC structure
359 bool hasTocLevels() const;
360 /// Can be LaTeX, DocBook, etc.
361 OutputType outputType() const { return outputType_; }
363 /// Constructs a DocumentClass based upon a LayoutFile.
364 DocumentClass(LayoutFile const & tc);
365 /// Needed in tex2lyx
368 /// The only class that can create a DocumentClass is
369 /// DocumentClassBundle, which calls the protected constructor.
370 friend class DocumentClassBundle;
372 static InsetLayout empty_insetlayout_;
376 /// DocumentClassBundle is a container for DocumentClass objects, so that
377 /// they stay in memory for use by Insets, CutAndPaste, and the like, even
378 /// when their associated Buffers are destroyed.
379 /// FIXME Some sort of garbage collection or reference counting wouldn't
380 /// be a bad idea here. It might be enough to check when a Buffer is closed
381 /// (or makeDocumentClass is called) whether the old DocumentClass is in use
384 /// This is a singleton class. Its sole instance is accessed via
385 /// DocumentClassBundle::get().
386 class DocumentClassBundle : boost::noncopyable {
388 /// \return Pointer to a new class equal to baseClass
389 DocumentClass & newClass(LayoutFile const & baseClass);
390 /// \return The sole instance of this class.
391 static DocumentClassBundle & get();
393 /// control instantiation
394 DocumentClassBundle() {}
396 ~DocumentClassBundle();
398 std::vector<DocumentClass *> documentClasses_;
402 /// convert page sides option to text 1 or 2
403 std::ostream & operator<<(std::ostream & os, PageSides p);