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 "InsetMath.h"
16 #include "texstream.h"
18 #include "support/Changer.h"
19 #include "support/strfwd.h"
20 #include "support/unique_ptr.h"
44 explicit WriteStream(otexrowstream & os, bool fragile = false,
45 bool latex = false, OutputType output = wsDefault,
46 Encoding const * encoding = 0);
50 int line() const { return line_; }
52 bool fragile() const { return fragile_; }
54 bool latex() const { return latex_; }
56 OutputType output() const { return output_; }
58 otexrowstream & os() { return os_; }
60 TexRow & texrow() { return os_.texrow(); }
62 bool & firstitem() { return firstitem_; }
64 void addlines(unsigned int);
65 /// record whether we can write an immediately following newline char
66 void canBreakLine(bool breakline) { canbreakline_ = breakline; }
67 /// tell whether we can write an immediately following newline char
68 bool canBreakLine() const { return canbreakline_; }
69 /// writes space if next thing is isalpha()
70 void pendingSpace(bool how);
71 /// writes space if next thing is isalpha()
72 bool pendingSpace() const { return pendingspace_; }
73 /// tell whether to write the closing brace of \ensuremath
74 void pendingBrace(bool brace);
75 /// tell whether to write the closing brace of \ensuremath
76 bool pendingBrace() const { return pendingbrace_; }
77 /// tell whether we are in text mode or not when producing latex code
78 void textMode(bool textmode);
79 /// tell whether we are in text mode or not when producing latex code
80 bool textMode() const { return textmode_; }
81 /// tell whether we are allowed to switch mode when producing latex code
82 void lockedMode(bool locked);
83 /// tell whether we are allowed to switch mode when producing latex code
84 bool lockedMode() const { return locked_; }
85 /// tell whether to use only ascii chars when producing latex code
86 void asciiOnly(bool ascii);
87 /// tell whether to use only ascii chars when producing latex code
88 bool asciiOnly() const { return ascii_; }
90 Encoding const * encoding() const { return encoding_; }
92 /// Temporarily change the TexRow information about the outer row entry.
93 Changer changeRowEntry(RowEntry entry);
94 /// TexRow::starts the innermost outer math inset
95 /// returns true if the outer row entry will appear at this line
100 /// do we have to write \\protect sometimes
102 /// are we at the beginning of an MathData?
104 /// are we writing to .tex?
106 /// output type (default, source preview, instant preview)?
108 /// do we have a space pending?
110 /// do we have a brace pending?
112 /// are we in text mode when producing latex code?
114 /// are we allowed to switch mode when producing latex code?
116 /// should we use only ascii chars when producing latex code?
118 /// are we allowed to output an immediately following newline?
123 Encoding const * encoding_;
124 /// Row entry we are in
125 /// (it is a pointer to allow forward-declaration)
126 unique_ptr<RowEntry> row_entry_;
130 WriteStream & operator<<(WriteStream &, MathAtom const &);
132 WriteStream & operator<<(WriteStream &, MathData const &);
134 WriteStream & operator<<(WriteStream &, docstring const &);
136 WriteStream & operator<<(WriteStream &, char const * const);
138 WriteStream & operator<<(WriteStream &, char);
140 WriteStream & operator<<(WriteStream &, int);
142 WriteStream & operator<<(WriteStream &, unsigned int);
144 /// ensure math mode, possibly by opening \ensuremath
145 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
147 /// ensure the requested mode, possibly by closing \ensuremath
148 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked, bool ascii);
152 * MathEnsurer - utility class for ensuring math mode
154 * A local variable of this type can be used to either ensure math mode
155 * or delay the writing of a pending brace when outputting LaTeX.
159 * MathEnsurer ensurer(os);
161 * If not already in math mode, inserts an \ensuremath command followed
162 * by an open brace. This brace will be automatically closed when exiting
163 * math mode. Math mode is automatically exited when writing something
164 * that doesn't explicitly require math mode.
168 * MathEnsurer ensurer(os, false);
170 * Simply suspend writing a closing brace until the end of ensurer's scope.
174 * MathEnsurer ensurer(os, needs_math_mode, true);
176 * The third parameter is set to true only for a user defined macro, which
177 * needs special handling. When it is a MathMacro, the needs_math_mode
178 * parameter is true and the behavior is as in Example 1. When the
179 * needs_math_mode parameter is false (not a MathMacro) and the macro
180 * was entered in a text box and we are in math mode, the mode is reset
181 * to text. This is because the macro was probably designed for text mode
182 * (given that it was entered in text mode and we have no way to tell the
189 explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
190 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
192 ~MathEnsurer() { os_.pendingBrace(brace_); }
202 * ModeSpecifier - utility class for specifying a given mode (math or text)
204 * A local variable of this type can be used to specify that a command or
205 * environment works in a given mode. For example, \mbox works in text
206 * mode, but \boxed works in math mode. Note that no mode changing commands
207 * are needed, but we have to track the current mode, hence this class.
208 * This is only used when exporting to latex and helps determining whether
209 * the mode needs being temporarily switched when a command would not work
210 * in the current mode. As there are cases where this switching is to be
211 * avoided, the optional third parameter can be used to lock the mode.
212 * When the mode is locked, the optional fourth parameter specifies whether
213 * strings are to be output by using a suitable ascii representation.
217 * ModeSpecifier specifier(os, TEXT_MODE);
219 * Sets the current mode to text mode and allows mode switching.
223 * ModeSpecifier specifier(os, TEXT_MODE, true);
225 * Sets the current mode to text mode and disallows mode switching.
229 * ModeSpecifier specifier(os, TEXT_MODE, true, true);
231 * Sets the current mode to text mode, disallows mode switching, and outputs
232 * strings as ascii only.
234 * At the end of specifier's scope the mode is reset to its previous value.
240 explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
241 bool locked = false, bool ascii = false)
242 : os_(os), oldmodes_(ensureMode(os, mode, locked, ascii)) {}
246 os_.textMode(oldmodes_ & 0x01);
247 os_.lockedMode(oldmodes_ & 0x02);
248 os_.asciiOnly(oldmodes_ & 0x04);
266 MTag(char const * const tag, std::string attr = "")
267 : tag_(tag), attr_(attr) {}
269 char const * const tag_;
277 ETag(char const * const tag) : tag_(tag) {}
279 char const * const tag_;
283 /// Throw MathExportException to signal that the attempt to export
284 /// some math in the current format did not succeed. E.g., we can't
285 /// export xymatrix as MathML, so that will throw, and we'll fall back
287 class MathExportException : public std::exception {};
293 explicit MathStream(odocstream & os);
297 odocstream & os() { return os_; }
299 int line() const { return line_; }
301 int & tab() { return tab_; }
303 friend MathStream & operator<<(MathStream &, char const *);
305 void defer(docstring const &);
307 void defer(std::string const &);
309 docstring deferred() const;
311 bool inText() const { return in_text_; }
314 void setTextMode(bool t) { in_text_ = t; }
324 odocstringstream deferred_;
326 friend class SetMode;
330 MathStream & operator<<(MathStream &, MathAtom const &);
332 MathStream & operator<<(MathStream &, MathData const &);
334 MathStream & operator<<(MathStream &, docstring const &);
336 MathStream & operator<<(MathStream &, char const *);
338 MathStream & operator<<(MathStream &, char);
340 MathStream & operator<<(MathStream &, char_type);
342 MathStream & operator<<(MathStream &, MTag const &);
344 MathStream & operator<<(MathStream &, ETag const &);
347 /// A simpler version of ModeSpecifier, for MathML
351 explicit SetMode(MathStream & os, bool text);
365 explicit HtmlStream(odocstream & os);
369 odocstream & os() { return os_; }
371 int line() const { return line_; }
373 int & tab() { return tab_; }
375 friend HtmlStream & operator<<(HtmlStream &, char const *);
377 void defer(docstring const &);
379 void defer(std::string const &);
381 docstring deferred() const;
383 bool inText() const { return in_text_; }
386 void setTextMode(bool t) { in_text_ = t; }
396 odocstringstream deferred_;
398 friend class SetHTMLMode;
402 HtmlStream & operator<<(HtmlStream &, MathAtom const &);
404 HtmlStream & operator<<(HtmlStream &, MathData const &);
406 HtmlStream & operator<<(HtmlStream &, docstring const &);
408 HtmlStream & operator<<(HtmlStream &, char const *);
410 HtmlStream & operator<<(HtmlStream &, char);
412 HtmlStream & operator<<(HtmlStream &, char_type);
414 HtmlStream & operator<<(HtmlStream &, MTag const &);
416 HtmlStream & operator<<(HtmlStream &, ETag const &);
422 explicit SetHTMLMode(HtmlStream & os, bool text);
440 explicit NormalStream(odocstream & os) : os_(os) {}
442 odocstream & os() { return os_; }
449 NormalStream & operator<<(NormalStream &, MathAtom const &);
451 NormalStream & operator<<(NormalStream &, MathData const &);
453 NormalStream & operator<<(NormalStream &, docstring const &);
455 NormalStream & operator<<(NormalStream &, char const *);
457 NormalStream & operator<<(NormalStream &, char);
459 NormalStream & operator<<(NormalStream &, int);
470 explicit MapleStream(odocstream & os) : os_(os) {}
472 odocstream & os() { return os_; }
480 MapleStream & operator<<(MapleStream &, MathAtom const &);
482 MapleStream & operator<<(MapleStream &, MathData const &);
484 MapleStream & operator<<(MapleStream &, docstring const &);
486 MapleStream & operator<<(MapleStream &, char_type);
488 MapleStream & operator<<(MapleStream &, char const *);
490 MapleStream & operator<<(MapleStream &, char);
492 MapleStream & operator<<(MapleStream &, int);
503 explicit MaximaStream(odocstream & os) : os_(os) {}
505 odocstream & os() { return os_; }
513 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
515 MaximaStream & operator<<(MaximaStream &, MathData const &);
517 MaximaStream & operator<<(MaximaStream &, docstring const &);
519 MaximaStream & operator<<(MaximaStream &, char_type);
521 MaximaStream & operator<<(MaximaStream &, char const *);
523 MaximaStream & operator<<(MaximaStream &, char);
525 MaximaStream & operator<<(MaximaStream &, int);
533 class MathematicaStream {
536 explicit MathematicaStream(odocstream & os) : os_(os) {}
538 odocstream & os() { return os_; }
546 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
548 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
550 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
552 MathematicaStream & operator<<(MathematicaStream &, char const *);
554 MathematicaStream & operator<<(MathematicaStream &, char);
556 MathematicaStream & operator<<(MathematicaStream &, int);
567 explicit OctaveStream(odocstream & os) : os_(os) {}
569 odocstream & os() { return os_; }
576 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
578 OctaveStream & operator<<(OctaveStream &, MathData const &);
580 OctaveStream & operator<<(OctaveStream &, docstring const &);
582 OctaveStream & operator<<(OctaveStream &, char_type);
584 OctaveStream & operator<<(OctaveStream &, char const *);
586 OctaveStream & operator<<(OctaveStream &, char);
588 OctaveStream & operator<<(OctaveStream &, int);
591 docstring convertDelimToXMLEscape(docstring const & name);