Enrico Forestieri wrote:
> I am not able to generate a bigger "{" by "\bigl\{" in mathed (I must
> use "\bigl\lbrace" for that) because I think that the code dealing
> with \bigl has not a chance of viewing \{, being it transformed to {}.
> This is currently beyond my capabilities (but I continue learning).
Only a tiny bit was missing: The transformation of { and } to \{ and \},
respectively in MathNestInset::interpret. I am going to ccommit the
attached patch.
Georg
Log:
Make MathBigInset working
* src/cursor.C
(LCursor::plainInsert): combine the previous math atom with the new
one to a MathBigInset if possible
* src/mathed/math_biginset.[Ch]
(MathBigInset::name): implement
(MathBigInset::isBigInsetDelim): new, test whether a given token is
a valid MathBigInset delimiter
* src/mathed/math_biginset.C
(MathBigInset::size): handle Big, Bigg and Biggg
(MathBigInset::increase): ditto
(MathBigInset::draw): fix deco drawing
(MathBigInset::write): append space if necessary
* src/mathed/math_factory.C
(createMathInset): handle l->inset == "big"
* src/mathed/math_parser.C
(Token::asInput): return a token as input, stolen from tex2lyx
(void Parser::parse1): Create a MathBigInset when needed
* src/mathed/math_support.C:
(deco_table): add lbrace and rbrace
* src/mathed/math_nestinset.C
(MathNestInset::interpret): combine the previous math atom with the
new character to a MathBigInset if possible
* src/ParagraphParameters.C
(findToken): move from here
* src/support/lstrings.[Ch]
(findToken): to here
* lib/symbols: add MathBigInset symbols
Index: src/cursor.C
===================================================================
--- src/cursor.C (Revision 13698)
+++ src/cursor.C (Arbeitskopie)
@@ -35,10 +35,12 @@
#include "insets/insettabular.h"
#include "insets/insettext.h"
+#include "mathed/math_biginset.h"
#include "mathed/math_data.h"
#include "mathed/math_inset.h"
#include "mathed/math_scriptinset.h"
#include "mathed/math_macrotable.h"
+#include "mathed/math_parser.h"
#include "support/limited_stack.h"
@@ -650,6 +652,22 @@ void LCursor::markErase()
void LCursor::plainInsert(MathAtom const & t)
{
+ // Create a MathBigInset from cell()[pos() - 1] and t if possible
+ if (!empty() && pos() > 0 && cell()[pos() - 1]->asUnknownInset()) {
+ string const name = asString(t);
+ if (MathBigInset::isBigInsetDelim(name)) {
+ string prev = asString(cell()[pos() - 1]);
+ if (prev[0] == '\\') {
+ prev = prev.substr(1);
+ latexkeys const * l = in_word_set(prev);
+ if (l && l->inset == "big") {
+ cell()[pos() - 1] =
+ MathAtom(new MathBigInset(prev, name));
+ return;
+ }
+ }
+ }
+ }
cell().insert(pos(), t);
++pos();
}
Index: src/mathed/math_biginset.h
===================================================================
--- src/mathed/math_biginset.h (Revision 13698)
+++ src/mathed/math_biginset.h (Arbeitskopie)
@@ -16,12 +16,14 @@
#include <string>
-/// Inset for \bigl & Co.
+/// Inset for \\bigl & Co.
class MathBigInset : public MathDimInset {
public:
///
MathBigInset(std::string const & name, std::string const & delim);
///
+ std::string name() const;
+ ///
void metrics(MetricsInfo & mi, Dimension & dim) const;
///
void draw(PainterInfo & pi, int x, int y) const;
@@ -29,6 +31,8 @@ public:
void write(WriteStream & os) const;
///
void normalize(NormalStream & os) const;
+ ///
+ static bool isBigInsetDelim(std::string const &);
private:
virtual std::auto_ptr<InsetBase> doClone() const;
@@ -37,9 +41,9 @@ private:
///
double increase() const;
- /// \bigl or what?
+ /// \\bigl or what?
std::string const name_;
- /// ( or [ or Vert...
+ /// ( or [ or \\Vert...
std::string const delim_;
};
Index: src/mathed/math_factory.C
===================================================================
--- src/mathed/math_factory.C (Revision 13698)
+++ src/mathed/math_factory.C (Arbeitskopie)
@@ -276,6 +276,10 @@ MathAtom createMathInset(string const &
return MathAtom(new MathFontOldInset(l));
if (inset == "matrix")
return MathAtom(new MathAMSArrayInset(s));
+ if (inset == "big")
+ // we can't create a MathBigInset, since the argument
+ // is missing.
+ return MathAtom(new MathUnknownInset(s));
return MathAtom(new MathSymbolInset(l));
}
Index: src/mathed/math_parser.C
===================================================================
--- src/mathed/math_parser.C (Revision 13698)
+++ src/mathed/math_parser.C (Arbeitskopie)
@@ -40,6 +40,7 @@ following hack as starting point to writ
#include "math_parser.h"
#include "math_arrayinset.h"
+#include "math_biginset.h"
#include "math_braceinset.h"
#include "math_charinset.h"
#include "math_colorinset.h"
@@ -256,6 +257,8 @@ public:
char character() const { return char_; }
///
string asString() const { return cs_.size() ? cs_ : string(1, char_); }
+ ///
+ string asInput() const { return cs_.size() ? '\\' + cs_ : string(1, char_); }
private:
///
@@ -1298,7 +1301,20 @@ void Parser::parse1(MathGridInset & grid
else if (t.cs().size()) {
latexkeys const * l = in_word_set(t.cs());
if (l) {
- if (l->inset == "font") {
+ if (l->inset == "big") {
+ skipSpaces();
+ string const delim = getToken().asInput();
+ if (MathBigInset::isBigInsetDelim(delim))
+ cell->push_back(MathAtom(
+ new MathBigInset(t.cs(), delim)));
+ else {
+ cell->push_back(createMathInset(t.cs()));
+ cell->push_back(createMathInset(
+ delim.substr(1)));
+ }
+ }
+
+ else if (l->inset == "font") {
cell->push_back(createMathInset(t.cs()));
parse(cell->back().nucleus()->cell(0),
FLAG_ITEM, asMode(mode, l->extra));
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C (Revision 13698)
+++ src/mathed/math_nestinset.C (Arbeitskopie)
@@ -13,6 +13,7 @@
#include "math_nestinset.h"
#include "math_arrayinset.h"
+#include "math_biginset.h"
#include "math_boxinset.h"
#include "math_braceinset.h"
#include "math_colorinset.h"
@@ -1144,6 +1145,36 @@ bool MathNestInset::interpret(LCursor &
return true;
}
+ // One character big delimiters. The others are handled in
+ // LCursor::plainInsert.
+ latexkeys const * l = in_word_set(name.substr(1));
+ if (name[0] == '\\' && l && l->inset == "big") {
+ string delim;
+ switch (c) {
+ case '{':
+ delim = "\\{";
+ break;
+ case '}':
+ delim = "\\}";
+ break;
+ default:
+ delim = string(1, c);
+ break;
+ }
+ if (MathBigInset::isBigInsetDelim(delim)) {
+ // name + delim ared a valid MathBigInset.
+ // We can't use cur.macroModeClose() because
+ // it does not handle delim.
+ MathUnknownInset * p = cur.activeMacro();
+ p->finalize();
+ --cur.pos();
+ cur.cell().erase(cur.pos());
+ cur.plainInsert(MathAtom(
+ new MathBigInset(name.substr(1), delim)));
+ return true;
+ }
+ }
+
// leave macro mode and try again if necessary
cur.macroModeClose();
if (c == '{')
Index: src/mathed/math_biginset.C
===================================================================
--- src/mathed/math_biginset.C (Revision 13698)
+++ src/mathed/math_biginset.C (Arbeitskopie)
@@ -15,6 +15,8 @@
#include "math_mathmlstream.h"
#include "math_streamstr.h"
+#include "support/lstrings.h"
+
using std::string;
using std::auto_ptr;
@@ -25,6 +27,12 @@ MathBigInset::MathBigInset(string const
{}
+string MathBigInset::name() const
+{
+ return name_;
+}
+
+
auto_ptr<InsetBase> MathBigInset::doClone() const
{
return auto_ptr<InsetBase>(new MathBigInset(*this));
@@ -33,18 +41,21 @@ auto_ptr<InsetBase> MathBigInset::doClon
MathBigInset::size_type MathBigInset::size() const
{
- return name_.size() - 4;
+ // order: big Big bigg Bigg biggg Biggg
+ // 0 1 2 3 4 5
+ return name_[0] == 'B' ?
+ 2 * (name_.size() - 4) + 1:
+ 2 * (name_.size() - 4);
}
double MathBigInset::increase() const
{
- switch (size()) {
- case 1: return 0.2;
- case 2: return 0.44;
- case 3: return 0.7;
- default: return 0.0;
- }
+ // The formula used in amsmath.sty is
+ // 1.2 * (1.0 + size() * 0.5) - 1.0.
+ // We use a smaller step and a bigger offset because our base size
+ // is different.
+ return (size() + 1) * 0.3;
}
@@ -61,13 +72,23 @@ void MathBigInset::metrics(MetricsInfo &
void MathBigInset::draw(PainterInfo & pi, int x, int y) const
{
- mathed_draw_deco(pi, x + 1, y - dim_.ascent(), 4, dim_.height(), delim_);
+ // mathed_draw_deco does not use the leading backslash, so remove it.
+ // Replace \| by \Vert (equivalent in LaTeX), since mathed_draw_deco
+ // would treat it as |.
+ string const delim = (delim_ == "\\|") ?
+ "Vert" :
+ lyx::support::ltrim(delim_, "\\");
+ mathed_draw_deco(pi, x + 1, y - dim_.ascent(), 4, dim_.height(),
+ delim);
+ setPosCache(pi, x, y);
}
void MathBigInset::write(WriteStream & os) const
{
os << '\\' << name_ << ' ' << delim_;
+ if (delim_[0] == '\\')
+ os.pendingSpace(true);
}
@@ -75,3 +96,19 @@ void MathBigInset::normalize(NormalStrea
{
os << '[' << name_ << ' ' << delim_ << ']';
}
+
+
+bool MathBigInset::isBigInsetDelim(string const & delim)
+{
+ // mathed_draw_deco must handle these
+ static char const * const delimiters[] = {
+ "(", ")", "\\{", "\\}", "\\lbrace", "\\rbrace", "[", "]",
+ "|", "/", "\\|", "\\vert", "\\Vert", "'", "\\backslash",
+ "\\langle", "\\lceil", "\\lfloor",
+ "\\rangle", "\\rceil", "\\rfloor",
+ "\\downarrow", "\\Downarrow",
+ "\\uparrow", "\\Uparrow",
+ "\\updownarrow", "\\Updownarrow", ""
+ };
+ return (lyx::support::findToken(delimiters, delim) >= 0);
+}
Index: src/mathed/math_support.C
===================================================================
--- src/mathed/math_support.C (Revision 13698)
+++ src/mathed/math_support.C (Arbeitskopie)
@@ -283,6 +283,8 @@ named_deco_struct deco_table[] = {
{")", parenth, 2 },
{"{", brace, 0 },
{"}", brace, 2 },
+ {"lbrace", brace, 0 },
+ {"rbrace", brace, 2 },
{"[", brack, 0 },
{"]", brack, 2 },
{"|", vert, 0 },
Index: src/ParagraphParameters.C
===================================================================
--- src/ParagraphParameters.C (Revision 13698)
+++ src/ParagraphParameters.C (Arbeitskopie)
@@ -40,20 +40,11 @@ using std::string;
// anonym namespace
namespace {
-int findToken(char const * const str[], string const search_token)
+int findToken(char const * const str[], string const & search_token)
{
- int i = 0;
-
- if (search_token != "default") {
- while (str[i][0] && str[i] != search_token) {
- ++i;
- }
- if (!str[i][0]) {
- i = -1;
- }
- }
-
- return i;
+ return search_token == "default" ?
+ 0 :
+ lyx::support::findToken(str, search_token);
}
}
Index: src/support/lstrings.C
===================================================================
--- src/support/lstrings.C (Revision 13698)
+++ src/support/lstrings.C (Arbeitskopie)
@@ -534,6 +534,18 @@ string const getStringFromVector(vector<
}
+int findToken(char const * const str[], string const & search_token)
+{
+ int i = 0;
+
+ while (str[i][0] && str[i] != search_token)
+ ++i;
+ if (!str[i][0])
+ i = -1;
+ return i;
+}
+
+
#ifndef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES
#if USE_BOOST_FORMAT
Index: src/support/lstrings.h
===================================================================
--- src/support/lstrings.h (Revision 13698)
+++ src/support/lstrings.h (Arbeitskopie)
@@ -176,6 +176,10 @@ std::vector<std::string> const getVector
std::string const getStringFromVector(std::vector<std::string> const & vec,
std::string const & delim = std::string(","));
+/// Search \p search_token in \p str and return the position if it is
+/// found, else -1. The last item in \p str must be "".
+int findToken(char const * const str[], std::string const & search_token);
+
#ifdef I_AM_NOT_AFRAID_OF_HEADER_LIBRARIES
Index: lib/symbols
===================================================================
--- lib/symbols (Revision 13698)
+++ lib/symbols (Arbeitskopie)
@@ -41,6 +41,28 @@ dotso dots none
ldots dots none
vdots dots none
+# big delimiters
+bigl big none
+bigm big none
+bigr big none
+Bigl big none
+Bigm big none
+Bigr big none
+biggl big none
+biggm big none
+biggr big none
+Biggl big none
+Biggm big none
+Biggr big none
+# The following are not standard LaTeX, but defined in the lucida font
+# packages. No 'm' versions!
+# See lucidabr.dtx for a possible implementation if you want to use these
+# with other fonts.
+bigggl big none
+bigggr big none
+Bigggl big none
+Bigggr big none
+
# font changes
# name "font" math/text family series shape color
# mathnormal should stay the first