4 * Purpose: Math editor definitions
5 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
6 * Created: January 1996
7 * Description: Math paragraph and objects for a WYSIWYG math editor.
11 * Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra
13 * Version: 0.8beta, Mathed & Lyx project.
15 * You are free to use and modify this code under the terms of
16 * the GNU General Public Licence version 2 or later.
27 #include "support/LIstream.h"
36 #define USE_OSTREAM_ONLY 1
45 MATH_ALIGN_BOTTOM = 4,
55 /// Standard Math Sizes (Math mode styles)
68 /// Standard LaTeX Math Environments
69 enum MathedEnvironment {
85 /** The restrictions of a standard LaTeX math paragraph
86 allows to get a small number of text codes (<30) */
87 enum MathedTextCodes {
90 /// Open and Close group
100 /// Super and sub scripts
104 /// Editable Math Inset
106 /// Editable Text Inset
110 /// Internal code for constants
112 /// Internal code for variables
128 /// Math mode TeX characters ",;:{}"
130 /// Special characters "{}&#_%"
132 /// Internal code for operators
134 /// Internal code for symbols
143 /// This must be < 32
147 ostream & operator<<(ostream &, MathedTextCodes mtc);
150 #define LM_TC_NORMAL LM_TC_VAR
153 /// Types of lyx-math insets
154 enum MathedInsetTypes {
157 /// A simple paragraph
159 /// A simple numbered paragraph
161 /// A multiline paragraph
163 /// A multiline numbered paragraph
204 enum MathedBinaryTypes {
212 LMB_BOP = (LMB_RELATION | LMB_OPERATOR)
217 /** Abstract base class for all math objects.
218 A math insets is for use of the math editor only, it isn't a
219 general LyX inset. It's used to represent all the math objects.
220 The formulaInset (a LyX inset) encapsulates a math inset.
224 /// A math inset has a name (usually its LaTeX name), type and font-size
225 MathedInset(char const * nm, short ot, short st);
227 MathedInset(MathedInset *);
229 virtual ~MathedInset() {}
232 virtual void draw(Painter &, int x, int baseline) = 0;
234 /// Write LaTeX and Lyx code
235 virtual void Write(ostream &) = 0;
237 #ifndef USE_OSTREAM_ONLY
238 /// Write LaTeX and Lyx code
239 virtual void Write(string & file) = 0;
242 /// Reproduces itself
243 virtual MathedInset * Clone() = 0;
245 /// Compute the size of the object
246 virtual void Metrics() = 0;
248 virtual int Ascent() const { return ascent; }
250 virtual int Descent() const { return descent; }
252 virtual int Width() const { return width; }
254 virtual int Height() const { return ascent + descent; }
257 virtual bool GetLimits() const { return false; }
259 virtual void SetLimits(bool) {}
262 char const * GetName() const { return name; }
264 short GetType() const { return objtype; }
266 short GetStyle() const { return size; }
268 //Man: Avoid to use these functions if it's not strictly necessary
270 virtual void SetType(short t) { objtype = t; }
272 virtual void SetStyle(short st) { size = st; } // Metrics();
274 virtual void SetName(char const * n) { name = n; }
289 static int df_asc, df_des, df_width;
291 /// In a near future maybe we use a better fonts renderer than X
292 void drawStr(Painter &, short, int, int, int, byte *, int);
294 friend class MathedCursor;
296 friend void mathed_init_fonts();
302 /// Paragraph permissions
305 /// If false can use a non-standard size
307 /// If true can insert newlines
309 /// If true can use tabs
311 /// If true can insert new columns
312 LMPF_ALLOW_NEW_COL = 8,
313 /// Smaller than current size (frac)
315 /// Script size (subscript, stackrel)
320 /** The math paragraph base class, base to all editable math objects */
321 class MathParInset: public MathedInset {
324 MathParInset(short st = LM_ST_TEXT, char const * nm = 0,
325 short ot = LM_OT_MIN);
327 MathParInset(MathParInset *);
329 virtual ~MathParInset();
331 virtual MathedInset * Clone();
333 /// Draw the object on a drawable
334 virtual void draw(Painter &, int x, int baseline);
337 virtual void Write(ostream &);
339 #ifndef USE_OSTREAM_ONLY
341 virtual void Write(string & file);
345 virtual void Metrics();
347 virtual void UserSetSize(short);
349 /// Data is stored in a LyXArray
350 virtual void SetData(LyxArrayBase *);
352 virtual LyxArrayBase * GetData() { return array; }
354 /// Paragraph position
355 virtual void GetXY(int &, int &) const;
357 virtual void setXY(int x, int y) { xo = x; yo = y; }
359 virtual void SetFocus(int, int) {}
361 virtual bool Inside(int, int);
363 // Tab stuff used by Matrix.
365 virtual void SetAlign(char, char const *) {}
367 // virtual int GetTabPos() { return 0; }
369 // virtual int GetTab(int) { return 0; }
371 virtual int GetColumns() { return 1; }
373 virtual int GetRows() { return 1; }
375 virtual bool isMatrix() { return false; }
376 // /// These functions should report an error
377 // virtual char const* GetLabel() { return 0; }
378 // virtual char const* GetLabel(int) { return 0; }
380 // Vertical switching
382 virtual bool setArgumentIdx(int i) { return (i == 0); }
384 virtual bool setNextArgIdx() { return false; }
386 virtual int getArgumentIdx() { return 0; }
388 virtual int getMaxArgumentIdx() { return 0; }
390 // virtual void SetLabel(char const *) {}
392 virtual void SetStyle(short);
394 virtual MathedRowSt * getRowSt() const { return 0; }
396 virtual void setRowSt(MathedRowSt *) {}
398 virtual bool Permit(short f) { return bool(f & flag); }
401 /// Paragraph data is stored here
402 LyxArrayBase * array;
403 /// Cursor start position
410 virtual void setFlag(MathedParFlag f) { flag |= f; }
412 friend class InsetFormula;
414 friend class MathedXIter;
416 friend class MathedCursor;
418 friend LyxArrayBase * mathed_parse(unsigned flags = 0,
419 LyxArrayBase * a = 0,
420 MathParInset ** p = 0);
424 /* The physical structure of a row and aditional information is stored here.
425 It allows to manage the extra info independently of the paragraph data.
426 Only used for multiline paragraphs.
431 w = new int[n + 1]; // this leaks
433 for (int i = 0 ; i < n + 1 ; ++i)
444 /// Should be const but...
445 MathedRowSt * getNext() const { return next; }
446 /// ...we couldn't use this.
447 void setNext(MathedRowSt * n) { next = n; }
449 char const * getLabel() const { return label; }
451 bool isNumbered() const { return numbered; }
453 int getBaseline() const { return y; }
455 int getTab(int i) { return w[i]; }
457 void setLabel(char * l) { label = l; }
459 void setNumbered(bool nf) { numbered = nf; }
461 void setTab(int i, int t) { w[i] = t; }
475 friend class MathMatrixInset;
477 friend class MathedXIter;
481 /** Multiline math paragraph base class.
482 This is the base to all multiline editable math objects
483 like array and eqnarray.
485 class MathMatrixInset: public MathParInset {
488 MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
490 MathMatrixInset(MathMatrixInset *);
492 MathedInset * Clone();
494 virtual ~MathMatrixInset();
496 void draw(Painter &, int, int);
498 void Write(ostream &);
500 #ifndef USE_OSTREAM_ONLY
502 void Write(string & file);
508 void SetData(LyxArrayBase *);
510 void SetAlign(char, char const *);
512 char * GetAlign(char * vv) {
519 int GetColumns() { return nc; }
521 int GetRows() { return nr; }
523 virtual bool isMatrix() { return true; }
525 /// Use this to manage the extra information independently of paragraph
526 MathedRowSt * getRowSt() const { return row; }
528 void setRowSt(MathedRowSt * r) { row = r; }
531 /// Number of columns & rows
536 char v_align; // add approp. signedness
539 /// Vertical structure
546 /************************* Prototypes **********************************/
548 LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * data,
551 void mathed_write(MathParInset *, ostream &, int *, char fragile,
552 char const * label = 0);
554 #ifndef USE_OSTREAM_ONLY
556 void mathed_write(MathParInset *, string &, int *, char fragile,
557 char const * label = 0);
561 void mathed_parser_file(istream &, int);
563 int mathed_parser_lineno();
565 int MathedLookupBOP(short);
567 /************************ Inline functions ********************************/
570 bool MathIsInset(short x)
572 return LM_TC_INSET <= x && x <= LM_TC_ACTIVE_INSET;
577 bool MathIsFont(short x)
579 return LM_TC_CONST <= x && x <= LM_TC_BSYM;
584 bool MathIsAlphaFont(short x)
586 return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
591 bool MathIsActive(short x)
593 return LM_TC_INSET < x && x <= LM_TC_ACTIVE_INSET;
598 bool MathIsUp(short x)
600 return x == LM_TC_UP;
605 bool MathIsDown(short x)
607 return x == LM_TC_DOWN;
612 bool MathIsScript(short x)
614 return x == LM_TC_DOWN || x == LM_TC_UP;
619 bool MathIsBOPS(short x)
621 return MathedLookupBOP(x) > LMB_NONE;
627 bool MathIsBinary(short x)
629 return x == LM_TC_BOP || x == LM_TC_BOPS;
634 bool MathIsSymbol(short x) {
635 return LM_TC_SYMB <= x && x <= LM_TC_BSYM;
640 MathedInset::MathedInset(char const * nm, short ot, short st):
641 name(nm), objtype(ot), size(st)
643 width = ascent = descent = 0;
647 bool MathParInset::Inside(int x, int y)
649 return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
654 void MathParInset::GetXY(int & x, int & y) const
661 void MathParInset::UserSetSize(short sz)
665 flag = flag & ~LMPF_FIXED_SIZE;
671 void MathParInset::SetStyle(short sz)
673 if (Permit(LMPF_FIXED_SIZE)) {
674 if (Permit(LMPF_SCRIPT))
675 sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
676 if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
679 MathedInset::SetStyle(sz);