JKQTMathText:
- new options interface for JKQTMathText::parse() - breaking: removed JKQTMathtext::unparsedNode - several minor improvements
@ -48,10 +48,12 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>IMPROVED: rendering of sqrt</li>
|
||||
<li>IMPROVED: rendering and size calculation of decorations</li>
|
||||
<li>IMPROVED: tokenizing and parsing of text in text-mode: now a lot of accents with commands like \c \\\"a, \c \\'e and variants (e.g. \c {\\\"a}, \c \\\"{a}, ...) are supported now</li>
|
||||
<li>IMPROVED/breaking: refactored symbol node JKQTMathTextSymbolNode and changed font-lookup!</li>
|
||||
<li>IMPROVED/NEW/breaking: refactored whitespace-processing node JKQTMathTextWhitespaceNode, now all major LaTeX whitespace commands are supported properly</li>
|
||||
<li>IMPROVED/NEW/breaking: refactored LaTeX parser in JKQTMathText</li>
|
||||
<li>REMOVED/breaking: \c \\v[a-zA-Z] and shorthand for \c \\vec{a-zA-Z} was removed, implementation of \c \\bbR,\c \\bbC,... changed</li>
|
||||
<li>IMPROVED/BREAKING: refactored symbol node JKQTMathTextSymbolNode and changed font-lookup!</li>
|
||||
<li>IMPROVED/NEW/BREAKING: refactored whitespace-processing node JKQTMathTextWhitespaceNode, now all major LaTeX whitespace commands are supported properly</li>
|
||||
<li>IMPROVED/NEW/BREAKING: refactored LaTeX parser in JKQTMathText</li>
|
||||
<li>REMOVED/BREAKING: \c \\v[a-zA-Z] and shorthand for \c \\vec{a-zA-Z} was removed, implementation of \c \\bbR,\c \\bbC,... changed</li>
|
||||
<li>MODIFIED/BREAKING: new options interface for JKQTMathText::parse()</li>
|
||||
<li>EMOVED/BREAKING: removed JKQTMathtext::unparsedNode</li>
|
||||
<li>IMPROVED/REWORKED rendering of text in text- and math-mode. Now it is more consistent with the output of LaTeX itself</li>
|
||||
<li>IMPROVED/REWORKED rendering of blackboard font: now several different rendering modes can be selected using JKQTMathText::setFontBlackboradMode()</li>
|
||||
<li>BREAKING/REWORKED: The \\verb!...!-command now works the same as in LaTeX</li>
|
||||
@ -123,25 +125,25 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include:
|
||||
<li> fixed issue <a href="https://github.com/jkriege2/JKQtPlotter/issues/52">#52: 'runtime_error': is not a member of 'std'</a>, thanks to <a href="https://github.com/gomgomi">user:gomgomi</a></li>
|
||||
<li> fixed issue <a href="https://github.com/jkriege2/JKQtPlotter/issues/56">#56: Logscale zoom multiple zeros? </a>, thanks to <a href="https://github.com/sufuk">user:sufuk</a></li>
|
||||
<li> merged PR <a href="https://github.com/jkriege2/JKQtPlotter/pull/51">#51: Bug: JKMathParser exception return local variable </a>, thanks to <a href="https://github.com/StephanOostveen">user:StephanOostveen</a></li>
|
||||
<li>renamed/breaking change: renamed JKQTPPlotObject->JKQTPGeometricPlotElement and added new base class JKQTPPlotAnnotationElement</li>
|
||||
<li>renamed/breaking change: renamed JKQTPColorPaletteStyleAndToolsMixin::setPalette() -> JKQTPColorPaletteStyleAndToolsMixin::setColorPalette()</li>
|
||||
<li>removed/breaking change: removed the usage of some deprecated functions and objects (e.g. QMatrix)</li>
|
||||
<li>removed/breaking change: removed the overlay elements (derived from JKQTPOverlayElement), which were not very well set up and are more confusing than useful.</li>
|
||||
<li>improved/breaking change: geometric objects now use an adaptive drawing algorithm to represent curves (before e.g. ellipses were always separated into a fixed number of line-segments)</li>
|
||||
<li>improved/breaking change: geometric elements constructor: removed all styling properties, added setStyle()-functions to replace them. This is necessary to better work with the extended Styling system</li>
|
||||
<li>renamed/BREAKING change: renamed JKQTPPlotObject->JKQTPGeometricPlotElement and added new base class JKQTPPlotAnnotationElement</li>
|
||||
<li>renamed/BREAKING change: renamed JKQTPColorPaletteStyleAndToolsMixin::setPalette() -> JKQTPColorPaletteStyleAndToolsMixin::setColorPalette()</li>
|
||||
<li>removed/BREAKING change: removed the usage of some deprecated functions and objects (e.g. QMatrix)</li>
|
||||
<li>removed/BREAKING change: removed the overlay elements (derived from JKQTPOverlayElement), which were not very well set up and are more confusing than useful.</li>
|
||||
<li>improved/BREAKING change: geometric objects now use an adaptive drawing algorithm to represent curves (before e.g. ellipses were always separated into a fixed number of line-segments)</li>
|
||||
<li>improved/BREAKING change: geometric elements constructor: removed all styling properties, added setStyle()-functions to replace them. This is necessary to better work with the extended Styling system</li>
|
||||
<li>improved: constructors and access functions for several geometric objects (e.g. more constructors, additional functions to retrieve parameters in diferent forms, iterators for polygons, ...)</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of parsed function plots and declared several setters as slots.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of bar & impulse charts.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of range charts.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of special line (step) graphs.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of filled line graphs.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of range plot elements (JKQTPVerticalRange and JKQTPHorizontalRange).</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of boxplots.</li>
|
||||
<li>improved/breaking change: reworked class hierarchy of violin plots.</li>
|
||||
<li>improved/breaking change: extended styling system for graphs.</li>
|
||||
<li>improved/breaking change: reworked graph Base-Classes (promoted several setters to slots, added Q_PROPERTY- and Q_ENUM-declarations...)</li>
|
||||
<li>improved/breaking change: made more functions and function parameters const</li>
|
||||
<li>improved/breaking change: image plots now manage CONST-data, not plain pointer arrays... This is OK, since the raw data is never owned nor modified by the plot, only referenced!.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of parsed function plots and declared several setters as slots.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of bar & impulse charts.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of range charts.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of special line (step) graphs.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of filled line graphs.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of range plot elements (JKQTPVerticalRange and JKQTPHorizontalRange).</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of boxplots.</li>
|
||||
<li>improved/BREAKING change: reworked class hierarchy of violin plots.</li>
|
||||
<li>improved/BREAKING change: extended styling system for graphs.</li>
|
||||
<li>improved/BREAKING change: reworked graph Base-Classes (promoted several setters to slots, added Q_PROPERTY- and Q_ENUM-declarations...)</li>
|
||||
<li>improved/BREAKING change: made more functions and function parameters const</li>
|
||||
<li>improved/BREAKING change: image plots now manage CONST-data, not plain pointer arrays... This is OK, since the raw data is never owned nor modified by the plot, only referenced!.</li>
|
||||
<li>bugfixed/improved: aspect ratio handling in JKQTPlotter.</li>
|
||||
<li>new: switching to semantic versioning ... starting with v4.0.0</li>
|
||||
<li>new: Compatibility with Qt 5.15 and Qt6</li>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 831 B After Width: | Height: | Size: 904 B |
Before Width: | Height: | Size: 994 B After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 923 B |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.7 KiB |
@ -486,7 +486,7 @@ QTreeWidgetItem *TestForm::createTree(JKQTMathTextNode *node, QTreeWidgetItem* p
|
||||
int l=matrixN->getLines();
|
||||
int c=matrixN->getColumns();
|
||||
name=QString("MatrixNode: l*c=%1*%2").arg(l).arg(c);
|
||||
QVector<QVector<JKQTMathTextNode*> > children=matrixN->getChildren();
|
||||
QVector<QVector<JKQTMathTextNode*> > children=matrixN->getChildrenMatrix();
|
||||
for (int y=0; y<l; y++) {
|
||||
for (int x=0; x<c; x++) {
|
||||
if (children[y].at(x)!=nullptr) {
|
||||
|
@ -185,10 +185,8 @@ JKQTMathText::JKQTMathText(QObject* parent):
|
||||
//qDebug()<<"set fonts: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
|
||||
useXITS();
|
||||
//qDebug()<<"useXITS: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms"; t0=std::chrono::high_resolution_clock::now();
|
||||
useUnparsed=false;
|
||||
|
||||
parsedNode=nullptr;
|
||||
unparsedNode=nullptr;
|
||||
|
||||
currentToken=MTTnone;
|
||||
currentTokenName="";
|
||||
@ -200,8 +198,6 @@ JKQTMathText::JKQTMathText(QObject* parent):
|
||||
JKQTMathText::~JKQTMathText() {
|
||||
if (parsedNode!=nullptr) delete parsedNode;
|
||||
parsedNode=nullptr;
|
||||
if (unparsedNode!=nullptr) delete unparsedNode;
|
||||
unparsedNode=nullptr;
|
||||
}
|
||||
|
||||
void JKQTMathText::loadSettings(const QSettings& settings, const QString& group){
|
||||
@ -1058,16 +1054,6 @@ void JKQTMathText::setMatrixYPaddingFactor(double factor)
|
||||
matrix_yPadding_factor=factor;
|
||||
}
|
||||
|
||||
void JKQTMathText::setUseUnparsed(bool __value)
|
||||
{
|
||||
this->useUnparsed = __value;
|
||||
}
|
||||
|
||||
bool JKQTMathText::isUsingUnparsed() const
|
||||
{
|
||||
return this->useUnparsed;
|
||||
}
|
||||
|
||||
QStringList JKQTMathText::getErrorList() const {
|
||||
return this->error_list;
|
||||
}
|
||||
@ -2288,15 +2274,15 @@ JKQTMathTextNode *JKQTMathText::getParsedNode() const {
|
||||
|
||||
|
||||
|
||||
bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter, bool allowLinebreaks){
|
||||
QString ntext;
|
||||
if (addSpaceBeforeAndAfter) ntext=QString("\\;")+text+QString("\\;");
|
||||
else ntext=text;
|
||||
bool JKQTMathText::parse(const QString& text, ParseOptions options){
|
||||
QString ntext=text;
|
||||
if (options.testFlag(StartWithMathMode)) ntext=QString("$")+ntext+QString("$");
|
||||
if (options.testFlag(AddSpaceBeforeAndAfter)) ntext=QString("\\;")+ntext+QString("\\;");
|
||||
if (parsedNode && parseString==ntext) return true;
|
||||
|
||||
|
||||
if (parsedNode!=nullptr) delete parsedNode;
|
||||
if (unparsedNode!=nullptr) delete unparsedNode;
|
||||
//std::cout<<"JKQTMathText::parse('"<<ntext.toStdString()<<"', options="<<std::hex<<static_cast<int>(options)<<")\n";
|
||||
parseString=ntext;
|
||||
|
||||
currentTokenID=-1;
|
||||
@ -2306,35 +2292,41 @@ bool JKQTMathText::parse(const QString& text, bool addSpaceBeforeAndAfter, bool
|
||||
lastLineCount.clear();
|
||||
|
||||
error_list.clear();
|
||||
if (allowLinebreaks) {
|
||||
if (options.testFlag(AllowLinebreaks)) {
|
||||
parsedNode=parseMultilineLatexString(true, QString(""), MTHALeft, 1.0, MTSMDefaultSpacing, MTVOFirstLine);
|
||||
} else {
|
||||
parsedNode=parseLatexString(true);
|
||||
}
|
||||
unparsedNode=new JKQTMathTextVerbatimNode(this, text);
|
||||
parsedNode=simplifyJKQTMathTextNode(parsedNode);
|
||||
return (parsedNode!=nullptr);
|
||||
}
|
||||
|
||||
|
||||
QSizeF JKQTMathText::getSize(QPainter& painter){
|
||||
if (getNodeTree()!=nullptr) {
|
||||
double w=0, a=0, d=0, s=0;
|
||||
getSizeDetail(painter, w, a, d, s);
|
||||
return QSizeF(w, a+d);
|
||||
const JKQTMathTextNodeSize s=getSizeDetail(painter);
|
||||
return s.getSize();
|
||||
}
|
||||
return QSizeF(0,0);
|
||||
}
|
||||
|
||||
QSize JKQTMathText::getIntSize(QPainter &painter)
|
||||
{
|
||||
if (getNodeTree()!=nullptr) {
|
||||
const JKQTMathTextNodeSize s=getSizeDetail(painter);
|
||||
return s.getIntSize();
|
||||
}
|
||||
return QSize(0,0);
|
||||
}
|
||||
|
||||
double JKQTMathText::getDescent(QPainter& painter) {
|
||||
double w=0, a=0, d=0, s=0;
|
||||
getSizeDetail(painter, w, a, d, s);
|
||||
return d;
|
||||
const JKQTMathTextNodeSize s=getSizeDetail(painter);
|
||||
return s.getDescent();
|
||||
}
|
||||
|
||||
double JKQTMathText::getAscent(QPainter& painter) {
|
||||
double w=0, a=0, d=0, s=0;
|
||||
getSizeDetail(painter, w, a, d, s);
|
||||
return a;
|
||||
const JKQTMathTextNodeSize s=getSizeDetail(painter);
|
||||
return s.baselineHeight;
|
||||
}
|
||||
|
||||
void JKQTMathText::getSizeDetail(QPainter& painter, double& width, double& ascent, double& descent, double& strikeoutPos) {
|
||||
@ -2516,7 +2508,6 @@ QPicture JKQTMathText::drawIntoPicture(bool drawBoxes)
|
||||
|
||||
|
||||
JKQTMathTextNode *JKQTMathText::getNodeTree() const {
|
||||
if (useUnparsed) return unparsedNode;
|
||||
return parsedNode;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef JKQTMATHTEXT_H
|
||||
#define JKQTMATHTEXT_H
|
||||
|
||||
#include <QFlags>
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QPainter>
|
||||
@ -214,16 +215,28 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
void loadSettings(const QSettings& settings, const QString& group=QString("mathtext/"));
|
||||
/** \brief store the object settings to the given QSettings object with the given name prefix */
|
||||
void saveSettings(QSettings& settings, const QString& group=QString("mathtext/")) const;
|
||||
/** \brief options for parse() */
|
||||
enum ParseOption {
|
||||
AddSpaceBeforeAndAfter = 0x01, /*!< \brief If set, a little bit of space is added before and after the text. */
|
||||
StartWithMathMode = 0x02, /*!< \brief if set, the parser assumes the LaTeX string is in math-mode (as if surrounded by \c $ ) */
|
||||
AllowLinebreaks = 0x04, /*!< \brief If set, linebreak (i.e. \c \\ or \c \\newline ) are allowed, otherwise a single line wihtout such linebreak commands is expected */
|
||||
DefaultParseOptions=AllowLinebreaks,
|
||||
};
|
||||
Q_DECLARE_FLAGS(ParseOptions, ParseOption)
|
||||
Q_FLAG(ParseOptions)
|
||||
/** \brief parse the given LaTeX string.
|
||||
*
|
||||
* \param addSpaceBeforeAndAfter If \ctrue a little bit of space is added before and after the text.
|
||||
* \param allowLinebreaks If \c true , linebreak (i.e. \c \\ or \c \\newline ) are allowed, otherwise a single line wihtout such linebreak commands is expected
|
||||
* \param options Options for parsing, \see ParseOptions
|
||||
* \param allowLinebreaks
|
||||
*
|
||||
* \returns \c true on success.
|
||||
*/
|
||||
bool parse(const QString &text, bool addSpaceBeforeAndAfter=false, bool allowLinebreaks=true);
|
||||
/** \brief get the size of the drawn representation. returns an invalid size if no text has been parsed. */
|
||||
bool parse(const QString &text, ParseOptions options=DefaultParseOptions);
|
||||
|
||||
/** \brief get the size of the drawn representation. returns \c QSizeF(0,0) if no text has been parsed. */
|
||||
QSizeF getSize(QPainter& painter);
|
||||
/** \brief get the rounded (using ceil) to an integer size of the drawn representation. returns \c QSize(0,0) if no text has been parsed. */
|
||||
QSize getIntSize(QPainter& painter);
|
||||
/** \brief return the descent, i.e. the distance from the baseline to the lowest part of the representation */
|
||||
double getDescent(QPainter& painter);
|
||||
/** \brief return the ascentt, i.e. the distance from the baseline to the highest part of the representation */
|
||||
@ -643,11 +656,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
void setMatrixYPaddingFactor(double factor);
|
||||
|
||||
|
||||
|
||||
/** \copydoc useUnparsed */
|
||||
void setUseUnparsed(bool __value);
|
||||
/** \copydoc useUnparsed */
|
||||
bool isUsingUnparsed() const;
|
||||
/** \copydoc error_list */
|
||||
QStringList getErrorList() const;
|
||||
/** \brief returns \c true when errors were registered in the system \see error_list */
|
||||
@ -883,10 +891,6 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
|
||||
/** \brief the result of parsing the last string supplied to the object via parse() */
|
||||
JKQTMathTextNode* parsedNode;
|
||||
/** \brief a tree containing the unparsed text as a single node */
|
||||
JKQTMathTextNode* unparsedNode;
|
||||
/** \brief if true, the unparsedNode is drawn \see unparsedNode */
|
||||
bool useUnparsed;
|
||||
|
||||
/** \brief returns the syntax tree of JKQTMathTextNode's that was created by the last parse call */
|
||||
JKQTMathTextNode* getNodeTree() const;
|
||||
|
@ -203,6 +203,7 @@ JKQTMathTextSimpleInstructionNode::InstructionProperties::InstructionProperties(
|
||||
JKQTMathTextModifiedTextPropsInstructionNode::JKQTMathTextModifiedTextPropsInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
|
||||
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
|
||||
{
|
||||
fillInstructions();
|
||||
}
|
||||
|
||||
JKQTMathTextModifiedTextPropsInstructionNode::~JKQTMathTextModifiedTextPropsInstructionNode() {
|
||||
@ -215,6 +216,7 @@ QString JKQTMathTextModifiedTextPropsInstructionNode::getTypeName() const
|
||||
}
|
||||
|
||||
void JKQTMathTextModifiedTextPropsInstructionNode::getSizeInternal(QPainter& painter, JKQTMathTextEnvironment currentEv, double& width, double& baselineHeight, double& overallHeight, double& strikeoutPos, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
fillInstructions();
|
||||
JKQTMathTextEnvironment ev=currentEv;
|
||||
|
||||
executeInstruction(ev);
|
||||
@ -223,11 +225,12 @@ void JKQTMathTextModifiedTextPropsInstructionNode::getSizeInternal(QPainter& pai
|
||||
}
|
||||
|
||||
double JKQTMathTextModifiedTextPropsInstructionNode::draw(QPainter& painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize* /*prevNodeSize*/) {
|
||||
fillInstructions();
|
||||
doDrawBoxes(painter, x, y, currentEv);
|
||||
JKQTMathTextEnvironment ev=currentEv;
|
||||
|
||||
executeInstruction(ev);
|
||||
|
||||
//std::cout<<" MODNODE: "<<getInstructionName().toStdString()<<" ev.mathMode="<<ev.insideMath<<", ev.forceUpright="<<ev.insideMathForceDigitsUpright<<"\n";
|
||||
return getChild()->draw(painter, x, y, ev);
|
||||
}
|
||||
|
||||
@ -266,6 +269,7 @@ void JKQTMathTextModifiedTextPropsInstructionNode::modifyInMathEnvironment(const
|
||||
|
||||
void JKQTMathTextModifiedTextPropsInstructionNode::executeInstruction(JKQTMathTextEnvironment &ev) const
|
||||
{
|
||||
fillInstructions();
|
||||
instructions.value(getInstructionName(), InstructionProperties()).modifier(ev, getParameters());
|
||||
}
|
||||
|
||||
@ -649,6 +653,7 @@ JKQTMathTextModifiedTextPropsInstructionNode::InstructionProperties::Instruction
|
||||
JKQTMathTextBoxInstructionNode::JKQTMathTextBoxInstructionNode(JKQTMathText* _parent, const QString& name, JKQTMathTextNode* child, const QStringList& parameters):
|
||||
JKQTMathTextInstruction1Node(_parent, name, child, parameters)
|
||||
{
|
||||
fillInstructions();
|
||||
}
|
||||
|
||||
JKQTMathTextBoxInstructionNode::~JKQTMathTextBoxInstructionNode() {
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, const QVector<QVector<JKQTMathTextNode *> > &children, const QString &columnSpec):
|
||||
JKQTMathTextNode(_parent),
|
||||
JKQTMathTextMultiChildNode(_parent),
|
||||
verticalLineRHSColumn(),
|
||||
verticalLineLeft(LTnone),
|
||||
horizontalLineBottomRow(),
|
||||
@ -52,7 +52,7 @@ JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText* _parent, const QVec
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText *_parent, const QString &columnSpec):
|
||||
JKQTMathTextNode(_parent),
|
||||
JKQTMathTextMultiChildNode(_parent),
|
||||
verticalLineRHSColumn(),
|
||||
verticalLineLeft(LTnone),
|
||||
horizontalLineBottomRow(),
|
||||
@ -64,12 +64,7 @@ JKQTMathTextMatrixNode::JKQTMathTextMatrixNode(JKQTMathText *_parent, const QStr
|
||||
}
|
||||
|
||||
JKQTMathTextMatrixNode::~JKQTMathTextMatrixNode() {
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
delete children[i].at(j);
|
||||
}
|
||||
}
|
||||
children.clear();
|
||||
clearChildrenImpl(true);
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::setChildren(const QVector<QVector<JKQTMathTextNode *> > &children)
|
||||
@ -108,7 +103,7 @@ bool JKQTMathTextMatrixNode::toHtml(QString &/*html*/, JKQTMathTextEnvironment /
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<QVector<JKQTMathTextNode *> > JKQTMathTextMatrixNode::getChildren() const {
|
||||
QVector<QVector<JKQTMathTextNode *> > JKQTMathTextMatrixNode::getChildrenMatrix() const {
|
||||
return this->children;
|
||||
}
|
||||
|
||||
@ -120,6 +115,106 @@ int JKQTMathTextMatrixNode::getLines() const {
|
||||
return this->lines;
|
||||
}
|
||||
|
||||
QList<JKQTMathTextNode *> JKQTMathTextMatrixNode::getChildren()
|
||||
{
|
||||
QList<JKQTMathTextNode *> l;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
l<<children[i].at(j);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
int JKQTMathTextMatrixNode::childCount() const
|
||||
{
|
||||
int s=0;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
s+=children[i].size();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void JKQTMathTextMatrixNode::clearChildren(bool deleteChildren)
|
||||
{
|
||||
clearChildrenImpl(deleteChildren);
|
||||
}
|
||||
|
||||
|
||||
void JKQTMathTextMatrixNode::clearChildrenImpl(bool deleteChildren)
|
||||
{
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (deleteChildren) delete children[i].at(j);
|
||||
}
|
||||
}
|
||||
children.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void JKQTMathTextMatrixNode::deleteChild(int nn)
|
||||
{
|
||||
int n=0;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (n==nn) {
|
||||
delete children[i].operator[](j);
|
||||
children[i].operator[](j)=new JKQTMathTextNoopNode(parentMathText);
|
||||
children[i].operator[](j)->setParentNode(this);
|
||||
return ;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
JKQTMathTextNode *JKQTMathTextMatrixNode::getChild(int nn)
|
||||
{
|
||||
int n=0;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (n==nn) {
|
||||
return children[i].at(j);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const JKQTMathTextNode *JKQTMathTextMatrixNode::getChild(int nn) const
|
||||
{
|
||||
int n=0;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (n==nn) {
|
||||
return children[i].at(j);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKQTMathTextNode *JKQTMathTextMatrixNode::replaceChild(int nn, JKQTMathTextNode *newChild)
|
||||
{
|
||||
int n=0;
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
for (int j=0; j<children[i].size(); j++) {
|
||||
if (n==nn) {
|
||||
JKQTMathTextNode* old= children[i].at(j);
|
||||
children[i].operator[](j)=newChild;
|
||||
return old;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void JKQTMathTextMatrixNode::setDrawBoxes(bool draw)
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ class JKQTMathText; // forward
|
||||
*
|
||||
* \image html jkqtmathtext/jkqtmathtext_array.png
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextMultiChildNode {
|
||||
public:
|
||||
/** \brief types of lines */
|
||||
enum LineType {
|
||||
@ -72,11 +72,25 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
|
||||
/** \copydoc JKQTMathTextNode::toHtml() */
|
||||
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override;
|
||||
/** \brief returns the child nodes */
|
||||
QVector<QVector<JKQTMathTextNode*> > getChildren() const;
|
||||
QVector<QVector<JKQTMathTextNode*> > getChildrenMatrix() const;
|
||||
/** \copydoc columns */
|
||||
int getColumns() const;
|
||||
/** \copydoc lines */
|
||||
int getLines() const;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChildren() */
|
||||
virtual QList<JKQTMathTextNode*> getChildren() override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::childCount() */
|
||||
virtual int childCount() const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::clearChildren() */
|
||||
virtual void clearChildren(bool deleteChildren=true) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::deleteChild() */
|
||||
virtual void deleteChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual JKQTMathTextNode* getChild(int i) override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual const JKQTMathTextNode* getChild(int i) const override;
|
||||
/** \copydoc JKQTMathTextMultiChildNode::getChild() */
|
||||
virtual JKQTMathTextNode* replaceChild(int i, JKQTMathTextNode* newChild) override;
|
||||
protected:
|
||||
/** \brief describes the layout of the whole node */
|
||||
struct LayoutInfo: public JKQTMathTextNodeSize {
|
||||
@ -135,6 +149,8 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextMatrixNode: public JKQTMathTextNode {
|
||||
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);
|
||||
/** \copydoc JKQTMathTextMultiChildNode::clearChildren() */
|
||||
void clearChildrenImpl(bool deleteChildren);
|
||||
};
|
||||
|
||||
#endif // JKQTMATHTEXTMATRIXNODE_H
|
||||
|
@ -380,3 +380,37 @@ JKQTMathTextNodeSize JKQTMathTextNode::getSize(QPainter &painter, JKQTMathTextEn
|
||||
getSize(painter, currentEv, s.width, s.baselineHeight, s.overallHeight, s.strikeoutPos, prevNodeSize);
|
||||
return s;
|
||||
}
|
||||
|
||||
JKQTMathTextNoopNode::JKQTMathTextNoopNode(JKQTMathText *parent):
|
||||
JKQTMathTextNode(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTMathTextNoopNode::~JKQTMathTextNoopNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString JKQTMathTextNoopNode::getTypeName() const
|
||||
{
|
||||
return "MTNoopNode";
|
||||
}
|
||||
|
||||
bool JKQTMathTextNoopNode::toHtml(QString &html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
double JKQTMathTextNoopNode::draw(QPainter &painter, double x, double y, JKQTMathTextEnvironment currentEv, const JKQTMathTextNodeSize *prevNodeSize)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
void JKQTMathTextNoopNode::getSizeInternal(QPainter &painter, JKQTMathTextEnvironment currentEv, double &width, double &baselineHeight, double &overallHeight, double &strikeoutPos, const JKQTMathTextNodeSize *prevNodeSize)
|
||||
{
|
||||
width=0;
|
||||
baselineHeight=0;
|
||||
overallHeight=0;
|
||||
strikeoutPos=0;
|
||||
}
|
||||
|
@ -279,4 +279,26 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextDualChildNode: public JKQTMathTextMult
|
||||
JKQTMathTextNode* child2;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** \brief subclass representing a node that outputs nothing
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNoopNode: public JKQTMathTextNode {
|
||||
public:
|
||||
explicit JKQTMathTextNoopNode(JKQTMathText* parent);
|
||||
virtual ~JKQTMathTextNoopNode() override;
|
||||
/** \copydoc JKQTMathTextNode::getTypeName() */
|
||||
virtual QString getTypeName() const override;
|
||||
/** \copydoc JKQTMathTextNode::toHtml() */
|
||||
virtual bool toHtml(QString& html, JKQTMathTextEnvironment currentEv, JKQTMathTextEnvironment defaultEv) override;
|
||||
/** \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;
|
||||
|
||||
};
|
||||
#endif // JKQTMATHTEXTNODE_H
|
||||
|
@ -30,26 +30,27 @@
|
||||
JKQTMathTextNode *simplifyJKQTMathTextNode(JKQTMathTextNode *node)
|
||||
{
|
||||
JKQTMathTextHorizontalListNode* nl=dynamic_cast<JKQTMathTextHorizontalListNode*>(node);
|
||||
JKQTMathTextVerticalListNode* vl=dynamic_cast<JKQTMathTextVerticalListNode*>(node);
|
||||
JKQTMathTextMultiChildNode* nmc=dynamic_cast<JKQTMathTextMultiChildNode*>(node);
|
||||
JKQTMathTextSingleChildNode* nsc=dynamic_cast<JKQTMathTextSingleChildNode*>(node);
|
||||
if (nl) {
|
||||
if (nl->childCount()==1) {
|
||||
if ((nl || vl) && nmc) {
|
||||
if (nmc->childCount()==1) {
|
||||
// if there was only a single node: simplify the syntax tree, by removing the outer list node
|
||||
JKQTMathTextNode* ret= simplifyJKQTMathTextNode(nl->getChild(0));
|
||||
nl->clearChildren(false);
|
||||
JKQTMathTextNode* ret= simplifyJKQTMathTextNode(nmc->getChild(0));
|
||||
nmc->clearChildren(false);
|
||||
ret->setParentNode(nullptr);
|
||||
delete nl;
|
||||
delete nmc;
|
||||
return ret;
|
||||
} else if (nl->childCount()>1) {
|
||||
} else if (nmc->childCount()>1) {
|
||||
// if there are several child nodes, apply this method recursively
|
||||
for (int i=0; i<nl->childCount(); i++) {
|
||||
JKQTMathTextNode* c=nl->getChild(i);
|
||||
for (int i=0; i<nmc->childCount(); i++) {
|
||||
JKQTMathTextNode* c=nmc->getChild(i);
|
||||
JKQTMathTextNode* newc= simplifyJKQTMathTextNode(c);
|
||||
if (c!=newc) nl->replaceAndDeleteChild(i, newc);
|
||||
if (c!=newc) nmc->replaceAndDeleteChild(i, newc);
|
||||
}
|
||||
return nl;
|
||||
return nmc;
|
||||
}
|
||||
return nl;
|
||||
return nmc;
|
||||
} else if (nmc) {
|
||||
// apply this method recursively to any children
|
||||
for (int i=0; i<nmc->childCount(); i++) {
|
||||
@ -106,3 +107,32 @@ JKQTMathTextNode *simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode *node)
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
namespace JKQTMathText_private {
|
||||
QString JKQTMathTextNodeTree2String(JKQTMathTextNode *root, int level)
|
||||
{
|
||||
QString tree;
|
||||
JKQTMathTextMultiChildNode* nmc=dynamic_cast<JKQTMathTextMultiChildNode*>(root);
|
||||
JKQTMathTextSingleChildNode* nsc=dynamic_cast<JKQTMathTextSingleChildNode*>(root);
|
||||
if (level>=1) {
|
||||
for (int i=0; i<level-1; i++) tree+="| ";
|
||||
}
|
||||
if (level>0) tree+="+--";
|
||||
tree+=root->getTypeName()+"\n";
|
||||
if (nmc) {
|
||||
for (int i=0; i<nmc->childCount(); i++) {
|
||||
tree+=JKQTMathTextNodeTree2String(nmc->getChild(i), level+1);
|
||||
}
|
||||
} else if (nsc) {
|
||||
tree+=JKQTMathTextNodeTree2String(nsc->getChild(), level+1);
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
QString JKQTMathTextNodeTree2String(JKQTMathTextNode *root)
|
||||
{
|
||||
return JKQTMathText_private::JKQTMathTextNodeTree2String(root, 0);
|
||||
}
|
||||
|
@ -44,6 +44,44 @@ JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyJKQTMathTextNode(JKQTMathTextN
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode* simplifyAndTrimJKQTMathTextNode(JKQTMathTextNode* node);
|
||||
|
||||
/*! \brief converts a node-tree with the given \a root into a string, representing the node-tree
|
||||
\ingroup jkqtmathtext_items
|
||||
|
||||
\see This method uses JKQTMathText::getTypeName()
|
||||
|
||||
Here is an example output for
|
||||
\code
|
||||
$x_{1/2}=\frac{-b\pm\sqrt{b^2-4ac}}{2a}$
|
||||
\endcode
|
||||
|
||||
The output looks like this:
|
||||
\verbatim
|
||||
JKQTMathTextModifiedTextPropsInstructionNode(equation)
|
||||
+--MTHorizontalListNode
|
||||
| +--JKQTMathTextTextNode(x)
|
||||
| +--MTsubscriptNode
|
||||
| | +--MTHorizontalListNode
|
||||
| | | +--JKQTMathTextTextNode(1)
|
||||
| | | +--JKQTMathTextTextNode(/)
|
||||
| | | +--JKQTMathTextTextNode(2)
|
||||
| +--JKQTMathTextSymbolNode(=)
|
||||
| +--MTfracNode
|
||||
| | +--MTHorizontalListNode
|
||||
| | | +--JKQTMathTextSymbolNode(-)
|
||||
| | | +--JKQTMathTextTextNode(b)
|
||||
| | | +--JKQTMathTextSymbolNode(pm)
|
||||
| | | +--MTsqrtNode
|
||||
| | | | +--MTHorizontalListNode
|
||||
| | | | | +--JKQTMathTextTextNode(b)
|
||||
| | | | | +--MTsuperscriptNode
|
||||
| | | | | | +--JKQTMathTextTextNode(2)
|
||||
| | | | | +--JKQTMathTextSymbolNode(-)
|
||||
| | | | | +--JKQTMathTextTextNode(4ac)
|
||||
| | +--JKQTMathTextTextNode(2a)
|
||||
\endverbatim
|
||||
*/
|
||||
JKQTMATHTEXT_LIB_EXPORT QString JKQTMathTextNodeTree2String(JKQTMathTextNode* root);
|
||||
|
||||
#endif // JKQTMATHTEXTNODETOOLS_H
|
||||
|
||||
|
||||
|
@ -302,8 +302,9 @@ double JKQTMathTextTextNode::draw(QPainter& painter, double x, double y, JKQTMat
|
||||
|
||||
//qDebug()<<"JKQTMathTextTextNode: text="<<text<<" font="<<f;
|
||||
|
||||
|
||||
//std::cout<<" TEXT: currentEv.mathMode="<<currentEv.insideMath<<", currentEv.forceUpright="<<currentEv.insideMathForceDigitsUpright<<"\n";
|
||||
for (int i=0; i<textpart.size(); i++) {
|
||||
//std::cout<<" TEXT: mode="<<fontMode[i]<<", text='"<<textpart[i].toStdString()<<"'\n";
|
||||
switch(fontMode[i]) {
|
||||
case FMasDefined:
|
||||
painter.setFont(f);
|
||||
|
@ -1738,7 +1738,6 @@ bool JKQTBasePlotter::printpreviewNew(QPaintDevice* paintDevice, bool setAbsolut
|
||||
plotterStyle.widgetBackgroundBrush=bc;
|
||||
paintMagnification=oldP;
|
||||
|
||||
mathText.setUseUnparsed(false);
|
||||
|
||||
return res;
|
||||
|
||||
@ -3744,7 +3743,6 @@ void JKQTBasePlotter::saveImage(const QString& filename, bool displayPreview) {
|
||||
QFile::copy(fn, tempFM);
|
||||
}
|
||||
|
||||
mathText.setUseUnparsed(!jkqtpPaintDeviceAdapters[adapterID]->useLatexParser());
|
||||
|
||||
gridPrintingCalc();
|
||||
QPaintDevice* paintDevice=jkqtpPaintDeviceAdapters[adapterID]->createPaintdevice(fn, jkqtp_roundTo<int>(gridPrintingSize.width()), jkqtp_roundTo<int>(gridPrintingSize.height()));
|
||||
@ -5104,11 +5102,6 @@ JKQTBasePlotter::textSizeData::textSizeData():
|
||||
|
||||
|
||||
|
||||
bool JKQTPPaintDeviceAdapter::useLatexParser() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QPaintDevice *JKQTPPaintDeviceAdapter::createPaintdeviceMM(const QString &filename, double widthMM, double heightMM) const
|
||||
{
|
||||
#if QT_VERSION>=QT_VERSION_CHECK(6,0,0)
|
||||
|
@ -87,7 +87,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter {
|
||||
virtual double getPrintSizeXInMM() const =0;
|
||||
virtual double getPrintSizeYInMM() const =0;
|
||||
virtual bool isPrinter() const=0;
|
||||
virtual bool useLatexParser() const;
|
||||
/** \brief create a paint device with a given size in pt */
|
||||
virtual QPaintDevice* createPaintdevice(const QString& filename, int widthPix, int heightPix) const=0;
|
||||
/** \brief create a paint device with a given size in millimeters ... the default implementation call createPaintdevice(), assuming the standard logical resolution of the desktop!!!) */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "jkqtmathtext/jkqtmathtextlabel.h"
|
||||
#include "jkqtcommon/jkqtpstringtools.h"
|
||||
#include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
|
||||
#include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
|
||||
#include <iostream>
|
||||
|
||||
void processFont(const QString font, QStringList& fonts, QString& mathFont)
|
||||
@ -510,13 +511,17 @@ int main(int argc, char* argv[])
|
||||
<<latex[i].toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<mathText.getErrorList().join("\n").toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getParsedNode()).toStdString()
|
||||
<<"-----------------------------------------------------------\n"
|
||||
;
|
||||
} else if (verbose) {
|
||||
std::cout<<"parsing LaTeX: OK\n"
|
||||
<<"parsing duration: "<<durParseMS<<"ms\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<latex[i].toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getParsedNode()).toStdString()
|
||||
<<"-----------------------------------------------------------\n";
|
||||
}
|
||||
|
||||
|