X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxtextclass.C;h=168520301dfa345535120f4a6dec85d789450db4;hb=701b99ecd70ac472aa53c8b2317af44def4f9670;hp=d44748b0e5cec4e526fcc78bc15a8bef6348f259;hpb=102266cf922b4a62c9ce33635b67e98a8872c004;p=lyx.git diff --git a/src/lyxtextclass.C b/src/lyxtextclass.C index d44748b0e5..168520301d 100644 --- a/src/lyxtextclass.C +++ b/src/lyxtextclass.C @@ -1,12 +1,15 @@ -/* This file is part of - * ====================================================== +/** + * \file lyxtextclass.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * LyX, The Document Processor + * \author Lars Gullik Bjønnes + * \author Jean-Marc Lasgouttes + * \author Angus Leeming + * \author John Levon + * \author André Pönitz * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2001 The LyX Team. - * - * ====================================================== + * Full author contact details are available in file CREDITS. */ #include @@ -15,39 +18,47 @@ #include "debug.h" #include "lyxlex.h" #include "counters.h" +#include "Floating.h" #include "FloatList.h" #include "support/lstrings.h" -#include "support/LAssert.h" -#include "support/lyxfunctional.h" #include "support/filetools.h" -#include +using lyx::support::LibFileSearch; +using lyx::support::MakeDisplayPath; +using lyx::support::rtrim; +using lyx::support::subst; using std::endl; using std::find_if; using std::remove_if; +using std::string; using std::ostream; -namespace { // anon -struct compare_name { - compare_name(string const & name) - : name_(name) {} - template - bool operator()(C & c) { +namespace { + +class LayoutNamesEqual : public std::unary_function { +public: + LayoutNamesEqual(string const & name) + : name_(name) + {} + bool operator()(LyXLayout_ptr const & c) const + { return c->name() == name_; } +private: string name_; }; -} // anon +} // namespace anon LyXTextClass::LyXTextClass(string const & fn, string const & cln, - string const & desc) + string const & desc, bool texClassAvail ) : name_(fn), latexname_(cln), description_(desc), - floatlist_(new FloatList), ctrs_(new Counters) + floatlist_(new FloatList), ctrs_(new Counters), + texClassAvail_(texClassAvail) { outputType_ = LATEX; columns_ = 1; @@ -55,14 +66,19 @@ LyXTextClass::LyXTextClass(string const & fn, string const & cln, secnumdepth_ = 3; tocdepth_ = 3; pagestyle_ = "default"; - maxcounter_ = LABEL_COUNTER_CHAPTER; defaultfont_ = LyXFont(LyXFont::ALL_SANE); opt_fontsize_ = "10|11|12"; opt_pagestyle_ = "empty|plain|headings|fancy"; provides_ = nothing; titletype_ = TITLE_COMMAND_AFTER; titlename_ = "maketitle"; - loaded = false; + loaded_ = false; +} + + +bool LyXTextClass::isTeXClassAvailable() const +{ + return texClassAvail_; } @@ -87,12 +103,13 @@ enum TextClassTags { TC_INPUT, TC_STYLE, TC_DEFAULTSTYLE, + TC_CHARSTYLE, + TC_ENVIRONMENT, TC_NOSTYLE, TC_COLUMNS, TC_SIDES, TC_PAGESTYLE, TC_DEFAULTFONT, - TC_MAXCOUNTER, TC_SECNUMDEPTH, TC_TOCDEPTH, TC_CLASSOPTIONS, @@ -114,15 +131,16 @@ enum TextClassTags { bool LyXTextClass::Read(string const & filename, bool merge) { keyword_item textClassTags[] = { + { "charstyle", TC_CHARSTYLE }, { "classoptions", TC_CLASSOPTIONS }, { "columns", TC_COLUMNS }, { "counter", TC_COUNTER }, { "defaultfont", TC_DEFAULTFONT }, { "defaultstyle", TC_DEFAULTSTYLE }, + { "environment", TC_ENVIRONMENT }, { "float", TC_FLOAT }, { "input", TC_INPUT }, { "leftmargin", TC_LEFTMARGIN }, - { "maxcounter", TC_MAXCOUNTER }, { "nofloat", TC_NOFLOAT }, { "nostyle", TC_NOSTYLE }, { "outputtype", TC_OUTPUTTYPE }, @@ -150,7 +168,8 @@ bool LyXTextClass::Read(string const & filename, bool merge) << MakeDisplayPath(filename) << endl; - LyXLex lexrc(textClassTags, TC_TITLELATEXTYPE); + LyXLex lexrc(textClassTags, + sizeof(textClassTags) / sizeof(textClassTags[0])); bool error = false; lexrc.setFile(filename); @@ -159,6 +178,7 @@ bool LyXTextClass::Read(string const & filename, bool merge) // parsing while (lexrc.isOK() && !error) { int le = lexrc.lex(); + switch (le) { case LyXLex::LEX_FEOF: continue; @@ -167,9 +187,13 @@ bool LyXTextClass::Read(string const & filename, bool merge) lexrc.printError("Unknown TextClass tag `$$Token'"); error = true; continue; - default: break; + + default: + break; } + switch (static_cast(le)) { + case TC_OUTPUTTYPE: // output type definition readOutputType(lexrc); break; @@ -196,19 +220,24 @@ bool LyXTextClass::Read(string const & filename, bool merge) } break; + case TC_ENVIRONMENT: case TC_STYLE: if (lexrc.next()) { string const name = subst(lexrc.getString(), '_', ' '); if (hasLayout(name)) { - LyXLayout * lay = - operator[](name).get(); + LyXLayout * lay = operator[](name).get(); error = do_readStyle(lexrc, *lay); } else { LyXLayout lay; lay.setName(name); + if (le == TC_ENVIRONMENT) + lay.is_environment = true; if (!(error = do_readStyle(lexrc, lay))) - layoutlist_.push_back(boost::shared_ptr(new LyXLayout(lay))); + layoutlist_.push_back( + boost::shared_ptr(new LyXLayout(lay)) + ); + if (defaultlayout_.empty()) { // We do not have a default // layout yet, so we choose @@ -270,10 +299,6 @@ bool LyXTextClass::Read(string const & filename, bool merge) } break; - case TC_MAXCOUNTER: - readMaxCounter(lexrc); - break; - case TC_SECNUMDEPTH: lexrc.next(); secnumdepth_ = lexrc.getInteger(); @@ -322,6 +347,12 @@ bool LyXTextClass::Read(string const & filename, bool merge) if (lexrc.next()) rightmargin_ = lexrc.getString(); break; + case TC_CHARSTYLE: + if (lexrc.next()) { + string const name = subst(lexrc.getString(), '_', ' '); + readCharStyle(lexrc, name); + } + break; case TC_FLOAT: readFloat(lexrc); break; @@ -434,68 +465,11 @@ enum MaxCounterTags { }; -void LyXTextClass::readMaxCounter(LyXLex & lexrc) -{ - keyword_item maxCounterTags[] = { - {"counter_chapter", MC_COUNTER_CHAPTER }, - {"counter_enumi", MC_COUNTER_ENUMI }, - {"counter_enumii", MC_COUNTER_ENUMII }, - {"counter_enumiii", MC_COUNTER_ENUMIII }, - {"counter_enumiv", MC_COUNTER_ENUMIV }, - {"counter_paragraph", MC_COUNTER_PARAGRAPH }, - {"counter_section", MC_COUNTER_SECTION }, - {"counter_subparagraph", MC_COUNTER_SUBPARAGRAPH }, - {"counter_subsection", MC_COUNTER_SUBSECTION }, - {"counter_subsubsection", MC_COUNTER_SUBSUBSECTION } - }; - - pushpophelper pph(lexrc, maxCounterTags, MC_COUNTER_ENUMIV); - int le = lexrc.lex(); - switch (le) { - case LyXLex::LEX_UNDEF: - lexrc.printError("Unknown MaxCounter tag `$$Token'"); - return; - default: break; - } - switch (static_cast(le)) { - case MC_COUNTER_CHAPTER: - maxcounter_ = LABEL_COUNTER_CHAPTER; - break; - case MC_COUNTER_SECTION: - maxcounter_ = LABEL_COUNTER_SECTION; - break; - case MC_COUNTER_SUBSECTION: - maxcounter_ = LABEL_COUNTER_SUBSECTION; - break; - case MC_COUNTER_SUBSUBSECTION: - maxcounter_ = LABEL_COUNTER_SUBSUBSECTION; - break; - case MC_COUNTER_PARAGRAPH: - maxcounter_ = LABEL_COUNTER_PARAGRAPH; - break; - case MC_COUNTER_SUBPARAGRAPH: - maxcounter_ = LABEL_COUNTER_SUBPARAGRAPH; - break; - case MC_COUNTER_ENUMI: - maxcounter_ = LABEL_COUNTER_ENUMI; - break; - case MC_COUNTER_ENUMII: - maxcounter_ = LABEL_COUNTER_ENUMII; - break; - case MC_COUNTER_ENUMIII: - maxcounter_ = LABEL_COUNTER_ENUMIII; - break; - case MC_COUNTER_ENUMIV: - maxcounter_ = LABEL_COUNTER_ENUMIV; - break; - } -} - - enum ClassOptionsTags { CO_FONTSIZE = 1, CO_PAGESTYLE, CO_OTHER, + CO_HEADER, CO_END }; @@ -505,6 +479,7 @@ void LyXTextClass::readClassOptions(LyXLex & lexrc) keyword_item classOptionsTags[] = { {"end", CO_END }, {"fontsize", CO_FONTSIZE }, + {"header", CO_HEADER }, {"other", CO_OTHER }, {"pagestyle", CO_PAGESTYLE } }; @@ -532,6 +507,10 @@ void LyXTextClass::readClassOptions(LyXLex & lexrc) lexrc.next(); options_ = lexrc.getString(); break; + case CO_HEADER: + lexrc.next(); + class_header_ = subst(lexrc.getString(), """, "\""); + break; case CO_END: getout = true; break; @@ -540,6 +519,93 @@ void LyXTextClass::readClassOptions(LyXLex & lexrc) lexrc.popTable(); } +enum CharStyleTags { + CS_FONT = 1, + CS_LABELFONT, + CS_LATEXTYPE, + CS_LATEXNAME, + CS_LATEXPARAM, + CS_PREAMBLE, + CS_END +}; + + +void LyXTextClass::readCharStyle(LyXLex & lexrc, string const & name) +{ + keyword_item elementTags[] = { + { "end", CS_END }, + { "font", CS_FONT }, + { "labelfont", CS_LABELFONT }, + { "latexname", CS_LATEXNAME }, + { "latexparam", CS_LATEXPARAM }, + { "latextype", CS_LATEXTYPE }, + { "preamble", CS_PREAMBLE} + }; + + lexrc.pushTable(elementTags, CS_END); + + string latextype; + string latexname; + string latexparam; + LyXFont font(LyXFont::ALL_INHERIT); + LyXFont labelfont(LyXFont::ALL_INHERIT); + string preamble; + + bool getout = false; + while (!getout && lexrc.isOK()) { + int le = lexrc.lex(); + switch (le) { + case LyXLex::LEX_UNDEF: + lexrc.printError("Unknown ClassOption tag `$$Token'"); + continue; + default: break; + } + switch (static_cast(le)) { + case CS_LATEXTYPE: + lexrc.next(); + latextype = lexrc.getString(); + break; + case CS_LATEXNAME: + lexrc.next(); + latexname = lexrc.getString(); + break; + case CS_LATEXPARAM: + lexrc.next(); + latexparam = subst(lexrc.getString(), """, "\""); + break; + case CS_LABELFONT: + labelfont.lyxRead(lexrc); + break; + case CS_FONT: + font.lyxRead(lexrc); + labelfont = font; + break; + case CS_PREAMBLE: + preamble = lexrc.getLongString("EndPreamble"); + break; + case CS_END: + getout = true; + break; + } + } + + // + // Here add element to list if getout == true + if (getout) { + CharStyle cs; + cs.name = name; + cs.latextype = latextype; + cs.latexname = latexname; + cs.latexparam = latexparam; + cs.font = font; + cs.labelfont = labelfont; + cs.preamble = preamble; + charstyles().push_back(cs); + } + + lexrc.popTable(); +} + enum FloatTags { FT_TYPE = 1, @@ -553,6 +619,7 @@ enum FloatTags { FT_END }; + void LyXTextClass::readFloat(LyXLex & lexrc) { keyword_item floatTags[] = { @@ -686,7 +753,7 @@ void LyXTextClass::readCounter(LyXLex & lexrc) } } - // Here if have a full float if getout == true + // Here if have a full counter if getout == true if (getout) { if (within.empty()) { ctrs_->newCounter(name); @@ -722,47 +789,38 @@ bool LyXTextClass::hasLayout(string const & n) const string const name = (n.empty() ? defaultLayoutName() : n); return find_if(layoutlist_.begin(), layoutlist_.end(), - compare_name(name)) + LayoutNamesEqual(name)) != layoutlist_.end(); } -LyXLayout_ptr const & LyXTextClass::operator[](string const & n) const -{ - lyx::Assert(!n.empty()); - - if (n.empty()) - lyxerr << "Operator[] called with empty n" << endl; - string const name = (n.empty() ? defaultLayoutName() : n); - - static string lastLayoutName; - static LayoutList::difference_type lastLayoutIndex; - - if (name == lastLayoutName) - return layoutlist_[lastLayoutIndex]; +LyXLayout_ptr const & LyXTextClass::operator[](string const & name) const +{ + BOOST_ASSERT(!name.empty()); LayoutList::const_iterator cit = find_if(layoutlist_.begin(), layoutlist_.end(), - compare_name(name)); + LayoutNamesEqual(name)); if (cit == layoutlist_.end()) { lyxerr << "We failed to find the layout '" << name << "' in the layout list. You MUST investigate!" << endl; + for (LayoutList::const_iterator it = layoutlist_.begin(); + it != layoutlist_.end(); ++it) + lyxerr << " " << it->get()->name() << endl; // we require the name to exist - lyx::Assert(false); + BOOST_ASSERT(false); } - lastLayoutName = name; - lastLayoutIndex = std::distance(layoutlist_.begin(), cit); - return (*cit); } + bool LyXTextClass::delete_layout(string const & name) { if (name == defaultLayoutName()) @@ -770,7 +828,7 @@ bool LyXTextClass::delete_layout(string const & name) LayoutList::iterator it = remove_if(layoutlist_.begin(), layoutlist_.end(), - compare_name(name)); + LayoutNamesEqual(name)); LayoutList::iterator end = layoutlist_.end(); bool const ret = (it != end); @@ -782,22 +840,22 @@ bool LyXTextClass::delete_layout(string const & name) // Load textclass info if not loaded yet bool LyXTextClass::load() const { - if (loaded) + if (loaded_) return true; // Read style-file string const real_file = LibFileSearch("layouts", name_, "layout"); + loaded_ = const_cast(this)->Read(real_file) == 0; - if (const_cast(this)->Read(real_file)) { + if (!loaded_) { lyxerr << "Error reading `" << MakeDisplayPath(real_file) << "'\n(Check `" << name_ << "')\nCheck your installation and " "try Options/Reconfigure..." << endl; - loaded = false; } - loaded = true; - return loaded; + + return loaded_; } @@ -819,6 +877,18 @@ Counters & LyXTextClass::counters() const } +CharStyles::iterator LyXTextClass::charstyle(string const & s) const +{ + CharStyles::iterator cs = charstyles().begin(); + CharStyles::iterator csend = charstyles().end(); + for (; cs != csend; ++cs) { + if (cs->name == s) + return cs; + } + return csend; +} + + string const & LyXTextClass::defaultLayoutName() const { // This really should come from the actual layout... (Lgb) @@ -869,6 +939,12 @@ string const & LyXTextClass::options() const } +string const & LyXTextClass::class_header() const +{ + return class_header_; +} + + string const & LyXTextClass::pagestyle() const { return pagestyle_; @@ -917,12 +993,6 @@ unsigned int LyXTextClass::columns() const } -int LyXTextClass::maxcounter() const -{ - return maxcounter_; -} - - LYX_TITLE_LATEX_TYPES LyXTextClass::titletype() const { return titletype_; @@ -935,9 +1005,6 @@ string const & LyXTextClass::titlename() const } - - - int LyXTextClass::size() const { return layoutlist_.size();