JKQTMathText: added support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but enlarged paramtheses

This commit is contained in:
jkriege2 2022-08-03 09:55:45 +02:00
parent 44c843b90e
commit c7ffdacfcc
18 changed files with 312 additions and 22 deletions

View File

@ -109,14 +109,25 @@
- \c \\left( \c \\right) : default meaning (), \image html jkqtmathtext/jkqtmathtext_brace_round.png - \c \\left( \c \\right) : default meaning (), \image html jkqtmathtext/jkqtmathtext_brace_round.png
- \c \\left[ \c \\right] : default meaning [], \image html jkqtmathtext/jkqtmathtext_brace_rect.png - \c \\left[ \c \\right] : default meaning [], \image html jkqtmathtext/jkqtmathtext_brace_rect.png
- \c \\left\\{ \c \\right\\} : default meaning {}, \image html jkqtmathtext/jkqtmathtext_brace_curly.png - \c \\left\\{ \c \\right\\} : default meaning {}, \image html jkqtmathtext/jkqtmathtext_brace_curly.png
- \c \\left< \c \\right> : "averaging" braces , \image html jkqtmathtext/jkqtmathtext_brace_tri.png - \c \\left\\langle \c \\right\\rangle : "averaging" braces , \image html jkqtmathtext/jkqtmathtext_brace_tri.png
- \c \\left\\lfloor \c \\right\\rfloor : floor braces , \image html jkqtmathtext/jkqtmathtext_brace_floor.png - \c \\left\\lfloor \c \\right\\rfloor : floor braces , \image html jkqtmathtext/jkqtmathtext_brace_floor.png
- \c \\left~ \c \\right~ \c \\left\\lceil \c \\right\\rceil : ceil braces , \image html jkqtmathtext/jkqtmathtext_brace_ceil.png - \c \\left\\lceil \c \\right\\rceil : ceil braces , \image html jkqtmathtext/jkqtmathtext_brace_ceil.png
- \c \\left| \c \\right| : absolute value braces | |, \image html jkqtmathtext/jkqtmathtext_brace_oneline.png - \c \\left| \c \\right| : absolute value braces | |, \image html jkqtmathtext/jkqtmathtext_bracejkqtmathtext_brace_ucorner_oneline.png
- \c \\left\\| \c \\right\\| \endcode : norm braces || ||, \image html jkqtmathtext/jkqtmathtext_brace_dblline.png - \c \\left\\| \c \\right\\| \endcode : norm braces || ||, \image html jkqtmathtext/jkqtmathtext_brace_dblline.png
- \c \\left\\llcorner \c \\right\\lrcorner : lower corner braces , \image html jkqtmathtext/jkqtmathtext_brace_lcorner.png
- \c \\left\\ulcorner \c \\right\\urcorner : upper corner braces , \image html jkqtmathtext/.png
- You can use \c \\left. or \c \\right. to have only right or only left brace - You can use \c \\left. or \c \\right. to have only right or only left brace
. .
In additional fixed-size parantheses are available with the following family of instructions:
- \c \\bigl([\\{\\langle... , \c \\big([\\{\\langle... and \c \\bigr)]\\}\\rangle... \image html jkqtmathtext/jkqtmathtext_brace_big.png
- \c \\Bigl([\\{\\langle... , \c \\Big([\\{\\langle... and \c \\Bigr)]\\}\\rangle... \image html jkqtmathtext/jkqtmathtext_brace_bbig.png
- \c \\biggl([\\{\\langle... , \c \\bigg([\\{\\langle... and \c \\biggr)]\\}\\rangle... \image html jkqtmathtext/jkqtmathtext_brace_bigg.png
- \c \\Biggl([\\{\\langle... , \c \\Bigg([\\{\\langle... and \c \\Biggr)]\\}\\rangle... \image html jkqtmathtext/jkqtmathtext_brace_bbigg.png
.
They use the same rendering code as the standard \c \\left and \c \\right instructions. Here is an example:
\image html jkqtmathtext/jkqtmathtext_brace_bigfamily.png generated by <code> $\Biggl\langle\biggl\{\Bigl[\bigl( r^{123}\bigr)\Bigr]\biggr\}\Biggr\rangle$</code>
\subsection JKQTMathTextSuppoertedLaTeXRoots Roots \subsection JKQTMathTextSuppoertedLaTeXRoots Roots
There are also instructions that allow to write roots: There are also instructions that allow to write roots:
- <code>$\\sqrt{1+\\sqrt{1+x}}$</code> \image html jkqtmathtext/jkqtmathtext_sqrt.png - <code>$\\sqrt{1+\\sqrt{1+x}}$</code> \image html jkqtmathtext/jkqtmathtext_sqrt.png

View File

@ -40,7 +40,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
</ul></li> </ul></li>
<li>JKQTMathText:<ul> <li>JKQTMathText:<ul>
<li>check sub/superscript with italic text in math mode, possibly a correction is necessary</li> <li>check sub/superscript with italic text in math mode, possibly a correction is necessary</li>
<li>add support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but large paramtheses</li>
<li>explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work</li> <li>explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work</li>
<li>maybe: add support for text with linebreaks by adding a JKQTMathTextVerticalListNode in addition to JKQTMathTextListNode</li> <li>maybe: add support for text with linebreaks by adding a JKQTMathTextVerticalListNode in addition to JKQTMathTextListNode</li>
<li>maybe: add tool programs to auto-generate some example images</li> <li>maybe: add tool programs to auto-generate some example images</li>

View File

@ -77,6 +77,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: added support for framed/shaded/snugshade-environments with linebreaks and framed</li> <li>NEW: added support for framed/shaded/snugshade-environments with linebreaks and framed</li>
<li>NEW: added support for -- and --- for en- and em-dashes</li> <li>NEW: added support for -- and --- for en- and em-dashes</li>
<li>NEW: added support for \c \\char"HEX , \c \\char'OCTAL and \c \\charDECIMAL for inserting any uicode character code</li> <li>NEW: added support for \c \\char"HEX , \c \\char'OCTAL and \c \\charDECIMAL for inserting any uicode character code</li>
<li>NEW: added support for \\bigl,\\bigr,\\Bigr,... commands for fixed-size but enlarged paramtheses</li>
</ul></li> </ul></li>
</ul> </ul>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

View File

@ -195,6 +195,7 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text/math: brace test: non-left/right top-corner", "text: \\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner -- math: $\\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner$"); ui->cmbTestset->addItem("text/math: brace test: non-left/right top-corner", "text: \\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner -- math: $\\ulcorner\\ulcorner\\ulcorner r^{123}\\urcorner\\urcorner\\urcorner$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right bottom-corner", "text: \\llcorner\\llcorner\\llcorner r^{123}\\lrcorner\\lrcorner\\lrcorner -- math: $\\llcorner\\llcorner\\llcorner r^{123}\\lrcorner\\lrcorner\\lrcorner$"); ui->cmbTestset->addItem("text/math: brace test: non-left/right bottom-corner", "text: \\llcorner\\llcorner\\llcorner r^{123}\\lrcorner\\lrcorner\\lrcorner -- math: $\\llcorner\\llcorner\\llcorner r^{123}\\lrcorner\\lrcorner\\lrcorner$");
ui->cmbTestset->addItem("text/math: brace test: non-left/right { | }", "text: \\{r^{123}|r\\equiv 5\\} -- math: $\\{r^{123}|r\\equiv 5\\}$"); ui->cmbTestset->addItem("text/math: brace test: non-left/right { | }", "text: \\{r^{123}|r\\equiv 5\\} -- math: $\\{r^{123}|r\\equiv 5\\}$");
ui->cmbTestset->addItem("math: brace test: bigl/Bigl/... mixed", "math: $\\Biggl\\langle\\biggl\\{\\Bigl[\\bigl(( r^{123})\\bigr)\\Bigr]\\biggr\\}\\Biggr\\rangle$");
ui->cmbTestset->addItem("text/math: sub-, superscript test", "text: r^{1234}_{321} r_{321}^{1234} -- math: $r^{1234}_{321} r_{321}^{1234} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); ui->cmbTestset->addItem("text/math: sub-, superscript test", "text: r^{1234}_{321} r_{321}^{1234} -- math: $r^{1234}_{321} r_{321}^{1234} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$");
ui->cmbTestset->addItem("text/math: super-, subscript test", "text: r^{123}_{4321} r_{4321}^{123} -- math: $r^{123}_{4321} r_{4321}^{123} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$"); ui->cmbTestset->addItem("text/math: super-, subscript test", "text: r^{123}_{4321} r_{4321}^{123} -- math: $r^{123}_{4321} r_{4321}^{123} -- \\kappa^2 -- \\kappa_2 -- \\kappa_2^2$");
//ui->cmbTestset->addItem("", ""); //ui->cmbTestset->addItem("", "");
@ -462,6 +463,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
JKQTMathTextFracNode* fracN=dynamic_cast<JKQTMathTextFracNode*>(node); JKQTMathTextFracNode* fracN=dynamic_cast<JKQTMathTextFracNode*>(node);
JKQTMathTextMatrixNode* matrixN=dynamic_cast<JKQTMathTextMatrixNode*>(node); JKQTMathTextMatrixNode* matrixN=dynamic_cast<JKQTMathTextMatrixNode*>(node);
JKQTMathTextDecoratedNode* decoN=dynamic_cast<JKQTMathTextDecoratedNode*>(node); JKQTMathTextDecoratedNode* decoN=dynamic_cast<JKQTMathTextDecoratedNode*>(node);
JKQTMathTextEmptyBoxNode* emptyN=dynamic_cast<JKQTMathTextEmptyBoxNode*>(node);
QTreeWidgetItem* ti=nullptr; QTreeWidgetItem* ti=nullptr;
if (parent) ti=new QTreeWidgetItem(parent); if (parent) ti=new QTreeWidgetItem(parent);
@ -527,6 +529,8 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
name=QString("WhitespaceNode :type=%1, count=%2").arg(spN->Type2String(spN->getWhitespaceType())).arg(spN->getWhitespaceCount()); name=QString("WhitespaceNode :type=%1, count=%2").arg(spN->Type2String(spN->getWhitespaceType())).arg(spN->getWhitespaceCount());
} else if (txtN) { } else if (txtN) {
name=QString("TextNode: \'%1\'").arg(txtN->getText()); name=QString("TextNode: \'%1\'").arg(txtN->getText());
} else if (emptyN) {
name=QString("EmptyBoxNode %1%2 x %3%4").arg(emptyN->getWidth()).arg(JKQTMathTextEmptyBoxNode::Units2String(emptyN->getWidthUnit())).arg(emptyN->getHeight()).arg(JKQTMathTextEmptyBoxNode::Units2String(emptyN->getHeightUnit()));
} else { } else {
name=QString("unknown"); name=QString("unknown");
} }

View File

@ -1008,8 +1008,10 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
auto fAddUml=[](const QString& cmd, const QChar& letter, const QChar& ch) { auto fAddUml=[](const QString& cmd, const QChar& letter, const QChar& ch) {
QString i; QString i;
if (cmd.size()>0 && !letter.isNull()) { if (cmd.size()>0 && !letter.isNull()) {
i="\\"+cmd+letter; if (cmd.size()==1 && !cmd[0].isLetter()) {
accentLetters[i]=ch; accentLetters_LenBackslash.insert(i.size()); i="\\"+cmd+letter;
accentLetters[i]=ch; accentLetters_LenBackslash.insert(i.size());
}
i="{\\"+cmd+letter+"}"; i="{\\"+cmd+letter+"}";
accentLetters[i]=ch; accentLetters_LenCurly.insert(i.size()); accentLetters[i]=ch; accentLetters_LenCurly.insert(i.size());
i="\\"+cmd+"{"+letter+"}"; i="\\"+cmd+"{"+letter+"}";
@ -1490,6 +1492,11 @@ JKQTMathText::tokenType JKQTMathText::getToken() {
return currentToken=MTTnone; return currentToken=MTTnone;
} }
void JKQTMathText::giveBackToTokenizer(size_t count)
{
currentTokenID-=count;
}
JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace, const QString& quitOnEnvironmentEnd, bool quitOnClosingBracket) { JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace, const QString& quitOnEnvironmentEnd, bool quitOnClosingBracket) {
//std::cout<<" entering parseLatexString()\n"; //std::cout<<" entering parseLatexString()\n";
JKQTMathTextHorizontalListNode* nl=new JKQTMathTextHorizontalListNode(this); JKQTMathTextHorizontalListNode* nl=new JKQTMathTextHorizontalListNode(this);
@ -1499,7 +1506,7 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
// initialize some static sets for easy and fast character lookup // initialize some static sets for easy and fast character lookup
static QSet<QString> mathEnvironmentSpecialText; static QSet<QString> mathEnvironmentSpecialText;
if (mathEnvironmentSpecialText.size()==0) { if (mathEnvironmentSpecialText.size()==0) {
mathEnvironmentSpecialText<<"+"<<"-"<<"="<<"*"<<"<"<<">"<<"|"<<"/"; mathEnvironmentSpecialText<<"+"<<"-"<<"="<<"*"<<"<"<<">";
} }
bool getNew=true; bool getNew=true;
@ -1769,6 +1776,28 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
} }
JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew) { JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew) {
static QHash<QString,double> big_instructions_family;
if (big_instructions_family.size()==0) {
big_instructions_family["big"]=0.85;//1.2;
big_instructions_family["bigl"]=0.85;//1.2;
big_instructions_family["bigm"]=0.85;//1.2;
big_instructions_family["bigr"]=0.85;//1.2;
big_instructions_family["Big"]=1.15;//1.85;
big_instructions_family["Bigl"]=1.15;//1.85;
big_instructions_family["Bigm"]=1.15;//1.85;
big_instructions_family["Bigr"]=1.15;//1.85;
big_instructions_family["bigg"]=1.45;//2.4;
big_instructions_family["biggl"]=1.45;//2.4;
big_instructions_family["biggm"]=1.45;//2.4;
big_instructions_family["biggr"]=1.45;//2.4;
big_instructions_family["Bigg"]=1.75;//3.1;
big_instructions_family["Biggl"]=1.75;//3.1;
big_instructions_family["Biggm"]=1.75;//3.1;
big_instructions_family["Biggr"]=1.75;//3.1;
}
if (currentToken!=MTTinstruction) { if (currentToken!=MTTinstruction) {
if (_foundError) *_foundError=true; if (_foundError) *_foundError=true;
if (getNew) *getNew=false; if (getNew) *getNew=false;
@ -1788,6 +1817,42 @@ JKQTMathTextNode* JKQTMathText::parseInstruction(bool *_foundError, bool* getNew
child->setSubSuperscriptAboveBelowNode(true); child->setSubSuperscriptAboveBelowNode(true);
} }
if (getNew) *getNew=true; if (getNew) *getNew=true;
} else if (big_instructions_family.contains(currentInstructionName)) {
// after \big,\bigl... we expect a symbol-instruction or at least one character of text
while (getToken()==MTTwhitespace);// eat whitespace
JKQTMathTextBraceType bracetype=MTBTUnknown;
bool openbrace=true;
if (currentToken==MTTinstruction) {
bracetype=TokenName2JKQTMathTextBraceType(currentTokenName, &openbrace);
} else if (currentToken==MTTtext) {
const QString firstTokenChar(currentTokenName[0]);
bracetype=TokenName2JKQTMathTextBraceType(firstTokenChar, &openbrace);
if (bracetype!=MTBTUnknown) {
giveBackToTokenizer(currentTokenName.size()-1);
} else {
giveBackToTokenizer(currentTokenName.size());
}
} else if (currentToken==MTTopenbracket) {
bracetype=MTBTSquareBracket;
openbrace=true;
} else if (currentToken==MTTclosebracket) {
bracetype=MTBTSquareBracket;
openbrace=false;
} else {
error_list.append(tr("error @ ch. %1: expected symbol-encoding instruction or a character after '\\%2' command, but found token type %3").arg(currentTokenID).arg(currentInstructionName).arg(tokenType2String(currentToken)));
}
if (bracetype!=MTBTUnknown) {
JKQTMathTextEmptyBoxNode* sizeChild=new JKQTMathTextEmptyBoxNode(this, 0, JKQTMathTextEmptyBoxNode::EBUem, big_instructions_family[currentInstructionName], JKQTMathTextEmptyBoxNode::EBUem);
if (openbrace) {
child=new JKQTMathTextBraceNode(this, bracetype, MTBTNone, sizeChild);
} else {
child=new JKQTMathTextBraceNode(this, MTBTNone, bracetype, sizeChild);
}
} else {
error_list.append(tr("error @ ch. %1: expected symbol-encoding instruction or character after '\\%2' command").arg(currentTokenID).arg(currentInstructionName));
}
if (getNew) *getNew=true;
} else if (JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(currentInstructionName)) { } else if (JKQTMathTextModifiedTextPropsInstructionNode::supportsInstructionName(currentInstructionName)) {
const size_t Nparams=JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(currentInstructionName); const size_t Nparams=JKQTMathTextModifiedTextPropsInstructionNode::countParametersOfInstruction(currentInstructionName);
bool foundError=false; bool foundError=false;
@ -2128,6 +2193,29 @@ JKQTMathTextNode *JKQTMathText::getNodeTree() const {
return parsedNode; return parsedNode;
} }
QString JKQTMathText::tokenType2String(tokenType type)
{
switch(type) {
case MTTnone: return "MTTnone";
case MTTtext: return "MTTtext";
case MTTinstruction: return "MTTinstruction";
case MTTinstructionNewline: return "MTTinstructionNewline";
case MTTunderscore: return "MTTunderscore";
case MTThat: return "MTThat";
case MTTdollar: return "MTTdollar";
case MTTopenbrace: return "MTTopenbrace";
case MTTclosebrace: return "MTTclosebrace";
case MTTopenbracket: return "MTTopenbracket";
case MTTclosebracket: return "MTTclosebracket";
case MTTwhitespace: return "MTTwhitespace";
case MTTampersand: return "MTTampersand";
case MTThyphen: return "MTThyphen";
case MTTendash: return "MTTendash";
case MTTemdash: return "MTTemdash";
}
return "???";
}

View File

@ -729,9 +729,13 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
MTTendash, /*!< \brief the en-dash character sequence \c "--" in text-mode */ MTTendash, /*!< \brief the en-dash character sequence \c "--" in text-mode */
MTTemdash, /*!< \brief the em-dash character sequence \c "---" in text-mode */ MTTemdash, /*!< \brief the em-dash character sequence \c "---" in text-mode */
}; };
/** \biref convert a tokenType into a string, e.g. for debugging output */
static QString tokenType2String(tokenType type);
/** \brief tokenizer for the LaTeX parser */ /** \brief tokenizer for the LaTeX parser */
tokenType getToken(); tokenType getToken();
/** \brief returns some characters to the Tokenizer */
void giveBackToTokenizer(size_t count);
/** \brief parse a LaTeX string /** \brief parse a LaTeX string
* *
* \param get if \c true this calls getToken() * \param get if \c true this calls getToken()

View File

@ -358,18 +358,29 @@ QString JKQTMathTextBraceType2String(JKQTMathTextBraceType type) {
return "???"; return "???";
} }
JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString &tokenName) JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString &tokenName, bool* isOpening)
{ {
if (tokenName=="(" || tokenName==")") return MTBTParenthesis; if (tokenName=="(") { if (isOpening) *isOpening=true; return MTBTParenthesis; }
if (tokenName=="[" || tokenName=="]") return MTBTSquareBracket; if (tokenName==")") { if (isOpening) *isOpening=false; return MTBTParenthesis; }
if (tokenName=="{" || tokenName=="}") return MTBTCurlyBracket; if (tokenName=="[") { if (isOpening) *isOpening=true; return MTBTSquareBracket; }
if (tokenName=="|") return MTBTSingleLine; if (tokenName=="]") { if (isOpening) *isOpening=false; return MTBTSquareBracket; }
if (tokenName=="||" || tokenName=="#") return MTBTDoubleLine; if (tokenName=="{") { if (isOpening) *isOpening=true; return MTBTCurlyBracket; }
if (tokenName=="<" || tokenName==">" || tokenName=="langle" || tokenName=="rangle") return MTBTAngleBracket; if (tokenName=="}") { if (isOpening) *isOpening=false; return MTBTCurlyBracket; }
if (tokenName=="_" || tokenName=="lfloor" || tokenName=="rfloor") return MTBTFloorBracket; if (tokenName=="|") { if (isOpening) *isOpening=true; return MTBTSingleLine; }
if (tokenName=="~" || tokenName=="lceil" || tokenName=="rceil") return MTBTCeilBracket; if (tokenName=="||" || tokenName=="#") { if (isOpening) *isOpening=true; return MTBTDoubleLine; }
if (tokenName=="ulcorner" || tokenName=="urcorner"||tokenName=="tlcorner" || tokenName=="trcorner") return MTBTTopCorner;
if (tokenName=="blcorner" || tokenName=="brcorner"||tokenName=="llcorner" || tokenName=="lrcorner") return MTBTBottomCorner; if (tokenName=="<" || tokenName=="langle") { if (isOpening) *isOpening=true; return MTBTAngleBracket; }
if (tokenName==">" || tokenName=="rangle") { if (isOpening) *isOpening=false; return MTBTAngleBracket; }
if (tokenName=="_" || tokenName=="lfloor") { if (isOpening) *isOpening=true; return MTBTFloorBracket; }
if (tokenName=="_" || tokenName=="rfloor") { if (isOpening) *isOpening=false; return MTBTFloorBracket; }
if (tokenName=="~" || tokenName=="lceil") { if (isOpening) *isOpening=true; return MTBTCeilBracket; }
if (tokenName=="~" || tokenName=="rceil") { if (isOpening) *isOpening=false; return MTBTCeilBracket; }
if (tokenName=="ulcorner" || tokenName=="tlcorner") { if (isOpening) *isOpening=true; return MTBTTopCorner; }
if (tokenName=="urcorner" || tokenName=="trcorner") { if (isOpening) *isOpening=false; return MTBTTopCorner; }
if (tokenName=="blcorner" || tokenName=="llcorner") { if (isOpening) *isOpening=true; return MTBTBottomCorner; }
if (tokenName=="brcorner" || tokenName=="lrcorner") { if (isOpening) *isOpening=false; return MTBTBottomCorner; }
if (isOpening) *isOpening=true;
if (tokenName=="any") return MTBTAny; if (tokenName=="any") return MTBTAny;
if (tokenName=="." || tokenName=="" || tokenName=="none") return MTBTNone; if (tokenName=="." || tokenName=="" || tokenName=="none") return MTBTNone;
return MTBTUnknown; return MTBTUnknown;

View File

@ -169,7 +169,7 @@ JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextBraceType2String(JKQTMathTextBraceTy
/** \brief convert a string \a tokenName describing a LaTeX Token or Instruction into an opening or closing JKQTMathTextBraceType /** \brief convert a string \a tokenName describing a LaTeX Token or Instruction into an opening or closing JKQTMathTextBraceType
* \ingroup jkqtmathtext_tools * \ingroup jkqtmathtext_tools
*/ */
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString& tokenName); JKQTMATHTEXT_LIB_EXPORT JKQTMathTextBraceType TokenName2JKQTMathTextBraceType(const QString& tokenName, bool *isOpening=nullptr);
/** \brief convert a string \a tokenName describing a LaTeX Instruction into an opening JKQTMathTextBraceType /** \brief convert a string \a tokenName describing a LaTeX Instruction into an opening JKQTMathTextBraceType
* \ingroup jkqtmathtext_tools * \ingroup jkqtmathtext_tools
* *

View File

@ -591,6 +591,32 @@ void JKQTMathTextModifiedTextPropsInstructionNode::fillInstructions()
}, 0); }, 0);
instructions["scriptscriptstyle"]= i; instructions["scriptscriptstyle"]= i;
} }
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.2;
}, 0);
instructions["bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*1.85;
}, 0);
instructions["Bigsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*2.4;
}, 0);
instructions["biggsize"]= i;
}
{
InstructionProperties i([](JKQTMathTextEnvironment& ev, const QStringList& /*parameters*/) {
ev.fontSize=ev.fontSize*3.1;
}, 0);
instructions["Biggsize"]= i;
}
} }
JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties(): JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::InstructionProperties():

View File

@ -102,8 +102,9 @@ size_t JKQTMathTextWhitespaceNode::getWhitespaceCount() const
return whitespace.count; return whitespace.count;
} }
double JKQTMathTextWhitespaceNode::draw(QPainter &painter, double x, double /*y*/, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize *prevNodeSize) double JKQTMathTextWhitespaceNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize *prevNodeSize)
{ {
doDrawBoxes(painter, x,y,currentEv);
double width=0, bh=0, oh=0, sp=0; double width=0, bh=0, oh=0, sp=0;
getSize(painter, currentEv, width, bh, oh, sp, prevNodeSize); getSize(painter, currentEv, width, bh, oh, sp, prevNodeSize);
return x+width; return x+width;
@ -215,3 +216,101 @@ QString JKQTMathTextWhitespaceNode::Type2HTML(Types type)
return " "; return " ";
} }
QString JKQTMathTextEmptyBoxNode::Units2String(Units type)
{
switch(type) {
case EBUem: return "em";
case EBUex: return "ex";
}
return "?";
}
JKQTMathTextEmptyBoxNode::Units JKQTMathTextEmptyBoxNode::String2Units(QString type)
{
type=type.toLower().trimmed();
if (type=="ex") return EBUex;
if (type=="em") return EBUem;
return EBUem;
}
double JKQTMathTextEmptyBoxNode::Units2PixelWidth(double value, Units unit, JKQTMathTextEnvironment currentEv, QPaintDevice *pd) const
{
const QFontMetricsF fm(currentEv.getFont(parentMathText), pd);
if (unit==EBUem) {
#if (QT_VERSION>=QT_VERSION_CHECK(5, 15, 0))
const double em=fm.horizontalAdvance(QChar(0x2003));//currentEv.fontSize;
#else
const double em=fm.width(QChar(0x2003));//currentEv.fontSize;
#endif
return value*em;
} else if (unit==EBUex) {
const double ex=fm.xHeight();
return value*ex;
}
return 0;
}
JKQTMathTextEmptyBoxNode::JKQTMathTextEmptyBoxNode(JKQTMathText *parent, double width_, Units widthUnit_, double height_, Units heightUnit_):
JKQTMathTextNode(parent),
width(width_), widthUnit(widthUnit_),
height(height_),heightUnit(heightUnit_)
{
}
JKQTMathTextEmptyBoxNode::~JKQTMathTextEmptyBoxNode()
{
}
QString JKQTMathTextEmptyBoxNode::getTypeName() const
{
return QString("JKQTMathTextEmptyBoxNode(%1%2 x %3%4)").arg(getWidth()).arg(JKQTMathTextEmptyBoxNode::Units2String(getWidthUnit())).arg(getHeight()).arg(JKQTMathTextEmptyBoxNode::Units2String(getHeightUnit()));
}
bool JKQTMathTextEmptyBoxNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv)
{
return true;
}
JKQTMathTextEmptyBoxNode::Units JKQTMathTextEmptyBoxNode::getWidthUnit() const
{
return widthUnit;
}
double JKQTMathTextEmptyBoxNode::getWidth() const
{
return width;
}
JKQTMathTextEmptyBoxNode::Units JKQTMathTextEmptyBoxNode::getHeightUnit() const
{
return heightUnit;
}
double JKQTMathTextEmptyBoxNode::getHeight() const
{
return height;
}
double JKQTMathTextEmptyBoxNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize *prevNodeSize)
{
doDrawBoxes(painter, x,y,currentEv);
double width=0, bh=0, oh=0, sp=0;
getSize(painter, currentEv, width, bh, oh, sp, prevNodeSize);
return x+width;
}
void JKQTMathTextEmptyBoxNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const JKQTMathTextNodeSize */*prevNodeSize*/)
{
const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
width=Units2PixelWidth(width, widthUnit, currentEv, painter.device());
overallHeight=Units2PixelWidth(height, heightUnit, currentEv, painter.device());
if (height>0) {
baselineHeight=overallHeight;
} else {
baselineHeight=0;
}
strikeoutPos=fm.strikeOutPos();
}

View File

@ -76,9 +76,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextWhitespaceNode: public JKQTMathTextNod
virtual QString getTypeName() const override; virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::toHtml() */ /** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override; virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override;
/** \brief copydoc WhitespaceProps::type */ /** \copydoc WhitespaceProps::type */
Types getWhitespaceType() const; Types getWhitespaceType() const;
/** \brief copydoc WhitespaceProps::count */ /** \copydoc WhitespaceProps::count */
size_t getWhitespaceCount() const; size_t getWhitespaceCount() const;
/** \copydoc JKQTMathTextNode::draw() */ /** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override; virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
@ -103,6 +103,53 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextWhitespaceNode: public JKQTMathTextNod
static void fillSupportedInstructions(); static void fillSupportedInstructions();
}; };
/** \brief subclass representing an empty bbox with defined width/height in the syntax tree
* \ingroup jkqtmathtext_items
*
*/
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextEmptyBoxNode: public JKQTMathTextNode {
public:
enum Units {
EBUem, /*!< \brief 1em = width('M') */
EBUex, /*!< \brief 1ex = xHeight */
};
/** \brief converts Types \a type into a string */
static QString Units2String(Units type);
/** \brief converts Types \a type into a string */
static Units String2Units(QString type);
/** \brief converts Types \a type into its width in pixels, based on \a currentEv and \a pd */
double Units2PixelWidth(double value, Units unit, JKQTMathTextEnvironment currentEv, QPaintDevice *pd) const;
/** \brief constructs a node */
explicit JKQTMathTextEmptyBoxNode(JKQTMathText* parent, double width_, Units widthUnit_, double height_, Units heightUnit_);
virtual ~JKQTMathTextEmptyBoxNode() override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::toHtml() */
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override;
/** \copydoc widthUnit */
Units getWidthUnit() const;
/** \copydoc width */
double getWidth() const;
/** \copydoc heightUnit */
Units getHeightUnit() const;
/** \copydoc height */
double getHeight() const;
/** \copydoc JKQTMathTextNode::draw() */
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \brief width of the (empty) box, units of this value defined in widthUnit */
double width;
/** \biref units to interpret width */
Units widthUnit;
/** \brief height of the (empty) box, units of this value defined in heightUnit */
double height;
/** \biref units to interpret height */
Units heightUnit;
};
#endif // JKQTMATHTEXTWHITESPACENODE_H #endif // JKQTMATHTEXTWHITESPACENODE_H