forked from nathancarter/qtmathjax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
texengine.cpp
152 lines (136 loc) · 4.35 KB
/
texengine.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "texengine.h"
#include <QCoreApplication>
#include <QWebElement>
#include <QDir>
TeXEngine::TeXEngine ()
: running( false ), isReady( false )
{
view = new QWebView( NULL );
connect( view, SIGNAL(loadFinished(bool)), this, SLOT(ready(bool)) );
QString toLoad = "qrc:/main.html";
view->load( QUrl( toLoad ) );
frame = view->page()->mainFrame();
connect( frame, SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(addJSObject()) );
cache.setMaxCost( 10000000 );
}
TeXEngine::~TeXEngine ()
{
delete view;
}
QWebView* TeXEngine::webView ()
{
return view;
}
bool TeXEngine::hasComputed ( QString TeXcode )
{
return cache.contains( TeXcode );
}
QString TeXEngine::TeX2SVG ( QString TeXcode )
{
if ( hasComputed( TeXcode ) ) {
QString *ptr = cache[TeXcode];
return ptr ? QString( ptr->constData() ) : QString();
}
while ( !isReady ) {
if ( !lastError.isEmpty() ) {
computeNextInBackground();
return QString();
}
QCoreApplication::processEvents( QEventLoop::AllEvents, 20 );
}
currentInput = TeXcode;
TeXcode = TeXcode.replace( "\\", "\\\\" ).replace( "'", "\\'" )
.replace( "\n", "\\\n" );
running = true;
lastError = QString();
QString toRun = QString( "var TeX2SVG_result = null;"
"try {"
" TeX2SVG_result = UpdateMath( '%1' );"
"} catch ( e ) {"
" TeX2SVG_result = e + '';"
"}"
"TeX2SVG_result" ).arg( TeXcode );
QVariant result = frame->evaluateJavaScript( toRun );
if ( result.toString() != "started" ) {
lastError = result.toString();
computeNextInBackground();
return QString();
}
while ( running )
QCoreApplication::processEvents( QEventLoop::AllEvents, 20 );
computeNextInBackground();
QString *ptr = cache[currentInput];
return ptr ? QString( ptr->constData() ) : QString();
}
void TeXEngine::asyncTeX2SVG ( QString TeXcode )
{
if ( hasComputed( TeXcode ) || queue.contains( TeXcode ) )
return;
queue << TeXcode;
computeNextInBackground();
}
void TeXEngine::computeNextInBackground ()
{
if ( queue.isEmpty() || running )
return;
currentInput = queue.first();
QString TeXcode = currentInput;
TeXcode = TeXcode.replace( "\\", "\\\\" ).replace( "'", "\\'" )
.replace( "\n", "\\\n" );
running = true;
lastError = QString();
QString toRun = QString( "var TeX2SVG_result = null;"
"try {"
" TeX2SVG_result = UpdateMath( '%1' );"
"} catch ( e ) {"
" TeX2SVG_result = e + '';"
"}"
"TeX2SVG_result" ).arg( TeXcode );
QVariant result = frame->evaluateJavaScript( toRun );
if ( result.toString() != "started" )
lastError = result.toString();
}
void TeXEngine::MathJaxDone ()
{
running = false;
if(!queue.isEmpty()) queue.takeFirst();
QWebElementCollection es = frame->findAllElements( "svg" );
QString toLoad;
QString defs;
QRegExp svgre( "<svg([^>]*)>(.*)</svg>" );
QRegExp defre( "<defs.*defs>" );
foreach ( QWebElement e, es ) {
QString piece = e.parent().toInnerXml();
if ( defre.indexIn( piece ) > -1 ) {
defs += defre.cap();
} else if ( svgre.indexIn( piece ) > -1 ) {
QString result = QString( "<svg%1>%2%3</svg>" ).arg( svgre.cap( 1 ) )
.arg( defs )
.arg( svgre.cap( 2 ) );
cache.insert( currentInput, new QString( result ), result.count() );
}
}
computeNextInBackground();
}
void TeXEngine::MathJaxError ( QString errorMessage )
{
lastError = errorMessage;
}
QString TeXEngine::error ()
{
return lastError;
}
void TeXEngine::addJSObject ()
{
frame->addToJavaScriptWindowObject( "qtapp", this );
}
void TeXEngine::ready ( bool loadSucceeded )
{
if ( loadSucceeded ) {
isReady = true;
} else {
lastError = "Failed to load MathJax engine";
}
computeNextInBackground();
}