diff --git a/doc/dox/jkqtmathtext_supportedlatex.dox b/doc/dox/jkqtmathtext_supportedlatex.dox
index dc3dadd696..c6878213c5 100644
--- a/doc/dox/jkqtmathtext_supportedlatex.dox
+++ b/doc/dox/jkqtmathtext_supportedlatex.dox
@@ -184,12 +184,56 @@
.
+ \section JKQTMathTextSuppoertedLaTeXTabular Tabular Environments
+
+ \see Additional matrix-environments are listed in \ref
+
+ For text-mode tables, the \c tabular -environment is supported:
+ - $\\begin{tabular}{COLSPEC} a & b & ...\\\\ c & d & ...\\end{tabular}$
+ \c COLSPEC is a LaTeX column specifier, i.e. a sequence composed of these parts:
+ - \c l : left-aligned column
+ - \c c : centered column
+ - \c r : right-aligned column
+ - \c | : single line
+ - \c || : double line
+ - \c : : single dashed line
+ - \c :: : double dashed line
+ .
+ .
+ In all these environments, you can use the following instructions to draw lines above/below a row in the matrix:
+ - \c \\hline or \c \\midrule: a single line
+ - \c \\hline\\hline : a double line
+ - \c \\toprule or \c \\bottomrule : a heavy line
+ - \c \\hdashline : a single dashed line
+ - \c \\hdashline\\hdashline : a double dashed line
+ .
+
+ Here is an example:
+ \code
+ \begin{tabular}{:l|cr||}
+ \hdashline
+ a1--- & b1--- & c1---\\
+ a2- & b2- & c2-\\
+ \hline
+ a3 & b3 & c3\\
+ \hline\hline
+ a4 & b4 & c4\\
+ \bottomrule
+ \end{tabular}
+ \endcode
+
+ \image html jkqtmathtext/jkqtmathtext_tabular.png
+
+
\section JKQTMathTextSuppoertedLaTeXMathSupport Supported Mathematical Constructs
\subsection JKQTMathTextSuppoertedLaTeXSubSuper Sub- and Superscript
The standard LaTeX sub-/superscript instructions (i.e. \c text_{sub} or \c text^{super} ) are supported:
- - \c ^{...} \c _{...} : display the contents of braces in superscript/subscript \image html jkqtmathtext/jkqtmathtext_supersub.png
+ - \c ^{...} \c _{...} : display the contents of braces in superscript/subscript \image html jkqtmathtext/jkqtmathtext_supersub.png
Special subscript/superscript typesetting applies, when the sub/super follows \c \\sum \c \\Prod ...: \image html jkqtmathtext/jkqtmathtext_specialsubsuper.png
+ - $\\substack[lrc]{...\\\\...}$
allows to e.g. subset several lines below a \c \\sum using \c \\sum\\limits_\\substack{a<5\\\\b<100}: \image html jkqtmathtext/jkqtmathtext_substack.png
+ - \c \\limits , \c \\nolimits : Several special symbols, like \c \\sum , \c \\lim , ... cause sub-/superscripts to be positioned below/above the symbol, not besides it. This behaviour can be altered by using \c \\limits and \c \\nolimits : \image html jkqtmathtext/jkqtmathtext_limits.png
+
.
\subsection JKQTMathTextSuppoertedLaTeXBraces Braces/Parantheses ...
@@ -235,28 +279,48 @@
.
\subsection JKQTMathTextSuppoertedLaTeXFrac Fraction Type Instructions
- Several Matrix/Array-typed LaTeX instructions are supported:
+ Several fraction-typed LaTeX instructions are supported:
- $\\frac{...}{...}$
\image html jkqtmathtext/MTFMfrac.png
- $\\tfrac{...}{...}$
(70% smaller font) \image html jkqtmathtext/MTFMtfrac.png
- $\\dfrac{...}{...}$
\image html jkqtmathtext/MTFMdfrac.png
- $\\sfrac{...}{...}$
\image html jkqtmathtext/MTFMsfrac.png
- $\\stfrac{...}{...}$
(70% smaller font) \image html jkqtmathtext/MTFMstfrac.png
+ - $\\stackrel{...}{...}$ $\\binom{...}{...}$
\image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
.
\subsection JKQTMathTextSuppoertedLaTeXMatrix Matrix/Array Type Instructions
- Several Matrix/Array-typed LaTeX instructions are supported:
+ Simple instructions are:
- $\\stackrel{...}{...}$ $\\binom{...}{...}$
\image html jkqtmathtext/jkqtmathtext_brace_stackrel.png
+ .
+
+ Several Matrix/Array-typed LaTeX instructions are supported:
- $\\begin{cases} ... & ... \\\\ ... & ... \\end{cases}$
\image html jkqtmathtext/jkqtmathtext_brace_begincases.png
- - $\\begin{array} a & b & ...\\\\ c & d & ...\\end{array}$
$\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$
\image html jkqtmathtext/jkqtmathtext_array.png
+ - $\\begin{matrix} a & b & ...\\\\ c & d & ...\\end{matrix}$
\image html jkqtmathtext/jkqtmathtext_matrix.png
- $\\begin{pmatrix} a & b & ...\\\\ c & d & ...\\end{pmatrix}$
\image html jkqtmathtext/jkqtmathtext_pmatrix.png
- $\\begin{bmatrix} a & b & ...\\\\ c & d & ...\\end{bmatrix}$
\image html jkqtmathtext/jkqtmathtext_bmatrix.png
- $\\begin{Bmatrix} a & b & ...\\\\ c & d & ...\\end{Bmatrix}$
\image html jkqtmathtext/jkqtmathtext_bbmatrix.png
- $\\begin{vmatrix} a & b & ...\\\\ c & d & ...\\end{vmatrix}$
\image html jkqtmathtext/jkqtmathtext_vmatrix.png
- $\\begin{Vmatrix} a & b & ...\\\\ c & d & ...\\end{Vmatrix}$
\image html jkqtmathtext/jkqtmathtext_vvmatrix.png
- - $\\substack[lrc]{...\\\\...}$
\image html jkqtmathtext/jkqtmathtext_substack.png
- $\\lsubstack{...\\\\...}$
\image html jkqtmathtext/jkqtmathtext_lsubstack.png
- $\\rsubstack{...\\\\...}$
\image html jkqtmathtext/jkqtmathtext_rsubstack.png
- .
+ - $\\begin{array}{COLSPEC} a & b & ...\\\\ c & d & ...\\end{array}$
\image html jkqtmathtext/jkqtmathtext_array.png
+ \c COLSPEC is a LaTeX column specifier, i.e. a sequence composed of these parts:
+ - \c l : left-aligned column
+ - \c c : centered column
+ - \c r : right-aligned column
+ - \c | : single line
+ - \c || : double line
+ - \c : : single dashed line
+ - \c :: : double dashed line
+ .
+ .
+ In all these environments, you can use the following instructions to draw lines above/below a row in the matrix:
+ - \c \\hline or \c \\midrule: a single line
+ - \c \\hline\\hline : a double line
+ - \c \\toprule or \c \\bottomrule : a heavy line
+ - \c \\hdashline : a single dashed line
+ - \c \\hdashline\\hdashline : a double dashed line
+ .
diff --git a/doc/dox/todo.dox b/doc/dox/todo.dox
index a2bbc67751..f9c5ff7c22 100644
--- a/doc/dox/todo.dox
+++ b/doc/dox/todo.dox
@@ -41,7 +41,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
JKQTMathText:
- check sub/superscript with italic text in math mode, possibly a correction is necessary
- explore options to make font-environment-modifying commands avails, like "{blacktext\\color{red}redtext}", today only commands like "\\textcolor{red}{redtext}" work
- - improve support for array-environment with limited support for formatting string like l|r|c and maybe add support for \\hline command, possibly also \\cellcolor etz.
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 381d992b2d..485be8599c 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -89,6 +89,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: additional method JKQTMathtext::getSizeDetail() that returns all size-properties as a convenient struct, also added matching varinat JKQTMathTextNode::getSize()
NEW: additional method JKQTMathtext::drawIntoPixmap(), JKQTMathtext::drawIntoPicture(), JKQTMathtext::drawIntoImage() which returns a QPixmap, QPicture and QImage respectively that contains the render result of the currently parsed markup
NEW: added command line tool \ref JKQTMathTextRenderCmdLineTool that renders LaTeX into images, using it to generate the documentation images for JKQTMathText
+ NEW: array/tabular-environments have limited support for formatting string like \c l|r|c and for \c \\hline , \c \\hdashline , \c \\toprule , \c \\midrule , \c \\bottomrule
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_array.png b/doc/images/jkqtmathtext/jkqtmathtext_array.png
index 319b342508..e1b521453a 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_array.png and b/doc/images/jkqtmathtext/jkqtmathtext_array.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_bbmatrix.png b/doc/images/jkqtmathtext/jkqtmathtext_bbmatrix.png
index 7372fcaeb1..2c8cbbaee9 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_bbmatrix.png and b/doc/images/jkqtmathtext/jkqtmathtext_bbmatrix.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_bmatrix.png b/doc/images/jkqtmathtext/jkqtmathtext_bmatrix.png
index 256895bba7..892c5cba57 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_bmatrix.png and b/doc/images/jkqtmathtext/jkqtmathtext_bmatrix.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_brace_array.png b/doc/images/jkqtmathtext/jkqtmathtext_brace_array.png
deleted file mode 100644
index aa0ac052f4..0000000000
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_brace_array.png and /dev/null differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_brace_begincases.png b/doc/images/jkqtmathtext/jkqtmathtext_brace_begincases.png
index 39f7553cee..7f92792a27 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_brace_begincases.png and b/doc/images/jkqtmathtext/jkqtmathtext_brace_begincases.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_limits.png b/doc/images/jkqtmathtext/jkqtmathtext_limits.png
new file mode 100644
index 0000000000..c70e44e9a3
Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_limits.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_mathaccents.png b/doc/images/jkqtmathtext/jkqtmathtext_mathaccents.png
index 6aa260c21a..60061851a8 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_mathaccents.png and b/doc/images/jkqtmathtext/jkqtmathtext_mathaccents.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_mathmode_and_textmode.png b/doc/images/jkqtmathtext/jkqtmathtext_mathmode_and_textmode.png
index a03451802f..00e5b19bb5 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_mathmode_and_textmode.png and b/doc/images/jkqtmathtext/jkqtmathtext_mathmode_and_textmode.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_mathoperator_width_factor.png b/doc/images/jkqtmathtext/jkqtmathtext_mathoperator_width_factor.png
index f1c1ad7843..2478da921f 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_mathoperator_width_factor.png and b/doc/images/jkqtmathtext/jkqtmathtext_mathoperator_width_factor.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_matrix.png b/doc/images/jkqtmathtext/jkqtmathtext_matrix.png
new file mode 100644
index 0000000000..fb18ddf6c0
Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_matrix.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.cdr b/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.cdr
new file mode 100644
index 0000000000..b7541e26b4
Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.cdr differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.png b/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.png
new file mode 100644
index 0000000000..f1bc5b21be
Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_matrix_geometry.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_pmatrix.png b/doc/images/jkqtmathtext/jkqtmathtext_pmatrix.png
index 6f46d80328..06b3d71b29 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_pmatrix.png and b/doc/images/jkqtmathtext/jkqtmathtext_pmatrix.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_tabular.png b/doc/images/jkqtmathtext/jkqtmathtext_tabular.png
new file mode 100644
index 0000000000..74df993e32
Binary files /dev/null and b/doc/images/jkqtmathtext/jkqtmathtext_tabular.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_textaccents.png b/doc/images/jkqtmathtext/jkqtmathtext_textaccents.png
index 7bcb2b6830..8dec679b50 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_textaccents.png and b/doc/images/jkqtmathtext/jkqtmathtext_textaccents.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_vmatrix.png b/doc/images/jkqtmathtext/jkqtmathtext_vmatrix.png
index 4e4161371a..a799b1ee64 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_vmatrix.png and b/doc/images/jkqtmathtext/jkqtmathtext_vmatrix.png differ
diff --git a/doc/images/jkqtmathtext/jkqtmathtext_vvmatrix.png b/doc/images/jkqtmathtext/jkqtmathtext_vvmatrix.png
index 0af8d51253..3d9cd102e1 100644
Binary files a/doc/images/jkqtmathtext/jkqtmathtext_vvmatrix.png and b/doc/images/jkqtmathtext/jkqtmathtext_vvmatrix.png differ
diff --git a/doc/jkqtmathtext_docimages_accents.jkmt b/doc/jkqtmathtext_docimages_accents.jkmt
index 25b58952f2..bd686cfe71 100644
--- a/doc/jkqtmathtext_docimages_accents.jkmt
+++ b/doc/jkqtmathtext_docimages_accents.jkmt
@@ -84,7 +84,7 @@ jkqtmathtext_mathdeco.png
$\vec{x}\ \dot{x}\ \ddot{x}\ \overline{x}\ \underline{x}\ \hat{x}\ \tilde{x}\ \uul{x}\ \ool{x}\ \bar{x}\ \arrow{x}\ \widehat{x}\ \widetilde{x}\ ...$
---
jkqtmathtext_textaccents.png
-\begin{array}
+\begin{array}{llll}
{\backslash}"A: & \"A\"a & {\backslash}`A: & \`A\`a \\
{\backslash}'A: & \'A\'a &{\backslash}{\circonflex}A: & \^A\^a \\
{\backslash}{\sim}A: & \~A\~a &{\backslash}r\{A\}: & \r{A}\r{a} \\
@@ -96,7 +96,7 @@ jkqtmathtext_textaccents.png
\end{array}
---
jkqtmathtext_mathaccents.png
-\begin{array}
+\begin{array}{llll}
{\backslash}dot\{A\}: & $\dot{A}\dot{a}$ & {\backslash}ddot\{A\}: & $\ddot{A}\ddot{a}$ \\
{\backslash}grave\{A\}: & $\grave{A}\grave{a}$ & {\backslash}acute\{A\}: & $\acute{A}\acute{a}$ \\
{\backslash}acute\{A\}: & $\acute{A}\acute{a}$ & {\backslash}tilde\{A\}: & $\tilde{A}\tilde{a}$ \\
diff --git a/doc/jkqtmathtext_docimages_braces.jkmt b/doc/jkqtmathtext_docimages_braces.jkmt
index 6f5b019637..abb52884a3 100644
--- a/doc/jkqtmathtext_docimages_braces.jkmt
+++ b/doc/jkqtmathtext_docimages_braces.jkmt
@@ -1,7 +1,4 @@
---
-jkqtmathtext_brace_array.png
-$\left\langle\begin{array}a&b&...\\ c&d&...\end{array}\right\rangle$
----
jkqtmathtext_brace_bbig.png
$\Bigl[\Bigl(r^{123}\Bigr)\Bigr]$
---
diff --git a/doc/jkqtmathtext_docimages_math.jkmt b/doc/jkqtmathtext_docimages_math.jkmt
index 0967ffde39..da465cdba3 100644
--- a/doc/jkqtmathtext_docimages_math.jkmt
+++ b/doc/jkqtmathtext_docimages_math.jkmt
@@ -28,8 +28,11 @@ jkqtmathtext_substack.png
{\backslash}substack: $\sum\limits_\substack{0\leq i\leq10\\-5\leq j\leq1000}f_{i,j}$
---
jkqtmathtext_mathmode_and_textmode.png
-\begin{array}text: & abc123+d/e\\ math: & $abc123+d/e$\end{array}
+\begin{matrix}text: & abc123+d/e\\ math: & $abc123+d/e$\end{matrix}
---
jkqtmathtext_mathoperator_width_factor.png
--showboxes
-\begin{array}Math: $a=b$ & text: a=b\\\textcolor{blue}{extra space}&\textcolor{blue}{normal spacing}\end{array}
+\begin{matrix}Math: $a=b$ & text: a=b\\\textcolor{blue}{extra space}&\textcolor{blue}{normal spacing}\end{matrix}
+---
+jkqtmathtext_limits.png
+no specifier: $\sum_{i=0}^\infty k_i^2\ \ \lim_{x\rightarrow0}f(x)\ \ \nabla_{x}f(x)$ \ \ \ \ \ {\backslash}limits: $\sum\limits_{i=0}^\infty k_i^2\ \ \lim\limits_{x\rightarrow0}f(x)\ \ \nabla\limits_{x}f(x)$ \ \ \ \ \ {\backslash}nolimits: $\sum\nolimits_{i=0}^\infty k_i^2\ \ \lim\nolimits_{x\rightarrow0}f(x)\ \ \nabla\nolimits_{x}f(x)$
diff --git a/doc/jkqtmathtext_docimages_matrix.jkmt b/doc/jkqtmathtext_docimages_matrix.jkmt
index 28662c46aa..879df80e02 100644
--- a/doc/jkqtmathtext_docimages_matrix.jkmt
+++ b/doc/jkqtmathtext_docimages_matrix.jkmt
@@ -1,6 +1,6 @@
---
-jkqtmathtext_array.png
-$\begin{array}a&b&...\\ c&d&...\end{array}$
+jkqtmathtext_matrix.png
+$\mat{M}_1=\begin{matrix}a&b&...\\ c&d&...\end{matrix}\ \ \ \ \ \ \mat{M}_2=\left\langle\begin{matrix}a&b&...\\ c&d&...\end{matrix}\right\rangle$
---
jkqtmathtext_bmatrix.png
$\begin{bmatrix}a&b&...\\ c&d&...\end{bmatrix}$
@@ -18,4 +18,30 @@ jkqtmathtext_vvmatrix.png
$\begin{Vmatrix}a&b&...\\ c&d&...\end{Vmatrix}$
---
jkqtmathtext_brace_begincases.png
-$f(x)=\begin{cases}\sfrac{1}{2} & \text{if} 0\leq x\leq 1 \\ \sfrac{2}{3} & \text{if} 3\leq x\leq 4 \\ 0 & \text{elsewhere} \end{cases}$
+$f(x)=\begin{cases}\sfrac{1}{2} & \text{if}\ 0\leq x\leq 1 \\ \sfrac{2}{3} & \text{if}\ 3\leq x\leq 4 \\ 0 & \text{elsewhere} \end{cases}$
+---
+jkqtmathtext_tabular.png
+\begin{tabular}{:l|cr||}
+ \hdashline
+ a1--- & b1--- & c1---\\
+ a2- & b2- & c2-\\
+ \hline
+ a3 & b3 & c3\\
+ \hline\hline
+ a4 & b4 & c4\\
+ \bottomrule
+\end{tabular}
+---
+jkqtmathtext_array.png
+$\mat{M}_\cdot=\begin{array}{l:ll}
+ \alpha & a & \ldots \\
+ \hdashline
+ \beta & b & \ldots \\
+ \vdots & \vdots & \ddots \\
+\end{array}
+\ \ \ \ \ \mat{M}_{()}=\left(\begin{array}{l:ll}
+ \alpha & a & \ldots \\
+ \hdashline
+ \beta & b & \ldots \\
+ \vdots & \vdots & \ddots \\
+\end{array}\right)$
diff --git a/examples/jkqtmathtext_test/testform.cpp b/examples/jkqtmathtext_test/testform.cpp
index e9d984b104..e056c80f4d 100644
--- a/examples/jkqtmathtext_test/testform.cpp
+++ b/examples/jkqtmathtext_test/testform.cpp
@@ -97,6 +97,8 @@ TestForm::TestForm(QWidget *parent) :
ui->cmbTestset->addItem("text: framed", "\\begin{framed}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{framed}");
ui->cmbTestset->addItem("text: shaded", "\\begin{shaded}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{shaded}");
ui->cmbTestset->addItem("text: snugshade", "\\begin{snugshade}text\\\\\\textbf{2^{nd} line of text}\\\\last \\textit{line!} $\\frac{1}{2}$\\end{snugshade}");
+ ui->cmbTestset->addItem("text: tabular", "\\begin{tabular}{:l|cr||}\\hdashline a1--- & b1-- & c1---\\\\ a2-- & b2\\_ & c2\\_\\\\\\hline a3 & b3 & c3\\\\\\hline\\hline a4 & b4 & c4\\\\\\bottomrule\\end{tabular}");
+ ui->cmbTestset->addItem("math: array", "$\\mat{M}=\\left(\\begin{array}{l:ll} \\alpha & a & \\ldots \\\\ \\hdashline \\beta & b & \\ldots \\\\ \\vdots & \\vdots & \\ddots \\\\ \\end{array}\\right)$");
ui->cmbTestset->addItem("mathtest", "This is normal text: $this is math:\\langle r^2(\\tau)\\rangle=\\left\\langle (\\vec{r}(t)-\\vec{r}(t+\\tau) )^2\\right\\rangle\\ \\ \\ g(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1} \\lfloor\\rfloor\\lceil\\rceil\\langle\\rangle\\left\\{\\vec{a}\\left|\\|\\vec{a}\\|_2\\geq2\\right.\\right\\} \\vec{r}\\vec{R}\\frac{\\sqrt{\\sqrt{\\sqrt{\\sum_{i=0}^\\infty \\hat{i}^2}+y^\\alpha}+1}}{\\dot{v}\\equiv\\ddot{r}}\\argmin_{\\vec{k}}\\sum_{\\sqrt{i}=0}^{N}\\int_{x_0}^{x_1}\\left(\\left(\\left(x\\right)\\right)\\right)\\underbrace{\\left[\\left\\{\\frac{\\partial f}{\\partial x}\\right\\}\\cdot\\frac{1}{2}\\right]}{\\text{underbraced text \\hbar}}\\cdots\\frac{\\sqrt{\\sum_{i=0}^2 \\hat{i}^2}+y^\\alpha}{\\dot{v}\\equiv\\ddot{r}}, \\hat{t}\\hat{T} \\overbrace{\\left|\\sqrt{x\\cdot Y}\\right|}{\\propto\\bbN\\circ\\bbZ} \\left<\\arrow{x(\\tau)}\\cdot\\vec{R}(t+\\bar{\\tau})\\right> \\alpha\\beta\\gamma\\delta\\epsilon\\Gamma\\Delta\\Theta\\Omega \\left\\_\\left~\\cbrt{\\hbar\\omega}\\right~\\right\\_$");
ui->cmbTestset->addItem("math: upper/lower parantheses test:", "$\\text{bblabla} \\frac{1}{2}\\cdot\\left(\\frac{1}{\\mathrm{e}^x+\\mathrm{e}^{-x}}\\right)\\cdot\\left(\\frac{1}{\\frac{1+2}{5+x}}\\right)\\cdot\\left(\\frac{1}{\\exp\\left[-\\frac{y^2}{\\sqrt{x}}\\right]\\cdot\\exp\\left[-\\frac{1}{\\frac{1}{2}}\\right]}\\right) $");
ui->cmbTestset->addItem("math: ACF test", "$g_{rg}^{ab}(\\tau)=\\frac{1}{N}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-1}\\cdot\\left(1+\\frac{2}{3}\\frac{\\langle r^2(\\tau)\\rangle}{w_{xy}^2}\\right)^{-\\frac{1}{2}}$");
diff --git a/lib/jkqtmathtext/jkqtmathtext.cpp b/lib/jkqtmathtext/jkqtmathtext.cpp
index 96be8c4267..8d02cba2a2 100644
--- a/lib/jkqtmathtext/jkqtmathtext.cpp
+++ b/lib/jkqtmathtext/jkqtmathtext.cpp
@@ -99,6 +99,14 @@ JKQTMathText::JKQTMathText(QObject* parent):
sqrt_height_factor=1.2;
sqrt_smallfont_factor=0.57;
+ matrix_linewidth_thin_factor=0.4;
+ matrix_linewidth_heavy_factor=1.5;
+ matrix_line_separation_factor=2.0;
+ matrix_xSeparation_factor=0.5;
+ matrix_ySeparation_factor=0.5;
+ matrix_xPadding_factor=0.5;
+ matrix_yPadding_factor=0.5;
+
blackboradFontMode=MTBBDMdefault;
@@ -231,6 +239,13 @@ void JKQTMathText::loadSettings(const QSettings& settings, const QString& group)
bigmathoperator_font_factor=settings.value(group+"bigmathoperator_font_factor", bigmathoperator_font_factor).toDouble();
frac_nested_factor=settings.value(group+"frac_nested_factor", frac_nested_factor).toDouble();
+ matrix_linewidth_thin_factor=settings.value(group+"matrix_linewidth_thin_factor", matrix_linewidth_thin_factor).toDouble();
+ matrix_linewidth_heavy_factor=settings.value(group+"matrix_linewidth_heavy_factor", matrix_linewidth_heavy_factor).toDouble();
+ matrix_line_separation_factor=settings.value(group+"matrix_line_separation_factor", matrix_line_separation_factor).toDouble();
+ matrix_xSeparation_factor=settings.value(group+"matrix_xSeparation_factor", matrix_xSeparation_factor).toDouble();
+ matrix_ySeparation_factor=settings.value(group+"matrix_ySeparation_factor", matrix_ySeparation_factor).toDouble();
+ matrix_xPadding_factor=settings.value(group+"matrix_xPadding_factor", matrix_xPadding_factor).toDouble();
+ matrix_yPadding_factor=settings.value(group+"matrix_yPadding_factor", matrix_yPadding_factor).toDouble();
if (settings.value(group+"use_stix_fonts", false).toBool()) useSTIX();
if (settings.value(group+"use_xits_fonts", false).toBool()) useXITS();
@@ -272,6 +287,13 @@ void JKQTMathText::saveSettings(QSettings& settings, const QString& group) const
settings.setValue(group+ "sqrt_smallfont_factor", sqrt_smallfont_factor);
settings.setValue(group+ "bigmathoperator_font_factor", bigmathoperator_font_factor);
settings.setValue(group+ "frac_nested_factor", frac_nested_factor);
+ settings.setValue(group+ "matrix_linewidth_thin_factor", matrix_linewidth_thin_factor);
+ settings.setValue(group+ "matrix_linewidth_heavy_factor", matrix_linewidth_heavy_factor);
+ settings.setValue(group+ "matrix_line_separation_factor", matrix_line_separation_factor);
+ settings.setValue(group+ "matrix_xSeparation_factor", matrix_xSeparation_factor);
+ settings.setValue(group+ "matrix_ySeparation_factor", matrix_ySeparation_factor);
+ settings.setValue(group+ "matrix_xPadding_factor", matrix_xPadding_factor);
+ settings.setValue(group+ "matrix_yPadding_factor", matrix_yPadding_factor);
}
bool JKQTMathText::useSTIX(bool mathModeOnly) {
@@ -966,6 +988,76 @@ double JKQTMathText::getSqrtSmallFontFactor() const
return sqrt_smallfont_factor;
}
+double JKQTMathText::getMatrixLinewidthThinFactor()
+{
+ return matrix_linewidth_thin_factor;
+}
+
+void JKQTMathText::setMatrixLinewidthThinFactor(double factor)
+{
+ matrix_linewidth_thin_factor=factor;
+}
+
+double JKQTMathText::getMatrixLinewidthHeavyFactor()
+{
+ return matrix_linewidth_heavy_factor;
+}
+
+void JKQTMathText::setMatrixLinewidthHeavyFactor(double factor)
+{
+ matrix_linewidth_heavy_factor=factor;
+}
+
+double JKQTMathText::getMatrixLineSeparationFactor()
+{
+ return matrix_line_separation_factor;
+}
+
+void JKQTMathText::setMatrixLineSeparationFactor(double factor)
+{
+ matrix_line_separation_factor=factor;
+}
+
+double JKQTMathText::getMatrixXSeparationFactor()
+{
+ return matrix_xSeparation_factor;
+}
+
+void JKQTMathText::setMatrixXSeparationFactor(double factor)
+{
+ matrix_xSeparation_factor=factor;
+}
+
+double JKQTMathText::getMatrixYSeparationFactor()
+{
+ return matrix_ySeparation_factor;
+}
+
+void JKQTMathText::setMatrixYSeparationFactor(double factor)
+{
+ matrix_ySeparation_factor=factor;
+}
+
+double JKQTMathText::getMatrixXPaddingFactor()
+{
+ return matrix_xPadding_factor;
+}
+
+void JKQTMathText::setMatrixXPaddingFactor(double factor)
+{
+ matrix_xPadding_factor=factor;
+}
+
+double JKQTMathText::getMatrixYPaddingFactor()
+{
+ return matrix_yPadding_factor;
+}
+
+void JKQTMathText::setMatrixYPaddingFactor(double factor)
+{
+ matrix_yPadding_factor=factor;
+}
+
void JKQTMathText::setUseUnparsed(bool __value)
{
this->useUnparsed = __value;
@@ -1531,6 +1623,7 @@ void JKQTMathText::giveBackToTokenizer(size_t count)
}
JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace, const QString& quitOnEnvironmentEnd, bool quitOnClosingBracket) {
+ QMap countLine;
//std::cout<<" entering parseLatexString()\n";
JKQTMathTextHorizontalListNode* nl=new JKQTMathTextHorizontalListNode(this);
if (get) getToken();
@@ -1593,6 +1686,12 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(true);
} else if (currentInstructionName=="nolimits") {
if (nl->hasChildren()) nl->getLastChild()->setSubSuperscriptAboveBelowNode(false);
+ } else if (currentInstructionName=="hline" || currentInstructionName=="midrule") {
+ countLine["hline"]=countLine.value("hline",0)+1;
+ } else if (currentInstructionName=="hdashline") {
+ countLine["hdashline"]=countLine.value("hdashline",0)+1;
+ } else if (currentInstructionName=="toprule" || currentInstructionName=="bottomrule") {
+ countLine["heavyline"]=countLine.value("heavyline",0)+1;
} else if (currentInstructionName=="right") {
getToken();
if (currentToken==MTTtext) {
@@ -1717,34 +1816,89 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
} else if (currentToken==MTTinstructionBegin) {
const QString envname=currentTokenName;
- if (envname=="matrix" || envname=="array" || envname=="aligned" || envname=="align" || envname=="cases" || envname=="pmatrix"|| envname=="bmatrix"|| envname=="Bmatrix"|| envname=="vmatrix"|| envname=="Vmatrix") {
+ if (envname=="matrix" || envname=="array" || envname=="aligned" || envname=="align" || envname=="cases" || envname=="pmatrix"|| envname=="bmatrix"|| envname=="Bmatrix"|| envname=="vmatrix"|| envname=="Vmatrix" || envname=="tabular") {
+ QString colspec="";
+ if (envname=="tabular" || envname=="array") {
+ if (getToken()==MTTopenbrace) {
+ colspec=readUntil(true, "}");
+ } else {
+ error_list.append(tr("error @ ch. %1: expected {COLUMNSPEC} after '\\begin{%2}'").arg(currentTokenID).arg(envname));
+ }
+ }
+ JKQTMathTextMatrixNode* matrixNode=new JKQTMathTextMatrixNode(this, colspec);
QVector< QVector > items;
//int lines=0;
//int cols=0;
bool first=true;
+ bool firstLine=true;
QVector line;
+ size_t colCount=0;
//std::cout<<"found \\begin{matrix}\n";
while (first || currentToken==MTTampersand || currentToken==MTTinstructionNewline) {
- JKQTMathTextNode* it=parseLatexString(true, MTBTAny, envname);
+ while (getToken()==MTTwhitespace) ; // eat whitespace
+ JKQTMathTextNode* it=simplifyAndTrimJKQTMathTextNode(parseLatexString(false, MTBTAny, envname));
+ if (firstLine) {
+ if (lastLineCount.value("hline",0)==1) {
+ matrixNode->setTopLine(JKQTMathTextMatrixNode::LTline);
+ } else if (lastLineCount.value("hline",0)>1) {
+ matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdoubleline);
+ } else if (lastLineCount.value("heavyline",0)>0) {
+ matrixNode->setTopLine(JKQTMathTextMatrixNode::LTheavyline);
+ } else if (lastLineCount.value("hdashline",0)==1) {
+ matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdashed);
+ } else if (lastLineCount.value("hdashline",0)>1) {
+ matrixNode->setTopLine(JKQTMathTextMatrixNode::LTdoubleDashed);
+ }
+ } else {
+ if (lastLineCount.value("hline",0)==1) {
+ matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTline);
+ } else if (lastLineCount.value("hline",0)>1) {
+ matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdoubleline);
+ } else if (lastLineCount.value("heavyline",0)>0) {
+ matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTheavyline);
+ } else if (lastLineCount.value("hdashline",0)==1) {
+ matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdashed);
+ } else if (lastLineCount.value("hdashline",0)>1) {
+ matrixNode->setRowBottomLine(items.size()-1, JKQTMathTextMatrixNode::LTdoubleDashed);
+ }
+ }
if (currentToken==MTTampersand) {
//std::cout<<" appending item\n";
line.append(it);
} else {
- line.append(it);
//std::cout<<" appending item and line with "<(it);
+ if (mnc && mnc->childCount()>0) {
+ line.append(it);
+ } else {
+ line.append(it);
+ }
+ } else {
+ line.append(it);
+ }
+ if (currentToken==MTTinstructionNewline || line.size()>0) {
+ colCount=qMax(colCount, static_cast(line.size()));
+ if (line.size()==0 || (line.size()>1 && line.size()==colCount)) {
+ items.append(line);
+ } else if (line.size()>1 && line.size()!=colCount) {
+ error_list.append(tr("error @ ch. %1: wrong number of entries widthin '\\begin{%2}...\\end{%2}'").arg(currentTokenID).arg(envname));
+ }
+ }
line.clear();
+ firstLine=false;
}
first=false;
}
//std::cout<<" creating matrix-node with "<addChild(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, new JKQTMathTextMatrixNode(this, items)));
- else if (envname=="cases") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTNone, new JKQTMathTextMatrixNode(this, items)));
- else if (envname=="bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, new JKQTMathTextMatrixNode(this, items)));
- else if (envname=="Bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTCurlyBracket, new JKQTMathTextMatrixNode(this, items)));
- else if (envname=="vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSingleLine, MTBTSingleLine, new JKQTMathTextMatrixNode(this, items)));
- else if (envname=="Vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTDoubleLine, MTBTDoubleLine, new JKQTMathTextMatrixNode(this, items)));
- else nl->addChild(new JKQTMathTextMatrixNode(this, items));
+ matrixNode->setChildren(items);
+ if (envname=="pmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTParenthesis, MTBTParenthesis, matrixNode));
+ else if (envname=="cases") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTNone, matrixNode));
+ else if (envname=="bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSquareBracket, MTBTSquareBracket, matrixNode));
+ else if (envname=="Bmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTCurlyBracket, MTBTCurlyBracket, matrixNode));
+ else if (envname=="vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTSingleLine, MTBTSingleLine, matrixNode));
+ else if (envname=="Vmatrix") nl->addChild(new JKQTMathTextBraceNode(this, MTBTDoubleLine, MTBTDoubleLine, matrixNode));
+ else nl->addChild(matrixNode);
//std::cout<<" creating matrix-node ... done!\n";
} else if (envname=="center" || envname=="document" || envname=="flushleft" || envname=="flushright") {
JKQTMathTextHorizontalAlignment alignment=MTHALeft;
@@ -1795,6 +1949,8 @@ JKQTMathTextNode* JKQTMathText::parseLatexString(bool get, JKQTMathTextBraceType
if (getNew) getToken();
}
//std::cout<<" leaving parseLatexString()\n";
+ lastLineCount=countLine;
+
return simplifyJKQTMathTextNode(nl);
}
@@ -2126,6 +2282,8 @@ bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter){
currentToken=MTTnone;
currentTokenName="";
parsingMathEnvironment=false;
+ lastLineCount.clear();
+
error_list.clear();
parsedNode=parseLatexString(true);
unparsedNode=new JKQTMathTextVerbatimNode(this, text);
diff --git a/lib/jkqtmathtext/jkqtmathtext.h b/lib/jkqtmathtext/jkqtmathtext.h
index fec3314822..19ad678537 100644
--- a/lib/jkqtmathtext/jkqtmathtext.h
+++ b/lib/jkqtmathtext/jkqtmathtext.h
@@ -606,6 +606,35 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
/** \copydoc sqrt_smallfont_factor */
double getSqrtSmallFontFactor() const;
+ /** \copydoc matrix_linewidth_thin_factor */
+ double getMatrixLinewidthThinFactor();
+ /** \copydoc matrix_linewidth_thin_factor */
+ void setMatrixLinewidthThinFactor(double factor);
+ /** \copydoc matrix_linewidth_heavy_factor */
+ double getMatrixLinewidthHeavyFactor();
+ /** \copydoc matrix_linewidth_heavy_factor */
+ void setMatrixLinewidthHeavyFactor(double factor);
+ /** \copydoc matrix_line_separation_factor */
+ double getMatrixLineSeparationFactor();
+ /** \copydoc matrix_line_separation_factor */
+ void setMatrixLineSeparationFactor(double factor);
+ /** \copydoc matrix_xSeparation_factor */
+ double getMatrixXSeparationFactor();
+ /** \copydoc matrix_xSeparation_factor */
+ void setMatrixXSeparationFactor(double factor);
+ /** \copydoc matrix_ySeparation_factor */
+ double getMatrixYSeparationFactor();
+ /** \copydoc matrix_ySeparation_factor */
+ void setMatrixYSeparationFactor(double factor);
+ /** \copydoc matrix_xPadding_factor */
+ double getMatrixXPaddingFactor();
+ /** \copydoc matrix_xPadding_factor */
+ void setMatrixXPaddingFactor(double factor);
+ /** \copydoc matrix_yPadding_factor */
+ double getMatrixYPaddingFactor();
+ /** \copydoc matrix_yPadding_factor */
+ void setMatrixYPaddingFactor(double factor);
+
/** \copydoc useUnparsed */
@@ -798,6 +827,43 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
double sqrt_width_Xfactor;
/** \brief height-increase of the sqrt-symbol, as factor of the child's height */
double sqrt_height_factor;
+
+ /** \brief width of thin table lines, this factor is multiplied with the current \c font.linewidth()
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_linewidth_thin_factor;
+ /** \brief width of heavy table lines, this factor is multiplied with the current \c font.linewidth()
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_linewidth_heavy_factor;
+ /** \brief separation of double-lines in tables, this factor is multiplied with the \c font.linewidth()
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_line_separation_factor;
+ /** \brief x-separation of two columns, this factor is multiplied with the \c font.width("x")
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_xSeparation_factor;
+ /** \brief y-separation of two columns, this factor is multiplied with the \c font.width("x")
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_ySeparation_factor;
+ /** \brief x-padding of two columns, this factor is multiplied with the \c font.width("x")
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_xPadding_factor;
+ /** \brief y-padding of two columns, this factor is multiplied with the \c font.width("x")
+ *
+ * \image html jkqtmathtext/jkqtmathtext_matrix_geometry.png
+ */
+ double matrix_yPadding_factor;
+
/** \brief a list that will be filled with error messages while parsing, if any error occur
*
* This list of errors is (mostly) filled during a call to parse(). During rendering (e.g. with draw() )
@@ -891,6 +957,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
tokenType currentToken;
/** \brief the JKQTMathTextBraceType associated with the last \c \\right command the parser encountered */
JKQTMathTextBraceType lastRightBraceType;
+ /** \brief returns the number of \c \\hline , \c \\hdashline , ... commands in the last parseLatexString() call */
+ QMap lastLineCount;
/** \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 */
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
index c6817ec81f..7645fc1229 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextlistnode.cpp
@@ -553,6 +553,14 @@ void JKQTMathTextHorizontalListNode::clearChildren(bool deleteChildren)
clearChildrenImpl(deleteChildren);
}
+void JKQTMathTextHorizontalListNode::deleteChild(int i)
+{
+ if (i>=0 && i=0 && i > children):
- JKQTMathTextNode(_parent)
+JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, const QVector > &children, const QString &columnSpec):
+ JKQTMathTextNode(_parent),
+ verticalLineRHSColumn(),
+ verticalLineLeft(LTnone),
+ horizontalLineBottomRow(),
+ horizontalLineTop(LTnone),
+ columns(0),
+ lines(0)
{
- this->lines=children.size();
- this->columns=0;
- for (int i=0; ithis->columns) this->columns=children[i].size();
- }
- this->children=children;
- for (int i=0; isetParentNode(this);
- }
- }
+ setChildren(children);
+ parseColumnSpec(columnSpec);
+}
+
+JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText *_parent, const QString &columnSpec):
+ JKQTMathTextNode(_parent),
+ verticalLineRHSColumn(),
+ verticalLineLeft(LTnone),
+ horizontalLineBottomRow(),
+ horizontalLineTop(LTnone),
+ columns(0),
+ lines(0)
+{
+ parseColumnSpec(columnSpec);
}
JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() {
@@ -63,113 +72,36 @@ JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() {
children.clear();
}
+void JKQTMathTextMatrixNode::setChildren(const QVector > &children)
+{
+ this->lines=children.size();
+ this->columns=0;
+ for (int i=0; ithis->columns) this->columns=children[i].size();
+ }
+ this->children=children;
+ for (int i=0; isetParentNode(this);
+ }
+ }
+}
+
+void JKQTMathTextMatrixNode::setRowBottomLine(int col, LineType line)
+{
+ horizontalLineBottomRow[col]=line;
+}
+
+void JKQTMathTextMatrixNode::setTopLine(LineType line)
+{
+ horizontalLineTop=line;
+}
+
QString JKQTMathTextMatrixNode::getTypeName() const
{
return "MTmatrixNode";
}
-void JKQTMathTextMatrixNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
- QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
- JKQTMathTextEnvironment ev1=currentEv;
-
- double xh=fm.strikeOutPos();//fm.xHeight();
- //double Ah=fm.ascent();
- double xw=fm.boundingRect("x").width();
-
- //ev1.fontSize=ev1.fontSize*parent->getFracFactor();
-
-
- QVector colwidth, rowheight;
- //QVector > widths, heights, baselines;
-
- double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos1=0;
- //widths.resize(lines);
- colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos1);
- /*widths[i].operator[](j)=width1;
- baselines[i].operator[](j)=baselineHeight;
- heights[i].operator[](j)=overallHeight1;*/
- if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1;
- if (width1>colwidth[j]) colwidth[j]=width1;
- }
- }
-
-
- overallHeight=(lines-1)*xw/2.0;
- width=columns*xw;
- for (int i=0; igetFracFactor();
-
-
- QVector colwidth, rowheight, rowascent;
- //QVector > widths, heights, baselines;
-
- double width1=0, baselineHeight1=0, overallHeight1=0, strikeoutPos=0;
- //widths.resize(lines);
- colwidth.resize(columns); for (int i=0; igetSize(painter, ev1, width1, baselineHeight1, overallHeight1, strikeoutPos);
- /*widths[i].operator[](j)=width1;
- baselines[i].operator[](j)=baselineHeight;
- heights[i].operator[](j)=overallHeight1;*/
- if (overallHeight1>rowheight[i]) rowheight[i]=overallHeight1;
- if (baselineHeight1>rowascent[i]) rowascent[i]=baselineHeight1;
- if (width1>colwidth[j]) colwidth[j]=width1;
- }
- }
-
- double overallHeight=(lines-1)*xw/2.0;
- double width=(columns)*xw;
- for (int i=0; i0) yy=yy+rowascent[0];
- for (int i=0; idraw(painter, xx, yy, ev1);
- xx=xx+colwidth[j]+xw;
- }
-
- if (ilines;
}
+
void JKQTMathTextMatrixNode::setDrawBoxes(bool draw)
{
this->drawBoxes=draw;
@@ -199,5 +132,204 @@ void JKQTMathTextMatrixNode::setDrawBoxes(bool draw)
}
+void JKQTMathTextMatrixNode::drawVLine(QPainter &painter, double x, double y, double height, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation)
+{
+ if (lt==LTnone) return;
+ QPen p(color, linewidth, Qt::SolidLine);
+ if (lt==LTdashed || lt==LTdoubleDashed) p.setStyle(Qt::DashLine);
+ if (lt==LTheavyline) p.setWidth(linewidthHeavy);
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ painter.setPen(p);
+ if (lt==LTline || lt==LTdashed || lt==LTheavyline) {
+ painter.drawLine(QPointF(x,y), QPointF(x,y+height));
+ } else if (lt==LTdoubleline || lt==LTdoubleDashed) {
+ painter.drawLine(QPointF(x-doublelineseparation/2.0,y), QPointF(x-doublelineseparation/2.0,y+height));
+ painter.drawLine(QPointF(x+doublelineseparation/2.0,y), QPointF(x+doublelineseparation/2.0,y+height));
+ }
+}
+
+void JKQTMathTextMatrixNode::drawHLine(QPainter &painter, double x, double y, double width, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation)
+{
+ if (lt==LTnone) return;
+ QPen p(color, linewidth, Qt::SolidLine);
+ if (lt==LTdashed || lt==LTdoubleDashed) p.setStyle(Qt::DashLine);
+ if (lt==LTheavyline) p.setWidth(linewidthHeavy);
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ painter.setPen(p);
+ if (lt==LTline || lt==LTdashed || lt==LTheavyline) {
+ painter.drawLine(QPointF(x,y), QPointF(x+width,y));
+ } else if (lt==LTdoubleline || lt==LTdoubleDashed) {
+ painter.drawLine(QPointF(x,y-doublelineseparation/2.0), QPointF(x+width,y-doublelineseparation/2.0));
+ painter.drawLine(QPointF(x,y+doublelineseparation/2.0), QPointF(x+width,y+doublelineseparation/2.0));
+ }
+}
+
+void JKQTMathTextMatrixNode::parseColumnSpec(const QString &columnSpec)
+{
+ int i=0;
+ while (iaddToErrorList(QString("array spec has unknown character '%1' (full spec was '%2')").arg(columnSpec[i]).arg(columnSpec));
+ }
+ i++;
+ }
+}
+
+
+JKQTMathTextMatrixNode::LayoutInfo::LayoutInfo():
+ JKQTMathTextNodeSize(), colwidth(), rowheight()
+{
+
+}
+
+JKQTMathTextMatrixNode::LayoutInfo JKQTMathTextMatrixNode::calcLayout(QPainter &painter, const JKQTMathTextEnvironment ¤tEv) const
+{
+ LayoutInfo l;
+
+ const QFontMetricsF fm(currentEv.getFont(parentMathText), painter.device());
+ JKQTMathTextEnvironment ev1=currentEv;
+
+ const double xheight=fm.strikeOutPos();
+ const double xwidth=fm.boundingRect("x").width();
+ const double XPadding=parentMathText->getMatrixXPaddingFactor()*xwidth;
+ const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
+ const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
+ const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
+
+ l.colwidth.resize(columns); for (int i=0; i(columns, 0.0);
+ QVector rowdescent;
+ rowdescent.resize(lines);
+ for (int i=0; igetSize(painter, ev1);
+ l.cellwidth[i].operator[](j)=cs.width;
+ l.colwidth[j]=qMax(l.colwidth[j], cs.width);
+ l.rowascent[i]=qMax(l.rowascent[i], cs.baselineHeight);
+ rowdescent[i]=qMax(rowdescent[i], cs.getDescent());
+ }
+ l.rowheight[i]=l.rowascent[i]+rowdescent[i];
+ }
+
+
+ l.overallHeight=(lines-1)*YSeparation+l.topPadding+l.bottomPadding;
+ l.width=(columns-1)*XSeparation+l.leftPadding+l.rightPadding;
+ for (int i=0; igetMatrixXPaddingFactor()*xwidth;
+ //const double YPadding=parentMathText->getMatrixYPaddingFactor()*xwidth;
+ const double XSeparation=parentMathText->getMatrixXSeparationFactor()*xwidth;
+ const double YSeparation=parentMathText->getMatrixYSeparationFactor()*xwidth;
+ const double yTop=y-l.baselineHeight+l.topPadding;
+ const double xLeft=x+l.leftPadding;
+ const double linewidth=parentMathText->getMatrixLinewidthThinFactor()*fm.lineWidth();
+ const double linewidthThick=parentMathText->getMatrixLinewidthHeavyFactor()*fm.lineWidth();
+ const double lineSeparation=parentMathText->getMatrixLineSeparationFactor()*fm.lineWidth();
+ double leftlineX=xLeft-l.leftPadding/2.0;
+ double rightlineX=x+l.width-l.rightPadding/2.0;
+ double toplineY=yTop-l.topPadding/2.0;
+ double bottomlineY=y+l.getDescent()-l.bottomPadding/2;
+ if (verticalLineLeft==LTdoubleline || verticalLineLeft==LTdoubleDashed) leftlineX-=linewidth;
+ if (horizontalLineTop==LTdoubleline || horizontalLineTop==LTdoubleDashed) toplineY-=linewidth;
+ if (verticalLineRHSColumn.value(lines-1, LTnone)==LTdoubleline || verticalLineRHSColumn.value(lines-1, LTnone)==LTdoubleDashed) rightlineX+=linewidth;
+ if (horizontalLineBottomRow.value(columns-1, LTnone)==LTdoubleline || horizontalLineBottomRow.value(columns-1, LTnone)==LTdoubleDashed) bottomlineY+=linewidth;
+
+
+
+ double xx;
+ double yy=yTop;
+ if (lines>0) yy=yy+l.rowascent[0];
+ for (int i=0; idraw(painter, xx+xoffset, yy, ev1);
+ xx=xx+l.colwidth[j]+XSeparation;
+ if (i==0 && j > children);
+ /** \brief types of lines */
+ enum LineType {
+ LTnone, /*!< \brief noline */
+ LTline, /*!< \brief single line */
+ LTdoubleline, /*!< \brief double line */
+ LTheavyline, /*!< \brief heavier/thick line */
+ LTdashed, /*!< \brief single dashed line */
+ LTdoubleDashed, /*!< \brief double dashed line */
+ LTdefault=LTnone
+ };
+ JKQTMathTextMatrixNode(JKQTMathText* parent, const QVector >& children, const QString& columnSpec=QString());
+ JKQTMathTextMatrixNode(JKQTMathText* parent, const QString& columnSpec=QString());
virtual ~JKQTMathTextMatrixNode() override;
+ /** \brief sets the child nodes */
+ void setChildren(const QVector >& children);
+ /** \copydoc horizontalLineBottomRow */
+ void setRowBottomLine(int col, LineType line);
+ /** \copydoc horizontalLineTop */
+ void setTopLine(LineType line);
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override;
/** \copydoc JKQTMathTextNode::draw() */
@@ -52,16 +78,63 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
/** \copydoc lines */
int getLines() const;
protected:
+ /** \brief describes the layout of the whole node */
+ struct LayoutInfo: public JKQTMathTextNodeSize {
+ LayoutInfo();
+ /** \brief widths of the columns */
+ QVector colwidth;
+ /** \brief widths of the cells */
+ QVector > cellwidth;
+ inline double& getCellwidth(int line, int col) {
+ return cellwidth[line].operator[](col);
+ }
+ inline const double& getCellwidth(int line, int col) const {
+ return cellwidth[line].operator[](col);
+ }
+ /** \brief heights of the rows */
+ QVector rowheight;
+ /** \brief ascents of the rows */
+ QVector rowascent;
+ double leftPadding;
+ double rightPadding;
+ double topPadding;
+ double bottomPadding;
+
+ };
+ /** \brief calclates the layout of the whole block/node
+ *
+ * \note This function does NOT call transformEnvironment();
+ * it has to be called before calling this!
+ */
+ LayoutInfo calcLayout(QPainter& painter, const JKQTMathTextEnvironment& currentEv) const;
/** \copydoc JKQTMathTextNode::getSizeInternal() */
virtual void getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \copydoc JKQTMathTextNode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
/** \brief child nodes making up the matrix, vector of rows */
QVector > children;
+ /** \brief alignment of the columns */
+ QVector columnAlignment;
+ /** \brief lines to the right of each column */
+ QMap verticalLineRHSColumn;
+ /** \brief line at the left of the table */
+ LineType verticalLineLeft;
+ /** \brief lines to the bottom of each row */
+ QMap horizontalLineBottomRow;
+ /** \brief line at the top of the table */
+ LineType horizontalLineTop;
+
/** \brief number of columns in the matrix */
int columns;
/** \brief number of rows in the matrix */
int lines;
+
+ /** \brief draw a vertical line starting at pixel position (\a x, \a y ) with length \a height, using linetype \a lt, width \a linewidth and \a color */
+ static void drawVLine(QPainter& painter, double x, double y, double height, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation);
+ /** \brief draw a horizontal line starting at pixel position (\a x, \a y ) with length \a width, using linetype \a lt, width \a linewidth and \a color */
+ static void drawHLine(QPainter& painter, double x, double y, double width, LineType lt, double linewidth, double linewidthHeavy, QColor color, double doublelineseparation);
+ /** \brief parses a column specifier */
+ void parseColumnSpec(const QString& columnspec);
};
#endif // JKQTMATHTEXTMATRIXNODE_H
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp
index 1fd9fdfb9d..15d92b53bb 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.cpp
@@ -285,6 +285,18 @@ void JKQTMathTextDualChildNode::clearChildren(bool deleteChildren)
if (deleteChildren&&c2) delete c2;
}
+void JKQTMathTextDualChildNode::deleteChild(int i)
+{
+ if (child1&&i==0) {
+ delete child1;
+ child1=nullptr;
+ }
+ if (child2&&i==1) {
+ delete child2;
+ child2=nullptr;
+ }
+}
+
JKQTMathTextMultiChildNode::JKQTMathTextMultiChildNode(JKQTMathText *parentMathText):
JKQTMathTextNode(parentMathText)
{
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h
index b80b7ed0f1..c07e98bd11 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextnode.h
@@ -232,6 +232,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMultiChildNode: public JKQTMathTextNod
/** \brief clear all children, deleting them if \a deleteChildren==true */
virtual void clearChildren(bool deleteChildren=true) =0;
+ /** \brief delete the i-th child */
+ virtual void deleteChild(int i) =0;
/** \copydoc JKQTMathTextNode::setDrawBoxes() */
virtual void setDrawBoxes(bool draw) override;
@@ -266,6 +268,9 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDualChildNode: public JKQTMathTextMult
virtual int childCount() const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual void clearChildren(bool deleteChildren=true) override;
+ /** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
+ virtual void deleteChild(int i) override;
+
protected:
/** \brief first child node of this node */
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp
index 9bc5d6f0a8..fb0706c29d 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.cpp
@@ -21,6 +21,8 @@
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
#include "jkqtmathtext/nodes/jkqtmathtextlistnode.h"
+#include "jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h"
+#include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
#include "jkqtmathtext/jkqtmathtexttools.h"
#include "jkqtmathtext/jkqtmathtext.h"
#include
@@ -65,3 +67,42 @@ JKQTMathTextNode *simplifyJKQTMathTextNode(JKQTMathTextNode *node)
}
return node;
}
+
+JKQTMathTextNode *simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode *node)
+{
+ auto cleanText=[](JKQTMathTextNode* t) {
+ JKQTMathTextMultiChildNode* nmc=dynamic_cast(t);
+ JKQTMathTextNode* tt0=(nmc&&nmc->childCount()>0)?nmc->getFirstChild():t;
+ JKQTMathTextNode* tt1=(nmc&&nmc->childCount()>0)?nmc->getLastChild():t;
+ JKQTMathTextTextNode* txt0=dynamic_cast(tt0);
+ if (txt0) {
+ txt0->removeLeadingWhitespace();
+ }
+ JKQTMathTextTextNode* txt1=dynamic_cast(tt1);
+ if (txt1) {
+ txt1->removeTrailingWhitespace();
+ }
+ };
+ JKQTMathTextNode* t=node;
+ for (int iter=0; iter<3; iter++) {
+ t=simplifyJKQTMathTextNode(t);
+ JKQTMathTextMultiChildNode* nmc=dynamic_cast(t);
+ if (nmc && nmc->childCount()>0) {
+ bool done=false;
+ cleanText(nmc);
+ while (!done && nmc->childCount()>0) {
+ JKQTMathTextWhitespaceNode* ws0=dynamic_cast(nmc->getFirstChild());
+ JKQTMathTextWhitespaceNode* ws1=dynamic_cast(nmc->getLastChild());
+ if (ws0 && ws0->getWhitespaceType()==JKQTMathTextWhitespaceNode::WSTNormal) {
+ nmc->deleteChild(0);
+ } else if (ws1 && ws1->getWhitespaceType()==JKQTMathTextWhitespaceNode::WSTNormal) {
+ nmc->deleteChild(nmc->childCount()-1);
+ } else {
+ done=true;
+ }
+ }
+ }
+ cleanText(t);
+ }
+ return t;
+}
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.h b/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.h
index eafc409cb1..3ea902703d 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextnodetools.h
@@ -37,6 +37,13 @@ class JKQTMathTextNode; // forward
*/
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyJKQTMathTextNode(JKQTMathTextNode* node);
+/** \brief calls simplifyJKQTMathTextNode(). In addition it tries to clear whitespace at the start and end of the tree
+ * \ingroup jkqtmathtext_items
+ *
+ * \see simplifyJKQTMathTextNode()
+ */
+JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode* node);
+
#endif // JKQTMATHTEXTNODETOOLS_H
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
index 602e890e81..e9d895997b 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.cpp
@@ -227,3 +227,15 @@ void JKQTMathTextSqrtNode::clearChildren(bool deleteChildren)
}
}
+void JKQTMathTextSqrtNode::deleteChild(int i)
+{
+ if (child && i==0) {
+ delete child;
+ child=nullptr;
+ }
+ if (childDegree && i==1) {
+ delete childDegree;
+ childDegree=nullptr;
+ }
+}
+
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
index 52948eddd1..42468d548d 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsqrtnode.h
@@ -70,6 +70,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSqrtNode: public JKQTMathTextMultiChil
virtual int childCount() const override;
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
virtual void clearChildren(bool deleteChildren=true) override;
+ /** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
+ virtual void deleteChild(int i) override;
protected:
/** \copydoc JKQTMathTextNode::getSizeInternal() */
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp
index 5a4aec5cb2..bdc9d811fa 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.cpp
@@ -376,6 +376,16 @@ JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::MathOperatorText
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::NarrowMathOperatorText(const QString &op)
+{
+ return NarrowMathOperatorText(op, op);
+}
+
+JKQTMathTextSymbolNode::SymbolFullProps JKQTMathTextSymbolNode::NarrowMathOperatorText(const QString &op, const QString &ophtml)
+{
+ return SymbolFullProps(SymbolProps(op, ItalicOff|BoldOff|HeightIsAscent, 1.0, 0.0)).addGlobalFlags(SmallExtendWidthInMathmode|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)).addGlobalFlags(ExtendWidthInMathmode|MakeWhitespaceHalf);
@@ -532,7 +542,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["brcorner"]=s; symbols["lrcorner"]=s; }
{ auto s=UprightSymbolUnicode(QChar(0x2022)).addUprightHtml("•").addUprightWinSymbol(QChar(0xB7));
symbols["bullet"]=s; symbols["textbullet"]=s; }
- symbols["cdots"]=UnicodeSymbol(QChar(0x22EF)).addHtml("···").addStd(QString(3, QChar(0xB7)));
+ symbols["cdots"]=UprightSymbolUnicode(QChar(0x22EF)).addHtml("···").addStd(QString(3, QChar(0xB7)));
{ auto s=UnicodeSymbol(QChar(0x2103)).addUprightStd("°C").addUprightHtml("°C");
symbols["celsius"]=s; symbols["degC"]=s; symbols["degreeCelsius"]=s; }
symbols["ell"]=UprightSymbolUnicode(QChar(0x2113), "ℓ");
@@ -583,8 +593,6 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["infty"]=UnicodeSymbol(QChar(0x221E)).addHtml("∞").addWinSymbol(QChar(0xA5)).addStd("8", RotateSymbol90);
symbols["langle"]=UprightSymbolUnicode(QChar(0x2329)).addWinSymbol(QChar(0xE1));
symbols["lceil"]=UprightSymbolUnicode(QChar(0x2308)).addHtml("⌈").addWinSymbol(QChar(0xE9));
- { auto s=SimpleTextSymbol("...").addUnicode(QChar(0x2026)).addWinSymbol(QChar(0xB6));
- symbols["ldots"]=s; symbols["dots"]=s; }
symbols["lfloor"]=UprightSymbolUnicode(QChar(0x230A)).addHtml("⌊").addWinSymbol(QChar(0xEB));
symbols["lightning"]=UnicodeSymbol(QChar(0x21AF));
symbols["male"]=UnicodeSymbol(QChar(0x2642)).addHtml("♂");
@@ -642,46 +650,46 @@ 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").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- symbols["argmax"] = MathOperatorText("arg max", "arg max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- symbols["argmin"] = MathOperatorText("arg min", "arg min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- 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").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- symbols["liminf"] = MathOperatorText("lim inf", "lim inf").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- symbols["limsup"] = MathOperatorText("lim sup", "lim sup").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
- 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["Pr"] = NarrowMathOperatorText("Pr");
+ symbols["acos"] = NarrowMathOperatorText("acos");
+ symbols["arccos"] = NarrowMathOperatorText("arccos");
+ symbols["arcsin"] = NarrowMathOperatorText("arcsin");
+ symbols["arctan"] = NarrowMathOperatorText("arctan");
+ symbols["arg"] = NarrowMathOperatorText("arg").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["argmax"] = NarrowMathOperatorText("arg max", "arg max").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["argmin"] = NarrowMathOperatorText("arg min", "arg min").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["asin"] = NarrowMathOperatorText("asin");
+ symbols["atan"] = NarrowMathOperatorText("atan");
+ symbols["cos"] = NarrowMathOperatorText("cos");
+ symbols["cosh"] = NarrowMathOperatorText("cosh");
+ symbols["cot"] = NarrowMathOperatorText("cot");
+ symbols["coth"] = NarrowMathOperatorText("coth");
+ symbols["coth"] = NarrowMathOperatorText("coth");
+ symbols["deg"] = NarrowMathOperatorText("deg");
+ symbols["det"] = NarrowMathOperatorText("det");
+ symbols["dim"] = NarrowMathOperatorText("dim");
+ symbols["exp"] = NarrowMathOperatorText("exp");
+ symbols["gcd"] = NarrowMathOperatorText("gcd");
+ symbols["hom"] = NarrowMathOperatorText("hom");
+ symbols["ker"] = NarrowMathOperatorText("ker");
+ symbols["lb"] = NarrowMathOperatorText("lb");
+ symbols["ld"] = NarrowMathOperatorText("ld");
+ symbols["lim"] = NarrowMathOperatorText("lim").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["liminf"] = NarrowMathOperatorText("lim inf", "lim inf").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["limsup"] = NarrowMathOperatorText("lim sup", "lim sup").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
+ symbols["ln"] = NarrowMathOperatorText("ln");
+ symbols["log"] = NarrowMathOperatorText("log");
+ symbols["max"] = NarrowMathOperatorText("max");
+ symbols["median"] = NarrowMathOperatorText("median");
+ symbols["min"] = NarrowMathOperatorText("min");
+ symbols["mod"] = NarrowMathOperatorText("mod");
+ symbols["sec"] = NarrowMathOperatorText("sec");
+ symbols["sgn"] = NarrowMathOperatorText("sgn");
+ symbols["sign"] = NarrowMathOperatorText("sign");
+ symbols["sin"] = NarrowMathOperatorText("sin");
+ symbols["sinh"] = NarrowMathOperatorText("sinh");
+ symbols["tan"] = NarrowMathOperatorText("tan");
+ symbols["tanh"] = NarrowMathOperatorText("tanh");
/**************************************************************************************
* STANDARD MathOperator Symbols
@@ -701,12 +709,12 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["Updownarrow"]=UprightSymbolUnicode(QChar(0x21D5)).addUprightHtml("⇕");
symbols["approx"]=MathOperatorSymbolUnicode(QChar(0x2248)).addMathOperatorHtml("≈").addMathOperatorWinSymbol(QChar(0xBB));
symbols["bbC"]=UnicodeSymbol(QChar(0x2102));
- symbols["bbH"]=MathOperatorSymbolUnicode(QChar(0x210D));
- symbols["bbN"]=MathOperatorSymbolUnicode(QChar(0x2115));
- symbols["bbP"]=MathOperatorSymbolUnicode(QChar(0x2119));
- symbols["bbQ"]=MathOperatorSymbolUnicode(QChar(0x211A));
- symbols["bbR"]=MathOperatorSymbolUnicode(QChar(0x211D));
- symbols["bbZ"]=MathOperatorSymbolUnicode(QChar(0x2124));
+ symbols["bbH"]=UnicodeSymbol(QChar(0x210D));
+ symbols["bbN"]=UnicodeSymbol(QChar(0x2115));
+ symbols["bbP"]=UnicodeSymbol(QChar(0x2119));
+ symbols["bbQ"]=UnicodeSymbol(QChar(0x211A));
+ symbols["bbR"]=UnicodeSymbol(QChar(0x211D));
+ symbols["bbZ"]=UnicodeSymbol(QChar(0x2124));
symbols["because"]=MathOperatorSymbolUnicode(QChar(0x2235)).addMathOperatorHtml("∵");
symbols["bigcap"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C2)).addMathOperatorHtml("⋂").addMathOperatorWinSymbol(QChar(0xC7), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
symbols["bigcup"]=NarrowMathOperatorSymbolUnicode(QChar(0x22C3)).addMathOperatorHtml("⋃").addMathOperatorWinSymbol(QChar(0xC8), 1.8).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
@@ -727,7 +735,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["coprod"]=NarrowMathOperatorSymbolUnicode(QChar(0x2210)).addMathOperatorHtml("∐").addWinSymbol(QChar(0xD5), ItalicOff|BoldOff|FlipSymbolUpDown, 1.8, 0.1).addGlobalFlags(SubSuperscriptBelowAboveSymbol);
{ auto s=MathOperatorSymbolUnicode(QChar(0x222A)).addMathOperatorHtml("∪").addMathOperatorWinSymbol(QChar(0xC8));
symbols["cup"]=s; symbols["lor"]=s; }
- symbols["ddots"]=MathOperatorSymbolUnicode(QChar(0x22F1)).addMathOperatorHtml("⋱");
+ symbols["ddots"]=UprightSymbolUnicode(QChar(0x22F1)).addMathOperatorHtml("⋱");
symbols["div"]=MathOperatorSymbolUnicode(QChar(0x00F7)).addMathOperatorHtml("÷").addMathOperatorWinSymbol(QChar(0xB8));
symbols["downarrow"]=UprightSymbolUnicode(QChar(0x2193)).addUprightHtml("↓").addUprightWinSymbol(QChar(0xAF));
symbols["downharpoonleft"]=UprightSymbolUnicode(QChar(0x21C3)).addUprightHtml("⇃");
@@ -735,13 +743,13 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
{ auto s=MathOperatorSymbolUnicode(QChar(0x2205)).addMathOperatorHtml("∅").addMathOperatorWinSymbol(QChar(0xC6)).addStd("0", BoldOff|ItalicOff|DrawSlash);
symbols["emptyset"]=s; symbols["varnothing"]=s; }
symbols["equiv"]=MathOperatorSymbolUnicode(QChar(0x2261)).addMathOperatorHtml("≡").addMathOperatorWinSymbol(QChar(0xBA));
- symbols["exists"]=MathOperatorSymbolUnicode(QChar(0x2203)).addMathOperatorHtml("∃").addMathOperatorWinSymbol(QChar(0x24)).addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight);
- symbols["forall"]=MathOperatorSymbolUnicode(QChar(0x2200)).addMathOperatorHtml("∀").addMathOperatorWinSymbol(QChar(0x22)).addStd("A", ItalicOff|BoldOff|FlipSymbolUpDown);
+ symbols["exists"]=NarrowMathOperatorSymbolUnicode(QChar(0x2203)).addMathOperatorHtml("∃").addMathOperatorWinSymbol(QChar(0x24)).addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight);
+ symbols["forall"]=NarrowMathOperatorSymbolUnicode(QChar(0x2200)).addMathOperatorHtml("∀").addMathOperatorWinSymbol(QChar(0x22)).addStd("A", ItalicOff|BoldOff|FlipSymbolUpDown);
{ auto s=MathOperatorSymbolUnicode(QChar(0x2265)).addMathOperatorHtml("≥").addMathOperatorWinSymbol(QChar(0xB3));
symbols["geq"]=s; symbols["ge"]=s; }
symbols["geqq"]=MathOperatorSymbolUnicode(QChar(0x2267)).addMathOperatorHtml("≧");
symbols["gg"]=MathOperatorSymbolUnicode(QChar(0x226B)).addMathOperatorHtml("≫").addMathOperatorStd(">>");
- symbols["iddots"]=MathOperatorSymbolUnicode(QChar(0x22F0)).addMathOperatorHtml("⋰");
+ symbols["iddots"]=UprightSymbolUnicode(QChar(0x22F0)).addMathOperatorHtml("⋰");
{ auto s=UprightSymbolUnicode(QChar(0x21D4)).addUprightHtml("⇔").addUprightWinSymbol(QChar(0xDB));
symbols["iff"]=s; symbols["Leftrightarrow"]=s; }
symbols["iiint"]=NarrowMathOperatorSymbolUnicode(QChar(0x222D)).addGlobalFlags(IntLikeSymbolCorrection | SubSuperscriptBelowAboveSymbol).addMathOperatorHtml("∭").addMathOperatorWinSymbol(QString(3, QChar(0xF2)), 1.8, 0.1);
@@ -770,17 +778,17 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["mid"]=MathOperatorSymbolUnicode(QChar(0x2223)).addMathOperatorHtml("∣").addMathOperatorWinSymbol(QChar(0xBD)).addMathOperatorStd("|");
symbols["mp"]=MathOperatorSymbolUnicode(QChar(0x2213)).addMathOperatorHtml("∓").addWinSymbol(QChar(0xB1),ItalicOff|BoldOff|FlipSymbolUpDown).addStd(QChar(0xB1),ItalicOff|BoldOff|FlipSymbolUpDown);
symbols["multimap"]=MathOperatorSymbolUnicode(QChar(0x22B8)).addMathOperatorHtml("⊸");
- symbols["nabla"]=MathOperatorSymbolUnicode(QChar(0x2207)).addMathOperatorHtml("∇").addMathOperatorWinSymbol(QChar(0xD1));
- symbols["ne"]=MathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9));
+ symbols["nabla"]=NarrowMathOperatorSymbolUnicode(QChar(0x2207)).addMathOperatorHtml("∇").addMathOperatorWinSymbol(QChar(0xD1));
+ symbols["ne"]=NarrowMathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9));
symbols["nearrow"]=UprightSymbolUnicode(QChar(0x2197)).addUprightHtml("↗");
{ auto s=MathOperatorSymbolUnicode(QChar(0x00AC)).addMathOperatorHtml("¬").addMathOperatorWinSymbol(QChar(0xD8));
symbols["neg"]=s; symbols["lnot"]=s; }
symbols["neq"]=MathOperatorSymbolUnicode(QChar(0x2260)).addMathOperatorHtml("≠").addMathOperatorWinSymbol(QChar(0xB9)).addStd("=", ItalicOff|BoldOff|DrawSlash);
- symbols["nexists"]=MathOperatorSymbolUnicode(QChar(0x2204)).addMathOperatorHtml("∄").addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight|DrawSlash).addMathOperatorWinSymbol(QChar(0x24), ItalicOff|BoldOff|DrawSlash);
- symbols["ni"]=MathOperatorSymbolUnicode(QChar(0x220B)).addMathOperatorHtml("∋").addMathOperatorWinSymbol(QChar(0xCE), ItalicOff|BoldOff|FlipSymbolLeftRight);
- symbols["nmid"]=MathOperatorSymbolUnicode(QChar(0x2224)).addMathOperatorHtml("∤");
- symbols["notin"]=MathOperatorSymbolUnicode(QChar(0x2209)).addMathOperatorHtml("∉").addMathOperatorWinSymbol(QChar(0xCF));
- symbols["notni"]=MathOperatorSymbolUnicode(QChar(0x220C)).addMathOperatorHtml("∌");
+ symbols["nexists"]=NarrowMathOperatorSymbolUnicode(QChar(0x2204)).addMathOperatorHtml("∄").addStd("E", ItalicOff|BoldOff|FlipSymbolLeftRight|DrawSlash).addMathOperatorWinSymbol(QChar(0x24), ItalicOff|BoldOff|DrawSlash);
+ symbols["ni"]=NarrowMathOperatorSymbolUnicode(QChar(0x220B)).addMathOperatorHtml("∋").addMathOperatorWinSymbol(QChar(0xCE), ItalicOff|BoldOff|FlipSymbolLeftRight);
+ symbols["nmid"]=NarrowMathOperatorSymbolUnicode(QChar(0x2224)).addMathOperatorHtml("∤");
+ symbols["notin"]=NarrowMathOperatorSymbolUnicode(QChar(0x2209)).addMathOperatorHtml("∉").addMathOperatorWinSymbol(QChar(0xCF));
+ symbols["notni"]=NarrowMathOperatorSymbolUnicode(QChar(0x220C)).addMathOperatorHtml("∌");
symbols["nparallel"]=MathOperatorSymbolUnicode(QChar(0x2226)).addMathOperatorHtml("∦");
symbols["nwarrow"]=UprightSymbolUnicode(QChar(0x2196)).addUprightHtml("↖");
symbols["odot"]=MathOperatorSymbolUnicode(QChar(0x2299)).addMathOperatorHtml("⊙");
@@ -791,7 +799,7 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
symbols["oplus"]=MathOperatorSymbolUnicode(QChar(0x2295)).addMathOperatorHtml("⊕").addMathOperatorWinSymbol(QChar(0xC5));
symbols["oslash"]=MathOperatorSymbolUnicode(QChar(0x2298)).addMathOperatorHtml("⊘");
symbols["otimes"]=MathOperatorSymbolUnicode(QChar(0x2297)).addMathOperatorHtml("⊗").addMathOperatorWinSymbol(QChar(0xC4));
- symbols["parallel"]=MathOperatorSymbolUnicode(QChar(0x2225)).addMathOperatorHtml("∥").addMathOperatorStd("||");
+ symbols["parallel"]=NarrowMathOperatorSymbolUnicode(QChar(0x2225)).addMathOperatorHtml("∥").addMathOperatorStd("||");
symbols["pm"] = MathOperatorSymbol(QChar(0xB1), "±").addMathOperatorWinSymbol(QChar(0xB1));
symbols["prec"]=MathOperatorSymbolUnicode(QChar(0x227A)).addMathOperatorHtml("≺");
symbols["prod"]=NarrowMathOperatorSymbolUnicode(QChar(0x220F)).addMathOperatorWinSymbol(QChar(0xD5), 1.8, 0.1).addMathOperatorHtml("∏").addGlobalFlags(SubSuperscriptBelowAboveSymbol);
@@ -821,13 +829,13 @@ void JKQTMathTextSymbolNode::fillSymbolTables()
{ auto s=UprightSymbolUnicode(QChar(0x2192)).addUprightHtml("→").addUprightWinSymbol(QChar(0xAE));
symbols["to"]=s; symbols["rightarrow"]=s; }
symbols["top"]=MathOperatorSymbolUnicode(QChar(0x22A4)).addMathOperatorHtml("⊤").addMathOperatorWinSymbol(QChar(0x5E));
- symbols["triangle"]=MathOperatorSymbolUnicode(QChar(0x2206));
+ symbols["triangle"]=NarrowMathOperatorSymbolUnicode(QChar(0x2206));
symbols["uparrow"]=UprightSymbolUnicode(QChar(0x2191)).addUprightHtml("↑").addUprightWinSymbol(QChar(0xAD));
symbols["updownarrow"]=UprightSymbolUnicode(QChar(0x2195)).addUprightHtml("↕");
symbols["upharpoonleft"]=UprightSymbolUnicode(QChar(0x21BF)).addUprightHtml("↿");
symbols["upharpoonright"]=UprightSymbolUnicode(QChar(0x21BE)).addUprightHtml("↾");
- symbols["vartriangleleft"]=MathOperatorSymbolUnicode(QChar(0x22B2)).addMathOperatorHtml("⊲");
- symbols["vdots"]=MathOperatorSymbolUnicode(QChar(0x22EE)).addMathOperatorHtml("⋮");
+ symbols["vartriangleleft"]=NarrowMathOperatorSymbolUnicode(QChar(0x22B2)).addMathOperatorHtml("⊲");
+ symbols["vdots"]=UprightSymbolUnicode(QChar(0x22EE)).addMathOperatorHtml("⋮");
symbols["vee"]=MathOperatorSymbolUnicode(QChar(0x2228)).addMathOperatorHtml("∨").addMathOperatorWinSymbol(QChar(0xDA));
symbols["vdash"]=MathOperatorSymbolUnicode(QChar(0x22A2)).addMathOperatorHtml("⊢");
symbols["dashv"]=MathOperatorSymbolUnicode(QChar(0x22A3)).addMathOperatorHtml("⊣");
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h
index 54c1a06bbd..5d59fb5d87 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtextsymbolnode.h
@@ -289,6 +289,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextSymbolNode: public JKQTMathTextNode {
static SymbolFullProps NarrowMathOperatorSymbolStd(const QString& symbol);
/** \brief constructs a SymbolProps for a narrow math-operator symbol like \c \\pm ... in unicode-full-encoding, i.e. ItalicOff, BoldOff, SmallExtendWidthInMathmode */
static SymbolFullProps NarrowMathOperatorSymbolStd(const QString& symbol, const QString& symbolHTML);
+ /** \brief constructs a SymbolProps for a narrow math-operator like \c \\sin ..., i.e. ItalicOff, BoldOff, HeightIsAscent, ExtendWidthInMathmode */
+ static SymbolFullProps NarrowMathOperatorText(const QString& op);
+ /** \brief constructs a SymbolProps with explicit HTML for a narrow math-operator like \c \\sin ..., i.e. ItalicOff, BoldOff, HeightIsAscent, ExtendWidthInMathmode */
+ static SymbolFullProps NarrowMathOperatorText(const QString& op, const QString& ophtml);
/** \brief symbols that can be generated in any standard-font */
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp
index 8d5a4adebb..222223e66b 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp
+++ b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.cpp
@@ -337,6 +337,16 @@ QString JKQTMathTextTextNode::getTypeName() const
return QLatin1String("JKQTMathTextTextNode(")+text+")";
}
+void JKQTMathTextTextNode::removeTrailingWhitespace()
+{
+ while (text.size()>0 && text[text.size()-1].isSpace()) text=text.left(text.size()-1);
+}
+
+void JKQTMathTextTextNode::removeLeadingWhitespace()
+{
+ while (text.size()>0 && text[0].isSpace()) text=text.right(text.size()-1);
+}
+
QString JKQTMathTextTextNode::textTransform(const QString &text, const JKQTMathTextEnvironment ¤tEv) const
{
QString txt=text;
diff --git a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h
index 8d996df4f6..f5f76fa622 100644
--- a/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h
+++ b/lib/jkqtmathtext/nodes/jkqtmathtexttextnode.h
@@ -68,6 +68,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextTextNode: public JKQTMathTextTextBaseN
virtual double draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* prevNodeSize=nullptr) override;
/** \copydoc JKQTMathTextNode::getTypeName() */
virtual QString getTypeName() const override ;
+ /** \brief remove trailing whitespace, is used by simplifyJKQTMathTextNode() */
+ void removeTrailingWhitespace();
+ /** \brief remove leading whitespace, is used by simplifyJKQTMathTextNode() */
+ void removeLeadingWhitespace();
protected:
/** \brief defines how a character shold be drawn, used by splitTextForLayout */
enum FontMode {