#include "InsetMathChar.h"
#include "InsetMathColor.h"
+#include "InsetMathFrac.h"
+#include "InsetMathGrid.h"
+#include "InsetMathNest.h"
+#include "InsetMathScript.h"
#include "MathExtern.h"
#include "MathFactory.h"
#include "MathStream.h"
#include "LaTeXFeatures.h"
#include "LyXRC.h"
#include "MacroTable.h"
+#include "MathMacro.h"
+#include "MathMacroTemplate.h"
#include "output_xhtml.h"
#include "Paragraph.h"
#include "ParIterator.h"
if (s == "gather") return hullGather;
if (s == "flalign") return hullFlAlign;
if (s == "regexp") return hullRegexp;
- lyxerr << "unknown hull type '" << to_utf8(s) << "'" << endl;
+ lyxerr << "unknown hull type '" << to_utf8(s) << "'" << endl;
return HullType(-1);
}
case hullGather: return from_ascii("gather");
case hullFlAlign: return from_ascii("flalign");
case hullRegexp: return from_ascii("regexp");
- default:
+ default:
lyxerr << "unknown hull type '" << type << "'" << endl;
return from_ascii("none");
}
InsetMathHull::InsetMathHull(Buffer * buf)
: InsetMathGrid(buf, 1, 1), type_(hullNone), numbered_(1, NUMBER),
- numbers_(1, empty_docstring()), label_(1, dummy_pointer),
- preview_(new RenderPreview(this)), use_preview_(false)
+ numbers_(1, empty_docstring()), label_(1, dummy_pointer),
+ preview_(new RenderPreview(this)), use_preview_(false)
{
//lyxerr << "sizeof InsetMath: " << sizeof(InsetMath) << endl;
//lyxerr << "sizeof MetricsInfo: " << sizeof(MetricsInfo) << endl;
InsetMathHull::InsetMathHull(Buffer * buf, HullType type)
: InsetMathGrid(buf, getCols(type), 1), type_(type), numbered_(1, NUMBER),
- numbers_(1, empty_docstring()), label_(1, dummy_pointer),
- preview_(new RenderPreview(this)), use_preview_(false)
+ numbers_(1, empty_docstring()), label_(1, dummy_pointer),
+ preview_(new RenderPreview(this)), use_preview_(false)
{
buffer_ = buf;
initMath();
}
-void InsetMathHull::addToToc(DocIterator const & pit, bool output_active) const
+void InsetMathHull::addToToc(DocIterator const & pit, bool output_active,
+ UpdateType utype) const
{
if (!buffer_) {
//FIXME: buffer_ should be set at creation for this inset! Problem is
return;
}
- Toc & toc = buffer().tocBackend().toc("equation");
+ shared_ptr<Toc> toc = buffer().tocBackend().toc("equation");
for (row_type row = 0; row != nrows(); ++row) {
if (!numbered(row))
continue;
if (label_[row])
- label_[row]->addToToc(pit, output_active);
- toc.push_back(TocItem(pit, 0, nicelabel(row), output_active));
+ label_[row]->addToToc(pit, output_active, utype);
+ toc->push_back(TocItem(pit, 0, nicelabel(row), output_active));
}
}
}
+//FIXME: This has probably no effect and can be removed.\r
char InsetMathHull::defaultColAlign(col_type col)
{
- if (type_ == hullEqnArray)
- return "rcl"[col];
- if (type_ == hullMultline)
- return 'c';
- if (type_ == hullGather)
- return 'c';
- if (type_ >= hullAlign)
- return "rl"[col & 1];
- return 'c';
+ return colAlign(type_, col);\r
}
-char InsetMathHull::displayColAlign(col_type col, row_type row) const
+char InsetMathHull::displayColAlign(idx_type idx) const
{
- if (type_ == hullMultline) {
- if (row == 0)
+ switch (type_) {\r
+ case hullMultline: {\r
+ row_type const r = row(idx);
+ if (r == 0)
return 'l';
- if (row == nrows() - 1)
+ if (r == nrows() - 1)
return 'r';
+ return 'c';\r
+ }\r
+ case hullEqnArray:\r
+ case hullGather:\r
+ case hullAlign:\r
+ case hullAlignAt:\r
+ case hullXAlignAt:\r
+ case hullXXAlignAt:\r
+ case hullFlAlign:\r
+ return colAlign(type_, col(idx));\r
+ default:\r
+ break;\r
}
- return InsetMathGrid::displayColAlign(col, row);
+ return InsetMathGrid::displayColAlign(idx);
}
{
Dimension const dim = dimension(*pi.base.bv);
if (previewTooSmall(dim)) {
- pi.pain.fillRectangle(x, y - 2 * ERROR_FRAME_WIDTH,
+ pi.pain.fillRectangle(x, y - 2 * ERROR_FRAME_WIDTH,
dim.wid, dim.asc + dim.des, backgroundColor(pi));
return;
- }
+ }
pi.pain.fillRectangle(x + 1, y - dim.asc + 1, dim.wid - 2,
dim.asc + dim.des - 1, pi.backgroundColor(this));
}
InsetMathGrid::metricsT(mi, dim);
} else {
odocstringstream os;
- WriteStream wi(os, false, true, WriteStream::wsDefault);
+ TexRow texrow(false);
+ otexrowstream ots(os,texrow);
+ WriteStream wi(ots, false, true, WriteStream::wsDefault);
write(wi);
dim.wid = os.str().size();
dim.asc = 1;
InsetMathGrid::drawT(pain, x, y);
} else {
odocstringstream os;
- WriteStream wi(os, false, true, WriteStream::wsDefault);
+ TexRow texrow(false);
+ otexrowstream ots(os,texrow);
+ WriteStream wi(ots, false, true, WriteStream::wsDefault);
write(wi);
pain.draw(x, y, os.str().c_str());
}
static Encoding const * encoding = 0;
if (inset.isBufferValid())
encoding = &(inset.buffer().params().encoding());
- WriteStream wi(ls, false, true, WriteStream::wsPreview, encoding);
+ TexRow texrow(false);
+ otexrowstream ots(ls,texrow);
+ WriteStream wi(ots, false, true, WriteStream::wsPreview, encoding);
inset.write(wi);
return ls.str();
}
}
+void InsetMathHull::usedMacros(MathData const & md, DocIterator const & pos,
+ MacroNameSet & macros, MacroNameSet & defs) const
+{
+ MacroNameSet::iterator const end = macros.end();
+
+ for (size_t i = 0; i < md.size(); ++i) {
+ MathMacro const * mi = md[i].nucleus()->asMacro();
+ MathMacroTemplate const * mt = md[i].nucleus()->asMacroTemplate();
+ InsetMathScript const * si = md[i].nucleus()->asScriptInset();
+ InsetMathFracBase const * fi = md[i].nucleus()->asFracBaseInset();
+ InsetMathGrid const * gi = md[i].nucleus()->asGridInset();
+ InsetMathNest const * ni = md[i].nucleus()->asNestInset();
+ if (mi) {
+ // Look for macros in the arguments of this macro.
+ for (idx_type idx = 0; idx < mi->nargs(); ++idx)
+ usedMacros(mi->cell(idx), pos, macros, defs);
+ // Make sure this is a macro defined in the document
+ // (as we also spot the macros in the symbols file)
+ // or that we have not already accounted for it.
+ docstring const name = mi->name();
+ if (macros.find(name) == end)
+ continue;
+ macros.erase(name);
+ // Look for macros in the definition of this macro.
+ MathData ar(pos.buffer());
+ MacroData const * data =
+ pos.buffer()->getMacro(name, pos, true);
+ if (data) {
+ odocstringstream macro_def;
+ data->write(macro_def, true);
+ macro_def << endl;
+ defs.insert(macro_def.str());
+ asArray(data->definition(), ar);
+ }
+ usedMacros(ar, pos, macros, defs);
+ } else if (mt) {
+ MathData ar(pos.buffer());
+ asArray(mt->definition(), ar);
+ usedMacros(ar, pos, macros, defs);
+ } else if (si) {
+ if (!si->nuc().empty())
+ usedMacros(si->nuc(), pos, macros, defs);
+ if (si->hasDown())
+ usedMacros(si->down(), pos, macros, defs);
+ if (si->hasUp())
+ usedMacros(si->up(), pos, macros, defs);
+ } else if (fi || gi) {
+ idx_type nidx = fi ? fi->nargs() : gi->nargs();
+ for (idx_type idx = 0; idx < nidx; ++idx)
+ usedMacros(fi ? fi->cell(idx) : gi->cell(idx),
+ pos, macros, defs);
+ } else if (ni) {
+ usedMacros(ni->cell(0), pos, macros, defs);
+ }
+ }
+}
+
+
void InsetMathHull::preparePreview(DocIterator const & pos,
bool forexport) const
{
// collect macros at this position
MacroNameSet macros;
buffer->listMacroNames(macros);
- MacroNameSet::iterator it = macros.begin();
- MacroNameSet::iterator end = macros.end();
- odocstringstream macro_preamble;
- for (; it != end; ++it) {
- MacroData const * data = buffer->getMacro(*it, pos, true);
- if (data) {
- data->write(macro_preamble, true);
- macro_preamble << endl;
- }
- }
+
+ // collect definitions only for the macros used in this inset
+ MacroNameSet defs;
+ for (idx_type idx = 0; idx < nargs(); ++idx)
+ usedMacros(cell(idx), pos, macros, defs);
+
+ MacroNameSet::iterator it = defs.begin();
+ MacroNameSet::iterator end = defs.end();
+ docstring macro_preamble;
+ for (; it != end; ++it)
+ macro_preamble.append(*it);
+
+ // set the font series and size for this snippet
+ DocIterator dit = pos;
+ while (dit.inMathed())
+ dit.pop_back();
+ Paragraph const & par = dit.paragraph();
+ Font font = par.getFontSettings(buffer->params(), dit.pos());
+ font.fontInfo().realize(par.layout().font);
+ string const lsize = font.latexSize();
+ docstring setfont;
+ docstring endfont;
+ if (font.fontInfo().series() == BOLD_SERIES) {
+ setfont += from_ascii("\\textbf{");
+ endfont += '}';
+ }
+ if (lsize != "normalsize" && !prefixIs(lsize, "error"))
+ setfont += from_ascii("\\" + lsize + '\n');
docstring setcnt;
if (forexport && haveNumbers()) {
'{' + convert<docstring>(num) + '}';
}
}
- docstring const snippet = macro_preamble.str() +
- setcnt + latexString(*this);
+ docstring const snippet = macro_preamble + setfont + setcnt
+ + latexString(*this) + endfont;
LYXERR(Debug::MACROS, "Preview snippet: " << snippet);
preview_->addPreview(snippet, *buffer, forexport);
}
case hullSimple:
os << '$';
+ os.startOuterRow();
if (cell(0).empty())
os << ' ';
break;
case hullEquation:
+ os << "\n";
+ os.startOuterRow();
if (n)
- os << "\n\\begin{equation" << star(n) << "}\n";
+ os << "\\begin{equation" << star(n) << "}\n";
else
- os << "\n\\[\n";
+ os << "\\[\n";
break;
case hullEqnArray:
case hullFlAlign:
case hullGather:
case hullMultline:
- os << "\n\\begin{" << hullName(type_) << star(n) << "}\n";
+ os << "\n";
+ os.startOuterRow();
+ os << "\\begin{" << hullName(type_) << star(n) << "}\n";
break;
case hullAlignAt:
case hullXAlignAt:
- os << "\n\\begin{" << hullName(type_) << star(n) << '}'
+ os << "\n";
+ os.startOuterRow();
+ os << "\\begin{" << hullName(type_) << star(n) << '}'
<< '{' << static_cast<unsigned int>((ncols() + 1)/2) << "}\n";
break;
case hullXXAlignAt:
- os << "\n\\begin{" << hullName(type_) << '}'
+ os << "\n";
+ os.startOuterRow();
+ os << "\\begin{" << hullName(type_) << '}'
<< '{' << static_cast<unsigned int>((ncols() + 1)/2) << "}\n";
break;
break;
default:
- os << "\n\\begin{unknown" << star(n) << "}\n";
+ os << "\n";
+ os.startOuterRow();
+ os << "\\begin{unknown" << star(n) << "}\n";
break;
}
}
break;
case hullEquation:
+ os << "\n";
+ os.startOuterRow();
if (n)
- os << "\n\\end{equation" << star(n) << "}\n";
+ os << "\\end{equation" << star(n) << "}\n";
else
- os << "\n\\]\n";
+ os << "\\]\n";
break;
case hullEqnArray:
case hullXAlignAt:
case hullGather:
case hullMultline:
- os << "\n\\end{" << hullName(type_) << star(n) << "}\n";
+ os << "\n";
+ os.startOuterRow();
+ os << "\\end{" << hullName(type_) << star(n) << "}\n";
break;
case hullXXAlignAt:
- os << "\n\\end{" << hullName(type_) << "}\n";
+ os << "\n";
+ os.startOuterRow();
+ os << "\\end{" << hullName(type_) << "}\n";
break;
case hullRegexp:
break;
default:
- os << "\n\\end{unknown" << star(n) << "}\n";
+ os << "\n";
+ os.startOuterRow();
+ os << "\\end{unknown" << star(n) << "}\n";
break;
}
}
}
+bool InsetMathHull::isMutable(HullType type)\r
+{\r
+ switch (type) {\r
+ case hullNone:\r
+ case hullSimple:\r
+ case hullEquation:\r
+ case hullEqnArray:\r
+ case hullAlign:\r
+ case hullFlAlign:\r
+ case hullAlignAt:\r
+ case hullXAlignAt:\r
+ case hullXXAlignAt:\r
+ case hullMultline:\r
+ case hullGather:\r
+ return true;\r
+ default:\r
+ return false;\r
+ }\r
+}\r
+\r
+\r
void InsetMathHull::mutate(HullType newtype)
{
//lyxerr << "mutating from '" << type_ << "' to '" << newtype << "'" << endl;
return res + InsetMathGrid::eolString(row, fragile, latex, last_eoln);
}
-
void InsetMathHull::write(WriteStream & os) const
{
ModeSpecifier specifier(os, MATH_MODE);
if (type_ == hullSimple || type_ == hullEquation) {
cur.recordUndoInset();
bool const align =
- cur.bv().buffer().params().use_package("amsmath") == BufferParams::package_on;
+ cur.bv().buffer().params().use_package("amsmath") != BufferParams::package_off;
mutate(align ? hullAlign : hullEqnArray);
// mutate() may change labels and such.
cur.forceBufferUpdate();
case LFUN_MATH_DISPLAY: {
cur.recordUndoInset();
mutate(type_ == hullSimple ? hullEquation : hullSimple);
- cur.idx() = 0;
- cur.pos() = cur.lastpos();
- //cur.dispatched(FINISHED);
+ // if the cursor is in a cell that got merged, move it to
+ // start of the hull inset.
+ if (cur.idx() > 0) {
+ cur.idx() = 0;
+ cur.pos() = 0;
+ }
+ if (cur.pos() > cur.lastpos())
+ cur.pos() = cur.lastpos();
+
break;
}
void InsetMathHull::write(ostream & os) const
{
odocstringstream oss;
- WriteStream wi(oss, false, false, WriteStream::wsDefault);
+ TexRow texrow(false);
+ otexrowstream ots(oss,texrow);
+ WriteStream wi(ots, false, false, WriteStream::wsDefault);
oss << "Formula ";
write(wi);
os << to_utf8(oss.str());
}
odocstringstream oss;
+ TexRow texrow(false);
+ otexrowstream ots(oss,texrow);
Encoding const * const enc = encodings.fromLyXName("utf8");
- WriteStream wi(oss, false, true, WriteStream::wsDefault, enc);
+ WriteStream wi(ots, false, true, WriteStream::wsDefault, enc);
// Fix Bug #6139
if (type_ == hullRegexp)
// and do not include the newline.
if (op.for_toc || op.for_tooltip || oss.str().size() >= max_length)
break;
- if (r < nrows() - 1)
+ if (r < nrows() - 1)
wi << "\n";
}
}
++ms.tab(); ms.cr(); ms.os() << '<' << bname << '>';
odocstringstream ls;
+ TexRow texrow;
+ otexstream ols(ls, texrow);
if (runparams.flavor == OutputParams::XML) {
ms << MTag("alt role='tex' ");
// Workaround for db2latex: db2latex always includes equations with
// \ensuremath{} or \begin{display}\end{display}
// so we strip LyX' math environment
- WriteStream wi(ls, false, false, WriteStream::wsDefault, runparams.encoding);
+ WriteStream wi(ols, false, false, WriteStream::wsDefault, runparams.encoding);
InsetMathGrid::write(wi);
ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&"), "<", "<"));
ms << ETag("alt");
InsetMathGrid::mathmlize(ms);
ms << ETag("math");
} else {
- TexRow texrow;
- texrow.reset();
- otexstream ols(ls, texrow);
ms << MTag("alt role='tex'");
latex(ols, runparams);
res = texrow.rows();
// Unfortunately, we cannot use latexString() because we do not want
// $...$ or whatever.
odocstringstream ls;
- WriteStream wi(ls, false, true, WriteStream::wsPreview);
+ TexRow texrow(false);
+ otexrowstream ots(ls,texrow);
+ WriteStream wi(ots, false, true, WriteStream::wsPreview);
ModeSpecifier specifier(wi, MATH_MODE);
mathAsLatex(wi);
docstring const latex = ls.str();
}
-void InsetMathHull::forOutliner(docstring & os, size_t) const
+void InsetMathHull::forOutliner(docstring & os, size_t const, bool const) const
{
odocstringstream ods;
OutputParams op(0);
op.for_toc = true;
+ // FIXME: this results in spilling TeX into the LyXHTML output since the
+ // outliner is used to generate the LyXHTML list of figures/etc.
plaintext(ods, op);
os += ods.str();
}