125 "speakText" =>
false,
126 "speakRuleset" =>
"mathspeak",
127 "speakStyle"=>
"default",
130 "linebreaks"=>
false,
140 include_once
"./Services/Administration/classes/class.ilSetting.php";
142 $this->
init(self::PURPOSE_BROWSER);
145 $this->use_curl = extension_loaded(
'cURL');
157 if (self::$_instance === null) {
158 self::$_instance =
new self;
160 return self::$_instance;
169 public function init($a_purpose = self::PURPOSE_BROWSER)
172 unset($this->engine);
175 if ($this->
settings->get(
'enable_server')) {
176 $this->server_address = $this->
settings->get(
'server_address');
177 $this->server_timeout = $this->
settings->get(
'server_timeout');
179 if ($a_purpose == self::PURPOSE_BROWSER && $this->
settings->get(
'server_for_browser')) {
180 $this->engine = self::ENGINE_SERVER;
183 } elseif ($a_purpose == self::PURPOSE_EXPORT && $this->
settings->get(
'server_for_export')) {
184 $this->engine = self::ENGINE_SERVER;
188 } elseif ($a_purpose == self::PURPOSE_PDF && $this->
settings->get(
'server_for_pdf')) {
189 $this->engine = self::ENGINE_SERVER;
194 } elseif ($a_purpose == self::PURPOSE_DEFERRED_PDF && $this->
settings->get(
'server_for_pdf')) {
195 $this->engine = self::ENGINE_DEFERRED;
201 if (!isset($this->engine) && $this->
settings->get(
'enable')) {
202 $this->engine = self::ENGINE_CLIENT;
203 $this->mathjax_url = $this->
settings->get(
'path_to_mathjax');
206 switch ((
int) $this->
settings->get(
"limiter")) {
208 $this->start_limiter =
"[tex]";
209 $this->end_limiter =
"[/tex]";
213 $this->start_limiter =
'<span class="math">';
214 $this->end_limiter =
'</span>';
218 $this->start_limiter =
"\(";
219 $this->end_limiter =
"\)";
226 if (!isset($this->engine) && !empty($this->mimetex_url)) {
227 $this->engine = self::ENGINE_MIMETEX;
231 if (!isset($this->engine)) {
232 $this->engine = self::ENGINE_NONE;
246 switch ($a_rendering) {
247 case self::RENDER_SVG_AS_XML_EMBED:
248 case self::RENDER_SVG_AS_IMG_EMBED:
249 case self::RENDER_SVG_AS_IMG_FILE:
250 $this->rendering = $a_rendering;
251 $this->output =
'svg';
254 case self::RENDER_PNG_AS_IMG_EMBED:
255 case self::RENDER_PNG_AS_IMG_FILE:
256 case self::RENDER_PNG_AS_FO_FILE:
257 $this->rendering = $a_rendering;
258 $this->output =
'png';
271 $this->dpi = (float) $a_dpi;
282 $this->zoom_factor = (float) $a_factor;
295 if ($a_tpl == null) {
299 if ($this->engine == self::ENGINE_CLIENT) {
300 $a_tpl->addJavaScript($this->mathjax_url);
317 public function insertLatexImages($a_text, $a_start =
'[tex]', $a_end =
'[/tex]', $a_dir = null, $a_path = null)
322 if ($this->engine != self::ENGINE_MIMETEX) {
323 $a_text = preg_replace(
"/\\\\([RZN])([^a-zA-Z]|<\/span>)/",
"\\mathbb{" .
"$1" .
"}" .
"$2", $a_text);
327 $a_start = str_replace(
"\\",
"", $a_start);
328 $a_end = str_replace(
"\\",
"", $a_end);
331 while (is_int($spos = stripos($a_text, $a_start, $cpos))) {
332 if (is_int($epos = stripos($a_text, $a_end, $spos + strlen($a_start)))) {
334 $tex = substr($a_text, $spos + strlen($a_start), $epos - $spos - strlen($a_start));
337 if (substr($tex, 0, 7) ==
'base64:') {
338 $tex = base64_decode(substr($tex, 7));
343 $tex = str_replace(
'<br>',
'', $tex);
344 $tex = str_replace(
'<br/>',
'', $tex);
345 $tex = str_replace(
'<br />',
'', $tex);
346 $tex = str_replace(
'\\\\',
'\\cr', $tex);
349 if (!is_int(strpos($tex,
'</div>'))) {
350 switch ($this->engine) {
351 case self::ENGINE_CLIENT:
355 $tex = str_replace(
'<',
'<', $tex);
359 case self::ENGINE_SERVER:
363 $tex = html_entity_decode($tex, ENT_QUOTES,
'UTF-8');
367 case self::ENGINE_MIMETEX:
372 case self::ENGINE_DEFERRED:
374 $replacement =
'[tex]' .
'base64:' . base64_encode($tex) .
'[/tex]';
377 case self::ENGINE_NONE:
379 $replacement = htmlspecialchars($tex);
384 $a_text = substr($a_text, 0, $spos) . $replacement . substr($a_text, $epos + strlen($a_end));
401 protected function renderMathJax($a_tex, $a_output_dir = null, $a_image_path = null)
407 switch ($this->output) {
423 $hash = md5($a_tex .
'#' . $this->dpi);
424 $file = $this->cache_dir .
'/' . substr($hash, 0, 4) .
'/' . substr($hash, 4, 4) .
'/' . $hash . $suffix;
427 if (!is_file(
$file)) {
429 if ($this->use_curl) {
430 $curl = curl_init($this->server_address);
431 curl_setopt($curl, CURLOPT_HEADER,
false);
432 curl_setopt($curl, CURLOPT_RETURNTRANSFER,
true);
433 curl_setopt($curl, CURLOPT_HTTPHEADER,
array(
"Content-type: application/json"));
434 curl_setopt($curl, CURLOPT_POST,
true);
435 curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode(
$options));
436 curl_setopt($curl, CURLOPT_TIMEOUT, $this->server_timeout);
439 $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
442 if ($status != 200) {
444 return "[TeX rendering failed: " . $lines[1] .
" " . htmlspecialchars($a_tex) .
"]";
447 $context = stream_context_create(
452 'header' =>
"Content-Type: application/json\r\n",
453 'timeout' => $this->server_timeout,
454 'ignore_errors' =>
true 458 $response = @file_get_contents($this->server_address,
false, $context);
460 return "[TeX rendering failed: " . htmlspecialchars($a_tex) .
"]";
465 @mkdir(dirname(
$file), 0777,
true);
472 if (isset($a_output_dir) && is_dir($a_output_dir)) {
473 @copy(
$file, $a_output_dir .
'/' . $hash . $suffix);
474 $src = $a_image_path .
'/' . $hash . $suffix;
476 $src = ILIAS_HTTP_PATH .
'/' .
$file;
480 switch ($this->output) {
482 list($width, $height) = getimagesize(
$file);
483 $width = round($width * $this->zoom_factor);
484 $height = round($height * $this->zoom_factor);
490 $svg = simplexml_load_file(
$file);
491 $width = round($svg[
'width'] * $this->zoom_factor);
492 $height = round($svg[
'height'] * $this->zoom_factor);
493 $mime =
'image/svg+xml';
499 switch ($this->rendering) {
500 case self::RENDER_SVG_AS_XML_EMBED:
504 case self::RENDER_SVG_AS_IMG_EMBED:
505 case self::RENDER_PNG_AS_IMG_EMBED:
506 $html =
'<img src="data:' . $mime .
';base64,' 508 .
'" style="width:' . $width .
'; height:' . $height .
';" />';
511 case self::RENDER_SVG_AS_IMG_FILE:
512 case self::RENDER_PNG_AS_IMG_FILE:
513 $html =
'<img src="' . $src .
'" style="width:' . $width .
'; height:' . $height .
';" />';
516 case self::RENDER_PNG_AS_FO_FILE:
517 $html =
'<fo:external-graphic src="url(' . realpath(
$file) .
')"' 518 .
' content-height="' . $height .
'px" content-width="' . $width .
'px"></fo:external-graphic>';
522 $html = htmlspecialchars($a_tex);
528 return "[TeX rendering failed: " . $e->getMessage() .
"]";
541 protected function renderMimetex($a_tex, $a_output_dir = null, $a_image_path = null)
543 $call = $this->mimetex_url .
'?' 544 . rawurlencode(str_replace(
'&',
'&', str_replace(
'>',
'>', str_replace(
'<',
'<', $a_tex))));
546 if (empty($a_output_dir)) {
547 $html =
'<img alt="' . htmlentities($a_tex) .
'" src="' . $call .
'" />';
549 $cnt = $this->mimetex_count++;
552 $fpr = @fopen($call,
"r");
555 while (!feof($fpr)) {
556 $buf = fread($fpr, 1024);
558 if (is_int(strpos(strtoupper(substr($buf, 0, 5)),
"GIF"))) {
563 $fpw = fopen($a_output_dir .
"/img" . $cnt .
"." . $suffix,
"w");
572 $html =
'<img alt="' . htmlentities($a_tex) .
'" src=' . $a_image_path .
'/img"' . $cnt .
'.' . $suffix .
'/' .
'" />';
595 while (
$size >= 1024) {
renderMimetex($a_tex, $a_output_dir=null, $a_image_path=null)
Render image from tex code using mimetex.
Class for Server-side generation of latex formulas.
insertLatexImages($a_text, $a_start='[tex]', $a_end='[/tex]', $a_dir=null, $a_path=null)
Replace tex tags with formula image code New version of ilUtil::insertLatexImages.
includeMathJax($a_tpl=null)
Include Mathjax javascript in a template.
const RENDER_PNG_AS_IMG_EMBED
renderMathJax($a_tex, $a_output_dir=null, $a_image_path=null)
Render image from tex code using the MathJax server.
init($a_purpose=self::PURPOSE_BROWSER)
Initialize the usage This must be done before any rendering call.
const RENDER_SVG_AS_IMG_FILE
setRendering($a_rendering)
Set the image type rendered by the server.
setDpi($a_dpi)
Set the dpi of the rendered images.
__construct()
Singleton: protected constructor.
const RENDER_PNG_AS_IMG_FILE
setZoomFactor($a_factor)
Set the zoom factor for images.
getCacheSize()
Get the size of the image cache.
Create styles array
The data for the language used.
const RENDER_PNG_AS_FO_FILE
static dirsize($directory)
get size of a directory or a file.
clearCache()
Clear the cache of rendered graphics.
static getInstance()
Singleton: get instance.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
const RENDER_SVG_AS_IMG_EMBED
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getWebspaceDir($mode="filesystem")
get webspace directory
const RENDER_SVG_AS_XML_EMBED
const PURPOSE_DEFERRED_PDF
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options