1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2001 the LyX Team.
9 * ====================================================== */
14 #pragma implementation "LaTeXFeatures.h"
21 #include "LaTeXFeatures.h"
22 #include "bufferparams.h"
24 #include "support/filetools.h"
25 #include "support/lstrings.h"
26 #include "FloatList.h"
33 LaTeXFeatures::LaTeXFeatures(BufferParams const & p, LyXTextClass::size_type n)
34 : layout(n, false), params(p)
40 void LaTeXFeatures::require(string const & name)
42 // INSET_GRAPHICS: remove this when InsetFig is thrown.
43 if (name == "graphics") {
44 features.push_back("graphicx");
45 features.push_back("graphics");
47 features.push_back(name);
51 void LaTeXFeatures::useLayout(std::vector<bool>::size_type const & idx)
56 bool LaTeXFeatures::isRequired(string const & name) const
58 FeaturesList::const_iterator i = std::find(features.begin(),
61 return i!= features.end();
64 void LaTeXFeatures::addExternalPreamble(string const & pream)
66 externalPreambles += pream;
69 void LaTeXFeatures::useFloat(string const & name)
71 usedFloats.insert(name);
74 void LaTeXFeatures::useLanguage(Language const * lang)
76 UsedLanguages.insert(lang);
79 void LaTeXFeatures::includeFile(string const & key, string const & name)
81 IncludedFiles[key] = name;
84 bool LaTeXFeatures::hasLanguages()
86 return !UsedLanguages.empty();
89 string LaTeXFeatures::getLanguages() const
92 ostringstream languages;
94 for (LanguageList::const_iterator cit =
95 UsedLanguages.begin();
96 cit != UsedLanguages.end();
98 languages << (*cit)->babel() << ',';
100 return languages.str().c_str();
103 set<string> LaTeXFeatures::getEncodingSet(string const & doc_encoding)
105 set<string> encodings;
106 for (LanguageList::const_iterator it =
107 UsedLanguages.begin();
108 it != UsedLanguages.end(); ++it)
109 if ((*it)->encoding()->LatexName() != doc_encoding)
110 encodings.insert((*it)->encoding()->LatexName());
114 string const LaTeXFeatures::getPackages() const
116 ostringstream packages;
117 LyXTextClass const & tclass =
118 textclasslist.TextClass(params.textclass);
122 * These are all the 'simple' includes. i.e
123 * packages which we just \usepackage{package}
127 if (isRequired("array"))
128 packages << "\\usepackage{array}\n";
131 if (isRequired("verbatim"))
132 packages << "\\usepackage{verbatim}\n";
135 if (isRequired("longtable"))
136 packages << "\\usepackage{longtable}\n";
139 if (isRequired("rotating"))
140 packages << "\\usepackage{rotating}\n";
144 if (isRequired("latexsym"))
145 packages << "\\usepackage{latexsym}\n";
148 if (isRequired("pifont"))
149 packages << "\\usepackage{pifont}\n";
152 if (isRequired("subfigure"))
153 packages << "\\usepackage{subfigure}\n";
156 if (isRequired("floatflt"))
157 packages << "\\usepackage{floatflt}\n";
161 if (isRequired("varioref"))
162 packages << "\\usepackage{varioref}\n";
165 if (isRequired("prettyref"))
166 packages << "\\usepackage{prettyref}\n";
169 * The rest of these packages are somewhat more complicated
174 if (isRequired("color")) {
175 if (params.graphicsDriver == "default")
176 packages << "\\usepackage{color}\n";
178 packages << "\\usepackage["
179 << params.graphicsDriver
184 if (isRequired("makeidx")) {
185 if (! tclass.provides(LyXTextClass::makeidx))
186 packages << "\\usepackage{makeidx}\n";
187 packages << "\\makeindex\n";
191 if (isRequired("graphicx") && params.graphicsDriver != "none") {
192 if (params.graphicsDriver == "default")
193 packages << "\\usepackage{graphicx}\n";
195 packages << "\\usepackage["
196 << params.graphicsDriver
200 // INSET_GRAPHICS: remove this when InsetFig is thrown.
202 if (isRequired("graphics") && params.graphicsDriver != "none") {
203 if (params.graphicsDriver == "default")
204 packages << "\\usepackage{graphics}\n";
206 packages << "\\usepackage["
207 << params.graphicsDriver
212 // packages << "\\usepackage{algorithm}\n";
215 // lyxskak.sty --- newer chess support based on skak.sty
216 if (isRequired("chess")) {
217 packages << "\\usepackage[ps,mover]{lyxskak}\n";
221 if ((params.spacing.getSpace() != Spacing::Single
222 && !params.spacing.isDefault())
223 || isRequired("setspace")) {
224 packages << "\\usepackage{setspace}\n";
226 switch (params.spacing.getSpace()) {
227 case Spacing::Default:
228 case Spacing::Single:
229 // we dont use setspace.sty so dont print anything
230 //packages += "\\singlespacing\n";
232 case Spacing::Onehalf:
233 packages << "\\onehalfspacing\n";
235 case Spacing::Double:
236 packages << "\\doublespacing\n";
239 packages << "\\setstretch{"
240 << params.spacing.getValue() << "}\n";
245 if (isRequired("amssymb") || params.use_amsmath)
246 packages << "\\usepackage{amssymb}\n";
248 if (isRequired("url") && ! tclass.provides(LyXTextClass::url))
249 packages << "\\IfFileExists{url.sty}{\\usepackage{url}}\n"
250 " {\\newcommand{\\url}{\\texttt}}\n";
253 // We only need float.sty if we use non builtin floats, or if we
254 // use the "H" modifier. This includes modified table and
255 // figure floats. (Lgb)
256 if (!usedFloats.empty()) {
257 UsedFloats::const_iterator beg = usedFloats.begin();
258 UsedFloats::const_iterator end = usedFloats.end();
259 for (; beg != end; ++beg) {
260 Floating const & fl = floatList.getType((*beg));
261 if (!fl.type().empty() && !fl.builtin()) {
262 const_cast<LaTeXFeatures *>(this)->require("floats");
267 if (isRequired("floats")) {
268 packages << "\\usepackage{float}\n";
272 if (isRequired("natbib")) {
273 packages << "\\usepackage[";
274 if (params.use_numerical_citations) {
275 packages << "numbers";
277 packages << "authoryear";
279 packages << "]{natbib}\n";
282 packages << externalPreambles;
284 return packages.str().c_str();
289 string const LaTeXFeatures::getMacros() const
291 ostringstream macros;
293 // always include this
294 if (true || isRequired("lyx"))
295 macros << lyx_def << '\n';
297 if (isRequired("lyxline"))
298 macros << lyxline_def << '\n';
300 if (isRequired("noun")) {
301 macros << noun_def << '\n';
304 if (isRequired("lyxarrow")) {
305 macros << lyxarrow_def << '\n';
309 if (isRequired("quotesinglbase"))
310 macros << quotesinglbase_def << '\n';
311 if (isRequired("quotedblbase"))
312 macros << quotedblbase_def << '\n';
313 if (isRequired("guilsinglleft"))
314 macros << guilsinglleft_def << '\n';
315 if (isRequired("guilsinglright"))
316 macros << guilsinglright_def << '\n';
317 if (isRequired("guillemotleft"))
318 macros << guillemotleft_def << '\n';
319 if (isRequired("guillemotright"))
320 macros << guillemotright_def << '\n';
323 if (isRequired("boldsymbol") && !isRequired("amsstyle"))
324 macros << boldsymbol_def << '\n';
325 if (isRequired("binom") && !isRequired("amsstyle"))
326 macros << binom_def << '\n';
329 if (isRequired("NeedLyXMinipageIndent"))
330 macros << minipageindent_def;
331 if (isRequired("ParagraphIndent"))
332 macros << paragraphindent_def;
333 if (isRequired("NeedLyXFootnoteCode"))
334 macros << floatingfootnote_def;
337 getFloatDefinitions(macros);
339 for (LanguageList::const_iterator cit = UsedLanguages.begin();
340 cit != UsedLanguages.end(); ++cit)
341 if (!(*cit)->latex_options().empty())
342 macros << (*cit)->latex_options() << '\n';
343 if (!params.language->latex_options().empty())
344 macros << params.language->latex_options() << '\n';
346 return macros.str().c_str();
350 string const LaTeXFeatures::getTClassPreamble() const
352 // the text class specific preamble
353 LyXTextClass const & tclass =
354 textclasslist.TextClass(params.textclass);
355 ostringstream tcpreamble;
357 tcpreamble << tclass.preamble();
359 for (LyXTextClass::size_type i = 0; i < tclass.numLayouts(); ++i) {
361 tcpreamble << tclass[i].preamble();
365 return tcpreamble.str().c_str();
369 string const LaTeXFeatures::getLyXSGMLEntities() const
371 // Definition of entities used in the document that are LyX related.
372 ostringstream entities;
374 if (isRequired("lyxarrow")) {
375 entities << "<!ENTITY lyxarrow \"->\">"
379 return entities.str().c_str();
383 string const LaTeXFeatures::getIncludedFiles(string const & fname) const
385 ostringstream sgmlpreamble;
386 string const basename = OnlyPath(fname);
388 FileMap::const_iterator end = IncludedFiles.end();
389 for (FileMap::const_iterator fi = IncludedFiles.begin();
391 sgmlpreamble << "\n<!ENTITY " << fi->first
392 << (IsSGMLFilename(fi->second) ? " SYSTEM \"" : " \"" )
393 << MakeRelPath(fi->second, basename) << "\">";
395 return sgmlpreamble.str().c_str();
399 void LaTeXFeatures::showStruct() const {
400 lyxerr << "LyX needs the following commands when LaTeXing:"
401 << "\n***** Packages:" << getPackages()
402 << "\n***** Macros:" << getMacros()
403 << "\n***** Textclass stuff:" << getTClassPreamble()
404 << "\n***** done." << endl;
408 BufferParams const & LaTeXFeatures::bufferParams() const
413 void LaTeXFeatures::getFloatDefinitions(std::ostream & os) const
415 // Here we will output the code to create the needed float styles.
416 // We will try to do this as minimal as possible.
417 // \floatstyle{ruled}
418 // \newfloat{algorithm}{htbp}{loa}
419 // \floatname{algorithm}{Algorithm}
420 UsedFloats::const_iterator cit = usedFloats.begin();
421 UsedFloats::const_iterator end = usedFloats.end();
422 // ostringstream floats;
423 for (; cit != end; ++cit) {
424 Floating const & fl = floatList.getType((*cit));
426 // For builtin floats we do nothing.
427 if (fl.builtin()) continue;
429 // We have to special case "table" and "figure"
430 if (fl.type() == "tabular" || fl.type() == "figure") {
431 // Output code to modify "table" or "figure"
432 // but only if builtin == false
433 // and that have to be true at this point in the
435 string const type = fl.type();
436 string const placement = fl.placement();
437 string const style = fl.style();
438 if (!style.empty()) {
439 os << "\\floatstyle{" << style << "}\n"
440 << "\\restylefloat{" << type << "}\n";
442 if (!placement.empty()) {
443 os << "\\floatplacement{" << type << "}{"
444 << placement << "}\n";
447 // The other non builtin floats.
449 string const type = fl.type();
450 string const placement = fl.placement();
451 string const ext = fl.ext();
452 string const within = fl.within();
453 string const style = fl.style();
454 string const name = fl.name();
455 os << "\\floatstyle{" << style << "}\n"
456 << "\\newfloat{" << type << "}{" << placement
457 << "}{" << ext << "}";
459 os << "[" << within << "]";
461 << "\\floatname{" << type << "}{"
464 // What missing here is to code to minimalize the code
465 // outputted so that the same floatstyle will not be
466 // used several times, when the same style is still in