2022-08-20 22:19:40 +08:00
/*
2024-02-06 21:50:49 +08:00
Copyright ( c ) 2008 - 2024 Jan W . Krieger ( < jan @ jkrieger . de > )
2022-08-20 22:19:40 +08:00
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 */
2024-01-31 22:47:26 +08:00
MTTtilde , /*!< \brief the tilde character \c "~" */
2022-08-20 22:19:40 +08:00
} ;
/** \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