mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-24 09:31:40 +08:00
BREAKING/REWORKED: Separated the LaTeX parser into JKQTMathTextLatexParser from JKQTMathText
This commit is contained in:
parent
d4c024fcd8
commit
6273e469cd
@ -24,6 +24,13 @@
|
||||
|
||||
This group assembles general information around JKQTMathText. It explains the rendering model, lists the supported LaTeX-subset etc.
|
||||
|
||||
\defgroup jkqtmathtext_general_languages Supported Markup Languages
|
||||
\ingroup jkqtmathtext_general
|
||||
|
||||
\defgroup jkqtmathtext_general_latex LaTeX Markup
|
||||
\ingroup jkqtmathtext_general_languages
|
||||
|
||||
LaTeX is the default markup language and supported in JKQTMathText via JKQTMathTextLatexParser.
|
||||
|
||||
\defgroup jkqtmathtext_render Math Renderer Class (JKQTMathText)
|
||||
\ingroup jkqtmathtext
|
||||
@ -52,6 +59,9 @@
|
||||
This group contains all classes that are used to build a memory-representation of the math to be rendered.
|
||||
They form a tree in memory.
|
||||
|
||||
\defgroup jkqtmathtext_parser Math Markup Parser Classes
|
||||
\ingroup jkqtmathtext
|
||||
|
||||
\defgroup jkqtmathtext_tools Tool Functions and Types for JKQTMathText
|
||||
\ingroup jkqtmathtext_interaltools
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*!
|
||||
|
||||
\defgroup jkqtmathtext_supportedlatex Supported LaTeX-Subset
|
||||
\ingroup jkqtmathtext_general
|
||||
\ingroup jkqtmathtext_general_latex
|
||||
|
||||
\tableofcontents
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*!
|
||||
\defgroup jkqtmathtext_supportedlatexsymbols Supported LaTeX-Symbols
|
||||
\ingroup jkqtmathtext_general
|
||||
\ingroup jkqtmathtext_general_latex
|
||||
|
||||
\tableofcontents
|
||||
|
||||
|
@ -57,6 +57,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<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>
|
||||
<li>BREAKING/REWORKED: Separated the LaTeX parser into JKQTMathTextLatexParser from JKQTMathText</li>
|
||||
<li>BREAKING/CLEANUP: cleanup: Removed Parameter prevNodeSize from JKQTMathTextNode::draw() and JKQTMathTextNode::getSize()/JKQTMathTextNode::getSizeInternal(), since it is only really necessary for JKQTMathTextSubscriptNode and JKQTMathTextSuperscriptNode</li>
|
||||
<li>BREAKING/CLEANUP: using JKQTMathTextNodeSize for all size-calculation functions and got rid of all functions that take the output parameters with call-by-reference, additional information can be outut by local size-classes that derive from JKQTMathTextNodeSize, see e.g. JKQTMathTextSymbolNode::NodeSize and JKQTMathTextSymbolNode::getSymbolSize()</li>
|
||||
<li>NEW: JKQTMathTextVerticalListNode allows to typeset a vertical list of lines</li>
|
||||
|
@ -685,7 +685,7 @@ void TestForm::updateMath()
|
||||
double durationParse=0;
|
||||
if (mt.parse(mathTest)) {
|
||||
durationParse=ht.getTime()/1000.0;
|
||||
ui->tree->addTopLevelItem(createTree(mt.getParsedNode()));
|
||||
ui->tree->addTopLevelItem(createTree(mt.getNodeTree()));
|
||||
} else {
|
||||
durationParse=ht.getTime()/1000.0;
|
||||
}
|
||||
|
@ -25,8 +25,10 @@ isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) {
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextnodetools.h \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextnoopnode.h \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextverbatimnode.h \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.cpp \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.cpp
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.h \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.h \
|
||||
$$PWD/jkqtmathtext/parsers/jkqtmathtextparser.h \
|
||||
$$PWD/jkqtmathtext/parsers/jkqtmathtextlatexparser.h
|
||||
|
||||
|
||||
SOURCES += $$PWD/jkqtmathtext/jkqtmathtext.cpp \
|
||||
@ -49,7 +51,9 @@ isEmpty(JKQTP_MATHTEXT_PRI_INCLUDED) {
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextnoopnode.cpp \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextverbatimnode.cpp \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextboxinstructionnode.cpp \
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.cpp
|
||||
$$PWD/jkqtmathtext/nodes/jkqtmathtextmodifyenvironmentnode.cpp\
|
||||
$$PWD/jkqtmathtext/parsers/jkqtmathtextparser.cpp \
|
||||
$$PWD/jkqtmathtext/parsers/jkqtmathtextlatexparser.cpp
|
||||
|
||||
include($$PWD/jkqtmathtext/resources/xits.pri)
|
||||
DEFINES += AUTOLOAD_XITS_FONTS
|
||||
|
@ -46,6 +46,11 @@ set(SOURCES_NODES
|
||||
${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextverbatimnode.cpp
|
||||
)
|
||||
|
||||
set(SOURCES_PARSERS
|
||||
${CMAKE_CURRENT_LIST_DIR}/parsers/jkqtmathtextparser.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/parsers/jkqtmathtextlatexparser.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/jkqtmathtext.h>
|
||||
$<INSTALL_INTERFACE:jkqtmathtext.h>
|
||||
@ -56,6 +61,7 @@ set(HEADERS
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/jkqtmathtext_imexport.h>
|
||||
$<INSTALL_INTERFACE:jkqtmathtext_imexport.h>
|
||||
)
|
||||
|
||||
set(HEADERS_NODES
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/nodes/jkqtmathtextnode.h>
|
||||
$<INSTALL_INTERFACE:nodes/jkqtmathtextnode.h>
|
||||
@ -97,6 +103,14 @@ set(HEADERS_NODES
|
||||
$<INSTALL_INTERFACE:nodes/jkqtmathtextverbatimnode.h>
|
||||
)
|
||||
|
||||
|
||||
set(HEADERS_PARSERS
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/parsers/jkqtmathtextparser.h>
|
||||
$<INSTALL_INTERFACE:parsers/jkqtmathtextparser.h>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/parsers/jkqtmathtextlatexparser.h>
|
||||
$<INSTALL_INTERFACE:parsers/jkqtmathtextlatexparser.h>
|
||||
)
|
||||
|
||||
if(JKQtPlotter_BUILD_INCLUDE_XITS_FONTS)
|
||||
set(RESOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/resources/xits.qrc
|
||||
@ -136,7 +150,7 @@ function(JKQtMathText_setDefaultLibOptions TARGETNAME)
|
||||
endfunction()
|
||||
|
||||
if(JKQtPlotter_BUILD_SHARED_LIBS)
|
||||
add_library(${libsh_name} SHARED ${SOURCES} ${RESOURCES} ${HEADERS} ${SOURCES_NODES} ${HEADERS_NODES} )
|
||||
add_library(${libsh_name} SHARED ${SOURCES} ${RESOURCES} ${HEADERS} ${SOURCES_NODES} ${HEADERS_NODES} ${SOURCES_PARSERS} ${HEADERS_PARSERS})
|
||||
JKQtMathText_setDefaultLibOptions(${libsh_name})
|
||||
set_property(TARGET ${libsh_name} PROPERTY OUTPUT_NAME "${libsh_name_decorated}")
|
||||
target_link_libraries(${libsh_name} PUBLIC JKQTCommonSharedLib)
|
||||
@ -149,7 +163,7 @@ if(JKQtPlotter_BUILD_SHARED_LIBS)
|
||||
endif()
|
||||
|
||||
if(JKQtPlotter_BUILD_STATIC_LIBS)
|
||||
add_library(${lib_name} STATIC ${SOURCES} ${RESOURCES} ${HEADERS} ${SOURCES_NODES} ${HEADERS_NODES})
|
||||
add_library(${lib_name} STATIC ${SOURCES} ${RESOURCES} ${HEADERS} ${SOURCES_NODES} ${HEADERS_NODES} ${SOURCES_PARSERS} ${HEADERS_PARSERS})
|
||||
JKQtMathText_setDefaultLibOptions(${lib_name})
|
||||
set_property(TARGET ${lib_name} PROPERTY OUTPUT_NAME "${lib_name_decorated}")
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,34 +34,48 @@
|
||||
#include <QFile>
|
||||
#include "jkqtmathtext/jkqtmathtext_imexport.h"
|
||||
#include "jkqtmathtext/jkqtmathtexttools.h"
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QHash>
|
||||
#include <QPicture>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
|
||||
class JKQTMathTextNode; // forward
|
||||
class JKQTMathTextParser; // forward
|
||||
class JKQTMathTextVerticalListNode; // forward
|
||||
|
||||
/*! \brief this class parses a LaTeX string and can then draw the contained text/equation onto a <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||
/*! \brief this class parses a mathematical markup string and can then draw the contained text/equation onto a <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
|
||||
\ingroup jkqtmathtext_render
|
||||
|
||||
|
||||
JKQTMathText is a self-contained LaTeX-renderer for Qt. It is used to renderer
|
||||
JKQTMathText is a self-contained mathematical markup renderer for Qt. It is used to renderer
|
||||
labels in JKQTPlotter/JKQTBasePlotter, but can be used independently.
|
||||
The class does not depend on any library, except Qt.
|
||||
In particular it actually parses a LaTeX string and draws it in pure C++. It does NOT rely
|
||||
|
||||
The implementation is split over several classes:
|
||||
- JKQTMathText implements drawing, based on a memory representatioj of the markup. It also provides an interface for class users.
|
||||
- JKQTMathTextParser and its children like JKQTMathTextLatexParser parses mathamtical markup.
|
||||
- The nodes summarized in \ref jkqtmathtext_nodes are used to build the memory representation of the markup.
|
||||
.
|
||||
|
||||
In particular JKQTMathTextLatexParser actually parses e.g. a LaTeX string and draws it in pure C++. It does NOT rely
|
||||
on an installed LaTeX for the rendering!
|
||||
|
||||
\see See \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
|
||||
and \ref jkqtmathtext_renderingmodel for a description of the rendering model.
|
||||
and \ref jkqtmathtext_renderingmodel for a description of the rendering model of JKQTMathTextLatexParser.
|
||||
|
||||
|
||||
\section JKQTMathTextUsage Usage
|
||||
|
||||
\subsection JKQTMathTextUsageParsing Parsing Functions
|
||||
The class provieds two flavours of a parsing function:
|
||||
- There is a function \c parse(markup, markupType) that accepts the markup, the type of markup (as enum DefaultParserTypes) and parser options.
|
||||
This function determines the appropriate parser class, based on the markup type.
|
||||
- A templated function parse<TParser>(markup, options) that gets a parser class to be used on the markup.
|
||||
.
|
||||
|
||||
\subsection JKQTMathTextUsageDirect Drawing Functions
|
||||
The class provides different variants of the drawing function draw() that paints using an
|
||||
externlly provided <a href="https://doc.qt.io/qt-6/qpainter.html">QPainter</a>. These variants
|
||||
@ -72,6 +86,8 @@ class JKQTMathTextVerticalListNode; // forward
|
||||
|
||||
\image html jkqtmathtext/jkqtmathtext_node_geo.png
|
||||
|
||||
Note that you first need to call one of the \ref JKQTMathTextUsageParsing so there is anything to render!
|
||||
|
||||
|
||||
|
||||
\subsection JKQTMathTextUsageConvenience Convenience Functions
|
||||
@ -203,6 +219,9 @@ class JKQTMathTextVerticalListNode; // forward
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
friend class JKQTMathTextParser;
|
||||
friend class JKQTMathTextNode;
|
||||
|
||||
/** \brief minimum linewidth allowed in a JKQTMathText (given in pt) */
|
||||
static const double ABS_MIN_LINEWIDTH;
|
||||
|
||||
@ -224,14 +243,42 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
};
|
||||
Q_DECLARE_FLAGS(ParseOptions, ParseOption)
|
||||
Q_FLAG(ParseOptions)
|
||||
/** \brief parse the given LaTeX string.
|
||||
/** \brief lists the parser classes that are available by default (convenience interface to the templated parse()-funktion */
|
||||
enum DefaultParserTypes {
|
||||
LatexParser, /*!< \brief use the LaTeX parser from JKQTMathTextLatexParser */
|
||||
DefaultParser=LatexParser
|
||||
};
|
||||
/** \brief parse the given math \a markup string with a parser derived from \a markuptType.
|
||||
*
|
||||
* \param markup the string of math markup
|
||||
* \param markupType defines the language the \a markup is written in (and is used to derive the parser to use)
|
||||
* \param options Options for parsing, \see ParseOptions
|
||||
* \param allowLinebreaks
|
||||
*
|
||||
* \returns \c true on success.
|
||||
*/
|
||||
bool parse(const QString &text, ParseOptions options=DefaultParseOptions);
|
||||
bool parse(const QString &markup, DefaultParserTypes markuptType=DefaultParser, ParseOptions options=DefaultParseOptions);
|
||||
/** \brief parse the given math \a markup string, using the given parser class \a TParser
|
||||
*
|
||||
* \tparam TParser the parser (deived from JKQTMathTextParser) to be used
|
||||
* \param markup the string of math markup
|
||||
* \param options Options for parsing, \see ParseOptions
|
||||
*
|
||||
* \returns \c true on success.
|
||||
*/
|
||||
template <class TParser>
|
||||
inline bool parse(const QString &markup, ParseOptions options=DefaultParseOptions) {
|
||||
static_assert(std::is_base_of<JKQTMathTextParser, TParser>::value, "in parse<TParser>() the type TParser has to be derived from JKQTMathTextParser to work!");
|
||||
std::unique_ptr<TParser> p=std::make_unique<TParser>(this);
|
||||
if (parsedNode) delete parsedNode;
|
||||
parsedNode=nullptr;
|
||||
clearErrorList();
|
||||
parsedNode=p->parse(markup, options);
|
||||
return parsedNode!=nullptr;
|
||||
}
|
||||
/** \brief returns the syntax tree of JKQTMathTextNode's that was created by the last parse() call */
|
||||
JKQTMathTextNode* getNodeTree() ;
|
||||
/** \copydoc parsedNode */
|
||||
const JKQTMathTextNode *getNodeTree() const;
|
||||
|
||||
/** \brief get the size of the drawn representation. returns an invalid size if no text has been parsed. */
|
||||
QSizeF getSize(QPainter& painter);
|
||||
@ -652,12 +699,15 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
QStringList getErrorList() const;
|
||||
/** \brief returns \c true when errors were registered in the system \see error_list */
|
||||
bool hadErrors() const;
|
||||
protected:
|
||||
/** \copydoc error_list */
|
||||
void addToErrorList(const QString& error);
|
||||
/** \brief clears all registered errors (see error_list)
|
||||
*/
|
||||
void clearErrorList();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
/** \brief table with font replacements to use (e.g. if it is known that a certain font is not good for rendering, you can add
|
||||
* an alternative using addReplacementFont(). These are automatically applied, when setting a new font name! */
|
||||
QMap<QString, QString> fontReplacements;
|
||||
@ -885,114 +935,10 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathText : public QObject {
|
||||
*/
|
||||
QStringList error_list;
|
||||
|
||||
/** \brief the result of parsing the last string supplied to the object via parse() */
|
||||
/** \brief the syntax tree of JKQTMathTextNode's that was created by the last parse() call */
|
||||
JKQTMathTextNode* parsedNode;
|
||||
|
||||
/** \brief returns the syntax tree of JKQTMathTextNode's that was created by the last parse call */
|
||||
JKQTMathTextNode* getNodeTree() const;
|
||||
|
||||
/** \brief the token types that may arrise in the string */
|
||||
enum tokenType {
|
||||
MTTnone, /*!< \brief no token */
|
||||
MTTtext, /*!< \brief a piece of general text */
|
||||
MTTinstruction, /*!< \brief an instruction, started by \c "\", e.g. \c "\\textbf", ... */
|
||||
MTTinstructionNewline, /*!< \brief a newline instruction \c "\\" */
|
||||
MTTinstructionVerbatim, /*!< \brief a verbatim instruction, e.g. \c \\verb!verbatimtext! was found: currentTokenName will contain the text enclode by the verbatim delimiters */
|
||||
MTTinstructionVerbatimVisibleSpace, /*!< \brief a verbatim instruction that generates visible whitespaces, e.g. \c \\begin{verbatim}...\\end{verbatim} was found: currentTokenName will contain the text enclode by the verbatim delimiters */
|
||||
MTTinstructionBegin, /*!< \brief a \c '\\begin{...}' instruction, currentTokenName is the name of the environment */
|
||||
MTTinstructionEnd, /*!< \brief a \c '\\end{...}' instruction, currentTokenName is the name of the environment */
|
||||
MTTunderscore, /*!< \brief the character \c "_" */
|
||||
MTThat, /*!< \brief the character \c "^" */
|
||||
MTTdollar, /*!< \brief the character \c "$" */
|
||||
MTTopenbrace, /*!< \brief the character \c "{" */
|
||||
MTTclosebrace, /*!< \brief the character \c "}" */
|
||||
MTTopenbracket, /*!< \brief the character \c "[" */
|
||||
MTTclosebracket, /*!< \brief the character \c "]" */
|
||||
MTTwhitespace, /*!< \brief some whitespace */
|
||||
MTTampersand, /*!< \brief the character \c "&" */
|
||||
MTThyphen, /*!< \brief the single hyphen character \c "-" in text-mode \note MTTendash and MTTemdash take precedence over MTThypen */
|
||||
MTTendash, /*!< \brief the en-dash character sequence \c "--" in text-mode */
|
||||
MTTemdash, /*!< \brief the em-dash character sequence \c "---" in text-mode */
|
||||
|
||||
};
|
||||
/** \brief convert a tokenType into a string, e.g. for debugging output */
|
||||
static QString tokenType2String(tokenType type);
|
||||
|
||||
/** \brief tokenizer for the LaTeX parser */
|
||||
tokenType getToken();
|
||||
/** \brief returns some characters to the Tokenizer */
|
||||
void giveBackToTokenizer(size_t count);
|
||||
/** \brief parse a LaTeX string
|
||||
*
|
||||
* \param get if \c true this calls getToken()
|
||||
* \param quitOnClosingBrace if unequal MTBTAny, this returns if the given closing brace is found
|
||||
* \param quitOnEnvironmentEnd wuit if \c \\end{quitOnEnvironmentEnd} is found
|
||||
* \param quitOnClosingBracket if \c true, quits on encountering a MTTclosebracket token
|
||||
*/
|
||||
JKQTMathTextNode* parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace=JKQTMathTextBraceType::MTBTAny, const QString& quitOnEnvironmentEnd=QString(""), bool quitOnClosingBracket=false);
|
||||
/** \brief parse a LaTeX string with linebreaks
|
||||
*
|
||||
* \param get if \c true this calls getToken()
|
||||
* \param quitOnEnvironmentEnd wuit if \c \\end{quitOnEnvironmentEnd} is found
|
||||
* \param _alignment horizontal alignment of the JKQTMathTextVerticalListNode \see JKQTMathTextVerticalListNode::alignment and JKQTMathTextHorizontalAlignment
|
||||
* \param _linespacingFactor line spacing factor of the lines \see JKQTMathTextVerticalListNode::linespacingFactor
|
||||
* \param spacingMode_ spacing mode/algorithm for the lines \see JKQTMathTextLineSpacingMode and JKQTMathTextLineSpacingMode
|
||||
* \param _verticalOrientation vertical orientation of the block of all lines, see JKQTMathTextVerticalListNode::verticalOrientation and JKQTMathTextVerticalOrientation
|
||||
*
|
||||
* \returns JKQTMathTextVerticalListNode with the lines as children
|
||||
*/
|
||||
JKQTMathTextVerticalListNode *parseMultilineLatexString(bool get, const QString& quitOnEnvironmentEnd=QString(""), JKQTMathTextHorizontalAlignment _alignment=MTHALeft, double _linespacingFactor=1.0, JKQTMathTextLineSpacingMode spacingMode_=MTSMDefaultSpacing, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine);
|
||||
/** \brief parses a list of string-arguments, i.e. \c {p1}{p2}{...}
|
||||
*
|
||||
* \param get call getToken() at the start, otherwise it is expected that currentToken==MTTopenbrace
|
||||
* \param Nparams the number of parameters to expect
|
||||
* \param[out] foundError will be set to \c true if an error occured (unexpected token) or \c false otherwise
|
||||
* \return the list of parameter strings with Nparam entries or an empty or partial list on error
|
||||
*/
|
||||
QStringList parseStringParams(bool get, size_t Nparams, bool *foundError=nullptr);
|
||||
/** \brief parses a string, i.e. a sequence of text and whitespaces. returns after any other token was found */
|
||||
QString parseSingleString(bool get);
|
||||
/** \brief read all text without tokenizing, until the sequence \a endsequence is found.
|
||||
*
|
||||
* \param get if \c true the functions begins by reading a new character, otherwise the current character is used as first character
|
||||
* \param endsequence the sequence, ending the read
|
||||
* \param removeFirstlineWhitespace if \c true the returned string does not contain the first whitespace-line and a possible trailing whitespace line
|
||||
* \return the read string, excluding the \a endsequence
|
||||
*/
|
||||
QString readUntil(bool get, const QString& endsequence, bool removeFirstlineWhitespace=false);
|
||||
/** \brief parses a single instruction (including it's parameters)
|
||||
*
|
||||
* \param[out] _foundError will be set to \c true if an error occured (unexpected token) or \c false otherwise
|
||||
* \param[out] getNew returns \c true if the parser has to call getToken() to go on
|
||||
* \return the instruction node or \c nullptr on error (then also \a _foundError is set \c true )
|
||||
* \note This method expects the current token currentToken to be MTTinstruction
|
||||
*/
|
||||
JKQTMathTextNode* parseInstruction(bool *_foundError=nullptr, bool* getNew=nullptr);
|
||||
/** \brief parse a LaTeX math environment */
|
||||
JKQTMathTextNode* parseMath(bool get);
|
||||
|
||||
/** \brief used by the tokenizer. type of the current token */
|
||||
tokenType currentToken;
|
||||
/** \brief the JKQTMathTextBraceType associated with the last \c \\right command the parser encountered */
|
||||
JKQTMathTextBraceType lastRightBraceType;
|
||||
/** \brief returns the number of \c \\hline , \c \\hdashline , ... commands in the last parseLatexString() call */
|
||||
QMap<QString,size_t> 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 */
|
||||
int currentTokenID;
|
||||
/** \brief used by the tokenizer. The string to be parsed */
|
||||
QString parseString;
|
||||
/** \brief used by the parser. indicates whether we are in a math environment */
|
||||
bool parsingMathEnvironment;
|
||||
/** \brief used by the parser. indicates whether to use textstyle or displaystyle in math-mode */
|
||||
bool parsinginMathTextStyle;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/** \copydoc parsedNode */
|
||||
JKQTMathTextNode *getParsedNode() const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -297,7 +297,7 @@ void JKQTMathTextMatrixNode::parseColumnSpec(const QString &columnSpec)
|
||||
verticalLineRHSColumn[columnAlignment.size()-1]=LTdashed;
|
||||
}
|
||||
} else if (!columnSpec[i].isSpace()){
|
||||
parentMathText->addToErrorList(QString("array spec has unknown character '%1' (full spec was '%2')").arg(columnSpec[i]).arg(columnSpec));
|
||||
addToErrorList(QString("array spec has unknown character '%1' (full spec was '%2')").arg(columnSpec[i]).arg(columnSpec));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -114,6 +114,11 @@ void JKQTMathTextNode::doDrawBoxes(QPainter& painter, double x, double y, JKQTMa
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTMathTextNode::addToErrorList(const QString &error)
|
||||
{
|
||||
parentMathText->addToErrorList(error);
|
||||
}
|
||||
|
||||
void JKQTMathTextNode::setDrawBoxes(bool draw)
|
||||
{
|
||||
this->drawBoxes=draw;
|
||||
|
@ -160,6 +160,13 @@ class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextNode {
|
||||
}
|
||||
return lst;
|
||||
}
|
||||
|
||||
/** \brief adds a new error to the JKQTMathText referenced by parentMathText
|
||||
*
|
||||
* \see JKQTMathText::addToErrorList()
|
||||
*/
|
||||
void addToErrorList(const QString& error);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
1346
lib/jkqtmathtext/parsers/jkqtmathtextlatexparser.cpp
Normal file
1346
lib/jkqtmathtext/parsers/jkqtmathtextlatexparser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
204
lib/jkqtmathtext/parsers/jkqtmathtextlatexparser.h
Normal file
204
lib/jkqtmathtext/parsers/jkqtmathtextlatexparser.h
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
with contributions from: Razi Alavizadeh
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef JKQTMATHTEXTLATEXPARSER_H
|
||||
#define JKQTMATHTEXTLATEXPARSER_H
|
||||
|
||||
#include "jkqtmathtext/parsers/jkqtmathtextparser.h"
|
||||
#include "jkqtmathtext/jkqtmathtext.h"
|
||||
#include "jkqtmathtext/jkqtmathtext_imexport.h"
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
|
||||
class JKQTMathTextNode; // forward
|
||||
class JKQTMathTextVerticalListNode; // forward
|
||||
|
||||
/*! \brief a LaTeX parser for JKQTMathText
|
||||
\ingroup jkqtmathtext_parser
|
||||
|
||||
|
||||
JKQTMathText is a self-contained mathematical markup renderer for Qt. It is used to renderer
|
||||
labels in JKQTPlotter/JKQTBasePlotter, but can be used independently.
|
||||
|
||||
That class is responsible for rendering a memory representation of mathematical markup,
|
||||
but relies on the current class JKQTMathTextLatexParser to parse a LaTeX string into
|
||||
the mentioned memory representation.
|
||||
|
||||
\see See \ref jkqtmathtext_supportedlatex for a description of the supported LaTeX subset
|
||||
and \ref jkqtmathtext_renderingmodel for a description of the rendering model.
|
||||
|
||||
In particular JKQTMathTextLatexParser actually parses e.g. a LaTeX string and draws it in pure C++. It does NOT rely
|
||||
on an installed LaTeX for the rendering!
|
||||
|
||||
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextLatexParser : public JKQTMathTextParser {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/** \brief class constructor */
|
||||
JKQTMathTextLatexParser(JKQTMathText * parent = nullptr);
|
||||
/** \brief class destructor */
|
||||
~JKQTMathTextLatexParser();
|
||||
|
||||
virtual JKQTMathTextNode* parse(const QString &text, JKQTMathText::ParseOptions options=JKQTMathText::DefaultParseOptions) override;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** \brief the token types that may arrise in the string */
|
||||
enum tokenType {
|
||||
MTTnone, /*!< \brief no token */
|
||||
MTTtext, /*!< \brief a piece of general text */
|
||||
MTTinstruction, /*!< \brief an instruction, started by \c "\", e.g. \c "\\textbf", ... */
|
||||
MTTinstructionNewline, /*!< \brief a newline instruction \c "\\" */
|
||||
MTTinstructionVerbatim, /*!< \brief a verbatim instruction, e.g. \c \\verb!verbatimtext! was found: currentTokenName will contain the text enclode by the verbatim delimiters */
|
||||
MTTinstructionVerbatimVisibleSpace, /*!< \brief a verbatim instruction that generates visible whitespaces, e.g. \c \\begin{verbatim}...\\end{verbatim} was found: currentTokenName will contain the text enclode by the verbatim delimiters */
|
||||
MTTinstructionBegin, /*!< \brief a \c '\\begin{...}' instruction, currentTokenName is the name of the environment */
|
||||
MTTinstructionEnd, /*!< \brief a \c '\\end{...}' instruction, currentTokenName is the name of the environment */
|
||||
MTTunderscore, /*!< \brief the character \c "_" */
|
||||
MTThat, /*!< \brief the character \c "^" */
|
||||
MTTdollar, /*!< \brief the character \c "$" */
|
||||
MTTopenbrace, /*!< \brief the character \c "{" */
|
||||
MTTclosebrace, /*!< \brief the character \c "}" */
|
||||
MTTopenbracket, /*!< \brief the character \c "[" */
|
||||
MTTclosebracket, /*!< \brief the character \c "]" */
|
||||
MTTwhitespace, /*!< \brief some whitespace */
|
||||
MTTampersand, /*!< \brief the character \c "&" */
|
||||
MTThyphen, /*!< \brief the single hyphen character \c "-" in text-mode \note MTTendash and MTTemdash take precedence over MTThypen */
|
||||
MTTendash, /*!< \brief the en-dash character sequence \c "--" in text-mode */
|
||||
MTTemdash, /*!< \brief the em-dash character sequence \c "---" in text-mode */
|
||||
|
||||
};
|
||||
/** \brief convert a tokenType into a string, e.g. for debugging output */
|
||||
static QString tokenType2String(tokenType type);
|
||||
|
||||
/** \brief tokenizer for the LaTeX parser */
|
||||
tokenType getToken();
|
||||
/** \brief returns some characters to the Tokenizer */
|
||||
void giveBackToTokenizer(size_t count);
|
||||
/** \brief parse a LaTeX string
|
||||
*
|
||||
* \param get if \c true this calls getToken()
|
||||
* \param quitOnClosingBrace if unequal MTBTAny, this returns if the given closing brace is found
|
||||
* \param quitOnEnvironmentEnd wuit if \c \\end{quitOnEnvironmentEnd} is found
|
||||
* \param quitOnClosingBracket if \c true, quits on encountering a MTTclosebracket token
|
||||
*/
|
||||
JKQTMathTextNode* parseLatexString(bool get, JKQTMathTextBraceType quitOnClosingBrace=JKQTMathTextBraceType::MTBTAny, const QString& quitOnEnvironmentEnd=QString(""), bool quitOnClosingBracket=false);
|
||||
/** \brief parse a LaTeX string with linebreaks
|
||||
*
|
||||
* \param get if \c true this calls getToken()
|
||||
* \param quitOnEnvironmentEnd wuit if \c \\end{quitOnEnvironmentEnd} is found
|
||||
* \param _alignment horizontal alignment of the JKQTMathTextVerticalListNode \see JKQTMathTextVerticalListNode::alignment and JKQTMathTextHorizontalAlignment
|
||||
* \param _linespacingFactor line spacing factor of the lines \see JKQTMathTextVerticalListNode::linespacingFactor
|
||||
* \param spacingMode_ spacing mode/algorithm for the lines \see JKQTMathTextLineSpacingMode and JKQTMathTextLineSpacingMode
|
||||
* \param _verticalOrientation vertical orientation of the block of all lines, see JKQTMathTextVerticalListNode::verticalOrientation and JKQTMathTextVerticalOrientation
|
||||
*
|
||||
* \returns JKQTMathTextVerticalListNode with the lines as children
|
||||
*/
|
||||
JKQTMathTextVerticalListNode *parseMultilineLatexString(bool get, const QString& quitOnEnvironmentEnd=QString(""), JKQTMathTextHorizontalAlignment _alignment=MTHALeft, double _linespacingFactor=1.0, JKQTMathTextLineSpacingMode spacingMode_=MTSMDefaultSpacing, JKQTMathTextVerticalOrientation _verticalOrientation=MTVOFirstLine);
|
||||
/** \brief parses a list of string-arguments, i.e. \c {p1}{p2}{...}
|
||||
*
|
||||
* \param get call getToken() at the start, otherwise it is expected that currentToken==MTTopenbrace
|
||||
* \param Nparams the number of parameters to expect
|
||||
* \param[out] foundError will be set to \c true if an error occured (unexpected token) or \c false otherwise
|
||||
* \return the list of parameter strings with Nparam entries or an empty or partial list on error
|
||||
*/
|
||||
QStringList parseStringParams(bool get, size_t Nparams, bool *foundError=nullptr);
|
||||
/** \brief parses a string, i.e. a sequence of text and whitespaces. returns after any other token was found */
|
||||
QString parseSingleString(bool get);
|
||||
/** \brief read all text without tokenizing, until the sequence \a endsequence is found.
|
||||
*
|
||||
* \param get if \c true the functions begins by reading a new character, otherwise the current character is used as first character
|
||||
* \param endsequence the sequence, ending the read
|
||||
* \param removeFirstlineWhitespace if \c true the returned string does not contain the first whitespace-line and a possible trailing whitespace line
|
||||
* \return the read string, excluding the \a endsequence
|
||||
*/
|
||||
QString readUntil(bool get, const QString& endsequence, bool removeFirstlineWhitespace=false);
|
||||
/** \brief parses a single instruction (including it's parameters)
|
||||
*
|
||||
* \param[out] _foundError will be set to \c true if an error occured (unexpected token) or \c false otherwise
|
||||
* \param[out] getNew returns \c true if the parser has to call getToken() to go on
|
||||
* \return the instruction node or \c nullptr on error (then also \a _foundError is set \c true )
|
||||
* \note This method expects the current token currentToken to be MTTinstruction
|
||||
*/
|
||||
JKQTMathTextNode* parseInstruction(bool *_foundError=nullptr, bool* getNew=nullptr);
|
||||
/** \brief parse a LaTeX math environment */
|
||||
JKQTMathTextNode* parseMath(bool get);
|
||||
|
||||
/** \brief used by the tokenizer. type of the current token */
|
||||
tokenType currentToken;
|
||||
/** \brief the JKQTMathTextBraceType associated with the last \c \\right command the parser encountered */
|
||||
JKQTMathTextBraceType lastRightBraceType;
|
||||
/** \brief returns the number of \c \\hline , \c \\hdashline , ... commands in the last parseLatexString() call */
|
||||
QMap<QString,size_t> lastMatrixLineCommandCount;
|
||||
/** \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 */
|
||||
int currentTokenID;
|
||||
/** \brief used by the tokenizer. The string to be parsed */
|
||||
QString parseString;
|
||||
/** \brief used by the parser. indicates whether we are in a math environment */
|
||||
bool parsingMathEnvironment;
|
||||
/** \brief used by the parser. indicates whether to use textstyle or displaystyle in math-mode */
|
||||
bool parsinginMathTextStyle;
|
||||
|
||||
/** \brief characters that initiate a new token */
|
||||
static QSet<QChar> TokenCharacters;
|
||||
/** \brief characters that require special treatment in math mode */
|
||||
static QSet<QChar> mathEnvironmentSpecialChars;
|
||||
/** \brief characters that require special treatment in math mode */
|
||||
static QSet<QChar> mathEnvironmentSpecialEndChars;
|
||||
/** \brief single character instructions */
|
||||
static QSet<QChar> SingleCharInstructions;
|
||||
/** \brief maps instructions for accents in text-mode (e.g. \c \\'a or \c \\ae ) to the corresponding unicode character */
|
||||
static QHash<QString, QChar> accentLetters;
|
||||
/** \brief lists all lengths of keys in accentLetters that start with a backslash */
|
||||
static QSet<int> accentLetters_LenBackslash;
|
||||
/** \brief lists all lengths of keys in accentLetters that start with a curly brace */
|
||||
static QSet<int> accentLetters_LenCurly;
|
||||
/** \brief characters that have to be replaced by the correspcoting JKQTMathTextSymbolNode in math mode */
|
||||
static QSet<QString> mathEnvironmentSpecialText;
|
||||
/** \brief maps instructions for braces with fixed size, e.g \c \\bigl to the magnification factor of the brace versus the base font */
|
||||
static QHash<QString,double> big_instructions_family;
|
||||
|
||||
|
||||
/** \brief fills all static data structures, if they are still empty */
|
||||
static void initStaticStructures();
|
||||
};
|
||||
|
||||
|
||||
#endif // JKQTMATHTEXTLATEXPARSER_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
52
lib/jkqtmathtext/parsers/jkqtmathtextparser.cpp
Normal file
52
lib/jkqtmathtext/parsers/jkqtmathtextparser.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "jkqtmathtext/parsers/jkqtmathtextparser.h"
|
||||
#include "jkqtmathtext/jkqtmathtext.h"
|
||||
|
||||
|
||||
JKQTMathTextParser::JKQTMathTextParser(JKQTMathText* parent):
|
||||
QObject(parent), parentMathText(parent)
|
||||
{
|
||||
}
|
||||
|
||||
JKQTMathTextParser::~JKQTMathTextParser() {
|
||||
}
|
||||
|
||||
JKQTMathText *JKQTMathTextParser::getParentMathText()
|
||||
{
|
||||
return parentMathText;
|
||||
}
|
||||
|
||||
const JKQTMathText *JKQTMathTextParser::getParentMathText() const
|
||||
{
|
||||
return parentMathText;
|
||||
}
|
||||
|
||||
void JKQTMathTextParser::addToErrorList(const QString &error)
|
||||
{
|
||||
parentMathText->addToErrorList(error);
|
||||
}
|
||||
|
||||
void JKQTMathTextParser::clearErrorList()
|
||||
{
|
||||
parentMathText->clearErrorList();
|
||||
}
|
87
lib/jkqtmathtext/parsers/jkqtmathtextparser.h
Normal file
87
lib/jkqtmathtext/parsers/jkqtmathtextparser.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
with contributions from: Razi Alavizadeh
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef JKQTMATHTEXTPARSER_H
|
||||
#define JKQTMATHTEXTPARSER_H
|
||||
|
||||
#include "jkqtmathtext/jkqtmathtext_imexport.h"
|
||||
#include "jkqtmathtext/jkqtmathtext.h"
|
||||
#include <QFlags>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
|
||||
class JKQTMathTextNode; // forward
|
||||
|
||||
/*! \brief base class for all parsers used by JKQTMathText
|
||||
\ingroup jkqtmathtext_parser
|
||||
|
||||
*/
|
||||
class JKQTMATHTEXT_LIB_EXPORT JKQTMathTextParser : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** \brief class constructor */
|
||||
JKQTMathTextParser(JKQTMathText * parent = nullptr);
|
||||
/** \brief class destructor */
|
||||
virtual ~JKQTMathTextParser();
|
||||
/** \brief parse the given mathematical markup string.
|
||||
*
|
||||
* \param text the markup to be parsed
|
||||
* \param options Options for parsing, \see ParseOptions
|
||||
*
|
||||
* \returns the memory representation of the markup \c nullptr on failure.
|
||||
*/
|
||||
virtual JKQTMathTextNode* parse(const QString &text, JKQTMathText::ParseOptions options=JKQTMathText::DefaultParseOptions)=0;
|
||||
|
||||
/** \brief parentMathText */
|
||||
JKQTMathText* getParentMathText();
|
||||
/** \brief parentMathText */
|
||||
const JKQTMathText* getParentMathText() const;
|
||||
protected:
|
||||
/** \brief JKQTMathText that instanciated and uses this parser */
|
||||
JKQTMathText* parentMathText;
|
||||
/** \brief adds a new error to the JKQTMathText referenced by parentMathText
|
||||
*
|
||||
* \see JKQTMathText::addToErrorList()
|
||||
*/
|
||||
void addToErrorList(const QString& error);
|
||||
/** \brief clears the error list in the JKQTMathText referenced by parentMathText
|
||||
*
|
||||
* \see JKQTMathText::clearErrorList()
|
||||
*/
|
||||
void clearErrorList();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // JKQTMATHTEXTPARSER_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -136,7 +136,7 @@ int main(int argc, char* argv[])
|
||||
int i=1;
|
||||
fileList<<"/*!\n"
|
||||
" \\defgroup jkqtmathtext_supportedlatexsymbols Supported LaTeX-Symbols\n"
|
||||
" \\ingroup jkqtmathtext_general\n\n\\tableofcontents\n\n";
|
||||
" \\ingroup jkqtmathtext_general_latex\n\n\\tableofcontents\n\n";
|
||||
fileList<<" \\section jkqtmathtext_supportedlatexsymbols_greek Greek Letters\n";
|
||||
fileList<<" The following table lists all greek letters and their variants available in JKQTMathParser. They are defined in the node-class JKQTMathTextSymbolNode:\n";
|
||||
fileList<<" <table>\n";
|
||||
@ -512,7 +512,7 @@ int main(int argc, char* argv[])
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<mathText.getErrorList().join("\n").toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getParsedNode()).toStdString()
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getNodeTree()).toStdString()
|
||||
<<"-----------------------------------------------------------\n"
|
||||
;
|
||||
} else if (verbose) {
|
||||
@ -521,7 +521,7 @@ int main(int argc, char* argv[])
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<latex[i].toStdString()<<"\n"
|
||||
<<"-----------------------------------------------------------\n"
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getParsedNode()).toStdString()
|
||||
<<"RENDERTREE:\n"<<JKQTMathTextNodeTree2String(mathText.getNodeTree()).toStdString()
|
||||
<<"-----------------------------------------------------------\n";
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user