Commit Graph

148 Commits

Author SHA1 Message Date
Guillaume Munch
087f72202e Use math class information from lib/symbols for intelligent splitting
This was missing for macros defined in lib/symbols. This only affects the
equation splitting since global macros are always linearized. This fixes #10107.
2017-01-03 20:35:41 +01:00
Guillaume Munch
3e79e0f5f0 Fix wrong mode on output for macros that shadow global macros
Testcase: Define a math macro \AA, overriding the definition of \AA from
lib/symbols, then insert it in math mode.

* Before this commit: \text{\AA}, and \lyxmathsym{\AA} after deleting \text, but
  displayed like \AA.

* After this commit: \text{\AA} is inserted, but one gets \AA after deleting
  \text. The output is now consistent with the display and the meaning.

* Expected: only \AA is inserted. This is unfortuately not what one gets; for
  this to work, the scope of the macros would need to be resolved upon creating
  the inset.
2017-01-03 20:35:20 +01:00
Guillaume Munch
e35fda62a7 Some code factoring for changing mode.
About removing the changeEnsureMath in MathMacro::{metrics,draw} : as it is only
called in edition mode, it only happened for user macros for which no ensureMath
is needed anyway. ChangeEnsureMath should indeed be applied for global macros,
but since they are linearized there is no obvious place to call it.
2017-01-03 20:18:48 +01:00
Jean-Marc Lasgouttes
02e82157ec Get rid of Inset::setPosCache
This helper method is used to set the inset position cache at drawing
time. However this is already done by the drawing code itself
(MathRow::draw, RowPainter::paintInset), so that there is no need to
do this same work again in a different place.

Note that the inset positions are still set in InsetTabular::draw for
each cell.

This commit comes with a mild risk attached (it might be that some of
these calls were useful after all!), but all of this is fixable.
2016-12-06 16:15:47 +01:00
Jean-Marc Lasgouttes
d85cf3218a Remove unused method in ArgumentProxy
Also reorder some methods.
2016-12-02 16:19:02 +01:00
Jean-Marc Lasgouttes
2acc4fc54c Improve spacing of BOX elements
Tweak the algorithm so that a BOX math row element can have some
spacing. To this end, MathRow::before/after do not look at the type of
an element for deciding when to skip it, but rather to its math class.

In the new setting, the spacing algorithm works on all elements, but
skips the MC_UNKNOWN elements as if they were not present. As a
consequence, the two element types BEGIN and END have been replaced by
a single DUMMY (they can be recognized from their class).

To simply the code, add a new `mclass' argument to the
MathRow::Element constructor (default is MC_UNKNOWN).
2016-12-02 16:14:12 +01:00
Jean-Marc Lasgouttes
190d312e35 Factor out the code that handles default macro arguments 2016-12-02 14:56:09 +01:00
Jean-Marc Lasgouttes
0f15dcc698 Rewrite handling of macro nesting in math rows
Macro nesting is now recorded into the macro inset itself. This allows
the ArgumentProxy inset to determine whether it is editable or not by
looking at its macro.

Remove code in the metrics and draw methods of ArgumentProxy: this
code is AFAICS not active anymore, since arguments are linearized into
math rows.

Use Changer idiom to change locally the values of MecticsInfo::base.macro_nesting.
2016-12-02 11:56:49 +01:00
Jean-Marc Lasgouttes
58e479527e Reintroduce broken support for default macro arguments
This got forgotten in the math typesetting rewrite.

Fixes bug #10508.
2016-12-02 11:18:51 +01:00
Enrico Forestieri
e8f480e7c2 Fix display and output of math macros with optional arguments
This is a long standing issue, present since the new math macros
inception in version 1.6. It manifests as a display issue when a
macro with optional arguments appears in the optional argument of
another macro. In this case the display is messed up and it is
difficult, if not impossible, changing the arguments as they do not
appear on screen as related to a specific macro instance. It also
manifests as latex errors when compiling, even if the latex output
is formally correct, due to limitations of the xargs package used
to output the macros. Most probably, both aspects have the same
root cause, as simply enclosing in braces the macro and its
parameters solves both issues. However, when reloading a document,
lyx strips the outer braces enclosing a macro argument, thus
frustrating this possible workaround.

This commit solves the display issue by correctly accounting for
macros with optional arguments nested in the argument of another
macro, and circumvents the xargs package limitations causing errors
by enclosing in braces the macros with optional arguments appearing
in the argument of an outer macro when they are output. This means
that when loading an old document with such macros and saving it
again, the macro representation is updated and will have these
additional braces. However, as such braces are stripped by lyx on
loading, there is no risk that they accumulate.

See also this thread:
http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg197828.html
2016-12-01 18:02:47 +01:00
Guillaume Munch
c3e33b765e Match the font in MathMacro::metrics with the font in MathMacro::draw
This fixes the "bad keming" of math ERT (in fact wrong metrics) which recently
was worsened by InsetMathChar substitutions and their MathClass spacing.

Also fix a small inefficiency: always prefer:

  Changer dummy = (currentMode() == TEXT_MODE)
    ? pi.base.font.changeShape(UP_SHAPE) : Changer();

over:

  Changer dummy = pi.base.font.changeShape((currentMode() == TEXT_MODE)
    ? UP_SHAPE : pi.base.font.shape());

The former only records and restores a value when the condition is satisfied,
and does not cost anything otherwise.
2016-11-23 23:18:02 +01:00
Jean-Marc Lasgouttes
9a9a6a8c8f Skip drawing of markers in non-editable math data
There is no reason to reserve pixel space in macros replacement text,
which is not editable. This makes macros more compact and eases the
writing of lib/symbols.

* introduce new InsetMath::drawMarkers and friends that do nothing
  when nested inside a macro. This required to move macro_nesting
  inside MetricsBase, and to pass MetricsInfo & to metricsMarkers.

* keep track of nesting when drawing rows or macros.
2016-11-17 08:48:32 +01:00
Jean-Marc Lasgouttes
f3f9b083d1 Only display a blue rectangle for editable empty insets
Empty insets should use a minimal amount of space, especially when
they are part of a built-in macro in lib/symbols.

With this change, blue rectangles signal actually editable places.
Empty macros in editable data are shown as grey boxes, but they do not
appear when further nested.

This is done by adding a new type BOX of MathRow::Element object and a
MetricsInfo::macro_nesting that keeps track of macros (and is reset to
0 in editable macro arguments).
2016-11-16 18:33:02 +01:00
Jean-Marc Lasgouttes
bf56e2c8e1 Set correctly the spacing between atoms in MathData
* new MathRow class which contains the description of a MathData
  object in terms of math class and spacing

  + macros and their arguments used in the MathData object are
    linearized (replaced with their contents) so that all math insets
    are typeset as a string together. To this end, we introduce a
    method addToMathRow to InsetMath and MathData. This method allows
    to linearize recursively a MathData object.

  + It is then necessary to set manually the dimension and position of
    the macros and arguments.

  + the class class and spacing are computed using the MathClass helpers.

  The MathRow data is cached in the MathData object in a bufferview-dependent
  way (different dpi for different screens).

* delegate most of the work MathData::metrics/draw to MathRow metrics/draw.

  The case of draw is trickier, since many draw() methods rely on their
  metrics without any spacing added.
2016-11-16 15:21:52 +01:00
Enrico Forestieri
e3c3719643 Don't print useless messages while parsing math macros
Math macros can be displayed on screen by providing a different
representation than the one used for latex output. This representation
is actually used by lyx even while it is being updated. This leads to
printing useless error messages on the terminal. For example, a macro
parameter has to be entered as \#1 and, if the macro is already used in
a math inset, lyx prints on terminal the error message "Math parse error:
missing token after \\" as soon as one hits the \ key, followed by
"MathMacroArgument::MathMacroArgument: wrong Argument id: -48" as soon as
one hits the # key. So, this is not a useful information and simply
clutters the terminal output. On the other hand, the input is sanitized
even if one stops input after hitting either \ or #, so that no further
messages are issued. Hence, those error messages are simply pointless.
2016-10-31 15:23:20 +01:00
Enrico Forestieri
6642152e66 Do not rely on math macros being updated
Trying to spare a few cycles by avoiding computing metrics during
screen updates and export. See also 8f86ee74, 72cf7c8f, and e36a8903.
Guillaume will tell whether this also avoids crashing his documents ;)
2016-09-25 20:31:13 +02:00
Enrico Forestieri
314e30d5fd Correctly classify macros
Some macros defined in the lib/symbols file are classified are texmode.
But the MathMacro class was missing a currentMode method for returning
this information.
2016-09-25 01:11:16 +02:00
Enrico Forestieri
e36a8903d7 Really fix the problem with not updated macros
Revert to the strategy used at 8f86ee74 but not using mathedWordList
because it may be still uninitialized at load time. Instead, use the
globalMacros method for getting the same info.
There was a thinko at 8ec91e80, because globalMacros always returns
null for user defined macros.
2016-09-15 02:39:30 +02:00
Enrico Forestieri
8ec91e804a Make sure not to use a pointer that may be bogus
It may happen that mathedWordList is not still updated at load time,
so we would still be using a bogus pointer. Better fetching the
necessary info from the global macro table.
2016-09-14 02:27:18 +02:00
Enrico Forestieri
8f86ee74cd Make sure that math macros are updated at export time.
The math macros system is quite complex. Macros are updated during
metrics calculation, so a missing update is very likely to cause a
crash. This commit tries to assure that they are updated at export
time, which also happens when the table of contents is updated.
Moreover, in order to circumvent a possible missing update, when
a math macro is detected we try to avoid using the sym_ member
of the MacroData class, as it may contain bogus values.
2016-09-13 08:02:02 +02:00
Enrico Forestieri
2aa930bbe8 Fix display and export of some latex macros
Fixes #9742.
2016-09-10 18:32:44 +02:00
Guillaume Munch
b2b8733096 Remove a conversion to_utf8() inside FontSetChanger
This requires to change many docstrings into std::strings. The logic behind that
is that they represent a fixed set of math fonts, and therefore “string” means
here “poor man's enum” rather than text (this is consistent with MetricsBase).

Profiling of scrolling inside a document over macro-instensive areas:

Before the patch:
  44,1% BufferView::updateMetrics()
   -> 34,8% InsetMathHull::metrics()
     -> 9,8% FontSetChanger::FontSetChanger()
  28,4% BufferView::draw()

After the patch:
  35,3% BufferView::updateMetrics()
   -> 27,2% InsetMathHull::metrics
     -> 0,4% FontSetChanger::FontSetChanger()
  47,5% BufferView::draw()

FontSetChanger::FontSetChanger() is made 41x less expensive (with reference
BV::draw()) just by removing this conversion. The remaining 0,4% could be
squished by replacing the strings with a proper enum, but this is premature. Of
course, this only treats the symptoms: there is no good reason that this
function is called 45500 times over the time of 40 repaints.
2016-06-13 08:46:15 +01:00
Guillaume Munch
348e0241af Do not include MetricsInfo.h in MathStream.h
Fixes the FIXME in MathStream.h
2016-06-13 08:46:15 +01:00
Guillaume Munch
e2bc7ffae3 RefChanger
RefChanger temporarily assigns a value to a non-const reference of any
kind. RefChanger provides a flexible and uniform generalisation of the various
scope guards previously derived from the old Changer class in MetricsInfo.h.

As before, a temporary assignment lasts as long as the Changer object lives. But
the new Changer is movable. In particular, contorsions are no longer needed to
change a private field. Special code can be moved into the appropriate classes,
and it is no longer necessary to create a new class for each specific use.

Syntax change:

   FontSetChanger dummy(mi.base, value);
-> Changer dummy = mi.base.changeFontSet(value);

New function for generating arbitrary Changers:

  Changer dummy = make_change(ref, val, condition);

Bugfix:

* Fix the display of \displaystyle{\substack{\frac{xyz}{}}} (missing style
  change).
2016-06-13 08:46:15 +01:00
Georg Baum
ff4668621b Fxy typo in XHTML output (bug #10124)
There was a simple typo that did ouput the slash before the closing tag
instead of inside the closing tag.
2016-05-22 17:32:04 +02:00
Enrico Forestieri
82fe5183ca Fix #9490: SIGSEGV involving LyX macros --- A reproducible MWE (part II) 2015-10-03 17:41:25 +02:00
Enrico Forestieri
b7dd5ade94 Remove unneeded header
Forgot this at 4dff1394
2015-07-06 23:47:22 +02:00
Enrico Forestieri
4dff1394ab Avoid calling Buffer::getMacro inside the MathMacro copy constructor
It turns out that it is always better using the copy of the MacroData
for updating the macro_ pointer to avoid problems related to the cursor
position.
2015-07-05 20:44:54 +02:00
Enrico Forestieri
2072de8349 Avoid code duplication 2015-06-30 19:27:38 +02:00
Enrico Forestieri
305a712bbb Avoid using a dangling pointer
This can happen when a macro is copied and then the document where
it is defined is closed. In this case, the macro survives in the
cut stack but the the buffer pointer is dangling.
2015-06-30 18:54:19 +02:00
Enrico Forestieri
d275d034c0 Check whether the buffer pointer is valid before using it 2015-06-25 01:25:42 +02:00
Enrico Forestieri
fee356eb56 Assure not to miss requirements on loading with instant preview on 2015-06-25 00:49:15 +02:00
Enrico Forestieri
f3b03699ef Fix crash when copying a macro with instant preview on
The MacroData pointer is updated by MathData::metrics() which is not
called when selecting a math inset with instant preview for math on.
Thus, we have to update it in the copy constructor otherwise a crash
is almost assured when hitting Ctrl+C.
2015-06-24 23:38:53 +02:00
Georg Baum
84cca2dd94 Fix indentation 2015-05-17 17:27:27 +02:00
Georg Baum
1b5875043d Fix math macro crash (bug 9418)
In the test case the crash occured in mathml export of the temporary buffer,
because the macro was updated, and because one of the used other macros was
not copied, the macro argument was detached. However, the underlying problem
of the crash was a broken ArgumentProxy::mathMacro_ reference which became
invalid each time the ownng MathMacro was copied. In the bug test case the
copying happened due to resizing a std::vector, but any other copy would have
created the same problem. The crash did not always happen, because sometimes
the old freed memory was not immediately reused, so the invalid reference did
still point to usable data.

The fix is easy: Convert ArgumentProxy::mathMacro_ to a pointer and update it
always after creating a copy of the owner. The pimpl of MathMacro from the
previous commit helps here to distinguish between the data that can be
automatically copied (in MathMacro::Private) and the cleanup that needs to be
done manually (in MathMacro). This way, the manual copy constructor and
assigment operator of MathMacro does not need to be touched if a new member is
added.
2015-04-02 21:35:05 +02:00
Georg Baum
948ed1ffd5 Pimpl MathMacro
This will make it easier to fix bug 9418.
2015-04-02 21:20:32 +02:00
Georg Baum
af6cb2d0e2 Initialize definition_ correctly 2015-03-30 22:04:52 +02:00
Georg Baum
417139f4da Remove InsetMathSqrt hack from MathMacro
The expanded cells of a mathmacro were previously stored in an InsetMathSqrt.
This was only used as a container for the MathData object in the first cell
of the sqrt inset, which contained the actual expanded arguments.
Funny enough, the only place were the inset property of expanded_ was really
used cannot be seen in the diff. It was MathMacro::kerning(), and this usage
was wrong, since InsetMathSqrt::kerning() always returns 0. Threfore, using
the correct type (MathData) for expanded_ does not only make the code more
readable, gets rid of an unneeded dependency, but also fixes a bug: Now the
correct kerning is returned for expanded cells. Also, expanded_ and
definition_ use the same type now, which looks nicely symmetric.
2015-03-29 14:50:37 +02:00
Georg Baum
d48855cdfe Improve CAS output of math macros
Previously, things like [ name ] where exported for computer algebra systems.
Now, the expanded macros are exported, which may still be wrong, but now the
CAS has at least a chance to understand what was meant.
2015-03-29 13:53:01 +02:00
Georg Baum
bc8638bd25 Fix wrong LATTEST
Thanks to Scott for testing. If a macro is unknown (displayed in red), then
macro_ is 0. The LATTEST is now adjusted and works like in MathMacro::write()
where I stole it from.
2015-02-16 22:33:48 +01:00
Georg Baum
33b059bd9d Make macro xhtml export more secure
Actually I wanted to do that in cc87f8100 but forgot to adjust the original
solution completely. Now we do not search for an arbitrary latexkeys instance
which just happens to have the same name as the macro, but we only use the
symbol that was explicitly set for global macros.
2014-12-30 13:30:40 +01:00
Georg Baum
cc87f81002 Fix html export of \ne (second part of bug #9372)
The fix consists of two parts: The needed infrastructure to assign HTML
entities to global math macros, and the actual fix for \ne and \neq.
2014-12-29 21:13:42 +01:00
Jean-Marc Lasgouttes
689e54f34a Make sure that UpdateLocker is used correctly in the future 2014-11-17 11:52:14 +01:00
Georg Baum
0f2069b8a5 Fix recursive math macro crash (bug #9140)
This is different from bug #8999, since in this case a new macro instance is
created. You still get a TeX capacity exceeded error if you try to typeset the
exported document, but this is the same as for bug #8999 and better than a
crash.
2014-11-14 21:30:42 +01:00
Uwe Stöhr
ff85a4902e mathed: bformat infoize messages
- should fix bug #1908
2014-11-14 18:18:30 +01:00
Jean-Marc
1cdbb94ff5 Fix possible bug spotted by cppcheck
I am not sure what this locking is really about, but the new code seems to be the right thing to do.
2014-07-05 19:12:09 +02:00
Georg Baum
e85e9424b3 Fix display of predefined macros (bug #9059)
This was a regression of e86cdc40: A newly introduced member variable was
not initialized in the constructor, which made it quite random whether symbols
like \coloneqq where displayed correctly or as an empty edit box.
2014-03-28 23:16:36 +01:00
Richard Heck
e86cdc4020 Fix bug #8999 by locking math macros while they are updating. 2014-03-05 18:46:38 -05:00
Enrico Forestieri
3c1969574f Fix bug #8889 by always issuing \protect in fragile environments. 2014-02-22 10:30:55 -05:00
Richard Heck
d79225ae98 Remove all messages to user related to assertions. We'll just use
a basic message which is defined in lassert.cpp now.
2013-04-27 17:52:55 -04:00