]> git.lyx.org Git - features.git/blob - src/lyxtextclass.C
dont use pragma impementation and interface anymore
[features.git] / src / lyxtextclass.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2001 The LyX Team.
8  *
9  * ======================================================
10  */
11
12 #include <config.h>
13
14 #include "lyxtextclass.h"
15 #include "debug.h"
16 #include "lyxlex.h"
17 #include "counters.h"
18 #include "FloatList.h"
19
20 #include "support/lstrings.h"
21 #include "support/LAssert.h"
22 #include "support/lyxfunctional.h"
23 #include "support/filetools.h"
24
25 #include <algorithm>
26
27 using std::endl;
28 using std::find_if;
29 using std::remove_if;
30 using std::ostream;
31
32 namespace { // anon
33
34 struct compare_name {
35         compare_name(string const & name)
36                 : name_(name) {}
37         template <class C>
38         bool operator()(C & c) {
39                 return c->name() == name_;
40         }
41         string name_;
42 };
43
44 } // anon
45
46
47 LyXTextClass::LyXTextClass(string const & fn, string const & cln,
48                            string const & desc)
49         : name_(fn), latexname_(cln), description_(desc),
50           floatlist_(new FloatList), ctrs_(new Counters)
51 {
52         outputType_ = LATEX;
53         columns_ = 1;
54         sides_ = OneSide;
55         secnumdepth_ = 3;
56         tocdepth_ = 3;
57         pagestyle_ = "default";
58         maxcounter_ = LABEL_COUNTER_CHAPTER;
59         defaultfont_ = LyXFont(LyXFont::ALL_SANE);
60         opt_fontsize_ = "10|11|12";
61         opt_pagestyle_ = "empty|plain|headings|fancy";
62         provides_ = nothing;
63         loaded = false;
64 }
65
66
67 bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
68 {
69         lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
70         if (!lay.Read(lexrc, *this)) {
71                 // Resolve fonts
72                 lay.resfont = lay.font;
73                 lay.resfont.realize(defaultfont());
74                 lay.reslabelfont = lay.labelfont;
75                 lay.reslabelfont.realize(defaultfont());
76                 return false; // no errors
77         }
78         lyxerr << "Error parsing style `" << lay.name() << '\'' << endl;
79         return true;
80 }
81
82
83 enum TextClassTags {
84         TC_OUTPUTTYPE = 1,
85         TC_INPUT,
86         TC_STYLE,
87         TC_DEFAULTSTYLE,
88         TC_NOSTYLE,
89         TC_COLUMNS,
90         TC_SIDES,
91         TC_PAGESTYLE,
92         TC_DEFAULTFONT,
93         TC_MAXCOUNTER,
94         TC_SECNUMDEPTH,
95         TC_TOCDEPTH,
96         TC_CLASSOPTIONS,
97         TC_PREAMBLE,
98         TC_PROVIDESAMSMATH,
99         TC_PROVIDESNATBIB,
100         TC_PROVIDESMAKEIDX,
101         TC_PROVIDESURL,
102         TC_LEFTMARGIN,
103         TC_RIGHTMARGIN,
104         TC_FLOAT,
105         TC_COUNTER,
106         TC_NOFLOAT
107 };
108
109
110 // Reads a textclass structure from file.
111 bool LyXTextClass::Read(string const & filename, bool merge)
112 {
113         keyword_item textClassTags[] = {
114                 { "classoptions",    TC_CLASSOPTIONS },
115                 { "columns",         TC_COLUMNS },
116                 { "counter",         TC_COUNTER },
117                 { "defaultfont",     TC_DEFAULTFONT },
118                 { "defaultstyle",    TC_DEFAULTSTYLE },
119                 { "float",           TC_FLOAT },
120                 { "input",           TC_INPUT },
121                 { "leftmargin",      TC_LEFTMARGIN },
122                 { "maxcounter",      TC_MAXCOUNTER },
123                 { "nofloat",         TC_NOFLOAT },
124                 { "nostyle",         TC_NOSTYLE },
125                 { "outputtype",      TC_OUTPUTTYPE },
126                 { "pagestyle",       TC_PAGESTYLE },
127                 { "preamble",        TC_PREAMBLE },
128                 { "providesamsmath", TC_PROVIDESAMSMATH },
129                 { "providesmakeidx", TC_PROVIDESMAKEIDX },
130                 { "providesnatbib",  TC_PROVIDESNATBIB },
131                 { "providesurl",     TC_PROVIDESURL },
132                 { "rightmargin",     TC_RIGHTMARGIN },
133                 { "secnumdepth",     TC_SECNUMDEPTH },
134                 { "sides",           TC_SIDES },
135                 { "style",           TC_STYLE },
136                 { "tocdepth",        TC_TOCDEPTH }
137         };
138
139         if (!merge)
140                 lyxerr[Debug::TCLASS] << "Reading textclass "
141                                       << MakeDisplayPath(filename)
142                                       << endl;
143         else
144                 lyxerr[Debug::TCLASS] << "Reading input file "
145                                      << MakeDisplayPath(filename)
146                                      << endl;
147
148         LyXLex lexrc(textClassTags, TC_NOFLOAT);
149         bool error = false;
150
151         lexrc.setFile(filename);
152         if (!lexrc.isOK()) error = true;
153
154         // parsing
155         while (lexrc.isOK() && !error) {
156                 int le = lexrc.lex();
157                 switch (le) {
158                 case LyXLex::LEX_FEOF:
159                         continue;
160
161                 case LyXLex::LEX_UNDEF:
162                         lexrc.printError("Unknown TextClass tag `$$Token'");
163                         error = true;
164                         continue;
165                 default: break;
166                 }
167                 switch (static_cast<TextClassTags>(le)) {
168                 case TC_OUTPUTTYPE:   // output type definition
169                         readOutputType(lexrc);
170                         break;
171
172                 case TC_INPUT: // Include file
173                         if (lexrc.next()) {
174                                 string tmp = LibFileSearch("layouts",
175                                                             lexrc.getString(),
176                                                             "layout");
177
178                                 if (Read(tmp, true)) {
179                                         lexrc.printError("Error reading input"
180                                                          "file: "+tmp);
181                                         error = true;
182                                 }
183                         }
184                         break;
185
186                 case TC_DEFAULTSTYLE:
187                         if (lexrc.next()) {
188                                 string const name = subst(lexrc.getString(),
189                                                           '_', ' ');
190                                 defaultlayout_ = name;
191                         }
192                         break;
193
194                 case TC_STYLE:
195                         if (lexrc.next()) {
196                                 string const name = subst(lexrc.getString(),
197                                                     '_', ' ');
198                                 if (hasLayout(name)) {
199                                         LyXLayout * lay =
200                                                 operator[](name).get();
201                                         error = do_readStyle(lexrc, *lay);
202                                 } else {
203                                         LyXLayout lay;
204                                         lay.setName(name);
205                                         if (!(error = do_readStyle(lexrc, lay)))
206                                                 layoutlist_.push_back(boost::shared_ptr<LyXLayout>(new LyXLayout(lay)));
207                                         if (defaultlayout_.empty()) {
208                                                 // We do not have a default
209                                                 // layout yet, so we choose
210                                                 // the first layout we
211                                                 // encounter.
212                                                 defaultlayout_ = name;
213                                         }
214                                 }
215                         }
216                         else {
217                                 lexrc.printError("No name given for style: `$$Token'.");
218                                 error = true;
219                         }
220                         break;
221
222                 case TC_NOSTYLE:
223                         if (lexrc.next()) {
224                                 string const style = subst(lexrc.getString(),
225                                                      '_', ' ');
226                                 if (!delete_layout(style))
227                                         lyxerr << "Cannot delete style `"
228                                                << style << '\'' << endl;
229 //                                      lexrc.printError("Cannot delete style"
230 //                                                       " `$$Token'");
231                         }
232                         break;
233
234                 case TC_COLUMNS:
235                         if (lexrc.next())
236                                 columns_ = lexrc.getInteger();
237                         break;
238
239                 case TC_SIDES:
240                         if (lexrc.next()) {
241                                 switch (lexrc.getInteger()) {
242                                 case 1: sides_ = OneSide; break;
243                                 case 2: sides_ = TwoSides; break;
244                                 default:
245                                         lyxerr << "Impossible number of page"
246                                                 " sides, setting to one."
247                                                << endl;
248                                         sides_ = OneSide;
249                                         break;
250                                 }
251                         }
252                         break;
253
254                 case TC_PAGESTYLE:
255                         lexrc.next();
256                         pagestyle_ = rtrim(lexrc.getString());
257                         break;
258
259                 case TC_DEFAULTFONT:
260                         defaultfont_.lyxRead(lexrc);
261                         if (!defaultfont_.resolved()) {
262                                 lexrc.printError("Warning: defaultfont should "
263                                                  "be fully instantiated!");
264                                 defaultfont_.realize(LyXFont(LyXFont::ALL_SANE));
265                         }
266                         break;
267
268                 case TC_MAXCOUNTER:
269                         readMaxCounter(lexrc);
270                         break;
271
272                 case TC_SECNUMDEPTH:
273                         lexrc.next();
274                         secnumdepth_ = lexrc.getInteger();
275                         break;
276
277                 case TC_TOCDEPTH:
278                         lexrc.next();
279                         tocdepth_ = lexrc.getInteger();
280                         break;
281
282                         // First step to support options
283                 case TC_CLASSOPTIONS:
284                         readClassOptions(lexrc);
285                         break;
286
287                 case TC_PREAMBLE:
288                         preamble_ = lexrc.getLongString("EndPreamble");
289                         break;
290
291                 case TC_PROVIDESAMSMATH:
292                         if (lexrc.next() && lexrc.getInteger())
293                                 provides_ |= amsmath;
294                         break;
295
296                 case TC_PROVIDESNATBIB:
297                         if (lexrc.next() && lexrc.getInteger())
298                                 provides_ |= natbib;
299                         break;
300
301                 case TC_PROVIDESMAKEIDX:
302                         if (lexrc.next() && lexrc.getInteger())
303                                 provides_ |= makeidx;
304                         break;
305
306                 case TC_PROVIDESURL:
307                         if (lexrc.next() && lexrc.getInteger())
308                                 provides_ |= url;
309                         break;
310
311                 case TC_LEFTMARGIN:     // left margin type
312                         if (lexrc.next())
313                                 leftmargin_ = lexrc.getString();
314                         break;
315
316                 case TC_RIGHTMARGIN:    // right margin type
317                         if (lexrc.next())
318                                 rightmargin_ = lexrc.getString();
319                         break;
320                 case TC_FLOAT:
321                         readFloat(lexrc);
322                         break;
323                 case TC_COUNTER:
324                         readCounter(lexrc);
325                         break;
326                 case TC_NOFLOAT:
327                         if (lexrc.next()) {
328                                 string const nofloat = lexrc.getString();
329                                 floatlist_->erase(nofloat);
330                         }
331                         break;
332
333                 }
334         }
335
336         if (!merge) { // we are at top level here.
337                 lyxerr[Debug::TCLASS] << "Finished reading textclass "
338                                       << MakeDisplayPath(filename)
339                                       << endl;
340                 if (defaultlayout_.empty()) {
341                         lyxerr << "Error: Textclass '" << name_
342                                << "' is missing a defaultstyle." << endl;
343                         error = true;
344                 }
345         } else
346                 lyxerr[Debug::TCLASS] << "Finished reading input file "
347                                       << MakeDisplayPath(filename)
348                                       << endl;
349
350         return error;
351 }
352
353
354 void LyXTextClass::readOutputType(LyXLex & lexrc)
355 {
356         keyword_item outputTypeTags[] = {
357                 { "docbook", DOCBOOK },
358                 { "latex", LATEX },
359                 { "linuxdoc", LINUXDOC },
360                 { "literate", LITERATE }
361         };
362
363         pushpophelper pph(lexrc, outputTypeTags, LITERATE);
364
365         int le = lexrc.lex();
366         switch (le) {
367         case LyXLex::LEX_UNDEF:
368                 lexrc.printError("Unknown output type `$$Token'");
369                 return;
370         case LATEX:
371         case LINUXDOC:
372         case DOCBOOK:
373         case LITERATE:
374                 outputType_ = static_cast<OutputType>(le);
375                 break;
376         default:
377                 lyxerr << "Unhandled value " << le
378                        << " in LyXTextClass::readOutputType." << endl;
379
380                 break;
381         }
382 }
383
384
385 enum MaxCounterTags {
386         MC_COUNTER_CHAPTER = 1,
387         MC_COUNTER_SECTION,
388         MC_COUNTER_SUBSECTION,
389         MC_COUNTER_SUBSUBSECTION,
390         MC_COUNTER_PARAGRAPH,
391         MC_COUNTER_SUBPARAGRAPH,
392         MC_COUNTER_ENUMI,
393         MC_COUNTER_ENUMII,
394         MC_COUNTER_ENUMIII,
395         MC_COUNTER_ENUMIV
396 };
397
398
399 void LyXTextClass::readMaxCounter(LyXLex & lexrc)
400 {
401         keyword_item maxCounterTags[] = {
402                 {"counter_chapter", MC_COUNTER_CHAPTER },
403                 {"counter_enumi", MC_COUNTER_ENUMI },
404                 {"counter_enumii", MC_COUNTER_ENUMII },
405                 {"counter_enumiii", MC_COUNTER_ENUMIII },
406                 {"counter_enumiv", MC_COUNTER_ENUMIV },
407                 {"counter_paragraph", MC_COUNTER_PARAGRAPH },
408                 {"counter_section", MC_COUNTER_SECTION },
409                 {"counter_subparagraph", MC_COUNTER_SUBPARAGRAPH },
410                 {"counter_subsection", MC_COUNTER_SUBSECTION },
411                 {"counter_subsubsection", MC_COUNTER_SUBSUBSECTION }
412         };
413
414         pushpophelper pph(lexrc, maxCounterTags, MC_COUNTER_ENUMIV);
415         int le = lexrc.lex();
416         switch (le) {
417         case LyXLex::LEX_UNDEF:
418                 lexrc.printError("Unknown MaxCounter tag `$$Token'");
419                 return;
420         default: break;
421         }
422         switch (static_cast<MaxCounterTags>(le)) {
423         case MC_COUNTER_CHAPTER:
424                 maxcounter_ = LABEL_COUNTER_CHAPTER;
425                 break;
426         case MC_COUNTER_SECTION:
427                 maxcounter_ = LABEL_COUNTER_SECTION;
428                 break;
429         case MC_COUNTER_SUBSECTION:
430                 maxcounter_ = LABEL_COUNTER_SUBSECTION;
431                 break;
432         case MC_COUNTER_SUBSUBSECTION:
433                 maxcounter_ = LABEL_COUNTER_SUBSUBSECTION;
434                 break;
435         case MC_COUNTER_PARAGRAPH:
436                 maxcounter_ = LABEL_COUNTER_PARAGRAPH;
437                 break;
438         case MC_COUNTER_SUBPARAGRAPH:
439                 maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH;
440                 break;
441         case MC_COUNTER_ENUMI:
442                 maxcounter_ = LABEL_COUNTER_ENUMI;
443                 break;
444         case MC_COUNTER_ENUMII:
445                 maxcounter_ = LABEL_COUNTER_ENUMII;
446                 break;
447         case MC_COUNTER_ENUMIII:
448                 maxcounter_ = LABEL_COUNTER_ENUMIII;
449                 break;
450         case MC_COUNTER_ENUMIV:
451                 maxcounter_ = LABEL_COUNTER_ENUMIV;
452                 break;
453         }
454 }
455
456
457 enum ClassOptionsTags {
458         CO_FONTSIZE = 1,
459         CO_PAGESTYLE,
460         CO_OTHER,
461         CO_END
462 };
463
464
465 void LyXTextClass::readClassOptions(LyXLex & lexrc)
466 {
467         keyword_item classOptionsTags[] = {
468                 {"end", CO_END },
469                 {"fontsize", CO_FONTSIZE },
470                 {"other", CO_OTHER },
471                 {"pagestyle", CO_PAGESTYLE }
472         };
473
474         lexrc.pushTable(classOptionsTags, CO_END);
475         bool getout = false;
476         while (!getout && lexrc.isOK()) {
477                 int le = lexrc.lex();
478                 switch (le) {
479                 case LyXLex::LEX_UNDEF:
480                         lexrc.printError("Unknown ClassOption tag `$$Token'");
481                         continue;
482                 default: break;
483                 }
484                 switch (static_cast<ClassOptionsTags>(le)) {
485                 case CO_FONTSIZE:
486                         lexrc.next();
487                         opt_fontsize_ = rtrim(lexrc.getString());
488                         break;
489                 case CO_PAGESTYLE:
490                         lexrc.next();
491                         opt_pagestyle_ = rtrim(lexrc.getString());
492                         break;
493                 case CO_OTHER:
494                         lexrc.next();
495                         options_ = lexrc.getString();
496                         break;
497                 case CO_END:
498                         getout = true;
499                         break;
500                 }
501         }
502         lexrc.popTable();
503 }
504
505
506 enum FloatTags {
507         FT_TYPE = 1,
508         FT_NAME,
509         FT_PLACEMENT,
510         FT_EXT,
511         FT_WITHIN,
512         FT_STYLE,
513         FT_LISTNAME,
514         FT_BUILTIN,
515         FT_END
516 };
517
518 void LyXTextClass::readFloat(LyXLex & lexrc)
519 {
520         keyword_item floatTags[] = {
521                 { "end", FT_END },
522                 { "extension", FT_EXT },
523                 { "guiname", FT_NAME },
524                 { "latexbuiltin", FT_BUILTIN },
525                 { "listname", FT_LISTNAME },
526                 { "numberwithin", FT_WITHIN },
527                 { "placement", FT_PLACEMENT },
528                 { "style", FT_STYLE },
529                 { "type", FT_TYPE }
530         };
531
532         lexrc.pushTable(floatTags, FT_END);
533
534         string type;
535         string placement;
536         string ext;
537         string within;
538         string style;
539         string name;
540         string listname;
541         bool builtin = false;
542
543         bool getout = false;
544         while (!getout && lexrc.isOK()) {
545                 int le = lexrc.lex();
546                 switch (le) {
547                 case LyXLex::LEX_UNDEF:
548                         lexrc.printError("Unknown ClassOption tag `$$Token'");
549                         continue;
550                 default: break;
551                 }
552                 switch (static_cast<FloatTags>(le)) {
553                 case FT_TYPE:
554                         lexrc.next();
555                         type = lexrc.getString();
556                         // Here we could check if this type is already defined
557                         // and modify it with the rest of the vars instead.
558                         break;
559                 case FT_NAME:
560                         lexrc.next();
561                         name = lexrc.getString();
562                         break;
563                 case FT_PLACEMENT:
564                         lexrc.next();
565                         placement = lexrc.getString();
566                         break;
567                 case FT_EXT:
568                         lexrc.next();
569                         ext = lexrc.getString();
570                         break;
571                 case FT_WITHIN:
572                         lexrc.next();
573                         within = lexrc.getString();
574                         if (within == "none")
575                                 within.erase();
576                         break;
577                 case FT_STYLE:
578                         lexrc.next();
579                         style = lexrc.getString();
580                         break;
581                 case FT_LISTNAME:
582                         lexrc.next();
583                         listname = lexrc.getString();
584                         break;
585                 case FT_BUILTIN:
586                         lexrc.next();
587                         builtin = lexrc.getBool();
588                         break;
589                 case FT_END:
590                         getout = true;
591                         break;
592                 }
593         }
594
595         // Here if have a full float if getout == true
596         if (getout) {
597                 Floating newfloat(type, placement, ext, within,
598                                   style, name, listname, builtin);
599                 floatlist_->newFloat(newfloat);
600         }
601
602         lexrc.popTable();
603 }
604
605
606 enum CounterTags {
607         CT_NAME = 1,
608         CT_WITHIN,
609         CT_END
610 };
611
612 void LyXTextClass::readCounter(LyXLex & lexrc)
613 {
614         keyword_item counterTags[] = {
615                 { "end", CT_END },
616                 { "name", CT_NAME },
617                 { "within", CT_WITHIN }
618         };
619
620         lexrc.pushTable(counterTags, CT_END);
621
622         string name;
623         string within;
624
625         bool getout = false;
626         while (!getout && lexrc.isOK()) {
627                 int le = lexrc.lex();
628                 switch (le) {
629                 case LyXLex::LEX_UNDEF:
630                         lexrc.printError("Unknown ClassOption tag `$$Token'");
631                         continue;
632                 default: break;
633                 }
634                 switch (static_cast<CounterTags>(le)) {
635                 case CT_NAME:
636                         lexrc.next();
637                         name = lexrc.getString();
638                         break;
639                 case CT_WITHIN:
640                         lexrc.next();
641                         within = lexrc.getString();
642                         if (within == "none")
643                                 within.erase();
644                         break;
645                 case CT_END:
646                         getout = true;
647                         break;
648                 }
649         }
650
651         // Here if have a full float if getout == true
652         if (getout) {
653                 if (within.empty()) {
654                         ctrs_->newCounter(name);
655                 } else {
656                         ctrs_->newCounter(name, within);
657                 }
658         }
659
660         lexrc.popTable();
661 }
662
663
664 LyXFont const & LyXTextClass::defaultfont() const
665 {
666         return defaultfont_;
667 }
668
669
670 string const & LyXTextClass::leftmargin() const
671 {
672         return leftmargin_;
673 }
674
675
676 string const & LyXTextClass::rightmargin() const
677 {
678         return rightmargin_;
679 }
680
681
682 bool LyXTextClass::hasLayout(string const & n) const
683 {
684         string const name = (n.empty() ? defaultLayoutName() : n);
685
686         return find_if(layoutlist_.begin(), layoutlist_.end(),
687                        compare_name(name))
688                 != layoutlist_.end();
689 }
690
691
692 LyXLayout_ptr const & LyXTextClass::operator[](string const & n) const
693 {
694         lyx::Assert(!n.empty());
695
696         if (n.empty())
697                 lyxerr << "Operator[] called with empty n" << endl;
698
699         string const name = (n.empty() ? defaultLayoutName() : n);
700
701         static string lastLayoutName;
702         static LayoutList::difference_type lastLayoutIndex;
703
704         if (name == lastLayoutName)
705                 return layoutlist_[lastLayoutIndex];
706
707         LayoutList::const_iterator cit =
708                 find_if(layoutlist_.begin(),
709                         layoutlist_.end(),
710                         compare_name(name));
711
712         if (cit == layoutlist_.end()) {
713                 lyxerr << "We failed to find the layout '" << name
714                        << "' in the layout list. You MUST investigate!"
715                        << endl;
716
717                 // we require the name to exist
718                 lyx::Assert(false);
719         }
720
721         lastLayoutName = name;
722         lastLayoutIndex = std::distance(layoutlist_.begin(), cit);
723
724         return (*cit);
725 }
726
727
728 bool LyXTextClass::delete_layout(string const & name)
729 {
730         if (name == defaultLayoutName())
731                 return false;
732
733         LayoutList::iterator it =
734                 remove_if(layoutlist_.begin(), layoutlist_.end(),
735                           compare_name(name));
736
737         LayoutList::iterator end = layoutlist_.end();
738         bool const ret = (it != end);
739         layoutlist_.erase(it, end);
740         return ret;
741 }
742
743
744 // Load textclass info if not loaded yet
745 bool LyXTextClass::load() const
746 {
747         if (loaded)
748                 return true;
749
750         // Read style-file
751         string const real_file = LibFileSearch("layouts", name_, "layout");
752
753         if (const_cast<LyXTextClass*>(this)->Read(real_file)) {
754                 lyxerr << "Error reading `"
755                        << MakeDisplayPath(real_file)
756                        << "'\n(Check `" << name_
757                        << "')\nCheck your installation and "
758                         "try Options/Reconfigure..." << endl;
759                 loaded = false;
760         }
761         loaded = true;
762         return loaded;
763 }
764
765
766 FloatList & LyXTextClass::floats()
767 {
768         return *floatlist_.get();
769 }
770
771
772 FloatList const & LyXTextClass::floats() const
773 {
774         return *floatlist_.get();
775 }
776
777
778 Counters & LyXTextClass::counters() const
779 {
780         return *ctrs_.get();
781 }
782
783
784 string const & LyXTextClass::defaultLayoutName() const
785 {
786         // This really should come from the actual layout... (Lgb)
787         return defaultlayout_;
788 }
789
790
791 LyXLayout_ptr const & LyXTextClass::defaultLayout() const
792 {
793         return operator[](defaultLayoutName());
794 }
795
796
797 string const & LyXTextClass::name() const
798 {
799         return name_;
800 }
801
802
803 string const & LyXTextClass::latexname() const
804 {
805         const_cast<LyXTextClass*>(this)->load();
806         return latexname_;
807 }
808
809
810 string const & LyXTextClass::description() const
811 {
812         return description_;
813 }
814
815
816 string const & LyXTextClass::opt_fontsize() const
817 {
818         return opt_fontsize_;
819 }
820
821
822 string const & LyXTextClass::opt_pagestyle() const
823 {
824         return opt_pagestyle_;
825 }
826
827
828 string const & LyXTextClass::options() const
829 {
830         return options_;
831 }
832
833
834 string const & LyXTextClass::pagestyle() const
835 {
836         return pagestyle_;
837 }
838
839
840 string const & LyXTextClass::preamble() const
841 {
842         return preamble_;
843 }
844
845
846 LyXTextClass::PageSides LyXTextClass::sides() const
847 {
848         return sides_;
849 }
850
851
852 int LyXTextClass::secnumdepth() const
853 {
854         return secnumdepth_;
855 }
856
857
858 int LyXTextClass::tocdepth() const
859 {
860         return tocdepth_;
861 }
862
863
864 OutputType LyXTextClass::outputType() const
865 {
866         return outputType_;
867 }
868
869
870 bool LyXTextClass::provides(LyXTextClass::Provides p) const
871 {
872         return provides_ & p;
873 }
874
875
876 unsigned int LyXTextClass::columns() const
877 {
878         return columns_;
879 }
880
881
882 int LyXTextClass::maxcounter() const
883 {
884         return maxcounter_;
885 }
886
887
888 int LyXTextClass::size() const
889 {
890         return layoutlist_.size();
891 }
892
893
894 ostream & operator<<(ostream & os, LyXTextClass::PageSides p)
895 {
896         switch (p) {
897         case LyXTextClass::OneSide:
898                 os << '1';
899                 break;
900         case LyXTextClass::TwoSides:
901                 os << '2';
902                 break;
903         }
904         return os;
905 }