diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index b67d46f141..bfdfed6b96 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -39,6 +39,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: reworked node class tree: inserted base-class nodes for single-child, dual-child!
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 , ...
NEW: shows strikeoutPos when drawing Debug-Boxes
+ NEW: LaTeX-Parser understands optional instruction parameters in [...] now
diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp
index 6f65577d07..08f334231b 100644
--- a/examples/jkqtmathtext_test/testform.cpp
+++ b/examples/jkqtmathtext_test/testform.cpp
@@ -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");
diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp
index 0d10efa371..3750c7749d 100644
--- a/lib/jkqtmathtext/jkqtmathtext.cpp
+++ b/lib/jkqtmathtext/jkqtmathtext.cpp
@@ -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 TokenCharacters;
+ static QSet mathEnvironmentSpecialChars, mathEnvironmentSpecialEndChars;
+ static QSet 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 '"< 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 mathEnvironmentSpecialChars, mathEnvironmentSpecialEndChars;
- if (mathEnvironmentSpecialChars.size()==0) {
- mathEnvironmentSpecialChars<<'(' << '[' << '|' << ')' << ']' << '+' << '-' << '*' << '/' << '<' << '>' << '=';
- mathEnvironmentSpecialEndChars<<'(' << '&' << '[' << '|' << ')' << ']' << '\\' << '$' << '{' << '}' << '_' << '^' << '+' << '-' << '/' << '*' << '=' << '<' << '>';
- }
if (mathEnvironmentSpecialChars.contains(c)) {
currentTokenName=c;
//std::cout<<"found text node '"< 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 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 '"<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 (currentTokenIDaddNode(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 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 "<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 '"<(n1);
+ JKQTMathTextTextNode* n1txt=dynamic_cast(n1);
+ if (n1lst && n1lst->count()==1) {
+ n1txt=dynamic_cast(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 '"<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=="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;
}
diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h
index 9f7d043264..87519e6c95 100644
--- a/lib/jkqtmathtext/jkqtmathtext.h
+++ b/lib/jkqtmathtext/jkqtmathtext.h
@@ -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);
diff --git a/lib/jkqtmathtext/jkqtmathtexttools.cpp b/lib/jkqtmathtext/jkqtmathtexttools.cpp
index 95a0a5c7c6..0559a886e7 100644
--- a/lib/jkqtmathtext/jkqtmathtexttools.cpp
+++ b/lib/jkqtmathtext/jkqtmathtexttools.cpp
@@ -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);
+}
diff --git a/lib/jkqtmathtext/jkqtmathtexttools.h b/lib/jkqtmathtext/jkqtmathtexttools.h
index 56a2de288b..c311685efb 100644
--- a/lib/jkqtmathtext/jkqtmathtexttools.h
+++ b/lib/jkqtmathtext/jkqtmathtexttools.h
@@ -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
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp
index 2a465d91f3..8992983ec7 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.cpp
@@ -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()<<" ==> "<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);
}
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h
index e952854133..b66fb45106 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextbracenode.h
@@ -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;
};
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
index 5bd6fe1e39..fbed241144 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
@@ -50,10 +50,7 @@ JKQTMathTextListNode::JKQTMathTextListNode(JKQTMathText* _parent):
}
JKQTMathTextListNode::~JKQTMathTextListNode() {
- for (int i=0; i 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; icount()==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;
+}
+
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h
index cc81b7af10..57ffb00cc4 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.h
@@ -51,6 +51,18 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextListNode: public JKQTMathTextNode {
virtual void setDrawBoxes(bool draw) override;
/** \copydoc nodes */
QList 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;