]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.cpp
e616cd0e836612438a65d2b34bbc749efe2d8217
[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         // Skip leading '\n' if we had already output a newline char
89         size_t const first =
90                 (s.length() > 0 && (s[0] != '\n' || ws.canBreakLine())) ? 0 : 1;
91
92         // Check whether there's something to output
93         if (s.length() <= first)
94                 return ws;
95
96         if (ws.pendingBrace()) {
97                 ws.os() << '}';
98                 ws.pendingBrace(false);
99                 ws.pendingSpace(false);
100                 ws.textMode(true);
101         } else if (ws.pendingSpace()) {
102                 if (isAlphaASCII(s[first]))
103                         ws.os() << ' ';
104                 else if (s[first] == ' ' && ws.textMode())
105                         ws.os() << '\\';
106                 ws.pendingSpace(false);
107         }
108         ws.os() << s.substr(first);
109         int lf = 0;
110         char_type lastchar;
111         docstring::const_iterator dit = s.begin() + first;
112         docstring::const_iterator end = s.end();
113         for (; dit != end; ++dit) {
114                 lastchar = *dit;
115                 if (lastchar == '\n')
116                         ++lf;
117         }
118         ws.addlines(lf);
119         ws.canBreakLine(lastchar != '\n');
120         return ws;
121 }
122
123
124 WriteStream::WriteStream(odocstream & os, bool fragile, bool latex, OutputType output,
125                         Encoding const * encoding)
126         : os_(os), fragile_(fragile), firstitem_(false), latex_(latex),
127           output_(output), pendingspace_(false), pendingbrace_(false),
128           canbreakline_(true), textmode_(false), locked_(0), ascii_(0),
129           line_(0), encoding_(encoding)
130 {}
131
132
133 WriteStream::WriteStream(odocstream & os)
134         : os_(os), fragile_(false), firstitem_(false), latex_(false),
135           output_(wsDefault), pendingspace_(false), pendingbrace_(false),
136           canbreakline_(true), textmode_(false), locked_(0), ascii_(0),
137           line_(0), encoding_(0)
138 {}
139
140
141 WriteStream::~WriteStream()
142 {
143         if (pendingbrace_)
144                 os_ << '}';
145         else if (pendingspace_)
146                 os_ << ' ';
147 }
148
149
150 void WriteStream::addlines(unsigned int n)
151 {
152         line_ += n;
153 }
154
155
156 void WriteStream::pendingSpace(bool how)
157 {
158         pendingspace_ = how;
159 }
160
161
162 void WriteStream::pendingBrace(bool brace)
163 {
164         pendingbrace_ = brace;
165 }
166
167
168 void WriteStream::textMode(bool textmode)
169 {
170         textmode_ = textmode;
171 }
172
173
174 void WriteStream::lockedMode(bool locked)
175 {
176         locked_ = locked;
177 }
178
179
180 void WriteStream::asciiOnly(bool ascii)
181 {
182         ascii_ = ascii;
183 }
184
185
186 WriteStream & operator<<(WriteStream & ws, MathAtom const & at)
187 {
188         at->write(ws);
189         return ws;
190 }
191
192
193 WriteStream & operator<<(WriteStream & ws, MathData const & ar)
194 {
195         write(ar, ws);
196         return ws;
197 }
198
199
200 WriteStream & operator<<(WriteStream & ws, char const * s)
201 {
202         ws << from_utf8(s);
203         return ws;
204 }
205
206
207 WriteStream & operator<<(WriteStream & ws, char c)
208 {
209         if (c == '\n' && !ws.canBreakLine())
210                 return ws;
211
212         if (ws.pendingBrace()) {
213                 ws.os() << '}';
214                 ws.pendingBrace(false);
215                 ws.pendingSpace(false);
216                 ws.textMode(true);
217         } else if (ws.pendingSpace()) {
218                 if (isAlphaASCII(c))
219                         ws.os() << ' ';
220                 else if (c == ' ' && ws.textMode())
221                         ws.os() << '\\';
222                 ws.pendingSpace(false);
223         }
224         ws.os() << c;
225         if (c == '\n') {
226                 ws.addlines(1);
227                 ws.canBreakLine(false);
228         }
229         return ws;
230 }
231
232
233 WriteStream & operator<<(WriteStream & ws, int i)
234 {
235         if (ws.pendingBrace()) {
236                 ws.os() << '}';
237                 ws.pendingBrace(false);
238                 ws.textMode(true);
239         }
240         ws.os() << i;
241         ws.canBreakLine(true);
242         return ws;
243 }
244
245
246 WriteStream & operator<<(WriteStream & ws, unsigned int i)
247 {
248         if (ws.pendingBrace()) {
249                 ws.os() << '}';
250                 ws.pendingBrace(false);
251                 ws.textMode(true);
252         }
253         ws.os() << i;
254         ws.canBreakLine(true);
255         return ws;
256 }
257
258
259 //////////////////////////////////////////////////////////////////////
260
261
262 MathStream::MathStream(odocstream & os)
263         : os_(os), tab_(0), line_(0), in_text_(false)
264 {}
265
266
267 void MathStream::cr()
268 {
269         os() << '\n';
270         for (int i = 0; i < tab(); ++i)
271                 os() << ' ';
272 }
273
274
275 void MathStream::defer(docstring const & s)
276 {
277         deferred_ << s;
278 }
279
280
281 void MathStream::defer(string const & s)
282 {
283         deferred_ << from_utf8(s);
284 }
285
286
287 docstring MathStream::deferred() const
288
289         return deferred_.str();
290 }
291
292
293 MathStream & operator<<(MathStream & ms, MathAtom const & at)
294 {
295         at->mathmlize(ms);
296         return ms;
297 }
298
299
300 MathStream & operator<<(MathStream & ms, MathData const & ar)
301 {
302         mathmlize(ar, ms);
303         return ms;
304 }
305
306
307 MathStream & operator<<(MathStream & ms, char const * s)
308 {
309         ms.os() << s;
310         return ms;
311 }
312
313
314 MathStream & operator<<(MathStream & ms, char c)
315 {
316         ms.os() << c;
317         return ms;
318 }
319
320
321 MathStream & operator<<(MathStream & ms, char_type c)
322 {
323         ms.os().put(c);
324         return ms;
325 }
326
327
328 MathStream & operator<<(MathStream & ms, MTag const & t)
329 {
330         ++ms.tab();
331         ms.cr();
332         ms.os() << '<' << from_ascii(t.tag_);
333         if (!t.attr_.empty())
334                 ms.os() << " " << from_ascii(t.attr_);
335         ms << '>';
336         return ms;
337 }
338
339
340 MathStream & operator<<(MathStream & ms, ETag const & t)
341 {
342         ms.cr();
343         if (ms.tab() > 0)
344                 --ms.tab();
345         ms.os() << "</" << from_ascii(t.tag_) << '>';
346         return ms;
347 }
348
349
350 MathStream & operator<<(MathStream & ms, docstring const & s)
351 {
352         ms.os() << s;
353         return ms;
354 }
355
356
357 //////////////////////////////////////////////////////////////////////
358
359
360 HtmlStream::HtmlStream(odocstream & os)
361         : os_(os), tab_(0), line_(0), in_text_(false)
362 {}
363
364
365 void HtmlStream::defer(docstring const & s)
366 {
367         deferred_ << s;
368 }
369
370
371 void HtmlStream::defer(string const & s)
372 {
373         deferred_ << from_utf8(s);
374 }
375
376
377 docstring HtmlStream::deferred() const
378
379         return deferred_.str();
380 }
381
382
383 HtmlStream & operator<<(HtmlStream & ms, MathAtom const & at)
384 {
385         at->htmlize(ms);
386         return ms;
387 }
388
389
390 HtmlStream & operator<<(HtmlStream & ms, MathData const & ar)
391 {
392         htmlize(ar, ms);
393         return ms;
394 }
395
396
397 HtmlStream & operator<<(HtmlStream & ms, char const * s)
398 {
399         ms.os() << s;
400         return ms;
401 }
402
403
404 HtmlStream & operator<<(HtmlStream & ms, char c)
405 {
406         ms.os() << c;
407         return ms;
408 }
409
410
411 HtmlStream & operator<<(HtmlStream & ms, char_type c)
412 {
413         ms.os().put(c);
414         return ms;
415 }
416
417
418 HtmlStream & operator<<(HtmlStream & ms, MTag const & t)
419 {
420         ms.os() << '<' << from_ascii(t.tag_);
421         if (!t.attr_.empty())
422                 ms.os() << " " << from_ascii(t.attr_);
423         ms << '>';
424         return ms;
425 }
426
427
428 HtmlStream & operator<<(HtmlStream & ms, ETag const & t)
429 {
430         ms.os() << "</" << from_ascii(t.tag_) << '>';
431         return ms;
432 }
433
434
435 HtmlStream & operator<<(HtmlStream & ms, docstring const & s)
436 {
437         ms.os() << s;
438         return ms;
439 }
440
441
442 //////////////////////////////////////////////////////////////////////
443
444
445 SetMode::SetMode(MathStream & os, bool text)
446         : os_(os), opened_(false)
447 {
448         init(text, "");
449 }
450
451
452 SetMode::SetMode(MathStream & os, bool text, string const & attrs)
453         : os_(os), opened_(false)
454 {
455         init(text, attrs);
456 }
457
458
459 void SetMode::init(bool text, string const & attrs)
460 {
461         was_text_ = os_.inText();
462         if (was_text_)
463                 os_ << "</mtext>";
464         if (text) {
465                 os_.setTextMode();
466                 os_ << "<mtext";
467                 if (!attrs.empty())
468                         os_ << " " << from_utf8(attrs);
469                 os_ << ">";
470                 opened_ = true;
471         } else {
472                 if (!attrs.empty()) {
473                         os_ << "<mstyle " << from_utf8(attrs) << ">";
474                         opened_ = true;
475                 }
476                 os_.setMathMode();
477         }
478 }
479
480
481 SetMode::~SetMode()
482 {
483         if (opened_) {
484                 if (os_.inText())
485                         os_ << "</mtext>";
486                 else
487                         os_ << "</mstyle>";
488         }
489         if (was_text_) {
490                 os_.setTextMode();
491                 os_ << "<mtext>";
492         } else {
493                 os_.setMathMode();
494         }
495 }
496
497
498 //////////////////////////////////////////////////////////////////////
499
500
501 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text)
502         : os_(os), opened_(false)
503 {
504         init(text, "");
505 }
506
507
508 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text, string attrs)
509         : os_(os), opened_(true)
510 {
511         init(text, attrs);
512 }
513
514
515 void SetHTMLMode::init(bool text, string const & attrs)
516 {
517         was_text_ = os_.inText();
518         if (text) {
519                 os_.setTextMode();
520                 if (attrs.empty())
521                         os_ << MTag("span");
522                 else
523                         os_ << MTag("span", attrs);
524                 opened_ = true;
525         } else
526                 os_.setMathMode();
527 }
528
529
530 SetHTMLMode::~SetHTMLMode()
531 {
532         if (opened_)
533                 os_ << ETag("span");
534         if (was_text_)
535                 os_.setTextMode();
536         else
537                 os_.setMathMode();
538 }
539
540
541 //////////////////////////////////////////////////////////////////////
542
543
544 MapleStream & operator<<(MapleStream & ms, MathAtom const & at)
545 {
546         at->maple(ms);
547         return ms;
548 }
549
550
551 MapleStream & operator<<(MapleStream & ms, MathData const & ar)
552 {
553         maple(ar, ms);
554         return ms;
555 }
556
557
558 MapleStream & operator<<(MapleStream & ms, char const * s)
559 {
560         ms.os() << s;
561         return ms;
562 }
563
564
565 MapleStream & operator<<(MapleStream & ms, char c)
566 {
567         ms.os() << c;
568         return ms;
569 }
570
571
572 MapleStream & operator<<(MapleStream & ms, int i)
573 {
574         ms.os() << i;
575         return ms;
576 }
577
578
579 MapleStream & operator<<(MapleStream & ms, char_type c)
580 {
581         ms.os().put(c);
582         return ms;
583 }
584
585
586 MapleStream & operator<<(MapleStream & ms, docstring const & s)
587 {
588         ms.os() << s;
589         return ms;
590 }
591
592
593 //////////////////////////////////////////////////////////////////////
594
595
596 MaximaStream & operator<<(MaximaStream & ms, MathAtom const & at)
597 {
598         at->maxima(ms);
599         return ms;
600 }
601
602
603 MaximaStream & operator<<(MaximaStream & ms, MathData const & ar)
604 {
605         maxima(ar, ms);
606         return ms;
607 }
608
609
610 MaximaStream & operator<<(MaximaStream & ms, char const * s)
611 {
612         ms.os() << s;
613         return ms;
614 }
615
616
617 MaximaStream & operator<<(MaximaStream & ms, char c)
618 {
619         ms.os() << c;
620         return ms;
621 }
622
623
624 MaximaStream & operator<<(MaximaStream & ms, int i)
625 {
626         ms.os() << i;
627         return ms;
628 }
629
630
631 MaximaStream & operator<<(MaximaStream & ms, docstring const & s)
632 {
633         ms.os() << s;
634         return ms;
635 }
636
637
638 MaximaStream & operator<<(MaximaStream & ms, char_type c)
639 {
640         ms.os().put(c);
641         return ms;
642 }
643
644
645 //////////////////////////////////////////////////////////////////////
646
647
648 MathematicaStream & operator<<(MathematicaStream & ms, MathAtom const & at)
649 {
650         at->mathematica(ms);
651         return ms;
652 }
653
654
655 MathematicaStream & operator<<(MathematicaStream & ms, MathData const & ar)
656 {
657         mathematica(ar, ms);
658         return ms;
659 }
660
661
662 MathematicaStream & operator<<(MathematicaStream & ms, char const * s)
663 {
664         ms.os() << s;
665         return ms;
666 }
667
668
669 MathematicaStream & operator<<(MathematicaStream & ms, char c)
670 {
671         ms.os() << c;
672         return ms;
673 }
674
675
676 MathematicaStream & operator<<(MathematicaStream & ms, int i)
677 {
678         ms.os() << i;
679         return ms;
680 }
681
682
683 MathematicaStream & operator<<(MathematicaStream & ms, docstring const & s)
684 {
685         ms.os() << s;
686         return ms;
687 }
688
689
690 MathematicaStream & operator<<(MathematicaStream & ms, char_type c)
691 {
692         ms.os().put(c);
693         return ms;
694 }
695
696
697 //////////////////////////////////////////////////////////////////////
698
699
700 OctaveStream & operator<<(OctaveStream & ns, MathAtom const & at)
701 {
702         at->octave(ns);
703         return ns;
704 }
705
706
707 OctaveStream & operator<<(OctaveStream & ns, MathData const & ar)
708 {
709         octave(ar, ns);
710         return ns;
711 }
712
713
714 OctaveStream & operator<<(OctaveStream & ns, char const * s)
715 {
716         ns.os() << s;
717         return ns;
718 }
719
720
721 OctaveStream & operator<<(OctaveStream & ns, char c)
722 {
723         ns.os() << c;
724         return ns;
725 }
726
727
728 OctaveStream & operator<<(OctaveStream & ns, int i)
729 {
730         ns.os() << i;
731         return ns;
732 }
733
734
735 OctaveStream & operator<<(OctaveStream & ns, docstring const & s)
736 {
737         ns.os() << s;
738         return ns;
739 }
740
741
742 OctaveStream & operator<<(OctaveStream & ns, char_type c)
743 {
744         ns.os().put(c);
745         return ns;
746 }
747
748
749 OctaveStream & operator<<(OctaveStream & os, string const & s)
750 {
751         os.os() << from_utf8(s);
752         return os;
753 }
754
755
756 } // namespace lyx