]> git.lyx.org Git - features.git/blob - src/mathed/MathStream.h
Simplify the TexRow information for mathed output
[features.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 "InsetMath.h"
16 #include "texstream.h"
17
18 #include "support/Changer.h"
19 #include "support/strfwd.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(otexrowstream & os, bool fragile, bool latex, OutputType output,
43                                 Encoding const * encoding = 0);
44         ///
45         explicit WriteStream(otexrowstream & 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         otexrowstream & os() { return os_; }
58         ///
59         TexRow & texrow() { return os_.texrow(); }
60         ///
61         bool & firstitem() { return firstitem_; }
62         ///
63         void addlines(unsigned int);
64         /// record whether we can write an immediately following newline char
65         void canBreakLine(bool breakline) { canbreakline_ = breakline; }
66         /// tell whether we can write an immediately following newline char
67         bool canBreakLine() const { return canbreakline_; }
68         /// writes space if next thing is isalpha()
69         void pendingSpace(bool how);
70         /// writes space if next thing is isalpha()
71         bool pendingSpace() const { return pendingspace_; }
72         /// tell whether to write the closing brace of \ensuremath
73         void pendingBrace(bool brace);
74         /// tell whether to write the closing brace of \ensuremath
75         bool pendingBrace() const { return pendingbrace_; }
76         /// tell whether we are in text mode or not when producing latex code
77         void textMode(bool textmode);
78         /// tell whether we are in text mode or not when producing latex code
79         bool textMode() const { return textmode_; }
80         /// tell whether we are allowed to switch mode when producing latex code
81         void lockedMode(bool locked);
82         /// tell whether we are allowed to switch mode when producing latex code
83         bool lockedMode() const { return locked_; }
84         /// tell whether to use only ascii chars when producing latex code
85         void asciiOnly(bool ascii);
86         /// tell whether to use only ascii chars when producing latex code
87         bool asciiOnly() const { return ascii_; }
88         /// LaTeX encoding
89         Encoding const * encoding() const { return encoding_; }
90
91         /// Temporarily change the TexRow information about the outer row entry.
92         Changer changeRowEntry(TexRow::RowEntry entry);
93         /// TexRow::starts the innermost outer math inset
94         /// returns true if the outer row entry will appear at this line
95         bool startOuterRow();
96 private:
97         ///
98         otexrowstream & os_;
99         /// do we have to write \\protect sometimes
100         bool fragile_;
101         /// are we at the beginning of an MathData?
102         bool firstitem_;
103         /// are we writing to .tex?
104         int latex_;
105         /// output type (default, source preview, instant preview)?
106         OutputType output_;
107         /// do we have a space pending?
108         bool pendingspace_;
109         /// do we have a brace pending?
110         bool pendingbrace_;
111         /// are we in text mode when producing latex code?
112         bool textmode_;
113         /// are we allowed to switch mode when producing latex code?
114         bool locked_;
115         /// should we use only ascii chars when producing latex code?
116         bool ascii_;
117         /// are we allowed to output an immediately following newline?
118         bool canbreakline_;
119         ///
120         int line_;
121         ///
122         Encoding const * encoding_;
123         /// Row entry we are in
124         TexRow::RowEntry row_entry_;
125 };
126
127 ///
128 WriteStream & operator<<(WriteStream &, MathAtom const &);
129 ///
130 WriteStream & operator<<(WriteStream &, MathData const &);
131 ///
132 WriteStream & operator<<(WriteStream &, docstring const &);
133 ///
134 WriteStream & operator<<(WriteStream &, char const * const);
135 ///
136 WriteStream & operator<<(WriteStream &, char);
137 ///
138 WriteStream & operator<<(WriteStream &, int);
139 ///
140 WriteStream & operator<<(WriteStream &, unsigned int);
141
142 /// ensure math mode, possibly by opening \ensuremath
143 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
144
145 /// ensure the requested mode, possibly by closing \ensuremath
146 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked, bool ascii);
147
148
149 /**
150  * MathEnsurer - utility class for ensuring math mode
151  *
152  * A local variable of this type can be used to either ensure math mode
153  * or delay the writing of a pending brace when outputting LaTeX.
154  *
155  * Example 1:
156  *
157  *      MathEnsurer ensurer(os);
158  *
159  * If not already in math mode, inserts an \ensuremath command followed
160  * by an open brace. This brace will be automatically closed when exiting
161  * math mode. Math mode is automatically exited when writing something
162  * that doesn't explicitly require math mode.
163  *
164  * Example 2:
165  *
166  *      MathEnsurer ensurer(os, false);
167  *
168  * Simply suspend writing a closing brace until the end of ensurer's scope.
169  *
170  * Example 3:
171  *
172  *      MathEnsurer ensurer(os, needs_math_mode, true);
173  *
174  * The third parameter is set to true only for a user defined macro, which
175  * needs special handling. When it is a MathMacro, the needs_math_mode
176  * parameter is true and the behavior is as in Example 1. When the
177  * needs_math_mode parameter is false (not a MathMacro) and the macro
178  * was entered in a text box and we are in math mode, the mode is reset
179  * to text. This is because the macro was probably designed for text mode
180  * (given that it was entered in text mode and we have no way to tell the
181  * contrary).
182  */
183 class MathEnsurer
184 {
185 public:
186         ///
187         explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
188                 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
189         ///
190         ~MathEnsurer() { os_.pendingBrace(brace_); }
191 private:
192         ///
193         WriteStream & os_;
194         ///
195         bool brace_;
196 };
197
198
199 /**
200  * ModeSpecifier - utility class for specifying a given mode (math or text)
201  *
202  * A local variable of this type can be used to specify that a command or
203  * environment works in a given mode. For example, \mbox works in text
204  * mode, but \boxed works in math mode. Note that no mode changing commands
205  * are needed, but we have to track the current mode, hence this class.
206  * This is only used when exporting to latex and helps determining whether
207  * the mode needs being temporarily switched when a command would not work
208  * in the current mode. As there are cases where this switching is to be
209  * avoided, the optional third parameter can be used to lock the mode.
210  * When the mode is locked, the optional fourth parameter specifies whether
211  * strings are to be output by using a suitable ascii representation.
212  *
213  * Example 1:
214  *
215  *      ModeSpecifier specifier(os, TEXT_MODE);
216  *
217  * Sets the current mode to text mode and allows mode switching.
218  *
219  * Example 2:
220  *
221  *      ModeSpecifier specifier(os, TEXT_MODE, true);
222  *
223  * Sets the current mode to text mode and disallows mode switching.
224  *
225  * Example 3:
226  *
227  *      ModeSpecifier specifier(os, TEXT_MODE, true, true);
228  *
229  * Sets the current mode to text mode, disallows mode switching, and outputs
230  * strings as ascii only.
231  *
232  * At the end of specifier's scope the mode is reset to its previous value.
233  */
234 class ModeSpecifier
235 {
236 public:
237         ///
238         explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
239                                 bool locked = false, bool ascii = false)
240                 : os_(os), oldmodes_(ensureMode(os, mode, locked, ascii)) {}
241         ///
242         ~ModeSpecifier()
243         {
244                 os_.textMode(oldmodes_ & 0x01);
245                 os_.lockedMode(oldmodes_ & 0x02);
246                 os_.asciiOnly(oldmodes_ & 0x04);
247         }
248 private:
249         ///
250         WriteStream & os_;
251         ///
252         int oldmodes_;
253 };
254
255
256
257 //
258 //  MathML
259 //
260
261 class MTag {
262 public:
263         ///
264         MTag(char const * const tag, std::string attr = "") 
265                 : tag_(tag), attr_(attr) {}
266         ///
267         char const * const tag_;
268         ///
269         std::string attr_;
270 };
271
272 class ETag {
273 public:
274         ///
275         ETag(char const * const tag) : tag_(tag) {}
276         ///
277         char const * const tag_;
278 };
279
280
281 /// Throw MathExportException to signal that the attempt to export
282 /// some math in the current format did not succeed. E.g., we can't
283 /// export xymatrix as MathML, so that will throw, and we'll fall back
284 /// to images.
285 class MathExportException : public std::exception {};
286
287
288 class MathStream {
289 public:
290         ///
291         explicit MathStream(odocstream & os);
292         ///
293         void cr();
294         ///
295         odocstream & os() { return os_; }
296         ///
297         int line() const { return line_; }
298         ///
299         int & tab() { return tab_; }
300         ///
301         friend MathStream & operator<<(MathStream &, char const *);
302         ///
303         void defer(docstring const &);
304         ///
305         void defer(std::string const &);
306         ///
307         docstring deferred() const;
308         ///
309         bool inText() const { return in_text_; }
310 private:
311         ///
312         void setTextMode(bool t) { in_text_ = t; }
313         ///
314         odocstream & os_;
315         ///
316         int tab_;
317         ///
318         int line_;
319         ///
320         bool in_text_;
321         ///
322         odocstringstream deferred_;
323         ///
324         friend class SetMode;
325 };
326
327 ///
328 MathStream & operator<<(MathStream &, MathAtom const &);
329 ///
330 MathStream & operator<<(MathStream &, MathData const &);
331 ///
332 MathStream & operator<<(MathStream &, docstring const &);
333 ///
334 MathStream & operator<<(MathStream &, char const *);
335 ///
336 MathStream & operator<<(MathStream &, char);
337 ///
338 MathStream & operator<<(MathStream &, char_type);
339 ///
340 MathStream & operator<<(MathStream &, MTag const &);
341 ///
342 MathStream & operator<<(MathStream &, ETag const &);
343
344
345 /// A simpler version of ModeSpecifier, for MathML
346 class SetMode {
347 public:
348         ///
349         explicit SetMode(MathStream & os, bool text);
350         ///
351         ~SetMode();
352 private:
353         ///
354         MathStream & os_;
355         ///
356         bool was_text_;
357 };
358
359
360 class HtmlStream {
361 public:
362         ///
363         explicit HtmlStream(odocstream & os);
364         ///
365         void cr();
366         ///
367         odocstream & os() { return os_; }
368         ///
369         int line() const { return line_; }
370         ///
371         int & tab() { return tab_; }
372         ///
373         friend HtmlStream & operator<<(HtmlStream &, char const *);
374         ///
375         void defer(docstring const &);
376         ///
377         void defer(std::string const &);
378         ///
379         docstring deferred() const;
380         ///
381         bool inText() const { return in_text_; }
382 private:
383         ///
384         void setTextMode(bool t) { in_text_ = t; }
385         ///
386         odocstream & os_;
387         ///
388         int tab_;
389         ///
390         int line_;
391         ///
392         bool in_text_;
393         ///
394         odocstringstream deferred_;
395         ///
396         friend class SetHTMLMode;
397 };
398
399 ///
400 HtmlStream & operator<<(HtmlStream &, MathAtom const &);
401 ///
402 HtmlStream & operator<<(HtmlStream &, MathData const &);
403 ///
404 HtmlStream & operator<<(HtmlStream &, docstring const &);
405 ///
406 HtmlStream & operator<<(HtmlStream &, char const *);
407 ///
408 HtmlStream & operator<<(HtmlStream &, char);
409 ///
410 HtmlStream & operator<<(HtmlStream &, char_type);
411 ///
412 HtmlStream & operator<<(HtmlStream &, MTag const &);
413 ///
414 HtmlStream & operator<<(HtmlStream &, ETag const &);
415
416
417 class SetHTMLMode {
418 public:
419         ///
420         explicit SetHTMLMode(HtmlStream & os, bool text);
421         ///
422         ~SetHTMLMode();
423 private:
424         ///
425         HtmlStream & os_;
426         ///
427         bool was_text_;
428 };
429
430
431 //
432 // Debugging
433 //
434
435 class NormalStream {
436 public:
437         ///
438         explicit NormalStream(odocstream & os) : os_(os) {}
439         ///
440         odocstream & os() { return os_; }
441 private:
442         ///
443         odocstream & os_;
444 };
445
446 ///
447 NormalStream & operator<<(NormalStream &, MathAtom const &);
448 ///
449 NormalStream & operator<<(NormalStream &, MathData const &);
450 ///
451 NormalStream & operator<<(NormalStream &, docstring const &);
452 ///
453 NormalStream & operator<<(NormalStream &, char const *);
454 ///
455 NormalStream & operator<<(NormalStream &, char);
456 ///
457 NormalStream & operator<<(NormalStream &, int);
458
459
460 //
461 // Maple
462 //
463
464
465 class MapleStream {
466 public:
467         ///
468         explicit MapleStream(odocstream & os) : os_(os) {}
469         ///
470         odocstream & os() { return os_; }
471 private:
472         ///
473         odocstream & os_;
474 };
475
476
477 ///
478 MapleStream & operator<<(MapleStream &, MathAtom const &);
479 ///
480 MapleStream & operator<<(MapleStream &, MathData const &);
481 ///
482 MapleStream & operator<<(MapleStream &, docstring const &);
483 ///
484 MapleStream & operator<<(MapleStream &, char_type);
485 ///
486 MapleStream & operator<<(MapleStream &, char const *);
487 ///
488 MapleStream & operator<<(MapleStream &, char);
489 ///
490 MapleStream & operator<<(MapleStream &, int);
491
492
493 //
494 // Maxima
495 //
496
497
498 class MaximaStream {
499 public:
500         ///
501         explicit MaximaStream(odocstream & os) : os_(os) {}
502         ///
503         odocstream & os() { return os_; }
504 private:
505         ///
506         odocstream & os_;
507 };
508
509
510 ///
511 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
512 ///
513 MaximaStream & operator<<(MaximaStream &, MathData const &);
514 ///
515 MaximaStream & operator<<(MaximaStream &, docstring const &);
516 ///
517 MaximaStream & operator<<(MaximaStream &, char_type);
518 ///
519 MaximaStream & operator<<(MaximaStream &, char const *);
520 ///
521 MaximaStream & operator<<(MaximaStream &, char);
522 ///
523 MaximaStream & operator<<(MaximaStream &, int);
524
525
526 //
527 // Mathematica
528 //
529
530
531 class MathematicaStream {
532 public:
533         ///
534         explicit MathematicaStream(odocstream & os) : os_(os) {}
535         ///
536         odocstream & os() { return os_; }
537 private:
538         ///
539         odocstream & os_;
540 };
541
542
543 ///
544 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
545 ///
546 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
547 ///
548 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
549 ///
550 MathematicaStream & operator<<(MathematicaStream &, char const *);
551 ///
552 MathematicaStream & operator<<(MathematicaStream &, char);
553 ///
554 MathematicaStream & operator<<(MathematicaStream &, int);
555
556
557 //
558 // Octave
559 //
560
561
562 class OctaveStream {
563 public:
564         ///
565         explicit OctaveStream(odocstream & os) : os_(os) {}
566         ///
567         odocstream & os() { return os_; }
568 private:
569         ///
570         odocstream & os_;
571 };
572
573 ///
574 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
575 ///
576 OctaveStream & operator<<(OctaveStream &, MathData const &);
577 ///
578 OctaveStream & operator<<(OctaveStream &, docstring const &);
579 ///
580 OctaveStream & operator<<(OctaveStream &, char_type);
581 ///
582 OctaveStream & operator<<(OctaveStream &, char const *);
583 ///
584 OctaveStream & operator<<(OctaveStream &, char);
585 ///
586 OctaveStream & operator<<(OctaveStream &, int);
587
588 } // namespace lyx
589
590 #endif