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.)
64 /// A LayoutFile (see LayoutFile.{h,cpp}) represents a *.layout file.
65 /// These are generally static objects---though they can be reloaded
66 /// from disk via LFUN_LAYOUT_RELOAD, so one should not assume that
67 /// they will never change.
69 /// A DocumentClass (see below) represents the layout information that
70 /// is associated with a given Buffer. These are static, in the sense
71 /// that they will not themselves change, but which DocumentClass is
72 /// associated with a Buffer can change, as modules are loaded and
73 /// unloaded, for example.
75 class TextClass : protected ProtectCopy {
78 virtual ~TextClass() {};
79 ///////////////////////////////////////////////////////////////////
81 ///////////////////////////////////////////////////////////////////
82 /// The individual paragraph layouts comprising the document class
83 // NOTE Do NOT try to make this a container of Layout pointers, e.g.,
84 // std::vector<Layout *>. This will lead to problems. The reason is
85 // that DocumentClass objects are generally created by copying a
86 // LayoutFile, which serves as a base for the DocumentClass. If the
87 // LayoutList is a container of pointers, then every DocumentClass
88 // that derives from a given LayoutFile (e.g., article) will SHARE
89 // a basic set of layouts. So if one Buffer were to modify a layout
90 // (say, Standard), that would modify that layout for EVERY Buffer
91 // that was based upon the same DocumentClass. (Of course, if you
92 // really, REALLY want to make LayoutList a vector<Layout *>, then
93 // you can implement custom assignment and copy constructors.)
94 typedef std::vector<Layout> LayoutList;
95 /// The inset layouts available to this class
96 typedef std::map<docstring, InsetLayout> InsetLayouts;
98 typedef LayoutList::const_iterator const_iterator;
100 ///////////////////////////////////////////////////////////////////
102 ///////////////////////////////////////////////////////////////////
104 const_iterator begin() const { return layoutlist_.begin(); }
106 const_iterator end() const { return layoutlist_.end(); }
109 ///////////////////////////////////////////////////////////////////
111 ///////////////////////////////////////////////////////////////////
113 Layout const & defaultLayout() const;
115 docstring const & defaultLayoutName() const;
117 bool isDefaultLayout(Layout const &) const;
119 bool isEmptyLayout(Layout const &) const;
120 /// returns a special layout for use when we don't really want one,
121 /// e.g., in table cells
122 Layout const & emptyLayout() const
123 { return operator[](emptylayout_); };
124 /// the name of the empty layout
125 docstring const & emptyLayoutName() const
126 { return emptylayout_; }
127 /// Enumerate the paragraph styles.
128 size_t layoutCount() const { return layoutlist_.size(); }
130 bool hasLayout(docstring const & name) const;
132 Layout const & operator[](docstring const & vname) const;
134 ///////////////////////////////////////////////////////////////////
136 ///////////////////////////////////////////////////////////////////
137 /// Enum used with TextClass::read
139 BASECLASS, //>This is a base class, i.e., top-level layout file
140 MERGE, //>This is a file included in a layout file
141 MODULE, //>This is a layout module
142 VALIDATION //>We're just validating
144 /// return values for read()
151 /// Performs the read of the layout file.
152 /// \return true on success.
153 bool read(support::FileName const & filename, ReadType rt = BASECLASS);
155 bool read(std::string const & str, ReadType rt = BASECLASS);
157 ReturnValues read(Lexer & lex, ReadType rt = BASECLASS);
158 /// validates the layout information passed in str
159 static bool validate(std::string const & str);
161 ///////////////////////////////////////////////////////////////////
163 ///////////////////////////////////////////////////////////////////
164 /// Sees to it the textclass structure has been loaded
165 bool load(std::string const & path = std::string()) const;
166 /// Has this layout file been loaded yet?
167 /// Overridden by DocumentClass
168 virtual bool loaded() const { return loaded_; }
170 ///////////////////////////////////////////////////////////////////
172 ///////////////////////////////////////////////////////////////////
174 std::string const & name() const { return name_; };
176 std::string const & description() const { return description_; };
178 std::string const & latexname() const { return latexname_; }
180 /// Protect construction
183 Layout & operator[](docstring const & vname);
185 ///////////////////////////////////////////////////////////////////
186 // non-const iterators
187 ///////////////////////////////////////////////////////////////////
189 typedef LayoutList::iterator iterator;
191 iterator begin() { return layoutlist_.begin(); }
193 iterator end() { return layoutlist_.end(); }
195 ///////////////////////////////////////////////////////////////////
197 ///////////////////////////////////////////////////////////////////
198 /// Paragraph styles used in this layout
199 LayoutList layoutlist_;
202 /// document class name
203 std::string latexname_;
204 /// document class description
205 std::string description_;
206 /// available types of float, eg. figure, algorithm.
207 mutable FloatList floatlist_;
208 /// Types of counters, eg. sections, eqns, figures, avail. in document class.
209 mutable Counters counters_;
210 /// Has this layout file been loaded yet?
211 mutable bool loaded_;
212 /// Is the TeX class available?
215 std::string opt_fontsize_;
217 std::string opt_pagestyle_;
218 /// Specific class options
219 std::string options_;
221 std::string pagestyle_;
223 std::string class_header_;
225 docstring defaultlayout_;
226 /// name of empty layout
227 static const docstring emptylayout_;
228 /// preamble text to support layout styles
230 /// latex packages loaded by document class.
231 std::set<std::string> provides_;
232 /// latex packages requested by document class.
233 std::set<std::string> requires_;
235 unsigned int columns_;
238 /// header depth to have numbering
240 /// header depth to appear in table of contents
242 /// Can be LaTeX, DocBook, etc.
243 OutputType outputType_;
244 /** Base font. The paragraph and layout fonts are resolved against
245 this font. This has to be fully instantiated. Attributes
246 FONT_INHERIT, FONT_IGNORE, and FONT_TOGGLE are
249 FontInfo defaultfont_;
250 /// Text that dictates how wide the left margin is on the screen
251 docstring leftmargin_;
252 /// Text that dictates how wide the right margin is on the screen
253 docstring rightmargin_;
254 /// The type of command used to produce a title
255 TitleLatexType titletype_;
256 /// The name of the title command
257 std::string titlename_;
258 /// Input layouts available to this layout
259 InsetLayouts insetlayoutlist_;
260 /// The minimal TocLevel of sectioning layouts
262 /// The maximal TocLevel of sectioning layouts
265 ///////////////////////////////////////////////////////////////////
266 // helper routines for reading layout files
267 ///////////////////////////////////////////////////////////////////
269 bool deleteLayout(docstring const &);
271 bool convertLayoutFormat(support::FileName const &, ReadType);
272 /// \return true for success.
273 bool readStyle(Lexer &, Layout &);
275 void readOutputType(Lexer &);
277 void readTitleType(Lexer &);
279 void readMaxCounter(Lexer &);
281 void readClassOptions(Lexer &);
283 void readCharStyle(Lexer &, std::string const &);
285 void readFloat(Lexer &);
287 void readCounter(Lexer &);
291 /// A DocumentClass represents the layout information associated with a
292 /// Buffer. It is based upon a LayoutFile, but may be modified by loading
295 /// In that regard, DocumentClass objects are "dynamic". But this is really
296 /// an illusion, since DocumentClass objects are not (currently) changed
297 /// when, say, a new Module is loaded. Rather, the old DocumentClass is
298 /// discarded---actually, it's kept around in case something on the cut
299 /// stack needs it---and a new one is created from scratch.
301 /// In the main LyX code, DocumentClass objects are created only by
302 /// DocumentClassBundle, for which see below.
304 class DocumentClass : public TextClass, boost::noncopyable {
307 virtual ~DocumentClass() {}
309 ///////////////////////////////////////////////////////////////////
311 ///////////////////////////////////////////////////////////////////
312 /// \return true if there is a Layout with latexname lay
313 bool hasLaTeXLayout(std::string const & lay) const;
314 /// A DocumentClass nevers count as loaded, since it is dynamic
315 virtual bool loaded() { return false; }
316 /// Inset layouts of this doc class
317 InsetLayouts const & insetLayouts() const { return insetlayoutlist_; };
318 /// \return the layout object of an inset given by name. If the name
319 /// is not found as such, the part after the ':' is stripped off, and
320 /// searched again. In this way, an error fallback can be provided:
321 /// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch)
322 /// will invoke the layout object defined by name = 'CharStyle'.
323 /// If that doesn't work either, an empty object returns (shouldn't
324 /// happen). -- Idea JMarc, comment MV
325 InsetLayout const & insetLayout(docstring const & name) const;
326 /// an empty inset layout for use as a default
327 static InsetLayout const & emptyInsetLayout() { return empty_insetlayout_; }
329 ///////////////////////////////////////////////////////////////////
331 ///////////////////////////////////////////////////////////////////
332 /// the list of floats defined in the document class
333 FloatList const & floats() const { return floatlist_; }
335 Counters & counters() const { return counters_; }
337 std::string const & opt_fontsize() const { return opt_fontsize_; }
339 std::string const & opt_pagestyle() const { return opt_pagestyle_; }
341 std::string const & options() const { return options_; }
343 std::string const & class_header() const { return class_header_; }
345 std::string const & pagestyle() const { return pagestyle_; }
347 docstring const & preamble() const { return preamble_; }
348 /// is this feature already provided by the class?
349 bool provides(std::string const & p) const;
350 /// features required by the class?
351 std::set<std::string> const & requires() const { return requires_; }
353 unsigned int columns() const { return columns_; }
355 PageSides sides() const { return sides_; }
357 int secnumdepth() const { return secnumdepth_; }
359 int tocdepth() const { return tocdepth_; }
361 FontInfo const & defaultfont() const { return defaultfont_; }
362 /// Text that dictates how wide the left margin is on the screen
363 docstring const & leftmargin() const { return leftmargin_; }
364 /// Text that dictates how wide the right margin is on the screen
365 docstring const & rightmargin() const { return rightmargin_; }
366 /// The type of command used to produce a title
367 TitleLatexType titletype() const { return titletype_; };
368 /// The name of the title command
369 std::string const & titlename() const { return titlename_; };
371 int size() const { return layoutlist_.size(); }
372 /// The minimal TocLevel of sectioning layouts
373 int min_toclevel() const { return min_toclevel_; }
374 /// The maximal TocLevel of sectioning layouts
375 int max_toclevel() const { return max_toclevel_; }
376 /// returns true if the class has a ToC structure
377 bool hasTocLevels() const;
378 /// Can be LaTeX, DocBook, etc.
379 OutputType outputType() const { return outputType_; }
381 /// Constructs a DocumentClass based upon a LayoutFile.
382 DocumentClass(LayoutFile const & tc);
383 /// Needed in tex2lyx
386 /// The only class that can create a DocumentClass is
387 /// DocumentClassBundle, which calls the protected constructor.
388 friend class DocumentClassBundle;
390 static InsetLayout empty_insetlayout_;
394 /// DocumentClassBundle is a container for DocumentClass objects, so that
395 /// they stay in memory for use by Insets, CutAndPaste, and the like, even
396 /// when their associated Buffers are destroyed.
397 /// FIXME Some sort of garbage collection or reference counting wouldn't
398 /// be a bad idea here. It might be enough to check when a Buffer is closed
399 /// (or makeDocumentClass is called) whether the old DocumentClass is in use
402 /// This is a singleton class. Its sole instance is accessed via
403 /// DocumentClassBundle::get().
404 class DocumentClassBundle : boost::noncopyable {
406 /// \return Pointer to a new class equal to baseClass
407 DocumentClass & newClass(LayoutFile const & baseClass);
408 /// \return The sole instance of this class.
409 static DocumentClassBundle & get();
411 /// control instantiation
412 DocumentClassBundle() {}
414 ~DocumentClassBundle();
416 std::vector<DocumentClass *> documentClasses_;
420 /// convert page sides option to text 1 or 2
421 std::ostream & operator<<(std::ostream & os, PageSides p);