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