2019-01-26 19:28:44 +08:00
/*
2022-06-08 21:38:26 +08:00
Copyright ( c ) 2008 - 2022 Jan W . Krieger ( < jan @ jkrieger . de > )
2019-01-26 19:28:44 +08:00
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
2019-02-08 00:24:46 +08:00
the Free Software Foundation , either version 2.1 of the License , or
2019-01-26 19:28:44 +08:00
( 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/jkqtmathtext.h"
2022-06-08 21:38:26 +08:00
# include "jkqtmathtext/nodes/jkqtmathtextnode.h"
2019-05-30 04:40:02 +08:00
# include "jkqtcommon/jkqtpcodestructuring.h"
# include "jkqtcommon/jkqtpstringtools.h"
2022-06-08 21:38:26 +08:00
# include "jkqtmathtext/nodes/jkqtmathtexttextnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextbracenode.h"
# include "jkqtmathtext/nodes/jkqtmathtextdecoratednode.h"
# include "jkqtmathtext/nodes/jkqtmathtextfracnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextinstructionnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextlistnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextmatrixnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsqrtnode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsubsupernode.h"
# include "jkqtmathtext/nodes/jkqtmathtextsymbolnode.h"
2022-07-04 02:30:12 +08:00
# include "jkqtmathtext/nodes/jkqtmathtextwhitespacenode.h"
2022-06-20 04:36:38 +08:00
# include "jkqtmathtext/nodes/jkqtmathtextnodetools.h"
2019-05-30 04:40:02 +08:00
# include <cmath>
2019-01-26 19:28:44 +08:00
# include <QFontMetricsF>
# include <QDebug>
# include <QFontDatabase>
# include <typeinfo>
# include <QApplication>
2020-08-14 20:12:59 +08:00
# include <QPainterPath>
2019-01-26 19:28:44 +08:00
2022-04-21 16:57:24 +08:00
2019-02-08 00:24:46 +08:00
const double JKQTMathText : : ABS_MIN_LINEWIDTH = 0.02 ;
2019-01-26 19:28:44 +08:00
2022-06-03 19:33:18 +08:00
2019-06-30 23:34:41 +08:00
// --------------------------------------------------------------------------------------------------
// -- implementation of the JKQTMathText methods
// --------------------------------------------------------------------------------------------------
JKQTMathText : : JKQTMathText ( QObject * parent ) :
QObject ( parent )
{
2019-11-24 19:48:20 +08:00
//std::chrono::high_resolution_clock::time_point t0=std::chrono::high_resolution_clock::now();
2020-06-28 15:49:20 +08:00
initJKQTMathTextResources ( ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"init_resoucre: "<<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();
2019-06-30 23:34:41 +08:00
fontSize = 10 ;
2022-07-05 03:02:43 +08:00
fontSizeUnits = JKQTMathTextEnvironment : : POINTS ;
2022-06-27 05:42:06 +08:00
fontColor = QColor ( " black " ) ;
italic_correction_factor = 0.4 ;
2019-06-30 23:34:41 +08:00
brace_factor = 1.04 ;
2022-06-27 05:42:06 +08:00
brace_shrink_factor = 0.45 ;
brace_y_shift_factor = 0.7 ; //-1;
2022-08-12 22:50:26 +08:00
subsuper_size_factor = 0.65 ;
2022-06-26 06:28:49 +08:00
subsuper_mode_selection_by_size_factor = 1.01 ;
2019-06-30 23:34:41 +08:00
sub_shift_factor = 0.4 ;
2022-06-26 06:28:49 +08:00
super_shift_factor = 0.7 ;
special_sub_shift_factor = 0.4 ;
special_super_shift_factor = 0.4 ;
2019-06-30 23:34:41 +08:00
2022-06-09 05:52:22 +08:00
frac_factor = 1.0 ;
frac_nested_factor = 0.7 ;
2019-06-30 23:34:41 +08:00
frac_shift_factor = 0.4 ;
2022-06-27 05:42:06 +08:00
2019-06-30 23:34:41 +08:00
underbrace_factor = 0.75 ;
2022-06-28 03:09:22 +08:00
underbrace_separation_xfactor = 0.25 ;
underbrace_bracesize_xfactor = 0.5 ;
2022-06-20 18:17:32 +08:00
underset_factor = 0.7 ;
2022-06-29 05:14:31 +08:00
decoration_height_factor = 0.3 ;
2022-06-07 05:24:05 +08:00
decoration_width_reduction_Xfactor = 0.2 ;
2022-06-29 05:14:31 +08:00
decoration_separation_factor = 0.1 ;
2022-06-27 05:42:06 +08:00
2019-06-30 23:34:41 +08:00
operatorsubsuper_size_factor = 0.65 ;
2022-06-26 06:28:49 +08:00
operatorsubsuper_distance_factor = 0.25 ;
operatorsubsuper_extraspace_factor = 0.5 ;
2022-06-28 04:57:49 +08:00
intsubsuper_xcorrection_factor = 0.25 ;
intsubbesides_xcorrection_xfactor = 0.33 ;
2022-08-02 18:10:59 +08:00
mathoperator_width_factor = 1.5 ;
2022-06-26 06:28:49 +08:00
bigmathoperator_font_factor = 1.8 ;
2019-06-30 23:34:41 +08:00
2022-06-28 18:00:20 +08:00
sqrt_width_Xfactor = 0.8 ;
sqrt_height_factor = 1.2 ;
sqrt_smallfont_factor = 0.57 ;
2022-08-12 18:54:10 +08:00
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 ;
2022-08-10 18:12:30 +08:00
blackboradFontMode = MTBBDMdefault ;
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
static QString serifFont = " serif " ;
static QString sansFont = " sans " ;
static QString symbolFont = " symbol " ;
static QString scriptFont = " script " ;
static QString typewriterFont = " typewriter " ;
static QString decorativeFont = " decorative " ;
static QString blackboardFont = " blackboard " ;
static QString fracturFont = " fraktur " ;
static bool firstStart = true ;
if ( firstStart ) {
2019-11-24 19:48:20 +08:00
//t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:59:04 +08:00
firstStart = false ;
2022-06-03 04:31:39 +08:00
# if (QT_VERSION<QT_VERSION_CHECK(6, 0, 0))
QFontDatabase fdb ;
const auto fonts = fdb . families ( ) ;
# else
const auto fonts = QFontDatabase : : families ( ) ;
# endif
2019-11-24 19:48:20 +08:00
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
auto checkForFonts = [ & fonts ] ( QString & targetfont , const QStringList & fontoptions ) {
for ( auto & f : fontoptions ) {
if ( fonts . contains ( f ) ) {
targetfont = f ;
break ;
}
}
} ;
2019-06-30 23:34:41 +08:00
2019-06-30 23:59:04 +08:00
checkForFonts ( serifFont , QStringList { " Times New Roman " , " Times " , " FreeSerif " , " DejaVu Serif " } ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"check 1st font: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms";
2019-06-30 23:59:04 +08:00
checkForFonts ( sansFont , QStringList { " Arial Unicode MS " , " Arial Unicode " , " Lucida Sans Unicode " , " Arial " , " Helvetica " , " FreeSans " , " DejaVu Sans " , " Lucida Sans " } ) ;
checkForFonts ( symbolFont , QStringList { " SymbolStandard " , " Symbol " } ) ;
checkForFonts ( typewriterFont , QStringList { " Courier New " , " Courier " , " Courier Std " , " FreeMono " , " CMU Typewriter Text " , " UM Typewriter " } ) ;
checkForFonts ( blackboardFont , QStringList { " Double Stroke " , " CloisterOpenFace BT " , " GoudyHandtooled BT " , " Castellar " , " MathJax_AMS " , " Castellar Standard " , " MathJax_AMS Standard " , " Colonna MT " } ) ;
checkForFonts ( decorativeFont , QStringList { " Lucida Calligraphy " , " Cookie " , " Segoe Print " , " Comic Sans " , " Comic Sans MS " , " Gabriola " , " Gabriola Standard " , " Lucida Handwriting Kursiv " , " Lucida Handwriting " , " Pristina " , " Pristina Standard " , " MathJax_Caligraphics " } ) ;
checkForFonts ( scriptFont , QStringList { " Lucida Handwriting " , " Dancing Script " , " Amazone BT " , " ScriptS " , " ScriptC " , " ScriptC Standard " , " Script " , " Brush Script MT " , " Brush Script MT Kursiv " , " MathJax_Script " } ) ;
checkForFonts ( fracturFont , QStringList { " Old English Text MT " , " Old English Text MT Standard " , " UnifrakturMaguntia Standard " , " UnifrakturMaguntia " , " MathJax_Fraktur " , " UnifrakturCook Fett " } ) ;
2019-11-24 19:48:20 +08:00
//qDebug()<<"check all font: "<<std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-t0).count()/1000.0<<"ms";
2019-06-30 23:59:04 +08:00
}
2019-06-30 23:34:41 +08:00
2019-11-24 19:48:20 +08:00
//t0=std::chrono::high_resolution_clock::now();
2019-06-30 23:34:41 +08:00
if ( serifFont ! = " serif " ) addReplacementFont ( " serif " , serifFont ) ;
if ( sansFont ! = " sans " ) addReplacementFont ( " sans " , sansFont ) ;
if ( symbolFont ! = " symbol " ) addReplacementFont ( " symbol " , symbolFont ) ;
if ( scriptFont ! = " script " ) addReplacementFont ( " script " , scriptFont ) ;
if ( typewriterFont ! = " typewriter " ) addReplacementFont ( " typewriter " , typewriterFont ) ;
if ( decorativeFont ! = " decorative " ) addReplacementFont ( " decorative " , decorativeFont ) ;
if ( fracturFont ! = " fraktur " ) addReplacementFont ( " fraktur " , fracturFont ) ;
if ( blackboardFont ! = " blackboard " ) {
addReplacementFont ( " blackboard " , blackboardFont ) ;
}
2019-11-24 19:48:20 +08:00
//qDebug()<<"add replacement 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();
2022-07-04 02:30:12 +08:00
setFontSans ( sansFont , estimateJKQTMathTextFontEncoding ( sansFont ) ) ;
setFontMathSans ( sansFont , estimateJKQTMathTextFontEncoding ( sansFont ) ) ;
setFontTypewriter ( typewriterFont , estimateJKQTMathTextFontEncoding ( typewriterFont ) ) ;
setFontRoman ( serifFont , estimateJKQTMathTextFontEncoding ( serifFont ) ) ;
setFontMathRoman ( serifFont , estimateJKQTMathTextFontEncoding ( serifFont ) ) ;
setFontCaligraphic ( decorativeFont , estimateJKQTMathTextFontEncoding ( decorativeFont ) ) ;
if ( blackboardFont ! = " blackboard " ) {
setFontBlackboard ( blackboardFont , estimateJKQTMathTextFontEncoding ( blackboardFont ) ) ;
2022-08-10 18:12:30 +08:00
setFontBlackboradMode ( MTBBDMunicodeCharactersOrFontDirectly ) ;
2022-07-04 02:30:12 +08:00
} else {
2022-08-10 18:12:30 +08:00
setFontBlackboard ( sansFont , estimateJKQTMathTextFontEncoding ( sansFont ) ) ;
setFontBlackboradMode ( MTBBDMunicodeCharactersOrSimulate ) ;
2022-07-04 02:30:12 +08:00
}
setFontScript ( scriptFont , estimateJKQTMathTextFontEncoding ( scriptFont ) ) ;
setFontFraktur ( fracturFont , estimateJKQTMathTextFontEncoding ( fracturFont ) ) ;
setFallbackFontSymbols ( symbolFont , estimateJKQTMathTextFontEncoding ( symbolFont ) ) ;
2019-11-24 19:48:20 +08:00
//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();
2019-06-30 23:34:41 +08:00
useXITS ( ) ;
2019-11-24 19:48:20 +08:00
//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();
2019-06-30 23:34:41 +08:00
parsedNode = nullptr ;
currentToken = MTTnone ;
currentTokenName = " " ;
currentTokenID = 0 ;
parseString = " " ;
parsingMathEnvironment = false ;
}
JKQTMathText : : ~ JKQTMathText ( ) {
if ( parsedNode ! = nullptr ) delete parsedNode ;
parsedNode = nullptr ;
}
void JKQTMathText : : loadSettings ( const QSettings & settings , const QString & group ) {
fontSize = settings . value ( group + " font_size " , fontSize ) . toDouble ( ) ;
2022-07-05 03:02:43 +08:00
fontSizeUnits = JKQTMathTextEnvironment : : String2FontSizeUnit ( settings . value ( group + " font_size_units " , JKQTMathTextEnvironment : : FontSizeUnit2String ( fontSizeUnits ) ) . toString ( ) ) ;
2019-06-30 23:34:41 +08:00
fontColor = jkqtp_String2QColor ( settings . value ( group + " font_color " , jkqtp_QColor2String ( fontColor ) ) . toString ( ) ) ;
brace_factor = settings . value ( group + " brace_factor " , brace_factor ) . toDouble ( ) ;
brace_shrink_factor = settings . value ( group + " brace_shrink_factor " , brace_shrink_factor ) . toDouble ( ) ;
subsuper_size_factor = settings . value ( group + " subsuper_size_factor " , subsuper_size_factor ) . toDouble ( ) ;
2022-06-26 06:28:49 +08:00
subsuper_mode_selection_by_size_factor = settings . value ( group + " subsuper_mode_selection_by_size_factor " , subsuper_mode_selection_by_size_factor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
italic_correction_factor = settings . value ( group + " italic_correction_factor " , italic_correction_factor ) . toDouble ( ) ;
super_shift_factor = settings . value ( group + " super_shift_factor " , super_shift_factor ) . toDouble ( ) ;
sub_shift_factor = settings . value ( group + " sub_shift_factor " , sub_shift_factor ) . toDouble ( ) ;
2022-06-26 06:28:49 +08:00
special_super_shift_factor = settings . value ( group + " special_super_shift_factor " , special_super_shift_factor ) . toDouble ( ) ;
special_sub_shift_factor = settings . value ( group + " special_sub_shift_factor " , special_sub_shift_factor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
frac_factor = settings . value ( group + " frac_factor " , frac_factor ) . toDouble ( ) ;
frac_shift_factor = settings . value ( group + " frac_shift_factor " , frac_shift_factor ) . toDouble ( ) ;
underbrace_factor = settings . value ( group + " underbrace_factor " , underbrace_factor ) . toDouble ( ) ;
2022-06-28 03:09:22 +08:00
underbrace_bracesize_xfactor = settings . value ( group + " underbrace_bracesize_xfactor " , underbrace_bracesize_xfactor ) . toDouble ( ) ;
underbrace_separation_xfactor = settings . value ( group + " underbrace_separation_xfactor " , underbrace_separation_xfactor ) . toDouble ( ) ;
2022-07-04 02:30:12 +08:00
underset_factor = settings . value ( group + " underset_factor " , underset_factor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
brace_y_shift_factor = settings . value ( group + " brace_y_shift_factor " , brace_y_shift_factor ) . toDouble ( ) ;
decoration_height_factor = settings . value ( group + " decoration_height_factor " , decoration_height_factor ) . toDouble ( ) ;
2022-06-29 05:14:31 +08:00
decoration_separation_factor = settings . value ( group + " decoration_separation_factor " , decoration_separation_factor ) . toDouble ( ) ;
2022-06-07 05:24:05 +08:00
decoration_width_reduction_Xfactor = settings . value ( group + " decoration_width_reduction_xfactor " , decoration_width_reduction_Xfactor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
operatorsubsuper_size_factor = settings . value ( group + " operatorsubsuper_size_factor " , operatorsubsuper_size_factor ) . toDouble ( ) ;
2022-06-26 06:28:49 +08:00
operatorsubsuper_distance_factor = settings . value ( group + " operatorsubsuper_distance_factor " , operatorsubsuper_distance_factor ) . toDouble ( ) ;
operatorsubsuper_extraspace_factor = settings . value ( group + " operatorsubsuper_extraspace_factor " , operatorsubsuper_extraspace_factor ) . toDouble ( ) ;
2019-06-30 23:34:41 +08:00
mathoperator_width_factor = settings . value ( group + " mathoperator_width_factor " , mathoperator_width_factor ) . toDouble ( ) ;
2022-06-28 04:57:49 +08:00
intsubsuper_xcorrection_factor = settings . value ( group + " intsubsuper_xcorrection_factor " , intsubsuper_xcorrection_factor ) . toDouble ( ) ;
intsubbesides_xcorrection_xfactor = settings . value ( group + " intsubbesides_xcorrection_xfactor " , intsubbesides_xcorrection_xfactor ) . toDouble ( ) ;
2022-06-28 18:00:20 +08:00
sqrt_width_Xfactor = settings . value ( group + " sqrt_width_Xfactor " , sqrt_width_Xfactor ) . toDouble ( ) ;
sqrt_height_factor = settings . value ( group + " sqrt_height_factor " , sqrt_height_factor ) . toDouble ( ) ;
sqrt_smallfont_factor = settings . value ( group + " sqrt_smallfont_factor " , sqrt_smallfont_factor ) . toDouble ( ) ;
2022-07-04 02:30:12 +08:00
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 ( ) ;
2019-06-30 23:34:41 +08:00
2022-08-12 18:54:10 +08:00
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 ( ) ;
2019-06-30 23:34:41 +08:00
if ( settings . value ( group + " use_stix_fonts " , false ) . toBool ( ) ) useSTIX ( ) ;
if ( settings . value ( group + " use_xits_fonts " , false ) . toBool ( ) ) useXITS ( ) ;
if ( settings . value ( group + " use_asana_fonts " , false ) . toBool ( ) ) useASANA ( ) ;
}
void JKQTMathText : : saveSettings ( QSettings & settings , const QString & group ) const {
settings . setValue ( group + " font_size " , fontSize ) ;
2022-07-05 03:02:43 +08:00
settings . setValue ( group + " font_size_units " , JKQTMathTextEnvironment : : FontSizeUnit2String ( fontSizeUnits ) ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " font_color " , jkqtp_QColor2String ( fontColor ) ) ;
settings . setValue ( group + " brace_factor " , brace_factor ) ;
settings . setValue ( group + " brace_shrink_factor " , brace_shrink_factor ) ;
settings . setValue ( group + " subsuper_size_factor " , subsuper_size_factor ) ;
2022-06-26 06:28:49 +08:00
settings . setValue ( group + " subsuper_mode_selection_by_size_factor " , subsuper_mode_selection_by_size_factor ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " italic_correction_factor " , italic_correction_factor ) ;
settings . setValue ( group + " sub_shift_factor " , sub_shift_factor ) ;
settings . setValue ( group + " super_shift_factor " , super_shift_factor ) ;
2022-06-26 06:28:49 +08:00
settings . setValue ( group + " special_sub_shift_factor " , special_sub_shift_factor ) ;
settings . setValue ( group + " special_super_shift_factor " , special_super_shift_factor ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " frac_factor " , frac_factor ) ;
settings . setValue ( group + " frac_shift_factor " , frac_shift_factor ) ;
settings . setValue ( group + " underbrace_factor " , underbrace_factor ) ;
2022-06-28 03:09:22 +08:00
settings . setValue ( group + " underbrace_bracesize_xfactor " , underbrace_bracesize_xfactor ) ;
settings . setValue ( group + " underbrace_separation_xfactor " , underbrace_separation_xfactor ) ;
2022-07-04 02:30:12 +08:00
settings . setValue ( group + " underset_factor " , underset_factor ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " operatorsubsuper_size_factor " , operatorsubsuper_size_factor ) ;
2022-06-26 06:28:49 +08:00
settings . setValue ( group + " operatorsubsuper_distance_factor " , operatorsubsuper_distance_factor ) ;
settings . setValue ( group + " operatorsubsuper_extraspace_factor " , operatorsubsuper_extraspace_factor ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " mathoperator_width_factor " , mathoperator_width_factor ) ;
2022-06-28 04:57:49 +08:00
settings . setValue ( group + " intsubsuper_xcorrection_factor " , intsubsuper_xcorrection_factor ) ;
settings . setValue ( group + " intsubbesides_xcorrection_xfactor " , intsubbesides_xcorrection_xfactor ) ;
2019-06-30 23:34:41 +08:00
settings . setValue ( group + " brace_y_shift_factor " , brace_y_shift_factor ) ;
settings . setValue ( group + " decoration_height_factor " , decoration_height_factor ) ;
2022-06-29 05:14:31 +08:00
settings . setValue ( group + " decoration_separation_factor " , decoration_separation_factor ) ;
2022-06-07 05:24:05 +08:00
settings . setValue ( group + " decoration_width_reduction_xfactor " , decoration_width_reduction_Xfactor ) ;
2022-06-28 18:00:20 +08:00
settings . setValue ( group + " sqrt_width_Xfactor " , sqrt_width_Xfactor ) ;
settings . setValue ( group + " sqrt_height_factor " , sqrt_height_factor ) ;
settings . setValue ( group + " sqrt_smallfont_factor " , sqrt_smallfont_factor ) ;
2022-07-04 02:30:12 +08:00
settings . setValue ( group + " bigmathoperator_font_factor " , bigmathoperator_font_factor ) ;
settings . setValue ( group + " frac_nested_factor " , frac_nested_factor ) ;
2022-08-12 18:54:10 +08:00
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 ) ;
2019-06-30 23:34:41 +08:00
}
bool JKQTMathText : : useSTIX ( bool mathModeOnly ) {
2022-07-04 02:30:12 +08:00
const JKQTMathTextFontSpecifier stixs = JKQTMathTextFontSpecifier : : getSTIXFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-07-04 02:30:12 +08:00
if ( ! mathModeOnly & & ! stixs . fontName ( ) . isEmpty ( ) ) {
setFontRoman ( stixs . fontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-07-04 02:30:12 +08:00
if ( ! stixs . mathFontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( stixs . mathFontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( stixs . mathFontName ( ) , MTFEUnicode ) ;
2022-06-03 03:02:23 +08:00
res = true ;
2022-07-04 02:30:12 +08:00
} else if ( ! stixs . fontName ( ) . isEmpty ( ) ) {
setFontMathRoman ( stixs . fontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( stixs . fontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
return res ;
}
bool JKQTMathText : : useXITS ( bool mathModeOnly )
{
2022-06-03 03:02:23 +08:00
const JKQTMathTextFontSpecifier xits = JKQTMathTextFontSpecifier : : getXITSFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-06-03 03:02:23 +08:00
if ( ! mathModeOnly & & ! xits . fontName ( ) . isEmpty ( ) ) {
2022-07-04 02:30:12 +08:00
setFontRoman ( xits . fontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( xits . fontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-06-03 03:02:23 +08:00
if ( ! xits . mathFontName ( ) . isEmpty ( ) ) {
2022-07-04 02:30:12 +08:00
setFontMathRoman ( xits . mathFontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( xits . mathFontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
return res ;
}
bool JKQTMathText : : useASANA ( bool mathModeOnly )
{
2022-06-03 03:02:23 +08:00
const JKQTMathTextFontSpecifier asana = JKQTMathTextFontSpecifier : : getXITSFamilies ( ) ;
2019-06-30 23:34:41 +08:00
bool res = false ;
2022-06-03 03:02:23 +08:00
if ( ! mathModeOnly & & ! asana . fontName ( ) . isEmpty ( ) ) {
2022-07-04 02:30:12 +08:00
setFontRoman ( asana . fontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( asana . fontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
2022-06-03 03:02:23 +08:00
if ( ! asana . mathFontName ( ) . isEmpty ( ) ) {
2022-07-04 02:30:12 +08:00
setFontMathRoman ( asana . mathFontName ( ) , MTFEUnicode ) ;
setFallbackFontSymbols ( asana . mathFontName ( ) , MTFEUnicode ) ;
2019-06-30 23:34:41 +08:00
res = true ;
}
return res ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : useAnyUnicode ( QString timesFont , const QString & sansFont , JKQTMathTextFontEncoding encodingTimes , JKQTMathTextFontEncoding encodingSans )
2022-07-05 03:02:43 +08:00
{
if ( ! timesFont . isEmpty ( ) ) {
setFontRoman ( timesFont , encodingTimes ) ;
setFontMathRoman ( timesFont , encodingTimes ) ;
}
if ( ! sansFont . isEmpty ( ) ) {
setFontSans ( sansFont , encodingSans ) ;
setFontMathSans ( sansFont , encodingSans ) ;
}
}
void JKQTMathText : : useAnyUnicodeForMathOnly ( QString timesFont , const QString & sansFont , JKQTMathTextFontEncoding encodingTimes , JKQTMathTextFontEncoding encodingSans )
{
if ( ! timesFont . isEmpty ( ) ) { setFontMathRoman ( timesFont , encodingTimes ) ; }
if ( ! sansFont . isEmpty ( ) ) { setFontMathSans ( sansFont , encodingSans ) ; }
}
void JKQTMathText : : useAnyUnicodeForTextOnly ( QString timesFont , const QString & sansFont , JKQTMathTextFontEncoding encodingTimes , JKQTMathTextFontEncoding encodingSans )
2019-06-30 23:34:41 +08:00
{
if ( ! timesFont . isEmpty ( ) ) { setFontRoman ( timesFont , encodingTimes ) ; }
if ( ! sansFont . isEmpty ( ) ) { setFontSans ( sansFont , encodingSans ) ; }
}
QString JKQTMathText : : toHtml ( bool * ok , double fontPointSize ) {
QString s ;
bool okk = false ;
2022-06-20 18:17:32 +08:00
if ( getNodeTree ( ) ! = nullptr ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-06-30 23:34:41 +08:00
ev . color = fontColor ;
ev . fontSize = fontPointSize ;
2022-07-05 03:02:43 +08:00
ev . fontSizeUnit = JKQTMathTextEnvironment : : POINTS ;
2019-06-30 23:34:41 +08:00
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment defaultev ;
2019-06-30 23:34:41 +08:00
defaultev . fontSize = fontPointSize ;
2022-07-05 03:02:43 +08:00
defaultev . fontSizeUnit = JKQTMathTextEnvironment : : POINTS ;
2019-06-30 23:34:41 +08:00
2022-06-20 18:17:32 +08:00
okk = getNodeTree ( ) - > toHtml ( s , ev , defaultev ) ;
2019-06-30 23:34:41 +08:00
}
if ( ok ) * ok = okk ;
return s ;
}
void JKQTMathText : : setFontColor ( const QColor & __value )
{
this - > fontColor = __value ;
}
QColor JKQTMathText : : getFontColor ( ) const
{
return this - > fontColor ;
}
void JKQTMathText : : setFontSize ( double __value )
{
2022-07-05 03:02:43 +08:00
setFontPointSize ( __value ) ;
}
void JKQTMathText : : setFontPointSize ( double __value )
{
fontSize = __value ;
fontSizeUnits = JKQTMathTextEnvironment : : POINTS ;
}
void JKQTMathText : : setFontSizePixels ( double __value )
{
fontSize = __value ;
fontSizeUnits = JKQTMathTextEnvironment : : PIXELS ;
2019-06-30 23:34:41 +08:00
}
double JKQTMathText : : getFontSize ( ) const
{
2022-07-05 03:02:43 +08:00
return getFontPointSize ( ) ;
}
double JKQTMathText : : getFontPointSize ( ) const
{
if ( fontSizeUnits = = JKQTMathTextEnvironment : : POINTS ) return fontSize ;
else return - 1 ;
}
double JKQTMathText : : getFontSizePixels ( ) const
{
if ( fontSizeUnits = = JKQTMathTextEnvironment : : PIXELS ) return fontSize ;
else return - 1 ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : addReplacementFont ( const QString & nonUseFont , const QString & useFont , JKQTMathTextFontEncoding useFontEncoding ) {
2019-06-30 23:34:41 +08:00
fontReplacements . insert ( nonUseFont , useFont ) ;
fontEncodingReplacements . insert ( nonUseFont , useFontEncoding ) ;
}
void JKQTMathText : : addReplacementFont ( const QString & nonUseFont , const QString & useFont ) {
fontReplacements . insert ( nonUseFont , useFont ) ;
auto it = fontEncodingReplacements . find ( nonUseFont ) ;
if ( it ! = fontEncodingReplacements . end ( ) ) fontEncodingReplacements . erase ( it ) ;
}
2022-06-08 21:38:26 +08:00
QPair < QString , JKQTMathTextFontEncoding > JKQTMathText : : getReplacementFont ( const QString & nonUseFont , const QString & defaultFont , JKQTMathTextFontEncoding defaultFontEncoding ) const {
QPair < QString , JKQTMathTextFontEncoding > res ( defaultFont , defaultFontEncoding ) ;
2019-06-30 23:34:41 +08:00
for ( auto it = fontReplacements . begin ( ) ; it ! = fontReplacements . end ( ) ; + + it ) {
if ( it . key ( ) . toLower ( ) = = nonUseFont . toLower ( ) ) {
res . first = it . value ( ) ;
res . second = fontEncodingReplacements . value ( res . first , res . second ) ;
return res ;
}
}
return res ;
}
2022-07-04 02:30:12 +08:00
QPair < QString , JKQTMathTextFontEncoding > JKQTMathText : : getFontData ( JKQTMathTextEnvironmentFont font , bool in_math_environment ) const
2019-06-30 23:34:41 +08:00
{
2022-06-03 19:33:18 +08:00
if ( in_math_environment ) {
if ( font = = MTEroman ) font = MTEmathRoman ;
if ( font = = MTEsans ) font = MTEmathSans ;
}
2022-06-03 03:02:23 +08:00
const auto fd = fontDefinitions . value ( font ) ;
2022-06-08 21:38:26 +08:00
return QPair < QString , JKQTMathTextFontEncoding > ( fd . fontName , fd . fontEncoding ) ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRomanOrSpecial ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
2022-06-03 03:02:23 +08:00
setFontRomanOrSpecial ( JKQTMathTextFontSpecifier : : fromFontSpec ( __value ) , encoding ) ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRomanOrSpecial ( const JKQTMathTextFontSpecifier & fontName , JKQTMathTextFontEncoding encoding )
2022-06-03 03:02:23 +08:00
{
if ( ! fontName . hasMathFontName ( ) ) {
if ( fontName . fontName ( ) . toUpper ( ) = = " XITS " ) useXITS ( false ) ;
else if ( fontName . fontName ( ) . toUpper ( ) = = " STIX " ) useSTIX ( false ) ;
else if ( fontName . fontName ( ) . toUpper ( ) = = " ASANA " ) useASANA ( false ) ;
else {
setFontRoman ( fontName . fontName ( ) , encoding ) ;
setFontMathRoman ( fontName . fontName ( ) , encoding ) ;
2019-06-30 23:34:41 +08:00
}
2022-06-03 03:02:23 +08:00
} else {
if ( fontName . mathFontName ( ) . toUpper ( ) = = " XITS " ) useXITS ( true ) ;
else if ( fontName . mathFontName ( ) . toUpper ( ) = = " STIX " ) useSTIX ( true ) ;
else if ( fontName . mathFontName ( ) . toUpper ( ) = = " ASANA " ) useASANA ( true ) ;
else setFontMathRoman ( fontName . mathFontName ( ) , encoding ) ;
setFontRoman ( fontName . fontName ( ) , encoding ) ;
2019-06-30 23:34:41 +08:00
}
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontRoman ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEroman ] . fontName = f . first ;
fontDefinitions [ MTEroman ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontRoman ( ) const
{
return fontDefinitions [ MTEroman ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingRoman ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEroman ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontSans ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEsans ] . fontName = f . first ;
fontDefinitions [ MTEsans ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontSans ( ) const
{
return fontDefinitions [ MTEsans ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingSans ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEsans ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontTypewriter ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEtypewriter ] . fontName = f . first ;
fontDefinitions [ MTEtypewriter ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontTypewriter ( ) const
{
return fontDefinitions [ MTEtypewriter ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingTypewriter ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEtypewriter ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontScript ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEscript ] . fontName = f . first ;
fontDefinitions [ MTEscript ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontScript ( ) const
{
return fontDefinitions [ MTEscript ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingScript ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEscript ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontFraktur ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEfraktur ] . fontName = f . first ;
fontDefinitions [ MTEfraktur ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontFraktur ( ) const
{
return fontDefinitions [ MTEfraktur ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingFraktur ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEfraktur ] . fontEncoding ;
}
2022-07-04 02:30:12 +08:00
void JKQTMathText : : setFallbackFontSymbols ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
2022-07-04 02:30:12 +08:00
auto f = getReplacementFont ( fontName , fontName , encoding ) ;
fontDefinitions [ MTEFallbackSymbols ] . fontName = f . first ;
fontDefinitions [ MTEFallbackSymbols ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
2022-07-04 02:30:12 +08:00
QString JKQTMathText : : getFallbackFontSymbols ( ) const
2019-06-30 23:34:41 +08:00
{
2022-07-04 02:30:12 +08:00
return fontDefinitions [ MTEFallbackSymbols ] . fontName ;
2019-06-30 23:34:41 +08:00
}
2022-07-04 02:30:12 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingFallbackFontSymbols ( ) const
2019-06-30 23:34:41 +08:00
{
2022-07-04 02:30:12 +08:00
return fontDefinitions [ MTEFallbackSymbols ] . fontEncoding ;
2019-06-30 23:34:41 +08:00
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontCaligraphic ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEcaligraphic ] . fontName = f . first ;
fontDefinitions [ MTEcaligraphic ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
QString JKQTMathText : : getFontCaligraphic ( ) const
{
return fontDefinitions [ MTEcaligraphic ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingCaligraphic ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEcaligraphic ] . fontEncoding ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontMathRoman ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( fontName , fontName , encoding ) ;
fontDefinitions [ MTEmathRoman ] . fontName = f . first ;
fontDefinitions [ MTEmathRoman ] . fontEncoding = f . second ;
}
QString JKQTMathText : : getFontMathRoman ( ) const
{
return fontDefinitions [ MTEmathRoman ] . fontName ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontMathSans ( const QString & fontName , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( fontName , fontName , encoding ) ;
fontDefinitions [ MTEmathSans ] . fontName = f . first ;
fontDefinitions [ MTEmathSans ] . fontEncoding = f . second ;
}
QString JKQTMathText : : getFontMathSans ( ) const
{
return fontDefinitions [ MTEmathSans ] . fontName ;
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingMathSans ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEmathSans ] . fontEncoding ;
}
2019-01-26 19:28:44 +08:00
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingMathRoman ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEmathRoman ] . fontEncoding ;
}
2019-01-26 19:28:44 +08:00
2022-06-08 21:38:26 +08:00
void JKQTMathText : : setFontBlackboard ( const QString & __value , JKQTMathTextFontEncoding encoding )
2019-06-30 23:34:41 +08:00
{
auto f = getReplacementFont ( __value , __value , encoding ) ;
2019-11-16 22:02:48 +08:00
fontDefinitions [ MTEblackboard ] . fontName = f . first ;
fontDefinitions [ MTEblackboard ] . fontEncoding = f . second ;
2019-06-30 23:34:41 +08:00
}
2019-01-26 19:28:44 +08:00
2022-08-10 18:12:30 +08:00
JKQTMathTextBlackboradDrawingMode JKQTMathText : : getFontBlackboradMode ( ) const
2019-06-30 23:34:41 +08:00
{
2022-08-10 18:12:30 +08:00
return blackboradFontMode ;
2019-06-30 23:34:41 +08:00
}
2019-01-26 19:28:44 +08:00
2022-08-10 18:12:30 +08:00
void JKQTMathText : : setFontBlackboradMode ( JKQTMathTextBlackboradDrawingMode mode )
2019-06-30 23:34:41 +08:00
{
2022-08-10 18:12:30 +08:00
blackboradFontMode = mode ;
2019-06-30 23:34:41 +08:00
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
QString JKQTMathText : : getFontBlackboard ( ) const
{
return fontDefinitions [ MTEblackboard ] . fontName ;
2019-01-26 19:28:44 +08:00
}
2022-06-08 21:38:26 +08:00
JKQTMathTextFontEncoding JKQTMathText : : getFontEncodingBlackboard ( ) const
2019-06-30 23:34:41 +08:00
{
return fontDefinitions [ MTEblackboard ] . fontEncoding ;
2019-06-21 04:24:47 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceFactor ( double __value )
{
this - > brace_factor = __value ;
2019-03-07 06:18:29 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceFactor ( ) const
{
return this - > brace_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSubsuperSizeFactor ( double __value )
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
this - > subsuper_size_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSubsuperSizeFactor ( ) const
{
return this - > subsuper_size_factor ;
}
2019-01-26 19:28:44 +08:00
2022-06-26 06:28:49 +08:00
void JKQTMathText : : setSubsuperModeSelectionBySizeFactor ( double __value )
{
subsuper_mode_selection_by_size_factor = __value ;
}
double JKQTMathText : : getSubsuperModeSelectionBySizeFactor ( ) const
{
return subsuper_mode_selection_by_size_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setItalicCorrectionFactor ( double __value )
{
this - > italic_correction_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getItalicCorrectionFactor ( ) const
{
return this - > italic_correction_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setOperatorsubsuperSizeFactor ( double __value )
{
this - > operatorsubsuper_size_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getOperatorsubsuperSizeFactor ( ) const
{
return this - > operatorsubsuper_size_factor ;
}
2019-01-26 19:28:44 +08:00
2022-06-26 06:28:49 +08:00
void JKQTMathText : : setOperatorsubsuperDistanceFactor ( double __value )
{
this - > operatorsubsuper_distance_factor = __value ;
}
double JKQTMathText : : getOperatorsubsuperDistanceFactor ( ) const
{
return this - > operatorsubsuper_distance_factor ;
}
void JKQTMathText : : setOperatorsubsuperExtraSpaceFactor ( double __value )
{
operatorsubsuper_extraspace_factor = __value ;
}
double JKQTMathText : : getOperatorsubsuperExtraSpaceFactor ( ) const
{
return operatorsubsuper_extraspace_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setMathoperatorWidthFactor ( double __value )
{
this - > mathoperator_width_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getMathoperatorWidthFactor ( ) const
{
return this - > mathoperator_width_factor ;
}
2019-01-26 19:28:44 +08:00
2022-06-28 04:57:49 +08:00
void JKQTMathText : : setIntSubSuperXCorrectionFactor ( double __value )
{
intsubsuper_xcorrection_factor = __value ;
}
double JKQTMathText : : getIntSubSuperXCorrectionFactor ( ) const
{
return intsubsuper_xcorrection_factor ;
}
void JKQTMathText : : setIntSubBesidesXCorrectionXFactor ( double __value )
{
intsubbesides_xcorrection_xfactor = __value ;
}
double JKQTMathText : : getIntSubBesidesXCorrectionXFactor ( ) const
{
return intsubbesides_xcorrection_xfactor ;
}
2022-06-26 06:28:49 +08:00
void JKQTMathText : : setBigMathoperatorFontFactor ( double __value )
{
bigmathoperator_font_factor = __value ;
}
double JKQTMathText : : getBigMathoperatorFontFactor ( ) const
{
return bigmathoperator_font_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSuperShiftFactor ( double __value )
{
this - > super_shift_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSuperShiftFactor ( ) const
{
return this - > super_shift_factor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setSubShiftFactor ( double __value )
{
this - > sub_shift_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getSubShiftFactor ( ) const
{
return this - > sub_shift_factor ;
}
2019-01-26 19:28:44 +08:00
2022-06-26 06:28:49 +08:00
double JKQTMathText : : getSpecialSuperShiftFactor ( ) const
{
return special_super_shift_factor ;
}
void JKQTMathText : : setSpecialSuperShiftFactor ( double __value )
{
special_super_shift_factor = __value ;
}
void JKQTMathText : : setSpecialSubShiftFactor ( double __value )
{
special_sub_shift_factor = __value ;
}
double JKQTMathText : : getSpecialSubShiftFactor ( ) const
{
return special_sub_shift_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceShrinkFactor ( double __value )
{
this - > brace_shrink_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceShrinkFactor ( ) const
{
return this - > brace_shrink_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setUnderbraceFactor ( double __value )
{
this - > underbrace_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getUnderbraceFactor ( ) const
{
return this - > underbrace_factor ;
}
2019-01-26 19:28:44 +08:00
2022-06-28 03:09:22 +08:00
void JKQTMathText : : setUnderbraceSeparationXFactor ( double __value )
{
underbrace_separation_xfactor = __value ;
}
double JKQTMathText : : getUnderbraceSeparationXFactor ( ) const
{
return underbrace_separation_xfactor ;
}
void JKQTMathText : : setUnderbraceBraceSizeXFactor ( double __value )
{
underbrace_bracesize_xfactor = __value ;
}
double JKQTMathText : : getUnderbraceBraceSizeXFactor ( ) const
{
return underbrace_bracesize_xfactor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setUndersetFactor ( double __value )
{
2022-06-20 18:17:32 +08:00
this - > underset_factor = __value ;
2019-06-30 23:34:41 +08:00
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getUndersetFactor ( ) const
{
2022-06-20 18:17:32 +08:00
return this - > underset_factor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setFracFactor ( double __value )
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
this - > frac_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getFracFactor ( ) const
2019-01-26 19:28:44 +08:00
{
2019-06-30 23:34:41 +08:00
return this - > frac_factor ;
2019-01-26 19:28:44 +08:00
}
2022-06-09 05:52:22 +08:00
void JKQTMathText : : setFracNestedFactor ( double __value )
{
frac_nested_factor = __value ;
}
double JKQTMathText : : getFracNestedFactor ( ) const
{
return frac_nested_factor ;
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setFracShiftFactor ( double __value )
{
this - > frac_shift_factor = __value ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getFracShiftFactor ( ) const
{
return this - > frac_shift_factor ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setBraceYShiftFactor ( double __value )
{
this - > brace_y_shift_factor = __value ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getBraceYShiftFactor ( ) const
{
return this - > brace_y_shift_factor ;
2019-01-26 19:28:44 +08:00
}
2019-06-30 23:34:41 +08:00
void JKQTMathText : : setDecorationHeightFactor ( double __value )
{
this - > decoration_height_factor = __value ;
2019-05-06 01:31:20 +08:00
}
2019-06-30 23:34:41 +08:00
double JKQTMathText : : getDecorationHeightFactor ( ) const
2019-02-08 00:24:46 +08:00
{
2019-06-30 23:34:41 +08:00
return this - > decoration_height_factor ;
2019-02-08 00:24:46 +08:00
}
2022-06-29 05:14:31 +08:00
void JKQTMathText : : setDecorationSeparationXFactor ( double __value )
{
decoration_separation_factor = __value ;
}
double JKQTMathText : : getDecorationSeparationFactor ( ) const
{
return decoration_separation_factor ;
}
void JKQTMathText : : setDecorationWidthReductionFactor ( double __value )
2022-06-07 05:24:05 +08:00
{
decoration_width_reduction_Xfactor = __value ;
}
double JKQTMathText : : getDecorationWidthReductionXFactor ( ) const
{
return decoration_width_reduction_Xfactor ;
}
2022-06-28 18:00:20 +08:00
void JKQTMathText : : setSqrtWidthXFactor ( double __value )
{
sqrt_width_Xfactor = __value ;
}
double JKQTMathText : : getSqrtWidthXFactor ( ) const
{
return sqrt_width_Xfactor ;
}
void JKQTMathText : : setSqrtHeightFactor ( double __value )
{
sqrt_height_factor = __value ;
}
double JKQTMathText : : getSqrtHeightFactor ( ) const
{
return sqrt_height_factor ;
}
void JKQTMathText : : setSqrtSmallFontFactor ( double __value )
{
sqrt_smallfont_factor = __value ;
}
double JKQTMathText : : getSqrtSmallFontFactor ( ) const
{
return sqrt_smallfont_factor ;
}
2022-08-12 18:54:10 +08:00
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 ;
}
2019-06-30 23:34:41 +08:00
QStringList JKQTMathText : : getErrorList ( ) const {
return this - > error_list ;
2019-01-26 19:28:44 +08:00
}
2022-08-07 23:57:52 +08:00
bool JKQTMathText : : hadErrors ( ) const
{
return error_list . size ( ) > 0 ;
}
2022-06-08 21:38:26 +08:00
void JKQTMathText : : addToErrorList ( const QString & error )
{
error_list . append ( error ) ;
}
2019-01-26 19:28:44 +08:00
2019-06-30 23:34:41 +08:00
2019-01-26 19:28:44 +08:00
JKQTMathText : : tokenType JKQTMathText : : getToken ( ) {
currentTokenID + + ;
if ( currentTokenID > parseString . size ( ) - 1 ) return currentToken = MTTnone ;
QChar c = parseString [ currentTokenID ] ;
currentTokenName = " " ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// define some static sets for easy character lookup/identificattion
static QSet < QChar > TokenCharacters ;
static QSet < QChar > mathEnvironmentSpecialChars , mathEnvironmentSpecialEndChars ;
static QSet < QChar > SingleCharInstructions ;
2022-07-11 04:01:11 +08:00
static QHash < QString , QChar > accentLetters ;
static QSet < int > accentLetters_LenBackslash ;
static QSet < int > accentLetters_LenCurly ;
2022-06-19 21:11:06 +08:00
if ( TokenCharacters . size ( ) = = 0 ) {
mathEnvironmentSpecialChars < < ' ( ' < < ' [ ' < < ' | ' < < ' ) ' < < ' ] ' < < ' + ' < < ' - ' < < ' * ' < < ' / ' < < ' < ' < < ' > ' < < ' = ' ;
mathEnvironmentSpecialEndChars < < ' ( ' < < ' & ' < < ' [ ' < < ' | ' < < ' ) ' < < ' ] ' < < ' \\ ' < < ' $ ' < < ' { ' < < ' } ' < < ' _ ' < < ' ^ ' < < ' + ' < < ' - ' < < ' / ' < < ' * ' < < ' = ' < < ' < ' < < ' > ' ;
2022-08-01 17:44:38 +08:00
TokenCharacters < < ' - ' < < ' _ ' < < ' ^ ' < < ' \\ ' < < ' $ ' < < ' & ' < < ' } ' < < ' { ' < < ' [ ' < < ' ] ' ;
2022-06-19 21:11:06 +08:00
SingleCharInstructions < < ' | ' < < ' ; ' < < ' : ' < < ' ! ' < < ' , ' < < ' _ ' < < ' \\ ' < < ' $ ' < < ' % ' < < ' & ' < < ' # ' < < ' } ' < < ' { ' < < ' ' < < ' [ ' < < ' ] ' ;
2022-07-11 04:01:11 +08:00
auto fAddUml = [ ] ( const QString & cmd , const QChar & letter , const QChar & ch ) {
QString i ;
if ( cmd . size ( ) > 0 & & ! letter . isNull ( ) ) {
2022-08-03 15:55:45 +08:00
if ( cmd . size ( ) = = 1 & & ! cmd [ 0 ] . isLetter ( ) ) {
i = " \\ " + cmd + letter ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
}
2022-07-11 04:01:11 +08:00
i = " { \\ " + cmd + letter + " } " ;
accentLetters [ i ] = ch ; accentLetters_LenCurly . insert ( i . size ( ) ) ;
i = " \\ " + cmd + " { " + letter + " } " ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
} else if ( cmd . size ( ) > 0 & & letter . isNull ( ) ) {
i = " \\ " + cmd + " " ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
i = " \\ " + cmd + " \t " ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
i = " \\ " + cmd + " \n " ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
i = " \\ " + cmd + " \\ " ;
accentLetters [ i ] = ch ; accentLetters_LenBackslash . insert ( i . size ( ) ) ;
i = " { \\ " + cmd + " } " ;
accentLetters [ i ] = ch ; accentLetters_LenCurly . insert ( i . size ( ) ) ;
}
} ;
// instructions like \"{a}
fAddUml ( " \" " , ' A ' , QChar ( 0xC4 ) ) ;
fAddUml ( " \" " , ' E ' , QChar ( 0xCB ) ) ;
fAddUml ( " \" " , ' I ' , QChar ( 0xCF ) ) ;
fAddUml ( " \" " , ' O ' , QChar ( 0xD6 ) ) ;
fAddUml ( " \" " , ' U ' , QChar ( 0xDC ) ) ;
fAddUml ( " \" " , ' Y ' , QChar ( 0x178 ) ) ;
fAddUml ( " \" " , ' a ' , QChar ( 0xE4 ) ) ;
fAddUml ( " \" " , ' e ' , QChar ( 0xEB ) ) ;
fAddUml ( " \" " , ' i ' , QChar ( 0xEF ) ) ;
fAddUml ( " \" " , ' o ' , QChar ( 0xF6 ) ) ;
fAddUml ( " \" " , ' u ' , QChar ( 0xFC ) ) ;
fAddUml ( " \" " , ' y ' , QChar ( 0xFF ) ) ;
fAddUml ( " ' " , ' A ' , QChar ( 0xC1 ) ) ;
fAddUml ( " ' " , ' E ' , QChar ( 0xC9 ) ) ;
fAddUml ( " ' " , ' I ' , QChar ( 0xCD ) ) ;
fAddUml ( " ' " , ' O ' , QChar ( 0xD3 ) ) ;
fAddUml ( " ' " , ' U ' , QChar ( 0xDA ) ) ;
fAddUml ( " ' " , ' Y ' , QChar ( 0xDD ) ) ;
fAddUml ( " ' " , ' a ' , QChar ( 0xE1 ) ) ;
fAddUml ( " ' " , ' e ' , QChar ( 0xE9 ) ) ;
fAddUml ( " ' " , ' i ' , QChar ( 0xED ) ) ;
fAddUml ( " ' " , ' o ' , QChar ( 0xF3 ) ) ;
fAddUml ( " ' " , ' u ' , QChar ( 0xFA ) ) ;
fAddUml ( " ' " , ' y ' , QChar ( 0xFD ) ) ;
fAddUml ( " ' " , ' C ' , QChar ( 0x106 ) ) ;
fAddUml ( " ' " , ' c ' , QChar ( 0x107 ) ) ;
fAddUml ( " ' " , ' L ' , QChar ( 0x139 ) ) ;
fAddUml ( " ' " , ' l ' , QChar ( 0x13A ) ) ;
fAddUml ( " ' " , ' N ' , QChar ( 0x143 ) ) ;
fAddUml ( " ' " , ' n ' , QChar ( 0x144 ) ) ;
fAddUml ( " ' " , ' R ' , QChar ( 0x154 ) ) ;
fAddUml ( " ' " , ' r ' , QChar ( 0x155 ) ) ;
fAddUml ( " ' " , ' S ' , QChar ( 0x15A ) ) ;
fAddUml ( " ' " , ' s ' , QChar ( 0x15B ) ) ;
fAddUml ( " ' " , ' Z ' , QChar ( 0x179 ) ) ;
fAddUml ( " ' " , ' z ' , QChar ( 0x17A ) ) ;
fAddUml ( " ' " , ' G ' , QChar ( 0x1F4 ) ) ;
fAddUml ( " ' " , ' g ' , QChar ( 0x1F5 ) ) ;
fAddUml ( " ` " , ' A ' , QChar ( 0xC0 ) ) ;
fAddUml ( " ` " , ' E ' , QChar ( 0xC8 ) ) ;
fAddUml ( " ` " , ' I ' , QChar ( 0xCC ) ) ;
fAddUml ( " ` " , ' O ' , QChar ( 0xD2 ) ) ;
fAddUml ( " ` " , ' U ' , QChar ( 0xD9 ) ) ;
fAddUml ( " ` " , ' a ' , QChar ( 0xE0 ) ) ;
fAddUml ( " ` " , ' e ' , QChar ( 0xE8 ) ) ;
fAddUml ( " ` " , ' i ' , QChar ( 0xEC ) ) ;
fAddUml ( " ` " , ' o ' , QChar ( 0xF2 ) ) ;
fAddUml ( " ` " , ' u ' , QChar ( 0xF9 ) ) ;
fAddUml ( " ` " , ' N ' , QChar ( 0x1F8 ) ) ;
fAddUml ( " ` " , ' n ' , QChar ( 0x1F9 ) ) ;
fAddUml ( " ^ " , ' A ' , QChar ( 0xC2 ) ) ;
fAddUml ( " ^ " , ' E ' , QChar ( 0xCA ) ) ;
fAddUml ( " ^ " , ' I ' , QChar ( 0xCE ) ) ;
fAddUml ( " ^ " , ' O ' , QChar ( 0xD4 ) ) ;
fAddUml ( " ^ " , ' U ' , QChar ( 0xDB ) ) ;
fAddUml ( " ^ " , ' a ' , QChar ( 0xE2 ) ) ;
fAddUml ( " ^ " , ' e ' , QChar ( 0xEA ) ) ;
fAddUml ( " ^ " , ' i ' , QChar ( 0xEE ) ) ;
fAddUml ( " ^ " , ' o ' , QChar ( 0xF4 ) ) ;
fAddUml ( " ^ " , ' u ' , QChar ( 0xFB ) ) ;
fAddUml ( " ^ " , ' C ' , QChar ( 0x108 ) ) ;
fAddUml ( " ^ " , ' c ' , QChar ( 0x109 ) ) ;
fAddUml ( " ^ " , ' G ' , QChar ( 0x11C ) ) ;
fAddUml ( " ^ " , ' g ' , QChar ( 0x11D ) ) ;
fAddUml ( " ^ " , ' H ' , QChar ( 0x124 ) ) ;
fAddUml ( " ^ " , ' h ' , QChar ( 0x125 ) ) ;
fAddUml ( " ^ " , ' J ' , QChar ( 0x134 ) ) ;
fAddUml ( " ^ " , ' j ' , QChar ( 0x135 ) ) ;
fAddUml ( " ^ " , ' S ' , QChar ( 0x15C ) ) ;
fAddUml ( " ^ " , ' s ' , QChar ( 0x15D ) ) ;
fAddUml ( " ^ " , ' W ' , QChar ( 0x174 ) ) ;
fAddUml ( " ^ " , ' w ' , QChar ( 0x175 ) ) ;
fAddUml ( " ^ " , ' Y ' , QChar ( 0x176 ) ) ;
fAddUml ( " ^ " , ' y ' , QChar ( 0x177 ) ) ;
fAddUml ( " v " , ' C ' , QChar ( 0x10C ) ) ;
fAddUml ( " v " , ' c ' , QChar ( 0x10D ) ) ;
fAddUml ( " v " , ' D ' , QChar ( 0x10E ) ) ;
fAddUml ( " v " , ' d ' , QChar ( 0x10F ) ) ;
fAddUml ( " v " , ' E ' , QChar ( 0x11A ) ) ;
fAddUml ( " v " , ' e ' , QChar ( 0x11B ) ) ;
fAddUml ( " v " , ' L ' , QChar ( 0x13D ) ) ;
fAddUml ( " v " , ' l ' , QChar ( 0x13E ) ) ;
fAddUml ( " v " , ' N ' , QChar ( 0x147 ) ) ;
fAddUml ( " v " , ' n ' , QChar ( 0x148 ) ) ;
fAddUml ( " v " , ' R ' , QChar ( 0x158 ) ) ;
fAddUml ( " v " , ' r ' , QChar ( 0x159 ) ) ;
fAddUml ( " v " , ' S ' , QChar ( 0x160 ) ) ;
fAddUml ( " v " , ' s ' , QChar ( 0x161 ) ) ;
fAddUml ( " v " , ' T ' , QChar ( 0x164 ) ) ;
fAddUml ( " v " , ' t ' , QChar ( 0x165 ) ) ;
fAddUml ( " v " , ' Z ' , QChar ( 0x17D ) ) ;
fAddUml ( " v " , ' z ' , QChar ( 0x17E ) ) ;
fAddUml ( " v " , ' A ' , QChar ( 0x1CD ) ) ;
fAddUml ( " v " , ' a ' , QChar ( 0x1CE ) ) ;
fAddUml ( " v " , ' I ' , QChar ( 0x1CF ) ) ;
fAddUml ( " v " , ' i ' , QChar ( 0x1D0 ) ) ;
fAddUml ( " v " , ' O ' , QChar ( 0x1D1 ) ) ;
fAddUml ( " v " , ' o ' , QChar ( 0x1D2 ) ) ;
fAddUml ( " v " , ' U ' , QChar ( 0x1D3 ) ) ;
fAddUml ( " v " , ' u ' , QChar ( 0x1D4 ) ) ;
fAddUml ( " v " , ' G ' , QChar ( 0x1E6 ) ) ;
fAddUml ( " v " , ' g ' , QChar ( 0x1E7 ) ) ;
fAddUml ( " v " , ' K ' , QChar ( 0x1E8 ) ) ;
fAddUml ( " v " , ' k ' , QChar ( 0x1E9 ) ) ;
fAddUml ( " v " , ' j ' , QChar ( 0x1F0 ) ) ;
fAddUml ( " v " , ' H ' , QChar ( 0x21E ) ) ;
fAddUml ( " v " , ' h ' , QChar ( 0x21F ) ) ;
fAddUml ( " ~ " , ' A ' , QChar ( 0xC3 ) ) ;
fAddUml ( " ~ " , ' N ' , QChar ( 0xD1 ) ) ;
fAddUml ( " ~ " , ' O ' , QChar ( 0xD5 ) ) ;
fAddUml ( " ~ " , ' a ' , QChar ( 0xE3 ) ) ;
fAddUml ( " ~ " , ' n ' , QChar ( 0xF1 ) ) ;
fAddUml ( " ~ " , ' o ' , QChar ( 0xF5 ) ) ;
fAddUml ( " ~ " , ' I ' , QChar ( 0x128 ) ) ;
fAddUml ( " ~ " , ' i ' , QChar ( 0x129 ) ) ;
fAddUml ( " ~ " , ' U ' , QChar ( 0x168 ) ) ;
fAddUml ( " ~ " , ' u ' , QChar ( 0x169 ) ) ;
fAddUml ( " r " , ' A ' , QChar ( 0xC5 ) ) ;
fAddUml ( " r " , ' a ' , QChar ( 0xE5 ) ) ;
fAddUml ( " r " , ' U ' , QChar ( 0x16E ) ) ;
fAddUml ( " r " , ' u ' , QChar ( 0x16F ) ) ;
fAddUml ( " = " , ' A ' , QChar ( 0xC2 ) ) ;
fAddUml ( " = " , ' E ' , QChar ( 0xCA ) ) ;
fAddUml ( " = " , ' I ' , QChar ( 0xCE ) ) ;
fAddUml ( " = " , ' O ' , QChar ( 0xD4 ) ) ;
fAddUml ( " = " , ' U ' , QChar ( 0xDB ) ) ;
fAddUml ( " = " , ' a ' , QChar ( 0xE2 ) ) ;
fAddUml ( " = " , ' e ' , QChar ( 0xEA ) ) ;
fAddUml ( " = " , ' i ' , QChar ( 0xEE ) ) ;
fAddUml ( " = " , ' o ' , QChar ( 0xF4 ) ) ;
fAddUml ( " = " , ' u ' , QChar ( 0xFB ) ) ;
fAddUml ( " = " , ' Y ' , QChar ( 0x108 ) ) ;
fAddUml ( " = " , ' y ' , QChar ( 0x109 ) ) ;
fAddUml ( " . " , ' C ' , QChar ( 0x10A ) ) ;
fAddUml ( " . " , ' c ' , QChar ( 0x10B ) ) ;
fAddUml ( " . " , ' E ' , QChar ( 0x116 ) ) ;
fAddUml ( " . " , ' e ' , QChar ( 0x117 ) ) ;
fAddUml ( " . " , ' G ' , QChar ( 0x120 ) ) ;
fAddUml ( " . " , ' g ' , QChar ( 0x121 ) ) ;
fAddUml ( " . " , ' I ' , QChar ( 0x130 ) ) ;
fAddUml ( " . " , ' Z ' , QChar ( 0x17B ) ) ;
fAddUml ( " . " , ' z ' , QChar ( 0x17C ) ) ;
fAddUml ( " . " , ' A ' , QChar ( 0x226 ) ) ;
fAddUml ( " . " , ' a ' , QChar ( 0x227 ) ) ;
fAddUml ( " . " , ' O ' , QChar ( 0x22E ) ) ;
fAddUml ( " . " , ' o ' , QChar ( 0x22F ) ) ;
fAddUml ( " . " , ' B ' , QChar ( 0x1E02 ) ) ;
fAddUml ( " . " , ' b ' , QChar ( 0x1E03 ) ) ;
fAddUml ( " . " , ' D ' , QChar ( 0x1E0A ) ) ;
fAddUml ( " . " , ' d ' , QChar ( 0x1E0B ) ) ;
fAddUml ( " . " , ' F ' , QChar ( 0x1E1E ) ) ;
fAddUml ( " . " , ' f ' , QChar ( 0x1E1F ) ) ;
fAddUml ( " . " , ' H ' , QChar ( 0x1E22 ) ) ;
fAddUml ( " . " , ' h ' , QChar ( 0x1E23 ) ) ;
fAddUml ( " . " , ' M ' , QChar ( 0x1E40 ) ) ;
fAddUml ( " . " , ' m ' , QChar ( 0x1E41 ) ) ;
fAddUml ( " . " , ' N ' , QChar ( 0x1E44 ) ) ;
fAddUml ( " . " , ' n ' , QChar ( 0x1E45 ) ) ;
fAddUml ( " . " , ' P ' , QChar ( 0x1E56 ) ) ;
fAddUml ( " . " , ' p ' , QChar ( 0x1E57 ) ) ;
fAddUml ( " . " , ' R ' , QChar ( 0x1E58 ) ) ;
fAddUml ( " . " , ' r ' , QChar ( 0x1E59 ) ) ;
fAddUml ( " . " , ' S ' , QChar ( 0x1E60 ) ) ;
fAddUml ( " . " , ' s ' , QChar ( 0x1E61 ) ) ;
fAddUml ( " . " , ' T ' , QChar ( 0x1E6A ) ) ;
fAddUml ( " . " , ' t ' , QChar ( 0x1E6B ) ) ;
fAddUml ( " . " , ' W ' , QChar ( 0x1E86 ) ) ;
fAddUml ( " . " , ' w ' , QChar ( 0x1E87 ) ) ;
fAddUml ( " . " , ' X ' , QChar ( 0x1E8A ) ) ;
fAddUml ( " . " , ' x ' , QChar ( 0x1E8B ) ) ;
fAddUml ( " . " , ' Y ' , QChar ( 0x1E8E ) ) ;
fAddUml ( " . " , ' y ' , QChar ( 0x1E8F ) ) ;
fAddUml ( " u " , ' A ' , QChar ( 0x102 ) ) ;
fAddUml ( " u " , ' a ' , QChar ( 0x103 ) ) ;
fAddUml ( " u " , ' E ' , QChar ( 0x114 ) ) ;
fAddUml ( " u " , ' e ' , QChar ( 0x115 ) ) ;
fAddUml ( " u " , ' G ' , QChar ( 0x11E ) ) ;
fAddUml ( " u " , ' g ' , QChar ( 0x11F ) ) ;
fAddUml ( " u " , ' I ' , QChar ( 0x12C ) ) ;
fAddUml ( " u " , ' i ' , QChar ( 0x12D ) ) ;
fAddUml ( " u " , ' O ' , QChar ( 0x14E ) ) ;
fAddUml ( " u " , ' o ' , QChar ( 0x14F ) ) ;
fAddUml ( " u " , ' U ' , QChar ( 0x16C ) ) ;
fAddUml ( " u " , ' u ' , QChar ( 0x16D ) ) ;
fAddUml ( " c " , ' C ' , QChar ( 0xC7 ) ) ;
fAddUml ( " c " , ' c ' , QChar ( 0xE7 ) ) ;
fAddUml ( " c " , ' G ' , QChar ( 0x122 ) ) ;
fAddUml ( " c " , ' g ' , QChar ( 0x123 ) ) ;
fAddUml ( " c " , ' K ' , QChar ( 0x136 ) ) ;
fAddUml ( " c " , ' k ' , QChar ( 0x137 ) ) ;
fAddUml ( " c " , ' L ' , QChar ( 0x13B ) ) ;
fAddUml ( " c " , ' l ' , QChar ( 0x13C ) ) ;
fAddUml ( " c " , ' N ' , QChar ( 0x145 ) ) ;
fAddUml ( " c " , ' n ' , QChar ( 0x146 ) ) ;
fAddUml ( " c " , ' R ' , QChar ( 0x156 ) ) ;
fAddUml ( " c " , ' r ' , QChar ( 0x157 ) ) ;
fAddUml ( " c " , ' S ' , QChar ( 0x15E ) ) ;
fAddUml ( " c " , ' s ' , QChar ( 0x15F ) ) ;
fAddUml ( " c " , ' T ' , QChar ( 0x162 ) ) ;
fAddUml ( " c " , ' t ' , QChar ( 0x163 ) ) ;
fAddUml ( " c " , ' E ' , QChar ( 0x228 ) ) ;
fAddUml ( " c " , ' e ' , QChar ( 0x229 ) ) ;
fAddUml ( " c " , ' D ' , QChar ( 0x1E10 ) ) ;
fAddUml ( " c " , ' d ' , QChar ( 0x1E11 ) ) ;
fAddUml ( " c " , ' H ' , QChar ( 0x1E28 ) ) ;
fAddUml ( " c " , ' h ' , QChar ( 0x1E29 ) ) ;
2022-07-18 21:01:42 +08:00
fAddUml ( " H " , ' O ' , QChar ( 0x150 ) ) ;
fAddUml ( " H " , ' o ' , QChar ( 0x151 ) ) ;
fAddUml ( " H " , ' U ' , QChar ( 0x170 ) ) ;
fAddUml ( " H " , ' u ' , QChar ( 0x171 ) ) ;
fAddUml ( " H " , ' Y ' , QChar ( 0x4F2 ) ) ;
fAddUml ( " H " , ' y ' , QChar ( 0x4F3 ) ) ;
fAddUml ( " k " , ' A ' , QChar ( 0x104 ) ) ;
fAddUml ( " k " , ' a ' , QChar ( 0x105 ) ) ;
fAddUml ( " k " , ' E ' , QChar ( 0x118 ) ) ;
fAddUml ( " k " , ' e ' , QChar ( 0x119 ) ) ;
fAddUml ( " k " , ' I ' , QChar ( 0x12E ) ) ;
fAddUml ( " k " , ' i ' , QChar ( 0x12F ) ) ;
fAddUml ( " k " , ' U ' , QChar ( 0x172 ) ) ;
fAddUml ( " k " , ' u ' , QChar ( 0x173 ) ) ;
fAddUml ( " k " , ' O ' , QChar ( 0x1EA ) ) ;
fAddUml ( " k " , ' u ' , QChar ( 0x1EB ) ) ;
2022-07-11 04:01:11 +08:00
// ligatures, instructions without {letter}
fAddUml ( " ss " , QChar ( ) , QChar ( 0xDF ) ) ;
fAddUml ( " ae " , QChar ( ) , QChar ( 0xE6 ) ) ;
fAddUml ( " AE " , QChar ( ) , QChar ( 0xC6 ) ) ;
fAddUml ( " oe " , QChar ( ) , QChar ( 0x153 ) ) ;
fAddUml ( " OE " , QChar ( ) , QChar ( 0x152 ) ) ;
fAddUml ( " o " , QChar ( ) , QChar ( 0xF8 ) ) ;
fAddUml ( " O " , QChar ( ) , QChar ( 0xD8 ) ) ;
fAddUml ( " S " , QChar ( ) , QChar ( 0xA7 ) ) ;
fAddUml ( " l " , QChar ( ) , QChar ( 0x142 ) ) ;
fAddUml ( " L " , QChar ( ) , QChar ( 0x141 ) ) ;
fAddUml ( " aa " , QChar ( ) , QChar ( 0xE5 ) ) ;
fAddUml ( " AA " , QChar ( ) , QChar ( 0xC5 ) ) ;
2022-06-19 21:11:06 +08:00
}
2022-08-01 17:44:38 +08:00
//----------------------------------------------------------
// check for emdash "---" or endash "--"
if ( c = = ' - ' & & ! parsingMathEnvironment ) {
if ( parseString . mid ( currentTokenID , 3 ) = = " --- " ) {
currentTokenID + = 2 ;
currentTokenName = " --- " ;
return currentToken = MTTemdash ;
} else if ( parseString . mid ( currentTokenID , 2 ) = = " -- " ) {
currentTokenID + = 1 ;
currentTokenName = " -- " ;
return currentToken = MTTendash ;
} else {
currentTokenName = " - " ;
return currentToken = MTThyphen ;
}
}
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// read an instruction name
if ( c = = ' \\ ' ) {
2022-07-11 04:01:11 +08:00
//----------------------------------------------------------
// parsing accent instructions like \ss \"{a} ...
2022-08-01 19:39:34 +08:00
const QString next5 = parseString . mid ( currentTokenID , 5 ) ;
if ( ! parsingMathEnvironment & & next5 ! = " \\ char " ) {
2022-07-11 04:01:11 +08:00
for ( int len : accentLetters_LenBackslash ) {
const QString acc = parseString . mid ( currentTokenID , len ) ;
if ( acc . size ( ) = = len & & accentLetters . contains ( acc ) ) {
currentTokenName = accentLetters [ acc ] ;
currentTokenID + = acc . trimmed ( ) . size ( ) - 1 ; // forward the instruction, omit trailing whitespace in instruction
if ( acc . endsWith ( ' \\ ' ) ) currentTokenID - - ;
return currentToken = MTTtext ;
}
}
}
2019-01-26 19:28:44 +08:00
currentTokenID + + ;
if ( currentTokenID > = parseString . size ( ) - 1 ) return currentToken = MTTnone ;
c = parseString [ currentTokenID ] ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
2022-07-31 05:30:47 +08:00
// recognize linebreak "\\"
if ( c = = ' \\ ' ) {
currentTokenName = c ; // parse one-symbol instructions like \\, \& ...
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTinstructionNewline ;
}
//----------------------------------------------------------
2022-06-19 21:11:06 +08:00
// parsing single-character instruction
if ( SingleCharInstructions . contains ( c ) ) {
2019-01-26 19:28:44 +08:00
currentTokenName = c ; // parse one-symbol instructions like \\, \& ...
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTinstruction ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// letter-only instruction name
} else {
2019-01-26 19:28:44 +08:00
while ( c . isLetter ( ) & & ( currentTokenID < parseString . size ( ) ) ) {
currentTokenName + = c ;
currentTokenID + + ;
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
}
if ( ! c . isLetter ( ) ) currentTokenID - - ;
currentTokenName = currentTokenName . trimmed ( ) ;
}
//std::cout<<"found instruction node '"<<currentTokenName.toStdString()<<"'\n";
2022-06-19 21:11:06 +08:00
if ( currentTokenName . size ( ) = = 0 ) error_list . append ( tr ( " error @ ch. %1: parser encountered empty istruction " ) . arg ( currentTokenID ) ) ;
2022-08-03 21:23:14 +08:00
else if ( currentTokenName = = " newline " ) return MTTinstructionNewline ;
else if ( currentTokenName = = " linebreak " ) return MTTinstructionNewline ;
else if ( currentTokenName = = " char " ) {
2022-08-01 19:39:34 +08:00
QString num = " " ;
currentTokenID + + ;
c = parseString [ currentTokenID ] ;
if ( c = = ' " ' ) {
// match '\char"HEXDIGITS'
currentTokenID + + ;
c = parseString [ currentTokenID ] ;
while ( ( currentTokenID < parseString . size ( ) ) & & ( c . isDigit ( ) | | QString ( " aAbBcCdDeEfF " ) . contains ( c ) ) ) {
num + = c ;
currentTokenID + + ;
c = parseString [ currentTokenID ] ;
}
if ( currentTokenID < parseString . size ( ) ) currentTokenID - - ;
currentTokenName = QString : : fromStdString ( jkqtp_UnicodeToUTF8 ( num . toLongLong ( nullptr , 16 ) ) ) ;
return currentToken = MTTtext ;
} else if ( c = = ' ` ' | | c = = ' \' ' ) {
// match '\char"OCTALDIGITS'
currentTokenID + + ;
c = parseString [ currentTokenID ] ;
while ( ( currentTokenID < parseString . size ( ) ) & & ( QString ( " 01234567 " ) . contains ( c ) ) ) {
num + = c ;
currentTokenID + + ;
2022-08-08 02:33:48 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
else c = QChar ( ) ;
2022-08-01 19:39:34 +08:00
}
if ( currentTokenID < parseString . size ( ) ) currentTokenID - - ;
currentTokenName = QString : : fromStdString ( jkqtp_UnicodeToUTF8 ( num . toLongLong ( nullptr , 8 ) ) ) ;
return currentToken = MTTtext ;
} else if ( c . isDigit ( ) ) {
// match '\charDECIMALDIGITS'
while ( ( currentTokenID < parseString . size ( ) ) & & ( c . isDigit ( ) ) ) {
num + = c ;
currentTokenID + + ;
c = parseString [ currentTokenID ] ;
}
if ( currentTokenID < parseString . size ( ) ) currentTokenID - - ;
currentTokenName = QString : : fromStdString ( jkqtp_UnicodeToUTF8 ( num . toLongLong ( nullptr , 10 ) ) ) ;
return currentToken = MTTtext ;
}
2022-08-03 21:23:14 +08:00
} else if ( currentTokenName . startsWith ( " verb " ) ) {
if ( currentTokenName . size ( ) > 4 ) currentTokenID - = ( currentTokenName . size ( ) - 4 ) ;
currentTokenID + + ;
const QString verbEndChar = parseString . mid ( currentTokenID , 1 ) ;
currentTokenName = readUntil ( true , verbEndChar ) ;
return currentToken = MTTinstructionVerbatim ;
2022-08-08 04:13:31 +08:00
} else if ( currentTokenName = = " begin " ) {
2022-08-03 21:23:14 +08:00
currentTokenID + + ;
if ( parseString [ currentTokenID ] ! = ' { ' ) error_list . append ( tr ( " error @ ch. %1: didn't find '{' after ' \\ begin' " ) . arg ( currentTokenID ) ) ; // find closing brace '}' after '\\begin{name');
currentTokenName = readUntil ( true , " } " ) ;
if ( currentTokenName = = " verbatim " ) {
2022-08-13 19:37:13 +08:00
currentTokenName = readUntil ( true , " \\ end{verbatim} " , true ) ;
2022-08-03 21:23:14 +08:00
return currentToken = MTTinstructionVerbatim ;
} else if ( currentTokenName = = " verbatim* " ) {
2022-08-13 19:37:13 +08:00
currentTokenName = readUntil ( true , " \\ end{verbatim*} " , true ) ;
2022-08-03 21:23:14 +08:00
return currentToken = MTTinstructionVerbatimVisibleSpace ;
} else if ( currentTokenName = = " lstlisting " ) {
2022-08-13 19:37:13 +08:00
currentTokenName = readUntil ( true , " \\ end{lstlisting} " , true ) ;
2022-08-03 21:23:14 +08:00
return currentToken = MTTinstructionVerbatim ;
}
return currentToken = MTTinstructionBegin ;
2022-08-08 04:13:31 +08:00
} else if ( currentTokenName = = " end " ) {
2022-08-03 21:23:14 +08:00
currentTokenID + + ;
2022-08-08 04:13:31 +08:00
if ( currentTokenID > = parseString . size ( ) | | parseString [ currentTokenID ] ! = ' { ' ) error_list . append ( tr ( " error @ ch. %1: didn't find '{' after ' \\ end' " ) . arg ( currentTokenID ) ) ; // find closing brace '}' after '\\begin{name');
2022-08-03 21:23:14 +08:00
currentTokenName = readUntil ( true , " } " ) ;
return currentToken = MTTinstructionEnd ;
2022-08-01 19:39:34 +08:00
}
2019-01-26 19:28:44 +08:00
return currentToken = MTTinstruction ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for $ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' $ ' ) {
//std::cout<<"found dollar\n";
return currentToken = MTTdollar ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for & character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' & ' ) {
//std::cout<<"found ampersand\n";
return currentToken = MTTampersand ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for { character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' { ' ) {
2022-07-11 04:01:11 +08:00
//----------------------------------------------------------
// parsing accent instructions like {\ss}
if ( ! parsingMathEnvironment ) {
for ( int len : accentLetters_LenCurly ) {
const QString acc = parseString . mid ( currentTokenID , len ) ;
if ( acc . size ( ) = = len & & accentLetters . contains ( acc ) ) {
currentTokenName = accentLetters [ acc ] ;
currentTokenID + = acc . trimmed ( ) . size ( ) - 1 ; // forward the instruction, omit trailing whitespace in instruction
if ( acc . endsWith ( ' \\ ' ) ) currentTokenID - - ;
return currentToken = MTTtext ;
}
}
}
2019-01-26 19:28:44 +08:00
return currentToken = MTTopenbrace ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for } character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' } ' ) {
return currentToken = MTTclosebrace ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for [ character
} else if ( c = = ' [ ' ) {
return currentToken = MTTopenbracket ;
//----------------------------------------------------------
// check for ] character
} else if ( c = = ' ] ' ) {
return currentToken = MTTclosebracket ;
//----------------------------------------------------------
// check for _ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' _ ' ) {
return currentToken = MTTunderscore ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for ^ character
2019-01-26 19:28:44 +08:00
} else if ( c = = ' ^ ' ) {
return currentToken = MTThat ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// check for whitespace character
2019-01-26 19:28:44 +08:00
} else if ( c . isSpace ( ) ) {
while ( c . isSpace ( ) & & ( currentTokenID < parseString . size ( ) ) ) { // eat up whitespace
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
if ( ! c . isSpace ( ) ) currentTokenID - - ;
//std::cout<<"found whitespace\n";
return currentToken = MTTwhitespace ;
} else {
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// no instruction or special character => parse text
2019-01-26 19:28:44 +08:00
if ( parsingMathEnvironment ) {
// inside math environments we split texts at every brace {[(|)]} so that
2022-06-08 21:38:26 +08:00
// braces form their own JKQTMathTextTextNode and may be formated accordingly
2022-06-03 19:33:18 +08:00
if ( mathEnvironmentSpecialChars . contains ( c ) ) {
2019-01-26 19:28:44 +08:00
currentTokenName = c ;
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
}
2022-06-03 19:33:18 +08:00
while ( ! mathEnvironmentSpecialEndChars . contains ( c ) & & ( currentTokenID < parseString . size ( ) ) ) {
2019-01-26 19:28:44 +08:00
// add whitespaces only once
if ( c . isSpace ( ) ) {
if ( ! currentTokenName . isEmpty ( ) ) {
if ( ! currentTokenName [ currentTokenName . size ( ) - 1 ] . isSpace ( ) )
currentTokenName + = c ;
}
} else currentTokenName + = c ;
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
2022-06-03 19:33:18 +08:00
if ( mathEnvironmentSpecialEndChars . contains ( c ) | | c . isSpace ( ) ) currentTokenID - - ;
2019-01-26 19:28:44 +08:00
//currentTokenName=currentTokenName.trimmed();
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
} else {
2022-06-19 21:11:06 +08:00
while ( ( ! c . isSpace ( ) ) & & ! TokenCharacters . contains ( c ) & & ( currentTokenID < parseString . size ( ) ) ) {
2019-01-26 19:28:44 +08:00
// add whitespaces only once
if ( c . isSpace ( ) ) {
if ( ! currentTokenName . isEmpty ( ) ) {
if ( ! currentTokenName [ currentTokenName . size ( ) - 1 ] . isSpace ( ) )
currentTokenName + = c ;
}
} else currentTokenName + = c ;
currentTokenID + + ;
2022-06-19 21:11:06 +08:00
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
2019-01-26 19:28:44 +08:00
}
2022-06-19 21:11:06 +08:00
if ( TokenCharacters . contains ( c ) | | c . isSpace ( ) ) currentTokenID - - ;
2019-01-26 19:28:44 +08:00
//currentTokenName=currentTokenName.trimmed();
//std::cout<<"found text node '"<<currentTokenName.toStdString()<<"'\n";
return currentToken = MTTtext ;
}
}
return currentToken = MTTnone ;
}
2022-08-03 15:55:45 +08:00
void JKQTMathText : : giveBackToTokenizer ( size_t count )
{
currentTokenID - = count ;
}
2022-06-19 21:11:06 +08:00
JKQTMathTextNode * JKQTMathText : : parseLatexString ( bool get , JKQTMathTextBraceType quitOnClosingBrace , const QString & quitOnEnvironmentEnd , bool quitOnClosingBracket ) {
2022-08-12 18:54:10 +08:00
QMap < QString , size_t > countLine ;
2019-01-26 19:28:44 +08:00
//std::cout<<" entering parseLatexString()\n";
2022-07-31 05:30:47 +08:00
JKQTMathTextHorizontalListNode * nl = new JKQTMathTextHorizontalListNode ( this ) ;
2019-01-26 19:28:44 +08:00
if ( get ) getToken ( ) ;
2022-06-19 21:11:06 +08:00
//----------------------------------------------------------
// initialize some static sets for easy and fast character lookup
static QSet < QString > mathEnvironmentSpecialText ;
if ( mathEnvironmentSpecialText . size ( ) = = 0 ) {
2022-08-03 15:55:45 +08:00
mathEnvironmentSpecialText < < " + " < < " - " < < " = " < < " * " < < " < " < < " > " ;
2022-06-19 21:11:06 +08:00
}
2019-01-26 19:28:44 +08:00
bool getNew = true ;
while ( currentToken ! = MTTnone ) {
getNew = true ;
if ( currentToken = = MTTtext ) {
2022-07-11 04:01:11 +08:00
QString text = currentTokenName ;
bool addWhite = false ;
if ( ! parsingMathEnvironment ) {
getToken ( ) ;
getNew = false ;
while ( currentToken = = MTTtext | | currentToken = = MTTwhitespace ) {
if ( currentToken = = MTTtext ) {
text + = currentTokenName ;
getNew = true ;
} else if ( currentToken = = MTTwhitespace ) {
text + = " " ;
getNew = true ;
}
getToken ( ) ;
getNew = false ;
}
if ( text . size ( ) > 0 & & text [ text . size ( ) - 1 ] . isSpace ( ) ) {
addWhite = true ;
text = text . left ( text . size ( ) - 1 ) ;
}
}
2022-06-03 19:33:18 +08:00
if ( parsingMathEnvironment ) {
2022-07-04 02:30:12 +08:00
if ( mathEnvironmentSpecialText . contains ( text . trimmed ( ) ) & & JKQTMathTextSymbolNode : : hasSymbol ( text . trimmed ( ) ) ) {
2022-07-06 04:03:08 +08:00
nl - > addChild ( new JKQTMathTextSymbolNode ( this , text . trimmed ( ) ) ) ;
2022-06-03 19:33:18 +08:00
} else {
2022-06-20 04:36:38 +08:00
nl - > addChild ( new JKQTMathTextTextNode ( this , text , addWhite , parsingMathEnvironment ) ) ;
2022-06-03 19:33:18 +08:00
}
} else {
2022-06-20 04:36:38 +08:00
nl - > addChild ( new JKQTMathTextTextNode ( this , text , addWhite , parsingMathEnvironment ) ) ;
2022-06-03 19:33:18 +08:00
}
2022-07-31 05:30:47 +08:00
} else if ( currentToken = = MTTinstructionNewline ) {
break ;
2022-07-09 05:15:42 +08:00
} else if ( currentToken = = MTTwhitespace ) {
if ( ! parsingMathEnvironment ) nl - > addChild ( new JKQTMathTextWhitespaceNode ( this ) ) ;
2022-08-01 17:44:38 +08:00
} else if ( currentToken = = MTTendash ) {
nl - > addChild ( new JKQTMathTextSymbolNode ( this , " endash " ) ) ;
} else if ( currentToken = = MTTemdash ) {
nl - > addChild ( new JKQTMathTextSymbolNode ( this , " emdash " ) ) ;
} else if ( currentToken = = MTThyphen ) {
nl - > addChild ( new JKQTMathTextSymbolNode ( this , " hyphen " ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTinstruction ) {
2022-06-19 21:11:06 +08:00
const QString currentInstructionName = currentTokenName ;
if ( currentInstructionName = = " \\ " ) break ; // break on linebrak character
2022-07-09 05:15:42 +08:00
if ( currentInstructionName = = " limits " ) {
2022-07-07 04:44:02 +08:00
if ( nl - > hasChildren ( ) ) nl - > getLastChild ( ) - > setSubSuperscriptAboveBelowNode ( true ) ;
2022-07-09 05:15:42 +08:00
} else if ( currentInstructionName = = " nolimits " ) {
2022-07-07 04:44:02 +08:00
if ( nl - > hasChildren ( ) ) nl - > getLastChild ( ) - > setSubSuperscriptAboveBelowNode ( false ) ;
2022-08-12 18:54:10 +08:00
} 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 ;
2022-07-09 05:15:42 +08:00
} else if ( currentInstructionName = = " right " ) {
getToken ( ) ;
if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) > 0 ) {
bool tokenWasNoBrace = false ;
const QString firstTokenChar ( currentTokenName [ 0 ] ) ;
if ( TokenNameMatchesJKQTMathTextBraceType ( firstTokenChar , quitOnClosingBrace , true , & tokenWasNoBrace ) ) {
lastRightBraceType = TokenName2JKQTMathTextBraceType ( firstTokenChar ) ;
if ( quitOnClosingBrace ! = MTBTAny ) currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
break ;
2022-07-04 02:30:12 +08:00
} else {
getNew = false ;
2019-01-26 19:28:44 +08:00
}
2022-07-09 05:15:42 +08:00
}
} else if ( currentToken = = MTTinstruction ) {
if ( InstructionNameMatchesJKQTMathTextBraceType ( currentTokenName , quitOnClosingBrace , true ) ) {
lastRightBraceType = InstructionName2JKQTMathTextBraceType ( currentTokenName ) ;
break ;
}
} else if ( currentToken = = MTTclosebracket ) {
if ( quitOnClosingBrace = = MTBTSquareBracket | | quitOnClosingBrace = = MTBTAny ) {
lastRightBraceType = MTBTSquareBracket ;
break ;
}
} else {
error_list . append ( tr ( " error @ ch. %1: unexpected token after \\ left " ) . arg ( currentTokenID ) ) ;
}
} else if ( currentInstructionName = = " left " ) {
getToken ( ) ;
if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) > 0 ) {
const QString firstTokenChar ( currentTokenName [ 0 ] ) ;
const JKQTMathTextBraceType bracetype = TokenName2JKQTMathTextBraceType ( firstTokenChar ) ;
if ( bracetype = = MTBTNone ) {
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ;
JKQTMathTextNode * cn = parseLatexString ( currentTokenName . size ( ) < = 0 , MTBTAny ) ;
2022-08-08 02:39:45 +08:00
nl - > addChild ( new JKQTMathTextBraceNode ( this , MTBTNone , lastRightBraceType , cn ) ) ;
2022-07-09 05:15:42 +08:00
} else if ( isPrintableJKQTMathTextBraceType ( bracetype ) ) {
currentTokenName = currentTokenName . right ( currentTokenName . size ( ) - 1 ) ; // we already used the first character from the text token!
JKQTMathTextNode * c = parseLatexString ( currentTokenName . size ( ) < = 0 , bracetype ) ;
nl - > addChild ( new JKQTMathTextBraceNode ( this , bracetype , lastRightBraceType , c ) ) ;
2022-07-04 02:30:12 +08:00
} else {
2022-07-09 05:15:42 +08:00
getNew = false ;
2022-07-04 02:30:12 +08:00
}
2022-07-09 05:15:42 +08:00
}
} else if ( currentToken = = MTTinstruction ) {
const JKQTMathTextBraceType bracetypeopening = InstructionName2OpeningJKQTMathTextBraceType ( currentTokenName ) ;
if ( bracetypeopening ! = MTBTUnknown ) {
JKQTMathTextNode * c = parseLatexString ( true , bracetypeopening ) ;
nl - > addChild ( new JKQTMathTextBraceNode ( this , bracetypeopening , lastRightBraceType , c ) ) ;
} else if ( currentToken = = MTTinstruction & & TokenNameMatchesJKQTMathTextBraceType ( currentTokenName , quitOnClosingBrace , true ) ) {
break ;
}
} else if ( currentToken = = MTTopenbracket ) {
JKQTMathTextNode * c = parseLatexString ( true , MTBTSquareBracket ) ;
nl - > addChild ( new JKQTMathTextBraceNode ( this , MTBTSquareBracket , lastRightBraceType , c ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: unexpected token after \\ left " ) . arg ( currentTokenID ) ) ;
}
} else {
bool foundError = false ;
JKQTMathTextNode * node = parseInstruction ( & foundError , & getNew ) ;
if ( node ) {
if ( foundError ) {
delete node ;
node = nullptr ;
2022-06-26 06:28:49 +08:00
} else {
2022-07-09 05:15:42 +08:00
nl - > addChild ( node ) ;
2019-01-26 19:28:44 +08:00
}
}
}
} else if ( currentToken = = MTTunderscore ) {
getToken ( ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * child = nullptr ;
JKQTMathTextNode * child2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTinstruction ) {
2022-07-09 05:15:42 +08:00
child = parseInstruction ( nullptr , & getNew ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTopenbrace ) {
child = parseLatexString ( true ) ;
} else if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) < = 1 ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , currentTokenName , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , QString ( currentTokenName [ 0 ] ) , false , parsingMathEnvironment ) ;
child2 = new JKQTMathTextTextNode ( this , currentTokenName . right ( currentTokenName . size ( ) - 1 ) , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
}
} else {
getNew = false ;
}
2022-06-20 04:36:38 +08:00
if ( child ! = nullptr ) nl - > addChild ( new JKQTMathTextSubscriptNode ( this , child ) ) ;
if ( child2 ! = nullptr ) nl - > addChild ( child2 ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTThat ) {
getToken ( ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * child = nullptr ;
JKQTMathTextNode * child2 = nullptr ;
2019-01-26 19:28:44 +08:00
if ( currentToken = = MTTinstruction ) {
2022-07-09 05:15:42 +08:00
child = parseInstruction ( nullptr , & getNew ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTopenbrace ) {
child = parseLatexString ( true ) ;
} else if ( currentToken = = MTTtext ) {
if ( currentTokenName . size ( ) < = 1 ) {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , currentTokenName , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
} else {
2022-06-08 21:38:26 +08:00
child = new JKQTMathTextTextNode ( this , QString ( currentTokenName [ 0 ] ) , false , parsingMathEnvironment ) ;
child2 = new JKQTMathTextTextNode ( this , currentTokenName . right ( currentTokenName . size ( ) - 1 ) , false , parsingMathEnvironment ) ;
2019-01-26 19:28:44 +08:00
}
} else {
getNew = false ;
}
2022-06-20 04:36:38 +08:00
if ( child ! = nullptr ) nl - > addChild ( new JKQTMathTextSuperscriptNode ( this , child ) ) ;
if ( child2 ! = nullptr ) nl - > addChild ( child2 ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTopenbrace ) {
2022-06-20 04:36:38 +08:00
nl - > addChild ( parseLatexString ( true ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTclosebrace ) {
break ;
2022-06-19 21:11:06 +08:00
} else if ( currentToken = = MTTopenbracket ) {
2022-06-20 04:36:38 +08:00
nl - > addChild ( new JKQTMathTextTextNode ( this , " [ " , false ) ) ;
2022-08-03 21:23:14 +08:00
} else if ( currentToken = = MTTinstructionVerbatim ) {
nl - > addChild ( new JKQTMathTextVerbatimNode ( this , currentTokenName , false ) ) ;
} else if ( currentToken = = MTTinstructionVerbatimVisibleSpace ) {
nl - > addChild ( new JKQTMathTextVerbatimNode ( this , currentTokenName , true ) ) ;
} else if ( currentToken = = MTTinstructionBegin ) {
const QString envname = currentTokenName ;
2022-08-12 18:54:10 +08:00
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 ) ;
2022-08-03 21:23:14 +08:00
QVector < QVector < JKQTMathTextNode * > > items ;
//int lines=0;
//int cols=0;
bool first = true ;
2022-08-12 18:54:10 +08:00
bool firstLine = true ;
2022-08-03 21:23:14 +08:00
QVector < JKQTMathTextNode * > line ;
2022-08-12 18:54:10 +08:00
size_t colCount = 0 ;
2022-08-03 21:23:14 +08:00
//std::cout<<"found \\begin{matrix}\n";
while ( first | | currentToken = = MTTampersand | | currentToken = = MTTinstructionNewline ) {
2022-08-12 18:54:10 +08:00
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 ) ;
}
}
2022-08-03 21:23:14 +08:00
if ( currentToken = = MTTampersand ) {
//std::cout<<" appending item\n";
line . append ( it ) ;
} else {
//std::cout<<" appending item and line with "<<line.size()<<" items.\n";
2022-08-12 18:54:10 +08:00
if ( currentToken = = MTTinstructionEnd ) {
JKQTMathTextMultiChildNode * mnc = dynamic_cast < JKQTMathTextMultiChildNode * > ( 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 < size_t > ( 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 ) ) ;
}
}
2022-08-03 21:23:14 +08:00
line . clear ( ) ;
2022-08-12 18:54:10 +08:00
firstLine = false ;
2022-08-03 21:23:14 +08:00
}
first = false ;
}
//std::cout<<" creating matrix-node with "<<items.size()<<" items.\n";
2022-08-12 18:54:10 +08:00
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 ) ;
2022-08-03 21:23:14 +08:00
//std::cout<<" creating matrix-node ... done!\n";
} else if ( envname = = " center " | | envname = = " document " | | envname = = " flushleft " | | envname = = " flushright " ) {
JKQTMathTextHorizontalAlignment alignment = MTHALeft ;
if ( envname = = " document " ) alignment = MTHALeft ;
else alignment = String2JKQTMathTextHorizontalAlignment ( envname ) ;
2022-08-13 19:37:13 +08:00
nl - > addChild ( parseMultilineLatexString ( true , envname , alignment , 1.0 , MTSMDefaultSpacing , MTVOFirstLine ) ) ;
2022-08-03 21:23:14 +08:00
} else if ( envname = = " framed " | | envname = = " shaded " | | envname = = " snugshade " ) {
JKQTMathTextHorizontalAlignment alignment = MTHALeft ;
2022-08-13 19:37:13 +08:00
JKQTMathTextVerticalListNode * vlist = parseMultilineLatexString ( true , envname , alignment , 1.0 , MTSMDefaultSpacing , MTVOFirstLine ) ;
2022-08-03 21:23:14 +08:00
QStringList color ;
color < < jkqtp_QColor2String ( Qt : : lightGray ) ;
nl - > addChild ( new JKQTMathTextBoxInstructionNode ( this , envname , vlist , color ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: unknown environment '%2' " ) . arg ( currentTokenID ) . arg ( envname ) ) ;
}
} else if ( currentToken = = MTTinstructionEnd ) {
QString envname = currentTokenName ;
if ( envname = = quitOnEnvironmentEnd ) {
break ;
} else {
error_list . append ( tr ( " error @ ch. %1: ' \\ end{%2}' widthout preceding ' \\ begin{%3}' " ) . arg ( currentTokenID ) . arg ( envname ) . arg ( envname ) ) ;
}
2022-06-19 21:11:06 +08:00
} else if ( currentToken = = MTTclosebracket ) {
if ( quitOnClosingBracket ) break ;
2022-06-20 04:36:38 +08:00
else nl - > addChild ( new JKQTMathTextTextNode ( this , " ] " , false ) ) ;
2019-01-26 19:28:44 +08:00
} else if ( currentToken = = MTTampersand ) {
break ;
} else if ( currentToken = = MTTdollar ) {
if ( parsingMathEnvironment ) { // reached end of math environment
parsingMathEnvironment = false ;
break ;
} else { // starting math environment
parsingMathEnvironment = true ;
2022-07-09 05:15:42 +08:00
nl - > addChild ( new JKQTMathTextModifiedTextPropsInstructionNode ( this , " equation " , parseLatexString ( true ) ) ) ;
2019-01-26 19:28:44 +08:00
}
}
if ( getNew ) getToken ( ) ;
}
//std::cout<<" leaving parseLatexString()\n";
2022-08-12 18:54:10 +08:00
lastLineCount = countLine ;
2022-06-20 04:36:38 +08:00
return simplifyJKQTMathTextNode ( nl ) ;
2019-01-26 19:28:44 +08:00
}
2022-08-13 19:37:13 +08:00
JKQTMathTextVerticalListNode * JKQTMathText : : parseMultilineLatexString ( bool get , const QString & quitOnEnvironmentEnd , JKQTMathTextHorizontalAlignment _alignment , double _linespacingFactor , JKQTMathTextLineSpacingMode spacingMode_ , JKQTMathTextVerticalOrientation _verticalOrientation )
{
JKQTMathTextVerticalListNode * vlist = new JKQTMathTextVerticalListNode ( this , _alignment , _linespacingFactor , spacingMode_ , _verticalOrientation ) ;
bool first = true ;
while ( first | | currentToken = = MTTinstructionNewline ) {
vlist - > addChild ( simplifyAndTrimJKQTMathTextNode ( parseLatexString ( true , MTBTAny , quitOnEnvironmentEnd ) ) ) ;
first = false ;
}
return vlist ;
}
2022-07-09 05:15:42 +08:00
JKQTMathTextNode * JKQTMathText : : parseInstruction ( bool * _foundError , bool * getNew ) {
2022-08-03 15:55:45 +08:00
static QHash < QString , double > big_instructions_family ;
if ( big_instructions_family . size ( ) = = 0 ) {
big_instructions_family [ " big " ] = 0.85 ; //1.2;
big_instructions_family [ " bigl " ] = 0.85 ; //1.2;
big_instructions_family [ " bigm " ] = 0.85 ; //1.2;
big_instructions_family [ " bigr " ] = 0.85 ; //1.2;
big_instructions_family [ " Big " ] = 1.15 ; //1.85;
big_instructions_family [ " Bigl " ] = 1.15 ; //1.85;
big_instructions_family [ " Bigm " ] = 1.15 ; //1.85;
big_instructions_family [ " Bigr " ] = 1.15 ; //1.85;
big_instructions_family [ " bigg " ] = 1.45 ; //2.4;
big_instructions_family [ " biggl " ] = 1.45 ; //2.4;
big_instructions_family [ " biggm " ] = 1.45 ; //2.4;
big_instructions_family [ " biggr " ] = 1.45 ; //2.4;
big_instructions_family [ " Bigg " ] = 1.75 ; //3.1;
big_instructions_family [ " Biggl " ] = 1.75 ; //3.1;
big_instructions_family [ " Biggm " ] = 1.75 ; //3.1;
big_instructions_family [ " Biggr " ] = 1.75 ; //3.1;
}
2022-07-09 05:15:42 +08:00
if ( currentToken ! = MTTinstruction ) {
if ( _foundError ) * _foundError = true ;
if ( getNew ) * getNew = false ;
error_list . append ( tr ( " error @ ch. %1: expected instruction token " ) . arg ( currentTokenID ) ) ;
return nullptr ;
}
bool foundError = false ;
const QString currentInstructionName = currentTokenName ;
JKQTMathTextNode * child = nullptr ;
if ( getNew ) * getNew = true ;
if ( JKQTMathTextWhitespaceNode : : supportsInstructionName ( currentInstructionName ) ) {
if ( getNew ) * getNew = true ;
child = new JKQTMathTextWhitespaceNode ( currentInstructionName , this ) ;
} else if ( JKQTMathTextSymbolNode : : hasSymbol ( currentInstructionName ) ) {
child = new JKQTMathTextSymbolNode ( this , currentInstructionName ) ;
if ( JKQTMathTextSymbolNode : : isSubSuperscriptBelowAboveSymbol ( currentInstructionName ) & & parsingMathEnvironment ) {
child - > setSubSuperscriptAboveBelowNode ( true ) ;
}
if ( getNew ) * getNew = true ;
2022-08-03 15:55:45 +08:00
} else if ( big_instructions_family . contains ( currentInstructionName ) ) {
// after \big,\bigl... we expect a symbol-instruction or at least one character of text
while ( getToken ( ) = = MTTwhitespace ) ; // eat whitespace
JKQTMathTextBraceType bracetype = MTBTUnknown ;
bool openbrace = true ;
if ( currentToken = = MTTinstruction ) {
bracetype = TokenName2JKQTMathTextBraceType ( currentTokenName , & openbrace ) ;
} else if ( currentToken = = MTTtext ) {
const QString firstTokenChar ( currentTokenName [ 0 ] ) ;
bracetype = TokenName2JKQTMathTextBraceType ( firstTokenChar , & openbrace ) ;
if ( bracetype ! = MTBTUnknown ) {
giveBackToTokenizer ( currentTokenName . size ( ) - 1 ) ;
} else {
giveBackToTokenizer ( currentTokenName . size ( ) ) ;
}
} else if ( currentToken = = MTTopenbracket ) {
bracetype = MTBTSquareBracket ;
openbrace = true ;
} else if ( currentToken = = MTTclosebracket ) {
bracetype = MTBTSquareBracket ;
openbrace = false ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected symbol-encoding instruction or a character after ' \\ %2' command, but found token type %3 " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( tokenType2String ( currentToken ) ) ) ;
}
if ( bracetype ! = MTBTUnknown ) {
JKQTMathTextEmptyBoxNode * sizeChild = new JKQTMathTextEmptyBoxNode ( this , 0 , JKQTMathTextEmptyBoxNode : : EBUem , big_instructions_family [ currentInstructionName ] , JKQTMathTextEmptyBoxNode : : EBUem ) ;
if ( openbrace ) {
child = new JKQTMathTextBraceNode ( this , bracetype , MTBTNone , sizeChild ) ;
} else {
child = new JKQTMathTextBraceNode ( this , MTBTNone , bracetype , sizeChild ) ;
}
} else {
error_list . append ( tr ( " error @ ch. %1: expected symbol-encoding instruction or character after ' \\ %2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
}
if ( getNew ) * getNew = true ;
2022-07-09 05:15:42 +08:00
} else if ( JKQTMathTextModifiedTextPropsInstructionNode : : supportsInstructionName ( currentInstructionName ) ) {
const size_t Nparams = JKQTMathTextModifiedTextPropsInstructionNode : : countParametersOfInstruction ( currentInstructionName ) ;
bool foundError = false ;
const QStringList params = parseStringParams ( true , Nparams , & foundError ) ;
if ( ! foundError ) {
if ( getToken ( ) = = MTTopenbrace ) {
const bool oldParseMath = parsingMathEnvironment ;
auto __finalpaint = JKQTPFinally ( std : : bind ( [ & oldParseMath ] ( bool & parsingMathEnvironment ) { parsingMathEnvironment = oldParseMath ; } , std : : ref ( parsingMathEnvironment ) ) ) ;
JKQTMathTextModifiedTextPropsInstructionNode : : modifyInMathEnvironment ( currentInstructionName , parsingMathEnvironment , params ) ;
child = new JKQTMathTextModifiedTextPropsInstructionNode ( this , currentInstructionName , parseLatexString ( true ) , params ) ;
} else {
foundError = true ;
}
}
if ( foundError ) {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( Nparams + 1 ) ) ;
}
2022-07-25 05:22:54 +08:00
} else if ( JKQTMathTextSimpleInstructionNode : : supportsInstructionName ( currentInstructionName ) ) {
const size_t Nparams = JKQTMathTextSimpleInstructionNode : : countParametersOfInstruction ( currentInstructionName ) ;
bool foundError = false ;
const QStringList params = parseStringParams ( true , Nparams , & foundError ) ;
if ( ! foundError ) {
child = new JKQTMathTextSimpleInstructionNode ( this , currentInstructionName , params ) ;
}
if ( foundError ) {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( Nparams ) ) ;
}
2022-07-09 05:15:42 +08:00
} else if ( JKQTMathTextBoxInstructionNode : : supportsInstructionName ( currentInstructionName ) ) {
const size_t Nparams = JKQTMathTextBoxInstructionNode : : countParametersOfInstruction ( currentInstructionName ) ;
bool foundError = false ;
const QStringList params = parseStringParams ( true , Nparams , & foundError ) ;
if ( ! foundError ) {
if ( getNew ) * getNew = true ;
if ( getToken ( ) = = MTTopenbrace ) {
const bool oldParseMath = parsingMathEnvironment ;
auto __finalpaint = JKQTPFinally ( std : : bind ( [ & oldParseMath ] ( bool & parsingMathEnvironment ) { parsingMathEnvironment = oldParseMath ; } , std : : ref ( parsingMathEnvironment ) ) ) ;
JKQTMathTextBoxInstructionNode : : modifyInMathEnvironment ( currentInstructionName , parsingMathEnvironment , params ) ;
child = new JKQTMathTextBoxInstructionNode ( this , currentInstructionName , parseLatexString ( true ) , params ) ;
} else {
foundError = true ;
}
}
if ( foundError ) {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( Nparams + 1 ) ) ;
}
2022-08-10 20:36:16 +08:00
} else if ( JKQTMathTextPhantomNode : : supportsInstructionName ( currentInstructionName ) ) {
if ( getNew ) * getNew = true ;
if ( getToken ( ) = = MTTopenbrace ) {
child = new JKQTMathTextPhantomNode ( this , currentInstructionName , parseLatexString ( true ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected one argument in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
}
2022-07-31 05:30:47 +08:00
} else if ( currentInstructionName = = " substack " | | currentInstructionName = = " rsubstack " | | currentInstructionName = = " lsubstack " ) {
getToken ( ) ;
JKQTMathTextHorizontalAlignment alignment = MTHACentered ;
if ( currentInstructionName = = " rsubstack " ) alignment = MTHARight ;
if ( currentInstructionName = = " lsubstack " ) alignment = MTHALeft ;
if ( currentToken = = MTTopenbracket ) {
alignment = String2JKQTMathTextHorizontalAlignment ( parseSingleString ( true ) ) ;
if ( currentToken ! = MTTclosebracket ) {
error_list . append ( tr ( " error @ ch. %1: didn't find closing brace ']' after ' \\ %2[]{}' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
getToken ( ) ;
}
if ( currentToken = = MTTopenbrace ) {
2022-08-13 19:37:13 +08:00
child = parseMultilineLatexString ( true , " " , alignment , 1.0 , MTSMMinimalSpacing , MTVOFirstLine ) ;
2022-07-31 05:30:47 +08:00
if ( currentToken ! = MTTclosebrace ) error_list . append ( tr ( " error @ ch. %1: didn't find closing brace '}' after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected one argument in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
2022-07-09 05:15:42 +08:00
} else if ( currentInstructionName = = " sqrt " ) {
getToken ( ) ;
if ( currentToken = = MTTopenbrace ) {
child = new JKQTMathTextSqrtNode ( this , parseLatexString ( true ) ) ;
} else if ( currentToken = = MTTopenbracket ) {
JKQTMathTextNode * n1 = parseLatexString ( true , MTBTAny , " " , true ) ;
JKQTMathTextNode * n2 = nullptr ;
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
else error_list . append ( tr ( " error @ ch. %1: expected one argument in '{' braces after '%2' command with an optional argument in [] " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
if ( n1 & & n2 ) {
child = new JKQTMathTextSqrtNode ( this , n2 , n1 ) ;
} else {
if ( n1 ) delete n1 ;
if ( n2 ) delete n2 ;
error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
}
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else if ( currentInstructionName = = " cbrt " ) {
if ( getToken ( ) = = MTTopenbrace ) {
child = new JKQTMathTextSqrtNode ( this , parseLatexString ( true ) , new JKQTMathTextTextNode ( this , " 3 " , false ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else if ( currentInstructionName = = " verb " ) {
if ( getToken ( ) = = MTTopenbrace ) {
QString text = " " ;
currentTokenID + + ;
if ( currentTokenID < = parseString . size ( ) - 1 ) {
QChar c = parseString [ currentTokenID ] ;
while ( c ! = ' } ' & & ( currentTokenID < parseString . size ( ) ) ) {
text = text + c ;
currentTokenID + + ;
if ( currentTokenID < parseString . size ( ) ) c = parseString [ currentTokenID ] ;
}
if ( c ! = ' } ' ) error_list . append ( tr ( " error @ ch. %1: \v erb{...} not closed by '}' " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
child = new JKQTMathTextTextNode ( this , text , false ) ;
}
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else if ( JKQTMathTextDecoratedNode : : supportsInstructionName ( currentInstructionName ) ) {
if ( getToken ( ) = = MTTopenbrace ) {
child = new JKQTMathTextDecoratedNode ( this , JKQTMathTextDecoratedNode : : InstructionName2DecorationType ( currentInstructionName ) , parseLatexString ( true ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else if ( JKQTMathTextFracNode : : supportsInstructionName ( currentInstructionName ) ) {
if ( getToken ( ) = = MTTopenbrace ) {
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
if ( n1 & & n2 ) child = new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : InstructionName2FracType ( currentInstructionName ) ) ;
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else if ( currentInstructionName = = " binom " ) {
if ( getToken ( ) = = MTTopenbrace ) {
JKQTMathTextNode * n1 = parseLatexString ( true ) ;
JKQTMathTextNode * n2 = nullptr ;
if ( getToken ( ) = = MTTopenbrace ) n2 = parseLatexString ( true ) ;
if ( n1 & & n2 ) child = new JKQTMathTextBraceNode ( this , MTBTParenthesis , MTBTParenthesis , new JKQTMathTextFracNode ( this , n1 , n2 , JKQTMathTextFracNode : : MTFMstackrel ) ) ;
else error_list . append ( tr ( " error @ ch. %1: expected two arguments in '{' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
} else {
error_list . append ( tr ( " error @ ch. %1: expected %3 arguments in '{...}' braces after '%2' command " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) . arg ( 1 ) ) ;
}
} else {
if ( getNew ) * getNew = true ;
foundError = true ;
error_list . append ( tr ( " error @ ch. %1: unknown instruction \\ %2 or unsupported instruction at this location " ) . arg ( currentTokenID ) . arg ( currentInstructionName ) ) ;
}
if ( _foundError ) * _foundError = foundError ;
return child ;
}
QStringList JKQTMathText : : parseStringParams ( bool get , size_t Nparams , bool * foundError ) {
2022-07-25 04:31:38 +08:00
const bool old_parsingMathEnvironment = parsingMathEnvironment ;
auto reset_parsingMathEnvironment = JKQTPFinally ( [ & ] ( ) { parsingMathEnvironment = old_parsingMathEnvironment ; } ) ;
2022-07-09 05:15:42 +08:00
if ( * foundError ) * foundError = false ;
if ( Nparams < = 0 ) return QStringList ( ) ;
else {
QStringList params ;
for ( size_t n = 0 ; n < Nparams ; n + + ) {
if ( n > 0 | | ( n = = 0 & & get ) ) getToken ( ) ;
if ( currentToken = = MTTopenbrace ) {
2022-07-25 04:31:38 +08:00
bool ok = true ;
QString thisparam = " " ;
while ( ok ) {
getToken ( ) ;
if ( currentToken = = MTTtext ) {
thisparam + = currentTokenName ;
} else if ( currentToken = = MTTwhitespace ) {
thisparam + = " " ;
} else if ( currentToken = = MTTclosebrace ) {
params . append ( thisparam ) ;
ok = false ;
} else {
2022-07-09 05:15:42 +08:00
if ( * foundError ) * foundError = true ;
return params ;
}
}
} else {
if ( * foundError ) * foundError = true ;
return params ;
}
}
return params ;
}
}
2022-07-31 05:30:47 +08:00
QString JKQTMathText : : parseSingleString ( bool get ) {
const bool old_parsingMathEnvironment = parsingMathEnvironment ;
auto reset_parsingMathEnvironment = JKQTPFinally ( [ & ] ( ) { parsingMathEnvironment = old_parsingMathEnvironment ; } ) ;
bool ok = true ;
QString thisparam = " " ;
while ( ok ) {
if ( get ) getToken ( ) ;
get = true ;
if ( currentToken = = MTTtext ) {
thisparam + = currentTokenName ;
} else if ( currentToken = = MTTwhitespace ) {
thisparam + = " " ;
} else {
ok = false ;
}
}
return thisparam ;
}
2022-08-13 19:37:13 +08:00
QString JKQTMathText : : readUntil ( bool get , const QString & endsequence , bool removeFirstlineWhitespace )
2022-08-03 21:23:14 +08:00
{
if ( get ) currentTokenID + + ;
QString seq ;
while ( currentTokenID < parseString . size ( ) & & ! seq . endsWith ( endsequence ) ) {
seq + = parseString [ currentTokenID ] ;
currentTokenID + + ;
}
currentTokenID - - ;
if ( seq . endsWith ( endsequence ) ) {
seq = seq . left ( seq . size ( ) - endsequence . size ( ) ) ;
}
2022-08-13 19:37:13 +08:00
if ( removeFirstlineWhitespace ) {
QStringList sl = seq . split ( ' \n ' ) ;
if ( sl . size ( ) > 0 ) {
bool allWS = true ;
for ( const QChar & ch : sl . first ( ) ) {
if ( ! ch . isSpace ( ) ) {
allWS = false ;
break ;
}
}
if ( allWS ) sl . removeFirst ( ) ;
}
if ( sl . size ( ) > 0 ) {
bool allWS = true ;
for ( const QChar & ch : sl . last ( ) ) {
if ( ! ch . isSpace ( ) ) {
allWS = false ;
break ;
}
}
if ( allWS ) sl . removeLast ( ) ;
}
seq = sl . join ( " \n " ) ;
}
2022-08-03 21:23:14 +08:00
return seq ;
}
2022-06-19 21:11:06 +08:00
2022-06-08 21:38:26 +08:00
JKQTMathTextNode * JKQTMathText : : getParsedNode ( ) const {
2019-06-30 23:34:41 +08:00
return this - > parsedNode ;
}
2019-01-26 19:28:44 +08:00
2022-08-13 21:32:31 +08:00
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 ( " \\ ; " ) ;
2019-01-26 19:28:44 +08:00
if ( parsedNode & & parseString = = ntext ) return true ;
if ( parsedNode ! = nullptr ) delete parsedNode ;
2022-08-13 21:32:31 +08:00
//std::cout<<"JKQTMathText::parse('"<<ntext.toStdString()<<"', options="<<std::hex<<static_cast<int>(options)<<")\n";
2019-01-26 19:28:44 +08:00
parseString = ntext ;
currentTokenID = - 1 ;
currentToken = MTTnone ;
currentTokenName = " " ;
parsingMathEnvironment = false ;
2022-08-12 18:54:10 +08:00
lastLineCount . clear ( ) ;
2019-01-26 19:28:44 +08:00
error_list . clear ( ) ;
2022-08-13 21:32:31 +08:00
if ( options . testFlag ( AllowLinebreaks ) ) {
2022-08-13 19:37:13 +08:00
parsedNode = parseMultilineLatexString ( true , QString ( " " ) , MTHALeft , 1.0 , MTSMDefaultSpacing , MTVOFirstLine ) ;
} else {
parsedNode = parseLatexString ( true ) ;
}
2022-08-13 21:32:31 +08:00
parsedNode = simplifyJKQTMathTextNode ( parsedNode ) ;
2019-01-26 19:28:44 +08:00
return ( parsedNode ! = nullptr ) ;
}
QSizeF JKQTMathText : : getSize ( QPainter & painter ) {
2022-06-20 18:17:32 +08:00
if ( getNodeTree ( ) ! = nullptr ) {
2022-08-13 21:32:31 +08:00
const JKQTMathTextNodeSize s = getSizeDetail ( painter ) ;
return s . getSize ( ) ;
2019-01-26 19:28:44 +08:00
}
return QSizeF ( 0 , 0 ) ;
}
2022-08-13 21:32:31 +08:00
QSize JKQTMathText : : getIntSize ( QPainter & painter )
{
if ( getNodeTree ( ) ! = nullptr ) {
const JKQTMathTextNodeSize s = getSizeDetail ( painter ) ;
return s . getIntSize ( ) ;
}
return QSize ( 0 , 0 ) ;
}
2019-01-26 19:28:44 +08:00
double JKQTMathText : : getDescent ( QPainter & painter ) {
2022-08-13 21:32:31 +08:00
const JKQTMathTextNodeSize s = getSizeDetail ( painter ) ;
return s . getDescent ( ) ;
2019-01-26 19:28:44 +08:00
}
double JKQTMathText : : getAscent ( QPainter & painter ) {
2022-08-13 21:32:31 +08:00
const JKQTMathTextNodeSize s = getSizeDetail ( painter ) ;
return s . baselineHeight ;
2019-01-26 19:28:44 +08:00
}
void JKQTMathText : : getSizeDetail ( QPainter & painter , double & width , double & ascent , double & descent , double & strikeoutPos ) {
2022-08-07 23:57:52 +08:00
JKQTMathTextNodeSize s = getSizeDetail ( painter ) ;
width = s . width ;
ascent = s . baselineHeight ;
descent = s . getDescent ( ) ;
strikeoutPos = s . strikeoutPos ;
}
JKQTMathTextNodeSize JKQTMathText : : getSizeDetail ( QPainter & painter )
{
JKQTMathTextNodeSize s ;
2022-06-20 18:17:32 +08:00
if ( getNodeTree ( ) ! = nullptr ) {
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
2022-07-05 03:02:43 +08:00
ev . fontSizeUnit = fontSizeUnits ;
2019-01-26 19:28:44 +08:00
2022-08-07 23:57:52 +08:00
s = getNodeTree ( ) - > getSize ( painter , ev ) ;
2019-01-26 19:28:44 +08:00
}
2022-08-07 23:57:52 +08:00
return s ;
2019-01-26 19:28:44 +08:00
}
2022-07-04 03:30:12 +08:00
void JKQTMathText : : draw ( QPainter & painter , QPointF x , bool drawBoxes )
{
draw ( painter , x . x ( ) , x . y ( ) , drawBoxes ) ;
}
2022-08-08 16:12:59 +08:00
double JKQTMathText : : draw ( QPainter & painter , double x , double y , bool drawBoxes ) {
2022-06-20 18:17:32 +08:00
if ( getNodeTree ( ) ! = nullptr ) {
2022-08-08 16:12:59 +08:00
painter . save ( ) ; auto __finalpaint = JKQTPFinally ( [ & painter ] ( ) { painter . restore ( ) ; } ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
2022-07-05 03:02:43 +08:00
ev . fontSizeUnit = fontSizeUnits ;
2022-06-20 18:17:32 +08:00
getNodeTree ( ) - > setDrawBoxes ( drawBoxes ) ;
2022-08-08 16:12:59 +08:00
const double xend = getNodeTree ( ) - > draw ( painter , x , y , ev ) ;
return xend ;
2019-01-26 19:28:44 +08:00
}
2022-08-08 16:12:59 +08:00
return x ;
2019-01-26 19:28:44 +08:00
}
2019-05-01 20:58:19 +08:00
void JKQTMathText : : draw ( QPainter & painter , unsigned int flags , QRectF rect , bool drawBoxes ) {
2022-06-20 18:17:32 +08:00
if ( getNodeTree ( ) ! = nullptr ) {
2022-08-08 16:12:59 +08:00
painter . save ( ) ; auto __finalpaint = JKQTPFinally ( [ & painter ] ( ) { painter . restore ( ) ; } ) ;
2022-06-08 21:38:26 +08:00
JKQTMathTextEnvironment ev ;
2019-01-26 19:28:44 +08:00
ev . color = fontColor ;
ev . fontSize = fontSize ;
2022-07-05 03:02:43 +08:00
ev . fontSizeUnit = fontSizeUnits ;
2022-06-20 18:17:32 +08:00
getNodeTree ( ) - > setDrawBoxes ( drawBoxes ) ;
2019-01-26 19:28:44 +08:00
2022-08-08 16:12:59 +08:00
const JKQTMathTextNodeSize size = getSizeDetail ( painter ) ;
2019-01-26 19:28:44 +08:00
// align left top
double x = rect . left ( ) ;
2022-08-08 16:12:59 +08:00
double y = rect . top ( ) + size . baselineHeight ;
2019-01-26 19:28:44 +08:00
// care for horizontal align
2022-08-08 16:12:59 +08:00
if ( ( flags & Qt : : AlignRight ) ! = 0 ) x = x + rect . width ( ) - size . width ;
else if ( ( flags & Qt : : AlignHCenter ) ! = 0 ) x = x + ( rect . width ( ) - size . width ) / 2.0 ;
2019-01-26 19:28:44 +08:00
// care for vertical align
2022-08-08 16:12:59 +08:00
if ( ( flags & Qt : : AlignBottom ) ! = 0 ) y = y + rect . height ( ) - size . overallHeight ;
else if ( ( flags & Qt : : AlignVCenter ) ! = 0 ) y = y + ( rect . height ( ) - size . overallHeight ) / 2.0 ;
2019-01-26 19:28:44 +08:00
// finally draw
2022-08-08 16:12:59 +08:00
const double xend = getNodeTree ( ) - > draw ( painter , x , y , ev ) ;
2019-01-26 19:28:44 +08:00
}
}
2022-08-07 23:57:52 +08:00
QPixmap JKQTMathText : : drawIntoPixmap ( bool drawBoxes , QColor backgroundColor , int sizeincrease , qreal devicePixelRatio )
{
// 1. generate dummy QPixmap that is needed to use a QPainter
// we need the dummy, because we first need to determine the size of the render output
// for which we need a QPainter.
QPixmap pix ( 1 , 1 ) ;
pix . setDevicePixelRatio ( devicePixelRatio ) ;
{
QPainter painter ;
// 2. now we determine the size and additional parameters,
// such as the ascent(or "baseline height")
painter . begin ( & pix ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
const JKQTMathTextNodeSize size = getSizeDetail ( painter ) ;
const QSize pixsize = size . getIntSize ( ) + QSize ( 2 * sizeincrease , 2 * sizeincrease ) ;
painter . end ( ) ;
// 3. finally we can generate a QPixmap with the appropriate
// size to contain the full rendering. We fill it with the
// color white and finally paint the math markup/LaTeX string
pix = QPixmap ( pixsize ) ;
pix . setDevicePixelRatio ( devicePixelRatio ) ;
pix . fill ( backgroundColor ) ;
painter . begin ( & pix ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
draw ( painter , Qt : : AlignVCenter | Qt : : AlignHCenter , QRect ( QPoint ( 0 , 0 ) , pixsize ) , drawBoxes ) ;
painter . end ( ) ;
}
return pix ;
}
QImage JKQTMathText : : drawIntoImage ( bool drawBoxes , QColor backgroundColor , int sizeincrease , qreal devicePixelRatio , unsigned int resolution_dpi )
{
// 1. generate dummy QPixmap that is needed to use a QPainter
// we need the dummy, because we first need to determine the size of the render output
// for which we need a QPainter.
QImage img ( 1 , 1 , QImage : : Format_ARGB32 ) ;
img . setDevicePixelRatio ( devicePixelRatio ) ;
img . setDotsPerMeterX ( resolution_dpi * ( 10000 / 254 ) ) ;
img . setDotsPerMeterY ( resolution_dpi * ( 10000 / 254 ) ) ;
{
QPainter painter ;
// 2. now we determine the size and additional parameters,
// such as the ascent(or "baseline height")
painter . begin ( & img ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
const JKQTMathTextNodeSize size = getSizeDetail ( painter ) ;
const QSize pixsize = size . getIntSize ( ) + QSize ( 2 * sizeincrease , 2 * sizeincrease ) ;
painter . end ( ) ;
// 3. finally we can generate a QPixmap with the appropriate
// size to contain the full rendering. We fill it with the
// color white and finally paint the math markup/LaTeX string
2022-08-08 16:12:59 +08:00
img = QImage ( pixsize * devicePixelRatio , QImage : : Format_ARGB32 ) ;
2022-08-07 23:57:52 +08:00
img . setDevicePixelRatio ( devicePixelRatio ) ;
2022-08-08 16:12:59 +08:00
img . setDotsPerMeterX ( resolution_dpi * ( 10000 / 254 ) ) ;
img . setDotsPerMeterY ( resolution_dpi * ( 10000 / 254 ) ) ;
2022-08-07 23:57:52 +08:00
img . fill ( backgroundColor ) ;
painter . begin ( & img ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
draw ( painter , Qt : : AlignVCenter | Qt : : AlignHCenter , QRect ( QPoint ( 0 , 0 ) , pixsize ) , drawBoxes ) ;
painter . end ( ) ;
}
return img ;
}
2022-08-08 16:12:59 +08:00
2022-08-07 23:57:52 +08:00
QPicture JKQTMathText : : drawIntoPicture ( bool drawBoxes )
{
// 1. generate dummy QPixmap that is needed to use a QPainter
// we need the dummy, because we first need to determine the size of the render output
// for which we need a QPainter.
QPicture pic ;
{
QPainter painter ;
// 2. now we determine the size and additional parameters,
// such as the ascent(or "baseline height")
painter . begin ( & pic ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
const JKQTMathTextNodeSize size = getSizeDetail ( painter ) ;
painter . end ( ) ;
// 3. finally we can generate a QPixmap with the appropriate
// size to contain the full rendering. We fill it with the
// color white and finally paint the math markup/LaTeX string
painter . begin ( & pic ) ;
painter . setRenderHint ( QPainter : : Antialiasing ) ;
painter . setRenderHint ( QPainter : : TextAntialiasing ) ;
painter . setRenderHint ( QPainter : : SmoothPixmapTransform ) ;
draw ( painter , 0 , size . baselineHeight , drawBoxes ) ;
painter . end ( ) ;
}
return pic ;
}
2019-01-26 19:28:44 +08:00
2022-06-20 18:17:32 +08:00
JKQTMathTextNode * JKQTMathText : : getNodeTree ( ) const {
2019-06-30 23:34:41 +08:00
return parsedNode ;
}
2022-08-03 15:55:45 +08:00
QString JKQTMathText : : tokenType2String ( tokenType type )
{
switch ( type ) {
case MTTnone : return " MTTnone " ;
case MTTtext : return " MTTtext " ;
case MTTinstruction : return " MTTinstruction " ;
case MTTinstructionNewline : return " MTTinstructionNewline " ;
case MTTunderscore : return " MTTunderscore " ;
case MTThat : return " MTThat " ;
case MTTdollar : return " MTTdollar " ;
case MTTopenbrace : return " MTTopenbrace " ;
case MTTclosebrace : return " MTTclosebrace " ;
case MTTopenbracket : return " MTTopenbracket " ;
case MTTclosebracket : return " MTTclosebracket " ;
case MTTwhitespace : return " MTTwhitespace " ;
case MTTampersand : return " MTTampersand " ;
case MTThyphen : return " MTThyphen " ;
case MTTendash : return " MTTendash " ;
case MTTemdash : return " MTTemdash " ;
2022-08-03 21:23:14 +08:00
case MTTinstructionVerbatim : return " MTTinstructionVerbatim " ;
case MTTinstructionVerbatimVisibleSpace : return " MTTinstructionVerbatimVisibleSpace " ;
case MTTinstructionBegin : return " MTTinstructionBegin " ;
case MTTinstructionEnd : return " MTTinstructionEnd " ;
2022-08-03 15:55:45 +08:00
}
return " ??? " ;
}
2022-06-03 03:02:23 +08:00