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