]> git.lyx.org Git - features.git/blob - src/mathed/math_defs.h
fix crossref label list, some debug messages + various
[features.git] / src / mathed / math_defs.h
1 // -*- C++ -*-
2 /*
3  *  File:        math_defs.h
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.
8  *
9  *  Dependencies: Xlib
10  *
11  *  Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra
12  *
13  *   Version: 0.8beta, Mathed & Lyx project.
14  *
15  *   You are free to use and modify this code under the terms of
16  *   the GNU General Public Licence version 2 or later.
17  * 
18  */
19
20 #ifndef MATH_DEFS
21 #define MATH_DEFS
22
23 #ifdef __GNUG__
24 #pragma interface
25 #endif
26
27 #include "support/LIstream.h"
28
29 #include "LString.h"
30 #include "debug.h"
31
32 #include "array.h"
33
34
35 ///
36 enum math_align {
37         ///
38         MATH_ALIGN_LEFT = 1,
39         ///
40         MATH_ALIGN_RIGHT = 2,
41         ///
42         MATH_ALIGN_BOTTOM = 4,
43         ///
44         MATH_ALIGN_TOP = 8
45 };
46 ///
47 #define MATH_COLSEP 8
48 ///
49 #define MATH_ROWSEP 8
50
51
52 /// Standard Math Sizes (Math mode styles)
53 enum MathedStyles {
54         ///
55         LM_ST_DISPLAY = 0,
56         ///
57         LM_ST_TEXT,
58         ///
59         LM_ST_SCRIPT,
60         ///
61         LM_ST_SCRIPTSCRIPT
62 };
63
64
65 /// Standard LaTeX Math Environments
66 enum MathedEnvironment {
67         ///
68         LM_EN_INTEXT = 0,
69         ///
70         LM_EN_DISPLAY,
71         ///
72         LM_EN_EQUATION,
73         ///
74         LM_EN_EQNARRAYAST,
75         ///
76         LM_EN_EQNARRAY,
77         ///
78         LM_EN_ARRAY
79 };
80
81
82 /** The restrictions of a standard LaTeX math paragraph
83   allows to get a small number of text codes (<30) */
84 enum MathedTextCodes  {
85         /// This must be >= 0
86         LM_TC_MIN = 0,
87         /// Open and Close group
88         LM_TC_OPEN,
89         ///
90         LM_TC_CLOSE,
91         /// Tabulator
92         LM_TC_TAB,
93         /// New line
94         LM_TC_CR,
95         /// Math Inset
96         LM_TC_INSET,
97         /// Super and sub scripts
98         LM_TC_UP,
99         ///
100         LM_TC_DOWN,
101         /// Editable Math Inset
102         LM_TC_ACTIVE_INSET,
103         /// Editable Text Inset
104         LM_TC_TEXT_INSET,
105         ///
106         LM_FONT_BEGIN,
107         /// Internal code for constants
108         LM_TC_CONST,
109         /// Internal code for variables
110         LM_TC_VAR,
111         ///
112         LM_TC_RM,
113         ///
114         LM_TC_CAL,
115         ///
116         LM_TC_BF,
117         ///
118         LM_TC_SF,
119         ///
120         LM_TC_TT,
121         ///
122         LM_TC_IT,
123         ///
124         LM_TC_TEXTRM,
125         /// Math mode TeX characters ",;:{}"
126         LM_TC_TEX,
127         /// Special characters "{}&#_%"
128         LM_TC_SPECIAL,
129         /// Internal code for operators
130         LM_TC_BOP,
131         /// Internal code for symbols
132         LM_TC_SYMB,
133         ///
134         LM_TC_BOPS,
135         ///
136         LM_TC_BSYM,
137         ///
138         LM_FONT_END,
139         
140         /// This must be < 32 
141         LM_TC_MAX
142 };
143
144 ostream & operator<<(ostream &, MathedTextCodes mtc);
145
146 ///
147 #define LM_TC_NORMAL LM_TC_VAR
148  
149        
150 /// Types of lyx-math insets 
151 enum MathedInsetTypes  {
152         ///
153         LM_OT_MIN = 0,
154         /// A simple paragraph
155         LM_OT_PAR,
156         /// A simple numbered paragraph
157         LM_OT_PARN,
158         /// A multiline paragraph
159         LM_OT_MPAR,
160         /// A multiline numbered paragraph
161         LM_OT_MPARN,
162         /// An array
163         LM_OT_MATRIX,
164         /// A big operator
165         LM_OT_BIGOP,
166         /// A LaTeX macro
167         LM_OT_UNDEF,
168         ///
169         LM_OT_FUNC,
170         ///
171         LM_OT_FUNCLIM,
172         ///
173         LM_OT_SCRIPT,
174         ///
175         LM_OT_SPACE,
176         ///
177         LM_OT_DOTS,
178         /// A fraction
179         LM_OT_FRAC,
180         ///
181         LM_OT_ATOP,
182         ///
183         LM_OT_STACKREL,
184         /// A radical
185         LM_OT_SQRT,
186         /// A delimiter
187         LM_OT_DELIM,
188         /// A decoration
189         LM_OT_DECO,
190         /// An accent
191         LM_OT_ACCENT,
192         ///
193         LM_OT_MACRO,
194         ///
195         LM_OT_MACRO_ARG,
196         ///
197         LM_OT_MAX
198 };
199
200 ///
201 enum MathedBinaryTypes {
202         ///
203         LMB_NONE = 0,
204         ///
205         LMB_RELATION,
206         ///
207         LMB_OPERATOR,
208         ///
209         LMB_BOP = (LMB_RELATION | LMB_OPERATOR)
210 };
211
212 class MathParInset;
213
214 /** Abstract base class for all math objects.
215     A math insets is for use of the math editor only, it isn't a
216     general LyX inset. It's used to represent all the math objects.
217     The formulaInset (a LyX inset) encapsulates a math inset.
218  */
219 class MathedInset  {
220  public: 
221     /// A math inset has a name (usually its LaTeX name), type and font-size
222     MathedInset(char const * nm, short ot, short st);
223     ///
224     MathedInset(MathedInset *);
225     ///
226     virtual ~MathedInset() {}
227     
228     /// Draw the object 
229     virtual void Draw(int x, int baseline) = 0;
230
231     /// Write LaTeX and Lyx code
232     virtual void Write(ostream &) = 0;
233
234     /// Write LaTeX and Lyx code
235     virtual void Write(string & file) = 0;
236    
237     /// Reproduces itself
238     virtual MathedInset * Clone() = 0;
239    
240     /// Compute the size of the object
241     virtual void Metrics() = 0; 
242     /// 
243     virtual int Ascent() const { return ascent; }
244     ///
245     virtual int Descent() const { return descent; }
246     ///
247     virtual int Width() const { return width; }
248     ///
249     virtual int Height() const { return ascent + descent; }
250     
251     ///
252     virtual bool GetLimits() const { return false; }
253     ///
254     virtual void SetLimits(bool) {}   
255    
256     ///
257     char const * GetName() const { return name; }
258     ///
259     short GetType() const { return objtype; }
260     ///
261     short GetStyle() const { return size; }
262           
263     //Man:  Avoid to use these functions if it's not strictly necessary 
264     ///
265     virtual void  SetType(short t) { objtype = t; }
266     ///
267     virtual void  SetStyle(short st) { size = st; } // Metrics();
268     ///
269     virtual void  SetName(char const * n) { name = n; }
270     /// 
271     void setDrawable(long unsigned int d) { pm = d; }
272  
273  protected:
274     ///
275     char const * name;
276     ///
277     short objtype;
278     ///
279     int width;
280     ///
281     int ascent;
282     ///
283     int descent;
284     ///
285     short size;
286     /// This works while only one process can draw unless
287     /// the process have their own data
288     static long unsigned int pm;
289     /// Default metrics
290     static int df_asc, df_des, df_width;
291
292     /// In a near future maybe we use a better fonts renderer than X
293     void drawStr(short, int, int, int, byte *, int);
294         ///
295     friend class MathedCursor;
296         ///
297     friend void mathed_init_fonts();
298 };
299
300 struct MathedRowSt;
301
302
303 /// Paragraph permissions
304 enum MathedParFlag {
305         LMPF_BASIC = 0,
306         /// If false can use a non-standard size
307         LMPF_FIXED_SIZE = 1,
308         /// If true can insert newlines 
309         LMPF_ALLOW_CR  = 2,
310         /// If true can use tabs
311         LMPF_ALLOW_TAB = 4,
312         /// If true can insert new columns
313         LMPF_ALLOW_NEW_COL = 8,
314         /// Smaller than current size (frac)
315         LMPF_SMALLER = 16,
316         /// Script size (subscript, stackrel)
317         LMPF_SCRIPT = 32
318 };
319
320
321 /** The math paragraph base class, base to all editable math objects */
322 class MathParInset: public MathedInset  {
323  public: 
324     ///
325     MathParInset(short st = LM_ST_TEXT, char const * nm = 0,
326                  short ot = LM_OT_MIN);
327     ///
328     MathParInset(MathParInset *);
329     ///
330     virtual ~MathParInset();
331     ///
332     virtual MathedInset * Clone();
333
334     /// Draw the object on a drawable
335     virtual void Draw(int x, int baseline);
336
337     /// Write LaTeX code
338     virtual void Write(ostream &);
339
340     /// Write LaTeX code
341     virtual void Write(string & file);
342     ///
343     virtual void Metrics();
344     ///
345     virtual void UserSetSize(short);
346  
347     /// Data is stored in a LyXArray
348     virtual void SetData(LyxArrayBase *);
349     ///
350     virtual LyxArrayBase * GetData() { return array; }
351
352     /// Paragraph position
353     virtual void GetXY(int &, int &) const;
354     ///
355     virtual void setXY(int x, int y) { xo = x;  yo = y; }
356     ///
357     virtual void SetFocus(int, int) {}
358     ///
359     virtual bool Inside(int, int);   
360    
361     // Tab stuff used by Matrix.
362     ///
363     virtual void SetAlign(char, char const *) {}
364 //    ///
365 //    virtual int GetTabPos() { return 0; }
366 //    ///
367 //    virtual int GetTab(int) { return 0; }
368     ///
369     virtual int GetColumns() { return 1; }
370     ///
371     virtual int GetRows() { return 1; }
372     ///
373     virtual bool isMatrix() { return false; }
374 //    /// These functions should report an error
375 //    virtual char const* GetLabel() { return 0; }
376 //    virtual char const* GetLabel(int) { return 0; }
377
378     // Vertical switching
379     ///
380     virtual bool setArgumentIdx(int i) { return (i == 0); }
381     ///
382     virtual bool setNextArgIdx() { return false; }
383     ///
384     virtual int  getArgumentIdx() { return 0; }
385     ///
386     virtual int  getMaxArgumentIdx() { return 0; }
387 //    ///
388 //    virtual void SetLabel(char const *) {}
389     ///
390     virtual void SetStyle(short);
391         ///
392     virtual MathedRowSt * getRowSt() const { return 0; }
393         ///
394     virtual void setRowSt(MathedRowSt *) {}
395         ///
396     virtual bool Permit(short f) { return bool(f & flag); }
397     
398  protected:
399     /// Paragraph data is stored here
400     LyxArrayBase * array;
401     /// Cursor start position
402     int xo, yo;
403     /// 
404     short flag;
405
406  private:
407     ///
408     virtual void setFlag(MathedParFlag f) { flag |= f; }
409         ///
410     friend class InsetFormula;
411         ///
412     friend class MathedXIter;
413         ///
414     friend class MathedCursor;
415         ///
416     friend LyxArrayBase * mathed_parse(unsigned flags = 0,
417                                        LyxArrayBase * a = 0,
418                                        MathParInset ** p = 0);
419 };
420
421
422 /* The physical structure of a row and aditional information is stored here.
423     It allows to manage the extra info independently of the paragraph data.  
424     Only used for multiline paragraphs.
425  */
426 struct MathedRowSt {    
427     /// 
428     MathedRowSt(int n) {
429             w = new int[n + 1]; // this leaks
430             asc = desc = y = 0;
431             for (int i = 0 ; i < n + 1 ; ++i)
432               w[i] = 0;
433             next = 0;
434             label = 0;
435             numbered = true;
436     }
437     ///
438     ~MathedRowSt() {
439         delete[] w;
440         if (label) // DEL LINE
441                 delete[] label;
442     }
443     /// Should be const but...
444     MathedRowSt * getNext() const  { return next; }
445     /// ...we couldn't use this.
446     void setNext(MathedRowSt * n) { next = n; }
447     ///
448     char const * getLabel() const { return label; }
449     ///
450     bool isNumbered() const { return numbered; }
451     ///
452     int  getBaseline() const { return y; }    
453     ///
454     int  getTab(int i) { return w[i]; }
455     /// 
456     void setLabel(char * l) { label = l; }
457     ///
458     void setNumbered(bool nf) { numbered = nf; }
459     ///
460     void setTab(int i, int t) { w[i] = t; }
461     
462  private:
463     /// Vericals 
464     int asc, desc, y;
465     /// widths 
466     int * w;
467     /// 
468     char * label;
469     ///
470     bool numbered;
471     ///
472     MathedRowSt * next;
473         ///
474     friend class MathMatrixInset;
475         ///
476     friend class MathedXIter;
477 };
478
479
480 /** Multiline math paragraph base class.
481     This is the base to all multiline editable math objects
482     like array and eqnarray. 
483  */
484 class MathMatrixInset: public MathParInset {
485  public: 
486     ///
487     MathMatrixInset(int m = 1, int n = 1, short st = LM_ST_TEXT);
488     ///
489     MathMatrixInset(MathMatrixInset *);
490     ///
491     MathedInset * Clone();
492     ///
493     virtual ~MathMatrixInset();
494     ///
495     void Draw(int, int);
496     ///
497     void Write(ostream &);
498     ///
499     void Write(string & file);
500     ///
501     void Metrics();
502     ///
503     void SetData(LyxArrayBase *);
504     ///
505     void SetAlign(char, char const *);
506     ///
507     char * GetAlign(char * vv) {
508         *vv = v_align;
509         return h_align;
510     }
511 //    ///
512 //    int GetTab(int);
513     ///
514     int GetColumns() { return nc; }
515     ///
516     int GetRows() { return nr; }
517     ///
518     virtual bool isMatrix() { return true; }
519
520     /// Use this to manage the extra information independently of paragraph
521     MathedRowSt * getRowSt() const { return row; }
522         ///
523     void setRowSt(MathedRowSt * r) { row = r; }
524     
525  protected:
526     ///  Number of columns & rows
527     int nc, nr;
528     /// tab sizes
529     int * ws;   
530     /// 
531     char v_align; // add approp. signedness
532     ///
533     char * h_align;
534     /// Vertical structure
535     MathedRowSt * row;
536
537 };
538
539
540
541 /*************************  Prototypes  **********************************/
542 /// 
543 LyxArrayBase * mathed_parse(unsigned flags, LyxArrayBase * data,
544                             MathParInset ** mt);
545 ///
546 void mathed_write(MathParInset *, ostream &, int *, char fragile,
547                   char const * label = 0);
548
549 ///
550 void mathed_write(MathParInset *, string &, int *, char fragile,
551                   char const * label = 0);
552 ///
553 void mathed_parser_file(istream &, int);
554 ///
555 int mathed_parser_lineno();
556 ///
557 int MathedLookupBOP(short);
558
559 /************************ Inline functions ********************************/
560 ///
561 inline bool MathIsInset(short x)
562 {
563         return LM_TC_INSET <= x && x <= LM_TC_ACTIVE_INSET;
564 }
565
566 ///
567 inline bool MathIsFont(short x)
568 {
569         return LM_TC_CONST <= x && x <= LM_TC_BSYM;
570 }
571
572 ///
573 inline bool MathIsAlphaFont(short x)
574 {
575         return LM_TC_VAR <= x && x <= LM_TC_TEXTRM;
576 }
577
578 ///
579 inline bool MathIsActive(short x)
580 {
581         return LM_TC_INSET < x && x <= LM_TC_ACTIVE_INSET;
582 }
583
584 ///
585 inline bool MathIsUp(short x)
586 {
587         return x == LM_TC_UP;
588 }
589
590 ///
591 inline bool MathIsDown(short x)
592 {
593         return x == LM_TC_DOWN;
594 }
595
596 ///
597 inline bool MathIsScript(short x)
598 {
599         return x == LM_TC_DOWN || x == LM_TC_UP;
600 }
601
602 ///
603 inline bool MathIsBOPS(short x)
604 {
605         return MathedLookupBOP(x) > LMB_NONE;
606 }
607
608
609 ///
610 inline bool MathIsBinary(short x)
611 {
612     return x == LM_TC_BOP || x == LM_TC_BOPS;
613 }
614
615 ///
616 inline bool MathIsSymbol(short x) {
617     return LM_TC_SYMB <= x && x <= LM_TC_BSYM;
618 }
619      
620
621 inline 
622 MathedInset::MathedInset(char const * nm, short ot, short st):
623   name(nm), objtype(ot), size(st) 
624 {
625    width = ascent = descent = 0;
626 }
627
628 inline
629 bool MathParInset::Inside(int x, int y) 
630 {
631   return (x >= xo && x <= xo + width && y <= yo + descent && y >= yo - ascent);
632 }
633
634
635 inline
636 void MathParInset::GetXY(int & x, int & y) const
637 {
638    x = xo; y = yo;
639 }
640
641
642 inline
643 void MathParInset::UserSetSize(short sz)
644 {
645    if (sz >= 0) {
646        size = sz;      
647        flag = flag & ~LMPF_FIXED_SIZE;
648    }
649 }
650
651
652 inline
653 void MathParInset::SetStyle(short sz) 
654 {
655     if (Permit(LMPF_FIXED_SIZE)) {
656         if (Permit(LMPF_SCRIPT)) 
657           sz = (sz < LM_ST_SCRIPT) ? LM_ST_SCRIPT: LM_ST_SCRIPTSCRIPT;
658         if (Permit(LMPF_SMALLER) && sz < LM_ST_SCRIPTSCRIPT) {
659             ++sz;
660         } 
661         MathedInset::SetStyle(sz);
662     }
663 }
664
665 #endif