4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
12 #ifndef MATH_MATHMLSTREAM_H
13 #define MATH_MATHMLSTREAM_H
15 #include "support/strfwd.h"
17 #include "InsetMath.h"
18 // FIXME: Move to individual insets
19 #include "MetricsInfo.h"
42 WriteStream(odocstream & os, bool fragile, bool latex, OutputType output,
43 Encoding const * encoding = 0);
45 explicit WriteStream(odocstream & os);
49 int line() const { return line_; }
51 bool fragile() const { return fragile_; }
53 bool latex() const { return latex_; }
55 OutputType output() const { return output_; }
57 odocstream & os() { return os_; }
59 bool & firstitem() { return firstitem_; }
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_; }
83 Encoding const * encoding() const { return encoding_; }
87 /// do we have to write \\protect sometimes
89 /// are we at the beginning of an MathData?
91 /// are we writing to .tex?
93 /// output type (default, source preview, instant preview)?
95 /// do we have a space pending?
97 /// do we have a brace pending?
99 /// are we in text mode when producing latex code?
101 /// are we allowed to switch mode when producing latex code?
103 /// should we use only ascii chars when producing latex code?
108 Encoding const * encoding_;
112 WriteStream & operator<<(WriteStream &, MathAtom const &);
114 WriteStream & operator<<(WriteStream &, MathData const &);
116 WriteStream & operator<<(WriteStream &, docstring const &);
118 WriteStream & operator<<(WriteStream &, char const * const);
120 WriteStream & operator<<(WriteStream &, char);
122 WriteStream & operator<<(WriteStream &, int);
124 WriteStream & operator<<(WriteStream &, unsigned int);
126 /// ensure math mode, possibly by opening \ensuremath
127 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
129 /// ensure the requested mode, possibly by closing \ensuremath
130 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked);
134 * MathEnsurer - utility class for ensuring math mode
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.
141 * MathEnsurer ensurer(os);
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.
150 * MathEnsurer ensurer(os, false);
152 * Simply suspend writing a closing brace until the end of ensurer's scope.
156 * MathEnsurer ensurer(os, needs_math_mode, true);
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
171 explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
172 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
174 ~MathEnsurer() { os_.pendingBrace(brace_); }
184 * ModeSpecifier - utility class for specifying a given mode (math or text)
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.
197 * ModeSpecifier specifier(os, TEXT_MODE);
199 * Sets the current mode to text mode and allows mode switching.
203 * ModeSpecifier specifier(os, TEXT_MODE, true);
205 * Sets the current mode to text mode and disallows mode switching.
207 * At the end of specifier's scope the mode is reset to its previous value.
213 explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
215 : os_(os), oldmodes_(ensureMode(os, mode, locked)) {}
219 os_.textMode(oldmodes_ & 1);
220 os_.lockedMode(oldmodes_ & 2);
238 MTag(char const * const tag, std::string attr = "")
239 : tag_(tag), attr_(attr) {}
241 char const * const tag_;
249 ETag(char const * const tag) : tag_(tag) {}
251 char const * const tag_;
258 explicit MathStream(odocstream & os);
262 odocstream & os() { return os_; }
264 int line() const { return line_; }
266 int & tab() { return tab_; }
268 friend MathStream & operator<<(MathStream &, char const *);
270 void defer(docstring const &);
272 void defer(std::string const &);
274 docstring deferred() const;
276 bool inText() const { return in_text_; }
279 void setTextMode() { in_text_ = true; }
281 void setMathMode() { in_text_ = false; }
293 odocstringstream deferred_;
295 friend class SetMode;
299 MathStream & operator<<(MathStream &, MathAtom const &);
301 MathStream & operator<<(MathStream &, MathData const &);
303 MathStream & operator<<(MathStream &, docstring const &);
305 MathStream & operator<<(MathStream &, char const *);
307 MathStream & operator<<(MathStream &, char);
309 MathStream & operator<<(MathStream &, char_type);
311 MathStream & operator<<(MathStream &, MTag const &);
313 MathStream & operator<<(MathStream &, ETag const &);
316 /// A simpler version of ModeSpecifier, for MathML
317 // FIXME There are still problems here with nesting, at least
318 // potentially. The problem is that true nesting of text mode isn't
319 // actually possible. I.e., we can't have:
320 // <mtext><mtext></mtext></mtext>
321 // So we have to have:
322 // <mtext></mtext><mtext></mtext><mtext></mtext>
323 // instead, where the last is really a continuation of the first.
324 // We'll need some kind of stack to remember all that.
328 explicit SetMode(MathStream & os, bool text, docstring attrs);
330 explicit SetMode(MathStream & os, bool text);
335 void init(bool, docstring);
352 explicit NormalStream(odocstream & os) : os_(os) {}
354 odocstream & os() { return os_; }
361 NormalStream & operator<<(NormalStream &, MathAtom const &);
363 NormalStream & operator<<(NormalStream &, MathData const &);
365 NormalStream & operator<<(NormalStream &, docstring const &);
367 NormalStream & operator<<(NormalStream &, char const *);
369 NormalStream & operator<<(NormalStream &, char);
371 NormalStream & operator<<(NormalStream &, int);
382 explicit MapleStream(odocstream & os) : os_(os) {}
384 odocstream & os() { return os_; }
392 MapleStream & operator<<(MapleStream &, MathAtom const &);
394 MapleStream & operator<<(MapleStream &, MathData const &);
396 MapleStream & operator<<(MapleStream &, docstring const &);
398 MapleStream & operator<<(MapleStream &, char_type);
400 MapleStream & operator<<(MapleStream &, char const *);
402 MapleStream & operator<<(MapleStream &, char);
404 MapleStream & operator<<(MapleStream &, int);
415 explicit MaximaStream(odocstream & os) : os_(os) {}
417 odocstream & os() { return os_; }
425 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
427 MaximaStream & operator<<(MaximaStream &, MathData const &);
429 MaximaStream & operator<<(MaximaStream &, docstring const &);
431 MaximaStream & operator<<(MaximaStream &, char_type);
433 MaximaStream & operator<<(MaximaStream &, char const *);
435 MaximaStream & operator<<(MaximaStream &, char);
437 MaximaStream & operator<<(MaximaStream &, int);
445 class MathematicaStream {
448 explicit MathematicaStream(odocstream & os) : os_(os) {}
450 odocstream & os() { return os_; }
458 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
460 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
462 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
464 MathematicaStream & operator<<(MathematicaStream &, char const *);
466 MathematicaStream & operator<<(MathematicaStream &, char);
468 MathematicaStream & operator<<(MathematicaStream &, int);
479 explicit OctaveStream(odocstream & os) : os_(os) {}
481 odocstream & os() { return os_; }
488 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
490 OctaveStream & operator<<(OctaveStream &, MathData const &);
492 OctaveStream & operator<<(OctaveStream &, docstring const &);
494 OctaveStream & operator<<(OctaveStream &, char_type);
496 OctaveStream & operator<<(OctaveStream &, char const *);
498 OctaveStream & operator<<(OctaveStream &, char);
500 OctaveStream & operator<<(OctaveStream &, int);