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