mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-24 09:31:40 +08:00
NEW: JKQTMathText: LaTeX-Parser understands optional instruction parameters in [...] now
This commit is contained in:
parent
5c255712ce
commit
d885f7f00a
@ -39,6 +39,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW: reworked node class tree: inserted base-class nodes for single-child, dual-child!</li>
|
||||
<li>NEW: improved frac-rendering: font-scaling takes nesting-level into account, overall-rendering, sizes, if a brace surrounds a frac, the heights are equal above and below to center the brace , ...</li>
|
||||
<li>NEW: shows strikeoutPos when drawing Debug-Boxes</li>
|
||||
<li>NEW: LaTeX-Parser understands optional instruction parameters in [...] now</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
@ -355,7 +355,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
|
||||
name=QString("MTsqrtNode: deg=%1").arg(sqrtN->getDegree());
|
||||
if (sqrtN->getChild()) ti->addChild(createTree(sqrtN->getChild(), ti));
|
||||
} else if (braceN) {
|
||||
name=QString("MTbraceNode: l[showL=%3]='%1', r[showR=%4]='%2'").arg(braceN->getOpenbrace()).arg(braceN->getClosebrace()).arg(braceN->getShowOpeningBrace()).arg(braceN->getShowClosingBrace());
|
||||
name=QString("MTbraceNode: l='%1', r='%2'").arg(JKQTMathTextBraceType2String(braceN->getOpenbrace())).arg(JKQTMathTextBraceType2String(braceN->getClosebrace()));
|
||||
if (braceN->getChild()) ti->addChild(createTree(braceN->getChild(), ti));
|
||||
} else if (superN) {
|
||||
name=QString("MTsuperscriptNode");
|
||||
|
@ -823,20 +823,33 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
|
||||
if (currentTokenID>parseString.size()-1) return currentToken=MTTnone;
|
||||
QChar c=parseString[currentTokenID];
|
||||
currentTokenName="";
|
||||
if (c=='\\') { // read an instruction name
|
||||
//----------------------------------------------------------
|
||||
// define some static sets for easy character lookup/identificattion
|
||||
static QSet<QChar> TokenCharacters;
|
||||
static QSet<QChar> mathEnvironmentSpecialChars, mathEnvironmentSpecialEndChars;
|
||||
static QSet<QChar> SingleCharInstructions;
|
||||
if (TokenCharacters.size()==0) {
|
||||
mathEnvironmentSpecialChars<<'(' << '[' << '|' << ')' << ']' << '+' << '-' << '*' << '/' << '<' << '>' << '=';
|
||||
mathEnvironmentSpecialEndChars<<'(' << '&' << '[' << '|' << ')' << ']' << '\\' << '$' << '{' << '}' << '_' << '^' << '+' << '-' << '/' << '*' << '=' << '<' << '>';
|
||||
TokenCharacters<<'_'<<'^'<<'\\'<<'$'<<'&'<<'}'<<'{'<<'['<<']';
|
||||
SingleCharInstructions<<'|'<<';'<<':'<<'!'<<','<<'_'<<'\\'<<'$'<<'%'<<'&'<<'#'<<'}'<<'{'<<' '<<'['<<']';
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
// read an instruction name
|
||||
if (c=='\\') {
|
||||
currentTokenID++;
|
||||
if (currentTokenID>=parseString.size()-1) return currentToken=MTTnone;
|
||||
c=parseString[currentTokenID];
|
||||
/*if (c=='_' || c=='\\' || c=='$' || c=='%' || c=='&' || c=='#' || c=='}' || c=='{') {
|
||||
currentTokenName=c; // parse special one-symbol instructions like \\, \& ...
|
||||
// that may be directly converted to text
|
||||
return currentToken=MTTtext;
|
||||
} else*/ if (c=='|' || c==';' || c==':' || c=='!' || c==',' || c=='_' || c=='\\' || c=='$' ||
|
||||
c=='%' || c=='&' || c=='#' || c=='}' || c=='{' || c==' ') {
|
||||
//----------------------------------------------------------
|
||||
// parsing single-character instruction
|
||||
if (SingleCharInstructions.contains(c)) {
|
||||
currentTokenName=c; // parse one-symbol instructions like \\, \& ...
|
||||
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
|
||||
return currentToken=MTTinstruction;
|
||||
} else { // parse letter instructions
|
||||
//----------------------------------------------------------
|
||||
// letter-only instruction name
|
||||
} else {
|
||||
while (c.isLetter()&& (currentTokenID<parseString.size())) {
|
||||
currentTokenName+=c;
|
||||
currentTokenID++;
|
||||
@ -846,42 +859,64 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
|
||||
currentTokenName=currentTokenName.trimmed();
|
||||
}
|
||||
//std::cout<<"found instruction node '"<<currentTokenName.toStdString()<<"'\n";
|
||||
if (currentTokenName.size()==0) error_list.append(tr("error @ ch. %1: parser encountered empty istruction").arg(currentTokenID));
|
||||
return currentToken=MTTinstruction;
|
||||
//----------------------------------------------------------
|
||||
// check for $ character
|
||||
} else if (c=='$') {
|
||||
//std::cout<<"found dollar\n";
|
||||
return currentToken=MTTdollar;
|
||||
//----------------------------------------------------------
|
||||
// check for & character
|
||||
} else if (c=='&') {
|
||||
//std::cout<<"found ampersand\n";
|
||||
return currentToken=MTTampersand;
|
||||
//----------------------------------------------------------
|
||||
// check for { character
|
||||
} else if (c=='{') {
|
||||
//std::cout<<"found openbrace\n";
|
||||
return currentToken=MTTopenbrace;
|
||||
//----------------------------------------------------------
|
||||
// check for } character
|
||||
} else if (c=='}') {
|
||||
//std::cout<<"found closebrace\n";
|
||||
return currentToken=MTTclosebrace;
|
||||
//----------------------------------------------------------
|
||||
// check for [ character
|
||||
} else if (c=='[') {
|
||||
//std::cout<<"found openbracket\n";
|
||||
return currentToken=MTTopenbracket;
|
||||
//----------------------------------------------------------
|
||||
// check for ] character
|
||||
} else if (c==']') {
|
||||
//std::cout<<"found closebracket\n";
|
||||
return currentToken=MTTclosebracket;
|
||||
//----------------------------------------------------------
|
||||
// check for _ character
|
||||
} else if (c=='_') {
|
||||
//std::cout<<"found underscore\n";
|
||||
return currentToken=MTTunderscore;
|
||||
//----------------------------------------------------------
|
||||
// check for ^ character
|
||||
} else if (c=='^') {
|
||||
//std::cout<<"found hat\n";
|
||||
return currentToken=MTThat;
|
||||
//----------------------------------------------------------
|
||||
// check for whitespace character
|
||||
} else if (c.isSpace()) {
|
||||
while (c.isSpace() &&(currentTokenID<parseString.size())) { // eat up whitespace
|
||||
currentTokenID++;
|
||||
if (currentTokenID<parseString.size())c=parseString[currentTokenID];
|
||||
if (currentTokenID<parseString.size()) c=parseString[currentTokenID];
|
||||
}
|
||||
if (!c.isSpace()) currentTokenID--;
|
||||
//std::cout<<"found whitespace\n";
|
||||
return currentToken=MTTwhitespace;
|
||||
} else {
|
||||
//----------------------------------------------------------
|
||||
// no instruction or special character => parse text
|
||||
if (parsingMathEnvironment) {
|
||||
// inside math environments we split texts at every brace {[(|)]} so that
|
||||
// braces form their own JKQTMathTextTextNode and may be formated accordingly
|
||||
static QSet<QChar> mathEnvironmentSpecialChars, mathEnvironmentSpecialEndChars;
|
||||
if (mathEnvironmentSpecialChars.size()==0) {
|
||||
mathEnvironmentSpecialChars<<'(' << '[' << '|' << ')' << ']' << '+' << '-' << '*' << '/' << '<' << '>' << '=';
|
||||
mathEnvironmentSpecialEndChars<<'(' << '&' << '[' << '|' << ')' << ']' << '\\' << '$' << '{' << '}' << '_' << '^' << '+' << '-' << '/' << '*' << '=' << '<' << '>';
|
||||
}
|
||||
if (mathEnvironmentSpecialChars.contains(c)) {
|
||||
currentTokenName=c;
|
||||
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
|
||||
@ -896,14 +931,14 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
|
||||
}
|
||||
} else currentTokenName+=c;
|
||||
currentTokenID++;
|
||||
if (currentTokenID<parseString.size())c=parseString[currentTokenID];
|
||||
if (currentTokenID<parseString.size()) c=parseString[currentTokenID];
|
||||
}
|
||||
if (mathEnvironmentSpecialEndChars.contains(c) || c.isSpace()) currentTokenID--;
|
||||
//currentTokenName=currentTokenName.trimmed();
|
||||
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
|
||||
return currentToken=MTTtext;
|
||||
} else {
|
||||
while ((!c.isSpace()) && c!='&' && c!='\\' && c!='$' && c!='{' && c!='}' && c!='_' && c!='^' && (currentTokenID<parseString.size())) {
|
||||
while ((!c.isSpace()) && !TokenCharacters.contains(c) && (currentTokenID<parseString.size())) {
|
||||
// add whitespaces only once
|
||||
if (c.isSpace()) {
|
||||
if (!currentTokenName.isEmpty()) {
|
||||
@ -912,9 +947,9 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
|
||||
}
|
||||
} else currentTokenName+=c;
|
||||
currentTokenID++;
|
||||
if (currentTokenID<parseString.size())c=parseString[currentTokenID];
|
||||
if (currentTokenID<parseString.size()) c=parseString[currentTokenID];
|
||||
}
|
||||
if (c=='&' || c=='\\' || c=='$' || c=='{' || c=='}' || c=='_' || c=='^' || c.isSpace()) currentTokenID--;
|
||||
if (TokenCharacters.contains(c) || c.isSpace()) currentTokenID--;
|
||||
//currentTokenName=currentTokenName.trimmed();
|
||||
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
|
||||
return currentToken=MTTtext;
|
||||
@ -923,10 +958,18 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
|
||||
return currentToken=MTTnone;
|
||||
}
|
||||
|
||||
JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOnClosingBrace, const QString& quitOnEnvironmentEnd) {
|
||||
JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace, const QString& quitOnEnvironmentEnd, bool quitOnClosingBracket) {
|
||||
//std::cout<<" entering parseLatexString()\n";
|
||||
JKQTMathTextListNode* nl=new JKQTMathTextListNode(this);
|
||||
if (get) getToken();
|
||||
|
||||
//----------------------------------------------------------
|
||||
// initialize some static sets for easy and fast character lookup
|
||||
static QSet<QString> mathEnvironmentSpecialText;
|
||||
if (mathEnvironmentSpecialText.size()==0) {
|
||||
mathEnvironmentSpecialText<<"+"<<"-"<<"="<<"*"<<"<"<<">"<<"|"<<"/";
|
||||
}
|
||||
|
||||
bool getNew=true;
|
||||
while (currentToken!=MTTnone) {
|
||||
getNew=true;
|
||||
@ -935,10 +978,6 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
bool addWhite=(getToken()==MTTwhitespace) && (!parsingMathEnvironment);
|
||||
getNew=addWhite;
|
||||
if (parsingMathEnvironment) {
|
||||
static QSet<QString> mathEnvironmentSpecialText;
|
||||
if (mathEnvironmentSpecialText.size()==0) {
|
||||
mathEnvironmentSpecialText<<"+"<<"-"<<"="<<"*"<<"<"<<">"<<"|"<<"/";
|
||||
}
|
||||
if (mathEnvironmentSpecialText.contains(text.trimmed())) {
|
||||
nl->addNode(new JKQTMathTextSymbolNode(this, text, addWhite));
|
||||
} else {
|
||||
@ -948,16 +987,16 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
nl->addNode(new JKQTMathTextTextNode(this, text, addWhite, parsingMathEnvironment));
|
||||
}
|
||||
} else if (currentToken==MTTinstruction) {
|
||||
QString name=currentTokenName;
|
||||
if (name=="\\") break; // break on linebrak character
|
||||
const QString currentInstructionName=currentTokenName;
|
||||
if (currentInstructionName=="\\") break; // break on linebrak character
|
||||
getToken(); // look at next token
|
||||
if (currentToken==MTTopenbrace) {
|
||||
//std::cout<<"found '{' after '"<<name.toStdString()<<"'\n";
|
||||
if (name=="sqrt") {
|
||||
if (currentInstructionName=="sqrt") {
|
||||
nl->addNode(new JKQTMathTextSqrtNode(this, parseLatexString(true)));
|
||||
} else if (name=="cbrt") {
|
||||
} else if (currentInstructionName=="cbrt") {
|
||||
nl->addNode(new JKQTMathTextSqrtNode(this, parseLatexString(true), 3));
|
||||
} else if (name=="verb") {
|
||||
} else if (currentInstructionName=="verb") {
|
||||
QString text="";
|
||||
currentTokenID++;
|
||||
if (currentTokenID<=parseString.size()-1) {
|
||||
@ -967,76 +1006,76 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
currentTokenID++;
|
||||
if (currentTokenID<parseString.size()) c=parseString[currentTokenID];
|
||||
}
|
||||
if (c!='}') error_list.append(tr("error @ ch. %1: \verb{...} not closed by '}'").arg(currentTokenID).arg(name));
|
||||
if (c!='}') error_list.append(tr("error @ ch. %1: \verb{...} not closed by '}'").arg(currentTokenID).arg(currentInstructionName));
|
||||
nl->addNode(new JKQTMathTextTextNode(this, text, false));
|
||||
}
|
||||
} else if (name=="frac") {
|
||||
} else if (currentInstructionName=="frac") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMfrac));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="dfrac" || name=="cfrac") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="dfrac" || currentInstructionName=="cfrac") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMdfrac));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="sfrac" || name=="slantfrac" || name=="xfrac") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="sfrac" || currentInstructionName=="slantfrac" || currentInstructionName=="xfrac") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMsfrac));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="stfrac" || name=="nicefrac" || name=="slanttextfrac" || name=="xtfrac") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="stfrac" || currentInstructionName=="nicefrac" || currentInstructionName=="slanttextfrac" || currentInstructionName=="xtfrac") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMstfrac));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="tfrac") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="tfrac") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMtfrac));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="stackrel") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="stackrel") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMstackrel));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="binom") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="binom") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTParenthesis, JKQTMathTextBraceNode::MTBTParenthesis, new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMstackrel)));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="underbrace") {
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMstackrel)));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="underbrace") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMunderbrace));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="underset") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="underset") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMunderset));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="overbrace") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="overbrace") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMoverbrace));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="overset") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="overset") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true);
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMoverset));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
} else if (name=="begin") {
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else if (currentInstructionName=="begin") {
|
||||
if (getToken()==MTTtext) {
|
||||
QString envname=currentTokenName;
|
||||
while (currentToken!=MTTclosebrace) getToken(); // find closing brace '}' after '\\begin{name'
|
||||
@ -1048,7 +1087,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
QVector<JKQTMathTextNode*> line;
|
||||
//std::cout<<"found \\begin{matrix}\n";
|
||||
while (first || currentToken==MTTampersand || (currentToken==MTTinstruction && currentTokenName=="\\")) {
|
||||
JKQTMathTextNode* it=parseLatexString(true, "", envname);
|
||||
JKQTMathTextNode* it=parseLatexString(true, MTBTAny, envname);
|
||||
if (currentToken==MTTampersand) {
|
||||
//std::cout<<" appending item\n";
|
||||
line.append(it);
|
||||
@ -1061,12 +1100,12 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
first=false;
|
||||
}
|
||||
//std::cout<<" creating matrix-node with "<<items.size()<<" items.\n";
|
||||
if (envname=="pmatrix") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTParenthesis, JKQTMathTextBraceNode::MTBTParenthesis, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="cases") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCurlyBracket, JKQTMathTextBraceNode::MTBTNone, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTSquareBracket, JKQTMathTextBraceNode::MTBTSquareBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCurlyBracket, JKQTMathTextBraceNode::MTBTCurlyBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTSingleLine, JKQTMathTextBraceNode::MTBTSingleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTDoubleLine, JKQTMathTextBraceNode::MTBTDoubleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
if (envname=="pmatrix") nl->addNode(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="cases") nl->addNode(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTNone, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Bmatrix") nl->addNode(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTCurlyBracket, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, MTBTSingleLine, MTBTSingleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
else if (envname=="Vmatrix") nl->addNode(new JKQTMathTextBraceNode(this, MTBTDoubleLine, MTBTDoubleLine, new JKQTMathTextMatrixNode(this, items)));
|
||||
else nl->addNode(new JKQTMathTextMatrixNode(this, items));
|
||||
//std::cout<<" creating matrix-node ... done!\n";
|
||||
} else {
|
||||
@ -1077,7 +1116,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
while (currentToken!=MTTclosebrace) getToken();
|
||||
getNew=true;
|
||||
}
|
||||
} else if (name=="end") {
|
||||
} else if (currentInstructionName=="end") {
|
||||
if (getToken()==MTTtext) {
|
||||
QString envname=currentTokenName;
|
||||
while (currentToken!=MTTclosebrace) getToken(); // find closing brace '}' after '\\begin{name'
|
||||
@ -1091,50 +1130,50 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
while (currentToken!=MTTclosebrace) getToken();
|
||||
getNew=true;
|
||||
}
|
||||
} else if (name=="vec") {
|
||||
} else if (currentInstructionName=="vec") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDvec, parseLatexString(true)));
|
||||
} else if (name=="overline"||name=="oline"||name=="ol") {
|
||||
} else if (currentInstructionName=="overline"||currentInstructionName=="oline"||currentInstructionName=="ol") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDoverline, parseLatexString(true)));
|
||||
} else if (name=="underline"||name=="uline"||name=="ul") {
|
||||
} else if (currentInstructionName=="underline"||currentInstructionName=="uline"||currentInstructionName=="ul") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDunderline, parseLatexString(true)));
|
||||
} else if (name=="uuline"||name=="uul") {
|
||||
} else if (currentInstructionName=="uuline"||currentInstructionName=="uul") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdoubleunderline, parseLatexString(true)));
|
||||
} else if (name=="ooline"||name=="ool") {
|
||||
} else if (currentInstructionName=="ooline"||currentInstructionName=="ool") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdoubleoverline, parseLatexString(true)));
|
||||
} else if (name=="arrow"||name=="overrightarrow"||name=="overarrow") {
|
||||
} else if (currentInstructionName=="arrow"||currentInstructionName=="overrightarrow"||currentInstructionName=="overarrow") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDarrow, parseLatexString(true)));
|
||||
} else if (name=="hat" || name=="^") {
|
||||
} else if (currentInstructionName=="hat" || currentInstructionName=="^") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDhat, parseLatexString(true)));
|
||||
} else if (name=="widehat") {
|
||||
} else if (currentInstructionName=="widehat") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidehat, parseLatexString(true)));
|
||||
} else if (name=="check" || name=="v") {
|
||||
} else if (currentInstructionName=="check" || currentInstructionName=="v") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDcheck, parseLatexString(true)));
|
||||
} else if (name=="widecheck") {
|
||||
} else if (currentInstructionName=="widecheck") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidecheck, parseLatexString(true)));
|
||||
} else if (name=="bar") {
|
||||
} else if (currentInstructionName=="bar") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbar, parseLatexString(true)));
|
||||
} else if (name=="dot" || name==".") {
|
||||
} else if (currentInstructionName=="dot" || currentInstructionName==".") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdot, parseLatexString(true)));
|
||||
} else if (name=="ocirc") {
|
||||
} else if (currentInstructionName=="ocirc") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDocirc, parseLatexString(true)));
|
||||
} else if (name=="tilde" || name=="~") {
|
||||
} else if (currentInstructionName=="tilde" || currentInstructionName=="~") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDtilde, parseLatexString(true)));
|
||||
} else if (name=="breve" || name=="u") {
|
||||
} else if (currentInstructionName=="breve" || currentInstructionName=="u") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbreve, parseLatexString(true)));
|
||||
} else if (name=="widetilde") {
|
||||
} else if (currentInstructionName=="widetilde") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidetilde, parseLatexString(true)));
|
||||
} else if (name=="ddot") {
|
||||
} else if (currentInstructionName=="ddot") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDddot, parseLatexString(true)));
|
||||
} else if (name=="cancel") {
|
||||
} else if (currentInstructionName=="cancel") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDcancel, parseLatexString(true)));
|
||||
} else if (name=="xcancel") {
|
||||
} else if (currentInstructionName=="xcancel") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDxcancel, parseLatexString(true)));
|
||||
} else if (name=="bcancel") {
|
||||
} else if (currentInstructionName=="bcancel") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbcancel, parseLatexString(true)));
|
||||
} else if (name=="strike" || name=="st" || name=="sout") {
|
||||
} else if (currentInstructionName=="strike" || currentInstructionName=="st" || currentInstructionName=="sout") {
|
||||
nl->addNode(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDstrike, parseLatexString(true)));
|
||||
} else {
|
||||
if (name=="textcolor" || name=="mathcolor" || name=="color" || name=="colorbox") {
|
||||
if (currentInstructionName=="textcolor" || currentInstructionName=="mathcolor" || currentInstructionName=="color" || currentInstructionName=="colorbox") {
|
||||
bool foundError=true;
|
||||
QString col="";
|
||||
if (getToken()==MTTtext) {
|
||||
@ -1145,127 +1184,106 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundError) error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(name));
|
||||
else nl->addNode(new JKQTMathTextInstruction1Node(this, name, parseLatexString(true), QStringList(col)));
|
||||
if (foundError) error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
else nl->addNode(new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true), QStringList(col)));
|
||||
|
||||
|
||||
} else {
|
||||
nl->addNode(new JKQTMathTextInstruction1Node(this, name, parseLatexString(true)));
|
||||
nl->addNode(new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true)));
|
||||
}
|
||||
}
|
||||
} else if (currentToken==MTTopenbracket && currentInstructionName!="left") {
|
||||
//std::cout<<"found '[' after '"<<name.toStdString()<<"'\n";
|
||||
if (currentInstructionName=="sqrt") {
|
||||
JKQTMathTextNode* n1=parseLatexString(true, MTBTAny, "", true);
|
||||
JKQTMathTextListNode* n1lst=dynamic_cast<JKQTMathTextListNode*>(n1);
|
||||
JKQTMathTextTextNode* n1txt=dynamic_cast<JKQTMathTextTextNode*>(n1);
|
||||
if (n1lst && n1lst->count()==1) {
|
||||
n1txt=dynamic_cast<JKQTMathTextTextNode*>(n1lst->child(0));
|
||||
}
|
||||
int degree=2;
|
||||
bool ok=false;
|
||||
if (n1txt) degree=n1txt->getText().toInt(&ok);
|
||||
if (!ok) {
|
||||
degree=2;
|
||||
error_list.append(tr("error @ ch. %1: an integer in [] after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
}
|
||||
|
||||
JKQTMathTextNode* n2=nullptr;
|
||||
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
|
||||
else error_list.append(tr("error @ ch. %1: expected one argument in '{' braces after '%2' command with an optional argument in []").arg(currentTokenID).arg(currentInstructionName));
|
||||
|
||||
if (n1 && n2) nl->addNode(new JKQTMathTextSqrtNode(this, n2, degree));
|
||||
else error_list.append(tr("error @ ch. %1: expected two arguments in '{' braces after '%2' command").arg(currentTokenID).arg(currentInstructionName));
|
||||
} else {
|
||||
nl->addNode(new JKQTMathTextTextNode(this, "[", false));
|
||||
}
|
||||
} else {
|
||||
//std::cout<<"did not find '{' after '"<<name.toStdString()<<"'\n";
|
||||
if (name=="right") {
|
||||
if (currentInstructionName=="right") {
|
||||
if (currentToken==MTTtext) {
|
||||
if (currentTokenName.size()>0) {
|
||||
if (QString(currentTokenName[0])==quitOnClosingBrace || quitOnClosingBrace=="any" || QString(currentTokenName[0])==".") {
|
||||
bool tokenWasNoBrace=false;
|
||||
if (TokenNameMatchesJKQTMathTextBraceType(currentTokenName[0], quitOnClosingBrace, true, &tokenWasNoBrace)) {
|
||||
//std::cout<<"found \\right '"<<currentTokenName.toStdString()<<"'\n";
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
showLeftBrace=(quitOnClosingBrace==MTBTAny || quitOnClosingBrace!=MTBTNone);
|
||||
showRightBrace=!tokenWasNoBrace;
|
||||
//if (!showRightBrace) std::cout<<"don't show right brace '"<<quitOnClosingBrace.toStdString()<<"' !!!\n";
|
||||
if (quitOnClosingBrace!="any") currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
if (quitOnClosingBrace!=MTBTAny) currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else {
|
||||
getNew=false;
|
||||
}
|
||||
}
|
||||
} else if (currentToken==MTTinstruction) {
|
||||
if (quitOnClosingBrace=="~" && (currentTokenName=="rceil" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="}" && (currentTokenName=="}" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="_" && (currentTokenName=="rfloor" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="#" && (currentTokenName=="|" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace==">" && (currentTokenName=="rangle" || QString(currentTokenName[0])==".")) {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
} else if (quitOnClosingBrace=="any") {
|
||||
showLeftBrace=true;
|
||||
showRightBrace=(QString(currentTokenName[0])!=".");
|
||||
//currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
if (InstructionNameMatchesJKQTMathTextBraceType(currentTokenName, quitOnClosingBrace, true)) {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
}
|
||||
} else if (currentToken==MTTclosebracket) {
|
||||
if (quitOnClosingBrace==MTBTSquareBracket || quitOnClosingBrace==MTBTAny) {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
getNew=false;
|
||||
}
|
||||
} else if (name=="left") {
|
||||
} else if (currentInstructionName=="left") {
|
||||
if (currentToken==MTTtext) {
|
||||
if (currentTokenName.size()>0) {
|
||||
if (currentTokenName[0]=='(') {
|
||||
const JKQTMathTextBraceType bracetype=TokenName2JKQTMathTextBraceType(currentTokenName[0]);
|
||||
if (bracetype==MTBTNone) {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
JKQTMathTextNode* cn=parseLatexString(currentTokenName.size()<=0, MTBTAny);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, MTBTNone, bracetype, cn));
|
||||
} else if (isPrintableJKQTMathTextBraceType(bracetype)) {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1); // we already used the first character from the text token!
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTParenthesis, JKQTMathTextBraceNode::MTBTParenthesis, parseLatexString(currentTokenName.size()<=0, ")"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='[') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTSquareBracket, JKQTMathTextBraceNode::MTBTSquareBracket, parseLatexString(currentTokenName.size()<=0, "]"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='{') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCurlyBracket, JKQTMathTextBraceNode::MTBTCurlyBracket, parseLatexString(currentTokenName.size()<=0, "}"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='<') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTAngleBracket, JKQTMathTextBraceNode::MTBTAngleBracket, parseLatexString(currentTokenName.size()<=0, ">"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='|') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTSingleLine, JKQTMathTextBraceNode::MTBTSingleLine, parseLatexString(currentTokenName.size()<=0, "|"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='~') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCeilBracket, JKQTMathTextBraceNode::MTBTCeilBracket, parseLatexString(currentTokenName.size()<=0, "~"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='_') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTFloorBracket, JKQTMathTextBraceNode::MTBTFloorBracket, parseLatexString(currentTokenName.size()<=0, "_"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='#') {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTDoubleLine, JKQTMathTextBraceNode::MTBTDoubleLine, parseLatexString(currentTokenName.size()<=0, "#"), showLeftBrace, showRightBrace));
|
||||
} else if (currentTokenName[0]=='.') {
|
||||
showLeftBrace=false;
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
JKQTMathTextNode* cn=parseLatexString(currentTokenName.size()<=0, "any");
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTNone, JKQTMathTextBraceNode::TokenNameString2TokenType(currentTokenName), cn, showLeftBrace, showRightBrace));
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, bracetype, bracetype, parseLatexString(currentTokenName.size()<=0, bracetype)));
|
||||
} else {
|
||||
getNew=false;
|
||||
}
|
||||
}
|
||||
} else if (currentToken==MTTinstruction && currentTokenName=="langle") {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTAngleBracket, JKQTMathTextBraceNode::MTBTAngleBracket, parseLatexString(true, ">"), showLeftBrace, showRightBrace));
|
||||
} else if (currentToken==MTTinstruction && currentTokenName=="{") {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCurlyBracket, JKQTMathTextBraceNode::MTBTCurlyBracket, parseLatexString(currentTokenName.size()<=0, "}"), showLeftBrace, showRightBrace));
|
||||
} else if (currentToken==MTTinstruction && currentTokenName=="lfloor") {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTFloorBracket, JKQTMathTextBraceNode::MTBTFloorBracket, parseLatexString(true, "_"), showLeftBrace, showRightBrace));
|
||||
} else if (currentToken==MTTinstruction && currentTokenName=="lceil") {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTCeilBracket, JKQTMathTextBraceNode::MTBTCeilBracket, parseLatexString(true, "~"), showLeftBrace, showRightBrace));
|
||||
} else if (currentToken==MTTinstruction && currentTokenName=="|") {
|
||||
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, JKQTMathTextBraceNode::MTBTDoubleLine, JKQTMathTextBraceNode::MTBTDoubleLine, parseLatexString(currentTokenName.size()<=0, "#"), showLeftBrace, showRightBrace));
|
||||
} else if (currentToken==MTTinstruction && currentTokenName==quitOnClosingBrace) {
|
||||
break;
|
||||
} else if (currentToken==MTTinstruction) {
|
||||
const JKQTMathTextBraceType bracetypeopening=InstructionName2OpeningJKQTMathTextBraceType(currentTokenName);
|
||||
if (bracetypeopening!=MTBTUnknown) {
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, bracetypeopening, bracetypeopening, parseLatexString(true, bracetypeopening)));
|
||||
} else if (currentToken==MTTinstruction && TokenNameMatchesJKQTMathTextBraceType(currentTokenName, quitOnClosingBrace, true)) {
|
||||
break;
|
||||
}
|
||||
} else if (currentToken==MTTopenbracket) {
|
||||
nl->addNode(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, parseLatexString(true, MTBTSquareBracket)));
|
||||
} else {
|
||||
error_list.append(tr("error @ ch. %1: unexpected token after \\left").arg(currentTokenID));
|
||||
}
|
||||
|
||||
} else {
|
||||
//bool addWhite=(currentToken==MTTwhitespace);
|
||||
//getNew=addWhite;
|
||||
getNew=false;
|
||||
bool done=false;
|
||||
if (name.size()==2) {
|
||||
QChar n0=name[0];
|
||||
QChar n1=name[1];
|
||||
if (currentInstructionName.size()==2) {
|
||||
QChar n0=currentInstructionName[0];
|
||||
QChar n1=currentInstructionName[1];
|
||||
if (n0=='v' && n1.isLetter()) {
|
||||
done=true;
|
||||
//std::cout<<"found \\v... command\n";
|
||||
@ -1275,16 +1293,16 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
//std::cout<<"found \\v... command\n";
|
||||
nl->addNode(new JKQTMathTextInstruction1Node(this, "mathcal", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment)));
|
||||
}
|
||||
} else if (name.size()==3) {
|
||||
QString n0=name.left(2);
|
||||
QChar n1=name[name.size()-1];
|
||||
} else if (currentInstructionName.size()==3) {
|
||||
QString n0=currentInstructionName.left(2);
|
||||
QChar n1=currentInstructionName[currentInstructionName.size()-1];
|
||||
if (n0=="bb" && n1.isLetter()) {
|
||||
done=true;
|
||||
//std::cout<<"found \\v... command\n";
|
||||
nl->addNode(new JKQTMathTextInstruction1Node(this, "mathbb", new JKQTMathTextTextNode(this, QString(n1), false, parsingMathEnvironment)));
|
||||
}
|
||||
}
|
||||
if (!done) nl->addNode(new JKQTMathTextSymbolNode(this, name, false));//, addWhite));
|
||||
if (!done) nl->addNode(new JKQTMathTextSymbolNode(this, currentInstructionName, false));//, addWhite));
|
||||
|
||||
}
|
||||
}
|
||||
@ -1354,6 +1372,11 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
nl->addNode(parseLatexString(true));
|
||||
} else if (currentToken==MTTclosebrace) {
|
||||
break;
|
||||
} else if (currentToken==MTTopenbracket) {
|
||||
nl->addNode(new JKQTMathTextTextNode(this, "[", false));
|
||||
} else if (currentToken==MTTclosebracket) {
|
||||
if (quitOnClosingBracket) break;
|
||||
else nl->addNode(new JKQTMathTextTextNode(this, "]", false));
|
||||
} else if (currentToken==MTTampersand) {
|
||||
break;
|
||||
} else if (currentToken==MTTdollar) {
|
||||
@ -1368,9 +1391,10 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, const QString& quitOn
|
||||
if (getNew) getToken();
|
||||
}
|
||||
//std::cout<<" leaving parseLatexString()\n";
|
||||
return nl;
|
||||
return JKQTMathTextListNode::simplyfyListNode(nl);
|
||||
}
|
||||
|
||||
|
||||
JKQTMathTextNode *JKQTMathText::getParsedNode() const {
|
||||
return this->parsedNode;
|
||||
}
|
||||
|
@ -589,22 +589,30 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
|
||||
/** \brief the token types that may arrise in the string */
|
||||
enum tokenType {
|
||||
MTTnone,
|
||||
MTTtext,
|
||||
MTTinstruction,
|
||||
MTTunderscore,
|
||||
MTThat,
|
||||
MTTdollar,
|
||||
MTTopenbrace,
|
||||
MTTclosebrace,
|
||||
MTTwhitespace,
|
||||
MTTampersand
|
||||
MTTnone, /*!< \brief no token */
|
||||
MTTtext, /*!< \brief a piece of general text */
|
||||
MTTinstruction, /*!< \brief an instruction, started by "\", e.g. "\textbf", ... */
|
||||
MTTunderscore, /*!< \brief the character "_" */
|
||||
MTThat, /*!< \brief the character "^" */
|
||||
MTTdollar, /*!< \brief the character "$" */
|
||||
MTTopenbrace, /*!< \brief the character "{" */
|
||||
MTTclosebrace, /*!< \brief the character "}" */
|
||||
MTTopenbracket, /*!< \brief the character "[" */
|
||||
MTTclosebracket, /*!< \brief the character "]" */
|
||||
MTTwhitespace, /*!< \brief some whitespace */
|
||||
MTTampersand /*!< \brief the character "&" */
|
||||
};
|
||||
|
||||
/** \brief tokenizer for the LaTeX parser */
|
||||
tokenType getToken();
|
||||
/** \brief parse a LaTeX string */
|
||||
JKQTMathTextNode* parseLatexString(bool get, const QString& quitOnClosingBrace=QString(""), const QString& quitOnEnvironmentEnd=QString(""));
|
||||
/** \brief parse a LaTeX string
|
||||
*
|
||||
* \param get if \c true this calls getToken()
|
||||
* \param quitOnClosingBrace if unequal MTBTAny, this returns if the given closing brace is found
|
||||
* \param quitOnEnvironmentEnd wuit if \end{quitOnEnvironmentEnd} is found
|
||||
* \param quitOnClosingBracket if \c true, quits on encountering a MTTclosebracket token
|
||||
*/
|
||||
JKQTMathTextNode* parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace=JKQTMathTextBraceType::MTBTAny, const QString& quitOnEnvironmentEnd=QString(""), bool quitOnClosingBracket=false);
|
||||
/** \brief parse a LaTeX math environment */
|
||||
JKQTMathTextNode* parseMath(bool get);
|
||||
|
||||
|
@ -325,6 +325,87 @@ QString JKQTMathTextFontEncoding2String(JKQTMathTextFontEncoding e)
|
||||
return "???";
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString JKQTMathTextBraceType2String(JKQTMathTextBraceType type) {
|
||||
switch(type) {
|
||||
case MTBTAngleBracket:
|
||||
return "angle_bracket";
|
||||
case MTBTSquareBracket:
|
||||
return "square_bracket";
|
||||
case MTBTCeilBracket:
|
||||
return "ceil_bracket";
|
||||
case MTBTCurlyBracket:
|
||||
return "curly_bracket";
|
||||
case MTBTDoubleLine:
|
||||
return "double_line";
|
||||
case MTBTFloorBracket:
|
||||
return "floor_bracket";
|
||||
case MTBTParenthesis:
|
||||
return "parenhesis";
|
||||
case MTBTSingleLine:
|
||||
return "single_line";
|
||||
case MTBTAny:
|
||||
return "any";
|
||||
case MTBTNone:
|
||||
return "none";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString &tokenName)
|
||||
{
|
||||
if (tokenName=="(" || tokenName==")") return MTBTParenthesis;
|
||||
if (tokenName=="[" || tokenName=="]") return MTBTSquareBracket;
|
||||
if (tokenName=="{" || tokenName=="}") return MTBTCurlyBracket;
|
||||
if (tokenName=="|") return MTBTSingleLine;
|
||||
if (tokenName=="||" || tokenName=="#") return MTBTDoubleLine;
|
||||
if (tokenName=="<" || tokenName==">" || tokenName=="langle" || tokenName=="rangle") return MTBTAngleBracket;
|
||||
if (tokenName=="_" || tokenName=="lfloor" || tokenName=="rfloor") return MTBTFloorBracket;
|
||||
if (tokenName=="~" || tokenName=="lceil" || tokenName=="rceil") return MTBTCeilBracket;
|
||||
if (tokenName=="any") return MTBTAny;
|
||||
if (tokenName=="." || tokenName=="" || tokenName=="none") return MTBTNone;
|
||||
return MTBTUnknown;
|
||||
}
|
||||
|
||||
JKQTMathTextBraceType InstructionName2OpeningJKQTMathTextBraceType(const QString &tokenName)
|
||||
{
|
||||
if (tokenName=="{") return MTBTCurlyBracket;
|
||||
if (tokenName=="|") return MTBTDoubleLine;
|
||||
if (tokenName=="langle") return MTBTAngleBracket;
|
||||
if (tokenName=="lfloor") return MTBTFloorBracket;
|
||||
if (tokenName=="lceil") return MTBTCeilBracket;
|
||||
return MTBTUnknown;
|
||||
}
|
||||
|
||||
JKQTMathTextBraceType InstructionName2JKQTMathTextBraceType(const QString &tokenName)
|
||||
{
|
||||
if (tokenName=="{" || tokenName=="}") return MTBTCurlyBracket;
|
||||
if (tokenName=="|") return MTBTDoubleLine;
|
||||
if (tokenName=="langle" || tokenName=="rangle") return MTBTAngleBracket;
|
||||
if (tokenName=="lfloor" || tokenName=="rfloor") return MTBTFloorBracket;
|
||||
if (tokenName=="lceil" || tokenName=="rceil") return MTBTCeilBracket;
|
||||
return MTBTUnknown;
|
||||
}
|
||||
|
||||
bool TokenNameMatchesJKQTMathTextBraceType(const QString &token, JKQTMathTextBraceType type, bool acceptMTBTNone, bool* tokenEqualsNone)
|
||||
{
|
||||
const JKQTMathTextBraceType bt=TokenName2JKQTMathTextBraceType(token);
|
||||
if (tokenEqualsNone) *tokenEqualsNone=(bt==MTBTNone);
|
||||
if (type==MTBTAny) return true;
|
||||
if (acceptMTBTNone && bt==MTBTNone) return true;
|
||||
return (bt==type);
|
||||
}
|
||||
|
||||
bool InstructionNameMatchesJKQTMathTextBraceType(const QString &token, JKQTMathTextBraceType type, bool acceptMTBTNone, bool* tokenEqualsNone)
|
||||
{
|
||||
const JKQTMathTextBraceType bt=InstructionName2JKQTMathTextBraceType(token);
|
||||
if (tokenEqualsNone) *tokenEqualsNone=(bt==MTBTNone);
|
||||
if (type==MTBTAny) return true;
|
||||
if (acceptMTBTNone && bt==MTBTNone) return true;
|
||||
return (bt==type);
|
||||
}
|
||||
|
||||
JKQTMathTextEnvironment::JKQTMathTextEnvironment() {
|
||||
color=QColor("black");
|
||||
font=MTEroman;
|
||||
@ -577,3 +658,8 @@ QFont JKQTMathTextGetNonItalic(const QFont &font)
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
bool isPrintableJKQTMathTextBraceType(JKQTMathTextBraceType type)
|
||||
{
|
||||
return (type!=MTBTAny) && (type!=MTBTUnknown);
|
||||
}
|
||||
|
@ -137,6 +137,65 @@ enum JKQTMathTextFontEncoding {
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextFontEncoding2String(JKQTMathTextFontEncoding e);
|
||||
|
||||
/** \brief types of available braces
|
||||
* \ingroup jkqtmathtext
|
||||
*/
|
||||
enum JKQTMathTextBraceType {
|
||||
MTBTParenthesis=0, /*!< \brief parantheses () \image html jkqtmathtext/jkqtmathtext_brace_round.png */
|
||||
MTBTSquareBracket, /*!< \brief brackets [] \image html jkqtmathtext/jkqtmathtext_brace_rect.png */
|
||||
MTBTCurlyBracket, /*!< \brief curly braces {} \image html jkqtmathtext/jkqtmathtext_brace_curly.png */
|
||||
MTBTAngleBracket, /*!< \brief angle backets <> \image html jkqtmathtext/jkqtmathtext_brace_tri.png */
|
||||
MTBTCeilBracket, /*!< \brief ceil brackets \image html jkqtmathtext/jkqtmathtext_brace_ceil.png */
|
||||
MTBTFloorBracket, /*!< \brief floor brackets \image html jkqtmathtext/jkqtmathtext_brace_floor.png */
|
||||
MTBTDoubleLine, /*!< \brief double-line brackets (norm ||...||) \image html jkqtmathtext/jkqtmathtext_brace_dblline.png */
|
||||
MTBTSingleLine, /*!< \brief single-line brackets (abs |...|) \image html jkqtmathtext/jkqtmathtext_brace_oneline.png */
|
||||
MTBTNone, /*!< \brief no bracket */
|
||||
MTBTAny, /*!< \brief any bracket, used by JKQTMathText::parseLatexString() */
|
||||
MTBTUnknown /*!< \brief an unknown tokenName presented to TokenName2JKQTMathTextBraceType() */
|
||||
};
|
||||
/** \brief convert a JKQTMathTextBraceType into a string
|
||||
* \ingroup jkqtmathtext
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextBraceType2String(JKQTMathTextBraceType type);
|
||||
/** \brief convert a string \a tokenName describing a LaTeX Token or Instruction into an opening or closing JKQTMathTextBraceType
|
||||
* \ingroup jkqtmathtext
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString& tokenName);
|
||||
/** \brief convert a string \a tokenName describing a LaTeX Instruction into an opening JKQTMathTextBraceType
|
||||
* \ingroup jkqtmathtext
|
||||
*
|
||||
* This returns a JKQTMathTextBraceType for which isPrintableJKQTMathTextBraceType() is \c true, or MTBTUnknown,
|
||||
* never MTBTNone or MTBTAny.
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceType InstructionName2OpeningJKQTMathTextBraceType(const QString& tokenName);
|
||||
/** \brief convert a string \a tokenName describing a LaTeX Instruction into an opening or closing JKQTMathTextBraceType
|
||||
* \ingroup jkqtmathtext
|
||||
*
|
||||
* This returns a JKQTMathTextBraceType for which isPrintableJKQTMathTextBraceType() is \c true, or MTBTUnknown,
|
||||
* never MTBTNone or MTBTAny.
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceType InstructionName2JKQTMathTextBraceType(const QString& tokenName);
|
||||
/** \brief return \c true if \a type represents a printable type of brace (including MTBTNone), basically \c true
|
||||
* for any JKQTMathTextBraceType that can be used as parameter to JKQTMathTextBraceNode
|
||||
* \ingroup jkqtmathtext
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT bool isPrintableJKQTMathTextBraceType(JKQTMathTextBraceType type);
|
||||
/** \brief returns true, if the given token/instruction-Name \a token ("{", "(", ..., "lceil", ".", ...) matches the given \a type (returns true, when \a type == MTBTAny )
|
||||
* \ingroup jkqtmathtext
|
||||
*
|
||||
* This accepts TokenName2JKQTMathTextBraceType(toke)==MTBTNone for any \a type, iff \a acceptMTBTNone \a ==true.
|
||||
*
|
||||
* Optionally returns in \a tokenEqualsNone whether \a token was encoding for MTBTNone .
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT bool TokenNameMatchesJKQTMathTextBraceType(const QString &token, JKQTMathTextBraceType type, bool acceptMTBTNone, bool *tokenEqualsNone=nullptr);
|
||||
/** \brief returns true, if the given instruction-Name \a token ("|", "{", ..., "lceil", ".", ...) matches the given \a type (returns true, when \a type == MTBTAny )
|
||||
* \ingroup jkqtmathtext
|
||||
*
|
||||
* This accepts TokenName2JKQTMathTextBraceType(toke)==MTBTNone for any \a type, iff \a acceptMTBTNone \a ==true.
|
||||
*
|
||||
* Optionally returns in \a tokenEqualsNone whether \a token was encoding for MTBTNone .
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT bool InstructionNameMatchesJKQTMathTextBraceType(const QString &token, JKQTMathTextBraceType type, bool acceptMTBTNone, bool *tokenEqualsNone=nullptr);
|
||||
|
||||
/** \brief the available logical fonts (default is MTEroman)
|
||||
* \ingroup jkqtmathtext
|
||||
|
@ -36,48 +36,11 @@
|
||||
|
||||
|
||||
|
||||
QString JKQTMathTextBraceNode::BraceType2String(BraceType type) {
|
||||
switch(type) {
|
||||
case MTBTAngleBracket:
|
||||
return "angle_bracket";
|
||||
case MTBTSquareBracket:
|
||||
return "square_bracket";
|
||||
case MTBTCeilBracket:
|
||||
return "ceil_bracket";
|
||||
case MTBTCurlyBracket:
|
||||
return "curly_bracket";
|
||||
case MTBTDoubleLine:
|
||||
return "double_line";
|
||||
case MTBTFloorBracket:
|
||||
return "floor_bracket";
|
||||
case MTBTParenthesis:
|
||||
return "parenhesis";
|
||||
case MTBTSingleLine:
|
||||
return "single_line";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
JKQTMathTextBraceNode::BraceType JKQTMathTextBraceNode::TokenNameString2TokenType(const QString &type)
|
||||
{
|
||||
if (type=="(" || type==")") return MTBTParenthesis;
|
||||
if (type=="[" || type=="]") return MTBTSquareBracket;
|
||||
if (type=="{" || type=="}") return MTBTCurlyBracket;
|
||||
if (type=="|") return MTBTSingleLine;
|
||||
if (type=="||" || type=="#") return MTBTDoubleLine;
|
||||
if (type=="<" || type==">" || type=="langle" || type=="rangle") return MTBTAngleBracket;
|
||||
if (type=="_" || type=="lfloor" || type=="rfloor") return MTBTFloorBracket;
|
||||
if (type=="~" || type=="lceil" || type=="rceil") return MTBTCeilBracket;
|
||||
return MTBTNone;
|
||||
}
|
||||
|
||||
JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, JKQTMathTextBraceNode::BraceType openbrace, JKQTMathTextBraceNode::BraceType closebrace, JKQTMathTextNode* child, bool showOpeningBrace, bool showClosingBrace):
|
||||
JKQTMathTextBraceNode::JKQTMathTextBraceNode(JKQTMathText* _parent, JKQTMathTextBraceType openbrace, JKQTMathTextBraceType closebrace, JKQTMathTextNode* child):
|
||||
JKQTMathTextSingleChildNode(child, _parent)
|
||||
{
|
||||
this->openbrace=openbrace;
|
||||
this->closebrace=closebrace;
|
||||
this->showClosingBrace=showClosingBrace;
|
||||
this->showOpeningBrace=showOpeningBrace;
|
||||
}
|
||||
|
||||
|
||||
@ -116,8 +79,8 @@ void JKQTMathTextBraceNode::getSizeInternalAndBrace(QPainter &painter, JKQTMathT
|
||||
|
||||
bracewidth=bracewidth/parentMathText->getBraceShrinkFactor();
|
||||
|
||||
if (showOpeningBrace) width+=bracewidth;
|
||||
if (showClosingBrace) width+=bracewidth;
|
||||
if (openbrace!=MTBTNone && openbrace!=MTBTAny) width+=bracewidth;
|
||||
if (closebrace!=MTBTNone && closebrace!=MTBTAny) width+=bracewidth;
|
||||
}
|
||||
|
||||
double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
@ -143,7 +106,8 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
painter.setPen(p);
|
||||
const double paren_fraction=0.85;
|
||||
const double brace_fraction=0.65;
|
||||
if (showOpeningBrace) {
|
||||
{
|
||||
bool showOpeningBrace=true;
|
||||
const double xbrace1=xnew+lw;
|
||||
const double xbrace2=qMin(xnew+paren_fraction*bracewidth, xnew+bracewidth-lw/2.0);
|
||||
const double xbrace2s=qMin(xnew+brace_fraction*bracewidth, xnew+bracewidth-lw/2.0);
|
||||
@ -154,7 +118,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.moveTo(xbrace2, y1);
|
||||
path.cubicTo(xbrace1, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace1, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace2, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTSquareBracket) {
|
||||
} else if (openbrace==MTBTSquareBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -163,14 +127,14 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace1, y2);
|
||||
path.lineTo(xbrace2s, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTCurlyBracket) {
|
||||
} else if (openbrace==MTBTCurlyBracket) {
|
||||
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0);
|
||||
painter.rotate(90);
|
||||
painter.drawPath(path);
|
||||
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTFloorBracket) {
|
||||
} else if (openbrace==MTBTFloorBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -178,7 +142,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace1, y1);
|
||||
path.lineTo(xbrace1, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTCeilBracket) {
|
||||
} else if (openbrace==MTBTCeilBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -186,19 +150,19 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace1, y2);
|
||||
path.lineTo(xbrace2s, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTSingleLine) {
|
||||
} else if (openbrace==MTBTSingleLine) {
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const QLineF l(xbrace1, y1, xbrace1, y2);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTDoubleLine) {
|
||||
} else if (openbrace==MTBTDoubleLine) {
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const QLineF l(xbrace1, y1, xbrace1, y2);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
const QLineF l2(xbrace1+1.5*lw, y1, xbrace1+1.5*lw, y2);
|
||||
if (l2.length()>0) painter.drawLine(l2);
|
||||
} else if (openbrace==JKQTMathTextBraceNode::MTBTAngleBracket) {
|
||||
} else if (openbrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -206,27 +170,32 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace1, (y2+y1)/2.0);
|
||||
path.lineTo(xbrace2, y2);
|
||||
painter.drawPath(path);
|
||||
} else {
|
||||
showOpeningBrace=false;
|
||||
}
|
||||
if (showOpeningBrace) {
|
||||
xnew=xnew+bracewidth;
|
||||
}
|
||||
xnew=xnew+bracewidth;
|
||||
}
|
||||
|
||||
painter.setPen(pold);
|
||||
|
||||
xnew= child->draw(painter, xnew, y, currentEv);
|
||||
|
||||
if (showClosingBrace) {
|
||||
{
|
||||
bool showClosingBrace=true;
|
||||
const double xbrace1=qMax(xnew+bracewidth-paren_fraction*bracewidth, xnew+lw/2.0);
|
||||
const double xbrace1s=qMax(xnew+bracewidth-brace_fraction*bracewidth, xnew+lw/2.0);
|
||||
const double xbrace2=xnew+bracewidth-lw;
|
||||
painter.setPen(p);
|
||||
if (closebrace==JKQTMathTextBraceNode::MTBTParenthesis) {
|
||||
if (closebrace==MTBTParenthesis) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
path.moveTo(xbrace1, y1);
|
||||
path.cubicTo(xbrace2, (y1+y2)/2.0+fabs(y1-y2)/6.0, xbrace2, (y1+y2)/2.0-fabs(y1-y2)/6.0 , xbrace1, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTSquareBracket) {
|
||||
} else if (closebrace==MTBTSquareBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -235,14 +204,14 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace2, y2);
|
||||
path.lineTo(xbrace1s, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTCurlyBracket) {
|
||||
} else if (closebrace==MTBTCurlyBracket) {
|
||||
QPainterPath path=JKQTMathTextMakeHBracePath(0,0,nodeOverallHeight, bracewidth*brace_fraction);
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.translate((xbrace1+xbrace2)/2.0, y-nodeBaselineHeight+nodeOverallHeight/2.0);
|
||||
painter.rotate(270);
|
||||
painter.drawPath(path);
|
||||
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTFloorBracket) {
|
||||
} else if (closebrace==MTBTFloorBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -250,7 +219,7 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace2, y1);
|
||||
path.lineTo(xbrace2, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTCeilBracket) {
|
||||
} else if (closebrace==MTBTCeilBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -258,19 +227,19 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace2, y2);
|
||||
path.lineTo(xbrace1s, y2);
|
||||
painter.drawPath(path);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTSingleLine) {
|
||||
} else if (closebrace==MTBTSingleLine) {
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const QLineF l(xbrace2, y1, xbrace2, y2);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTDoubleLine) {
|
||||
} else if (closebrace==MTBTDoubleLine) {
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
const QLineF l(xbrace2, y1, xbrace2, y2);
|
||||
if (l.length()>0) painter.drawLine(l);
|
||||
const QLineF l2(xbrace2-1.5*lw, y1, xbrace2-1.5*lw, y2);
|
||||
if (l2.length()>0) painter.drawLine(l2);
|
||||
} else if (closebrace==JKQTMathTextBraceNode::MTBTAngleBracket) {
|
||||
} else if (closebrace==MTBTAngleBracket) {
|
||||
QPainterPath path;
|
||||
const double y1=y+(nodeOverallHeight-nodeBaselineHeight);
|
||||
const double y2=y-nodeBaselineHeight;
|
||||
@ -278,9 +247,13 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
path.lineTo(xbrace2, (y2+y1)/2.0);
|
||||
path.lineTo(xbrace1, y2);
|
||||
painter.drawPath(path);
|
||||
} else {
|
||||
showClosingBrace=false;
|
||||
}
|
||||
painter.setPen(pold);
|
||||
xnew=xnew+bracewidth;
|
||||
if (showClosingBrace) {
|
||||
xnew=xnew+bracewidth;
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug()<<" ==> "<<bc<<fm.boundingRect(bc).width();
|
||||
@ -290,22 +263,22 @@ double JKQTMathTextBraceNode::draw(QPainter& painter, double x, double y, JKQTMa
|
||||
bool JKQTMathTextBraceNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) {
|
||||
QString ob;
|
||||
QString cb;
|
||||
if (openbrace==JKQTMathTextBraceNode::MTBTAngleBracket) ob="⟨";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTFloorBracket) ob="⌊";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTCeilBracket) ob="⌈";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTParenthesis) ob="(";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTSquareBracket) ob="[";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTCurlyBracket) ob="{";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTSingleLine) ob="|";
|
||||
else if (openbrace==JKQTMathTextBraceNode::MTBTDoubleLine) ob="||";
|
||||
if (closebrace==JKQTMathTextBraceNode::MTBTAngleBracket) cb="⟩";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTFloorBracket) cb="⌋";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTCeilBracket) cb="⌉";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTParenthesis) cb=")";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTSquareBracket) cb="]";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTCurlyBracket) cb="}";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTSingleLine) cb="|";
|
||||
else if (closebrace==JKQTMathTextBraceNode::MTBTDoubleLine) cb="||";
|
||||
if (openbrace==MTBTAngleBracket) ob="⟨";
|
||||
else if (openbrace==MTBTFloorBracket) ob="⌊";
|
||||
else if (openbrace==MTBTCeilBracket) ob="⌈";
|
||||
else if (openbrace==MTBTParenthesis) ob="(";
|
||||
else if (openbrace==MTBTSquareBracket) ob="[";
|
||||
else if (openbrace==MTBTCurlyBracket) ob="{";
|
||||
else if (openbrace==MTBTSingleLine) ob="|";
|
||||
else if (openbrace==MTBTDoubleLine) ob="||";
|
||||
if (closebrace==MTBTAngleBracket) cb="⟩";
|
||||
else if (closebrace==MTBTFloorBracket) cb="⌋";
|
||||
else if (closebrace==MTBTCeilBracket) cb="⌉";
|
||||
else if (closebrace==MTBTParenthesis) cb=")";
|
||||
else if (closebrace==MTBTSquareBracket) cb="]";
|
||||
else if (closebrace==MTBTCurlyBracket) cb="}";
|
||||
else if (closebrace==MTBTSingleLine) cb="|";
|
||||
else if (closebrace==MTBTDoubleLine) cb="||";
|
||||
|
||||
|
||||
html=html+ob;
|
||||
@ -319,32 +292,23 @@ bool JKQTMathTextBraceNode::toHtml(QString &html, JKQTMathTextEnvironment curren
|
||||
|
||||
QString JKQTMathTextBraceNode::getTypeName() const
|
||||
{
|
||||
return QLatin1String("MTbraceNode(")+BraceType2String(openbrace)+" "+BraceType2String(closebrace)+")";
|
||||
return QLatin1String("MTbraceNode(")+JKQTMathTextBraceType2String(openbrace)+" "+JKQTMathTextBraceType2String(closebrace)+")";
|
||||
}
|
||||
|
||||
JKQTMathTextBraceNode::BraceType JKQTMathTextBraceNode::getOpenbrace() const {
|
||||
JKQTMathTextBraceType JKQTMathTextBraceNode::getOpenbrace() const {
|
||||
return this->openbrace;
|
||||
}
|
||||
|
||||
JKQTMathTextBraceNode::BraceType JKQTMathTextBraceNode::getClosebrace() const {
|
||||
JKQTMathTextBraceType JKQTMathTextBraceNode::getClosebrace() const {
|
||||
return this->closebrace;
|
||||
}
|
||||
|
||||
bool JKQTMathTextBraceNode::getShowClosingBrace() const {
|
||||
return this->showClosingBrace;
|
||||
}
|
||||
|
||||
bool JKQTMathTextBraceNode::getShowOpeningBrace() const
|
||||
{
|
||||
return showOpeningBrace;
|
||||
}
|
||||
|
||||
void JKQTMathTextBraceNode::getBraceSize(QPainter &/*painter*/, JKQTMathTextEnvironment ev, double /*baselineHeight*/, double overallHeight, double &bracewidth, double &braceheight) const
|
||||
{
|
||||
const double lw=qMax(0.25,ceil(ev.fontSize/12.0));
|
||||
braceheight=overallHeight*parentMathText->getBraceFactor();
|
||||
bracewidth=0.6*pow(braceheight, 0.6);
|
||||
if (openbrace==JKQTMathTextBraceNode::MTBTCurlyBracket || closebrace==JKQTMathTextBraceNode::MTBTCurlyBracket) bracewidth=qMax(bracewidth, lw*3.5);
|
||||
if (openbrace==MTBTCurlyBracket || closebrace==MTBTCurlyBracket) bracewidth=qMax(bracewidth, lw*3.5);
|
||||
|
||||
}
|
||||
|
||||
|
@ -36,26 +36,16 @@ class JKQTMathText; // forward
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_bracenode_geo.png
|
||||
*/
|
||||
*
|
||||
* This node supports the brace-types encoded by JKQTMathTextBraceType:
|
||||
* \copydetails JKQTMathTextBraceType
|
||||
*
|
||||
* In addition it is possible to switch the opening and the closing braces independently on and off.
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleChildNode {
|
||||
public:
|
||||
/** \brief types of available braces */
|
||||
enum BraceType {
|
||||
MTBTParenthesis, /*!< \brief parantheses () \image html jkqtmathtext/jkqtmathtext_brace_round.png */
|
||||
MTBTSquareBracket, /*!< \brief brackets [] \image html jkqtmathtext/jkqtmathtext_brace_rect.png */
|
||||
MTBTCurlyBracket, /*!< \brief curly braces {} \image html jkqtmathtext/jkqtmathtext_brace_curly.png */
|
||||
MTBTAngleBracket, /*!< \brief angle backets <> \image html jkqtmathtext/jkqtmathtext_brace_tri.png */
|
||||
MTBTCeilBracket, /*!< \brief ceil brackets \image html jkqtmathtext/jkqtmathtext_brace_ceil.png */
|
||||
MTBTFloorBracket, /*!< \brief floor brackets \image html jkqtmathtext/jkqtmathtext_brace_floor.png */
|
||||
MTBTDoubleLine, /*!< \brief double-line brackets (norm ||...||) \image html jkqtmathtext/jkqtmathtext_brace_dblline.png */
|
||||
MTBTSingleLine, /*!< \brief single-line brackets (abs |...|) \image html jkqtmathtext/jkqtmathtext_brace_oneline.png */
|
||||
MTBTNone /*!< \brief no bracket */
|
||||
};
|
||||
/** \brief convert a BraceType into a string */
|
||||
static QString BraceType2String(BraceType type);
|
||||
/** \brief convert a string describing a LaTeX Token into a BraceType */
|
||||
static BraceType TokenNameString2TokenType(const QString& type);
|
||||
JKQTMathTextBraceNode(JKQTMathText* parent, BraceType openbrace, BraceType closebrace, JKQTMathTextNode* child, bool showOpeningBrace=true, bool showClosingBrace=true);
|
||||
|
||||
JKQTMathTextBraceNode(JKQTMathText* parent, JKQTMathTextBraceType openbrace, JKQTMathTextBraceType closebrace, JKQTMathTextNode* child);
|
||||
virtual ~JKQTMathTextBraceNode() override;
|
||||
/** \copydoc JKQTMathTextNode::draw() */
|
||||
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
|
||||
@ -64,13 +54,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleCh
|
||||
/** \copydoc JKQTMathTextNode::getTypeName() */
|
||||
virtual QString getTypeName() const override;
|
||||
/** \copydoc openbrace */
|
||||
BraceType getOpenbrace() const;
|
||||
JKQTMathTextBraceType getOpenbrace() const;
|
||||
/** \copydoc closebrace */
|
||||
BraceType getClosebrace() const;
|
||||
/** \copydoc showRightBrace */
|
||||
bool getShowClosingBrace() const;
|
||||
/** \copydoc showOpeningBrace */
|
||||
bool getShowOpeningBrace() const;
|
||||
JKQTMathTextBraceType getClosebrace() const;
|
||||
protected:
|
||||
/** \copydoc JKQTMathTextNode::getSizeInternal()
|
||||
*
|
||||
@ -80,13 +66,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceNode: public JKQTMathTextSingleCh
|
||||
/** calculates the size of this node (also returned by getSizeInternal() ) and of the brace */
|
||||
void getSizeInternalAndBrace(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, double& bracewidth, double&braceheight, const JKQTMathTextNodeSize* prevNodeSize=nullptr);
|
||||
/**\brief opening brace */
|
||||
BraceType openbrace;
|
||||
JKQTMathTextBraceType openbrace;
|
||||
/**\brief closing brace */
|
||||
BraceType closebrace;
|
||||
/**\brief if \c true, the closing (right hand side) brace is drawn */
|
||||
bool showClosingBrace;
|
||||
/**\brief if \c true, the opening (left hand side) brace is drawn */
|
||||
bool showOpeningBrace;
|
||||
JKQTMathTextBraceType closebrace;
|
||||
/** \brief calculate the width of the brace */
|
||||
void getBraceSize(QPainter& painter, JKQTMathTextEnvironment currentEv, double baselineHeight, double overallHeight, double& bracewidth, double& braceheight) const;
|
||||
};
|
||||
|
@ -50,10 +50,7 @@ JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent):
|
||||
}
|
||||
|
||||
JKQTMathTextListNode::~JKQTMathTextListNode() {
|
||||
for (int i=0; i<nodes.size(); i++) {
|
||||
delete nodes[i];
|
||||
}
|
||||
nodes.clear();
|
||||
clearChildren(true);
|
||||
}
|
||||
|
||||
QString JKQTMathTextListNode::getTypeName() const
|
||||
@ -441,4 +438,47 @@ QList<JKQTMathTextNode *> JKQTMathTextListNode::getNodes() const {
|
||||
return this->nodes;
|
||||
}
|
||||
|
||||
int JKQTMathTextListNode::count() const
|
||||
{
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
int JKQTMathTextListNode::size() const
|
||||
{
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
void JKQTMathTextListNode::clearChildren(bool deleteChildren)
|
||||
{
|
||||
if (deleteChildren) {
|
||||
for (int i=0; i<nodes.size(); i++) {
|
||||
delete nodes[i];
|
||||
}
|
||||
}
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
JKQTMathTextNode *JKQTMathTextListNode::child(int i)
|
||||
{
|
||||
return nodes[i];
|
||||
}
|
||||
|
||||
const JKQTMathTextNode *JKQTMathTextListNode::child(int i) const
|
||||
{
|
||||
return nodes[i];
|
||||
}
|
||||
|
||||
JKQTMathTextNode *JKQTMathTextListNode::simplyfyListNode(JKQTMathTextListNode *nl) {
|
||||
return nl;
|
||||
if (nl==nullptr) return nl;
|
||||
if (nl->count()==1) {
|
||||
// if there was only a single node: simplify the syntax tree, by removing the outer list node
|
||||
JKQTMathTextNode* ret= nl->child(0);
|
||||
nl->clearChildren(false);
|
||||
delete nl;
|
||||
return ret;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +51,18 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextNode {
|
||||
virtual void setDrawBoxes(bool draw) override;
|
||||
/** \copydoc nodes */
|
||||
QList<JKQTMathTextNode*> getNodes() const;
|
||||
/** \brief return number of children */
|
||||
int count() const;
|
||||
/** \brief return number of children */
|
||||
int size() const;
|
||||
/** \brief clear all children, deleting them if \a deleteChildren==true */
|
||||
void clearChildren(bool deleteChildren=true);
|
||||
/** \brief return i-th child node */
|
||||
JKQTMathTextNode* child(int i);
|
||||
/** \brief return i-th child node */
|
||||
const JKQTMathTextNode* child(int i) const;
|
||||
/** \brief simplifies the given list-node, i.e. if it contains one child only, the child is returned and the list node destroyed, otherwise the list node \a nl is returned */
|
||||
static JKQTMathTextNode* simplyfyListNode(JKQTMathTextListNode* nl);
|
||||
protected:
|
||||
/** \copydoc JKQTMathTextNode::getSizeInternal() */
|
||||
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
|
||||
|
Loading…
Reference in New Issue
Block a user