// -*- C++ -*- /* * File: math_macro.C * Purpose: Implementation of macro class for mathed * Author: Alejandro Aguilar Sierra * Created: November 1996 * Description: WYSIWYG math macros * * Dependencies: Mathed * * Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra * * Version: 0.2, Mathed & Lyx project. * * This code is under the GNU General Public Licence version 2 or later. */ #include #include FORMS_H_LOCATION #ifdef __GNUG__ #pragma implementation "math_macro.h" #pragma implementation "math_defs.h" #endif #include "LString.h" #include "math_macro.h" #include "math_iter.h" #include "math_inset.h" #include "support/lstrings.h" #include "debug.h" ostream & operator<<(ostream & o, MathedTextCodes mtc) { return o << int(mtc); } enum MathedMacroFlag { MMF_Env=1, MMF_Exp=2, MMF_Edit=4 }; ostream & operator<<(ostream & o, MathedMacroFlag mmf) { return o << int(mmf); } extern GC mathGC, mathFrameGC, latexGC; extern int mathed_string_width(short type, int style, byte const* s, int ls); extern int mathed_string_height(short, int, byte const*, int, int&, int&); MathMacro::MathMacro(MathMacroTemplate* t): MathParInset(LM_ST_TEXT, "", LM_OT_MACRO), tmplate(t) { nargs = tmplate->getNoArgs(); tcode = tmplate->getTCode(); args = new MacroArgumentBase[nargs]; for (int i=0; igetMacroPar(i)->Permit(LMPF_ALLOW_CR)) // args[i].row = new MathedRowSt(tmplate->getMacroPar(i)->GetColumns()); // else args[i].row = 0; /* int k = tmplate->getMacroPar(i)->GetColumns(); if (k>0) { args[i].array = new LyxArrayBase; for (int j=0; jInsert(j, LM_TC_TAB); }*/ } idx = 0; SetName(tmplate->GetName()); } MathMacro::MathMacro(MathMacro* m): MathParInset(LM_ST_TEXT, m->GetName(), LM_OT_MACRO) { tmplate = m->tmplate; nargs = tmplate->getNoArgs(); tcode = tmplate->getTCode(); args = new MacroArgumentBase[nargs]; idx = 0; SetName(tmplate->GetName()); for (int i=0; inargs; i++) { m->setArgumentIdx(i); MathedIter it(m->GetData()); args[i].row = m->args[i].row; args[i].array = it.Copy(); } } MathMacro::~MathMacro() { for (idx=0; idx0) tmplate->update(this); tmplate->Metrics(); width = tmplate->Width(); ascent = tmplate->Ascent(); descent = tmplate->Descent(); } void MathMacro::Draw(int x, int y) { xo = x; yo = y; Metrics(); tmplate->update(this); tmplate->SetStyle(size); mathGC = latexGC; tmplate->Draw(x, y); for (int i=0; iGetMacroXY(i, args[i].x, args[i].y); } int MathMacro::GetColumns() { return tmplate->getMacroPar(idx)->GetColumns(); } void MathMacro::GetXY(int& x, int& y) const { x = args[idx].x; y = args[idx].y; } bool MathMacro::Permit(short f) { return ((nargs>0) ? tmplate->getMacroPar(idx)->Permit(f): MathParInset::Permit(f)); } void MathMacro::SetFocus(int x, int y) { tmplate->update(this); tmplate->SetMacroFocus(idx, x, y); } void MathMacro::Write(FILE *file) { string output; MathMacro::Write(output); fprintf(file, "%s", output.c_str()); } void MathMacro::Write(string &file) { if (tmplate->flags & MMF_Exp) { lyxerr[Debug::MATHED] << "Expand " << tmplate->flags << ' ' << MMF_Exp << endl; tmplate->update(this); tmplate->Write(file); } else { if (tmplate->flags & MMF_Env) { file += "\\begin{"; file += name; file += "} "; } else { file += '\\'; file += name; } // if (options) { // file += '['; // file += options; // file += ']'; // } if (!(tmplate->flags & MMF_Env) && nargs>0) file += '{'; for (int i=0; iflags & MMF_Env) { file += "\\end{"; file += name; file += '}'; } else { if (nargs>0) file += '}'; else file += ' '; } } } /*--------------- Macro argument -----------------------------------*/ MathMacroArgument::MathMacroArgument(int n) { number = n; expnd_mode = false; SetType(LM_OT_MACRO_ARG); } void MathMacroArgument::Draw(int x, int baseline) { if (expnd_mode) { MathParInset::Draw(x, baseline); } else { unsigned char s[3]; sprintf((char*)s, "#%d", number); drawStr(LM_TC_TEX, size, x, baseline, &s[0], 2); } } void MathMacroArgument::Metrics() { if (expnd_mode) { MathParInset::Metrics(); } else { unsigned char s[3]; sprintf((char*)s, "#%d", number); width = mathed_string_width(LM_TC_TEX, size, &s[0], 2); mathed_string_height(LM_TC_TEX, size, &s[0], 2, ascent, descent); } } void MathMacroArgument::Write(FILE *file) { string output; MathMacroArgument::Write(output); fprintf(file, "%s", output.c_str()); } void MathMacroArgument::Write(string &file) { if (expnd_mode) { MathParInset::Write(file); } else { file += '#'; file += tostr(number); file += ' '; } } /* --------------------- MathMacroTemplate ---------------------------*/ MathMacroTemplate::MathMacroTemplate(char const *nm, int na, int flg): MathParInset(LM_ST_TEXT, nm, LM_OT_MACRO), flags(flg), nargs(na) { if (nargs>0) { tcode = LM_TC_ACTIVE_INSET; args = new MathMacroArgument[nargs]; for (int i=0; i0) ? args[0].getExpand(): false; if (flags & MMF_Edit) { for (int i=0; i0) ? args[0].getExpand(): false; if (flags & MMF_Edit) { for (int i=0; igetArgumentIdx(): 0; for (int i=0; isetArgumentIdx(i); args[i].SetData(macro->GetData()); MathedRowSt *row = macro->getRowSt(); args[i].setRowSt(row); } } if (macro) macro->setArgumentIdx(idx); } void MathMacroTemplate::WriteDef(FILE *file) { fprintf(file, "\n\\newcommand{\\%s}", name); if (nargs > 0 ) fprintf(file, "[%d]", nargs); fprintf(file, "{"); for (int i=0; i 0 ) { file += '['; file += tostr(nargs); file += ']'; } file += '{'; for (int i=0; i=0 && iGetName())==0) return macro_table[i]; } return 0; } void MathMacroTable::addTemplate(MathMacroTemplate *m) { if (num_macrosSetData(array); // These two are only while we are still with LyX 2.x m = new MathMacroTemplate("emptyset"); // this leaks addTemplate(m); array = new LyxArrayBase; // this leaks iter.SetData(array); iter.Insert(new MathAccentInset('O', LM_TC_RM, LM_not)); // this leaks m->SetData(array); m = new MathMacroTemplate("perp"); // this leaks addTemplate(m); array = new LyxArrayBase; // this leaks iter.SetData(array); iter.Insert(LM_bot, LM_TC_BOP); m->SetData(array); // binom has two arguments m = new MathMacroTemplate("binom", 2); addTemplate(m); array = new LyxArrayBase; m->SetData(array); iter.SetData(array); inset = new MathDelimInset('(', ')'); iter.Insert(inset, LM_TC_ACTIVE_INSET); array = new LyxArrayBase; iter.SetData(array); MathFracInset *frac = new MathFracInset(LM_OT_ATOP); iter.Insert(frac, LM_TC_ACTIVE_INSET); inset->SetData(array); array = new LyxArrayBase; array2 = new LyxArrayBase; iter.SetData(array); iter.Insert(m->getMacroPar(0)); iter.SetData(array2); iter.Insert(m->getMacroPar(1)); frac->SetData(array, array2); /* // Cases has 1 argument m = new MathMacroTemplate("cases", 1, MMF_Env); // this leaks addTemplate(m); array = new LyxArrayBase; // this leaks iter.SetData(array); arg = new MathMatrixInset(2,1); // this leaks m->setArgument(arg); arg->SetAlign('c',"ll"); iter.Insert(arg, LM_TC_ACTIVE_INSET); inset = new MathDelimInset('{', '.'); // this leaks inset->SetData(array); array = new LyxArrayBase; // this leaks iter.SetData(array); iter.Insert(inset, LM_TC_ACTIVE_INSET); m->SetData(array); // the environment substack has 1 argument m = new MathMacroTemplate("substack", 1, MMF_Env); // this leaks addTemplate(m); arg = new MathMatrixInset(1,1); // this leaks m->setArgument(arg); arg->SetType(LM_OT_MACRO); array = new LyxArrayBase; // this leaks iter.SetData(array); iter.Insert(arg, LM_TC_ACTIVE_INSET); m->SetData(array);*/ } MathMacroTable MathMacroTable::mathMTable(255); bool MathMacroTable::built = false;