]> git.lyx.org Git - lyx.git/blob - src/LaTeXFeatures.C
use more stringstream, remove some cruft
[lyx.git] / src / LaTeXFeatures.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor
6  *        
7  *           Copyright 1995 Matthias Ettrich
8  *           Copyright 1995-2000 the LyX Team.
9  *
10  * ====================================================== */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation "LaTeXFeatures.h"
16 #endif
17
18 #include "LString.h"
19 #include "debug.h"
20 #include "lyx_sty.h"
21 #include "lyxrc.h"
22 #include "LaTeXFeatures.h"
23 #include "bufferparams.h"
24 #include "layout.h"
25 #include "support/filetools.h"
26 #include "FloatList.h"
27 #include "language.h"
28
29 using std::endl;
30
31 LaTeXFeatures::LaTeXFeatures(BufferParams const & p, LyXTextClass::size_type n)
32         : layout(n, false), params(p)
33 {
34         // packages
35         array = false;
36         color = false;
37         graphics = false; // INSET_GRAPHICS: remove this when InsetFig is thrown.
38         graphicx = false;
39         setspace = false;
40         makeidx = false;
41         verbatim = false;
42         longtable = false;
43         algorithm = false;
44         rotating = false;
45         amssymb = false;
46         latexsym = false;
47         pifont = false;
48         subfigure = false;
49         floatflt = false;
50         url = false;
51         varioref = false;
52         prettyref = false;
53         chess = false;
54         
55         // commands
56         lyx = false;
57         lyxline = false;
58         noun = false;
59         lyxarrow = false;
60
61         // quotes
62         quotesinglbase = false;
63         quotedblbase = false;
64         guilsinglleft = false;
65         guilsinglright = false;
66         guillemotleft = false;
67         guillemotright = false;
68
69         // Math mode
70         amsstyle = false;
71         binom = false;
72         boldsymbol = false;
73     
74         // special features
75         LyXParagraphIndent = false;
76         NeedLyXFootnoteCode = false;
77         NeedLyXMinipageIndent = false;
78 }
79
80
81 void LaTeXFeatures::require(string const & name)
82 {
83         if (name == "array") {
84                 array = true;
85         } else if (name == "color") {
86                 color = true;
87         } else if (name == "graphics") {
88                 graphicx = true;
89                 graphics = true;// INSET_GRAPHICS: remove this when InsetFig is thrown.
90         } else if (name == "setspace") {
91                 setspace = true;
92         } else if (name == "makeidx") {
93                 makeidx = true;
94         } else if (name == "verbatim") {
95                 verbatim = true;
96         } else if (name == "longtable") {
97                 longtable = true;
98         } else if (name == "algorithm") {
99                 algorithm = true;
100         } else if (name == "rotating") {
101                 rotating = true;
102         } else if (name == "amssymb") {
103                 amssymb = true;
104         } else if (name == "latexsym") {
105                 latexsym = true;
106         } else if (name == "pifont") {
107                 pifont = true;
108         } else if (name == "subfigure") {
109                 subfigure = true;
110         } else if (name == "floatflt") {
111                 floatflt = true;
112         } else if (name == "url") {
113                 url = true;
114         } else if (name == "varioref") {
115                 varioref = true;
116         } else if (name == "prettyref") {
117                 prettyref = true;
118         } else if (name == "chess") {
119                 chess = true;
120         } else if (name == "amsstyle") {
121                 amsstyle = true;
122         } else if (name == "boldsymbol") {
123                 boldsymbol = true;
124         } else if (name == "binom") {
125                 binom = true;
126         }
127 }
128
129
130 string const LaTeXFeatures::getPackages() const
131 {
132         ostringstream packages;
133         LyXTextClass const & tclass =
134                 textclasslist.TextClass(params.textclass);
135
136         // array-package
137         if (array)
138                 packages << "\\usepackage{array}\n";
139
140         // color.sty
141         if (color) {
142                 if (params.graphicsDriver == "default")
143                         packages << "\\usepackage{color}\n";
144                 else
145                         packages << "\\usepackage[" 
146                                  << params.graphicsDriver
147                                  << "]{color}\n";
148         }
149                 
150         // makeidx.sty
151         if (makeidx) {
152                 if (! tclass.provides(LyXTextClass::makeidx)
153                     && params.language->babel() != "french") // french provides
154                                                              // \index !
155                         // French should not be hardcoded. (Lgb)
156                         packages << "\\usepackage{makeidx}\n";
157                 packages << "\\makeindex\n";
158         }
159
160         // graphicx.sty
161         if (graphicx && params.graphicsDriver != "none") {
162                 if (params.graphicsDriver == "default")
163                         packages << "\\usepackage{graphicx}\n";
164                 else
165                         packages << "\\usepackage[" 
166                                  << params.graphicsDriver
167                                  << "]{graphicx}\n";
168         }
169
170         // INSET_GRAPHICS: remove this when InsetFig is thrown.
171         // graphics.sty
172         if (graphics && params.graphicsDriver != "none") {
173                 if (params.graphicsDriver == "default")
174                         packages << "\\usepackage{graphics}\n";
175                 else
176                         packages << "\\usepackage[" 
177                                  << params.graphicsDriver
178                                  << "]{graphics}\n";
179         }
180
181         // verbatim.sty
182         if (verbatim)
183                 packages << "\\usepackage{verbatim}\n";
184
185         if (algorithm) {
186                 packages << "\\usepackage{algorithm}\n";
187         }
188
189         // lyxchess.sty
190         if (chess) {
191                 packages << "\\usepackage{lyxchess}\n";
192         }
193
194         // setspace.sty
195         if ((params.spacing.getSpace() != Spacing::Single
196              && !params.spacing.isDefault())
197             || setspace) {
198                 packages << "\\usepackage{setspace}\n";
199         }
200         switch (params.spacing.getSpace()) {
201         case Spacing::Default:
202         case Spacing::Single:
203                 // we dont use setspace.sty so dont print anything
204                 //packages += "\\singlespacing\n";
205                 break;
206         case Spacing::Onehalf:
207                 packages << "\\onehalfspacing\n";
208                 break;
209         case Spacing::Double:
210                 packages << "\\doublespacing\n";
211                 break;
212         case Spacing::Other:
213                 packages << "\\setstretch{"
214                          << params.spacing.getValue() << "}\n";
215                 break;
216         }
217
218         //longtable.sty
219         if (longtable)
220                 packages << "\\usepackage{longtable}\n";
221
222         //rotating.sty
223         if (rotating)
224                 packages << "\\usepackage{rotating}\n";
225
226         // amssymb.sty
227         if (amssymb || params.use_amsmath)
228                 packages << "\\usepackage{amssymb}\n";
229
230         // latexsym.sty
231         if (latexsym)
232                 packages << "\\usepackage{latexsym}\n";
233
234         // pifont.sty
235         if (pifont)
236                 packages << "\\usepackage{pifont}\n";
237
238         // subfigure.sty
239         if (subfigure)
240                 packages << "\\usepackage{subfigure}\n";
241
242         // floatflt.sty
243         if (floatflt)
244                 packages << "\\usepackage{floatflt}\n";
245
246         // url.sty
247         if (url && ! tclass.provides(LyXTextClass::url))
248                 packages << "\\IfFileExists{url.sty}{\\usepackage{url}}\n"
249                             "                      {\\newcommand{\\url}{\\texttt}}\n";
250
251         // varioref.sty
252         if (varioref)
253                 packages << "\\usepackage{varioref}\n";
254
255         // prettyref.sty
256         if (prettyref)
257                 packages << "\\usepackage{prettyref}\n";
258
259         // float.sty
260         // We only need float.sty if we use non builtin floats. This includes
261         // modified table and figure floats. (Lgb)
262         if (!usedFloats.empty()) {
263                 bool use_float = false;
264                 UsedFloats::const_iterator beg = usedFloats.begin();
265                 UsedFloats::const_iterator end = usedFloats.end();
266                 for (; beg != end; ++beg) {
267                         Floating const & fl = floatList.getType((*beg));
268                         if (!fl.type().empty() && !fl.builtin()) {
269                                 use_float = true;
270                                 break;
271                         }
272                 }
273                 if (use_float)
274                         packages << "\\usepackage{float}\n";
275         }
276         
277         packages << externalPreambles;
278
279         return packages.str().c_str();
280 }
281
282
283 string const LaTeXFeatures::getMacros() const
284 {
285         ostringstream macros;
286
287         // always include this
288         if (true || lyx) 
289                 macros << lyx_def << '\n';
290
291         if (lyxline) 
292                 macros << lyxline_def << '\n';
293
294         if (noun) {
295                 macros << noun_def << '\n';
296         }
297
298         if (lyxarrow) {
299                 macros << lyxarrow_def << '\n';
300         }
301
302         // quotes. 
303         if (quotesinglbase)
304                 macros << quotesinglbase_def << '\n';
305         if (quotedblbase)
306                 macros << quotedblbase_def << '\n';
307         if (guilsinglleft)
308                 macros << guilsinglleft_def << '\n';
309         if (guilsinglright)
310                 macros << guilsinglright_def << '\n';
311         if (guillemotleft)
312                 macros << guillemotleft_def << '\n';
313         if (guillemotright)
314                 macros << guillemotright_def << '\n';
315     
316         // Math mode    
317         if (boldsymbol && !amsstyle)
318                 macros << boldsymbol_def << '\n';
319         if (binom && !amsstyle)
320                 macros << binom_def << '\n';
321
322         // other
323         if (NeedLyXMinipageIndent) 
324                 macros << minipageindent_def;
325         if (LyXParagraphIndent) 
326                 macros << paragraphindent_def;
327         if (NeedLyXFootnoteCode) 
328                 macros << floatingfootnote_def;
329
330         // floats
331         getFloatDefinitions(macros);
332
333         for (LanguageList::const_iterator cit = UsedLanguages.begin();
334              cit != UsedLanguages.end(); ++cit)
335                 if (!(*cit)->latex_options().empty())
336                         macros << (*cit)->latex_options() << '\n';
337         if (!params.language->latex_options().empty())
338                 macros << params.language->latex_options() << '\n';
339
340         return macros.str().c_str();
341 }
342
343
344 string const LaTeXFeatures::getTClassPreamble() const
345 {
346         // the text class specific preamble 
347         LyXTextClass const & tclass =
348                 textclasslist.TextClass(params.textclass);
349         ostringstream tcpreamble;
350         
351         tcpreamble << tclass.preamble();
352
353         for (unsigned int i = 0; i < tclass.numLayouts(); ++i) {
354                 if (layout[i]) {
355                         tcpreamble << tclass[i].preamble();
356                 }
357         }
358
359         return tcpreamble.str().c_str();
360 }       
361
362
363 string const LaTeXFeatures::getIncludedFiles(string const & fname) const
364 {
365         ostringstream sgmlpreamble;
366         string const basename = OnlyPath(fname);
367
368         FileMap::const_iterator end = IncludedFiles.end();
369         for (FileMap::const_iterator fi = IncludedFiles.begin();
370              fi != end; ++fi)
371                 sgmlpreamble << "\n<!ENTITY " << fi->first
372                              << (IsSGMLFilename(fi->second) ? " SYSTEM \"" : " \"" )
373                              << MakeRelPath(fi->second, basename) << "\">";
374
375         return sgmlpreamble.str().c_str();
376 }
377
378
379 void LaTeXFeatures::showStruct() const {
380         lyxerr << "LyX needs the following commands when LaTeXing:"
381                << "\n***** Packages:" << getPackages()
382                << "\n***** Macros:" << getMacros()
383                << "\n***** Textclass stuff:" << getTClassPreamble()
384                << "\n***** done." << endl;
385 }
386
387
388 BufferParams const & LaTeXFeatures::bufferParams() const
389 {
390         return params;
391 }
392
393
394 void LaTeXFeatures::getFloatDefinitions(ostream & os) const
395 {
396         // Here we will output the code to create the needed float styles.
397         // We will try to do this as minimal as possible.
398         // \floatstyle{ruled}
399         // \newfloat{algorithm}{htbp}{loa}
400         // \floatname{algorithm}{Algorithm}
401         UsedFloats::const_iterator cit = usedFloats.begin();
402         UsedFloats::const_iterator end = usedFloats.end();
403         // ostringstream floats;
404         for (; cit != end; ++cit) {
405                 Floating const & fl = floatList.getType((*cit));
406                 
407                 // For builtin floats we do nothing.
408                 if (fl.builtin()) continue;
409                 
410                 // We have to special case "table" and "figure"
411                 if (fl.type() == "tabular" || fl.type() == "figure") {
412                         // Output code to modify "table" or "figure"
413                         // but only if builtin == false
414                         // and that have to be true at this point in the
415                         // function.
416                         string const type = fl.type();
417                         string const placement = fl.placement();
418                         string const style = fl.style();
419                         if (!style.empty()) {
420                                 os << "\\floatstyle{" << style << "}\n"
421                                    << "\\restylefloat{" << type << "}\n";
422                         }
423                         if (!placement.empty()) {
424                                 os << "\\floatplacement{" << type << "}{"
425                                    << placement << "}\n";
426                         }
427                 } else {
428                         // The other non builtin floats.
429                         
430                         string const type = fl.type();
431                         string const placement = fl.placement();
432                         string const ext = fl.ext();
433                         string const within = fl.within();
434                         string const style = fl.style();
435                         string const name = fl.name();
436                         os << "\\floatstyle{" << style << "}\n"
437                            << "\\newfloat{" << type << "}{" << placement
438                            << "}{" << ext << "}";
439                         if (!within.empty())
440                                 os << "[" << within << "]";
441                         os << "\n"
442                            << "\\floatname{" << type << "}{"
443                            << name << "}\n";
444                         
445                         // What missing here is to code to minimalize the code
446                         // outputted so that the same flotastyle will not be
447                         // used several times. when the same style is still in
448                         // effect. (Lgb)
449                 }
450         }
451 }