]> git.lyx.org Git - features.git/blob - src/mathed/MathStream.h
Remove a MathStream and HtmlStream member which is used nowhere.
[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 "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         enum OutputType {
37                 wsDefault,
38                 wsDryrun,
39                 wsPreview
40         };
41         ///
42         WriteStream(odocstream & os, bool fragile, bool latex, OutputType output,
43                 Encoding const * encoding = 0);
44         ///
45         explicit WriteStream(odocstream & 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         odocstream & os() { return os_; }
58         ///
59         bool & firstitem() { return firstitem_; }
60         ///
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_; }
82         /// LaTeX encoding
83         Encoding const * encoding() const { return encoding_; }
84 private:
85         ///
86         odocstream & os_;
87         /// do we have to write \\protect sometimes
88         bool fragile_;
89         /// are we at the beginning of an MathData?
90         bool firstitem_;
91         /// are we writing to .tex?
92         int latex_;
93         /// output type (default, source preview, instant preview)?
94         OutputType output_;
95         /// do we have a space pending?
96         bool pendingspace_;
97         /// do we have a brace pending?
98         bool pendingbrace_;
99         /// are we in text mode when producing latex code?
100         bool textmode_;
101         /// are we allowed to switch mode when producing latex code?
102         bool locked_;
103         /// should we use only ascii chars when producing latex code?
104         bool ascii_;
105         ///
106         int line_;
107         ///
108         Encoding const * encoding_;
109 };
110
111 ///
112 WriteStream & operator<<(WriteStream &, MathAtom const &);
113 ///
114 WriteStream & operator<<(WriteStream &, MathData const &);
115 ///
116 WriteStream & operator<<(WriteStream &, docstring const &);
117 ///
118 WriteStream & operator<<(WriteStream &, char const * const);
119 ///
120 WriteStream & operator<<(WriteStream &, char);
121 ///
122 WriteStream & operator<<(WriteStream &, int);
123 ///
124 WriteStream & operator<<(WriteStream &, unsigned int);
125
126 /// ensure math mode, possibly by opening \ensuremath
127 bool ensureMath(WriteStream & os, bool needs_math_mode = true, bool macro = false);
128
129 /// ensure the requested mode, possibly by closing \ensuremath
130 int ensureMode(WriteStream & os, InsetMath::mode_type mode, bool locked, bool ascii);
131
132
133 /**
134  * MathEnsurer - utility class for ensuring math mode
135  *
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.
138  *
139  * Example 1:
140  *
141  *      MathEnsurer ensurer(os);
142  *
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.
147  *
148  * Example 2:
149  *
150  *      MathEnsurer ensurer(os, false);
151  *
152  * Simply suspend writing a closing brace until the end of ensurer's scope.
153  *
154  * Example 3:
155  *
156  *      MathEnsurer ensurer(os, needs_math_mode, true);
157  *
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
165  * contrary).
166  */
167 class MathEnsurer
168 {
169 public:
170         ///
171         explicit MathEnsurer(WriteStream & os, bool needs_math_mode = true, bool macro = false)
172                 : os_(os), brace_(ensureMath(os, needs_math_mode, macro)) {}
173         ///
174         ~MathEnsurer() { os_.pendingBrace(brace_); }
175 private:
176         ///
177         WriteStream & os_;
178         ///
179         bool brace_;
180 };
181
182
183 /**
184  * ModeSpecifier - utility class for specifying a given mode (math or text)
185  *
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.
194  * When the mode is locked, the optional fourth parameter specifies whether
195  * strings are to be output by using a suitable ascii representation.
196  *
197  * Example 1:
198  *
199  *      ModeSpecifier specifier(os, TEXT_MODE);
200  *
201  * Sets the current mode to text mode and allows mode switching.
202  *
203  * Example 2:
204  *
205  *      ModeSpecifier specifier(os, TEXT_MODE, true);
206  *
207  * Sets the current mode to text mode and disallows mode switching.
208  *
209  * Example 3:
210  *
211  *      ModeSpecifier specifier(os, TEXT_MODE, true, true);
212  *
213  * Sets the current mode to text mode, disallows mode switching, and outputs
214  * strings as ascii only.
215  *
216  * At the end of specifier's scope the mode is reset to its previous value.
217  */
218 class ModeSpecifier
219 {
220 public:
221         ///
222         explicit ModeSpecifier(WriteStream & os, InsetMath::mode_type mode,
223                                 bool locked = false, bool ascii = false)
224                 : os_(os), oldmodes_(ensureMode(os, mode, locked, ascii)) {}
225         ///
226         ~ModeSpecifier()
227         {
228                 os_.textMode(oldmodes_ & 0x01);
229                 os_.lockedMode(oldmodes_ & 0x02);
230                 os_.asciiOnly(oldmodes_ & 0x04);
231         }
232 private:
233         ///
234         WriteStream & os_;
235         ///
236         int oldmodes_;
237 };
238
239
240
241 //
242 //  MathML
243 //
244
245 class MTag {
246 public:
247         ///
248         MTag(char const * const tag, std::string attr = "") 
249                 : tag_(tag), attr_(attr) {}
250         ///
251         char const * const tag_;
252         ///
253         std::string attr_;
254 };
255
256 class ETag {
257 public:
258         ///
259         ETag(char const * const tag) : tag_(tag) {}
260         ///
261         char const * const tag_;
262 };
263
264
265 /// Throw MathExportException to signal that the attempt to export
266 /// some math in the current format did not succeed. E.g., we can't
267 /// export xymatrix as MathML, so that will throw, and we'll fall back
268 /// to images.
269 class MathExportException : public std::exception {};
270
271
272 class MathStream {
273 public:
274         ///
275         explicit MathStream(odocstream & os);
276         ///
277         void cr();
278         ///
279         odocstream & os() { return os_; }
280         ///
281         int line() const { return line_; }
282         ///
283         int & tab() { return tab_; }
284         ///
285         friend MathStream & operator<<(MathStream &, char const *);
286         ///
287         void defer(docstring const &);
288         ///
289         void defer(std::string const &);
290         ///
291         docstring deferred() const;
292         ///
293         bool inText() const { return in_text_; }
294 private:
295         ///
296         void setTextMode() { in_text_ = true; }
297         ///
298         void setMathMode() { in_text_ = false; }
299         ///
300         odocstream & os_;
301         ///
302         int tab_;
303         ///
304         int line_;
305         ///
306         bool in_text_;
307         ///
308         odocstringstream deferred_;
309         ///
310         friend class SetMode;
311 };
312
313 ///
314 MathStream & operator<<(MathStream &, MathAtom const &);
315 ///
316 MathStream & operator<<(MathStream &, MathData const &);
317 ///
318 MathStream & operator<<(MathStream &, docstring const &);
319 ///
320 MathStream & operator<<(MathStream &, char const *);
321 ///
322 MathStream & operator<<(MathStream &, char);
323 ///
324 MathStream & operator<<(MathStream &, char_type);
325 ///
326 MathStream & operator<<(MathStream &, MTag const &);
327 ///
328 MathStream & operator<<(MathStream &, ETag const &);
329
330
331 /// A simpler version of ModeSpecifier, for MathML
332 // FIXME There are still problems here with nesting, at least
333 // potentially. The problem is that true nesting of text mode isn't
334 // actually possible. I.e., we can't have: 
335 //              <mtext><mtext></mtext></mtext>
336 // So we have to have:
337 //              <mtext></mtext><mtext></mtext><mtext></mtext>
338 // instead, where the last is really a continuation of the first.
339 // We'll need some kind of stack to remember all that.
340 class SetMode {
341 public:
342         ///
343         explicit SetMode(MathStream & os, bool text, std::string const & attrs);
344         ///
345         explicit SetMode(MathStream & os, bool text);
346         ///
347         ~SetMode();
348 private:
349         ///
350         void init(bool, std::string const &);
351         ///
352         MathStream & os_;
353         ///
354         bool opened_;
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() { in_text_ = true; }
385         ///
386         void setMathMode() { in_text_ = false; }
387         ///
388         odocstream & os_;
389         ///
390         int tab_;
391         ///
392         int line_;
393         ///
394         bool in_text_;
395         ///
396         odocstringstream deferred_;
397         ///
398         friend class SetHTMLMode;
399 };
400
401 ///
402 HtmlStream & operator<<(HtmlStream &, MathAtom const &);
403 ///
404 HtmlStream & operator<<(HtmlStream &, MathData const &);
405 ///
406 HtmlStream & operator<<(HtmlStream &, docstring const &);
407 ///
408 HtmlStream & operator<<(HtmlStream &, char const *);
409 ///
410 HtmlStream & operator<<(HtmlStream &, char);
411 ///
412 HtmlStream & operator<<(HtmlStream &, char_type);
413 ///
414 HtmlStream & operator<<(HtmlStream &, MTag const &);
415 ///
416 HtmlStream & operator<<(HtmlStream &, ETag const &);
417
418
419 class SetHTMLMode {
420 public:
421         ///
422         explicit SetHTMLMode(HtmlStream & os, bool text, std::string attrs);
423         ///
424         explicit SetHTMLMode(HtmlStream & os, bool text);
425         ///
426         ~SetHTMLMode();
427 private:
428         ///
429         void init(bool, std::string const &);
430         ///
431         HtmlStream & os_;
432         ///
433         bool opened_;
434         ///
435         bool was_text_;
436 };
437
438
439 //
440 // Debugging
441 //
442
443 class NormalStream {
444 public:
445         ///
446         explicit NormalStream(odocstream & os) : os_(os) {}
447         ///
448         odocstream & os() { return os_; }
449 private:
450         ///
451         odocstream & os_;
452 };
453
454 ///
455 NormalStream & operator<<(NormalStream &, MathAtom const &);
456 ///
457 NormalStream & operator<<(NormalStream &, MathData const &);
458 ///
459 NormalStream & operator<<(NormalStream &, docstring const &);
460 ///
461 NormalStream & operator<<(NormalStream &, char const *);
462 ///
463 NormalStream & operator<<(NormalStream &, char);
464 ///
465 NormalStream & operator<<(NormalStream &, int);
466
467
468 //
469 // Maple
470 //
471
472
473 class MapleStream {
474 public:
475         ///
476         explicit MapleStream(odocstream & os) : os_(os) {}
477         ///
478         odocstream & os() { return os_; }
479 private:
480         ///
481         odocstream & os_;
482 };
483
484
485 ///
486 MapleStream & operator<<(MapleStream &, MathAtom const &);
487 ///
488 MapleStream & operator<<(MapleStream &, MathData const &);
489 ///
490 MapleStream & operator<<(MapleStream &, docstring const &);
491 ///
492 MapleStream & operator<<(MapleStream &, char_type);
493 ///
494 MapleStream & operator<<(MapleStream &, char const *);
495 ///
496 MapleStream & operator<<(MapleStream &, char);
497 ///
498 MapleStream & operator<<(MapleStream &, int);
499
500
501 //
502 // Maxima
503 //
504
505
506 class MaximaStream {
507 public:
508         ///
509         explicit MaximaStream(odocstream & os) : os_(os) {}
510         ///
511         odocstream & os() { return os_; }
512 private:
513         ///
514         odocstream & os_;
515 };
516
517
518 ///
519 MaximaStream & operator<<(MaximaStream &, MathAtom const &);
520 ///
521 MaximaStream & operator<<(MaximaStream &, MathData const &);
522 ///
523 MaximaStream & operator<<(MaximaStream &, docstring const &);
524 ///
525 MaximaStream & operator<<(MaximaStream &, char_type);
526 ///
527 MaximaStream & operator<<(MaximaStream &, char const *);
528 ///
529 MaximaStream & operator<<(MaximaStream &, char);
530 ///
531 MaximaStream & operator<<(MaximaStream &, int);
532
533
534 //
535 // Mathematica
536 //
537
538
539 class MathematicaStream {
540 public:
541         ///
542         explicit MathematicaStream(odocstream & os) : os_(os) {}
543         ///
544         odocstream & os() { return os_; }
545 private:
546         ///
547         odocstream & os_;
548 };
549
550
551 ///
552 MathematicaStream & operator<<(MathematicaStream &, MathAtom const &);
553 ///
554 MathematicaStream & operator<<(MathematicaStream &, MathData const &);
555 ///
556 MathematicaStream & operator<<(MathematicaStream &, docstring const &);
557 ///
558 MathematicaStream & operator<<(MathematicaStream &, char const *);
559 ///
560 MathematicaStream & operator<<(MathematicaStream &, char);
561 ///
562 MathematicaStream & operator<<(MathematicaStream &, int);
563
564
565 //
566 // Octave
567 //
568
569
570 class OctaveStream {
571 public:
572         ///
573         explicit OctaveStream(odocstream & os) : os_(os) {}
574         ///
575         odocstream & os() { return os_; }
576 private:
577         ///
578         odocstream & os_;
579 };
580
581 ///
582 OctaveStream & operator<<(OctaveStream &, MathAtom const &);
583 ///
584 OctaveStream & operator<<(OctaveStream &, MathData const &);
585 ///
586 OctaveStream & operator<<(OctaveStream &, docstring const &);
587 ///
588 OctaveStream & operator<<(OctaveStream &, char_type);
589 ///
590 OctaveStream & operator<<(OctaveStream &, char const *);
591 ///
592 OctaveStream & operator<<(OctaveStream &, char);
593 ///
594 OctaveStream & operator<<(OctaveStream &, int);
595
596 } // namespace lyx
597
598 #endif