2 * \file InsetMathDelim.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 "InsetMathDelim.h"
17 #include "MathFactory.h"
18 #include "MathStream.h"
19 #include "MathSupport.h"
20 #include "MetricsInfo.h"
22 #include "LaTeXFeatures.h"
24 #include "support/docstring.h"
26 #include "frontends/FontMetrics.h"
34 static docstring convertDelimToLatexName(docstring const & name)
36 if (name.size() == 1) {
37 char_type const c = name[0];
38 if (c == '<' || c == '(' || c == '[' || c == '.'
39 || c == '>' || c == ')' || c == ']' || c == '/' || c == '|')
42 return '\\' + name + ' ';
46 InsetMathDelim::InsetMathDelim(Buffer * buf, docstring const & l,
48 : InsetMathNest(buf, 1), left_(l), right_(r), dw_(0), is_extracted_(false)
52 InsetMathDelim::InsetMathDelim(Buffer * buf, docstring const & l, docstring const & r,
54 : InsetMathNest(buf, 1), left_(l), right_(r), dw_(0), is_extracted_(false)
60 InsetMathDelim::InsetMathDelim(Buffer * buf, docstring const & l, docstring const & r,
61 MathData const & ar, bool const is_extracted)
62 : InsetMathNest(buf, 1), left_(l), right_(r), dw_(0), is_extracted_(is_extracted)
68 Inset * InsetMathDelim::clone() const
70 return new InsetMathDelim(*this);
74 void InsetMathDelim::validate(LaTeXFeatures & features) const
76 InsetMathNest::validate(features);
77 // The delimiters may be used without \left or \right as well.
78 // Therefore they are listed in lib/symbols, and if they have
79 // requirements, we need to add them here.
80 validate_math_word(features, left_);
81 validate_math_word(features, right_);
85 void InsetMathDelim::write(TeXMathStream & os) const
87 MathEnsurer ensurer(os);
88 os << "\\left" << convertDelimToLatexName(left_) << cell(0)
89 << "\\right" << convertDelimToLatexName(right_);
93 void InsetMathDelim::normalize(NormalStream & os) const
95 os << "[delim " << convertDelimToLatexName(left_) << ' '
96 << convertDelimToLatexName(right_) << ' ' << cell(0) << ']';
100 void InsetMathDelim::metrics(MetricsInfo & mi, Dimension & dim) const
102 Changer dummy = mi.base.changeEnsureMath();
104 cell(0).metrics(mi, dim0, false);
105 Dimension t = theFontMetrics(mi.base.font).dimension('I');
106 int h0 = (t.asc + t.des) / 2;
107 int a0 = max(dim0.asc, t.asc) - h0;
108 int d0 = max(dim0.des, t.des) + h0;
109 dw_ = dim0.height() / 5;
114 dim.wid = dim0.width() + 2 * dw_ + 2 * mathed_thinmuskip(mi.base.font);
115 dim.asc = max(a0, d0) + h0;
116 dim.des = max(a0, d0) - h0;
120 void InsetMathDelim::draw(PainterInfo & pi, int x, int y) const
122 Changer dummy = pi.base.changeEnsureMath();
123 Dimension const dim = dimension(*pi.base.bv);
124 int const b = y - dim.asc;
125 int const skip = mathed_thinmuskip(pi.base.font);
126 cell(0).draw(pi, x + dw_ + skip, y);
127 mathed_draw_deco(pi, x + skip / 2, b, dw_, dim.height(), left_);
128 mathed_draw_deco(pi, x + dim.width() - dw_ - skip / 2,
129 b, dw_, dim.height(), right_);
133 bool InsetMathDelim::isParenthesis() const
135 return left_ == "(" && right_ == ")";
139 bool InsetMathDelim::isBrackets() const
141 return left_ == "[" && right_ == "]";
145 bool InsetMathDelim::isAbs() const
147 return left_ == "|" && right_ == "|";
151 void InsetMathDelim::maple(MapleStream & os) const
154 if (cell(0).size() == 1 && cell(0).front()->asMatrixInset())
155 os << "linalg[det](" << cell(0) << ')';
157 os << "abs(" << cell(0) << ')';
160 os << left_ << cell(0) << right_;
164 void InsetMathDelim::maxima(MaximaStream & os) const
167 if (cell(0).size() == 1 && cell(0).front()->asMatrixInset())
168 os << "determinant(" << cell(0) << ')';
170 os << "abs(" << cell(0) << ')';
173 os << left_ << cell(0) << right_;
177 void InsetMathDelim::mathematica(MathematicaStream & os) const
180 if (cell(0).size() == 1 && cell(0).front()->asMatrixInset())
181 os << "Det[" << cell(0) << ']';
183 os << "Abs[" << cell(0) << ']';
186 os << left_ << cell(0) << right_;
190 void InsetMathDelim::mathmlize(MathMLStream & ms) const
192 // Ignore the delimiter if: it is empty or only a space (one character).
193 const std::string attr = is_extracted_ ? "stretchy='false'" : "";
194 if (!left_.empty() && ((left_.size() == 1 && left_[0] != ' ') || left_.size() > 1)) {
196 << MTagInline("mo", attr)
197 << convertDelimToXMLEscape(left_)
201 if (!right_.empty() && ((right_.size() == 1 && right_[0] != ' ') || right_.size() > 1)) {
202 ms << MTagInline("mo", attr)
203 << convertDelimToXMLEscape(right_)
210 void InsetMathDelim::htmlize(HtmlStream & os) const
212 os << convertDelimToXMLEscape(left_)
214 << convertDelimToXMLEscape(right_);
218 void InsetMathDelim::octave(OctaveStream & os) const
221 os << "det(" << cell(0) << ')';
223 os << left_ << cell(0) << right_;