-----------------------
+2012-12-28 Georg Baum <Georg.Baum@post.rwth-aachen.de>
+ * Format incremented to 457
+ support for the LaTeX-package stackrel (fix bug 8464)
+ New buffer param \use_package stackrel
+
2012-12-28 Jürgen Spitzmüller <spitz@lyx.org>
* Format incremented to 456: Proper support for memoir \epigraph
\epigraph{text}{source} > begin_layout Epigraph, <source> as
images/math/ssearrow.png \
images/math/sslash.png \
images/math/sswarrow.png \
+ images/math/stackrel.png \
+ images/math/stackrelthree.png \
images/math/star.png \
images/math/style.png \
images/math/sub.png \
\TestPackage{slashed}
\TestPackage{soul}
\TestPackage{splitidx}
+\TestPackage{stackrel}
\TestPackage{stmaryrd}
\TestPackage{subfig}
\TestPackage{Sweave}
converter programs.
\end_layout
+\begin_layout Subsection
+stackrel
+\end_layout
+
+\begin_layout Description
+Found:
+\begin_inset Info
+type "package"
+arg "stackrel"
+\end_inset
+
+
+\end_layout
+
+\begin_layout Description
+CTAN:
+\family typewriter
+macros/latex/contrib/oberdiek
+\end_layout
+
+\begin_layout Description
+Notes: The package
+\family sans
+stackrel
+\family default
+ is needed by LyX to be able to output formulas using the
+\backslash
+stackrel command with subscript.
+\end_layout
+
\begin_layout Subsection
stmaryrd
\end_layout
i = j
+def convert_use_stackrel(document):
+ "insert use_package stackrel"
+ i = find_token(document.header, "\\use_package", 0)
+ if i == -1:
+ document.warning("Malformed LyX document: Can't find \\use_package.")
+ return;
+ j = find_token(document.preamble, "\\usepackage{stackrel}", 0)
+ if j == -1:
+ document.header.insert(i + 1, "\\use_package stackrel 0")
+ else:
+ document.header.insert(i + 1, "\\use_package stackrel 2")
+ del document.preamble[j]
+
+
+def revert_use_stackrel(document):
+ "remove use_package stackrel"
+ regexp = re.compile(r'(\\use_package\s+stackrel)')
+ i = find_re(document.header, regexp, 0)
+ value = "1" # default is auto
+ if i != -1:
+ value = get_value(document.header, "\\use_package" , i).split()[1]
+ del document.header[i]
+ if value == "2": # on
+ add_to_preamble(document, ["\\usepackage{stackrel}"])
+ elif value == "1": # auto
+ regcmd = re.compile(r'.*\\stackrel\s*\[')
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Formula', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(i))
+ i += 1
+ continue
+ code = "\n".join(document.body[i:j])
+ if regcmd.match(code):
+ add_to_preamble(document, ["\\usepackage{stackrel}"])
+ return
+ i = j
+
+
def convert_cite_engine_type(document):
"Determine the \\cite_engine_type from the citation engine."
i = find_token(document.header, "\\cite_engine", 0)
[453, [convert_use_stmaryrd]],
[454, [convert_overprint]],
[455, []],
- [456, [convert_epigraph]]
+ [456, [convert_epigraph]],
+ [457, [convert_use_stackrel]]
]
revert = [
+ [456, [revert_use_stackrel]],
[455, [revert_epigraph]],
[454, [revert_frametitle]],
[453, [revert_overprint]],
Item "bcancel" "math-insert \bcancel"
Item "xcancel" "math-insert \xcancel"
Item "cancelto" "math-insert \cancelto"
+ Item "stackrel" "math-insert \stackrel"
+ Item "stackrelthree" "math-insert \stackrelthree"
End
Toolbar "latex_arrow" "Arrows"
packages.push_back("mathdots");
packages.push_back("mathtools");
packages.push_back("mhchem");
+ packages.push_back("stackrel");
packages.push_back("stmaryrd");
packages.push_back("undertilde");
}
typedef std::map<std::string, Package> PackageMap;
/** Whether and how to load packages like amsmath, esint, mhchem,
- * mathdots and undertilde.
+ * mathdots, stackrel, stmaryrd and undertilde.
*/
PackageMap use_packages;
params_.use_package("stmaryrd") != BufferParams::package_off)
packages << "\\usepackage{stmaryrd}\n";
+ if (mustProvide("stackrel") &&
+ params_.use_package("stackrel") != BufferParams::package_off)
+ packages << "\\usepackage{stackrel}\n";
+
if (mustProvide("undertilde") &&
params_.use_package("undertilde") != BufferParams::package_off)
packages << "\\usepackage{undertilde}\n";
N_("Use mhchem &package automatically"),
N_("Use mh&chem package"),
N_("The LaTeX package mhchem is only used if either the command \\ce or \\cf is inserted into formulas")},
+ {"stackrel",
+ N_("Use stackrel package automatically"),
+ N_("Use stackrel package"),
+ N_("The LaTeX package stackrel is only used if the command \\stackrel with subscript is inserted into formulas")},
{"stmaryrd",
N_("Use stmaryrd package automatically"),
N_("Use stmaryrd package"),
globals.push_back(from_ascii("\\root"));
globals.push_back(from_ascii("\\tabular"));
globals.push_back(from_ascii("\\stackrel"));
+ globals.push_back(from_ascii("\\stackrelthree"));
globals.push_back(from_ascii("\\binom"));
globals.push_back(from_ascii("\\choose"));
globals.push_back(from_ascii("\\brace"));
#include "InsetMathStackrel.h"
+#include "Cursor.h"
#include "LaTeXFeatures.h"
#include "MathData.h"
#include "MathStream.h"
namespace lyx {
-InsetMathStackrel::InsetMathStackrel(Buffer * buf) : InsetMathFracBase(buf)
+InsetMathStackrel::InsetMathStackrel(Buffer * buf, bool sub)
+ : InsetMathFracBase(buf, sub ? 3 : 2)
{}
}
+bool InsetMathStackrel::idxUpDown(Cursor & cur, bool up) const
+{
+ if (up) {
+ if (cur.idx() == 0)
+ return false;
+ } else {
+ if (cur.idx() + 1 == nargs())
+ return false;
+ }
+ InsetMath::idx_type target = up ? cur.idx() - 1 : cur.idx() + 1;
+ if (cur.idx() == target)
+ return false;
+ cur.idx() = target;
+ cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
+ return true;
+}
+
+
void InsetMathStackrel::metrics(MetricsInfo & mi, Dimension & dim) const
{
Dimension dim1;
FracChanger dummy(mi.base);
Dimension dim0;
cell(0).metrics(mi, dim0);
- dim.wid = max(dim0.width(), dim1.width()) + 4;
- dim.asc = dim1.ascent() + dim0.height() + 4;
- dim.des = dim1.descent();
+ if (nargs() > 2) {
+ Dimension dim2;
+ cell(2).metrics(mi, dim2);
+ dim.wid = max(max(dim0.width(), dim1.width()), dim2.width()) + 4;
+ dim.asc = dim1.ascent() + dim0.height() + 4;
+ dim.des = dim1.descent() + dim2.height() + dim2.descent() + 1;
+ } else {
+ dim.wid = max(dim0.width(), dim1.width()) + 4;
+ dim.asc = dim1.ascent() + dim0.height() + 4;
+ dim.des = dim1.descent();
+ }
metricsMarkers(dim);
}
cell(1).draw(pi, m - dim1.width() / 2, y);
FracChanger dummy(pi.base);
cell(0).draw(pi, m - dim0.width() / 2, yo);
+ if (nargs() > 2) {
+ Dimension const & dim2 = cell(2).dimension(*pi.base.bv);
+ int y2 = y + dim1.descent() + dim2.ascent() + 1;
+ cell(2).draw(pi, m - dim2.width() / 2, y2);
+ }
drawMarkers(pi, x, y);
}
void InsetMathStackrel::write(WriteStream & os) const
{
MathEnsurer ensurer(os);
- os << "\\stackrel{" << cell(0) << "}{" << cell(1) << '}';
+ os << "\\stackrel";
+ if (nargs() > 2)
+ os << '[' << cell(2) << ']';
+ os << '{' << cell(0) << "}{" << cell(1) << '}';
}
void InsetMathStackrel::normalize(NormalStream & os) const
{
- os << "[stackrel " << cell(0) << ' ' << cell(1) << ']';
+ os << "[stackrel " << cell(0) << ' ' << cell(1);
+ if (nargs() > 2)
+ os << ' ' << cell(2);
+ os << ']';
}
void InsetMathStackrel::mathmlize(MathStream & ms) const
{
- ms << "<mover accent='false'>" << cell(1) << cell(0) << "</mover>";
+ if (nargs() > 2)
+ ms << "<munderover>" << cell(1) << cell(2) << cell(0) << "</munderover>";
+ else
+ ms << "<mover accent='false'>" << cell(1) << cell(0) << "</mover>";
}
void InsetMathStackrel::htmlize(HtmlStream & os) const
{
- // at the moment, this is exactly the same as overset
- os << MTag("span", "class='overset'")
- << MTag("span", "class='top'") << cell(0) << ETag("span")
- << MTag("span") << cell(1) << ETag("span")
- << ETag("span");
+ if (nargs() > 2) {
+ os << MTag("span", "class='underoverset'")
+ << MTag("span", "class='top'") << cell(0) << ETag("span")
+ << MTag("span") << cell(1) << ETag("span")
+ << MTag("span", "class='bottom'") << cell(2) << ETag("span");
+ } else {
+ // at the moment, this is exactly the same as overset
+ os << MTag("span", "class='overset'")
+ << MTag("span", "class='top'") << cell(0) << ETag("span")
+ << MTag("span") << cell(1) << ETag("span");
+ }
+ os << ETag("span");
}
void InsetMathStackrel::validate(LaTeXFeatures & features) const
{
- // from overset
- if (features.runparams().math_flavor == OutputParams::MathAsHTML)
- features.addCSSSnippet(
- "span.overset{display: inline-block; vertical-align: bottom; text-align:center;}\n"
- "span.overset span {display: block;}\n"
- "span.top{font-size: 66%;}");
+ if (features.runparams().math_flavor == OutputParams::MathAsHTML) {
+ if (nargs() > 2) {
+ // FIXME: "vertical-align: middle" works only if the
+ // height of sub and super script is approximately equal.
+ features.addCSSSnippet(
+ "span.underoverset{display: inline-block; vertical-align: middle; text-align:center;}\n"
+ "span.underoverset span {display: block;}\n"
+ "span.bottom{font-size: 66%;}\n"
+ "span.top{font-size: 66%;}");
+ } else {
+ // from overset
+ features.addCSSSnippet(
+ "span.overset{display: inline-block; vertical-align: bottom; text-align:center;}\n"
+ "span.overset span {display: block;}\n"
+ "span.top{font-size: 66%;}");
+ }
+ }
+ if (nargs() > 2)
+ features.require("stackrel");
InsetMathNest::validate(features);
}
class InsetMathStackrel : public InsetMathFracBase {
public:
///
- InsetMathStackrel(Buffer * buf);
+ InsetMathStackrel(Buffer * buf, bool sub);
+ ///
+ bool idxUpDown(Cursor &, bool up) const;
///
void metrics(MetricsInfo & mi, Dimension & dim) const;
///
if (s == "tabular")
return MathAtom(new InsetMathTabular(buf, s, 1, 1));
if (s == "stackrel")
- return MathAtom(new InsetMathStackrel(buf));
+ return MathAtom(new InsetMathStackrel(buf, false));
+ // This string value is only for math toolbar use, no LaTeX name
+ if (s == "stackrelthree")
+ return MathAtom(new InsetMathStackrel(buf, true));
if (s == "binom")
return MathAtom(new InsetMathBinom(buf, InsetMathBinom::BINOM));
if (s == "dbinom")
#include "InsetMathSpace.h"
#include "InsetMathSplit.h"
#include "InsetMathSqrt.h"
+#include "InsetMathStackrel.h"
#include "InsetMathString.h"
#include "InsetMathTabular.h"
#include "MathMacroTemplate.h"
parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
}
+ else if (t.cs() == "stackrel") {
+ // Here allowed formats are \stackrel[subscript]{superscript}{operator}
+ MathData ar;
+ parse(ar, FLAG_OPTION, mode);
+ cell->push_back(MathAtom(new InsetMathStackrel(buf, !ar.empty())));
+ if (!ar.empty())
+ cell->back().nucleus()->cell(2) = ar;
+ parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode);
+ parse(cell->back().nucleus()->cell(1), FLAG_ITEM, mode);
+ }
+
else if (t.cs() == "xrightarrow" || t.cs() == "xleftarrow") {
cell->push_back(createInsetMath(t.cs(), buf));
parse(cell->back().nucleus()->cell(1), FLAG_OPTION, mode);
h_use_packages["mhchem"] = "0";
h_use_packages["mathdots"] = "0";
h_use_packages["mathtools"] = "0";
+ h_use_packages["stackrel"] = "0";
h_use_packages["stmaryrd"] = "0";
h_use_packages["undertilde"] = "0";
}
else if (name == "amsmath" || name == "amssymb" ||
name == "esint" || name == "mhchem" || name == "mathdots" ||
- name == "mathtools" || name == "stmaryrd" ||
- name == "undertilde")
+ name == "mathtools" || name == "stackrel" ||
+ name == "stmaryrd" || name == "undertilde")
h_use_packages[name] = "2";
else if (name == "babel") {
455 beamer frametitle command \begin_layout FrameTitle
\frametitle<overlay>[short}{long}
456 memoir: \epigraph{text}{source} layout Epigraph, InsetArgument
+457 automatic stackrel loading \use_package stackrel
General
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine natbib
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine natbib
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass amsart
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
#LyX file created by tex2lyx 2.1.0dev
-\lyxformat 456
+\lyxformat 457
\begin_document
\begin_header
\textclass article
\use_package mathdots 0
\use_package mathtools 0
\use_package mhchem 0
+\use_package stackrel 0
\use_package stmaryrd 0
\use_package undertilde 0
\cite_engine basic
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 456 // spitz: proper support for memoir epigraph
-#define LYX_FORMAT_TEX2LYX 456 // spitz: proper support for memoir epigraph
+#define LYX_FORMAT_LYX 457 // gb: automatic stackrel package loading
+#define LYX_FORMAT_TEX2LYX 457 // gb: automatic stackrel package loading
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER