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