\bind "M-m ~S-equal" "math-insert neq"
\bind "Escape" "escape"
+\bind "C-Tab" "tab-insert"
+
End
Menu "edit_math"
+# Item "Make eqnarray|e" "break-line e"
+# Item "Make multline|m" "break-line m"
+# Item "Make align 1 column|1" "break-line 1"
+# Item "Make align 2 columns|2" "break-line 2"
+# Item "Make align 3 columns|3" "break-line 3"
+# Item "Make alignat 2 columns|2" "break-line B"
+# Item "Make alignat 3 columns|3" "break-line C"
+# Separator
Item "Toggle numbering|n" "math-number"
Item "Toggle numbering of line|u" "math-nonumber"
Item "Toggle limits|l" "math-limits"
Item "V.Align Center|e" "math-valign center"
Item "V.Align Bottom|B" "math-valign bottom"
Separator
-# Item "Make eqnarray|e" "break-line e"
-# Item "Make multline|m" "break-line m"
-# Item "Make align 1 column|1" "break-line 1"
-# Item "Make align 2 columns|2" "break-line 2"
-# Item "Make align 3 columns|3" "break-line 3"
-# Item "Make alignat 2 columns|2" "break-line B"
-# Item "Make alignat 3 columns|3" "break-line C"
-# Separator
+ Item "Add Row" "math-row-insert"
+ Item "Delete Row" "math-row-delete"
+ Item "Add Column" "math-column-insert"
+ Item "Delete Column" "math-column-delete"
End
#
# INSERT MENU
#
Menu "insert"
- Item "Math Formula|h" "math-mode simple"
- Item "Display Formula|D" "math-mode display"
+ Item "Math Formula|h" "math-mode"
+ Item "Display Formula|D" "math-display"
+ #Item "Display Formula|D" "math-mode display"
+ #Item "Change to Inline Math Formula|q" "math-mutate simple"
+ #Item "Change to Displayed Math Formula|q" "math-mutate equation"
+ #Item "Change to Eqnarray Environment|q" "math-mutate eqnarray"
+ #Item "Change to Align Environment|g" "math-mutate align"
Separator
Submenu "Special Character|S" "insert_special"
Item "Citation Reference...|C" "citation-insert"
#include "insets/insetcaption.h"
#include "insets/insetfloatlist.h"
#include "insets/insetspecialchar.h"
-#include "mathed/formulamacro.h"
-#include "mathed/formula.h"
#include "gettext.h"
#include "ParagraphParameters.h"
+#include "mathed/formulabase.h"
extern LyXTextClass::size_type current_layout;
extern int greek_kb_flag;
extern void sigchldhandler(pid_t pid, int * status);
extern int bibitemMaxWidth(BufferView *, LyXFont const &);
+
namespace {
const unsigned int saved_positions_num = 20;
}
break;
- // --- insert characters ----------------------------------------
-
+ case LFUN_MATH_MACRO:
+ mathDispatchMathMacro(bv_, argument);
+ break;
+
case LFUN_MATH_DELIM:
+ mathDispatchMathDelim(bv_, argument);
+ break;
+
case LFUN_INSERT_MATRIX:
- {
- if (available()) {
- if (open_new_inset(new InsetFormula, false)) {
- bv_->theLockingInset()
- ->localDispatch(bv_, action, argument);
- }
- }
- }
- break;
-
+ mathDispatchInsertMatrix(bv_, argument);
+ break;
+
case LFUN_INSERT_MATH:
- {
- if (!available())
- break;
-
- InsetFormula * f = new InsetFormula(LM_OT_EQUATION);
- open_new_inset(f);
- f->localDispatch(bv_, LFUN_INSERT_MATH, argument);
- }
- break;
-
- case LFUN_MATH_DISPLAY:
- {
- if (available())
- open_new_inset(new InsetFormula(LM_OT_EQUATION), false);
+ mathDispatchInsertMath(bv_, argument);
break;
- }
-
- case LFUN_MATH_MACRO:
- {
- if (available()) {
- string s(argument);
- if (s.empty())
- owner_->getLyXFunc()->setErrorMessage(N_("Missing argument"));
- else {
- string const s1 = token(s, ' ', 1);
- int const na = s1.empty() ? 0 : lyx::atoi(s1);
- open_new_inset(new InsetFormulaMacro(token(s, ' ', 0), na), false);
- }
- }
- }
- break;
- case LFUN_MATH_MODE: // Open or create a math inset
- {
- if (available())
- open_new_inset(new InsetFormula, false);
- owner_->getLyXFunc()->setMessage(N_("Math editor mode"));
- }
- break;
-
+ case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection
+ mathDispatchMathImportSelection(bv_, argument);
+ break;
+
+ case LFUN_MATH_DISPLAY: // Open or create a displayed math inset
+ mathDispatchMathDisplay(bv_, argument);
+ break;
+
+ case LFUN_MATH_MODE: // Open or create an inlined math inset
+ mathDispatchMathMode(bv_, argument);
+ break;
+
case LFUN_CITATION_INSERT:
{
InsetCommandParams p;
{ commandframe, N_("command inset frame"), "commandframe", "black", "commandframe" },
{ special, N_("special character"), "special", "RoyalBlue", "special" },
{ math, N_("math"), "math", "DarkBlue", "math" },
- { mathbg, N_("math background"), "mathbg", "AntiqueWhite", "mathbg" },
- { mathmacrobg, N_("Math macro background"), "mathmacrobg", "AntiqueWhite", "mathmacrobg" },
+ { mathbg, N_("math background"), "mathbg", "linen", "mathbg" },
+ { mathmacrobg, N_("Math macro background"), "mathmacrobg", "linen", "mathmacrobg" },
{ mathframe, N_("math frame"), "mathframe", "Magenta", "mathframe" },
{ mathcursor, N_("math cursor"), "mathcursor", "black", "mathcursor" },
{ mathline, N_("math line"), "mathline", "Blue", "mathline" },
{ LFUN_MATH_LIMITS, "math-limits", "", Noop },
{ LFUN_MATH_MACRO, "math-macro", "", Noop },
{ LFUN_MATH_MUTATE, "math-mutate", "", Noop },
+ { LFUN_MATH_IMPORT_SELECTION, "math-import-selection", "", Noop },
{ LFUN_MATH_MACROARG, "math-macro-arg", "", Noop },
{ LFUN_INSERT_MATRIX, "math-matrix", "", Noop },
{ LFUN_MATH_MODE, "math-mode", N_("Math mode"), Noop },
LFUN_MATH_SIZE, // Alejandro 150896
LFUN_MATH_MACRO, // ale970510
LFUN_MATH_MACROARG, // ale970510 // 120
- LFUN_MATH_EXTERN, // Andre' 20010424
- LFUN_MATH_PANEL, // Andre' 20010522
- LFUN_MATH_VALIGN, // Andre' 20010522
- LFUN_MATH_HALIGN, // Andre' 20010522
- LFUN_MATH_ROW_INSERT, // Andre' 20010522
- LFUN_MATH_ROW_DELETE, // Andre' 20010522
- LFUN_MATH_COLUMN_INSERT, // Andre' 20010522
- LFUN_MATH_COLUMN_DELETE, // Andre' 20010522
- LFUN_MATH_MUTATE, // Andre' 20010523
+ LFUN_MATH_EXTERN, // Andre' 20010424
+ LFUN_MATH_PANEL, // Andre' 20010522
+ LFUN_MATH_VALIGN, // Andre' 20010522
+ LFUN_MATH_HALIGN, // Andre' 20010522
+ LFUN_MATH_ROW_INSERT, // Andre' 20010522
+ LFUN_MATH_ROW_DELETE, // Andre' 20010522
+ LFUN_MATH_COLUMN_INSERT, // Andre' 20010522
+ LFUN_MATH_COLUMN_DELETE, // Andre' 20010522
+ LFUN_MATH_MUTATE, // Andre' 20010523
+ LFUN_MATH_IMPORT_SELECTION, // Andre' 20010704
LFUN_FIGURE,
LFUN_DELETE_WORD_FORWARD,
LFUN_DELETE_WORD_BACKWARD,
case LFUN_BOOKMARK_GOTO:
disable = !owner->view()->
isSavedPosition(strToUnsignedInt(argument));
+
case LFUN_MATH_VALIGN: {
- Inset * tli = owner->view()->theLockingInset();
- if (tli && (tli->lyxCode() == Inset::MATH_CODE
- || tli->lyxCode() == Inset::MATHMACRO_CODE)) {
+ // I think this test can be simplified (Andre')
+ // mathcursor is != 0 iff we are in math mode
+ //Inset * tli = owner->view()->theLockingInset();
+ //if (tli && (tli->lyxCode() == Inset::MATH_CODE
+ // || tli->lyxCode() == Inset::MATHMACRO_CODE)) {
+ //
+ if (mathcursor) {
char align = mathcursor->valign();
if (align == '\0') {
disable = true;
break;
}
case LFUN_MATH_HALIGN: {
- Inset * tli = owner->view()->theLockingInset();
- if (tli && (tli->lyxCode() == Inset::MATH_CODE
- || tli->lyxCode() == Inset::MATHMACRO_CODE)) {
+ //Inset * tli = owner->view()->theLockingInset();
+ //if (tli && (tli->lyxCode() == Inset::MATH_CODE
+ // || tli->lyxCode() == Inset::MATHMACRO_CODE)) {
+ if (mathcursor) {
char align = mathcursor->halign();
if (align == '\0') {
disable = true;
disable = true;
break;
}
+
+ // we just need to be in math mode to enable that
+ case LFUN_MATH_SIZE:
+ case LFUN_MATH_LIMITS:
+ case LFUN_MATH_NONUMBER:
+ case LFUN_MATH_NUMBER:
+ disable = !mathcursor;
+ break;
+
+ // we need to be math mode and a math array for that
+ // Hack: halign produces non-zero result iff we are in a math array
+ case LFUN_MATH_ROW_INSERT:
+ case LFUN_MATH_ROW_DELETE:
+ case LFUN_MATH_COLUMN_INSERT:
+ case LFUN_MATH_COLUMN_DELETE:
+ disable = !mathcursor || !mathcursor->halign();
+ break;
+
default:
break;
}
return pos < size() ? bf_[pos + 1] : '\0';
}
+string MathArray::GetString(int & pos) const
+{
+ string s;
+ if (isInset(pos))
+ return s;
+
+ MathTextCodes const fcode = GetCode(pos);
+ do {
+ s += GetChar(pos);
+ next(pos);
+ } while (pos < size() && !isInset(pos) && GetCode(pos) == fcode);
+
+ return s;
+}
+
MathTextCodes MathArray::GetCode(int pos) const
{
return pos < size() ? MathTextCodes(bf_[pos]) : LM_TC_MIN;
#include "mathed/support.h"
#include "math_defs.h"
+#include "LString.h"
class MathInset;
class MathScriptInset;
MathScriptInset * nextScriptInset(int pos) const;
///
byte GetChar(int pos) const;
+ /// read subsequent chars of the same kind.
+ // pos is afterwards one behind the last char belonging to the string
+ string GetString(int & pos) const;
///
MathTextCodes GetCode(int pos) const;
///
extern char const * latex_mathenv[];
extern MathCursor * mathcursor;
-extern LyXFont WhichFont(short type, int size);
-
// quite a hack i know. Should be done with return values...
{}
+InsetFormula::InsetFormula(string const & s)
+ : InsetFormulaBase(0)
+{
+ istringstream is(s.c_str());
+ par(mathed_parse(is));
+}
+
Inset * InsetFormula::clone(Buffer const &) const
{
}
-void InsetFormula::write(Buffer const * buf, ostream & os) const
+void InsetFormula::write(ostream & os) const
{
os << "Formula ";
- latex(buf, os, false, false);
+ latex(os, false, false);
}
-int InsetFormula::latex(Buffer const *, ostream & os, bool fragile, bool) const
+int InsetFormula::latex(ostream & os, bool fragile, bool) const
{
par()->Write(os, fragile);
return 1;
}
-int InsetFormula::ascii(Buffer const *, ostream & os, int) const
+int InsetFormula::ascii(ostream & os, int) const
{
par()->Write(os, false);
return 1;
}
-int InsetFormula::linuxdoc(Buffer const * buf, ostream & os) const
+int InsetFormula::linuxdoc(ostream & os) const
{
- return ascii(buf, os, 0);
+ return ascii(os, 0);
}
-int InsetFormula::docBook(Buffer const * buf, ostream & os) const
+int InsetFormula::docBook(ostream & os) const
{
- return ascii(buf, os, 0);
+ return ascii(os, 0);
}
-void InsetFormula::read(Buffer const *, LyXLex & lex)
+void InsetFormula::read(LyXLex & lex)
{
- par_ = mathed_parse(lex);
+ par(mathed_parse(lex));
}
case LFUN_BREAKLINE:
bv->lockedInsetStoreUndo(Undo::INSERT);
- par()->breakLine();
+ mathcursor->breakLine();
updateLocal(bv);
break;
}
case LFUN_MATH_EXTERN:
+ bv->lockedInsetStoreUndo(Undo::EDIT);
handleExtern(arg, bv);
updateLocal(bv);
break;
case LFUN_MATH_MUTATE:
+ {
+ bv->lockedInsetStoreUndo(Undo::EDIT);
+ int x;
+ int y;
+ mathcursor->GetPos(x, y);
par()->mutate(arg);
+ mathcursor->SetPos(x, y);
+ mathcursor->normalize();
updateLocal(bv);
break;
-
- case LFUN_TABINSERT:
- lyxerr << "take index from cursor\n";
- par()->splitCell(0);
- updateLocal(bv);
- break;
+ }
case LFUN_MATH_DISPLAY:
- if (par()->GetType() == LM_OT_SIMPLE)
+ if (par()->GetType() == LM_OT_SIMPLE) {
par()->mutate(LM_OT_EQUATION);
+ par()->numbered(0, false);
+ }
else
par()->mutate(LM_OT_SIMPLE);
updateLocal(bv);
Systemcalls cmd(Systemcalls::System, script, 0);
ifstream is(outfile.c_str());
- par_ = mathed_parse(is);
+ par(mathed_parse(is));
}
bool InsetFormula::display() const
return static_cast<MathMatrixInset *>(par_);
}
+void InsetFormula::par(MathInset * p)
+{
+ delete par_;
+ par_ = p ? p : new MathMatrixInset;
+}
+
Inset::Code InsetFormula::lyxCode() const
{
par()->Metrics(LM_ST_TEXT);
return par()->width();
}
-
-/*
-LyXFont const InsetFormula::ConvertFont(LyXFont const & f) const
-{
- // We have already discussed what was here
- LyXFont font(f);
- font.setLatex(LyXFont::OFF);
- return font;
-}
-*/
#pragma interface
#endif
+#include "LString.h"
#include "mathed/formulabase.h"
#include "math_defs.h"
///
explicit InsetFormula(MathInsetTypes);
///
+ explicit InsetFormula(string const &);
+ ///
int ascent(BufferView *, LyXFont const &) const;
///
int descent(BufferView *, LyXFont const &) const;
int width(BufferView *, LyXFont const &) const;
///
void draw(BufferView *, LyXFont const &, int, float &, bool) const;
+
///
- void write(Buffer const *, std::ostream &) const;
+ void write(std::ostream &) const;
///
- void read(Buffer const *, LyXLex & lex);
+ void read(LyXLex & lex);
///
- int latex(Buffer const *, std::ostream &,
+ int latex(std::ostream &,
bool fragile, bool free_spc) const;
///
- int ascii(Buffer const *, std::ostream &, int linelen) const;
+ int ascii(std::ostream &, int linelen) const;
///
- int linuxdoc(Buffer const *, std::ostream &) const;
+ int linuxdoc(std::ostream &) const;
///
- int docBook(Buffer const *, std::ostream &) const;
+ int docBook(std::ostream &) const;
+
///
Inset * clone(Buffer const &) const;
///
bool display() const;
///
bool ams() const;
+private:
+ /// Safe setting of contents
+ void par(MathInset *);
};
#endif
#endif
#include "formula.h"
+#include "formulamacro.h"
#include "commandtags.h"
#include "math_cursor.h"
#include "math_parser.h"
#include "BufferView.h"
#include "lyxtext.h"
+#include "lyxfunc.h"
#include "gettext.h"
#include "LaTeXFeatures.h"
#include "debug.h"
string nicelabel(string const & label)
{
- return label.empty() ? string("(#)") : "(" + label + ")";
+ return "(" + (label.empty() ? "#" : label) + ")";
}
void handleFont(BufferView * bv, MathTextCodes t)
mathcursor->handleFont(t);
}
+bool openNewInset(BufferView * bv, UpdatableInset * new_inset)
+{
+ LyXText * lt = bv->getLyXText();
+
+ bv->beforeChange(lt);
+ lt->finishUndo();
+ if (!bv->insertInset(new_inset)) {
+ delete new_inset;
+ return false;
+ }
+ new_inset->edit(bv, 0, 0, 0);
+ return true;
+}
+
} // namespaces
}
-void InsetFormulaBase::write(Buffer const * buf, ostream & os) const
+void InsetFormulaBase::read(Buffer const *, LyXLex & lex)
{
- os << "Formula ";
- latex(buf, os, false, false);
+ read(lex);
}
-
-int InsetFormulaBase::ascii(Buffer const *, ostream & os, int) const
+void InsetFormulaBase::write(Buffer const *, ostream & os) const
{
- par_->Write(os, false);
- return 0;
+ write(os);
}
+int InsetFormulaBase::latex(Buffer const *, ostream & os,
+ bool fragile, bool spacing) const
+{
+ return latex(os, fragile, spacing);
+}
-int InsetFormulaBase::linuxdoc(Buffer const * buf, ostream & os) const
+int InsetFormulaBase::ascii(Buffer const *, ostream & os, int spacing) const
{
- return ascii(buf, os, 0);
+ return ascii(os, spacing);
}
+int InsetFormulaBase::linuxdoc(Buffer const *, ostream & os) const
+{
+ return linuxdoc(os);
+}
-int InsetFormulaBase::docBook(Buffer const * buf, ostream & os) const
+int InsetFormulaBase::docBook(Buffer const *, ostream & os) const
{
- return ascii(buf, os, 0);
+ return docBook(os);
}
+
// Check if uses AMS macros
void InsetFormulaBase::validate(LaTeXFeatures &) const
{}
sel_flag = false;
sel_x = 0;
sel_y = 0;
- bv->updateInset(this, false);
}
+ bv->updateInset(this, false);
}
}
updateLocal(bv);
break;
-
case LFUN_HOME:
mathcursor->Home();
- result = DISPATCHED_NOUPDATE;
+ updateLocal(bv);
break;
case LFUN_END:
mathcursor->End();
- result = DISPATCHED_NOUPDATE;
+ updateLocal(bv);
break;
case LFUN_DELETE_LINE_FORWARD:
break;
case LFUN_TAB:
- bv->lockedInsetStoreUndo(Undo::INSERT);
- mathcursor->idxRight();
+ mathcursor->idxNext();
+ updateLocal(bv);
+ break;
+
+ case LFUN_SHIFT_TAB:
+ mathcursor->idxPrev();
updateLocal(bv);
break;
case LFUN_TABINSERT:
- bv->lockedInsetStoreUndo(Undo::INSERT);
- mathcursor->idxRight();
+ bv->lockedInsetStoreUndo(Undo::EDIT);
+ mathcursor->splitCell();
updateLocal(bv);
break;
int y1;
istringstream is(arg.c_str());
is >> x >> y;
- lyxerr << "LFUN_SETXY: x: " << x << " y: " << y << "\n";
par_->GetXY(x1, y1);
mathcursor->SetPos(x1 + x, y1 + y);
+ updateLocal(bv);
}
break;
default:
if ((action == -1 || action == LFUN_SELFINSERT) && !arg.empty()) {
unsigned char c = arg[0];
+ lyxerr << "char: '" << c << "' int: " << int(c) << endl;
+ //owner_->getIntl()->getTrans().TranslateAndInsert(c, lt);
+ lyxerr << "trans: '" << c << "' int: " << int(c) << endl;
bv->lockedInsetStoreUndo(Undo::INSERT);
if (c == ' ' && mathcursor->getAccent() == LM_hat) {
return par_;
}
+
+void mathDispatchCreation(BufferView * bv, string const & arg, bool display)
+{
+ if (bv->available()) {
+// Feature "Read math inset from selection" disabled.
+// // use selection if available..
+// string sel;
+// if (action == LFUN_MATH_IMPORT_SELECTION)
+// sel = "";
+// else
+// sel = bv->getLyXText()->selectionAsString(bv->buffer());
+
+ InsetFormula * f;
+// if (sel.empty()) {
+ f = new InsetFormula;
+ openNewInset(bv, f);
+ // don't do that also for LFUN_MATH_MODE unless you want end up with
+ // always changing to mathrm when opening an inlined inset
+ // -- I really hate "LyXfunc overloading"...
+ if (display)
+ f->localDispatch(bv, LFUN_MATH_DISPLAY, string());
+ f->localDispatch(bv, LFUN_INSERT_MATH, arg);
+// } else {
+// f = new InsetFormula(sel);
+// bv->getLyXText()->cutSelection(bv);
+// openNewInset(bv, f);
+// }
+ }
+ bv->owner()->getLyXFunc()->setMessage(N_("Math editor mode"));
+}
+
+void mathDispatchMathDisplay(BufferView * bv, string const & arg)
+{
+ mathDispatchCreation(bv, arg, true);
+}
+
+void mathDispatchMathMode(BufferView * bv, string const & arg)
+{
+ mathDispatchCreation(bv, arg, false);
+}
+
+void mathDispatchMathImportSelection(BufferView * bv, string const & arg)
+{
+ mathDispatchCreation(bv, arg, true);
+}
+
+void mathDispatchMathMacro(BufferView * bv, string const & arg)
+{
+ if (bv->available()) {
+ string s(arg);
+ if (s.empty())
+ bv->owner()->getLyXFunc()->setErrorMessage(N_("Missing argument"));
+ else {
+ string const s1 = token(s, ' ', 1);
+ int const na = s1.empty() ? 0 : lyx::atoi(s1);
+ openNewInset(bv, new InsetFormulaMacro(token(s, ' ', 0), na));
+ }
+ }
+}
+
+void mathDispatchMathDelim(BufferView * bv, string const & arg)
+{
+ if (bv->available()) {
+ if (openNewInset(bv, new InsetFormula))
+ bv->theLockingInset()->localDispatch(bv, LFUN_MATH_DELIM, arg);
+ }
+}
+
+
+void mathDispatchInsertMatrix(BufferView * bv, string const & arg)
+{
+ if (bv->available()) {
+ if (openNewInset(bv, new InsetFormula))
+ bv->theLockingInset()->localDispatch(bv, LFUN_INSERT_MATRIX, arg);
+ }
+}
+
+void mathDispatchInsertMath(BufferView * bv, string const & arg)
+{
+ if (bv->available()) {
+ if (arg.size() && arg[0] == '\\') {
+ InsetFormula * f = new InsetFormula(arg);
+ openNewInset(bv, f);
+ } else {
+ return mathDispatchMathDisplay(bv, arg);
+ }
+ }
+}
+
// -*- C++ -*-
/*
- * File: formula.h
- * Purpose: Declaration of formula inset
- * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
- * Created: January 1996
+ * File: formulabase.h
+ * Purpose: Common parts of the math LyX insets
+ * Author: André Pönitz
+ * Created: May 2001
* Description: Allows the edition of math paragraphs inside Lyx.
*
- * Copyright: 1996, Alejandro Aguilar Sierra
- *
- * Version: 0.4, Lyx project.
+ * Copyright: 2001, The LyX Project
*
* You are free to use and modify this code under the terms of
* the GNU General Public Licence version 2 or later.
#include "insets/inset.h"
class Buffer;
+class BufferView;
class MathInset;
///
virtual int width(BufferView *, LyXFont const &) const = 0;
///
virtual void draw(BufferView *,LyXFont const &, int, float &, bool) const = 0;
+
+ /// These are just wrappers taking the unused Buffer * dummy parameter
+ ///
+ virtual void write(Buffer const *, std::ostream &) const;
///
- virtual void write(Buffer const *, std::ostream &) const = 0;
- ///
- virtual void read(Buffer const *, LyXLex & lex) = 0;
+ virtual void read(Buffer const *, LyXLex & lex);
///
virtual int latex(Buffer const *, std::ostream &,
- bool fragile, bool free_spc) const = 0;
+ bool fragile, bool free_spc) const;
///
- virtual int ascii(Buffer const *, std::ostream &, int linelen) const = 0;
+ virtual int ascii(Buffer const *, std::ostream &, int linelen) const;
+ ///
+ virtual int linuxdoc(Buffer const *, std::ostream &) const;
+ ///
+ virtual int docBook(Buffer const *, std::ostream &) const;
+
+protected:
+ /// the actual functions don't use the Buffer * parameter
///
- virtual int linuxdoc(Buffer const *, std::ostream &) const = 0;
+ virtual void write(std::ostream &) const = 0;
///
- virtual int docBook(Buffer const *, std::ostream &) const = 0;
+ virtual void read(LyXLex & lex) = 0;
+ ///
+ virtual int latex(std::ostream &, bool fragile, bool free_spc) const = 0;
+ ///
+ virtual int ascii(std::ostream &, int linelen) const = 0;
+ ///
+ virtual int linuxdoc(std::ostream &) const = 0;
+ ///
+ virtual int docBook(std::ostream &) const = 0;
+
+public:
///
virtual void validate(LaTeXFeatures &) const;
///
///
virtual void insetUnlock(BufferView *);
- /// To allow transparent use of math editing functions
+ /// To allow transparent use of math editing functions
virtual RESULT localDispatch(BufferView *, kb_action, string const &);
///
MathInset * par_;
};
+// We don't really mess want around with mathed stuff outside mathed.
+// So do it here.
+//
+void mathDispatchCreation(BufferView *, string const &, bool);
+//
+void mathDispatchMathDisplay(BufferView *, string const &);
+//
+void mathDispatchMathMode(BufferView *, string const &);
+//
+void mathDispatchMathMacro(BufferView *, string const &);
+//
+void mathDispatchMathDelim(BufferView *, string const &);
+//
+void mathDispatchInsertMath(BufferView *, string const &);
+//
+void mathDispatchInsertMatrix(BufferView *, string const &);
+//
+void mathDispatchMathImportSelection(BufferView *, string const &);
+
#endif
/*
- * File: formula.h
- * Purpose: Implementation of formula inset
- * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
- * Created: January 1996
- * Description: Allows the edition of math paragraphs inside Lyx.
+ * File: formulamacro.C
+ * Purpose: Implementation of the formula macro LyX inset
+ * Author: André Pönitz
+ * Created: March 2001
+ * Description: Allows the edition of math macros inside Lyx.
*
- * Copyright: 1996, 1997 Alejandro Aguilar Sierra
- *
- * Version: 0.4, Lyx project.
+ * Copyright: 2001 The LyX Project
*
* You are free to use and modify this code under the terms of
* the GNU General Public Licence version 2 or later.
}
-void InsetFormulaMacro::write(Buffer const *, ostream & os) const
+void InsetFormulaMacro::write(ostream & os) const
{
os << "FormulaMacro ";
tmacro()->Write(os, false);
}
-int InsetFormulaMacro::latex(Buffer const *, ostream & os, bool fragile,
+int InsetFormulaMacro::latex(ostream & os, bool fragile,
bool /*free_spacing*/) const
{
tmacro()->Write(os, fragile);
return 2;
}
-int InsetFormulaMacro::ascii(Buffer const *, ostream & os, int) const
+int InsetFormulaMacro::ascii(ostream & os, int) const
{
tmacro()->Write(os, false);
return 0;
}
-int InsetFormulaMacro::linuxdoc(Buffer const * buf, ostream & os) const
+int InsetFormulaMacro::linuxdoc(ostream & os) const
{
- return ascii(buf, os, 0);
+ return ascii(os, 0);
}
-int InsetFormulaMacro::docBook(Buffer const * buf, ostream & os) const
+int InsetFormulaMacro::docBook(ostream & os) const
{
- return ascii(buf, os, 0);
+ return ascii(os, 0);
}
-void InsetFormulaMacro::read(Buffer const *, LyXLex & lex)
+void InsetFormulaMacro::read(LyXLex & lex)
{
// Awful hack...
par_ = mathed_parse(lex);
int const w = width(bv, font) - 2;
int const h = ascent(bv, font) + descent(bv, font) - 2;
- pain.fillRectangle(int(x), y , w, h, LColor::mathbg);
+ // LColor::mathbg used to be "AntiqueWhite" but is "linen" now, too
+ pain.fillRectangle(int(x), y , w, h, LColor::mathmacrobg);
pain.rectangle(int(x), y, w, h, LColor::mathframe);
if (mathcursor && mathcursor->formula() == this && mathcursor->Selection()) {
case LFUN_MATH_MACROARG: {
int const i = lyx::atoi(arg);
lyxerr << "inserting macro arg " << i << "\n";
- if (i > 0 && i <= tmacro()->nargs()) {
+ if (i > 0 && i <= tmacro()->numargs()) {
mathcursor->insert(new MathMacroArgument(i));
updateLocal(bv);
} else {
- lyxerr << "not in range 0.." << tmacro()->nargs() << "\n";
+ lyxerr << "not in range 0.." << tmacro()->numargs() << "\n";
}
break;
}
int width(BufferView *, LyXFont const &) const;
///
void draw(BufferView *,LyXFont const &, int, float &, bool) const;
+
///
- void read(Buffer const *, LyXLex & lex);
+ void read(LyXLex & lex);
///
- void write(Buffer const *, std::ostream & os) const;
+ void write(std::ostream & os) const;
///
- int ascii(Buffer const *, std::ostream &, int linelen) const;
+ int ascii(std::ostream &, int linelen) const;
///
- int latex(Buffer const *, std::ostream & os, bool fragile,
- bool free_spc) const;
+ int latex(std::ostream & os, bool fragile, bool free_spc) const;
///
- int linuxdoc(Buffer const *, std::ostream & os) const;
+ int linuxdoc(std::ostream & os) const;
///
- int docBook(Buffer const *, std::ostream &) const;
+ int docBook(std::ostream &) const;
+
///
Inset * clone(Buffer const &) const;
///
using std::ostream;
MathBigopInset::MathBigopInset(string const & name, int id)
- : MathScriptInset(true, false), lims_(-1), sym_(id)
+ : MathScriptInset(true, false), lims_(0), sym_(id)
{
SetName(name);
}
#endif
#include <config.h>
+#include <cctype>
#include "math_inset.h"
#include "math_parser.h"
using std::endl;
using std::min;
using std::max;
+using std::isalnum;
namespace {
void MathCursor::dump(char const * what) const
{
+ return;
+
lyxerr << "MC: " << what
<< " cursor: " << cursor_
<< " anchor: " << anchor_
result = array().next(anchor_);
}
} else {
- MathInset * p = prevActiveInset();
- if (p) {
+ MathInset * p = prevInset();
+ if (p && p->isActive()) {
// We have to move deeper into the previous inset
array().prev(cursor_);
push(p, false);
result = array().next(cursor_);
}
} else {
- MathInset * p = nextActiveInset();
- if (p) {
+ MathInset * p = nextInset();
+ if (p && p->isActive()) {
push(p, true);
result = true;
} else {
void MathCursor::SetPos(int x, int y)
{
dump("SetPos 1");
- lyxerr << "MathCursor::SetPos x: " << x << " y: " << y << "\n";
+ //lyxerr << "MathCursor::SetPos x: " << x << " y: " << y << "\n";
MacroModeClose();
lastcode = LM_TC_MIN;
while (1) {
idx_ = -1;
cursor_ = -1;
+ //lyxerr << "found idx: " << idx_ << " cursor: " << cursor_ << "\n";
int distmin = 1 << 30; // large enough
for (int i = 0; i < par_->nargs(); ++i) {
MathXArray const & ar = par_->xcell(i);
}
}
lyxerr << "found idx: " << idx_ << " cursor: " << cursor_ << "\n";
- if (nextIsActive() && nextInset()->covers(x, y)) {
- MathInset * p = nextActiveInset();
- push(p, true);
- } else if (prevIsActive() && prevInset()->covers(x, y)) {
- MathInset * p = prevActiveInset();
+ MathInset * n = nextInset();
+ MathInset * p = prevInset();
+ if (n && (n->isActive() || n->isScriptInset()) && n->covers(x, y))
+ push(n, true);
+ else if (p && (p->isActive() || p->isScriptInset()) && p->covers(x, y)) {
array().prev(cursor_);
push(p, false);
} else
}
if (p) {
+ bool oldsel = selection;
+ if (oldsel)
+ SelCut();
insert(p);
if (p->nargs()) {
array().prev(cursor_);
push(p, true);
+ if (oldsel)
+ SelPaste();
}
p->Metrics(p->size());
}
if (selection) {
int const p1 = std::min(cursor_, anchor_);
int const p2 = std::max(cursor_, anchor_);
- for (int pos = p1; pos != p2; array().next(pos))
- if (!array().isInset(pos)) {
- MathTextCodes c = array().GetCode(pos) == t ? LM_TC_VAR : t;
- array().setCode(pos, c);
+ MathArray & ar = array();
+ for (int pos = p1; pos != p2; ar.next(pos))
+ if (!ar.isInset(pos) && isalnum(ar.GetChar(pos))) {
+ MathTextCodes c = ar.GetCode(pos) == t ? LM_TC_VAR : t;
+ ar.setCode(pos, c);
}
} else {
if (lastcode == t)
MathInset * MathCursor::enclosing(MathInsetTypes t, int & idx) const
{
if (par_->GetType() == t) {
- lyxerr << "enclosing par is current\n";
+ //lyxerr << "enclosing par is current\n";
idx = idx_;
return par_;
}
return array().GetInset(c);
}
-MathInset * MathCursor::prevActiveInset() const
-{
- if (cursor_ <= 0 || !array().isInset(cursor_ - 1))
- return 0;
- MathInset * inset = prevInset();
- return inset->isActive() ? inset : 0;
-}
-
MathInset * MathCursor::nextInset() const
{
}
-MathInset * MathCursor::nextActiveInset() const
-{
- if (!array().isInset(cursor_))
- return 0;
- MathInset * inset = nextInset();
- return inset->isActive() ? inset : 0;
-}
-
-
MathScriptInset * MathCursor::nearbyScriptInset() const
{
normalize();
}
-bool MathCursor::nextIsActive() const
-{
- return nextIsInset() && nextInset()->isActive();
-}
-
-
bool MathCursor::prevIsInset() const
{
return cursor_ > 0 && MathIsInset(prevCode());
}
-bool MathCursor::prevIsActive() const
-{
- return prevIsInset() && prevInset()->isActive();
-}
-
-
bool MathCursor::IsFont() const
{
return MathIsFont(nextCode());
cursor_ = xarray().x2pos(x);
}
-void MathCursor::idxRight()
+void MathCursor::idxNext()
{
- par_->idxRight(idx_, cursor_);
+ par_->idxNext(idx_, cursor_);
+}
+
+void MathCursor::idxPrev()
+{
+ par_->idxPrev(idx_, cursor_);
+}
+
+void MathCursor::splitCell()
+{
+ if (idx_ == par_->nargs() - 1)
+ return;
+ MathArray ar = array();
+ ar.erase(0, cursor_);
+ array().erase(cursor_, array().size());
+ ++idx_;
+ cursor_ = 0;
+ array().insert(0, ar);
+}
+
+void MathCursor::breakLine()
+{
+ MathMatrixInset * p = static_cast<MathMatrixInset *>(formula()->par());
+ if (p->GetType() == LM_OT_SIMPLE || p->GetType() == LM_OT_EQUATION)
+ p->mutate(LM_OT_EQNARRAY);
+ p->addRow(row());
+
+ // split line
+ const int r = row();
+ for (int c = col() + 1; c < p->ncols(); ++c) {
+ const int i1 = p->index(r, c);
+ const int i2 = p->index(r + 1, c);
+ lyxerr << "swapping cells " << i1 << " and " << i2 << "\n";
+ p->cell(i1).swap(p->cell(i2));
+ }
+
+ // split cell
+ splitCell();
+ MathArray & halfcell = array();
+ idx_ += p->ncols() - 1;
+ halfcell.swap(array());
}
char MathCursor::valign() const
void setLastCode(MathTextCodes t);
///
void handleFont(MathTextCodes t);
+ /// Splits cells and shifts right part to the next cell
+ void splitCell();
+ /// Splits line and insert new row of cell
+ void breakLine();
///
MathTextCodes getLastCode() const;
///
int idx() const { return idx_; }
///
- void idxRight();
+ void idxNext();
+ ///
+ void idxPrev();
///
void pullArg();
///
///
bool nextIsInset() const;
///
- bool nextIsActive() const;
- ///
bool prevIsInset() const;
///
- bool prevIsActive() const;
- ///
bool IsFont() const;
///
bool IsScript() const;
///
MathInset * nextInset() const;
///
- MathInset * nextActiveInset() const;
- ///
MathInset * prevInset() const;
///
- MathInset * prevActiveInset() const;
- ///
MathScriptInset * nearbyScriptInset() const;
///
void MathDecorationInset::Metrics(MathStyles st)
{
- int const h = 2 * mathed_char_height(LM_TC_VAR, size(), 'I',
- ascent_, descent_);
xcell(0).Metrics(st);
width_ = xcell(0).width();
ascent_ = xcell(0).ascent();
descent_ = xcell(0).descent();
- int w = width() + 4;
-
- dh_ = w / 5;
- if (dh_ > h)
- dh_ = h;
+ dh_ = mathed_char_height(LM_TC_VAR, size(), 'I', ascent_, descent_);
if (upper_) {
- ascent_ += dh_ + 2;
+ ascent_ += dh_ + 1;
dy_ = -ascent_;
} else {
- dy_ = descent_ + 2;
- descent_ += dh_ + 4;
+ dy_ = descent_ + 1;
+ descent_ += dh_ + 2;
}
- width_ = w;
}
void MathDecorationInset::draw(Painter & pain, int x, int y)
class MathDecorationInset : public MathInset {
public:
///
- MathDecorationInset(int);
+ explicit MathDecorationInset(int);
///
MathInset * clone() const;
///
LM_ST_SCRIPTSCRIPT
};
+// decrease math size for super- and subscripts
+MathStyles smallerStyleScript(MathStyles);
+
+// decrease math size for fractions
+MathStyles smallerStyleFrac(MathStyles st);
+
+
/** The restrictions of a standard LaTeX math paragraph
allows to get a small number of text codes (<30) */
void MathFracInset::Metrics(MathStyles st)
{
- xcell(0).Metrics(st);
- xcell(1).Metrics(st);
- size_ = st;
+ size_ = smallerStyleFrac(st);
+ xcell(0).Metrics(size_);
+ xcell(1).Metrics(size_);
width_ = std::max(xcell(0).width(), xcell(1).width()) + 4;
ascent_ = xcell(0).height() + 4 + 5;
descent_ = xcell(1).height() + 4 - 5;
mathed_string_height(LM_TC_TEXTRM, size_, name_, ascent_, descent_);
}
}
-
-
-bool MathFuncInset::GetLimits() const
-{
- return lims_ && (size() == LM_ST_DISPLAY);
-}
void WriteNormal(std::ostream &) const;
///
void Metrics(MathStyles st);
- ///
- bool GetLimits() const;
private:
///
bool lims_;
void delCol(int);
///
virtual void appendRow();
-
-protected:
///
int index(int row, int col) const;
+protected:
/// row info
std::vector<RowInfo> rowinfo_;
/// column info
MathInset::MathInset(string const & name, MathInsetTypes ot, int nargs)
: name_(name), objtype(ot), width_(0), ascent_(0), descent_(0),
- size_(LM_ST_TEXT), cells_(nargs), xo_(0), yo_(0)
+ size_(LM_ST_DISPLAY), cells_(nargs), xo_(0), yo_(0)
{}
}
-bool MathInset::idxRight(int & idx, int & pos) const
+bool MathInset::idxNext(int & idx, int & pos) const
{
if (idx + 1 >= nargs())
return false;
}
-bool MathInset::idxLeft(int & idx, int & pos) const
+bool MathInset::idxRight(int & idx, int & pos) const
+{
+ return idxNext(idx, pos);
+}
+
+
+bool MathInset::idxPrev(int & idx, int & pos) const
{
if (idx == 0)
return false;
}
+bool MathInset::idxLeft(int & idx, int & pos) const
+{
+ return idxPrev(idx, pos);
+}
+
bool MathInset::idxUp(int &, int &) const
{
return false;
/// The right key
virtual bool idxRight(int & idx, int & pos) const;
+ /// Move one physical cell up
+ virtual bool idxNext(int & idx, int & pos) const;
+ /// Move one physical cell down
+ virtual bool idxPrev(int & idx, int & pos) const;
+
/// Target pos when we enter the inset from the left by pressing "Right"
virtual bool idxFirst(int & idx, int & pos) const;
/// Target pos when we enter the inset from the left by pressing "Up"
width_ += mathed_string_width(LM_TC_TEXTRM, size_, name_) + 10;
+ int lasc;
+ int ldes;
+ int lwid;
+ mathed_string_dim(LM_TC_TEXTRM, size_, "#1: ", lasc, ldes, lwid);
+
for (int i = 0; i < nargs(); ++i) {
MathXArray & c = xcell(i);
c.Metrics(st);
- width_ = std::max(width_, c.width() + 30);
- descent_ += c.height() + 10;
+ width_ = std::max(width_, c.width() + lwid);
+ descent_ += std::max(c.ascent(), lasc) + 5;
+ descent_ += std::max(c.descent(), ldes) + 5;
}
} else {
expanded_ = tmplate_->xcell(0);
int h = y - ascent() + 2 + expanded_.ascent();
drawStr(pain, LM_TC_TEXTRM, size(), x + 3, h, name_);
- int w = mathed_string_width(LM_TC_TEXTRM, size(), name_);
+ int const w = mathed_string_width(LM_TC_TEXTRM, size(), name_);
expanded_.draw(pain, x + w + 12, h);
h += expanded_.descent();
+ int lasc;
+ int ldes;
+ int lwid;
+ mathed_string_dim(LM_TC_TEXTRM, size_, "#1: ", lasc, ldes, lwid);
+
for (int i = 0; i < nargs(); ++i) {
MathXArray & c = xcell(i);
- h += c.ascent() + 5;
- c.draw(pain, x + 30, h);
+ h += std::max(c.ascent(), lasc) + 5;
+ c.draw(pain, x + lwid, h);
char str[] = "#1:";
str[1] += i;
drawStr(pain, LM_TC_TEX, size(), x + 3, h, str);
- h += c.descent() + 5;
+ h += std::max(c.descent(), ldes) + 5;
}
col = LColor::red;
} else {
}
-void MathMatrixInset::Metrics(MathStyles st)
+void MathMatrixInset::Metrics(MathStyles /* st */)
{
- size_ = st;
+ size_ = (GetType() == LM_OT_SIMPLE) ? LM_ST_TEXT : LM_ST_DISPLAY;
+
//LyXFont wfont = WhichFont(LM_TC_BF, size());
//wfont.setLatex(LyXFont::OFF);
// let the cells adjust themselves
- MathGridInset::Metrics(st);
+ MathGridInset::Metrics(size_);
if (display()) {
ascent_ += 12;
os << "\\begin{alignat" << star(n) << "}"
<< "{" << ncols()/2 << "}\n";
break;
+ default:
+ os << "\\begin{unknown" << star(n) << "}";
}
}
case LM_OT_ALIGNAT:
os << "\\end{alignat" << star(n) << "}\n";
break;
+
+ default:
+ os << "\\end{unknown" << star(n) << "}";
}
}
}
}
-void MathMatrixInset::breakLine()
-{
- if (GetType() == LM_OT_SIMPLE || GetType() == LM_OT_EQUATION)
- mutate(LM_OT_EQNARRAY);
- addRow(nrows() - 1);
-}
-
-
-void MathMatrixInset::splitCell(int idx)
-{
- if (idx == nargs() - 1) {
- lyxerr << "can't split last cell\n";
- return;
- }
-
- lyxerr << "unimplemented\n";
-}
-
string MathMatrixInset::nicelabel(int row) const
{
case LM_OT_EQNARRAY:
switch (newtype) {
case LM_OT_SIMPLE:
- glueall();
- break;
-
case LM_OT_EQUATION:
- if (nrows() == 1) {
- MathGridInset::delCol(2);
- MathGridInset::delCol(1);
- SetType(LM_OT_EQUATION);
- mutate(newtype);
- } else
- lyxerr << "need to delete rows first\n";
+ glueall();
+ mutate(newtype);
break;
case LM_OT_ALIGN:
case LM_OT_EQNARRAY:
MathGridInset::addCol(1);
SetType(LM_OT_EQNARRAY);
- halign("lrl");
+ halign("rcl");
mutate(newtype);
break;
///
void Metrics(MathStyles st);
///
- void breakLine();
- ///
void draw(Painter &, int, int);
///
string label(int row) const;
///
void mutate(short);
- /// Splits cells and shifts right part to the next cell
- void splitCell(int idx);
-
private:
///
void Validate1(LaTeXFeatures & features);
while (yyis->good()) {
unsigned char c = getuchar(yyis);
- lyxerr << "reading byte: '" << c << "' code: " << lexcode[c] << endl;
- lyxerr << " code: " << lexcode['ü'] << endl;
+ //lyxerr << "reading byte: '" << c << "' code: " << lexcode[c] << endl;
if (yyvarcode == LM_TC_TEXTRM && c == ' ') {
yylval.i = ' ';
case LM_TK_UNDEF:
if (MathMacroTable::hasTemplate(yytext)) {
MathMacro * m = MathMacroTable::cloneTemplate(yytext);
- for (int i = 0; i < m->nargs(); ++i) {
+ for (int i = 0; i < m->nargs(); ++i)
mathed_parse(m->cell(i), FLAG_BRACE_OPT | FLAG_BRACE_LAST);
- lyxerr << "reading cell " << i << " '" << m->cell(i) << "'\n";
- }
do_insert(array, m);
- lyxerr << "macro: " << *m << "\n";
m->Metrics(LM_ST_TEXT);
} else
do_insert(array, new MathFuncInset(yytext, LM_OT_UNDEF));
void MathScriptInset::Metrics(MathStyles st)
{
- MathInset::Metrics(st);
- size_ = st;
+ size_ = smallerStyleScript(st);
+ xcell(0).Metrics(size_);
+ xcell(1).Metrics(size_);
+
width_ = std::max(xcell(0).width(), xcell(1).width()) + 2;
if (up())
ascent_ = std::max(ascent_, xcell(0).height() + 9);
s += c;
drawStr(pain, type, siz, x, y, s);
}
+
+// decrease math size for super- and subscripts
+MathStyles smallerStyleScript(MathStyles st)
+{
+ switch (st) {
+ case LM_ST_DISPLAY:
+ case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
+ default: st = LM_ST_SCRIPTSCRIPT;
+ }
+ return st;
+}
+
+// decrease math size for fractions
+MathStyles smallerStyleFrac(MathStyles st)
+{
+ switch (st) {
+ case LM_ST_DISPLAY: st = LM_ST_TEXT; break;
+ case LM_ST_TEXT: st = LM_ST_SCRIPT; break;
+ default: st = LM_ST_SCRIPTSCRIPT;
+ }
+ return st;
+}
std::ostream & operator<<(std::ostream & os, MathXArray const & ar)
{
os << ar.data_;
+ return os;
}