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