]> git.lyx.org Git - lyx.git/blob - src/mathed/MathStream.cpp
7a13955779b6028438f3f6dbc15f2f405d2020d3
[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 = 0;
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           textmode_(false), locked_(0), ascii_(0), canbreakline_(true),
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           textmode_(false), locked_(0), ascii_(0), canbreakline_(true),
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(c != '\n');
228         return ws;
229 }
230
231
232 WriteStream & operator<<(WriteStream & ws, int i)
233 {
234         if (ws.pendingBrace()) {
235                 ws.os() << '}';
236                 ws.pendingBrace(false);
237                 ws.textMode(true);
238         }
239         ws.os() << i;
240         ws.canBreakLine(true);
241         return ws;
242 }
243
244
245 WriteStream & operator<<(WriteStream & ws, unsigned int i)
246 {
247         if (ws.pendingBrace()) {
248                 ws.os() << '}';
249                 ws.pendingBrace(false);
250                 ws.textMode(true);
251         }
252         ws.os() << i;
253         ws.canBreakLine(true);
254         return ws;
255 }
256
257
258 //////////////////////////////////////////////////////////////////////
259
260
261 MathStream::MathStream(odocstream & os)
262         : os_(os), tab_(0), line_(0), in_text_(false)
263 {}
264
265
266 void MathStream::cr()
267 {
268         os() << '\n';
269         for (int i = 0; i < tab(); ++i)
270                 os() << ' ';
271 }
272
273
274 void MathStream::defer(docstring const & s)
275 {
276         deferred_ << s;
277 }
278
279
280 void MathStream::defer(string const & s)
281 {
282         deferred_ << from_utf8(s);
283 }
284
285
286 docstring MathStream::deferred() const
287
288         return deferred_.str();
289 }
290
291
292 MathStream & operator<<(MathStream & ms, MathAtom const & at)
293 {
294         at->mathmlize(ms);
295         return ms;
296 }
297
298
299 MathStream & operator<<(MathStream & ms, MathData const & ar)
300 {
301         mathmlize(ar, ms);
302         return ms;
303 }
304
305
306 MathStream & operator<<(MathStream & ms, char const * s)
307 {
308         ms.os() << s;
309         return ms;
310 }
311
312
313 MathStream & operator<<(MathStream & ms, char c)
314 {
315         ms.os() << c;
316         return ms;
317 }
318
319
320 MathStream & operator<<(MathStream & ms, char_type c)
321 {
322         ms.os().put(c);
323         return ms;
324 }
325
326
327 MathStream & operator<<(MathStream & ms, MTag const & t)
328 {
329         ++ms.tab();
330         ms.cr();
331         ms.os() << '<' << from_ascii(t.tag_);
332         if (!t.attr_.empty())
333                 ms.os() << " " << from_ascii(t.attr_);
334         ms << '>';
335         return ms;
336 }
337
338
339 MathStream & operator<<(MathStream & ms, ETag const & t)
340 {
341         ms.cr();
342         if (ms.tab() > 0)
343                 --ms.tab();
344         ms.os() << "</" << from_ascii(t.tag_) << '>';
345         return ms;
346 }
347
348
349 MathStream & operator<<(MathStream & ms, docstring const & s)
350 {
351         ms.os() << s;
352         return ms;
353 }
354
355
356 //////////////////////////////////////////////////////////////////////
357
358
359 HtmlStream::HtmlStream(odocstream & os)
360         : os_(os), tab_(0), line_(0), in_text_(false)
361 {}
362
363
364 void HtmlStream::defer(docstring const & s)
365 {
366         deferred_ << s;
367 }
368
369
370 void HtmlStream::defer(string const & s)
371 {
372         deferred_ << from_utf8(s);
373 }
374
375
376 docstring HtmlStream::deferred() const
377
378         return deferred_.str();
379 }
380
381
382 HtmlStream & operator<<(HtmlStream & ms, MathAtom const & at)
383 {
384         at->htmlize(ms);
385         return ms;
386 }
387
388
389 HtmlStream & operator<<(HtmlStream & ms, MathData const & ar)
390 {
391         htmlize(ar, ms);
392         return ms;
393 }
394
395
396 HtmlStream & operator<<(HtmlStream & ms, char const * s)
397 {
398         ms.os() << s;
399         return ms;
400 }
401
402
403 HtmlStream & operator<<(HtmlStream & ms, char c)
404 {
405         ms.os() << c;
406         return ms;
407 }
408
409
410 HtmlStream & operator<<(HtmlStream & ms, char_type c)
411 {
412         ms.os().put(c);
413         return ms;
414 }
415
416
417 HtmlStream & operator<<(HtmlStream & ms, MTag const & t)
418 {
419         ms.os() << '<' << from_ascii(t.tag_);
420         if (!t.attr_.empty())
421                 ms.os() << " " << from_ascii(t.attr_);
422         ms << '>';
423         return ms;
424 }
425
426
427 HtmlStream & operator<<(HtmlStream & ms, ETag const & t)
428 {
429         ms.os() << "</" << from_ascii(t.tag_) << '>';
430         return ms;
431 }
432
433
434 HtmlStream & operator<<(HtmlStream & ms, docstring const & s)
435 {
436         ms.os() << s;
437         return ms;
438 }
439
440
441 //////////////////////////////////////////////////////////////////////
442
443
444 SetMode::SetMode(MathStream & os, bool text)
445         : os_(os), opened_(false)
446 {
447         init(text, "");
448 }
449
450
451 SetMode::SetMode(MathStream & os, bool text, string const & attrs)
452         : os_(os), opened_(false)
453 {
454         init(text, attrs);
455 }
456
457
458 void SetMode::init(bool text, string const & attrs)
459 {
460         was_text_ = os_.inText();
461         if (was_text_)
462                 os_ << "</mtext>";
463         if (text) {
464                 os_.setTextMode();
465                 os_ << "<mtext";
466                 if (!attrs.empty())
467                         os_ << " " << from_utf8(attrs);
468                 os_ << ">";
469                 opened_ = true;
470         } else {
471                 if (!attrs.empty()) {
472                         os_ << "<mstyle " << from_utf8(attrs) << ">";
473                         opened_ = true;
474                 }
475                 os_.setMathMode();
476         }
477 }
478
479
480 SetMode::~SetMode()
481 {
482         if (opened_) {
483                 if (os_.inText())
484                         os_ << "</mtext>";
485                 else
486                         os_ << "</mstyle>";
487         }
488         if (was_text_) {
489                 os_.setTextMode();
490                 os_ << "<mtext>";
491         } else {
492                 os_.setMathMode();
493         }
494 }
495
496
497 //////////////////////////////////////////////////////////////////////
498
499
500 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text)
501         : os_(os), opened_(false)
502 {
503         init(text, "");
504 }
505
506
507 SetHTMLMode::SetHTMLMode(HtmlStream & os, bool text, string attrs)
508         : os_(os), opened_(true)
509 {
510         init(text, attrs);
511 }
512
513
514 void SetHTMLMode::init(bool text, string const & attrs)
515 {
516         was_text_ = os_.inText();
517         if (text) {
518                 os_.setTextMode();
519                 if (attrs.empty())
520                         os_ << MTag("span");
521                 else
522                         os_ << MTag("span", attrs);
523                 opened_ = true;
524         } else
525                 os_.setMathMode();
526 }
527
528
529 SetHTMLMode::~SetHTMLMode()
530 {
531         if (opened_)
532                 os_ << ETag("span");
533         if (was_text_)
534                 os_.setTextMode();
535         else
536                 os_.setMathMode();
537 }
538
539
540 //////////////////////////////////////////////////////////////////////
541
542
543 MapleStream & operator<<(MapleStream & ms, MathAtom const & at)
544 {
545         at->maple(ms);
546         return ms;
547 }
548
549
550 MapleStream & operator<<(MapleStream & ms, MathData const & ar)
551 {
552         maple(ar, ms);
553         return ms;
554 }
555
556
557 MapleStream & operator<<(MapleStream & ms, char const * s)
558 {
559         ms.os() << s;
560         return ms;
561 }
562
563
564 MapleStream & operator<<(MapleStream & ms, char c)
565 {
566         ms.os() << c;
567         return ms;
568 }
569
570
571 MapleStream & operator<<(MapleStream & ms, int i)
572 {
573         ms.os() << i;
574         return ms;
575 }
576
577
578 MapleStream & operator<<(MapleStream & ms, char_type c)
579 {
580         ms.os().put(c);
581         return ms;
582 }
583
584
585 MapleStream & operator<<(MapleStream & ms, docstring const & s)
586 {
587         ms.os() << s;
588         return ms;
589 }
590
591
592 //////////////////////////////////////////////////////////////////////
593
594
595 MaximaStream & operator<<(MaximaStream & ms, MathAtom const & at)
596 {
597         at->maxima(ms);
598         return ms;
599 }
600
601
602 MaximaStream & operator<<(MaximaStream & ms, MathData const & ar)
603 {
604         maxima(ar, ms);
605         return ms;
606 }
607
608
609 MaximaStream & operator<<(MaximaStream & ms, char const * s)
610 {
611         ms.os() << s;
612         return ms;
613 }
614
615
616 MaximaStream & operator<<(MaximaStream & ms, char c)
617 {
618         ms.os() << c;
619         return ms;
620 }
621
622
623 MaximaStream & operator<<(MaximaStream & ms, int i)
624 {
625         ms.os() << i;
626         return ms;
627 }
628
629
630 MaximaStream & operator<<(MaximaStream & ms, docstring const & s)
631 {
632         ms.os() << s;
633         return ms;
634 }
635
636
637 MaximaStream & operator<<(MaximaStream & ms, char_type c)
638 {
639         ms.os().put(c);
640         return ms;
641 }
642
643
644 //////////////////////////////////////////////////////////////////////
645
646
647 MathematicaStream & operator<<(MathematicaStream & ms, MathAtom const & at)
648 {
649         at->mathematica(ms);
650         return ms;
651 }
652
653
654 MathematicaStream & operator<<(MathematicaStream & ms, MathData const & ar)
655 {
656         mathematica(ar, ms);
657         return ms;
658 }
659
660
661 MathematicaStream & operator<<(MathematicaStream & ms, char const * s)
662 {
663         ms.os() << s;
664         return ms;
665 }
666
667
668 MathematicaStream & operator<<(MathematicaStream & ms, char c)
669 {
670         ms.os() << c;
671         return ms;
672 }
673
674
675 MathematicaStream & operator<<(MathematicaStream & ms, int i)
676 {
677         ms.os() << i;
678         return ms;
679 }
680
681
682 MathematicaStream & operator<<(MathematicaStream & ms, docstring const & s)
683 {
684         ms.os() << s;
685         return ms;
686 }
687
688
689 MathematicaStream & operator<<(MathematicaStream & ms, char_type c)
690 {
691         ms.os().put(c);
692         return ms;
693 }
694
695
696 //////////////////////////////////////////////////////////////////////
697
698
699 OctaveStream & operator<<(OctaveStream & ns, MathAtom const & at)
700 {
701         at->octave(ns);
702         return ns;
703 }
704
705
706 OctaveStream & operator<<(OctaveStream & ns, MathData const & ar)
707 {
708         octave(ar, ns);
709         return ns;
710 }
711
712
713 OctaveStream & operator<<(OctaveStream & ns, char const * s)
714 {
715         ns.os() << s;
716         return ns;
717 }
718
719
720 OctaveStream & operator<<(OctaveStream & ns, char c)
721 {
722         ns.os() << c;
723         return ns;
724 }
725
726
727 OctaveStream & operator<<(OctaveStream & ns, int i)
728 {
729         ns.os() << i;
730         return ns;
731 }
732
733
734 OctaveStream & operator<<(OctaveStream & ns, docstring const & s)
735 {
736         ns.os() << s;
737         return ns;
738 }
739
740
741 OctaveStream & operator<<(OctaveStream & ns, char_type c)
742 {
743         ns.os().put(c);
744         return ns;
745 }
746
747
748 OctaveStream & operator<<(OctaveStream & os, string const & s)
749 {
750         os.os() << from_utf8(s);
751         return os;
752 }
753
754
755 } // namespace lyx