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