mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 10:58:52 +00:00
The strategy adopted in bc47054b
had some drawbacks related to the way
instant preview snippets are generated. See the subthread starting at
http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg187916.html
for details.
The strategy adopted in this commit is that of adding macro definitions
only for the macros actually used in a preview snippet, independently
of whether some macro was already used in a previous snippet. In this way
the snippets don't need to be changed according to whether they are
compiled as a whole or separately from each other. This fact was causing
the regeneration of a preview snippet whenever the cursor entered the
corresponding inset, even if the generated image would have not changed.
The problem of defining or redefining a macro is taken care by the
python scripts.
This commit is contained in:
parent
bdec44d614
commit
11c2b7792c
@ -160,27 +160,23 @@ def extract_metrics_info(dvipng_stdout):
|
||||
|
||||
def fix_latex_file(latex_file, pdf_output):
|
||||
documentclass_re = re.compile("(\\\\documentclass\[)(1[012]pt,?)(.+)")
|
||||
def_re = re.compile(r"(\\newcommandx|\\global\\long\\def)(\\[a-zA-Z])(.+)")
|
||||
usepackage_re = re.compile("\\\\usepackage")
|
||||
userpreamble_re = re.compile("User specified LaTeX commands")
|
||||
enduserpreamble_re = re.compile("\\\\makeatother")
|
||||
begindoc_re = re.compile("\\\\begin\{document\}")
|
||||
|
||||
tmp = mkstemp()
|
||||
|
||||
in_doc_body = 0
|
||||
in_user_preamble = 0
|
||||
usepkg = 0
|
||||
changed = 0
|
||||
macros = []
|
||||
for line in open(latex_file, 'r').readlines():
|
||||
if in_doc_body:
|
||||
if changed:
|
||||
tmp.write(line)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
if begindoc_re.match(line) != None:
|
||||
in_doc_body = 1
|
||||
match = documentclass_re.match(line)
|
||||
if match != None:
|
||||
changed = 1
|
||||
tmp.write("%s%s\n" % (match.group(1), match.group(3)))
|
||||
continue
|
||||
|
||||
if not pdf_output and not usepkg:
|
||||
if userpreamble_re.search(line) != None:
|
||||
@ -200,13 +196,23 @@ def fix_latex_file(latex_file, pdf_output):
|
||||
tmp.write(line)
|
||||
continue
|
||||
|
||||
match = documentclass_re.match(line)
|
||||
match = def_re.match(line)
|
||||
if match == None:
|
||||
tmp.write(line)
|
||||
continue
|
||||
|
||||
changed = 1
|
||||
tmp.write("%s%s\n" % (match.group(1), match.group(3)))
|
||||
macroname = match.group(2)
|
||||
if not macroname in macros:
|
||||
macros.append(macroname)
|
||||
tmp.write(line)
|
||||
continue
|
||||
|
||||
definecmd = match.group(1)
|
||||
if definecmd == "\\global\\long\\def":
|
||||
tmp.write(line)
|
||||
else:
|
||||
changed = 1
|
||||
tmp.write("\\renewcommandx%s%s\n" % (match.group(2), match.group(3)))
|
||||
|
||||
if changed:
|
||||
copyfileobj(tmp, open(latex_file,"wb"), 1)
|
||||
@ -426,8 +432,8 @@ def main(argv):
|
||||
progress("Preprocess through lilypond-book: %s" % lilypond)
|
||||
progress("Altering the latex file for font size and colors")
|
||||
|
||||
# Omit font size specification in latex file and make sure that
|
||||
# the microtype package doesn't cause issues in dvi mode.
|
||||
# Omit font size specification in latex file and make sure that multiple
|
||||
# defined macros and the microtype package don't cause issues.
|
||||
fix_latex_file(latex_file, pdf_output)
|
||||
|
||||
if lilypond:
|
||||
|
@ -24,6 +24,9 @@
|
||||
|
||||
#include "graphics/PreviewImage.h"
|
||||
|
||||
#include "mathed/InsetMathHull.h"
|
||||
#include "mathed/MacroTable.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
@ -72,7 +75,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"
|
||||
@ -623,6 +628,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
|
||||
{
|
||||
@ -636,16 +690,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()) {
|
||||
@ -668,8 +723,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;
|
||||
|
||||
@ -162,6 +163,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;
|
||||
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user