diff --git a/lib/ChangeLog b/lib/ChangeLog index 54fba76536..d3c9af4599 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,7 @@ +2006-10-26 Enrico Forestieri + + * symbols: add MathBigInset symbols. + 2006-10-26 Jean-Marc Lasgouttes * CREDITS: diff --git a/lib/symbols b/lib/symbols index 65a6958dc0..583fe1a217 100644 --- a/lib/symbols +++ b/lib/symbols @@ -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 diff --git a/src/ChangeLog b/src/ChangeLog index b08cc8a1e9..693ac7f33d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,14 @@ +2006-10-26 Enrico Forestieri + + * lfuns.h (enum kb_action): New lfun LFUN_MATH_BIGDELIM + * LyXAction.C (init): New lfun LFUN_MATH_BIGDELIM + * cursor.C (macroModeClose): try to intepret the current macro before + it is simply inserted + * ParagraphParameters.C (findToken): move from here to lstrings.[Ch] + * text3.C (dispatch): handle LFUN_MATH_BIGDELIM + (getStatus): ditto + * ToolbarBackend.C (getIcon): handle LFUN_MATH_BIGDELIM + 2006-10-25 Jean-Marc Lasgouttes * text.C (backspacePos0): rewrite to make it simple and allow diff --git a/src/LyXAction.C b/src/LyXAction.C index de8d1ff455..a4589a8c20 100644 --- a/src/LyXAction.C +++ b/src/LyXAction.C @@ -212,6 +212,7 @@ void LyXAction::init() { LFUN_MARK_ON, "mark-on", ReadOnly }, { LFUN_SETMARK, "mark-toggle", ReadOnly }, { LFUN_MATH_DELIM, "math-delim", Noop }, + { LFUN_MATH_BIGDELIM, "math-bigdelim", Noop }, { LFUN_MATH_DISPLAY, "math-display", Noop }, { LFUN_INSERT_MATH, "math-insert", Noop }, { LFUN_SUBSCRIPT, "math-subscript", Noop }, diff --git a/src/ParagraphParameters.C b/src/ParagraphParameters.C index 1f5da6720a..6fead69a33 100644 --- a/src/ParagraphParameters.C +++ b/src/ParagraphParameters.C @@ -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); } } diff --git a/src/ToolbarBackend.C b/src/ToolbarBackend.C index baa2ddfbcd..82660dbc92 100644 --- a/src/ToolbarBackend.C +++ b/src/ToolbarBackend.C @@ -217,12 +217,16 @@ string const ToolbarBackend::getIcon(FuncRequest const & f) string fullname; - if (f.action == LFUN_INSERT_MATH) { + switch (f.action) { + case LFUN_INSERT_MATH: if (!f.argument.empty()) fullname = find_xpm(f.argument.substr(1)); - } else if (f.action == LFUN_MATH_DELIM) { + break; + case LFUN_MATH_DELIM: + case LFUN_MATH_BIGDELIM: fullname = find_xpm(f.argument); - } else { + break; + default: string const name = lyxaction.getActionName(f.action); string xpm_name(name); diff --git a/src/cursor.C b/src/cursor.C index ec74719902..5e8e5e198a 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -39,6 +39,7 @@ #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" @@ -857,6 +858,9 @@ bool LCursor::macroModeClose() if (macro && macro->getInsetName() == name) lyxerr << "can't enter recursive macro" << endl; + MathNestInset * const in = inset().asMathInset()->asNestInset(); + if (in && in->interpret(*this, s)) + return true; plainInsert(createMathInset(name)); return true; } diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index 857c0d7b81..309fe33367 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,8 @@ +2006-10-26 Enrico Forestieri + + * ControlMath.[Ch]: (dispatchBigDelim): new, deal with fixed size + delimiters. + 2006-08-16 Jean-Marc Lasgouttes * ControlAboutlyx.C (getVersion): change a bit the display of LyX diff --git a/src/frontends/controllers/ControlMath.C b/src/frontends/controllers/ControlMath.C index 43001606ac..d72f610643 100644 --- a/src/frontends/controllers/ControlMath.C +++ b/src/frontends/controllers/ControlMath.C @@ -79,6 +79,12 @@ void ControlMath::dispatchDelim(string const & str) const } +void ControlMath::dispatchBigDelim(string const & str) const +{ + dispatchFunc(LFUN_MATH_BIGDELIM, str); +} + + void ControlMath::dispatchToggleDisplay() const { dispatchFunc(LFUN_MATH_DISPLAY); diff --git a/src/frontends/controllers/ControlMath.h b/src/frontends/controllers/ControlMath.h index 0f220775ae..b843f75574 100644 --- a/src/frontends/controllers/ControlMath.h +++ b/src/frontends/controllers/ControlMath.h @@ -43,9 +43,11 @@ public: void dispatchCubeRoot() const; /// Insert a matrix void dispatchMatrix(std::string const & str) const; - /// Insert a delimiter + /// Insert a variable size delimiter void dispatchDelim(std::string const & str) const; - /// Wwitch between display and inline + /// Insert a big delimiter + void dispatchBigDelim(std::string const & str) const; + /// Switch between display and inline void dispatchToggleDisplay() const; /** A request to the kernel to launch a dialog. * \param name the dialog identifier. diff --git a/src/frontends/gtk/ChangeLog b/src/frontends/gtk/ChangeLog index 88a47c25d2..513a45a45e 100644 --- a/src/frontends/gtk/ChangeLog +++ b/src/frontends/gtk/ChangeLog @@ -1,3 +1,7 @@ +2006-10-26 Enrico Forestieri + + * GMathDelim.C: Add FIXME comment for fixed size delimiters. + 2006-03-20 Jürgen Spitzmüller * GBibtex.C: Move parsing of Options (stylefile, bibtotoc) diff --git a/src/frontends/gtk/GMathDelim.C b/src/frontends/gtk/GMathDelim.C index 1213c239a3..9688c54562 100644 --- a/src/frontends/gtk/GMathDelim.C +++ b/src/frontends/gtk/GMathDelim.C @@ -36,6 +36,8 @@ using std::string; namespace lyx { namespace frontend { +// FIXME: Implement fixed size delimiters (see qt3 and xforms frontends) + namespace { diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index 69a6d1fc97..000d1eefce 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,10 @@ +2006-10-26 Enrico Forestieri + + * QDelimiterDialog.[Ch] (fix_name, QDelimiterDialog, insertClicked, + size_selected): Allow for fixed size delimiters. + * ui/QDelimiterDialogBase.ui: Added a combobox for selecting + delimiter size. + 2006-10-16 Jürgen Spitzmüller * QDocumentDialog.C (updateNumbering): don't include headings diff --git a/src/frontends/qt2/QDelimiterDialog.C b/src/frontends/qt2/QDelimiterDialog.C index c3e7fd27fa..9a32674a2f 100644 --- a/src/frontends/qt2/QDelimiterDialog.C +++ b/src/frontends/qt2/QDelimiterDialog.C @@ -18,9 +18,14 @@ #include "controllers/ControlMath.h" +#include "gettext.h" + #include #include #include +#include + +#include using std::string; @@ -38,6 +43,12 @@ char const * delim[] = { }; +char const * const bigleft[] = {"bigl", "Bigl", "biggl", "Biggl", ""}; +char const * const bigright[] = {"bigr", "Bigr", "biggr", "Biggr", ""}; +char const * const biggui[] = {N_("big size"), N_("Big size"), + N_("bigg size"), N_("Bigg size"), ""}; + + string do_match(const string & str) { if (str == "(") return ")"; @@ -59,7 +70,7 @@ string do_match(const string & str) } -string fix_name(const string & str) +string fix_name(const string & str, bool big) { if (str == "slash") return "/"; @@ -67,7 +78,10 @@ string fix_name(const string & str) return "\\"; if (str == "empty") return "."; - return str; + if (!big || str == "(" || str == ")" || str == "[" || str == "]") + return str; + + return "\\" + str; } } // namespace anon @@ -89,11 +103,17 @@ QDelimiterDialog::QDelimiterDialog(QMathDelimiter * form) leftIP->add(QPixmap(toqstr(empty_xpm)), "empty", "empty"); rightIP->add(QPixmap(toqstr(empty_xpm)), "empty", "empty"); + delimSize->insertItem(qt_("Variable size")); + for (int i = 0; *biggui[i]; ++i) + delimSize->insertItem(qt_(biggui[i])); + size_ = 0; // Leave these std:: qualifications alone ! connect(leftIP, SIGNAL(button_clicked(const std::string &)), this, SLOT(ldelim_clicked(const std::string &))); connect(rightIP, SIGNAL(button_clicked(const std::string &)), this, SLOT(rdelim_clicked(const std::string &))); + connect(delimSize, SIGNAL(activated(int)), + this, SLOT(size_selected(int)) ); ldelim_clicked("("); rdelim_clicked(")"); } @@ -101,7 +121,18 @@ QDelimiterDialog::QDelimiterDialog(QMathDelimiter * form) void QDelimiterDialog::insertClicked() { - form_->controller().dispatchDelim(fix_name(left_) + ' ' + fix_name(right_)); + if (size_ == 0) { + form_->controller().dispatchDelim( + fix_name(left_, false) + ' ' + + fix_name(right_, false)); + } else { + std::ostringstream os; + os << '"' << bigleft[size_ - 1] << "\" \"" + << fix_name(left_, true) << "\" \"" + << bigright[size_ - 1] << "\" \"" + << fix_name(right_, true) << '"'; + form_->controller().dispatchBigDelim(os.str()); + } } @@ -137,5 +168,11 @@ void QDelimiterDialog::rdelim_clicked(const string & str) } } + +void QDelimiterDialog::size_selected(int index) +{ + size_ = index; +} + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt2/QDelimiterDialog.h b/src/frontends/qt2/QDelimiterDialog.h index 53b2324e24..9bab95b05f 100644 --- a/src/frontends/qt2/QDelimiterDialog.h +++ b/src/frontends/qt2/QDelimiterDialog.h @@ -30,6 +30,7 @@ public: public slots: void ldelim_clicked(const std::string & str); void rdelim_clicked(const std::string & str); + void size_selected(int); void insertClicked(); protected: //needed ? virtual void closeEvent(QCloseEvent * e); @@ -42,6 +43,9 @@ private: /// symbol of right delimiter std::string right_; + /// size of delimiters + int size_; + /// owning form QMathDelimiter * form_; }; diff --git a/src/frontends/qt2/ui/QDelimiterDialogBase.ui b/src/frontends/qt2/ui/QDelimiterDialogBase.ui index 4bf30d9bba..3cb6ef0594 100644 --- a/src/frontends/qt2/ui/QDelimiterDialogBase.ui +++ b/src/frontends/qt2/ui/QDelimiterDialogBase.ui @@ -350,6 +350,22 @@ + + + delimSize + + + + 7 + 0 + 0 + 0 + + + + Choose delimiter size + + diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index f3dc082381..767c9d3343 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,11 @@ +2006-10-26 Enrico Forestieri + + * forms/form_maths_delim.fd: Add combobox for selecting delimiter size. + * FormMathsDelim.h: Add private variable to store delimiter size. + * FormMathsDelim.C: Correct entry in delim_rversion[]. + (fix_name): new, return correct name for fixed size delimiter. + (build, apply, update): allow for fixed size delimiters. + 2006-08-13 Jean-Marc Lasgouttes * FormErrorList.C (update): do not call updateContents if the diff --git a/src/frontends/xforms/FormMathsDelim.C b/src/frontends/xforms/FormMathsDelim.C index 26a5beb559..90e3708624 100644 --- a/src/frontends/xforms/FormMathsDelim.C +++ b/src/frontends/xforms/FormMathsDelim.C @@ -18,13 +18,16 @@ #include "ControlMath.h" #include "bmtable.h" +#include "xforms_helpers.h" #include "xformsBC.h" #include "controllers/ButtonController.h" #include +#include using std::ostringstream; +using std::string; #include "delim.xbm" #include "delim0.xpm" @@ -37,7 +40,7 @@ namespace { int const delim_rversion[] = { 1,1,3,3,4,5,7,7,9,9,10,11, - 3,13,15,15,16,17,19,19,20,21,22 + 13,13,15,15,16,17,19,19,20,21,22 }; int const delim_size = sizeof(delim_rversion) / sizeof(delim_rversion[0]); @@ -50,6 +53,20 @@ char const * delim_values[] = { }; +string fix_name(string const & str) +{ + if (str == "(" || str == ")" || str == "[" || str == "]" || + str == "/" || str == "|" || str == ".") + return str; + + return "\\" + str; +} + + +char const * const bigleft[] = {"bigl", "Bigl", "biggl", "Biggl", ""}; +char const * const bigright[] = {"bigr", "Bigr", "biggr", "Biggr", ""}; +char const * const biggui[] = {N_("big"), N_("Big"), N_("bigg"), N_("Bigg"), ""}; + } // namespace anon @@ -64,6 +81,11 @@ void FormMathsDelim::build() { dialog_.reset(build_maths_delim(this)); + size_ = 0; + fl_addto_choice(dialog_->choice_size, _(N_("Variable")).c_str()); + for (int i = 0; *biggui[i]; ++i) + fl_addto_choice(dialog_->choice_size, _(biggui[i]).c_str()); + fl_set_button(dialog_->radio_left, 1); // Initialize button_pix to "()" as found in images/delim0.xpm: fl_set_pixmap_data(dialog_->button_pix, const_cast(delim0)); @@ -91,15 +113,26 @@ void FormMathsDelim::apply() { int const left = int(dialog_->radio_left->u_ldata); int const right = int(dialog_->radio_right->u_ldata); + size_ = fl_get_choice(dialog_->choice_size) - 1; ostringstream os; - os << delim_values[left] << ' ' << delim_values[right]; - controller().dispatchDelim(os.str()); + if (size_ == 0) { + os << delim_values[left] << ' ' << delim_values[right]; + controller().dispatchDelim(os.str()); + } else { + os << '"' << bigleft[size_ - 1] << "\" \"" + << fix_name(delim_values[left]) << "\" \"" + << bigright[size_ - 1] << "\" \"" + << fix_name(delim_values[right]) << '"'; + controller().dispatchBigDelim(os.str()); + } } void FormMathsDelim::update() { + fl_set_choice(dialog_->choice_size, size_ + 1); + setEnabled(dialog_->choice_size, true); bc().valid(); } diff --git a/src/frontends/xforms/FormMathsDelim.h b/src/frontends/xforms/FormMathsDelim.h index 6563896b25..397dc308ba 100644 --- a/src/frontends/xforms/FormMathsDelim.h +++ b/src/frontends/xforms/FormMathsDelim.h @@ -40,6 +40,8 @@ private: virtual ButtonPolicy::SMInput input(FL_OBJECT *, long); /// virtual void update(); + /// size of delimiters + int size_; }; } // namespace frontend diff --git a/src/frontends/xforms/forms/form_maths_delim.fd b/src/frontends/xforms/forms/form_maths_delim.fd index bc340b544d..a129fbdda5 100644 --- a/src/frontends/xforms/forms/form_maths_delim.fd +++ b/src/frontends/xforms/forms/form_maths_delim.fd @@ -11,7 +11,7 @@ SnapGrid: 2 Name: form_maths_delim Width: 250 Height: 221 -Number of Objects: 11 +Number of Objects: 12 -------------------- class: FL_BOX @@ -70,7 +70,7 @@ argument: 0 -------------------- class: FL_PIXMAPBUTTON type: NORMAL_BUTTON -box: 100 58 50 40 +box: 47 58 50 40 boxtype: FL_UP_BOX colors: FL_COL1 FL_COL1 alignment: FL_ALIGN_BOTTOM @@ -85,6 +85,24 @@ name: button_pix callback: C_FormDialogView_ApplyCB argument: 0 +-------------------- +class: FL_CHOICE +type: NORMAL_CHOICE +box: 107 73 80 25 +boxtype: FL_FRAME_BOX +colors: FL_COL1 FL_BLACK +alignment: FL_ALIGN_TOP +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: Size:|#S +shortcut: +resize: FL_RESIZE_X +gravity: FL_NoGravity FL_NoGravity +name: choice_size +callback: C_FormDialogView_InputCB +argument: 0 + -------------------- class: FL_BUTTON type: NORMAL_BUTTON diff --git a/src/lfuns.h b/src/lfuns.h index 7d866e9808..fa93cc913b 100644 --- a/src/lfuns.h +++ b/src/lfuns.h @@ -363,8 +363,9 @@ enum kb_action { LFUN_OUTLINE_IN, LFUN_OUTLINE_OUT, LFUN_TOGGLE_COMPRESSION, // bpeng 20060427 - // 275 - LFUN_INSET_DISSOLVE, // jspitzm 20060807 + LFUN_INSET_DISSOLVE, // jspitzm 20060807 + // 280 + LFUN_MATH_BIGDELIM, LFUN_LASTACTION // end of the table }; diff --git a/src/mathed/ChangeLog b/src/mathed/ChangeLog index 3b16171565..bf3cff246c 100644 --- a/src/mathed/ChangeLog +++ b/src/mathed/ChangeLog @@ -1,3 +1,27 @@ +2006-10-26 Enrico Forestieri + + * math_biginset.[Ch] (name): implement + (isBigInsetDelim): new, test whether a given token is a valid + MathBigInset delimiter. + (infoize2): implement to show name if the cursor is to the right. + * math_biginset.C (size, increase): handle Big, bigg and Bigg. + (draw): fix deco drawing. + (write): don't write space before delimiter but append one if necessary + * math_factory.C (createMathInset): handle l->inset == "big" + * math_parser.C (asInput): return a token as input, stolen from tex2lyx + (parse1): create a MathBigInset when needed. + * math_nestinset.C (doDispatch): try to intepret the argument of + LFUN_SELFINSERT also if it is longer than one character. + (doDispatch): remove debug message. + (doDispatch): remove LFUN_MATH_DELIM test for multiple cells (now + in getStatus). + (doDispatch): handle LFUN_MATH_BIGDELIM. + (getStatus): Disable LFUN_MATH_DELIM and LFUN_MATH_BIGDELIM when + the selection spans multiple cells. + * math_nestinset.[Ch] (interpret): new, combine the previous math + atom with the new character to a MathBigInset if possible. + * math_support.C (deco_table): add lbrace and rbrace. + 2006-10-09 Jürgen Spitzmüller * math_hullinset.C (doDispatch): changeRefsIfUnique needs a diff --git a/src/mathed/math_biginset.C b/src/mathed/math_biginset.C index ade63c123b..316b75835d 100644 --- a/src/mathed/math_biginset.C +++ b/src/mathed/math_biginset.C @@ -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 MathBigInset::doClone() const { return auto_ptr(new MathBigInset(*this)); @@ -33,18 +41,21 @@ auto_ptr 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_; + os << '\\' << name_ << delim_; + if (delim_[0] == '\\') + os.pendingSpace(true); } @@ -75,3 +96,25 @@ void MathBigInset::normalize(NormalStream & os) const { os << '[' << name_ << ' ' << delim_ << ']'; } + + +void MathBigInset::infoize2(std::ostream & os) const +{ + os << name_; +} + + +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); +} diff --git a/src/mathed/math_biginset.h b/src/mathed/math_biginset.h index f9547cc469..5d85fa2fa1 100644 --- a/src/mathed/math_biginset.h +++ b/src/mathed/math_biginset.h @@ -16,12 +16,14 @@ #include -/// 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,10 @@ public: void write(WriteStream & os) const; /// void normalize(NormalStream & os) const; + /// + void infoize2(std::ostream & os) const; + /// + static bool isBigInsetDelim(std::string const &); private: virtual std::auto_ptr doClone() const; @@ -37,9 +43,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_; }; diff --git a/src/mathed/math_factory.C b/src/mathed/math_factory.C index 024d54cf04..af3107cf84 100644 --- a/src/mathed/math_factory.C +++ b/src/mathed/math_factory.C @@ -278,6 +278,10 @@ MathAtom createMathInset(string const & s) return MathAtom(new MathAMSArrayInset(s)); if (inset == "split") return MathAtom(new MathSplitInset(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)); } diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 01e0a30fca..4c53aab817 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -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" @@ -657,7 +658,8 @@ void MathNestInset::doDispatch(LCursor & cur, FuncRequest & cmd) case LFUN_SELFINSERT: if (cmd.argument.size() != 1) { recordUndo(cur); - cur.insert(cmd.argument); + if (!interpret(cur, cmd.argument)) + cur.insert(cmd.argument); break; } // Don't record undo steps if we are in macro mode and @@ -840,7 +842,6 @@ void MathNestInset::doDispatch(LCursor & cur, FuncRequest & cmd) } case LFUN_MATH_DELIM: { - lyxerr << "MathNestInset::LFUN_MATH_DELIM" << endl; string ls; string rs = lyx::support::split(cmd.argument, ls, ' '); // Reasonable default values @@ -849,9 +850,37 @@ void MathNestInset::doDispatch(LCursor & cur, FuncRequest & cmd) if (rs.empty()) rs = ')'; recordUndo(cur, Undo::ATOMIC); - // Don't do this with multi-cell selections - if (cur.selBegin().idx() == cur.selEnd().idx()) - cur.handleNest(MathAtom(new MathDelimInset(ls, rs))); + cur.handleNest(MathAtom(new MathDelimInset(ls, rs))); + break; + } + + case LFUN_MATH_BIGDELIM: { + string const lname = cmd.getArg(0); + string const ldelim = cmd.getArg(1); + string const rname = cmd.getArg(2); + string const rdelim = cmd.getArg(3); + latexkeys const * l = in_word_set(lname); + bool const have_l = l && l->inset == "big" && + MathBigInset::isBigInsetDelim(ldelim); + l = in_word_set(rname); + bool const have_r = l && l->inset == "big" && + MathBigInset::isBigInsetDelim(rdelim); + // We mimic LFUN_MATH_DELIM in case we have an empty left + // or right delimiter. + if (have_l || have_r) { + recordUndo(cur, Undo::ATOMIC); + string const selection = grabAndEraseSelection(cur); + selClearOrDel(cur); + if (have_l) + cur.insert(MathAtom(new MathBigInset(lname, + ldelim))); + cur.niceInsert(selection); + if (have_r) + cur.insert(MathAtom(new MathBigInset(rname, + rdelim))); + } + // Don't call cur.undispatched() if we did nothing, this would + // lead to infinite recursion via LyXText::dispatch(). break; } @@ -909,7 +938,7 @@ void MathNestInset::doDispatch(LCursor & cur, FuncRequest & cmd) } -bool MathNestInset::getStatus(LCursor & /*cur*/, FuncRequest const & cmd, +bool MathNestInset::getStatus(LCursor & cur, FuncRequest const & cmd, FuncStatus & flag) const { // the font related toggles @@ -985,6 +1014,13 @@ bool MathNestInset::getStatus(LCursor & /*cur*/, FuncRequest const & cmd, case LFUN_INSERT_MATRIX: flag.enabled(currentMode() == MATH_MODE); break; + + case LFUN_MATH_DELIM: + case LFUN_MATH_BIGDELIM: + // Don't do this with multi-cell selections + flag.enabled(cur.selBegin().idx() == cur.selEnd().idx()); + break; + default: ret = false; break; @@ -1138,6 +1174,36 @@ bool MathNestInset::interpret(LCursor & cur, char c) return true; } + // One character big delimiters. The others are handled in + // the other interpret() method. + 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 == '{') @@ -1214,8 +1280,8 @@ bool MathNestInset::interpret(LCursor & cur, char c) } } - if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' || c == '%' - || c == '_' || c == '^') { + if (c == '{' || c == '}' || c == '&' || c == '$' || c == '#' || + c == '%' || c == '_' || c == '^') { cur.niceInsert(createMathInset(string(1, c))); return true; } @@ -1232,6 +1298,29 @@ bool MathNestInset::interpret(LCursor & cur, char c) } +bool MathNestInset::interpret(LCursor & cur, string const & str) +{ + // Create a MathBigInset from cur.cell()[cur.pos() - 1] and t if + // possible + if (!cur.empty() && cur.pos() > 0 && + cur.cell()[cur.pos() - 1]->asUnknownInset()) { + if (MathBigInset::isBigInsetDelim(str)) { + string prev = asString(cur.cell()[cur.pos() - 1]); + if (prev[0] == '\\') { + prev = prev.substr(1); + latexkeys const * l = in_word_set(prev); + if (l && l->inset == "big") { + cur.cell()[cur.pos() - 1] = + MathAtom(new MathBigInset(prev, str)); + return true; + } + } + } + } + return false; +} + + bool MathNestInset::script(LCursor & cur, bool up, string const & save_selection) { diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index cb4e31c786..f0a7492326 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -107,12 +107,18 @@ protected: /// void handleFont2(LCursor & cur, std::string const & arg); - /// + /// interpret \p c and insert the result at the current position of + /// of \p cur. Return whether the cursor should stay in the formula. bool interpret(LCursor & cur, char c); /// bool script(LCursor & cur, bool, std::string const & save_selection = std::string()); +public: + /// interpret \p str and insert the result at the current position of + /// \p cur if it is something known. Return whether \p cur was + /// inserted. + bool interpret(LCursor & cur, std::string const & str); private: /// lfun handler diff --git a/src/mathed/math_parser.C b/src/mathed/math_parser.C index 4d01de5f85..d10db72437 100644 --- a/src/mathed/math_parser.C +++ b/src/mathed/math_parser.C @@ -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" @@ -257,6 +258,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: /// @@ -1316,7 +1319,19 @@ 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())); + putback(); + } + } + + else if (l->inset == "font") { cell->push_back(createMathInset(t.cs())); parse(cell->back().nucleus()->cell(0), FLAG_ITEM, asMode(mode, l->extra)); diff --git a/src/mathed/math_support.C b/src/mathed/math_support.C index f857d8e753..04bcaacdee 100644 --- a/src/mathed/math_support.C +++ b/src/mathed/math_support.C @@ -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 }, diff --git a/src/support/lstrings.C b/src/support/lstrings.C index 7d58d73b54..b4b70f0f0c 100644 --- a/src/support/lstrings.C +++ b/src/support/lstrings.C @@ -534,6 +534,18 @@ string const getStringFromVector(vector 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 diff --git a/src/support/lstrings.h b/src/support/lstrings.h index 995d96b080..0ef0806edd 100644 --- a/src/support/lstrings.h +++ b/src/support/lstrings.h @@ -176,6 +176,10 @@ std::vector const getVectorFromString(std::string const & str, std::string const getStringFromVector(std::vector 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 diff --git a/src/text3.C b/src/text3.C index 389c116ec5..6bbcc87baf 100644 --- a/src/text3.C +++ b/src/text3.C @@ -1173,7 +1173,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_INSERT_MATH: case LFUN_INSERT_MATRIX: - case LFUN_MATH_DELIM: { + case LFUN_MATH_DELIM: + case LFUN_MATH_BIGDELIM: { cur.insert(new MathHullInset("simple")); cur.dispatch(FuncRequest(LFUN_RIGHT)); cur.dispatch(cmd); @@ -1733,6 +1734,7 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, case LFUN_INSERT_MATH: case LFUN_INSERT_MATRIX: case LFUN_MATH_DELIM: + case LFUN_MATH_BIGDELIM: case LFUN_SUBSCRIPT: case LFUN_SUPERSCRIPT: case LFUN_DEFAULT: diff --git a/status.14x b/status.14x index 387d20770f..aa8e2ada86 100644 --- a/status.14x +++ b/status.14x @@ -69,6 +69,8 @@ What's new - Make clicking in a "Wide" inset always enter that inset. +- Add support for fixed size math delimiters. + * Build/installation: