mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Fix bug #9354 (Preview inset does not work with math macros)
The patch also makes sure that only the macros actually used in a math inset are included in the preview snippet. In this way, the size of the tex file used for generating the previews does not explode in the presence of lots of macros.
This commit is contained in:
parent
558100ad58
commit
4c92d969eb
@ -25,6 +25,9 @@
|
||||
|
||||
#include "graphics/PreviewImage.h"
|
||||
|
||||
#include "mathed/InsetMathHull.h"
|
||||
#include "mathed/MacroTable.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
@ -74,7 +77,32 @@ void InsetPreview::preparePreview(DocIterator const & pos) const
|
||||
otexstream os(str, texrow);
|
||||
OutputParams runparams(&pos.buffer()->params().encoding());
|
||||
latex(os, runparams);
|
||||
docstring const snippet = str.str();
|
||||
|
||||
// collect macros at this position
|
||||
MacroNameSet macros;
|
||||
pos.buffer()->listMacroNames(macros);
|
||||
|
||||
// look for math insets and collect definitions for the used macros
|
||||
MacroNameSet defs;
|
||||
DocIterator dit = doc_iterator_begin(pos.buffer(), this);
|
||||
DocIterator const dend = doc_iterator_end(pos.buffer(), this);
|
||||
if (!dit.nextInset())
|
||||
dit.forwardInset();
|
||||
for (; dit != dend; dit.forwardInset()) {
|
||||
InsetMath * im = dit.nextInset()->asInsetMath();
|
||||
InsetMathHull * hull = im ? im->asHullInset() : 0;
|
||||
if (!hull)
|
||||
continue;
|
||||
for (idx_type idx = 0; idx < hull->nargs(); ++idx)
|
||||
hull->usedMacros(hull->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);
|
||||
|
||||
docstring const snippet = macro_preamble + str.str();
|
||||
preview_->addPreview(snippet, *pos.buffer());
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ class InsetMathAMSArray;
|
||||
class InsetMathBrace;
|
||||
class InsetMathChar;
|
||||
class InsetMathDelim;
|
||||
class InsetMathFracBase;
|
||||
class InsetMathFrac;
|
||||
class InsetMathFont;
|
||||
class InsetMathGrid;
|
||||
@ -129,6 +130,8 @@ public:
|
||||
virtual InsetMathChar const * asCharInset() const { return 0; }
|
||||
virtual InsetMathDelim * asDelimInset() { return 0; }
|
||||
virtual InsetMathDelim const * asDelimInset() const { return 0; }
|
||||
virtual InsetMathFracBase * asFracBaseInset() { return 0; }
|
||||
virtual InsetMathFracBase const * asFracBaseInset() const { return 0; }
|
||||
virtual InsetMathFrac * asFracInset() { return 0; }
|
||||
virtual InsetMathFrac const * asFracInset() const { return 0; }
|
||||
virtual InsetMathFont * asFontInset() { return 0; }
|
||||
|
@ -30,6 +30,10 @@ public:
|
||||
bool idxBackward(Cursor &) const { return false; }
|
||||
///
|
||||
bool idxForward(Cursor &) const { return false; }
|
||||
///
|
||||
InsetMathFracBase * asFracBaseInset() { return this; }
|
||||
///
|
||||
InsetMathFracBase const * asFracBaseInset() const { return this; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
#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"
|
||||
@ -32,6 +36,7 @@
|
||||
#include "LaTeXFeatures.h"
|
||||
#include "LyXRC.h"
|
||||
#include "MacroTable.h"
|
||||
#include "MathMacro.h"
|
||||
#include "output_xhtml.h"
|
||||
#include "Paragraph.h"
|
||||
#include "ParIterator.h"
|
||||
@ -622,6 +627,55 @@ void InsetMathHull::addPreview(DocIterator const & inset_pos,
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
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) {
|
||||
// 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);
|
||||
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 (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
|
||||
{
|
||||
@ -635,16 +689,17 @@ void InsetMathHull::preparePreview(DocIterator const & pos,
|
||||
// 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);
|
||||
|
||||
docstring setcnt;
|
||||
if (forexport && haveNumbers()) {
|
||||
@ -667,8 +722,7 @@ void InsetMathHull::preparePreview(DocIterator const & pos,
|
||||
'{' + convert<docstring>(num) + '}';
|
||||
}
|
||||
}
|
||||
docstring const snippet = macro_preamble.str() +
|
||||
setcnt + latexString(*this);
|
||||
docstring const snippet = macro_preamble + setcnt + latexString(*this);
|
||||
LYXERR(Debug::MACROS, "Preview snippet: " << snippet);
|
||||
preview_->addPreview(snippet, *buffer, forexport);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
namespace lyx {
|
||||
|
||||
class InsetLabel;
|
||||
class MacroNameSet;
|
||||
class ParConstIterator;
|
||||
class RenderPreview;
|
||||
|
||||
@ -152,6 +153,9 @@ public:
|
||||
/// Recreates the preview if preview is enabled.
|
||||
void reloadPreview(DocIterator const & pos) const;
|
||||
///
|
||||
void usedMacros(MathData const & md, DocIterator const & pos,
|
||||
MacroNameSet & macros, MacroNameSet & defs) const;
|
||||
///
|
||||
void initUnicodeMath() const;
|
||||
|
||||
///
|
||||
|
@ -135,7 +135,7 @@ What's new
|
||||
|
||||
- Fix test for urwclassico font (bug 9576).
|
||||
|
||||
- Fix issues with instant preview and math macros (bug 6369).
|
||||
- Fix issues with instant preview and math macros (bugs 6369 and 9354).
|
||||
|
||||
- Fix instant preview for the Math manual (bug 9508).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user