refactored/simplified JKQTMathText::parseLatexString()

bugfixed regression: JKQTMathText displays \left.\right)-type braces and \sum,\int,... with and without \limits correctly again
This commit is contained in:
jkriege2 2022-07-06 22:44:02 +02:00
parent f9370799fc
commit 36aeec13aa
8 changed files with 241 additions and 218 deletions

View File

@ -1161,6 +1161,13 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(new JKQTMathTextWhitespaceNode(currentInstructionName, this));
} else if (JKQTMathTextSymbolNode::hasSymbol(currentInstructionName)) {
nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName));
if (JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(currentInstructionName) && parsingMathEnvironment) {
nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
}
} else if (currentTokenName=="limits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
} else if (currentTokenName=="nolimits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
} else {
getToken(); // look at next token
if (currentToken==MTTopenbrace) {
@ -1182,41 +1189,11 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (c!='}') error_list.append(tr("error @ ch. %1: \verb{...} not closed by '}'").arg(currentTokenID).arg(currentInstructionName));
nl->addChild(new JKQTMathTextTextNode(this, text, false));
}
} else if (currentInstructionName=="frac") {
} else if (JKQTMathTextFracNode::supportsInstructionName(currentInstructionName)) {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(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(currentInstructionName));
} else if (currentInstructionName=="dfrac" || currentInstructionName=="cfrac") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(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(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->addChild(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(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->addChild(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(currentInstructionName));
} else if (currentInstructionName=="tfrac") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(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(currentInstructionName));
} else if (currentInstructionName=="stackrel") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMstackrel));
if (n1 && n2) nl->addChild(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::InstructionName2FracType(currentInstructionName)));
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);
@ -1224,42 +1201,6 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(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->addChild(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(currentInstructionName));
} else if (currentInstructionName=="underbracket") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMunderbracket));
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->addChild(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(currentInstructionName));
} else if (currentInstructionName=="overbrace") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(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(currentInstructionName));
} else if (currentInstructionName=="overbracket") {
JKQTMathTextNode* n1=parseLatexString(true);
JKQTMathTextNode* n2=nullptr;
if (getToken()==MTTopenbrace) n2=parseLatexString(true);
if (n1 && n2) nl->addChild(new JKQTMathTextFracNode(this, n1, n2, JKQTMathTextFracNode::MTFMoverbracket));
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->addChild(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(currentInstructionName));
} else if (currentInstructionName=="begin") {
if (getToken()==MTTtext) {
QString envname=currentTokenName;
@ -1315,48 +1256,8 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
while (currentToken!=MTTclosebrace) getToken();
getNew=true;
}
} else if (currentInstructionName=="vec") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDvec, parseLatexString(true)));
} else if (currentInstructionName=="overline"||currentInstructionName=="oline"||currentInstructionName=="ol") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDoverline, parseLatexString(true)));
} else if (currentInstructionName=="underline"||currentInstructionName=="uline"||currentInstructionName=="ul") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDunderline, parseLatexString(true)));
} else if (currentInstructionName=="uuline"||currentInstructionName=="uul") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdoubleunderline, parseLatexString(true)));
} else if (currentInstructionName=="ooline"||currentInstructionName=="ool") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdoubleoverline, parseLatexString(true)));
} else if (currentInstructionName=="arrow"||currentInstructionName=="overrightarrow"||currentInstructionName=="overarrow") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDarrow, parseLatexString(true)));
} else if (currentInstructionName=="hat" || currentInstructionName=="^") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDhat, parseLatexString(true)));
} else if (currentInstructionName=="widehat") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidehat, parseLatexString(true)));
} else if (currentInstructionName=="check" || currentInstructionName=="v") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDcheck, parseLatexString(true)));
} else if (currentInstructionName=="widecheck") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidecheck, parseLatexString(true)));
} else if (currentInstructionName=="bar") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbar, parseLatexString(true)));
} else if (currentInstructionName=="dot" || currentInstructionName==".") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDdot, parseLatexString(true)));
} else if (currentInstructionName=="ocirc") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDocirc, parseLatexString(true)));
} else if (currentInstructionName=="tilde" || currentInstructionName=="~") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDtilde, parseLatexString(true)));
} else if (currentInstructionName=="breve" || currentInstructionName=="u") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbreve, parseLatexString(true)));
} else if (currentInstructionName=="widetilde") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDwidetilde, parseLatexString(true)));
} else if (currentInstructionName=="ddot") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDddot, parseLatexString(true)));
} else if (currentInstructionName=="cancel") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDcancel, parseLatexString(true)));
} else if (currentInstructionName=="xcancel") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDxcancel, parseLatexString(true)));
} else if (currentInstructionName=="bcancel") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDbcancel, parseLatexString(true)));
} else if (currentInstructionName=="strike" || currentInstructionName=="st" || currentInstructionName=="sout") {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::MTDstrike, parseLatexString(true)));
} else if (JKQTMathTextDecoratedNode::supportsInstructionName(currentInstructionName)) {
nl->addChild(new JKQTMathTextDecoratedNode(this, JKQTMathTextDecoratedNode::InstructionName2DecorationType(currentInstructionName), parseLatexString(true)));
} else {
if (currentInstructionName=="textcolor" || currentInstructionName=="mathcolor" || currentInstructionName=="color" || currentInstructionName=="colorbox") {
bool foundError=true;
@ -1377,17 +1278,6 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true)));
}
}
if (getNew) getToken();
if (currentToken==MTTinstruction && currentTokenName=="limits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
getNew=true;
} else if (currentToken==MTTinstruction && currentTokenName=="nolimits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
getNew=true;
} else {
getNew=false;
}
} else if (currentToken==MTTopenbracket && currentInstructionName!="left") {
//std::cout<<"found '[' after '"<<name.toStdString()<<"'\n";
if (currentInstructionName=="sqrt") {
@ -1402,7 +1292,6 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(new JKQTMathTextTextNode(this, "[", false));
}
} else {
bool subSuperscriptAboveBelowNode=false;
//std::cout<<"did not find '{' after '"<<name.toStdString()<<"'\n";
if (currentInstructionName=="right") {
if (currentToken==MTTtext) {
@ -1410,6 +1299,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
bool tokenWasNoBrace=false;
const QString firstTokenChar(currentTokenName[0]);
if (TokenNameMatchesJKQTMathTextBraceType(firstTokenChar, quitOnClosingBrace, true, &tokenWasNoBrace)) {
lastRightBraceType=TokenName2JKQTMathTextBraceType(firstTokenChar);
if (quitOnClosingBrace!=MTBTAny) currentTokenName=currentTokenName.right(currentTokenName.size()-1);
break;
} else {
@ -1418,12 +1308,12 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
}
} else if (currentToken==MTTinstruction) {
if (InstructionNameMatchesJKQTMathTextBraceType(currentTokenName, quitOnClosingBrace, true)) {
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
lastRightBraceType=InstructionName2OpeningJKQTMathTextBraceType(currentTokenName);
break;
}
} else if (currentToken==MTTclosebracket) {
if (quitOnClosingBrace==MTBTSquareBracket || quitOnClosingBrace==MTBTAny) {
currentTokenName=currentTokenName.right(currentTokenName.size()-1);
lastRightBraceType=MTBTSquareBracket;
break;
}
} else {
@ -1440,7 +1330,8 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
nl->addChild(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->addChild(new JKQTMathTextBraceNode(this, bracetype, bracetype, parseLatexString(currentTokenName.size()<=0, bracetype)));
JKQTMathTextNode* c=parseLatexString(currentTokenName.size()<=0, bracetype);
nl->addChild(new JKQTMathTextBraceNode(this, bracetype, lastRightBraceType, c));
} else {
getNew=false;
}
@ -1448,38 +1339,21 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
} else if (currentToken==MTTinstruction) {
const JKQTMathTextBraceType bracetypeopening=InstructionName2OpeningJKQTMathTextBraceType(currentTokenName);
if (bracetypeopening!=MTBTUnknown) {
nl->addChild(new JKQTMathTextBraceNode(this, bracetypeopening, bracetypeopening, parseLatexString(true, bracetypeopening)));
JKQTMathTextNode* c=parseLatexString(true, bracetypeopening);
nl->addChild(new JKQTMathTextBraceNode(this, bracetypeopening, lastRightBraceType, c));
} else if (currentToken==MTTinstruction && TokenNameMatchesJKQTMathTextBraceType(currentTokenName, quitOnClosingBrace, true)) {
break;
}
} else if (currentToken==MTTopenbracket) {
nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, parseLatexString(true, MTBTSquareBracket)));
JKQTMathTextNode* c=parseLatexString(true, MTBTSquareBracket);
nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, lastRightBraceType, c));
} else {
error_list.append(tr("error @ ch. %1: unexpected token after \\left").arg(currentTokenID));
}
} else if (JKQTMathTextWhitespaceNode::supportsInstructionName(currentInstructionName)) {
nl->addChild(new JKQTMathTextWhitespaceNode(currentInstructionName, this));
} else if (JKQTMathTextSymbolNode::hasSymbol(currentInstructionName)) {
nl->addChild(new JKQTMathTextSymbolNode(this, currentInstructionName));
static QSet<QString> subsupOperations= (QSet<QString>()<<"sum"<<"prod"<<"coprod"
<<"bigcap"<<"bigcup"<<"bigvee"<<"bighat"
<<"int"<<"iint"<<"iiint"<<"oint"<<"oiint"<<"oiiint"
<<"mod"<<"median"<<"max"<<"min"<<"argmax"<<"argmin"<<"sup"<<"inf"
<<"liminf"<<"limsup"<<"lim"<<"max"<<"min");
if (subsupOperations.contains(currentInstructionName) && parsingMathEnvironment) {
nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
}
if (currentToken==MTTinstruction && currentTokenName=="limits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
} else if (currentToken==MTTinstruction && currentTokenName=="nolimits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
} else {
getNew=false;
}
} else {
error_list.append(tr("error @ ch. %1: unknown instruction \\%2").arg(currentTokenID).arg(currentInstructionName));
//error_list.append(tr("error @ ch. %1: unknown instruction \\%2").arg(currentTokenID).arg(currentInstructionName));
}
}
}
@ -1490,18 +1364,21 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
JKQTMathTextNode* child=nullptr;
JKQTMathTextNode* child2=nullptr;
if (currentToken==MTTinstruction) {
QString name=currentTokenName;
const QString currentInstructionName=currentTokenName;
getToken(); // look at next token
if (currentToken==MTTopenbrace) {
child=new JKQTMathTextInstruction1Node(this, name, parseLatexString(true));
} else if (JKQTMathTextWhitespaceNode::supportsInstructionName(name)) {
child=new JKQTMathTextInstruction1Node(this, currentInstructionName, parseLatexString(true));
} else if (JKQTMathTextWhitespaceNode::supportsInstructionName(currentInstructionName)) {
getNew=false;
child=new JKQTMathTextWhitespaceNode(name, this);
} else if (JKQTMathTextSymbolNode::hasSymbol(name)) {
child=new JKQTMathTextWhitespaceNode(currentInstructionName, this);
} else if (JKQTMathTextSymbolNode::hasSymbol(currentInstructionName)) {
getNew=false;
child=new JKQTMathTextSymbolNode(this, name);
child=new JKQTMathTextSymbolNode(this, currentInstructionName);
if (JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(currentInstructionName) && parsingMathEnvironment) {
child->setSubSuperscriptAboveBelowNode(true);
}
} else {
error_list.append(tr("error @ ch. %1: unknown instruction \\%2").arg(currentTokenID).arg(name));
error_list.append(tr("error @ ch. %1: unknown instruction \\%2").arg(currentTokenID).arg(currentInstructionName));
}
} else if (currentToken==MTTopenbrace) {
child=parseLatexString(true);
@ -1529,6 +1406,9 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
} else if (JKQTMathTextSymbolNode::hasSymbol(currentInstructionName)){
getNew=true;
child=new JKQTMathTextSymbolNode(this, currentInstructionName);
if (JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(currentInstructionName) && parsingMathEnvironment) {
child->setSubSuperscriptAboveBelowNode(true);
}
} else {
getToken(); // look at next token
if (currentToken==MTTopenbrace) {

View File

@ -818,6 +818,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
/** \brief used by the tokenizer. type of the current token */
tokenType currentToken;
/** \brief the JKQTMathTextBraceType associated with the last \c \\right command the parser encountered */
JKQTMathTextBraceType lastRightBraceType;
/** \brief used by the tokenizer. Name of the current token, id applicable */
QString currentTokenName;
/** \brief used by the tokenizer. Points to the currently read character in parseString */

View File

@ -86,6 +86,18 @@ QString JKQTMathTextDecoratedNode::DecorationType2String(JKQTMathTextDecoratedNo
return "unknown";
}
JKQTMathTextDecoratedNode::DecorationType JKQTMathTextDecoratedNode::InstructionName2DecorationType(const QString &mode)
{
fillInstructions();
return instructions[mode];
}
bool JKQTMathTextDecoratedNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
JKQTMathTextDecoratedNode::JKQTMathTextDecoratedNode(JKQTMathText* _parent, DecorationType decoration, JKQTMathTextNode* child):
@ -132,6 +144,50 @@ void JKQTMathTextDecoratedNode::getSizeInternal(QPainter& painter, JKQTMathTextE
width=std::max<double>(deco_miniwidth,cwidth);
}
QHash<QString, JKQTMathTextDecoratedNode::DecorationType> JKQTMathTextDecoratedNode::instructions;
void JKQTMathTextDecoratedNode::fillInstructions()
{
if (instructions.size()>0) return;
instructions["vec"]=MTDvec;
instructions["overline"]=MTDoverline;
instructions["oline"]=MTDoverline;
instructions["ol"]=MTDoverline;
instructions["underline"]=MTDunderline;
instructions["uline"]=MTDunderline;
instructions["ul"]=MTDunderline;
instructions["uuline"]=MTDdoubleunderline;
instructions["uul"]=MTDdoubleunderline;
instructions["ooline"]=MTDdoubleoverline;
instructions["ool"]=MTDdoubleoverline;
instructions["arrow"]=MTDarrow;
instructions["overrightarrow"]=MTDarrow;
instructions["overarrow"]=MTDarrow;
instructions["hat"]=MTDhat;
instructions["^"]=MTDhat;
instructions["widehat"]=MTDwidehat;
instructions["check"]=MTDcheck;
instructions["v"]=MTDcheck;
instructions["widecheck"]=MTDwidecheck;
instructions["bar"]=MTDbar;
instructions["dot"]=MTDdot;
instructions["."]=MTDdot;
instructions["ocirc"]=MTDocirc;
instructions["tilde"]=MTDtilde;
instructions["~"]=MTDtilde;
instructions["breve"]=MTDbreve;
instructions["u"]=MTDbreve;
instructions["widetilde"]=MTDwidetilde;
instructions["ddot"]=MTDddot;
instructions["cancel"]=MTDcancel;
instructions["xcancel"]=MTDxcancel;
instructions["bcancel"]=MTDbcancel;
instructions["strike"]=MTDstrike;
instructions["st"]=MTDstrike;
instructions["sout"]=MTDstrike;
}
double JKQTMathTextDecoratedNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
doDrawBoxes(painter, x, y, currentEv);
JKQTMathTextEnvironment ev=currentEv;

View File

@ -68,6 +68,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDecoratedNode: public JKQTMathTextSing
/** \brief convert a DecorationType into a string
*/
static QString DecorationType2String(DecorationType mode);
/** \brief returns the FracType corresponding to \a instructionName
* \see JKQTMathTextFracNode::FracType
*/
static DecorationType InstructionName2DecorationType(const QString& mode);
/** \brief returns true, if the given \a instructionName can be converted to a FracType
* \see JKQTMathTextFracNode::FracType
*/
static bool supportsInstructionName(const QString& instructionName);
JKQTMathTextDecoratedNode(JKQTMathText* parent, DecorationType decoration, JKQTMathTextNode* child);
virtual ~JKQTMathTextDecoratedNode() override;
@ -84,6 +93,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDecoratedNode: public JKQTMathTextSing
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \brief type of decoration that is added to the child node */
DecorationType decoration;
/** \brief lists all supported instructions */
static QHash<QString, DecorationType> instructions;
/** \biref fills instructions */
static void fillInstructions();
};
#endif // JKQTMATHTEXTDECORATEDNODE_H

View File

@ -34,6 +34,34 @@
#include <QFont>
QHash<QString, JKQTMathTextFracNode::FracType> JKQTMathTextFracNode::instructions;
void JKQTMathTextFracNode::fillInstructions()
{
if (instructions.size()>0) return;
instructions["frac"]=MTFMfrac;
instructions["dfrac"] = MTFMdfrac;
instructions["cfrac"]=MTFMdfrac;
instructions["sfrac"] = MTFMsfrac;
instructions["slantfrac"] = MTFMsfrac;
instructions["xfrac"]=MTFMsfrac;
instructions["stfrac"] = MTFMstfrac;
instructions["nicefrac"] = MTFMstfrac;
instructions["slanttextfrac"] = MTFMstfrac;
instructions["xtfrac"]=MTFMstfrac;
instructions["tfrac"]=MTFMtfrac;
instructions["stackrel"]=MTFMstackrel;
instructions["underbrace"]=MTFMunderbrace;
instructions["underbracket"]=MTFMunderbracket;
instructions["underset"]=MTFMunderset;
instructions["overbrace"]=MTFMoverbrace;
instructions["overbracket"]=MTFMoverbracket;
instructions["overset"]=MTFMoverset;
}
QString JKQTMathTextFracNode::FracType2String(JKQTMathTextFracNode::FracType mode)
@ -67,6 +95,18 @@ QString JKQTMathTextFracNode::FracType2String(JKQTMathTextFracNode::FracType mod
return "unknown";
}
JKQTMathTextFracNode::FracType JKQTMathTextFracNode::InstructionName2FracType(const QString &mode)
{
fillInstructions();
return instructions.value(mode, MTFMfrac);
}
bool JKQTMathTextFracNode::supportsInstructionName(const QString &instructionName)
{
fillInstructions();
return instructions.contains(instructionName);
}
JKQTMathTextFracNode::JKQTMathTextFracNode(JKQTMathText* _parent, JKQTMathTextNode* child_top, JKQTMathTextNode* child_bottom, JKQTMathTextFracNode::FracType mode):
@ -342,6 +382,3 @@ bool JKQTMathTextFracNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /*c
JKQTMathTextFracNode::FracType JKQTMathTextFracNode::getMode() const {
return this->mode;
}

View File

@ -67,6 +67,16 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFracNode: public JKQTMathTextDualChild
*/
static QString FracType2String(FracType mode);
/** \brief returns the FracType corresponding to \a instructionName
* \see JKQTMathTextFracNode::FracType
*/
static FracType InstructionName2FracType(const QString& mode);
/** \brief returns true, if the given \a instructionName can be converted to a FracType
* \see JKQTMathTextFracNode::FracType
*/
static bool supportsInstructionName(const QString& instructionName);
JKQTMathTextFracNode(JKQTMathText* parent, JKQTMathTextNode* child_top, JKQTMathTextNode* child_bottom, JKQTMathTextFracNode::FracType mode);
virtual ~JKQTMathTextFracNode() override;
@ -79,6 +89,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextFracNode: public JKQTMathTextDualChild
/** \copydoc mode */
JKQTMathTextFracNode::FracType getMode() const;
protected:
/** \brief lists all supported instructions */
static QHash<QString, FracType> instructions;
/** \biref fills instructions */
static void fillInstructions();
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \brief actual display type of fraction object */

View File

@ -75,7 +75,10 @@ void JKQTMathTextSymbolNode::getSymbolSizeInternal(QPainter &painter, JKQTMathTe
if (currentEv.insideMath) {
width=qMax(br.width(), mintbr.width());
if (has(globalFlags, ExtendWidthInMathmode)) {
if (has(globalFlags, SmallExtendWidthInMathmode)) {
if (!symprops.getSymbolSingleChar().isNull()) width=width*(1.0+(parentMathText->getMathoperatorWidthFactor()-1.0)/2.0);
else width=width+mintbr.width();
} else if (has(globalFlags, ExtendWidthInMathmode)) {
if (!symprops.getSymbolSingleChar().isNull()) width=width*parentMathText->getMathoperatorWidthFactor();
else width=width+mintbr.width();
}
@ -302,6 +305,15 @@ bool JKQTMathTextSymbolNode::hasSymbol(const QString &symbolName)
return symbols.contains(symbolName);
}
bool JKQTMathTextSymbolNode::isSubSuperscriptBelowAboveSymbol(const QString &symbolName)
{
fillSymbolTables();
if (symbols.contains(symbolName)) {
return has(symbols[symbolName].globalFlags, SubSuperscriptBelowAboveSymbol);
}
return false;
}
JKQTMathTextSymbolNode::SymbolProps::SymbolProps():
@ -326,7 +338,7 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymb
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymbol(const QString &op, const QString &ophtml)
{
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff, 1.0, 0.0)).setGlobalFlags(ExtendWidthInMathmode).addHtml(ophtml, ItalicOff|BoldOff, 1.0, 0.0);
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode).addHtml(ophtml, ItalicOff|BoldOff, 1.0, 0.0);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorText(const QString &op)
@ -336,12 +348,17 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorText
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorText(const QString &op, const QString &ophtml)
{
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).setGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf).addHtml(ophtml, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0);
return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf).addHtml(ophtml, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorSymbolUnicode(const QString &unicode)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).setGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorSymbolUnicode(const QString &unicode)
{
return SymbolFullProps(MTFEUnicode, SymbolProps(unicode, ItalicOff|BoldOff, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|MakeWhitespaceHalf);
}
JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::GreekLetter_WinSymbol_Unicode_Html(const QString &letterWinSymbol, const QString &letterUnicode, const QString &html)
@ -422,8 +439,6 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
/**************************************************************************************
* STANDARD Symbols available in all standard fonts
**************************************************************************************/
symbols[" "]=SimpleTextSymbol(" ", "&nbsp;");
symbols[""]=SimpleTextSymbol(" ", "&nbsp;");
symbols["#"]=SimpleTextSymbol("#", "&num;");
symbols["%"]=SimpleTextSymbol("%", "&NestedGreaterGreater;");
symbols["&"]=SimpleTextSymbol("&", "&amp;");
@ -565,45 +580,45 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
* STANDARD MathOperator Strings
**************************************************************************************/
symbols["Pr"] = MathOperatorText("Pr");
symbols["acos"] = MathOperatorText("acos");
symbols["arccos"] = MathOperatorText("arccos");
symbols["arcsin"] = MathOperatorText("arcsin");
symbols["arctan"] = MathOperatorText("arctan");
symbols["arg"] = MathOperatorText("arg");
symbols["argmax"] = MathOperatorText("arg max", "arg&thinsp;max");
symbols["argmin"] = MathOperatorText("arg min", "arg&thinsp;min");
symbols["asin"] = MathOperatorText("asin");
symbols["atan"] = MathOperatorText("atan");
symbols["cos"] = MathOperatorText("cos");
symbols["cosh"] = MathOperatorText("cosh");
symbols["cot"] = MathOperatorText("cot");
symbols["coth"] = MathOperatorText("coth");
symbols["coth"] = MathOperatorText("coth");
symbols["deg"] = MathOperatorText("deg");
symbols["det"] = MathOperatorText("det");
symbols["dim"] = MathOperatorText("dim");
symbols["exp"] = MathOperatorText("exp");
symbols["gcd"] = MathOperatorText("gcd");
symbols["hom"] = MathOperatorText("hom");
symbols["ker"] = MathOperatorText("ker");
symbols["lb"] = MathOperatorText("lb");
symbols["ld"] = MathOperatorText("ld");
symbols["lim"] = MathOperatorText("lim");
symbols["liminf"] = MathOperatorText("lim inf", "lim&thinsp;inf");
symbols["limsup"] = MathOperatorText("lim sup", "lim&thinsp;sup");
symbols["ln"] = MathOperatorText("ln");
symbols["log"] = MathOperatorText("log");
symbols["max"] = MathOperatorText("max");
symbols["median"] = MathOperatorText("median");
symbols["min"] = MathOperatorText("min");
symbols["mod"] = MathOperatorText("mod");
symbols["sec"] = MathOperatorText("sec");
symbols["sgn"] = MathOperatorText("sgn");
symbols["sign"] = MathOperatorText("sign");
symbols["sin"] = MathOperatorText("sin");
symbols["sinh"] = MathOperatorText("sinh");
symbols["tan"] = MathOperatorText("tan");
symbols["tanh"] = MathOperatorText("tanh");
symbols["acos"] = MathOperatorText("acos").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["arccos"] = MathOperatorText("arccos").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["arcsin"] = MathOperatorText("arcsin").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["arctan"] = MathOperatorText("arctan").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["arg"] = MathOperatorText("arg").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["argmax"] = MathOperatorText("arg max", "arg&thinsp;max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["argmin"] = MathOperatorText("arg min", "arg&thinsp;min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["asin"] = MathOperatorText("asin").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["atan"] = MathOperatorText("atan").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["cos"] = MathOperatorText("cos").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["cosh"] = MathOperatorText("cosh").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["cot"] = MathOperatorText("cot").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["coth"] = MathOperatorText("coth").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["coth"] = MathOperatorText("coth").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["deg"] = MathOperatorText("deg").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["det"] = MathOperatorText("det").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["dim"] = MathOperatorText("dim").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["exp"] = MathOperatorText("exp").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["gcd"] = MathOperatorText("gcd").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["hom"] = MathOperatorText("hom").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["ker"] = MathOperatorText("ker").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["lb"] = MathOperatorText("lb").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["ld"] = MathOperatorText("ld").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["lim"] = MathOperatorText("lim").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["liminf"] = MathOperatorText("lim inf", "lim&thinsp;inf").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["limsup"] = MathOperatorText("lim sup", "lim&thinsp;sup").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["ln"] = MathOperatorText("ln").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["log"] = MathOperatorText("log").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["max"] = MathOperatorText("max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["median"] = MathOperatorText("median").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["min"] = MathOperatorText("min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["mod"] = MathOperatorText("mod").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["sec"] = MathOperatorText("sec").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["sgn"] = MathOperatorText("sgn").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["sign"] = MathOperatorText("sign").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["sin"] = MathOperatorText("sin").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["sinh"] = MathOperatorText("sinh").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["tan"] = MathOperatorText("tan").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["tanh"] = MathOperatorText("tanh").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
/**************************************************************************************
* STANDARD MathOperator Symbols
@ -629,17 +644,17 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["bbR"]=MathOperatorSymbolUnicode(QChar(0x211D));
symbols["bbZ"]=MathOperatorSymbolUnicode(QChar(0x2124));
symbols["because"]=MathOperatorSymbolUnicode(QChar(0x2235)).addMathOperatorHtml("&because;");
symbols["bigcap"]=MathOperatorSymbolUnicode(QChar(0x22C2)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xC7), 1.8);
symbols["bigcup"]=MathOperatorSymbolUnicode(QChar(0x22C3)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xC8), 1.8);
symbols["bighat"]=MathOperatorSymbolUnicode(QChar(0x22C0)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xD9), 1.8);
symbols["bigvee"]=MathOperatorSymbolUnicode(QChar(0x22C1)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xDA), 1.8);
symbols["bigcap"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C2)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xC7), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["bigcup"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C3)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xC8), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["bighat"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C0)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xD9), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["bigvee"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C1)).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xDA), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
{ auto s=MathOperatorSymbolUnicode(QChar(0x22A5)).addMathOperatorHtml("&UpTee;");
symbols["bot"]=s; symbols["perp"]=s; }
{ auto s=MathOperatorSymbolUnicode(QChar(0x2229)).addMathOperatorHtml("&cap;").addMathOperatorWinSymbol(QChar(0xC7));
symbols["cap"]=s; symbols["land"]=s; }
symbols["cdot"]=MathOperatorSymbol(QChar(0xB7)).addMathOperatorHtml("&middot;").addMathOperatorWinSymbol(QChar(0xD7));
symbols["cong"]=MathOperatorSymbolUnicode(QChar(0x2245)).addMathOperatorHtml("&TildeFullEqual;");
symbols["coprod"]=MathOperatorSymbolUnicode(QChar(0x2210)).addMathOperatorHtml("&Coproduct;").addWinSymbol(QChar(0xD5), ItalicOff|BoldOff|FlipSymbolUpDown, 1.8, 0.1);
symbols["coprod"]=NarrowMathOperatorSymbolUnicode(QChar(0x2210)).addMathOperatorHtml("&Coproduct;").addWinSymbol(QChar(0xD5), ItalicOff|BoldOff|FlipSymbolUpDown, 1.8, 0.1).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
{ auto s=MathOperatorSymbolUnicode(QChar(0x222A)).addMathOperatorHtml("&cup;").addMathOperatorWinSymbol(QChar(0xC8));
symbols["cup"]=s; symbols["lor"]=s; }
symbols["ddots"]=MathOperatorSymbolUnicode(QChar(0x22F1)).addMathOperatorHtml("&dtdot;");
@ -659,10 +674,10 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["iddots"]=MathOperatorSymbolUnicode(QChar(0x22F0)).addMathOperatorHtml("&utdot;");
{ auto s=UprightSymbolUnicode(QChar(0x21D4)).addUprightHtml("&DoubleLeftRightArrow;").addUprightWinSymbol(QChar(0xDB));
symbols["iff"]=s; symbols["Leftrightarrow"]=s; }
symbols["iiint"]=MathOperatorSymbolUnicode(QChar(0x222D)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&tint;").addMathOperatorWinSymbol(QString(3, QChar(0xF2)), 1.8, 0.1);
symbols["iint"]=MathOperatorSymbolUnicode(QChar(0x222C)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&Int;").addMathOperatorWinSymbol(QString(2, QChar(0xF2)), 1.8, 0.1);
symbols["iiint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222D)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&tint;").addMathOperatorWinSymbol(QString(3, QChar(0xF2)), 1.8, 0.1);
symbols["iint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222C)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&Int;").addMathOperatorWinSymbol(QString(2, QChar(0xF2)), 1.8, 0.1);
symbols["in"]=MathOperatorSymbolUnicode(QChar(0x2208)).addMathOperatorHtml("&isin;").addMathOperatorWinSymbol(QChar(0xCE));
symbols["int"]=MathOperatorSymbolUnicode(QChar(0x222B)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xF2), 1.8, 0.1);
symbols["int"]=NarrowMathOperatorSymbolUnicode(QChar(0x222B)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&int;").addMathOperatorWinSymbol(QChar(0xF2), 1.8, 0.1);
symbols["leftarrow"]=UprightSymbolUnicode(QChar(0x2190)).addUprightHtml("&larr;").addUprightWinSymbol(QChar(0xAC));
symbols["leftharpoondown"]=UprightSymbolUnicode(QChar(0x21BD)).addUprightHtml("&leftharpoondown;");
symbols["leftharpoonup"]=UprightSymbolUnicode(QChar(0x21BC)).addUprightHtml("&LeftVector;");
@ -693,9 +708,9 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["nparallel"]=MathOperatorSymbolUnicode(QChar(0x2226)).addMathOperatorHtml("&NotDoubleVerticalBar;");
symbols["nwarrow"]=UprightSymbolUnicode(QChar(0x2196)).addUprightHtml("&UpperLeftArrow;");
symbols["odot"]=MathOperatorSymbolUnicode(QChar(0x2299)).addMathOperatorHtml("&odot;");
symbols["oiiint"]=MathOperatorSymbolUnicode(QChar(0x2230)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&Cconint;");
symbols["oiint"]=MathOperatorSymbolUnicode(QChar(0x222F)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&DoubleContourIntegral;");
symbols["oint"]=MathOperatorSymbolUnicode(QChar(0x222E)).setGlobalFlags(IntLikeSymbolCorrection).addMathOperatorHtml("&ContourIntegral;");
symbols["oiiint"]=NarrowMathOperatorSymbolUnicode(QChar(0x2230)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&Cconint;");
symbols["oiint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222F)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&DoubleContourIntegral;");
symbols["oint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222E)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("&ContourIntegral;");
symbols["ominus"]=MathOperatorSymbolUnicode(QChar(0x2296)).addMathOperatorHtml("&ominus;");
symbols["oplus"]=MathOperatorSymbolUnicode(QChar(0x2295)).addMathOperatorHtml("&CirclePlus;").addMathOperatorWinSymbol(QChar(0xC5));
symbols["oslash"]=MathOperatorSymbolUnicode(QChar(0x2298)).addMathOperatorHtml("&osol;");
@ -703,7 +718,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["parallel"]=MathOperatorSymbolUnicode(QChar(0x2225)).addMathOperatorHtml("&shortparallel;").addMathOperatorStd("||");
symbols["pm"] = MathOperatorSymbol(QChar(0xB1), "&plusmn;").addMathOperatorWinSymbol(QChar(0xB1));
symbols["prec"]=MathOperatorSymbolUnicode(QChar(0x227A)).addMathOperatorHtml("&prec;");
symbols["prod"]=MathOperatorSymbolUnicode(QChar(0x220F)).addMathOperatorWinSymbol(QChar(0xD5), 1.8, 0.1).addMathOperatorHtml("&prod;");
symbols["prod"]=NarrowMathOperatorSymbolUnicode(QChar(0x220F)).addMathOperatorWinSymbol(QChar(0xD5), 1.8, 0.1).addMathOperatorHtml("&prod;").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["propto"]=MathOperatorSymbolUnicode(QChar(0x221D)).addMathOperatorWinSymbol(QChar(0xB5)).addMathOperatorHtml("&Proportional;");
symbols["rightharpoondown"]=UprightSymbolUnicode(QChar(0x21C1)).addUprightHtml("&rightharpoondown;");
symbols["rightharpoonup"]=UprightSymbolUnicode(QChar(0x21C0)).addUprightHtml("&RightVector;");
@ -720,7 +735,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["subseteq"]=MathOperatorSymbolUnicode(QChar(0x2286)).addMathOperatorHtml("&SubsetEqual;").addMathOperatorWinSymbol(QChar(0xCD));
symbols["subsetnot"]=MathOperatorSymbolUnicode(QChar(0x2284)).addMathOperatorHtml("&nsub;").addMathOperatorWinSymbol(QChar(0xCB));
symbols["succ"]=MathOperatorSymbolUnicode(QChar(0x227B)).addMathOperatorHtml("&succ;");
symbols["sum"]=MathOperatorSymbolUnicode(QChar(0x2211)).addMathOperatorWinSymbol(QChar(0xE5), 1.8, 0.1).addMathOperatorHtml("&sum;");
symbols["sum"]=NarrowMathOperatorSymbolUnicode(QChar(0x2211)).addMathOperatorWinSymbol(QChar(0xE5), 1.8, 0.1).addMathOperatorHtml("&sum;").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["supset"]=MathOperatorSymbolUnicode(QChar(0x2283)).addMathOperatorHtml("&sup;").addMathOperatorWinSymbol(QChar(0xC9));
symbols["supseteq"]=MathOperatorSymbolUnicode(QChar(0x2287)).addMathOperatorHtml("&SupersetEqual;").addMathOperatorWinSymbol(QChar(0xCA));
symbols["supsetnot"]=MathOperatorSymbolUnicode(QChar(0x2285)).addMathOperatorHtml("&nsup;");

View File

@ -83,6 +83,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
void getSymbolSize(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, double& subSuperXCorrection, double& subBesidesXCorrection, const JKQTMathTextNodeSize* prevNodeSize=nullptr);
/** \brief checks whether the given symbol name can be prepresented by this type of node */
static bool hasSymbol(const QString& symbolName);
/** \brief checks whether the given symbol name can be prepresented by this type of node */
static bool isSubSuperscriptBelowAboveSymbol(const QString& symbolName);
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
@ -126,8 +128,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
enum GlobalSymbolFlags: uint64_t {
NoGLobalSymbolFlags= 0, /*!< \brief indicates that no properties are activated */
ExtendWidthInMathmode= 1 << 0, /*!< \brief this symbol has an extended width, when used within a moth-environment/in math-mode */
MakeWhitespaceHalf= 1 << 1, /*!< \brief symbol uses whitespaces in its text (SymbolProps::symbol). These should be typeset as half-spaces */
IntLikeSymbolCorrection= 1 << 2, /*!< \brief symbols, like \c \\int,\\iint,... require a correction in x-direction for subsequent sub-/superscripts ... this flag marks such symbols */
SmallExtendWidthInMathmode= 1 << 1, /*!< \brief like ExtendWidthInMathmode but adds a smaller whitespace */
MakeWhitespaceHalf= 1 << 2, /*!< \brief symbol uses whitespaces in its text (SymbolProps::symbol). These should be typeset as half-spaces */
IntLikeSymbolCorrection= 1 << 3, /*!< \brief symbols, like \c \\int,\\iint,... require a correction in x-direction for subsequent sub-/superscripts ... this flag marks such symbols */
SubSuperscriptBelowAboveSymbol= 1 << 4, /*!< \brief symbols, like \c \\int,\\iint,... if appearing in math-mode cause typesetting following sub-/superscripts below/above the symbol, not besides it. */
};
friend inline GlobalSymbolFlags operator~ (GlobalSymbolFlags a) { return (GlobalSymbolFlags)~static_cast<uint64_t>(a); }
@ -271,6 +275,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
static SymbolFullProps UprightSymbolUnicode(const QString& symbol, const QString& html=QString());
/** \brief constructs a SymbolProps for a math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, ExtendWidthInMathmode */
static SymbolFullProps MathOperatorSymbolUnicode(const QString& unicode);
/** \brief constructs a SymbolProps for a math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, SmallExtendWidthInMathmode */
static SymbolFullProps NarrowMathOperatorSymbolUnicode(const QString& unicode);
/** \brief symbols that can be generated in any standard-font */