]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
6fb8f8265fe18b3b45d8458edfa096876fa19871
[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         /// tell whether to use only ascii chars when producing latex code
79         void asciiOnly(bool ascii);
80         /// tell whether to use only ascii chars when producing latex code
81         bool asciiOnly() const { return ascii_; }
82         /// LaTeX encoding
83         Encoding const * encoding() const { return encoding_; }
84 private:
85         ///
86         odocstream & os_;
87         /// do we have to write \\protect sometimes
88         bool fragile_;
89         /// are we at the beginning of an MathData?
90         bool firstitem_;
91         /// are we writing to .tex?
92         int latex_;
93         /// output type (default, source preview, instant preview)?
94         OutputType output_;
95         /// do we have a space pending?
96         bool pendingspace_;
97         /// do we have a brace pending?
98         bool pendingbrace_;
99         /// are we in text mode when producing latex code?
100         bool textmode_;
101         /// are we allowed to switch mode when producing latex code?
102         bool locked_;
103         /// should we use only ascii chars when producing latex code?
104         bool ascii_;
105         ///
106         int line_;
107         ///
108         Encoding const * encoding_;
109 };
110
111 ///
112 WriteStream & operator<<(WriteStream &, MathAtom const &);
113 ///
114 WriteStream & operator<<(WriteStream &, MathData const &);
115 ///
116 WriteStream & operator<<(WriteStream &, docstring const &);
117 ///
118 WriteStream & operator<<(WriteStream &, char const * const);
119 ///
120 WriteStream & operator<<(WriteStream &, char);
121 ///
122 WriteStream & operator<<(WriteStream &, int);
123 ///
124 WriteStream & operator<<(WriteStream &, unsigned int);
125
126 /// ensure math mode, possibly by opening \ensuremath
127 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
128
129 /// ensure the requested mode, possibly by closing \ensuremath
130 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked, bool ascii);
131
132
133 /**
134  * MathEnsurer - utility class for ensuring math mode
135  *
136  * A local variable of this type can be used to either ensure math mode
137  * or delay the writing of a pending brace when outputting LaTeX.
138  *
139  * Example 1:
140  *
141  *      MathEnsurer ensurer(os);
142  *
143  * If not already in math mode, inserts an \ensuremath command followed
144  * by an open brace. This brace will be automatically closed when exiting
145  * math mode. Math mode is automatically exited when writing something
146  * that doesn't explicitly require math mode.
147  *
148  * Example 2:
149  *
150  *      MathEnsurer ensurer(os, false);
151  *
152  * Simply suspend writing a closing brace until the end of ensurer's scope.
153  *
154  * Example 3:
155  *
156  *      MathEnsurer ensurer(os, needs_math_mode, true);
157  *
158  * The third parameter is set to true only for a user defined macro, which
159  * needs special handling. When it is a MathMacro, the needs_math_mode
160  * parameter is true and the behavior is as in Example 1. When the
161  * needs_math_mode parameter is false (not a MathMacro) and the macro
162  * was entered in a text box and we are in math mode, the mode is reset
163  * to text. This is because the macro was probably designed for text mode
164  * (given that it was entered in text mode and we have no way to tell the
165  * contrary).
166  */
167 class MathEnsurer
168 {
169 public:
170         ///
171         explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
172                 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
173         ///
174         ~MathEnsurer() { os_.pendingBrace(brace_); }
175 private:
176         ///
177         WriteStream & os_;
178         ///
179         bool brace_;
180 };
181
182
183 /**
184  * ModeSpecifier - utility class for specifying a given mode (math or text)
185  *
186  * A local variable of this type can be used to specify that a command or
187  * environment works in a given mode. For example, \mbox works in text
188  * mode, but \boxed works in math mode. Note that no mode changing commands
189  * are needed, but we have to track the current mode, hence this class.
190  * This is only used when exporting to latex and helps determining whether
191  * the mode needs being temporarily switched when a command would not work
192  * in the current mode. As there are cases where this switching is to be
193  * avoided, the optional third parameter can be used to lock the mode.
194  * When the mode is locked, the optional fourth parameter specifies whether
195  * strings are to be output by using a suitable ascii representation.
196  *
197  * Example 1:
198  *
199  *      ModeSpecifier specifier(os, TEXT_MODE);
200  *
201  * Sets the current mode to text mode and allows mode switching.
202  *
203  * Example 2:
204  *
205  *      ModeSpecifier specifier(os, TEXT_MODE, true);
206  *
207  * Sets the current mode to text mode and disallows mode switching.
208  *
209  * Example 3:
210  *
211  *      ModeSpecifier specifier(os, TEXT_MODE, true, true);
212  *
213  * Sets the current mode to text mode, disallows mode switching, and outputs
214  * strings as ascii only.
215  *
216  * At the end of specifier's scope the mode is reset to its previous value.
217  */
218 class ModeSpecifier
219 {
220 public:
221         ///
222         explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
223                                 bool locked = false, bool ascii = false)
224                 : os_(os), oldmodes_(ensureMode(os, mode, locked, ascii)) {}
225         ///
226         ~ModeSpecifier()
227         {
228                 os_.textMode(oldmodes_ & 0x01);
229                 os_.lockedMode(oldmodes_ & 0x02);
230                 os_.asciiOnly(oldmodes_ & 0x04);
231         }
232 private:
233         ///
234         WriteStream & os_;
235         ///
236         int oldmodes_;
237 };
238
239
240
241 //
242 //  MathML
243 //
244
245 class MTag {
246 public:
247         ///
248         MTag(char const * const tag, std::string attr = "") 
249                 : tag_(tag), attr_(attr) {}
250         ///
251         char const * const tag_;
252         ///
253         std::string attr_;
254 };
255
256 class ETag {
257 public:
258         ///
259         ETag(char const * const tag) : tag_(tag) {}
260         ///
261         char const * const tag_;
262 };
263
264
265 class MathStream {
266 public:
267         ///
268         explicit MathStream(odocstream & os);
269         ///
270         void cr();
271         ///
272         odocstream & os() { return os_; }
273         ///
274         int line() const { return line_; }
275         ///
276         int & tab() { return tab_; }
277         ///
278         friend MathStream & operator<<(MathStream &, char const *);
279         ///
280         void defer(docstring const &);
281         ///
282         void defer(std::string const &);
283         ///
284         docstring deferred() const;
285         ///
286         bool inText() const { return in_text_; }
287 private:
288         ///
289         void setTextMode() { in_text_ = true; }
290         ///
291         void setMathMode() { in_text_ = false; }
292         ///
293         odocstream & os_;
294         ///
295         int tab_;
296         ///
297         int line_;
298         ///
299         char lastchar_;
300         ///
301         bool in_text_;
302         ///
303         odocstringstream deferred_;
304         ///
305         friend class SetMode;
306 };
307
308 ///
309 MathStream & operator<<(MathStream &, MathAtom const &);
310 ///
311 MathStream & operator<<(MathStream &, MathData const &);
312 ///
313 MathStream & operator<<(MathStream &, docstring const &);
314 ///
315 MathStream & operator<<(MathStream &, char const *);
316 ///
317 MathStream & operator<<(MathStream &, char);
318 ///
319 MathStream & operator<<(MathStream &, char_type);
320 ///
321 MathStream & operator<<(MathStream &, MTag const &);
322 ///
323 MathStream & operator<<(MathStream &, ETag const &);
324
325
326 /// A simpler version of ModeSpecifier, for MathML
327 // FIXME There are still problems here with nesting, at least
328 // potentially. The problem is that true nesting of text mode isn't
329 // actually possible. I.e., we can't have: 
330 //              <mtext><mtext></mtext></mtext>
331 // So we have to have:
332 //              <mtext></mtext><mtext></mtext><mtext></mtext>
333 // instead, where the last is really a continuation of the first.
334 // We'll need some kind of stack to remember all that.
335 class SetMode {
336 public:
337         ///
338         explicit SetMode(MathStream & os, bool text, docstring attrs);
339         ///
340         explicit SetMode(MathStream & os, bool text);
341         ///
342         ~SetMode();
343 private:
344         ///
345         void init(bool, docstring);
346         ///
347         MathStream & os_;
348         ///
349         bool opened_;
350         ///
351         bool was_text_;
352 };
353
354
355 //
356 // Debugging
357 //
358
359 class NormalStream {
360 public:
361         ///
362         explicit NormalStream(odocstream & os) : os_(os) {}
363         ///
364         odocstream & os() { return os_; }
365 private:
366         ///
367         odocstream & os_;
368 };
369
370 ///
371 NormalStream & operator<<(NormalStream &, MathAtom const &);
372 ///
373 NormalStream & operator<<(NormalStream &, MathData const &);
374 ///
375 NormalStream & operator<<(NormalStream &, docstring const &);
376 ///
377 NormalStream & operator<<(NormalStream &, char const *);
378 ///
379 NormalStream & operator<<(NormalStream &, char);
380 ///
381 NormalStream & operator<<(NormalStream &, int);
382
383
384 //
385 // Maple
386 //
387
388
389 class MapleStream {
390 public:
391         ///
392         explicit MapleStream(odocstream & os) : os_(os) {}
393         ///
394         odocstream & os() { return os_; }
395 private:
396         ///
397         odocstream & os_;
398 };
399
400
401 ///
402 MapleStream & operator<<(MapleStream &, MathAtom const &);
403 ///
404 MapleStream & operator<<(MapleStream &, MathData const &);
405 ///
406 MapleStream & operator<<(MapleStream &, docstring const &);
407 ///
408 MapleStream & operator<<(MapleStream &, char_type);
409 ///
410 MapleStream & operator<<(MapleStream &, char const *);
411 ///
412 MapleStream & operator<<(MapleStream &, char);
413 ///
414 MapleStream & operator<<(MapleStream &, int);
415
416
417 //
418 // Maxima
419 //
420
421
422 class MaximaStream {
423 public:
424         ///
425         explicit MaximaStream(odocstream & os) : os_(os) {}
426         ///
427         odocstream & os() { return os_; }
428 private:
429         ///
430         odocstream & os_;
431 };
432
433
434 ///
435 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
436 ///
437 MaximaStream & operator<<(MaximaStream &, MathData const &);
438 ///
439 MaximaStream & operator<<(MaximaStream &, docstring const &);
440 ///
441 MaximaStream & operator<<(MaximaStream &, char_type);
442 ///
443 MaximaStream & operator<<(MaximaStream &, char const *);
444 ///
445 MaximaStream & operator<<(MaximaStream &, char);
446 ///
447 MaximaStream & operator<<(MaximaStream &, int);
448
449
450 //
451 // Mathematica
452 //
453
454
455 class MathematicaStream {
456 public:
457         ///
458         explicit MathematicaStream(odocstream & os) : os_(os) {}
459         ///
460         odocstream & os() { return os_; }
461 private:
462         ///
463         odocstream & os_;
464 };
465
466
467 ///
468 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
469 ///
470 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
471 ///
472 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
473 ///
474 MathematicaStream & operator<<(MathematicaStream &, char const *);
475 ///
476 MathematicaStream & operator<<(MathematicaStream &, char);
477 ///
478 MathematicaStream & operator<<(MathematicaStream &, int);
479
480
481 //
482 // Octave
483 //
484
485
486 class OctaveStream {
487 public:
488         ///
489         explicit OctaveStream(odocstream & os) : os_(os) {}
490         ///
491         odocstream & os() { return os_; }
492 private:
493         ///
494         odocstream & os_;
495 };
496
497 ///
498 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
499 ///
500 OctaveStream & operator<<(OctaveStream &, MathData const &);
501 ///
502 OctaveStream & operator<<(OctaveStream &, docstring const &);
503 ///
504 OctaveStream & operator<<(OctaveStream &, char_type);
505 ///
506 OctaveStream & operator<<(OctaveStream &, char const *);
507 ///
508 OctaveStream & operator<<(OctaveStream &, char);
509 ///
510 OctaveStream & operator<<(OctaveStream &, int);
511
512 } // namespace lyx
513
514 #endif