X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeXFeatures.C;h=15102ef3c20b6e580f05b90086f8f3ad327fa036;hb=9dafe9b9a5cb12e19e0f3a1a9669d81dc140b0e3;hp=71bc6d49da6c49ce151449e08b26ea91b2d48184;hpb=0eccdd1c3613e5170deb77b22174dd0afde833e9;p=lyx.git diff --git a/src/LaTeXFeatures.C b/src/LaTeXFeatures.C index 71bc6d49da..15102ef3c2 100644 --- a/src/LaTeXFeatures.C +++ b/src/LaTeXFeatures.C @@ -1,256 +1,443 @@ -// -*- C++ -*- /* This file is part of - * ====================================================== + * ====================================================== * * LyX, The Document Processor * * Copyright 1995 Matthias Ettrich - * Copyright 1995-1999 the LyX Team. + * Copyright 1995-2001 the LyX Team. * - * ======================================================*/ + * ====================================================== */ #include #ifdef __GNUG__ -#pragma implementation "LaTeXFeatures.h" +#pragma implementation #endif -#include "LString.h" -#include "error.h" +#include "LaTeXFeatures.h" +#include "debug.h" #include "lyx_sty.h" #include "lyxrc.h" -#include "LaTeXFeatures.h" #include "bufferparams.h" -#include "layout.h" +#include "lyxtextclasslist.h" +#include "FloatList.h" +#include "language.h" +#include "encoding.h" +#include "LString.h" + +#include "support/filetools.h" +#include "support/lstrings.h" + +using lyx::layout_type; +using lyx::textclass_type; -extern LyXRC * lyxrc; +using std::endl; +using std::set; +using std::vector; +using std::find; +using std::ostream; -LaTeXFeatures::LaTeXFeatures(int n) + +LaTeXFeatures::LaTeXFeatures(BufferParams const & p, layout_type n) + : layout(n, false), params(p) +{} + + +void LaTeXFeatures::require(string const & name) { - // packages - color = false; - graphics = false; - setspace = false; - makeidx = false; - verbatim = false; - longtable = false; - algorithm = false; - rotating = false; - amssymb = false; - latexsym = false; - pifont = false; - subfigure = false; - floatflt = false; - url = false; + if (isRequired(name)) + return; - // commands - lyx = false; - lyxline = false; - noun = false; - lyxarrow = false; - - // quotes - quotesinglbase = false; - quotedblbase = false; - guilsinglleft = false; - guilsinglright = false; - guillemotleft = false; - guillemotright = false; - - // Math mode - amsstyle = false; - binom = false; - boldsymbol = false; - - // special features - LyXParagraphIndent = false; - NeedLyXFootnoteCode = false; - NeedLyXMinipageIndent = false; - - // layouts - layout = new bool[n]; - for (int i = n; i--;) - layout[i] = false; + features.push_back(name); +} + + +void LaTeXFeatures::useLayout(vector::size_type const & idx) +{ + layout[idx] = true; +} + + +bool LaTeXFeatures::isRequired(string const & name) const +{ + FeaturesList::const_iterator i = find(features.begin(), + features.end(), + name); + return i != features.end(); +} + + +void LaTeXFeatures::addExternalPreamble(string const & pream) +{ + externalPreambles += pream; +} + + +void LaTeXFeatures::useFloat(string const & name) +{ + usedFloats.insert(name); + // We only need float.sty if we use non builtin floats, or if we + // use the "H" modifier. This includes modified table and + // figure floats. (Lgb) + Floating const & fl = floatList.getType(name); + if (!fl.type().empty() && !fl.builtin()) { + require("float"); + } +} + + +void LaTeXFeatures::useLanguage(Language const * lang) +{ + UsedLanguages.insert(lang); +} + + +void LaTeXFeatures::includeFile(string const & key, string const & name) +{ + IncludedFiles[key] = name; } -string LaTeXFeatures::getPackages(BufferParams const ¶ms) +bool LaTeXFeatures::hasLanguages() { - string packages; - LyXTextClass *tclass = lyxstyle.TextClass(params.textclass); + return !UsedLanguages.empty(); +} + + +string LaTeXFeatures::getLanguages() const +{ + ostringstream languages; + + for (LanguageList::const_iterator cit = + UsedLanguages.begin(); + cit != UsedLanguages.end(); + ++cit) + languages << (*cit)->babel() << ','; + + return languages.str().c_str(); +} + + +set LaTeXFeatures::getEncodingSet(string const & doc_encoding) +{ + set encodings; + for (LanguageList::const_iterator it = + UsedLanguages.begin(); + it != UsedLanguages.end(); ++it) + if ((*it)->encoding()->LatexName() != doc_encoding) + encodings.insert((*it)->encoding()->LatexName()); + return encodings; +} +namespace { + +char const * simplefeatures[] = { + "array", + "verbatim", + "longtable", + "rotating", + "latexsym", + "pifont", + "subfigure", + "floatflt", + "varioref", + "prettyref", + "float" +}; + +const int nb_simplefeatures = sizeof(simplefeatures) / sizeof(char const *); + +} + +string const LaTeXFeatures::getPackages() const +{ + ostringstream packages; + LyXTextClass const & tclass = + textclasslist.TextClass(params.textclass); + + + /** + * These are all the 'simple' includes. i.e + * packages which we just \usepackage{package} + **/ + for (int i = 0 ; i < nb_simplefeatures ; ++i) { + if (isRequired(simplefeatures[i])) + packages << "\\usepackage{" + << simplefeatures[i] + << "}\n"; + } + + /** + * The rest of these packages are somewhat more complicated + * than those above. + **/ + + if (isRequired("amsmath") + && ! tclass.provides(LyXTextClass::amsmath)) { + packages << "\\usepackage{amsmath}\n"; + } + // color.sty - if (color) { + if (isRequired("color")) { if (params.graphicsDriver == "default") - packages +="\\usepackage{color}\n"; + packages << "\\usepackage{color}\n"; else - packages += "\\usepackage[" - + params.graphicsDriver + "]{color}\n"; + packages << "\\usepackage[" + << params.graphicsDriver + << "]{color}\n"; } // makeidx.sty - if (makeidx) { - if (! tclass->provides_makeidx - && params.language != "french") // french provides - // \index ! - packages += "\\usepackage{makeidx}\n"; - packages += "\\makeindex\n"; + if (isRequired("makeidx")) { + if (! tclass.provides(LyXTextClass::makeidx)) + packages << "\\usepackage{makeidx}\n"; + packages << "\\makeindex\n"; } - // graphics.sty - if (graphics && params.graphicsDriver != "none") { + // graphicx.sty + if (isRequired("graphicx") && params.graphicsDriver != "none") { if (params.graphicsDriver == "default") - packages += "\\usepackage{graphics}\n"; + packages << "\\usepackage{graphicx}\n"; else - packages += "\\usepackage[" - + params.graphicsDriver + "]{graphics}\n"; + packages << "\\usepackage[" + << params.graphicsDriver + << "]{graphicx}\n"; } - //verbatim.sty - if (verbatim) - packages += "\\usepackage{verbatim}\n"; + //if (algorithm) { + // packages << "\\usepackage{algorithm}\n"; + //} - if (algorithm) { - packages += "\\usepackage{algorithm}\n"; + // lyxskak.sty --- newer chess support based on skak.sty + if (isRequired("chess")) { + packages << "\\usepackage[ps,mover]{lyxskak}\n"; } // setspace.sty - if ((params.spacing.getSpace() != Spacing::Single) - || setspace) { - packages += "\\usepackage{setspace}\n"; + if ((params.spacing.getSpace() != Spacing::Single + && !params.spacing.isDefault()) + || isRequired("setspace")) { + packages << "\\usepackage{setspace}\n"; } switch (params.spacing.getSpace()) { + case Spacing::Default: case Spacing::Single: // we dont use setspace.sty so dont print anything //packages += "\\singlespacing\n"; break; case Spacing::Onehalf: - packages += "\\onehalfspacing\n"; + packages << "\\onehalfspacing\n"; break; case Spacing::Double: - packages += "\\doublespacing\n"; + packages << "\\doublespacing\n"; break; case Spacing::Other: - char value[30]; - sprintf(value, "%.2f", params.spacing.getValue()); - packages += string("\\setstretch{") - + value + "}\n"; + packages << "\\setstretch{" + << params.spacing.getValue() << "}\n"; break; } - //longtable.sty - if (longtable) - packages += "\\usepackage{longtable}\n"; - - //rotating.sty - if (rotating) - packages += "\\usepackage{rotating}\n"; - // amssymb.sty - if (amssymb) - packages += "\\usepackage{amssymb}\n"; - - // latexsym.sty - if (latexsym) - packages += "\\usepackage{latexsym}\n"; - - // pifont.sty - if (pifont) - packages += "\\usepackage{pifont}\n"; - - // subfigure.sty - if (subfigure) - packages += "\\usepackage{subfigure}\n"; - - // floatflt.sty - if (floatflt) - packages += "\\usepackage{floatflt}\n"; - + if (isRequired("amssymb") || params.use_amsmath) + packages << "\\usepackage{amssymb}\n"; // url.sty - if (url && ! tclass->provides_url) - packages += "\\IfFileExists{url.sty}{\\usepackage{url}}\n" + if (isRequired("url") && ! tclass.provides(LyXTextClass::url)) + packages << "\\IfFileExists{url.sty}{\\usepackage{url}}\n" " {\\newcommand{\\url}{\\texttt}}\n"; + + // float.sty + // natbib.sty + if (isRequired("natbib")) { + packages << "\\usepackage["; + if (params.use_numerical_citations) { + packages << "numbers"; + } else { + packages << "authoryear"; + } + packages << "]{natbib}\n"; + } - return packages; + packages << externalPreambles; + + return packages.str().c_str(); } -string LaTeXFeatures::getMacros(BufferParams const & /* params */) +string const LaTeXFeatures::getMacros() const { - string macros; + ostringstream macros; // always include this - if (true || lyx) - macros += lyx_def + '\n'; + if (true || isRequired("lyx")) + macros << lyx_def << '\n'; - if (lyxline) - macros += lyxline_def + '\n'; + if (isRequired("lyxline")) + macros << lyxline_def << '\n'; - if (noun) { - macros += noun_def + '\n'; - } + if (isRequired("noun")) + macros << noun_def << '\n'; - if (lyxarrow) { - macros += lyxarrow_def + '\n'; - } + if (isRequired("lyxarrow")) + macros << lyxarrow_def << '\n'; // quotes. - if (quotesinglbase) - macros += quotesinglbase_def + '\n'; - if (quotedblbase) - macros += quotedblbase_def + '\n'; - if (guilsinglleft) - macros += guilsinglleft_def + '\n'; - if (guilsinglright) - macros += guilsinglright_def + '\n'; - if (guillemotleft) - macros += guillemotleft_def + '\n'; - if (guillemotright) - macros += guillemotright_def + '\n'; + if (isRequired("quotesinglbase")) + macros << quotesinglbase_def << '\n'; + if (isRequired("quotedblbase")) + macros << quotedblbase_def << '\n'; + if (isRequired("guilsinglleft")) + macros << guilsinglleft_def << '\n'; + if (isRequired("guilsinglright")) + macros << guilsinglright_def << '\n'; + if (isRequired("guillemotleft")) + macros << guillemotleft_def << '\n'; + if (isRequired("guillemotright")) + macros << guillemotright_def << '\n'; // Math mode - if (boldsymbol && !amsstyle) - macros += boldsymbol_def + '\n'; - if (binom && !amsstyle) - macros += binom_def + '\n'; + if (isRequired("boldsymbol") && !isRequired("amsmath")) + macros << boldsymbol_def << '\n'; + if (isRequired("binom") && !isRequired("amsmath")) + macros << binom_def << '\n'; // other - if (NeedLyXMinipageIndent) - macros += minipageindent_def; - if (LyXParagraphIndent) - macros += paragraphindent_def; - if (NeedLyXFootnoteCode) - macros += floatingfootnote_def; - - return macros; + if (isRequired("NeedLyXMinipageIndent")) + macros << minipageindent_def; + if (isRequired("ParagraphIndent")) + macros << paragraphindent_def; + if (isRequired("NeedLyXFootnoteCode")) + macros << floatingfootnote_def; + + // floats + getFloatDefinitions(macros); + + for (LanguageList::const_iterator cit = UsedLanguages.begin(); + cit != UsedLanguages.end(); ++cit) + if (!(*cit)->latex_options().empty()) + macros << (*cit)->latex_options() << '\n'; + if (!params.language->latex_options().empty()) + macros << params.language->latex_options() << '\n'; + + return macros.str().c_str(); } -string LaTeXFeatures::getTClassPreamble(BufferParams const ¶ms) +string const LaTeXFeatures::getTClassPreamble() const { // the text class specific preamble - LyXTextClass *tclass = lyxstyle.TextClass(params.textclass); - string tcpreamble = tclass->preamble; - - int l; - for (l = 0 ; l < tclass->number_of_defined_layouts ; l++) { - if (layout[l] - && !tclass->style[l].preamble.empty()) - tcpreamble += tclass->style[l].preamble; + LyXTextClass const & tclass = textclasslist.TextClass(params.textclass); + ostringstream tcpreamble; + + tcpreamble << tclass.preamble(); + + for (layout_type i = 0; i < tclass.numLayouts(); ++i) { + if (layout[i]) { + tcpreamble << tclass[i].preamble(); + } } - return tcpreamble; + return tcpreamble.str().c_str(); } -void LaTeXFeatures::showStruct(BufferParams ¶ms) { - lyxerr.print("LyX needs the following commands when LaTeXing:"); - // packs - lyxerr.print("***** Packages:"); - lyxerr.print(getPackages(params)); - lyxerr.print("***** Macros:"); - lyxerr.print(getMacros(params)); - lyxerr.print("***** Textclass stuff:"); - lyxerr.print(getTClassPreamble(params)); - lyxerr.print("***** done."); +string const LaTeXFeatures::getLyXSGMLEntities() const +{ + // Definition of entities used in the document that are LyX related. + ostringstream entities; + + if (isRequired("lyxarrow")) { + entities << "" << '\n'; + } + + return entities.str().c_str(); +} + + +string const LaTeXFeatures::getIncludedFiles(string const & fname) const +{ + ostringstream sgmlpreamble; + string const basename = OnlyPath(fname); + + FileMap::const_iterator end = IncludedFiles.end(); + for (FileMap::const_iterator fi = IncludedFiles.begin(); + fi != end; ++fi) + sgmlpreamble << "\nfirst + << (IsSGMLFilename(fi->second) ? " SYSTEM \"" : " \"") + << MakeRelPath(fi->second, basename) << "\">"; + + return sgmlpreamble.str().c_str(); +} + + +void LaTeXFeatures::showStruct() const { + lyxerr << "LyX needs the following commands when LaTeXing:" + << "\n***** Packages:" << getPackages() + << "\n***** Macros:" << getMacros() + << "\n***** Textclass stuff:" << getTClassPreamble() + << "\n***** done." << endl; +} + + +BufferParams const & LaTeXFeatures::bufferParams() const +{ + return params; +} + +void LaTeXFeatures::getFloatDefinitions(ostream & os) const +{ + // Here we will output the code to create the needed float styles. + // We will try to do this as minimal as possible. + // \floatstyle{ruled} + // \newfloat{algorithm}{htbp}{loa} + // \floatname{algorithm}{Algorithm} + UsedFloats::const_iterator cit = usedFloats.begin(); + UsedFloats::const_iterator end = usedFloats.end(); + // ostringstream floats; + for (; cit != end; ++cit) { + Floating const & fl = floatList.getType((*cit)); + + // For builtin floats we do nothing. + if (fl.builtin()) continue; + + // We have to special case "table" and "figure" + if (fl.type() == "tabular" || fl.type() == "figure") { + // Output code to modify "table" or "figure" + // but only if builtin == false + // and that have to be true at this point in the + // function. + string const type = fl.type(); + string const placement = fl.placement(); + string const style = fl.style(); + if (!style.empty()) { + os << "\\floatstyle{" << style << "}\n" + << "\\restylefloat{" << type << "}\n"; + } + if (!placement.empty()) { + os << "\\floatplacement{" << type << "}{" + << placement << "}\n"; + } + } else { + // The other non builtin floats. + + string const type = fl.type(); + string const placement = fl.placement(); + string const ext = fl.ext(); + string const within = fl.within(); + string const style = fl.style(); + string const name = fl.name(); + os << "\\floatstyle{" << style << "}\n" + << "\\newfloat{" << type << "}{" << placement + << "}{" << ext << "}"; + if (!within.empty()) + os << "[" << within << "]"; + os << "\n" + << "\\floatname{" << type << "}{" + << name << "}\n"; + + // What missing here is to code to minimalize the code + // output so that the same floatstyle will not be + // used several times, when the same style is still in + // effect. (Lgb) + } + } }