]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.cpp
The beginnings of pure HTML output of math, for our internal XHTML
[lyx.git] / src / mathed / MathStream.cpp
1 /**
2  * \file MathStream.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "MathStream.h"
14
15 #include "MathData.h"
16 #include "MathExtern.h"
17
18 #include "support/textutils.h"
19 #include "support/docstring.h"
20
21 #include <algorithm>
22 #include <cstring>
23 #include <ostream>
24
25 using namespace std;
26
27 namespace lyx {
28
29
30 //////////////////////////////////////////////////////////////////////
31
32
33 NormalStream & operator<<(NormalStream & ns, MathAtom const & at)
34 {
35         at->normalize(ns);
36         return ns;
37 }
38
39
40 NormalStream & operator<<(NormalStream & ns, MathData const & ar)
41 {
42         normalize(ar, ns);
43         return ns;
44 }
45
46
47 NormalStream & operator<<(NormalStream & ns, docstring const & s)
48 {
49         ns.os() << s;
50         return ns;
51 }
52
53
54 NormalStream & operator<<(NormalStream & ns, const string & s)
55 {
56         ns.os() << from_utf8(s);
57         return ns;
58 }
59
60
61 NormalStream & operator<<(NormalStream & ns, char const * s)
62 {
63         ns.os() << s;
64         return ns;
65 }
66
67
68 NormalStream & operator<<(NormalStream & ns, char c)
69 {
70         ns.os() << c;
71         return ns;
72 }
73
74
75 NormalStream & operator<<(NormalStream & ns, int i)
76 {
77         ns.os() << i;
78         return ns;
79 }
80
81
82
83 /////////////////////////////////////////////////////////////////
84
85
86 WriteStream & operator<<(WriteStream & ws, docstring const & s)
87 {
88         if (ws.pendingBrace()) {
89                 ws.os() << '}';
90                 ws.pendingBrace(false);
91                 ws.pendingSpace(false);
92                 ws.textMode(true);
93         } else if (ws.pendingSpace() && s.length() > 0) {
94                 if (isAlphaASCII(s[0]))
95                         ws.os() << ' ';
96                 else if (s[0] == ' ' && ws.textMode())
97                         ws.os() << '\\';
98                 ws.pendingSpace(false);
99         }
100         ws.os() << s;
101         int lf = 0;
102         docstring::const_iterator dit = s.begin();
103         docstring::const_iterator end = s.end();
104         for (; dit != end; ++dit)
105                 if ((*dit) == '\n')
106                         ++lf;
107         ws.addlines(lf);
108         return ws;
109 }
110
111
112 WriteStream::WriteStream(odocstream & os, bool fragile, bool latex, OutputType output,
113                         Encoding const * encoding)
114         : os_(os), fragile_(fragile), firstitem_(false), latex_(latex),
115           output_(output), pendingspace_(false), pendingbrace_(false),
116           textmode_(false), locked_(0), ascii_(0), line_(0), encoding_(encoding)
117 {}
118
119
120 WriteStream::WriteStream(odocstream & os)
121         : os_(os), fragile_(false), firstitem_(false), latex_(false),
122           output_(wsDefault), pendingspace_(false), pendingbrace_(false),
123           textmode_(false), locked_(0), ascii_(0), line_(0), encoding_(0)
124 {}
125
126
127 WriteStream::~WriteStream()
128 {
129         if (pendingbrace_)
130                 os_ << '}';
131         else if (pendingspace_)
132                 os_ << ' ';
133 }
134
135
136 void WriteStream::addlines(unsigned int n)
137 {
138         line_ += n;
139 }
140
141
142 void WriteStream::pendingSpace(bool how)
143 {
144         pendingspace_ = how;
145 }
146
147
148 void WriteStream::pendingBrace(bool brace)
149 {
150         pendingbrace_ = brace;
151 }
152
153
154 void WriteStream::textMode(bool textmode)
155 {
156         textmode_ = textmode;
157 }
158
159
160 void WriteStream::lockedMode(bool locked)
161 {
162         locked_ = locked;
163 }
164
165
166 void WriteStream::asciiOnly(bool ascii)
167 {
168         ascii_ = ascii;
169 }
170
171
172 WriteStream & operator<<(WriteStream & ws, MathAtom const & at)
173 {
174         at->write(ws);
175         return ws;
176 }
177
178
179 WriteStream & operator<<(WriteStream & ws, MathData const & ar)
180 {
181         write(ar, ws);
182         return ws;
183 }
184
185
186 WriteStream & operator<<(WriteStream & ws, char const * s)
187 {
188         if (ws.pendingBrace()) {
189                 ws.os() << '}';
190                 ws.pendingBrace(false);
191                 ws.pendingSpace(false);
192                 ws.textMode(true);
193         } else if (ws.pendingSpace() && strlen(s) > 0) {
194                 if (isAlphaASCII(s[0]))
195                         ws.os() << ' ';
196                 else if (s[0] == ' ' && ws.textMode())
197                         ws.os() << '\\';
198                 ws.pendingSpace(false);
199         }
200         ws.os() << s;
201         ws.addlines(int(count(s, s + strlen(s), '\n')));
202         return ws;
203 }
204
205
206 WriteStream & operator<<(WriteStream & ws, char c)
207 {
208         if (ws.pendingBrace()) {
209                 ws.os() << '}';
210                 ws.pendingBrace(false);
211                 ws.pendingSpace(false);
212                 ws.textMode(true);
213         } else if (ws.pendingSpace()) {
214                 if (isAlphaASCII(c))
215                         ws.os() << ' ';
216                 else if (c == ' ' && ws.textMode())
217                         ws.os() << '\\';
218                 ws.pendingSpace(false);
219         }
220         ws.os() << c;
221         if (c == '\n')
222                 ws.addlines(1);
223         return ws;
224 }
225
226
227 WriteStream & operator<<(WriteStream & ws, int i)
228 {
229         if (ws.pendingBrace()) {
230                 ws.os() << '}';
231                 ws.pendingBrace(false);
232                 ws.textMode(true);
233         }
234         ws.os() << i;
235         return ws;
236 }
237
238
239 WriteStream & operator<<(WriteStream & ws, unsigned int i)
240 {
241         if (ws.pendingBrace()) {
242                 ws.os() << '}';
243                 ws.pendingBrace(false);
244                 ws.textMode(true);
245         }
246         ws.os() << i;
247         return ws;
248 }
249
250
251 //////////////////////////////////////////////////////////////////////
252
253
254 MathStream::MathStream(odocstream & os)
255         : os_(os), tab_(0), line_(0), lastchar_(0), in_text_(false)
256 {}
257
258
259 void MathStream::cr()
260 {
261         os() << '\n';
262         for (int i = 0; i < tab(); ++i)
263                 os() << ' ';
264 }
265
266
267 void MathStream::defer(docstring const & s)
268 {
269         deferred_ << s;
270 }
271
272
273 void MathStream::defer(string const & s)
274 {
275         deferred_ << from_utf8(s);
276 }
277
278
279 docstring MathStream::deferred() const
280
281         return deferred_.str();
282 }
283
284
285 MathStream & operator<<(MathStream & ms, MathAtom const & at)
286 {
287         at->mathmlize(ms);
288         return ms;
289 }
290
291
292 MathStream & operator<<(MathStream & ms, MathData const & ar)
293 {
294         mathmlize(ar, ms);
295         return ms;
296 }
297
298
299 MathStream & operator<<(MathStream & ms, char const * s)
300 {
301         ms.os() << s;
302         return ms;
303 }
304
305
306 MathStream & operator<<(MathStream & ms, char c)
307 {
308         ms.os() << c;
309         return ms;
310 }
311
312
313 MathStream & operator<<(MathStream & ms, char_type c)
314 {
315         ms.os().put(c);
316         return ms;
317 }
318
319
320 MathStream & operator<<(MathStream & ms, MTag const & t)
321 {
322         ++ms.tab();
323         ms.cr();
324         ms.os() << '<' << from_ascii(t.tag_);
325         if (!t.attr_.empty())
326                 ms.os() << " " << from_ascii(t.attr_);
327         ms << '>';
328         return ms;
329 }
330
331
332 MathStream & operator<<(MathStream & ms, ETag const & t)
333 {
334         ms.cr();
335         if (ms.tab() > 0)
336                 --ms.tab();
337         ms.os() << "</" << from_ascii(t.tag_) << '>';
338         return ms;
339 }
340
341
342 MathStream & operator<<(MathStream & ms, docstring const & s)
343 {
344         ms.os() << s;
345         return ms;
346 }
347
348
349 //////////////////////////////////////////////////////////////////////
350
351
352 HtmlStream::HtmlStream(odocstream & os)
353         : os_(os), tab_(0), line_(0), lastchar_(0), in_text_(false)
354 {}
355
356
357 void HtmlStream::defer(docstring const & s)
358 {
359         deferred_ << s;
360 }
361
362
363 void HtmlStream::defer(string const & s)
364 {
365         deferred_ << from_utf8(s);
366 }
367
368
369 docstring HtmlStream::deferred() const
370
371         return deferred_.str();
372 }
373
374
375 HtmlStream & operator<<(HtmlStream & ms, MathAtom const & at)
376 {
377         at->htmlize(ms);
378         return ms;
379 }
380
381
382 HtmlStream & operator<<(HtmlStream & ms, MathData const & ar)
383 {
384         htmlize(ar, ms);
385         return ms;
386 }
387
388
389 HtmlStream & operator<<(HtmlStream & ms, char const * s)
390 {
391         ms.os() << s;
392         return ms;
393 }
394
395
396 HtmlStream & operator<<(HtmlStream & ms, char c)
397 {
398         ms.os() << c;
399         return ms;
400 }
401
402
403 HtmlStream & operator<<(HtmlStream & ms, char_type c)
404 {
405         ms.os().put(c);
406         return ms;
407 }
408
409
410 HtmlStream & operator<<(HtmlStream & ms, MTag const & t)
411 {
412         ++ms.tab();
413         ms.os() << "\n";
414         ms.os() << '<' << from_ascii(t.tag_);
415         if (!t.attr_.empty())
416                 ms.os() << " " << from_ascii(t.attr_);
417         ms << '>';
418         return ms;
419 }
420
421
422 HtmlStream & operator<<(HtmlStream & ms, ETag const & t)
423 {
424         ms.os() << "\n";
425         if (ms.tab() > 0)
426                 --ms.tab();
427         ms.os() << "</" << from_ascii(t.tag_) << '>';
428         return ms;
429 }
430
431
432 HtmlStream & operator<<(HtmlStream & ms, docstring const & s)
433 {
434         ms.os() << s;
435         return ms;
436 }
437
438
439 //////////////////////////////////////////////////////////////////////
440
441
442 SetMode::SetMode(MathStream & os, bool text)
443         : os_(os), opened_(false)
444 {
445         init(text, from_ascii(""));
446 }
447
448
449 SetMode::SetMode(MathStream & os, bool text, docstring attrs)
450         : os_(os), opened_(false)
451 {
452         init(text, attrs);
453 }
454
455
456 void SetMode::init(bool text, docstring attrs)
457 {
458         was_text_ = os_.inText();
459         if (was_text_)
460                 os_ << "</mtext>";
461         if (text) {
462                 os_.setTextMode();
463                 os_ << "<mtext";
464                 if (!attrs.empty())
465                         os_ << " " << attrs;
466                 os_ << ">";
467                 opened_ = true;
468         } else {
469                 if (!attrs.empty()) {
470                         os_ << "<mstyle " << attrs << ">";
471                         opened_ = true;
472                 }
473                 os_.setMathMode();
474         }
475 }
476
477
478 SetMode::~SetMode()
479 {
480         if (opened_) {
481                 if (os_.inText())
482                         os_ << "</mtext>";
483                 else
484                         os_ << "</mstyle>";
485         }
486         if (was_text_) {
487                 os_.setTextMode();
488                 os_ << "<mtext>";
489         } else {
490                 os_.setMathMode();
491         }
492 }
493
494
495 //////////////////////////////////////////////////////////////////////
496
497
498 MapleStream & operator<<(MapleStream & ms, MathAtom const & at)
499 {
500         at->maple(ms);
501         return ms;
502 }
503
504
505 MapleStream & operator<<(MapleStream & ms, MathData const & ar)
506 {
507         maple(ar, ms);
508         return ms;
509 }
510
511
512 MapleStream & operator<<(MapleStream & ms, char const * s)
513 {
514         ms.os() << s;
515         return ms;
516 }
517
518
519 MapleStream & operator<<(MapleStream & ms, char c)
520 {
521         ms.os() << c;
522         return ms;
523 }
524
525
526 MapleStream & operator<<(MapleStream & ms, int i)
527 {
528         ms.os() << i;
529         return ms;
530 }
531
532
533 MapleStream & operator<<(MapleStream & ms, char_type c)
534 {
535         ms.os().put(c);
536         return ms;
537 }
538
539
540 MapleStream & operator<<(MapleStream & ms, docstring const & s)
541 {
542         ms.os() << s;
543         return ms;
544 }
545
546
547 //////////////////////////////////////////////////////////////////////
548
549
550 MaximaStream & operator<<(MaximaStream & ms, MathAtom const & at)
551 {
552         at->maxima(ms);
553         return ms;
554 }
555
556
557 MaximaStream & operator<<(MaximaStream & ms, MathData const & ar)
558 {
559         maxima(ar, ms);
560         return ms;
561 }
562
563
564 MaximaStream & operator<<(MaximaStream & ms, char const * s)
565 {
566         ms.os() << s;
567         return ms;
568 }
569
570
571 MaximaStream & operator<<(MaximaStream & ms, char c)
572 {
573         ms.os() << c;
574         return ms;
575 }
576
577
578 MaximaStream & operator<<(MaximaStream & ms, int i)
579 {
580         ms.os() << i;
581         return ms;
582 }
583
584
585 MaximaStream & operator<<(MaximaStream & ms, docstring const & s)
586 {
587         ms.os() << s;
588         return ms;
589 }
590
591
592 MaximaStream & operator<<(MaximaStream & ms, char_type c)
593 {
594         ms.os().put(c);
595         return ms;
596 }
597
598
599 //////////////////////////////////////////////////////////////////////
600
601
602 MathematicaStream & operator<<(MathematicaStream & ms, MathAtom const & at)
603 {
604         at->mathematica(ms);
605         return ms;
606 }
607
608
609 MathematicaStream & operator<<(MathematicaStream & ms, MathData const & ar)
610 {
611         mathematica(ar, ms);
612         return ms;
613 }
614
615
616 MathematicaStream & operator<<(MathematicaStream & ms, char const * s)
617 {
618         ms.os() << s;
619         return ms;
620 }
621
622
623 MathematicaStream & operator<<(MathematicaStream & ms, char c)
624 {
625         ms.os() << c;
626         return ms;
627 }
628
629
630 MathematicaStream & operator<<(MathematicaStream & ms, int i)
631 {
632         ms.os() << i;
633         return ms;
634 }
635
636
637 MathematicaStream & operator<<(MathematicaStream & ms, docstring const & s)
638 {
639         ms.os() << s;
640         return ms;
641 }
642
643
644 MathematicaStream & operator<<(MathematicaStream & ms, char_type c)
645 {
646         ms.os().put(c);
647         return ms;
648 }
649
650
651 //////////////////////////////////////////////////////////////////////
652
653
654 OctaveStream & operator<<(OctaveStream & ns, MathAtom const & at)
655 {
656         at->octave(ns);
657         return ns;
658 }
659
660
661 OctaveStream & operator<<(OctaveStream & ns, MathData const & ar)
662 {
663         octave(ar, ns);
664         return ns;
665 }
666
667
668 OctaveStream & operator<<(OctaveStream & ns, char const * s)
669 {
670         ns.os() << s;
671         return ns;
672 }
673
674
675 OctaveStream & operator<<(OctaveStream & ns, char c)
676 {
677         ns.os() << c;
678         return ns;
679 }
680
681
682 OctaveStream & operator<<(OctaveStream & ns, int i)
683 {
684         ns.os() << i;
685         return ns;
686 }
687
688
689 OctaveStream & operator<<(OctaveStream & ns, docstring const & s)
690 {
691         ns.os() << s;
692         return ns;
693 }
694
695
696 OctaveStream & operator<<(OctaveStream & ns, char_type c)
697 {
698         ns.os().put(c);
699         return ns;
700 }
701
702
703 OctaveStream & operator<<(OctaveStream & os, string const & s)
704 {
705         os.os() << from_utf8(s);
706         return os;
707 }
708
709
710 } // namespace lyx