]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.h
Fix bugs #6047, #4043, and #5394.
[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         WriteStream(odocstream & os, bool fragile, bool latex, bool dryrun,
37                 Encoding const * encoding = 0);
38         ///
39         explicit WriteStream(odocstream & os);
40         ///
41         ~WriteStream();
42         ///
43         int line() const { return line_; }
44         ///
45         bool fragile() const { return fragile_; }
46         ///
47         bool latex() const { return latex_; }
48         ///
49         bool dryrun() const { return dryrun_; }
50         ///
51         odocstream & os() { return os_; }
52         ///
53         bool & firstitem() { return firstitem_; }
54         ///
55         void addlines(unsigned int);
56         /// writes space if next thing is isalpha()
57         void pendingSpace(bool how);
58         /// writes space if next thing is isalpha()
59         bool pendingSpace() const { return pendingspace_; }
60         /// tell whether to write the closing brace of \ensuremath
61         void pendingBrace(bool brace);
62         /// tell whether to write the closing brace of \ensuremath
63         bool pendingBrace() const { return pendingbrace_; }
64         /// tell whether we are in text mode or not when producing latex code
65         void textMode(bool textmode);
66         /// tell whether we are in text mode or not when producing latex code
67         bool textMode() const { return textmode_; }
68         /// tell whether we are allowed to switch mode when producing latex code
69         void lockedMode(bool locked);
70         /// tell whether we are allowed to switch mode when producing latex code
71         bool lockedMode() const { return locked_; }
72         /// LaTeX encoding
73         Encoding const * encoding() const { return encoding_; }
74 private:
75         ///
76         odocstream & os_;
77         /// do we have to write \\protect sometimes
78         bool fragile_;
79         /// are we at the beginning of an MathData?
80         bool firstitem_;
81         /// are we writing to .tex?
82         int latex_;
83         /// is it for preview?
84         bool dryrun_;
85         /// do we have a space pending?
86         bool pendingspace_;
87         /// do we have a brace pending?
88         bool pendingbrace_;
89         /// are we in text mode when producing latex code?
90         bool textmode_;
91         /// are we allowed to switch mode when producing latex code?
92         bool locked_;
93         ///
94         int line_;
95         ///
96         Encoding const * encoding_;
97 };
98
99 ///
100 WriteStream & operator<<(WriteStream &, MathAtom const &);
101 ///
102 WriteStream & operator<<(WriteStream &, MathData const &);
103 ///
104 WriteStream & operator<<(WriteStream &, docstring const &);
105 ///
106 WriteStream & operator<<(WriteStream &, char const * const);
107 ///
108 WriteStream & operator<<(WriteStream &, char);
109 ///
110 WriteStream & operator<<(WriteStream &, int);
111 ///
112 WriteStream & operator<<(WriteStream &, unsigned int);
113
114 /// ensure math mode, possibly by opening \ensuremath
115 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
116
117 /// ensure the requested mode, possibly by closing \ensuremath
118 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked);
119
120
121 /**
122  * MathEnsurer - utility class for ensuring math mode
123  *
124  * A local variable of this type can be used to either ensure math mode
125  * or delay the writing of a pending brace when outputting LaTeX.
126  *
127  * Example 1:
128  *
129  *      MathEnsurer ensurer(os);
130  *
131  * If not already in math mode, inserts an \ensuremath command followed
132  * by an open brace. This brace will be automatically closed when exiting
133  * math mode. Math mode is automatically exited when writing something
134  * that doesn't explicitly require math mode.
135  *
136  * Example 2:
137  *
138  *      MathEnsurer ensurer(os, false);
139  *
140  * Simply suspend writing a closing brace until the end of ensurer's scope.
141  *
142  * Example 3:
143  *
144  *      MathEnsurer ensurer(os, needs_math_mode, true);
145  *
146  * The third parameter is set to true only for a user defined macro, which
147  * needs special handling. When it is a MathMacro, the needs_math_mode
148  * parameter is true and the behavior is as in Example 1. When the
149  * needs_math_mode parameter is false (not a MathMacro) and the macro
150  * was entered in a text box and we are in math mode, the mode is reset
151  * to text. This is because the macro was probably designed for text mode
152  * (given that it was entered in text mode and we have no way to tell the
153  * contrary).
154  */
155 class MathEnsurer
156 {
157 public:
158         ///
159         explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
160                 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
161         ///
162         ~MathEnsurer() { os_.pendingBrace(brace_); }
163 private:
164         ///
165         WriteStream & os_;
166         ///
167         bool brace_;
168 };
169
170
171 /**
172  * ModeSpecifier - utility class for specifying a given mode (math or text)
173  *
174  * A local variable of this type can be used to specify that a command or
175  * environment works in a given mode. For example, \mbox works in text
176  * mode, but \boxed works in math mode. Note that no mode changing commands
177  * are needed, but we have to track the current mode, hence this class.
178  * This is only used when exporting to latex and helps determining whether
179  * the mode needs being temporarily switched when a command would not work
180  * in the current mode. As there are cases where this switching is to be
181  * avoided, the optional third parameter can be used to lock the mode.
182  *
183  * Example 1:
184  *
185  *      ModeSpecifier specifier(os, TEXT_MODE);
186  *
187  * Sets the current mode to text mode and allows mode switching.
188  *
189  * Example 2:
190  *
191  *      ModeSpecifier specifier(os, TEXT_MODE, true);
192  *
193  * Sets the current mode to text mode and disallows mode switching.
194  *
195  * At the end of specifier's scope the mode is reset to its previous value.
196  */
197 class ModeSpecifier
198 {
199 public:
200         ///
201         explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
202                                 bool locked = false)
203                 : os_(os), oldmodes_(ensureMode(os, mode, locked)) {}
204         ///
205         ~ModeSpecifier()
206         {
207                 os_.textMode(oldmodes_ & 1);
208                 os_.lockedMode(oldmodes_ & 2);
209         }
210 private:
211         ///
212         WriteStream & os_;
213         ///
214         int oldmodes_;
215 };
216
217
218
219 //
220 //  MathML
221 //
222
223 class MTag {
224 public:
225         ///
226         MTag(char const * const tag) : tag_(tag) {}
227         ///
228         char const * const tag_;
229 };
230
231 class ETag {
232 public:
233         ///
234         ETag(char const * const tag) : tag_(tag) {}
235         ///
236         char const * const tag_;
237 };
238
239 class MathStream {
240 public:
241         ///
242         explicit MathStream(odocstream & os);
243         ///
244         void cr();
245         ///
246         odocstream & os() { return os_; }
247         ///
248         int line() const { return line_; }
249         ///
250         int & tab() { return tab_; }
251         ///
252         friend MathStream & operator<<(MathStream &, char const *);
253 private:
254         ///
255         odocstream & os_;
256         ///
257         int tab_;
258         ///
259         int line_;
260         ///
261         char lastchar_;
262 };
263
264 ///
265 MathStream & operator<<(MathStream &, MathAtom const &);
266 ///
267 MathStream & operator<<(MathStream &, MathData const &);
268 ///
269 MathStream & operator<<(MathStream &, docstring const &);
270 ///
271 MathStream & operator<<(MathStream &, char const *);
272 ///
273 MathStream & operator<<(MathStream &, char);
274 ///
275 MathStream & operator<<(MathStream &, MTag const &);
276 ///
277 MathStream & operator<<(MathStream &, ETag const &);
278
279
280
281 //
282 // Debugging
283 //
284
285 class NormalStream {
286 public:
287         ///
288         explicit NormalStream(odocstream & os) : os_(os) {}
289         ///
290         odocstream & os() { return os_; }
291 private:
292         ///
293         odocstream & os_;
294 };
295
296 ///
297 NormalStream & operator<<(NormalStream &, MathAtom const &);
298 ///
299 NormalStream & operator<<(NormalStream &, MathData const &);
300 ///
301 NormalStream & operator<<(NormalStream &, docstring const &);
302 ///
303 NormalStream & operator<<(NormalStream &, char const *);
304 ///
305 NormalStream & operator<<(NormalStream &, char);
306 ///
307 NormalStream & operator<<(NormalStream &, int);
308
309
310 //
311 // Maple
312 //
313
314
315 class MapleStream {
316 public:
317         ///
318         explicit MapleStream(odocstream & os) : os_(os) {}
319         ///
320         odocstream & os() { return os_; }
321 private:
322         ///
323         odocstream & os_;
324 };
325
326
327 ///
328 MapleStream & operator<<(MapleStream &, MathAtom const &);
329 ///
330 MapleStream & operator<<(MapleStream &, MathData const &);
331 ///
332 MapleStream & operator<<(MapleStream &, docstring const &);
333 ///
334 MapleStream & operator<<(MapleStream &, char_type);
335 ///
336 MapleStream & operator<<(MapleStream &, char const *);
337 ///
338 MapleStream & operator<<(MapleStream &, char);
339 ///
340 MapleStream & operator<<(MapleStream &, int);
341
342
343 //
344 // Maxima
345 //
346
347
348 class MaximaStream {
349 public:
350         ///
351         explicit MaximaStream(odocstream & os) : os_(os) {}
352         ///
353         odocstream & os() { return os_; }
354 private:
355         ///
356         odocstream & os_;
357 };
358
359
360 ///
361 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
362 ///
363 MaximaStream & operator<<(MaximaStream &, MathData const &);
364 ///
365 MaximaStream & operator<<(MaximaStream &, docstring const &);
366 ///
367 MaximaStream & operator<<(MaximaStream &, char_type);
368 ///
369 MaximaStream & operator<<(MaximaStream &, char const *);
370 ///
371 MaximaStream & operator<<(MaximaStream &, char);
372 ///
373 MaximaStream & operator<<(MaximaStream &, int);
374
375
376 //
377 // Mathematica
378 //
379
380
381 class MathematicaStream {
382 public:
383         ///
384         explicit MathematicaStream(odocstream & os) : os_(os) {}
385         ///
386         odocstream & os() { return os_; }
387 private:
388         ///
389         odocstream & os_;
390 };
391
392
393 ///
394 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
395 ///
396 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
397 ///
398 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
399 ///
400 MathematicaStream & operator<<(MathematicaStream &, char const *);
401 ///
402 MathematicaStream & operator<<(MathematicaStream &, char);
403 ///
404 MathematicaStream & operator<<(MathematicaStream &, int);
405
406
407 //
408 // Octave
409 //
410
411
412 class OctaveStream {
413 public:
414         ///
415         explicit OctaveStream(odocstream & os) : os_(os) {}
416         ///
417         odocstream & os() { return os_; }
418 private:
419         ///
420         odocstream & os_;
421 };
422
423 ///
424 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
425 ///
426 OctaveStream & operator<<(OctaveStream &, MathData const &);
427 ///
428 OctaveStream & operator<<(OctaveStream &, docstring const &);
429 ///
430 OctaveStream & operator<<(OctaveStream &, char_type);
431 ///
432 OctaveStream & operator<<(OctaveStream &, char const *);
433 ///
434 OctaveStream & operator<<(OctaveStream &, char);
435 ///
436 OctaveStream & operator<<(OctaveStream &, int);
437
438 } // namespace lyx
439
440 #endif