]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
c2eb3d232642d29540538187525c9439019923b4
[lyx.git] / src / mathed / MathStream.h
1 // -*- C++ -*-
2 /**
3  * \file MathStream.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef MATH_MATHMLSTREAM_H
13 #define MATH_MATHMLSTREAM_H
14
15 #include "support/strfwd.h"
16
17 #include "InsetMath.h"
18 // FIXME: Move to individual insets
19 #include "MetricsInfo.h"
20
21
22 namespace lyx {
23
24 class Encoding;
25 class InsetMath;
26 class MathAtom;
27 class MathData;
28
29 //
30 // LaTeX/LyX
31 //
32
33 class WriteStream {
34 public:
35         ///
36         enum OutputType {
37                 wsDefault,
38                 wsDryrun,
39                 wsPreview
40         };
41         ///
42         WriteStream(odocstream & os, bool fragile, bool latex, OutputType output,
43                 Encoding const * encoding = 0);
44         ///
45         explicit WriteStream(odocstream & os);
46         ///
47         ~WriteStream();
48         ///
49         int line() const { return line_; }
50         ///
51         bool fragile() const { return fragile_; }
52         ///
53         bool latex() const { return latex_; }
54         ///
55         OutputType output() const { return output_; }
56         ///
57         odocstream & os() { return os_; }
58         ///
59         bool & firstitem() { return firstitem_; }
60         ///
61         void addlines(unsigned int);
62         /// writes space if next thing is isalpha()
63         void pendingSpace(bool how);
64         /// writes space if next thing is isalpha()
65         bool pendingSpace() const { return pendingspace_; }
66         /// tell whether to write the closing brace of \ensuremath
67         void pendingBrace(bool brace);
68         /// tell whether to write the closing brace of \ensuremath
69         bool pendingBrace() const { return pendingbrace_; }
70         /// tell whether we are in text mode or not when producing latex code
71         void textMode(bool textmode);
72         /// tell whether we are in text mode or not when producing latex code
73         bool textMode() const { return textmode_; }
74         /// tell whether we are allowed to switch mode when producing latex code
75         void lockedMode(bool locked);
76         /// tell whether we are allowed to switch mode when producing latex code
77         bool lockedMode() const { return locked_; }
78         /// LaTeX encoding
79         Encoding const * encoding() const { return encoding_; }
80 private:
81         ///
82         odocstream & os_;
83         /// do we have to write \\protect sometimes
84         bool fragile_;
85         /// are we at the beginning of an MathData?
86         bool firstitem_;
87         /// are we writing to .tex?
88         int latex_;
89         /// output type (default, source preview, instant preview)?
90         OutputType output_;
91         /// do we have a space pending?
92         bool pendingspace_;
93         /// do we have a brace pending?
94         bool pendingbrace_;
95         /// are we in text mode when producing latex code?
96         bool textmode_;
97         /// are we allowed to switch mode when producing latex code?
98         bool locked_;
99         ///
100         int line_;
101         ///
102         Encoding const * encoding_;
103 };
104
105 ///
106 WriteStream & operator<<(WriteStream &, MathAtom const &);
107 ///
108 WriteStream & operator<<(WriteStream &, MathData const &);
109 ///
110 WriteStream & operator<<(WriteStream &, docstring const &);
111 ///
112 WriteStream & operator<<(WriteStream &, char const * const);
113 ///
114 WriteStream & operator<<(WriteStream &, char);
115 ///
116 WriteStream & operator<<(WriteStream &, int);
117 ///
118 WriteStream & operator<<(WriteStream &, unsigned int);
119
120 /// ensure math mode, possibly by opening \ensuremath
121 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
122
123 /// ensure the requested mode, possibly by closing \ensuremath
124 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked);
125
126
127 /**
128  * MathEnsurer - utility class for ensuring math mode
129  *
130  * A local variable of this type can be used to either ensure math mode
131  * or delay the writing of a pending brace when outputting LaTeX.
132  *
133  * Example 1:
134  *
135  *      MathEnsurer ensurer(os);
136  *
137  * If not already in math mode, inserts an \ensuremath command followed
138  * by an open brace. This brace will be automatically closed when exiting
139  * math mode. Math mode is automatically exited when writing something
140  * that doesn't explicitly require math mode.
141  *
142  * Example 2:
143  *
144  *      MathEnsurer ensurer(os, false);
145  *
146  * Simply suspend writing a closing brace until the end of ensurer's scope.
147  *
148  * Example 3:
149  *
150  *      MathEnsurer ensurer(os, needs_math_mode, true);
151  *
152  * The third parameter is set to true only for a user defined macro, which
153  * needs special handling. When it is a MathMacro, the needs_math_mode
154  * parameter is true and the behavior is as in Example 1. When the
155  * needs_math_mode parameter is false (not a MathMacro) and the macro
156  * was entered in a text box and we are in math mode, the mode is reset
157  * to text. This is because the macro was probably designed for text mode
158  * (given that it was entered in text mode and we have no way to tell the
159  * contrary).
160  */
161 class MathEnsurer
162 {
163 public:
164         ///
165         explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
166                 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
167         ///
168         ~MathEnsurer() { os_.pendingBrace(brace_); }
169 private:
170         ///
171         WriteStream & os_;
172         ///
173         bool brace_;
174 };
175
176
177 /**
178  * ModeSpecifier - utility class for specifying a given mode (math or text)
179  *
180  * A local variable of this type can be used to specify that a command or
181  * environment works in a given mode. For example, \mbox works in text
182  * mode, but \boxed works in math mode. Note that no mode changing commands
183  * are needed, but we have to track the current mode, hence this class.
184  * This is only used when exporting to latex and helps determining whether
185  * the mode needs being temporarily switched when a command would not work
186  * in the current mode. As there are cases where this switching is to be
187  * avoided, the optional third parameter can be used to lock the mode.
188  *
189  * Example 1:
190  *
191  *      ModeSpecifier specifier(os, TEXT_MODE);
192  *
193  * Sets the current mode to text mode and allows mode switching.
194  *
195  * Example 2:
196  *
197  *      ModeSpecifier specifier(os, TEXT_MODE, true);
198  *
199  * Sets the current mode to text mode and disallows mode switching.
200  *
201  * At the end of specifier's scope the mode is reset to its previous value.
202  */
203 class ModeSpecifier
204 {
205 public:
206         ///
207         explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
208                                 bool locked = false)
209                 : os_(os), oldmodes_(ensureMode(os, mode, locked)) {}
210         ///
211         ~ModeSpecifier()
212         {
213                 os_.textMode(oldmodes_ & 1);
214                 os_.lockedMode(oldmodes_ & 2);
215         }
216 private:
217         ///
218         WriteStream & os_;
219         ///
220         int oldmodes_;
221 };
222
223
224
225 //
226 //  MathML
227 //
228
229 class MTag {
230 public:
231         ///
232         MTag(char const * const tag) : tag_(tag) {}
233         ///
234         char const * const tag_;
235 };
236
237 class ETag {
238 public:
239         ///
240         ETag(char const * const tag) : tag_(tag) {}
241         ///
242         char const * const tag_;
243 };
244
245 class MathStream {
246 public:
247         ///
248         explicit MathStream(odocstream & os);
249         ///
250         void cr();
251         ///
252         odocstream & os() { return os_; }
253         ///
254         int line() const { return line_; }
255         ///
256         int & tab() { return tab_; }
257         ///
258         friend MathStream & operator<<(MathStream &, char const *);
259         ///
260         void defer(docstring const &);
261         ///
262         void defer(std::string const &);
263         ///
264         docstring deferred() const;
265 private:
266         ///
267         odocstream & os_;
268         ///
269         int tab_;
270         ///
271         int line_;
272         ///
273         char lastchar_;
274         ///
275         odocstringstream deferred_;
276 };
277
278 ///
279 MathStream & operator<<(MathStream &, MathAtom const &);
280 ///
281 MathStream & operator<<(MathStream &, MathData const &);
282 ///
283 MathStream & operator<<(MathStream &, docstring const &);
284 ///
285 MathStream & operator<<(MathStream &, char const *);
286 ///
287 MathStream & operator<<(MathStream &, char);
288 ///
289 MathStream & operator<<(MathStream &, char_type);
290 ///
291 MathStream & operator<<(MathStream &, MTag const &);
292 ///
293 MathStream & operator<<(MathStream &, ETag const &);
294
295
296
297 //
298 // Debugging
299 //
300
301 class NormalStream {
302 public:
303         ///
304         explicit NormalStream(odocstream & os) : os_(os) {}
305         ///
306         odocstream & os() { return os_; }
307 private:
308         ///
309         odocstream & os_;
310 };
311
312 ///
313 NormalStream & operator<<(NormalStream &, MathAtom const &);
314 ///
315 NormalStream & operator<<(NormalStream &, MathData const &);
316 ///
317 NormalStream & operator<<(NormalStream &, docstring const &);
318 ///
319 NormalStream & operator<<(NormalStream &, char const *);
320 ///
321 NormalStream & operator<<(NormalStream &, char);
322 ///
323 NormalStream & operator<<(NormalStream &, int);
324
325
326 //
327 // Maple
328 //
329
330
331 class MapleStream {
332 public:
333         ///
334         explicit MapleStream(odocstream & os) : os_(os) {}
335         ///
336         odocstream & os() { return os_; }
337 private:
338         ///
339         odocstream & os_;
340 };
341
342
343 ///
344 MapleStream & operator<<(MapleStream &, MathAtom const &);
345 ///
346 MapleStream & operator<<(MapleStream &, MathData const &);
347 ///
348 MapleStream & operator<<(MapleStream &, docstring const &);
349 ///
350 MapleStream & operator<<(MapleStream &, char_type);
351 ///
352 MapleStream & operator<<(MapleStream &, char const *);
353 ///
354 MapleStream & operator<<(MapleStream &, char);
355 ///
356 MapleStream & operator<<(MapleStream &, int);
357
358
359 //
360 // Maxima
361 //
362
363
364 class MaximaStream {
365 public:
366         ///
367         explicit MaximaStream(odocstream & os) : os_(os) {}
368         ///
369         odocstream & os() { return os_; }
370 private:
371         ///
372         odocstream & os_;
373 };
374
375
376 ///
377 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
378 ///
379 MaximaStream & operator<<(MaximaStream &, MathData const &);
380 ///
381 MaximaStream & operator<<(MaximaStream &, docstring const &);
382 ///
383 MaximaStream & operator<<(MaximaStream &, char_type);
384 ///
385 MaximaStream & operator<<(MaximaStream &, char const *);
386 ///
387 MaximaStream & operator<<(MaximaStream &, char);
388 ///
389 MaximaStream & operator<<(MaximaStream &, int);
390
391
392 //
393 // Mathematica
394 //
395
396
397 class MathematicaStream {
398 public:
399         ///
400         explicit MathematicaStream(odocstream & os) : os_(os) {}
401         ///
402         odocstream & os() { return os_; }
403 private:
404         ///
405         odocstream & os_;
406 };
407
408
409 ///
410 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
411 ///
412 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
413 ///
414 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
415 ///
416 MathematicaStream & operator<<(MathematicaStream &, char const *);
417 ///
418 MathematicaStream & operator<<(MathematicaStream &, char);
419 ///
420 MathematicaStream & operator<<(MathematicaStream &, int);
421
422
423 //
424 // Octave
425 //
426
427
428 class OctaveStream {
429 public:
430         ///
431         explicit OctaveStream(odocstream & os) : os_(os) {}
432         ///
433         odocstream & os() { return os_; }
434 private:
435         ///
436         odocstream & os_;
437 };
438
439 ///
440 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
441 ///
442 OctaveStream & operator<<(OctaveStream &, MathData const &);
443 ///
444 OctaveStream & operator<<(OctaveStream &, docstring const &);
445 ///
446 OctaveStream & operator<<(OctaveStream &, char_type);
447 ///
448 OctaveStream & operator<<(OctaveStream &, char const *);
449 ///
450 OctaveStream & operator<<(OctaveStream &, char);
451 ///
452 OctaveStream & operator<<(OctaveStream &, int);
453
454 } // namespace lyx
455
456 #endif