2 * \file MathSupport.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alejandro Aguilar Sierra
9 * Full author contact details are available in file CREDITS.
14 #include "MathSupport.h"
16 #include "InsetMathFont.h"
17 #include "InsetMathSymbol.h"
19 #include "MathParser.h"
20 #include "MathStream.h"
22 #include "frontends/FontLoader.h"
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
26 #include "support/debug.h"
27 #include "support/docstream.h"
28 #include "support/lyxlib.h"
37 using frontend::Painter;
44 Matrix(int, double, double);
46 void transform(double &, double &);
53 Matrix::Matrix(int code, double x, double y)
55 double const cs = (code & 1) ? 0 : (1 - code);
56 double const sn = (code & 1) ? (2 - code) : 0;
64 void Matrix::transform(double & x, double & y)
66 double xx = m_[0][0] * x + m_[0][1] * y;
67 double yy = m_[1][0] * x + m_[1][1] * y;
77 * Internal struct of a drawing: code n x1 y1 ... xn yn, where code is:
78 * 0 = end, 1 = line, 2 = polyline, 3 = square line, 4 = square polyline
82 double const parenthHigh[] = {
84 0.9840, 0.0014, 0.7143, 0.0323, 0.4603, 0.0772,
85 0.2540, 0.1278, 0.1746, 0.1966, 0.0952, 0.3300,
86 0.0950, 0.5000, 0.0952, 0.6700, 0.1746, 0.8034,
87 0.2540, 0.8722, 0.4603, 0.9228, 0.7143, 0.9677,
93 double const parenth[] = {
95 0.9930, 0.0071, 0.7324, 0.0578, 0.5141, 0.1126,
96 0.3380, 0.1714, 0.2183, 0.2333, 0.0634, 0.3621,
97 0.0141, 0.5000, 0.0563, 0.6369, 0.2113, 0.7647,
98 0.3310, 0.8276, 0.5070, 0.8864, 0.7254, 0.9412,
104 double const brace[] = {
106 0.9492, 0.0020, 0.9379, 0.0020, 0.7458, 0.0243,
107 0.5819, 0.0527, 0.4859, 0.0892, 0.4463, 0.1278,
108 0.4463, 0.3732, 0.4011, 0.4199, 0.2712, 0.4615,
109 0.0734, 0.4919, 0.0113, 0.5000, 0.0734, 0.5081,
110 0.2712, 0.5385, 0.4011, 0.5801, 0.4463, 0.6268,
111 0.4463, 0.8722, 0.4859, 0.9108, 0.5819, 0.9473,
112 0.7458, 0.9757, 0.9379, 0.9980, 0.9492, 0.9980,
117 double const mapsto[] = {
119 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
120 1, 0.015, 0.475, 0.945, 0.475,
121 1, 0.015, 0.015, 0.015, 0.985,
126 double const lhook[] = {
128 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
129 1, 0.015, 0.475, 0.7, 0.475,
131 0.7, 0.015, 0.825, 0.15, 0.985, 0.25,
132 0.825, 0.35, 0.7, 0.475,
137 double const rhook[] = {
139 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
140 1, 0.3, 0.475, 0.985, 0.475,
142 0.3, 0.015, 0.175, 0.15, 0.05, 0.25,
143 0.175, 0.35, 0.3, 0.475,
148 double const LRArrow[] = {
150 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
152 0.75, 0.015, 0.95, 0.5, 0.75, 0.985,
153 1, 0.2, 0.8, 0.8, 0.8,
154 1, 0.2, 0.2, 0.8, 0.2,
159 double const LArrow[] = {
161 0.25, 0.015, 0.05, 0.5, 0.25, 0.985,
162 1, 0.2, 0.8, 0.985, 0.8,
163 1, 0.2, 0.2, 0.985, 0.2,
168 double const lharpoondown[] = {
170 0.015, 0.5, 0.25, 0.985,
171 1, 0.02, 0.475, 0.985, 0.475,
176 double const lharpoonup[] = {
178 0.25, 0.015, 0.015, 0.5,
179 1, 0.02, 0.525, 0.985, 0.525,
184 double const lrharpoons[] = {
186 0.25, 0.015, 0.015, 0.225,
187 1, 0.02, 0.23, 0.985, 0.23,
189 0.75, 0.985, 0.985, 0.775,
190 1, 0.02, 0.7, 0.980, 0.7,
195 double const rlharpoons[] = {
197 0.75, 0.015, 0.985, 0.225,
198 1, 0.02, 0.23, 0.985, 0.23,
200 0.25, 0.985, 0.015, 0.775,
201 1, 0.02, 0.7, 0.980, 0.7,
206 double const arrow[] = {
208 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
209 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
211 3, 0.5000, 0.1500, 0.5000, 0.9500,
216 double const Arrow[] = {
218 0.0150, 0.7500, 0.2000, 0.6000, 0.3500, 0.3500,
219 0.5000, 0.0500, 0.6500, 0.3500, 0.8000, 0.6000,
221 3, 0.3500, 0.5000, 0.3500, 0.9500,
222 3, 0.6500, 0.5000, 0.6500, 0.9500,
227 double const udarrow[] = {
229 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
231 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
232 1, 0.5, 0.1, 0.5, 0.9,
237 double const Udarrow[] = {
239 0.015, 0.25, 0.5, 0.05, 0.95, 0.25,
241 0.015, 0.75, 0.5, 0.95, 0.95, 0.75,
242 1, 0.35, 0.2, 0.35, 0.8,
243 1, 0.65, 0.2, 0.65, 0.8,
248 double const brack[] = {
250 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
255 double const dbrack[] = {
257 0.95, 0.05, 0.05, 0.05, 0.05, 0.95, 0.95, 0.95,
259 0.50, 0.05, 0.50, 0.95,
264 double const corner[] = {
266 0.95, 0.05, 0.05, 0.05, 0.05, 0.95,
271 double const angle[] = {
273 1, 0, 0.05, 0.5, 1, 1,
278 double const slash[] = {
279 1, 0.95, 0.05, 0.05, 0.95,
284 double const hline[] = {
285 1, 0.00, 0.5, 1.0, 0.5,
290 double const ddot[] = {
291 1, 0.2, 0.5, 0.3, 0.5,
292 1, 0.7, 0.5, 0.8, 0.5,
297 double const dddot[] = {
298 1, 0.1, 0.5, 0.2, 0.5,
299 1, 0.45, 0.5, 0.55, 0.5,
300 1, 0.8, 0.5, 0.9, 0.5,
305 double const ddddot[] = {
306 1, 0.1, 0.5, 0.2, 0.5,
307 1, 0.45, 0.5, 0.55, 0.5,
308 1, 0.8, 0.5, 0.9, 0.5,
309 1, 1.15, 0.5, 1.25, 0.5,
314 double const hline3[] = {
316 1, 0.475, 0, 0.525, 0,
322 double const dline3[] = {
323 1, 0.1, 0.1, 0.15, 0.15,
324 1, 0.475, 0.475, 0.525, 0.525,
325 1, 0.85, 0.85, 0.9, 0.9,
330 double const hlinesmall[] = {
331 1, 0.4, 0.5, 0.6, 0.5,
336 double const ring[] = {
338 0.5, 0.8, 0.8, 0.5, 0.5, 0.2, 0.2, 0.5, 0.5, 0.8,
343 double const vert[] = {
344 1, 0.5, 0.05, 0.5, 0.95,
349 double const Vert[] = {
350 1, 0.3, 0.05, 0.3, 0.95,
351 1, 0.7, 0.05, 0.7, 0.95,
356 double const tilde[] = {
358 0.00, 0.8, 0.25, 0.2, 0.75, 0.8, 1.00, 0.2,
368 struct named_deco_struct {
374 named_deco_struct deco_table[] = {
376 {"widehat", angle, 3 },
377 {"widetilde", tilde, 0 },
378 {"underbar", hline, 0 },
379 {"underline", hline, 0 },
380 {"overline", hline, 0 },
381 {"underbrace", brace, 1 },
382 {"overbrace", brace, 3 },
383 {"overleftarrow", arrow, 1 },
384 {"overrightarrow", arrow, 3 },
385 {"overleftrightarrow", udarrow, 1 },
386 {"xhookleftarrow", lhook, 0 },
387 {"xhookrightarrow", rhook, 0 },
388 {"xleftarrow", arrow, 1 },
389 {"xLeftarrow", LArrow, 0 },
390 {"xleftharpoondown", lharpoondown, 0 },
391 {"xleftharpoonup", lharpoonup, 0 },
392 {"xleftrightharpoons", lrharpoons, 0 },
393 {"xleftrightarrow", udarrow, 1 },
394 {"xLeftrightarrow", LRArrow, 0 },
395 {"xmapsto", mapsto, 0 },
396 {"xrightarrow", arrow, 3 },
397 {"xRightarrow", LArrow, 2 },
398 {"xrightharpoondown", lharpoonup, 2 },
399 {"xrightharpoonup", lharpoondown, 2 },
400 {"xrightleftharpoons", rlharpoons, 0 },
401 {"underleftarrow", arrow, 1 },
402 {"underrightarrow", arrow, 3 },
403 {"underleftrightarrow", udarrow, 1 },
404 {"undertilde", tilde, 0 },
405 {"utilde", tilde, 0 },
412 {"lbrace", brace, 0 },
413 {"rbrace", brace, 2 },
416 {"llbracket", dbrack, 0 },
417 {"rrbracket", dbrack, 2 },
420 {"slash", slash, 0 },
431 {"backslash", slash, 1 },
432 {"langle", angle, 0 },
433 {"lceil", corner, 0 },
434 {"lfloor", corner, 1 },
435 {"rangle", angle, 2 },
436 {"rceil", corner, 3 },
437 {"rfloor", corner, 2 },
438 {"downarrow", arrow, 2 },
439 {"Downarrow", Arrow, 2 },
440 {"uparrow", arrow, 0 },
441 {"Uparrow", Arrow, 0 },
442 {"updownarrow", udarrow, 0 },
443 {"Updownarrow", Udarrow, 0 },
447 {"dddot", dddot, 0 },
448 {"ddddot", ddddot, 0 },
450 {"grave", slash, 1 },
451 {"acute", slash, 0 },
452 {"tilde", tilde, 0 },
454 {"dot", hlinesmall, 0 },
455 {"check", angle, 1 },
456 {"breve", parenth, 1 },
458 {"mathring", ring, 0 },
461 {"dots", hline3, 0 },
462 {"ldots", hline3, 0 },
463 {"cdots", hline3, 0 },
464 {"vdots", hline3, 1 },
465 {"ddots", dline3, 0 },
466 {"adots", dline3, 1 },
467 {"iddots", dline3, 1 },
468 {"dotsb", hline3, 0 },
469 {"dotsc", hline3, 0 },
470 {"dotsi", hline3, 0 },
471 {"dotsm", hline3, 0 },
472 {"dotso", hline3, 0 }
476 map<docstring, deco_struct> deco_list;
478 // sort the table on startup
479 class init_deco_table {
482 unsigned const n = sizeof(deco_table) / sizeof(deco_table[0]);
483 for (named_deco_struct * p = deco_table; p != deco_table + n; ++p) {
487 deco_list[from_ascii(p->name)] = d;
492 static init_deco_table dummy;
495 deco_struct const * search_deco(docstring const & name)
497 map<docstring, deco_struct>::const_iterator p = deco_list.find(name);
498 return p == deco_list.end() ? 0 : &(p->second);
505 int mathed_font_em(FontInfo const & font)
507 return theFontMetrics(font).em();
510 /* The math units. Quoting TeX by Topic, p.205:
512 * Spacing around mathematical objects is measured in mu units. A mu
513 * is 1/18th part of \fontdimen6 of the font in family 2 in the
514 * current style, the ‘quad’ value of the symbol font.
516 * A \thickmuskip (default value in plain TeX: 5mu plus 5mu) is
517 * inserted around (binary) relations, except where these are preceded
518 * or followed by other relations or punctuation, and except if they
519 * follow an open, or precede a close symbol.
521 * A \medmuskip (default value in plain TeX: 4mu plus 2mu minus 4mu)
522 * is put around binary operators.
524 * A \thinmuskip (default value in plain TeX: 3mu) follows after
525 * punctuation, and is put around inner objects, except where these
526 * are followed by a close or preceded by an open symbol, and except
527 * if the other object is a large operator or a binary relation.
530 int mathed_thinmuskip(FontInfo font)
532 font.setFamily(SYMBOL_FAMILY);
533 return support::iround(3.0 / 18 * theFontMetrics(font).em());
537 int mathed_medmuskip(FontInfo font)
539 font.setFamily(SYMBOL_FAMILY);
540 return support::iround(4.0 / 18 * theFontMetrics(font).em());
544 int mathed_thickmuskip(FontInfo font)
546 font.setFamily(SYMBOL_FAMILY);
547 return support::iround(5.0 / 18 * theFontMetrics(font).em());
551 int mathed_char_width(FontInfo const & font, char_type c)
553 return theFontMetrics(font).width(c);
557 int mathed_char_kerning(FontInfo const & font, char_type c)
559 frontend::FontMetrics const & fm = theFontMetrics(font);
560 return fm.rbearing(c) - fm.width(c);
564 void mathed_string_dim(FontInfo const & font,
568 frontend::FontMetrics const & fm = theFontMetrics(font);
571 for (docstring::const_iterator it = s.begin();
574 dim.asc = max(dim.asc, fm.ascent(*it));
575 dim.des = max(dim.des, fm.descent(*it));
577 dim.wid = fm.width(s);
581 int mathed_string_width(FontInfo const & font, docstring const & s)
583 return theFontMetrics(font).width(s);
587 void mathed_draw_deco(PainterInfo & pi, int x, int y, int w, int h,
588 docstring const & name)
591 pi.pain.line(x + w/2, y, x + w/2, y + h,
592 Color_cursor, Painter::line_onoffdash);
596 deco_struct const * mds = search_deco(name);
598 lyxerr << "Deco was not found. Programming error?" << endl;
599 lyxerr << "name: '" << to_utf8(name) << "'" << endl;
603 int const n = (w < h) ? w : h;
604 int const r = mds->angle;
605 double const * d = mds->data;
607 if (h > 70 && (name == "(" || name == ")"))
611 Matrix sqmt(r, n, n);
619 for (int i = 0; d[i]; ) {
620 int code = int(d[i++]);
621 if (code & 1) { // code == 1 || code == 3
627 sqmt.transform(xx, yy);
629 mt.transform(xx, yy);
630 mt.transform(x2, y2);
632 int(x + xx + 0.5), int(y + yy + 0.5),
633 int(x + x2 + 0.5), int(y + y2 + 0.5),
634 pi.base.font.color());
638 int const n = int(d[i++]);
639 for (int j = 0; j < n; ++j) {
642 // lyxerr << ' ' << xx << ' ' << yy << ' ';
644 sqmt.transform(xx, yy);
646 mt.transform(xx, yy);
647 xp[j] = int(x + xx + 0.5);
648 yp[j] = int(y + yy + 0.5);
649 // lyxerr << "P[" << j ' ' << xx << ' ' << yy << ' ' << x << ' ' << y << ']';
651 pi.pain.lines(xp, yp, n, pi.base.font.color());
657 void metricsStrRedBlack(MetricsInfo & mi, Dimension & dim, docstring const & str)
659 FontInfo font = mi.base.font;
660 augmentFont(font, from_ascii("mathnormal"));
661 mathed_string_dim(font, str, dim);
665 void drawStrRed(PainterInfo & pi, int x, int y, docstring const & str)
667 FontInfo f = pi.base.font;
668 augmentFont(f, from_ascii("mathnormal"));
669 f.setColor(Color_latex);
670 pi.pain.text(x, y, str, f);
674 void drawStrBlack(PainterInfo & pi, int x, int y, docstring const & str)
676 FontInfo f = pi.base.font;
677 augmentFont(f, from_ascii("mathnormal"));
678 f.setColor(Color_foreground);
679 pi.pain.text(x, y, str, f);
683 void math_font_max_dim(FontInfo const & font, int & asc, int & des)
685 frontend::FontMetrics const & fm = theFontMetrics(font);
686 asc = fm.maxAscent();
687 des = fm.maxDescent();
700 FontFamily const inh_family = INHERIT_FAMILY;
701 FontSeries const inh_series = INHERIT_SERIES;
702 FontShape const inh_shape = INHERIT_SHAPE;
705 // mathnormal should be the first, otherwise the fallback further down
707 fontinfo fontinfos[] = {
709 {"mathnormal", ROMAN_FAMILY, MEDIUM_SERIES,
710 ITALIC_SHAPE, Color_math},
711 {"mathbf", inh_family, BOLD_SERIES,
712 inh_shape, Color_math},
713 {"mathcal", CMSY_FAMILY, inh_series,
714 inh_shape, Color_math},
715 {"mathfrak", EUFRAK_FAMILY, inh_series,
716 inh_shape, Color_math},
717 {"mathrm", ROMAN_FAMILY, inh_series,
718 UP_SHAPE, Color_math},
719 {"mathsf", SANS_FAMILY, inh_series,
720 inh_shape, Color_math},
721 {"mathbb", MSB_FAMILY, inh_series,
722 inh_shape, Color_math},
723 {"mathtt", TYPEWRITER_FAMILY, inh_series,
724 inh_shape, Color_math},
725 {"mathit", inh_family, inh_series,
726 ITALIC_SHAPE, Color_math},
727 {"mathscr", RSFS_FAMILY, inh_series,
728 inh_shape, Color_math},
729 {"cmex", CMEX_FAMILY, inh_series,
730 inh_shape, Color_math},
731 {"cmm", CMM_FAMILY, inh_series,
732 inh_shape, Color_math},
733 {"cmr", CMR_FAMILY, inh_series,
734 inh_shape, Color_math},
735 {"cmsy", CMSY_FAMILY, inh_series,
736 inh_shape, Color_math},
737 {"eufrak", EUFRAK_FAMILY, inh_series,
738 inh_shape, Color_math},
739 {"msa", MSA_FAMILY, inh_series,
740 inh_shape, Color_math},
741 {"msb", MSB_FAMILY, inh_series,
742 inh_shape, Color_math},
743 {"stmry", STMARY_FAMILY, inh_series,
744 inh_shape, Color_math},
745 {"wasy", WASY_FAMILY, inh_series,
746 inh_shape, Color_math},
747 {"esint", ESINT_FAMILY, inh_series,
748 inh_shape, Color_math},
751 {"text", inh_family, inh_series,
752 inh_shape, Color_foreground},
753 {"textbf", inh_family, BOLD_SERIES,
754 inh_shape, Color_foreground},
755 {"textit", inh_family, inh_series,
756 ITALIC_SHAPE, Color_foreground},
757 {"textmd", inh_family, MEDIUM_SERIES,
758 inh_shape, Color_foreground},
759 {"textnormal", inh_family, inh_series,
760 UP_SHAPE, Color_foreground},
761 {"textrm", ROMAN_FAMILY,
762 inh_series, UP_SHAPE,Color_foreground},
763 {"textsc", inh_family, inh_series,
764 SMALLCAPS_SHAPE, Color_foreground},
765 {"textsf", SANS_FAMILY, inh_series,
766 inh_shape, Color_foreground},
767 {"textsl", inh_family, inh_series,
768 SLANTED_SHAPE, Color_foreground},
769 {"texttt", TYPEWRITER_FAMILY, inh_series,
770 inh_shape, Color_foreground},
771 {"textup", inh_family, inh_series,
772 UP_SHAPE, Color_foreground},
775 {"textipa", inh_family, inh_series,
776 inh_shape, Color_foreground},
779 {"ce", inh_family, inh_series,
780 inh_shape, Color_foreground},
781 {"cf", inh_family, inh_series,
782 inh_shape, Color_foreground},
784 // LyX internal usage
785 {"lyxtex", inh_family, inh_series,
786 UP_SHAPE, Color_latex},
787 // FIXME: The following two don't work on OS X, since the Symbol font
788 // uses a different encoding, and is therefore disabled in
789 // FontLoader::available().
790 {"lyxsymbol", SYMBOL_FAMILY, inh_series,
791 inh_shape, Color_math},
792 {"lyxboldsymbol", SYMBOL_FAMILY, BOLD_SERIES,
793 inh_shape, Color_math},
794 {"lyxblacktext", ROMAN_FAMILY, MEDIUM_SERIES,
795 UP_SHAPE, Color_foreground},
796 {"lyxnochange", inh_family, inh_series,
797 inh_shape, Color_foreground},
798 {"lyxfakebb", TYPEWRITER_FAMILY, BOLD_SERIES,
799 UP_SHAPE, Color_math},
800 {"lyxfakecal", SANS_FAMILY, MEDIUM_SERIES,
801 ITALIC_SHAPE, Color_math},
802 {"lyxfakefrak", ROMAN_FAMILY, BOLD_SERIES,
803 ITALIC_SHAPE, Color_math}
807 fontinfo * lookupFont(docstring const & name0)
809 //lyxerr << "searching font '" << name << "'" << endl;
810 int const n = sizeof(fontinfos) / sizeof(fontinfo);
811 string name = to_utf8(name0);
812 for (int i = 0; i < n; ++i)
813 if (fontinfos[i].cmd_ == name) {
814 //lyxerr << "found '" << i << "'" << endl;
815 return fontinfos + i;
821 fontinfo * searchFont(docstring const & name)
823 fontinfo * f = lookupFont(name);
824 return f ? f : fontinfos;
825 // this should be mathnormal
826 //return searchFont("mathnormal");
830 bool isFontName(docstring const & name)
832 return lookupFont(name);
836 bool isMathFont(docstring const & name)
838 fontinfo * f = lookupFont(name);
839 return f && f->color_ == Color_math;
843 bool isTextFont(docstring const & name)
845 fontinfo * f = lookupFont(name);
846 return f && f->color_ == Color_foreground;
850 FontInfo getFont(docstring const & name)
853 augmentFont(font, name);
858 void fakeFont(docstring const & orig, docstring const & fake)
860 fontinfo * forig = searchFont(orig);
861 fontinfo * ffake = searchFont(fake);
862 if (forig && ffake) {
863 forig->family_ = ffake->family_;
864 forig->series_ = ffake->series_;
865 forig->shape_ = ffake->shape_;
866 forig->color_ = ffake->color_;
868 lyxerr << "Can't fake font '" << to_utf8(orig) << "' with '"
869 << to_utf8(fake) << "'" << endl;
874 void augmentFont(FontInfo & font, docstring const & name)
876 static bool initialized = false;
879 // fake fonts if necessary
880 if (!theFontLoader().available(getFont(from_ascii("mathfrak"))))
881 fakeFont(from_ascii("mathfrak"), from_ascii("lyxfakefrak"));
882 if (!theFontLoader().available(getFont(from_ascii("mathcal"))))
883 fakeFont(from_ascii("mathcal"), from_ascii("lyxfakecal"));
885 fontinfo * info = searchFont(name);
886 if (info->family_ != inh_family)
887 font.setFamily(info->family_);
888 if (info->series_ != inh_series)
889 font.setSeries(info->series_);
890 if (info->shape_ != inh_shape)
891 font.setShape(info->shape_);
892 if (info->color_ != Color_none)
893 font.setColor(info->color_);
897 bool isAlphaSymbol(MathAtom const & at)
899 if (at->asCharInset() ||
900 (at->asSymbolInset() &&
901 at->asSymbolInset()->isOrdAlpha()))
904 if (at->asFontInset()) {
905 MathData const & ar = at->asFontInset()->cell(0);
906 for (size_t i = 0; i < ar.size(); ++i) {
907 if (!(ar[i]->asCharInset() ||
908 (ar[i]->asSymbolInset() &&
909 ar[i]->asSymbolInset()->isOrdAlpha())))
918 docstring asString(MathData const & ar)
921 TexRow texrow(false);
922 otexrowstream ots(os,texrow);
929 void asArray(docstring const & str, MathData & ar, Parse::flags pf)
931 bool quiet = pf & Parse::QUIET;
932 if ((str.size() == 1 && quiet) || (!mathed_parse_cell(ar, str, pf) && quiet))
933 mathed_parse_cell(ar, str, pf | Parse::VERBATIM);
937 docstring asString(InsetMath const & inset)
940 TexRow texrow(false);
941 otexrowstream ots(os,texrow);
948 docstring asString(MathAtom const & at)
951 TexRow texrow(false);
952 otexrowstream ots(os,texrow);