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;
193 } elseif ($a_purpose == self::PURPOSE_DEFERRED_PDF && $this->
settings->get(
'server_for_pdf')) {
194 $this->engine = self::ENGINE_DEFERRED;
200 if (!isset($this->engine) && $this->
settings->get(
'enable')) {
201 $this->engine = self::ENGINE_CLIENT;
202 $this->mathjax_url = $this->
settings->get(
'path_to_mathjax');
205 switch ((
int) $this->
settings->get(
"limiter")) {
207 $this->start_limiter =
"[tex]";
208 $this->end_limiter =
"[/tex]";
212 $this->start_limiter =
'<span class="math">';
213 $this->end_limiter =
'</span>';
217 $this->start_limiter =
"\(";
218 $this->end_limiter =
"\)";
225 if (!isset($this->engine) && !empty($this->mimetex_url)) {
226 $this->engine = self::ENGINE_MIMETEX;
230 if (!isset($this->engine)) {
231 $this->engine = self::ENGINE_NONE;
245 switch ($a_rendering) {
246 case self::RENDER_SVG_AS_XML_EMBED:
247 case self::RENDER_SVG_AS_IMG_EMBED:
248 case self::RENDER_SVG_AS_IMG_FILE:
249 $this->rendering = $a_rendering;
250 $this->output =
'svg';
253 case self::RENDER_PNG_AS_IMG_EMBED:
254 case self::RENDER_PNG_AS_IMG_FILE:
255 case self::RENDER_PNG_AS_FO_FILE:
256 $this->rendering = $a_rendering;
257 $this->output =
'png';
270 $this->dpi = (float) $a_dpi;
281 $this->zoom_factor = (float) $a_factor;
294 if ($a_tpl == null) {
298 if ($this->engine == self::ENGINE_CLIENT) {
299 $a_tpl->addJavaScript($this->mathjax_url);
316 public function insertLatexImages($a_text, $a_start =
'[tex]', $a_end =
'[/tex]', $a_dir = null, $a_path = null)
321 if ($this->engine != self::ENGINE_MIMETEX) {
322 $a_text = preg_replace(
"/\\\\([RZN])([^a-zA-Z]|<\/span>)/",
"\\mathbb{" .
"$1" .
"}" .
"$2", $a_text);
326 $a_start = str_replace(
"\\",
"", $a_start);
327 $a_end = str_replace(
"\\",
"", $a_end);
332 while (is_int($spos =
ilStr::strIPos($a_text, $a_start, $cpos))) {
340 $tex = base64_decode(substr($tex, 7));
345 $tex = str_replace(
'<br>',
'', $tex);
346 $tex = str_replace(
'<br/>',
'', $tex);
347 $tex = str_replace(
'<br />',
'', $tex);
348 $tex = str_replace(
'\\\\',
'\\cr', $tex);
356 switch ($this->engine) {
357 case self::ENGINE_CLIENT:
361 $tex = str_replace(
'<',
'<', $tex);
365 case self::ENGINE_SERVER:
369 $tex = html_entity_decode($tex, ENT_QUOTES,
'UTF-8');
373 case self::ENGINE_MIMETEX:
378 case self::ENGINE_DEFERRED:
380 $replacement =
'[tex]' .
'base64:' . base64_encode($tex) .
'[/tex]';
383 case self::ENGINE_NONE:
386 $replacement = htmlspecialchars($tex);
402 if ($cpos >= ilStr::strlen($a_text)) {
419 protected function renderMathJax($a_tex, $a_output_dir = null, $a_image_path = null)
425 switch ($this->output) {
441 $hash = md5($a_tex .
'#' . $this->dpi);
442 $file = $this->cache_dir .
'/' . substr($hash, 0, 4) .
'/' . substr($hash, 4, 4) .
'/' . $hash . $suffix;
445 if (!is_file($file)) {
447 if ($this->use_curl) {
448 $curl = curl_init($this->server_address);
449 curl_setopt($curl, CURLOPT_HEADER,
false);
450 curl_setopt($curl, CURLOPT_RETURNTRANSFER,
true);
451 curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Content-type: application/json"));
452 curl_setopt($curl, CURLOPT_POST,
true);
453 curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode(
$options));
454 curl_setopt($curl, CURLOPT_TIMEOUT, $this->server_timeout);
457 $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
460 if ($status != 200) {
462 return "[TeX rendering failed: " . $lines[1] .
" " . htmlspecialchars($a_tex) .
"]";
470 'header' =>
"Content-Type: application/json\r\n",
471 'timeout' => $this->server_timeout,
472 'ignore_errors' =>
true 478 return "[TeX rendering failed: " . htmlspecialchars($a_tex) .
"]";
483 @mkdir(dirname($file), 0777,
true);
490 if (isset($a_output_dir) && is_dir($a_output_dir)) {
491 @copy($file, $a_output_dir .
'/' . $hash . $suffix);
492 $src = $a_image_path .
'/' . $hash . $suffix;
494 $src = ILIAS_HTTP_PATH .
'/' . $file;
498 switch ($this->output) {
500 list($width, $height) = getimagesize($file);
501 $width = round($width * $this->zoom_factor);
502 $height = round($height * $this->zoom_factor);
508 $svg = simplexml_load_file($file);
509 $width = round($svg[
'width'] * $this->zoom_factor);
510 $height = round($svg[
'height'] * $this->zoom_factor);
511 $mime =
'image/svg+xml';
517 switch ($this->rendering) {
518 case self::RENDER_SVG_AS_XML_EMBED:
522 case self::RENDER_SVG_AS_IMG_EMBED:
523 case self::RENDER_PNG_AS_IMG_EMBED:
524 $html =
'<img src="data:' . $mime .
';base64,' 526 .
'" style="width:' . $width .
'; height:' . $height .
';" />';
529 case self::RENDER_SVG_AS_IMG_FILE:
530 case self::RENDER_PNG_AS_IMG_FILE:
531 $html =
'<img src="' . $src .
'" style="width:' . $width .
'; height:' . $height .
';" />';
534 case self::RENDER_PNG_AS_FO_FILE:
535 $html =
'<fo:external-graphic src="url(' . realpath($file) .
')"' 536 .
' content-height="' . $height .
'px" content-width="' . $width .
'px"></fo:external-graphic>';
540 $html = htmlspecialchars($a_tex);
546 return "[TeX rendering failed: " . $e->getMessage() .
"]";
559 protected function renderMimetex($a_tex, $a_output_dir = null, $a_image_path = null)
561 $call = $this->mimetex_url .
'?' 562 . rawurlencode(str_replace(
'&',
'&', str_replace(
'>',
'>', str_replace(
'<',
'<', $a_tex))));
564 if (empty($a_output_dir)) {
565 $html =
'<img alt="' . htmlentities($a_tex) .
'" src="' . $call .
'" />';
567 $cnt = $this->mimetex_count++;
570 $fpr = @
fopen($call,
"r");
573 while (!feof($fpr)) {
574 $buf = fread($fpr, 1024);
576 if (is_int(strpos(strtoupper(substr($buf, 0, 5)),
"GIF"))) {
581 $fpw =
fopen($a_output_dir .
"/img" . $cnt .
"." . $suffix,
"w");
590 $html =
'<img alt="' . htmlentities($a_tex) .
'" src=' . $a_image_path .
'/img"' . $cnt .
'.' . $suffix .
'/' .
'" />';
610 $type = array(
"k",
"M",
"G",
"T");
613 while (
$size >= 1024) {
618 return(round(
$size, 1) .
" " .
$type[$counter] .
"B");
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.
static strPos($a_haystack, $a_needle, $a_offset=null)
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.
static subStr($a_str, $a_start, $a_length=null)
static strIPos($a_haystack, $a_needle, $a_offset=null)
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.
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.
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