]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.cpp
8f2534bbb16e2d00a91061b78ccb9841b0dce002
[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.os() << '<' << from_ascii(t.tag_);
413         if (!t.attr_.empty())
414                 ms.os() << " " << from_ascii(t.attr_);
415         ms << '>';
416         return ms;
417 }
418
419
420 HtmlStream & operator<<(HtmlStream & ms, ETag const & t)
421 {
422         ms.os() << "</" << from_ascii(t.tag_) << '>';
423         return ms;
424 }
425
426
427 HtmlStream & operator<<(HtmlStream & ms, docstring const & s)
428 {
429         ms.os() << s;
430         return ms;
431 }
432
433
434 //////////////////////////////////////////////////////////////////////
435
436
437 SetMode::SetMode(MathStream & os, bool text)
438         : os_(os), opened_(false)
439 {
440         init(text, from_ascii(""));
441 }
442
443
444 SetMode::SetMode(MathStream & os, bool text, docstring attrs)
445         : os_(os), opened_(false)
446 {
447         init(text, attrs);
448 }
449
450
451 void SetMode::init(bool text, docstring attrs)
452 {
453         was_text_ = os_.inText();
454         if (was_text_)
455                 os_ << "</mtext>";
456         if (text) {
457                 os_.setTextMode();
458                 os_ << "<mtext";
459                 if (!attrs.empty())
460                         os_ << " " << attrs;
461                 os_ << ">";
462                 opened_ = true;
463         } else {
464                 if (!attrs.empty()) {
465                         os_ << "<mstyle " << attrs << ">";
466                         opened_ = true;
467                 }
468                 os_.setMathMode();
469         }
470 }
471
472
473 SetMode::~SetMode()
474 {
475         if (opened_) {
476                 if (os_.inText())
477                         os_ << "</mtext>";
478                 else
479                         os_ << "</mstyle>";
480         }
481         if (was_text_) {
482                 os_.setTextMode();
483                 os_ << "<mtext>";
484         } else {
485                 os_.setMathMode();
486         }
487 }
488
489
490 //////////////////////////////////////////////////////////////////////
491
492
493 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text)
494         : os_(os), opened_(false)
495 {
496         was_text_ = os_.inText();
497         if (text)
498                 os_.setTextMode();
499         else
500                 os_.setMathMode();
501 }
502
503
504 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text, string attrs)
505         : os_(os), opened_(true)
506 {
507         was_text_ = os_.inText();
508         if (text) {
509                 os_.setTextMode();
510                 os_ << MTag("span", attrs);
511         } else
512                 os_.setMathMode();
513 }
514
515
516 SetHTMLMode::~SetHTMLMode()
517 {
518         if (opened_)
519                 os_ << ETag("span");
520         if (was_text_)
521                 os_.setTextMode();
522         else
523                 os_.setMathMode();
524 }
525
526
527 //////////////////////////////////////////////////////////////////////
528
529
530 MapleStream & operator<<(MapleStream & ms, MathAtom const & at)
531 {
532         at->maple(ms);
533         return ms;
534 }
535
536
537 MapleStream & operator<<(MapleStream & ms, MathData const & ar)
538 {
539         maple(ar, ms);
540         return ms;
541 }
542
543
544 MapleStream & operator<<(MapleStream & ms, char const * s)
545 {
546         ms.os() << s;
547         return ms;
548 }
549
550
551 MapleStream & operator<<(MapleStream & ms, char c)
552 {
553         ms.os() << c;
554         return ms;
555 }
556
557
558 MapleStream & operator<<(MapleStream & ms, int i)
559 {
560         ms.os() << i;
561         return ms;
562 }
563
564
565 MapleStream & operator<<(MapleStream & ms, char_type c)
566 {
567         ms.os().put(c);
568         return ms;
569 }
570
571
572 MapleStream & operator<<(MapleStream & ms, docstring const & s)
573 {
574         ms.os() << s;
575         return ms;
576 }
577
578
579 //////////////////////////////////////////////////////////////////////
580
581
582 MaximaStream & operator<<(MaximaStream & ms, MathAtom const & at)
583 {
584         at->maxima(ms);
585         return ms;
586 }
587
588
589 MaximaStream & operator<<(MaximaStream & ms, MathData const & ar)
590 {
591         maxima(ar, ms);
592         return ms;
593 }
594
595
596 MaximaStream & operator<<(MaximaStream & ms, char const * s)
597 {
598         ms.os() << s;
599         return ms;
600 }
601
602
603 MaximaStream & operator<<(MaximaStream & ms, char c)
604 {
605         ms.os() << c;
606         return ms;
607 }
608
609
610 MaximaStream & operator<<(MaximaStream & ms, int i)
611 {
612         ms.os() << i;
613         return ms;
614 }
615
616
617 MaximaStream & operator<<(MaximaStream & ms, docstring const & s)
618 {
619         ms.os() << s;
620         return ms;
621 }
622
623
624 MaximaStream & operator<<(MaximaStream & ms, char_type c)
625 {
626         ms.os().put(c);
627         return ms;
628 }
629
630
631 //////////////////////////////////////////////////////////////////////
632
633
634 MathematicaStream & operator<<(MathematicaStream & ms, MathAtom const & at)
635 {
636         at->mathematica(ms);
637         return ms;
638 }
639
640
641 MathematicaStream & operator<<(MathematicaStream & ms, MathData const & ar)
642 {
643         mathematica(ar, ms);
644         return ms;
645 }
646
647
648 MathematicaStream & operator<<(MathematicaStream & ms, char const * s)
649 {
650         ms.os() << s;
651         return ms;
652 }
653
654
655 MathematicaStream & operator<<(MathematicaStream & ms, char c)
656 {
657         ms.os() << c;
658         return ms;
659 }
660
661
662 MathematicaStream & operator<<(MathematicaStream & ms, int i)
663 {
664         ms.os() << i;
665         return ms;
666 }
667
668
669 MathematicaStream & operator<<(MathematicaStream & ms, docstring const & s)
670 {
671         ms.os() << s;
672         return ms;
673 }
674
675
676 MathematicaStream & operator<<(MathematicaStream & ms, char_type c)
677 {
678         ms.os().put(c);
679         return ms;
680 }
681
682
683 //////////////////////////////////////////////////////////////////////
684
685
686 OctaveStream & operator<<(OctaveStream & ns, MathAtom const & at)
687 {
688         at->octave(ns);
689         return ns;
690 }
691
692
693 OctaveStream & operator<<(OctaveStream & ns, MathData const & ar)
694 {
695         octave(ar, ns);
696         return ns;
697 }
698
699
700 OctaveStream & operator<<(OctaveStream & ns, char const * s)
701 {
702         ns.os() << s;
703         return ns;
704 }
705
706
707 OctaveStream & operator<<(OctaveStream & ns, char c)
708 {
709         ns.os() << c;
710         return ns;
711 }
712
713
714 OctaveStream & operator<<(OctaveStream & ns, int i)
715 {
716         ns.os() << i;
717         return ns;
718 }
719
720
721 OctaveStream & operator<<(OctaveStream & ns, docstring const & s)
722 {
723         ns.os() << s;
724         return ns;
725 }
726
727
728 OctaveStream & operator<<(OctaveStream & ns, char_type c)
729 {
730         ns.os().put(c);
731         return ns;
732 }
733
734
735 OctaveStream & operator<<(OctaveStream & os, string const & s)
736 {
737         os.os() << from_utf8(s);
738         return os;
739 }
740
741
742 } // namespace lyx