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


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13700 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2006-04-20 09:55:45 +00:00
parent c9b081f6f9
commit 2bbe7e5b89
11 changed files with 166 additions and 25 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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 & name, string const & delim)
{}
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::doClone() const
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 & mi, Dimension & dim) const
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(NormalStream & os) const
{
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);
}

View File

@ -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_;
};

View File

@ -276,6 +276,10 @@ MathAtom createMathInset(string const & s)
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));
}

View File

@ -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 & cur, char c)
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 == '{')

View File

@ -40,6 +40,7 @@ following hack as starting point to write some macros:
#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, unsigned flags,
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));

View File

@ -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 },

View File

@ -534,6 +534,18 @@ string const getStringFromVector(vector<string> const & vec,
}
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

View File

@ -176,6 +176,10 @@ std::vector<std::string> const getVectorFromString(std::string const & str,
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