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