]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
Fix single character output for MathML. Kind of.
[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 private:
260         ///
261         odocstream & os_;
262         ///
263         int tab_;
264         ///
265         int line_;
266         ///
267         char lastchar_;
268 };
269
270 ///
271 MathStream & operator<<(MathStream &, MathAtom const &);
272 ///
273 MathStream & operator<<(MathStream &, MathData const &);
274 ///
275 MathStream & operator<<(MathStream &, docstring const &);
276 ///
277 MathStream & operator<<(MathStream &, char const *);
278 ///
279 MathStream & operator<<(MathStream &, char);
280 ///
281 MathStream & operator<<(MathStream &, MTag const &);
282 ///
283 MathStream & operator<<(MathStream &, ETag const &);
284
285
286
287 //
288 // Debugging
289 //
290
291 class NormalStream {
292 public:
293         ///
294         explicit NormalStream(odocstream & os) : os_(os) {}
295         ///
296         odocstream & os() { return os_; }
297 private:
298         ///
299         odocstream & os_;
300 };
301
302 ///
303 NormalStream & operator<<(NormalStream &, MathAtom const &);
304 ///
305 NormalStream & operator<<(NormalStream &, MathData const &);
306 ///
307 NormalStream & operator<<(NormalStream &, docstring const &);
308 ///
309 NormalStream & operator<<(NormalStream &, char const *);
310 ///
311 NormalStream & operator<<(NormalStream &, char);
312 ///
313 NormalStream & operator<<(NormalStream &, int);
314
315
316 //
317 // Maple
318 //
319
320
321 class MapleStream {
322 public:
323         ///
324         explicit MapleStream(odocstream & os) : os_(os) {}
325         ///
326         odocstream & os() { return os_; }
327 private:
328         ///
329         odocstream & os_;
330 };
331
332
333 ///
334 MapleStream & operator<<(MapleStream &, MathAtom const &);
335 ///
336 MapleStream & operator<<(MapleStream &, MathData const &);
337 ///
338 MapleStream & operator<<(MapleStream &, docstring const &);
339 ///
340 MapleStream & operator<<(MapleStream &, char_type);
341 ///
342 MapleStream & operator<<(MapleStream &, char const *);
343 ///
344 MapleStream & operator<<(MapleStream &, char);
345 ///
346 MapleStream & operator<<(MapleStream &, int);
347
348
349 //
350 // Maxima
351 //
352
353
354 class MaximaStream {
355 public:
356         ///
357         explicit MaximaStream(odocstream & os) : os_(os) {}
358         ///
359         odocstream & os() { return os_; }
360 private:
361         ///
362         odocstream & os_;
363 };
364
365
366 ///
367 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
368 ///
369 MaximaStream & operator<<(MaximaStream &, MathData const &);
370 ///
371 MaximaStream & operator<<(MaximaStream &, docstring const &);
372 ///
373 MaximaStream & operator<<(MaximaStream &, char_type);
374 ///
375 MaximaStream & operator<<(MaximaStream &, char const *);
376 ///
377 MaximaStream & operator<<(MaximaStream &, char);
378 ///
379 MaximaStream & operator<<(MaximaStream &, int);
380
381
382 //
383 // Mathematica
384 //
385
386
387 class MathematicaStream {
388 public:
389         ///
390         explicit MathematicaStream(odocstream & os) : os_(os) {}
391         ///
392         odocstream & os() { return os_; }
393 private:
394         ///
395         odocstream & os_;
396 };
397
398
399 ///
400 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
401 ///
402 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
403 ///
404 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
405 ///
406 MathematicaStream & operator<<(MathematicaStream &, char const *);
407 ///
408 MathematicaStream & operator<<(MathematicaStream &, char);
409 ///
410 MathematicaStream & operator<<(MathematicaStream &, int);
411
412
413 //
414 // Octave
415 //
416
417
418 class OctaveStream {
419 public:
420         ///
421         explicit OctaveStream(odocstream & os) : os_(os) {}
422         ///
423         odocstream & os() { return os_; }
424 private:
425         ///
426         odocstream & os_;
427 };
428
429 ///
430 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
431 ///
432 OctaveStream & operator<<(OctaveStream &, MathData const &);
433 ///
434 OctaveStream & operator<<(OctaveStream &, docstring const &);
435 ///
436 OctaveStream & operator<<(OctaveStream &, char_type);
437 ///
438 OctaveStream & operator<<(OctaveStream &, char const *);
439 ///
440 OctaveStream & operator<<(OctaveStream &, char);
441 ///
442 OctaveStream & operator<<(OctaveStream &, int);
443
444 } // namespace lyx
445
446 #endif