]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
51760a33dde485c22fdf4e041d503d77b024c88b
[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
246 class MathStream {
247 public:
248         ///
249         explicit MathStream(odocstream & os);
250         ///
251         void cr();
252         ///
253         odocstream & os() { return os_; }
254         ///
255         int line() const { return line_; }
256         ///
257         int & tab() { return tab_; }
258         ///
259         friend MathStream & operator<<(MathStream &, char const *);
260         ///
261         void defer(docstring const &);
262         ///
263         void defer(std::string const &);
264         ///
265         docstring deferred() const;
266         ///
267         bool inText() const { return in_text_; }
268 private:
269         ///
270         void setTextMode() { in_text_ = true; }
271         ///
272         void setMathMode() { in_text_ = false; }
273         ///
274         odocstream & os_;
275         ///
276         int tab_;
277         ///
278         int line_;
279         ///
280         char lastchar_;
281         ///
282         bool in_text_;
283         ///
284         odocstringstream deferred_;
285         ///
286         friend class SetMode;
287 };
288
289 ///
290 MathStream & operator<<(MathStream &, MathAtom const &);
291 ///
292 MathStream & operator<<(MathStream &, MathData const &);
293 ///
294 MathStream & operator<<(MathStream &, docstring const &);
295 ///
296 MathStream & operator<<(MathStream &, char const *);
297 ///
298 MathStream & operator<<(MathStream &, char);
299 ///
300 MathStream & operator<<(MathStream &, char_type);
301 ///
302 MathStream & operator<<(MathStream &, MTag const &);
303 ///
304 MathStream & operator<<(MathStream &, ETag const &);
305
306
307 // A simpler version of ModeSpecifier, for MathML
308 class SetMode {
309 public:
310         ///
311         explicit SetMode(MathStream & os, bool text, docstring attrs);
312         ///
313         explicit SetMode(MathStream & os, bool text);
314         ///
315         ~SetMode();
316 private:
317         ///
318         void init(bool, docstring);
319         ///
320         MathStream & os_;
321         ///
322         bool was_text_;
323 };
324
325
326 //
327 // Debugging
328 //
329
330 class NormalStream {
331 public:
332         ///
333         explicit NormalStream(odocstream & os) : os_(os) {}
334         ///
335         odocstream & os() { return os_; }
336 private:
337         ///
338         odocstream & os_;
339 };
340
341 ///
342 NormalStream & operator<<(NormalStream &, MathAtom const &);
343 ///
344 NormalStream & operator<<(NormalStream &, MathData const &);
345 ///
346 NormalStream & operator<<(NormalStream &, docstring const &);
347 ///
348 NormalStream & operator<<(NormalStream &, char const *);
349 ///
350 NormalStream & operator<<(NormalStream &, char);
351 ///
352 NormalStream & operator<<(NormalStream &, int);
353
354
355 //
356 // Maple
357 //
358
359
360 class MapleStream {
361 public:
362         ///
363         explicit MapleStream(odocstream & os) : os_(os) {}
364         ///
365         odocstream & os() { return os_; }
366 private:
367         ///
368         odocstream & os_;
369 };
370
371
372 ///
373 MapleStream & operator<<(MapleStream &, MathAtom const &);
374 ///
375 MapleStream & operator<<(MapleStream &, MathData const &);
376 ///
377 MapleStream & operator<<(MapleStream &, docstring const &);
378 ///
379 MapleStream & operator<<(MapleStream &, char_type);
380 ///
381 MapleStream & operator<<(MapleStream &, char const *);
382 ///
383 MapleStream & operator<<(MapleStream &, char);
384 ///
385 MapleStream & operator<<(MapleStream &, int);
386
387
388 //
389 // Maxima
390 //
391
392
393 class MaximaStream {
394 public:
395         ///
396         explicit MaximaStream(odocstream & os) : os_(os) {}
397         ///
398         odocstream & os() { return os_; }
399 private:
400         ///
401         odocstream & os_;
402 };
403
404
405 ///
406 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
407 ///
408 MaximaStream & operator<<(MaximaStream &, MathData const &);
409 ///
410 MaximaStream & operator<<(MaximaStream &, docstring const &);
411 ///
412 MaximaStream & operator<<(MaximaStream &, char_type);
413 ///
414 MaximaStream & operator<<(MaximaStream &, char const *);
415 ///
416 MaximaStream & operator<<(MaximaStream &, char);
417 ///
418 MaximaStream & operator<<(MaximaStream &, int);
419
420
421 //
422 // Mathematica
423 //
424
425
426 class MathematicaStream {
427 public:
428         ///
429         explicit MathematicaStream(odocstream & os) : os_(os) {}
430         ///
431         odocstream & os() { return os_; }
432 private:
433         ///
434         odocstream & os_;
435 };
436
437
438 ///
439 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
440 ///
441 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
442 ///
443 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
444 ///
445 MathematicaStream & operator<<(MathematicaStream &, char const *);
446 ///
447 MathematicaStream & operator<<(MathematicaStream &, char);
448 ///
449 MathematicaStream & operator<<(MathematicaStream &, int);
450
451
452 //
453 // Octave
454 //
455
456
457 class OctaveStream {
458 public:
459         ///
460         explicit OctaveStream(odocstream & os) : os_(os) {}
461         ///
462         odocstream & os() { return os_; }
463 private:
464         ///
465         odocstream & os_;
466 };
467
468 ///
469 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
470 ///
471 OctaveStream & operator<<(OctaveStream &, MathData const &);
472 ///
473 OctaveStream & operator<<(OctaveStream &, docstring const &);
474 ///
475 OctaveStream & operator<<(OctaveStream &, char_type);
476 ///
477 OctaveStream & operator<<(OctaveStream &, char const *);
478 ///
479 OctaveStream & operator<<(OctaveStream &, char);
480 ///
481 OctaveStream & operator<<(OctaveStream &, int);
482
483 } // namespace lyx
484
485 #endif