mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-24 18:43:37 +00:00
472 lines
9.6 KiB
C++
472 lines
9.6 KiB
C++
|
/*
|
||
|
* File: math_write.h
|
||
|
* Purpose: Write math paragraphs in LaTeX
|
||
|
* Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
|
||
|
* Created: January 1996
|
||
|
* Description:
|
||
|
*
|
||
|
* Dependencies: Xlib, XForms
|
||
|
*
|
||
|
* Copyright: (c) 1996, 1997 Alejandro Aguilar Sierra
|
||
|
*
|
||
|
* Version: 0.8beta, Mathed & 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 <config.h>
|
||
|
#include "LString.h"
|
||
|
#include "math_inset.h"
|
||
|
#include "math_iter.h"
|
||
|
#include "math_parser.h"
|
||
|
|
||
|
|
||
|
extern char const *latex_mathenv[];
|
||
|
extern char *latex_mathspace[];
|
||
|
|
||
|
// quite a hack i know. Should be done with return values...
|
||
|
static int number_of_newlines;
|
||
|
|
||
|
char const *math_font_name[] = {
|
||
|
"mathrm",
|
||
|
"mathcal",
|
||
|
"mathbf",
|
||
|
"mathsf",
|
||
|
"mathtt",
|
||
|
"mathit",
|
||
|
"textrm"
|
||
|
};
|
||
|
|
||
|
|
||
|
void
|
||
|
MathSpaceInset::Write(FILE *outf)
|
||
|
{
|
||
|
if (space>=0 && space<6) {
|
||
|
LString output;
|
||
|
MathSpaceInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
MathSpaceInset::Write(LString &outf)
|
||
|
{
|
||
|
if (space>=0 && space<6) {
|
||
|
outf += '\\';
|
||
|
outf += latex_mathspace[space];
|
||
|
outf += ' ';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
MathDotsInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathDotsInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void
|
||
|
MathDotsInset::Write(LString &outf)
|
||
|
{
|
||
|
outf += '\\';
|
||
|
outf += name;
|
||
|
outf += ' ';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathSqrtInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathSqrtInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathSqrtInset::Write(LString &outf)
|
||
|
{
|
||
|
outf += '\\';
|
||
|
outf += name;
|
||
|
outf += '{';
|
||
|
MathParInset::Write(outf);
|
||
|
outf += '}';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathDelimInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathDelimInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathDelimInset::Write(LString &outf)
|
||
|
{
|
||
|
latexkeys* l = (left != '|') ? lm_get_key_by_id(left, LM_TK_SYM): 0;
|
||
|
latexkeys* r = (right != '|') ? lm_get_key_by_id(right, LM_TK_SYM): 0;
|
||
|
outf += "\\left";
|
||
|
if (l) {
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
outf += ' ';
|
||
|
} else {
|
||
|
if (left=='{' || left=='}') {
|
||
|
outf += '\\';
|
||
|
outf += (char) left;
|
||
|
outf += ' ';
|
||
|
} else {
|
||
|
outf += (char) left;
|
||
|
outf += ' ';
|
||
|
}
|
||
|
}
|
||
|
MathParInset::Write(outf);
|
||
|
outf += "\\right";
|
||
|
if (r) {
|
||
|
outf += '\\';
|
||
|
outf += r->name;
|
||
|
outf += ' ';
|
||
|
} else {
|
||
|
if (right=='{' || right=='}') {
|
||
|
outf += '\\';
|
||
|
outf += (char) right;
|
||
|
outf += ' ';
|
||
|
} else {
|
||
|
outf += (char) right;
|
||
|
outf += ' ';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathDecorationInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathDecorationInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathDecorationInset::Write(LString &outf)
|
||
|
{
|
||
|
latexkeys* l = lm_get_key_by_id(deco, LM_TK_WIDE);
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
outf += '{';
|
||
|
MathParInset::Write(outf);
|
||
|
outf += '}';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathAccentInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathAccentInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathAccentInset::Write(LString &outf)
|
||
|
{
|
||
|
latexkeys* l = lm_get_key_by_id(code, LM_TK_ACCENT);
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
if (code!=LM_not)
|
||
|
outf += '{';
|
||
|
else
|
||
|
outf += ' ';
|
||
|
|
||
|
if (inset) {
|
||
|
inset->Write(outf);
|
||
|
} else {
|
||
|
if (fn>=LM_TC_RM && fn<=LM_TC_TEXTRM) {
|
||
|
outf += '\\';
|
||
|
outf += math_font_name[fn-LM_TC_RM];
|
||
|
outf += '{';
|
||
|
}
|
||
|
if (MathIsSymbol(fn)) {
|
||
|
latexkeys *l = lm_get_key_by_id(c, LM_TK_SYM);
|
||
|
if (l) {
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
outf += ' ';
|
||
|
}
|
||
|
} else
|
||
|
outf += (char) c;
|
||
|
|
||
|
if (fn>=LM_TC_RM && fn<=LM_TC_TEXTRM)
|
||
|
outf += '}';
|
||
|
}
|
||
|
|
||
|
if (code!=LM_not)
|
||
|
outf += '}';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathBigopInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathBigopInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathBigopInset::Write(LString &outf)
|
||
|
{
|
||
|
bool limp = GetLimits();
|
||
|
|
||
|
outf += '\\';
|
||
|
outf += name;
|
||
|
|
||
|
if (limp && !(sym!=LM_int && sym!=LM_oint && (GetStyle()==LM_ST_DISPLAY)))
|
||
|
outf += "\\limits ";
|
||
|
else
|
||
|
if (!limp && (sym!=LM_int && sym!=LM_oint && (GetStyle()==LM_ST_DISPLAY)))
|
||
|
outf += "\\nolimits ";
|
||
|
else
|
||
|
outf += ' ';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathFracInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathFracInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathFracInset::Write(LString &outf)
|
||
|
{
|
||
|
outf += '\\';
|
||
|
outf += name;
|
||
|
outf += '{';
|
||
|
MathParInset::Write(outf);
|
||
|
outf += "}{";
|
||
|
den->Write(outf);
|
||
|
outf += '}';
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathParInset::Write(FILE *outf)
|
||
|
{
|
||
|
if (!array) return;
|
||
|
LString output;
|
||
|
MathParInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathParInset::Write(LString &outf)
|
||
|
{
|
||
|
if (!array) return;
|
||
|
int brace = 0;
|
||
|
latexkeys *l;
|
||
|
MathedIter data(array);
|
||
|
// hack
|
||
|
MathedRowSt const* crow = getRowSt();
|
||
|
data.Reset();
|
||
|
|
||
|
if (!Permit(LMPF_FIXED_SIZE)) {
|
||
|
l = lm_get_key_by_id(size, LM_TK_STY);
|
||
|
if (l) {
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
outf += ' ';
|
||
|
}
|
||
|
}
|
||
|
while (data.OK()) {
|
||
|
byte cx = data.GetChar();
|
||
|
if (cx>=' ') {
|
||
|
int ls;
|
||
|
byte *s = data.GetString(ls);
|
||
|
|
||
|
if (data.FCode()>=LM_TC_RM && data.FCode()<=LM_TC_TEXTRM) {
|
||
|
outf += '\\';
|
||
|
outf += math_font_name[data.FCode()-LM_TC_RM];
|
||
|
outf += '{';
|
||
|
}
|
||
|
while (ls>0) {
|
||
|
if (MathIsSymbol(data.FCode())) {
|
||
|
l = lm_get_key_by_id(*s,(data.FCode()==LM_TC_BSYM)?LM_TK_BIGSYM:LM_TK_SYM);
|
||
|
if (l) {
|
||
|
outf += '\\';
|
||
|
outf += l->name;
|
||
|
outf += ' ';
|
||
|
} else {
|
||
|
fprintf(stderr, "Illegal symbol code[%u %d %d]", *s, ls, data.FCode());
|
||
|
}
|
||
|
} else {
|
||
|
// Is there a standard logical XOR?
|
||
|
if ((data.FCode()==LM_TC_TEX && *s!='{' && *s!='}') ||
|
||
|
(data.FCode()==LM_TC_SPECIAL))
|
||
|
outf += '\\';
|
||
|
else {
|
||
|
if (*s=='{') brace++;
|
||
|
if (*s=='}') brace--;
|
||
|
}
|
||
|
if (*s=='}' && data.FCode()==LM_TC_TEX && brace<0)
|
||
|
fprintf(stderr, "Math warning: Unexpected closing brace.\n");
|
||
|
else
|
||
|
outf += (char) *s;
|
||
|
}
|
||
|
s++; ls--;
|
||
|
}
|
||
|
if (data.FCode()>=LM_TC_RM && data.FCode()<=LM_TC_TEXTRM)
|
||
|
outf += '}';
|
||
|
} else
|
||
|
if (MathIsInset(cx)) {
|
||
|
MathedInset *p = data.GetInset();
|
||
|
if (cx==LM_TC_UP)
|
||
|
outf += "^{";
|
||
|
if (cx==LM_TC_DOWN)
|
||
|
outf += "_{";
|
||
|
p->Write(outf);
|
||
|
if (cx==LM_TC_UP || cx==LM_TC_DOWN)
|
||
|
outf += '}';
|
||
|
data.Next();
|
||
|
} else
|
||
|
switch(cx) {
|
||
|
case LM_TC_TAB:
|
||
|
{
|
||
|
outf += " & ";
|
||
|
data.Next();
|
||
|
break;
|
||
|
}
|
||
|
case LM_TC_CR:
|
||
|
{
|
||
|
if (crow) {
|
||
|
if (!crow->isNumbered()) {
|
||
|
outf +="\\nonumber ";
|
||
|
}
|
||
|
if (crow->getLabel()) {
|
||
|
outf += "\\label{";
|
||
|
outf += crow->getLabel();
|
||
|
outf += "} ";
|
||
|
}
|
||
|
crow = crow->getNext();
|
||
|
}
|
||
|
outf += "\\\\\n";
|
||
|
number_of_newlines++;
|
||
|
data.Next();
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
fprintf(stderr, "WMath Error: unrecognized code[%d]", cx);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (crow) {
|
||
|
if (!crow->isNumbered()) {
|
||
|
outf +="\\nonumber ";
|
||
|
}
|
||
|
if (crow->getLabel()) {
|
||
|
outf += "\\label{";
|
||
|
outf += crow->getLabel();
|
||
|
outf += "} ";
|
||
|
}
|
||
|
}
|
||
|
while (brace>0) {
|
||
|
outf += '}';
|
||
|
brace--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void MathMatrixInset::Write(FILE *outf)
|
||
|
{
|
||
|
LString output;
|
||
|
MathMatrixInset::Write(output);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
void MathMatrixInset::Write(LString &outf)
|
||
|
{
|
||
|
if (GetType() == LM_OT_MATRIX){
|
||
|
outf += "\\begin{";
|
||
|
outf += name;
|
||
|
outf += '}';
|
||
|
if (v_align=='t' || v_align=='b') {
|
||
|
outf += '[';
|
||
|
outf += (char) v_align;
|
||
|
outf += ']';
|
||
|
}
|
||
|
outf += '{';
|
||
|
outf += h_align;
|
||
|
outf += "}\n";
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
MathParInset::Write(outf);
|
||
|
if (GetType() == LM_OT_MATRIX){
|
||
|
outf += "\n\\end{";
|
||
|
outf += name;
|
||
|
outf += '}';
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void mathed_write(MathParInset* p, FILE* outf, int* newlines, char fragile, char const* label)
|
||
|
{
|
||
|
LString output;
|
||
|
mathed_write(p, output, newlines, fragile, label);
|
||
|
fprintf(outf, "%s", output.c_str());
|
||
|
}
|
||
|
|
||
|
extern int tex_code_break_column;
|
||
|
|
||
|
void mathed_write(MathParInset* p, LString& outf, int* newlines,
|
||
|
char fragile, char const* label)
|
||
|
{
|
||
|
number_of_newlines = 0;
|
||
|
short mathed_env = p->GetType();
|
||
|
|
||
|
if (mathed_env==LM_EN_INTEXT) {
|
||
|
if (fragile) outf += "\\protect";
|
||
|
outf += "\\( "; // changed from " \\( " (Albrecht Dress)
|
||
|
}
|
||
|
else {
|
||
|
if (! outf.suffixIs('\n')) {
|
||
|
// in batchmode we need to make sure
|
||
|
// a space before an equation doesn't
|
||
|
// make the LaTeX output different
|
||
|
// compared to "Exported LaTeX" ARRae
|
||
|
// Modified to work in a cleaner and hopefully more general way
|
||
|
// (JMarc)
|
||
|
outf += "\n";
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
if (mathed_env==LM_EN_DISPLAY){
|
||
|
outf += "\\[\n";
|
||
|
}
|
||
|
else {
|
||
|
outf += "\\begin{";
|
||
|
outf += latex_mathenv[mathed_env];
|
||
|
outf += "}\n";
|
||
|
}
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
|
||
|
if (label && label[0]>' ' && mathed_env==LM_EN_EQUATION){
|
||
|
outf += "\\label{";
|
||
|
outf += label;
|
||
|
outf += "}\n";
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
|
||
|
p->Write(outf);
|
||
|
|
||
|
if (mathed_env==LM_EN_INTEXT){
|
||
|
if (fragile) outf += "\\protect";
|
||
|
outf += " \\)";
|
||
|
}
|
||
|
else if (mathed_env==LM_EN_DISPLAY){
|
||
|
outf += "\\]\n";
|
||
|
number_of_newlines++;
|
||
|
}
|
||
|
else {
|
||
|
outf += "\n\\end{";
|
||
|
outf += latex_mathenv[mathed_env];
|
||
|
outf += "}\n";
|
||
|
number_of_newlines+=2;
|
||
|
}
|
||
|
*newlines = number_of_newlines;
|
||
|
}
|