]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
Whitespace.
[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 // FIXME There are still problems here with nesting, at least
309 // potentially. The problem is that true nesting of text mode isn't
310 // actually possible. I.e., we can't have: 
311 //              <mtext><mtext></mtext></mtext>
312 // So we have to have:
313 //              <mtext></mtext><mtext></mtext><mtext></mtext>
314 // instead, where the last is really a continuation of the first.
315 // We'll need some kind of stack to remember all that.
316 class SetMode {
317 public:
318         ///
319         explicit SetMode(MathStream & os, bool text, docstring attrs);
320         ///
321         explicit SetMode(MathStream & os, bool text);
322         ///
323         ~SetMode();
324 private:
325         ///
326         void init(bool, docstring);
327         ///
328         MathStream & os_;
329         ///
330         bool opened_;
331         ///
332         bool was_text_;
333 };
334
335
336 //
337 // Debugging
338 //
339
340 class NormalStream {
341 public:
342         ///
343         explicit NormalStream(odocstream & os) : os_(os) {}
344         ///
345         odocstream & os() { return os_; }
346 private:
347         ///
348         odocstream & os_;
349 };
350
351 ///
352 NormalStream & operator<<(NormalStream &, MathAtom const &);
353 ///
354 NormalStream & operator<<(NormalStream &, MathData const &);
355 ///
356 NormalStream & operator<<(NormalStream &, docstring const &);
357 ///
358 NormalStream & operator<<(NormalStream &, char const *);
359 ///
360 NormalStream & operator<<(NormalStream &, char);
361 ///
362 NormalStream & operator<<(NormalStream &, int);
363
364
365 //
366 // Maple
367 //
368
369
370 class MapleStream {
371 public:
372         ///
373         explicit MapleStream(odocstream & os) : os_(os) {}
374         ///
375         odocstream & os() { return os_; }
376 private:
377         ///
378         odocstream & os_;
379 };
380
381
382 ///
383 MapleStream & operator<<(MapleStream &, MathAtom const &);
384 ///
385 MapleStream & operator<<(MapleStream &, MathData const &);
386 ///
387 MapleStream & operator<<(MapleStream &, docstring const &);
388 ///
389 MapleStream & operator<<(MapleStream &, char_type);
390 ///
391 MapleStream & operator<<(MapleStream &, char const *);
392 ///
393 MapleStream & operator<<(MapleStream &, char);
394 ///
395 MapleStream & operator<<(MapleStream &, int);
396
397
398 //
399 // Maxima
400 //
401
402
403 class MaximaStream {
404 public:
405         ///
406         explicit MaximaStream(odocstream & os) : os_(os) {}
407         ///
408         odocstream & os() { return os_; }
409 private:
410         ///
411         odocstream & os_;
412 };
413
414
415 ///
416 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
417 ///
418 MaximaStream & operator<<(MaximaStream &, MathData const &);
419 ///
420 MaximaStream & operator<<(MaximaStream &, docstring const &);
421 ///
422 MaximaStream & operator<<(MaximaStream &, char_type);
423 ///
424 MaximaStream & operator<<(MaximaStream &, char const *);
425 ///
426 MaximaStream & operator<<(MaximaStream &, char);
427 ///
428 MaximaStream & operator<<(MaximaStream &, int);
429
430
431 //
432 // Mathematica
433 //
434
435
436 class MathematicaStream {
437 public:
438         ///
439         explicit MathematicaStream(odocstream & os) : os_(os) {}
440         ///
441         odocstream & os() { return os_; }
442 private:
443         ///
444         odocstream & os_;
445 };
446
447
448 ///
449 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
450 ///
451 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
452 ///
453 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
454 ///
455 MathematicaStream & operator<<(MathematicaStream &, char const *);
456 ///
457 MathematicaStream & operator<<(MathematicaStream &, char);
458 ///
459 MathematicaStream & operator<<(MathematicaStream &, int);
460
461
462 //
463 // Octave
464 //
465
466
467 class OctaveStream {
468 public:
469         ///
470         explicit OctaveStream(odocstream & os) : os_(os) {}
471         ///
472         odocstream & os() { return os_; }
473 private:
474         ///
475         odocstream & os_;
476 };
477
478 ///
479 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
480 ///
481 OctaveStream & operator<<(OctaveStream &, MathData const &);
482 ///
483 OctaveStream & operator<<(OctaveStream &, docstring const &);
484 ///
485 OctaveStream & operator<<(OctaveStream &, char_type);
486 ///
487 OctaveStream & operator<<(OctaveStream &, char const *);
488 ///
489 OctaveStream & operator<<(OctaveStream &, char);
490 ///
491 OctaveStream & operator<<(OctaveStream &, int);
492
493 } // namespace lyx
494
495 #endif