19 declare(strict_types=1);
76 protected string $rendering = self::RENDER_SVG_AS_XML_EMBED;
81 protected string $output = self::OUTPUT_SVG;
102 "speakText" =>
false,
103 "speakRuleset" =>
"mathspeak",
104 "speakStyle" =>
"default",
107 "linebreaks" =>
false,
117 $this->
init(self::PURPOSE_BROWSER);
125 if (!isset(self::$_instance)) {
130 return self::$_instance;
150 $this->engine = null;
151 $this->rendering = self::RENDER_SVG_AS_XML_EMBED;
152 $this->output = self::OUTPUT_SVG;
153 $this->dpi = self::DEFAULT_DPI;
154 $this->zoom_factor = self::DEFAULT_ZOOM;
157 if ($this->config->isServerEnabled()) {
158 if ($a_purpose === self::PURPOSE_BROWSER && $this->config->isServerForBrowser()) {
162 } elseif ($a_purpose === self::PURPOSE_EXPORT && $this->config->isServerForExport()) {
167 } elseif ($a_purpose === self::PURPOSE_PDF && $this->config->isServerForPdf()) {
172 } elseif ($a_purpose === self::PURPOSE_DEFERRED_PDF && $this->config->isServerForPdf()) {
179 if ($this->config->isClientEnabled()) {
186 if (!isset($this->engine)) {
192 if (!isset($this->engine)) {
193 $this->engine = self::ENGINE_NONE;
205 case self::ENGINE_CLIENT:
206 case self::ENGINE_SERVER:
207 case self::ENGINE_DEFERRED:
208 $this->engine = $a_engine;
211 $this->engine = self::ENGINE_NONE;
222 switch ($a_rendering) {
223 case self::RENDER_SVG_AS_XML_EMBED:
224 case self::RENDER_SVG_AS_IMG_EMBED:
225 $this->rendering = $a_rendering;
226 $this->output = self::OUTPUT_SVG;
229 case self::RENDER_PNG_AS_IMG_EMBED:
230 case self::RENDER_PNG_AS_FO_FILE:
231 $this->rendering = $a_rendering;
232 $this->output = self::OUTPUT_PNG;
252 $this->zoom_factor = $a_factor;
261 if ($this->config->isClientEnabled()) {
262 $tpl = $a_tpl ?? $this->factory->template();
264 if (!empty($this->config->getClintPolyfillUrl())) {
265 $tpl->addJavaScript($this->config->getClintPolyfillUrl());
267 if (!empty($this->config->getClientScriptUrl())) {
268 $tpl->addJavaScript($this->config->getClientScriptUrl());
284 public function insertLatexImages(
string $a_text, ?
string $a_start =
'[tex]', ?
string $a_end =
'[/tex]'): string
287 if ($this->engine === self::ENGINE_NONE) {
292 $a_start = str_replace(
"\\",
"", $a_start ??
'[tex]');
293 $a_end = str_replace(
"\\",
"", $a_end ??
'[/tex]');
298 while (is_int($spos =
ilStr::strIPos($a_text, $a_start, $cpos))) {
306 $tex = base64_decode(substr($tex, 7));
310 $tex = str_replace(array(
'<br>',
'<br/>',
'<br />'),
'', $tex);
313 $tex = preg_replace(
"/\\\\([RZN])([^a-zA-Z])/",
"\\mathbb{" .
"$1" .
"}" .
"$2", $tex);
320 switch ($this->engine) {
321 case self::ENGINE_CLIENT:
325 $tex = str_replace(
'<',
'<', $tex);
326 $replacement = $this->config->getClientLimiterStart() . $tex
327 . $this->config->getClientLimiterEnd();
330 case self::ENGINE_SERVER:
334 $tex = html_entity_decode($tex, ENT_QUOTES,
'UTF-8');
338 case self::ENGINE_DEFERRED:
340 $replacement =
'[tex]' .
'base64:' . base64_encode($tex) .
'[/tex]';
361 if ($cpos >= ilStr::strlen($a_text)) {
375 $options[
'math'] = $a_tex;
378 switch ($this->output) {
379 case self::OUTPUT_PNG:
380 $options[
'svg'] =
false;
381 $options[
'png'] =
true;
385 case self::OUTPUT_SVG:
387 $options[
'svg'] =
true;
388 $options[
'png'] =
false;
393 $image = $this->factory->image($a_tex, $this->output, $this->dpi);
396 if (!$image->exists()) {
397 $server = $this->factory->server($this->config);
398 $image->write(
$server->call($options));
402 switch ($this->output) {
403 case self::OUTPUT_PNG:
404 [$width, $height] = getimagesize($image->absolutePath());
405 $width = round($width * $this->zoom_factor);
406 $height = round($height * $this->zoom_factor);
410 case self::OUTPUT_SVG:
412 $svg = simplexml_load_string(file_get_contents($image->absolutePath()));
413 $width = round($svg[
'width'] * $this->zoom_factor);
414 $height = round($svg[
'height'] * $this->zoom_factor);
415 $mime =
'image/svg+xml';
420 switch ($this->rendering) {
421 case self::RENDER_SVG_AS_XML_EMBED:
422 $html = $image->read();
425 case self::RENDER_SVG_AS_IMG_EMBED:
426 case self::RENDER_PNG_AS_IMG_EMBED:
427 $html =
'<img src="data:' . $mime .
';base64,' 428 . base64_encode($image->read())
429 .
'" style="width:' . $width .
'; height:' . $height .
';" />';
432 case self::RENDER_PNG_AS_FO_FILE:
433 $html =
'<fo:external-graphic src="' . $image->absolutePath() .
'"' 434 .
' content-height="' . $height .
'px" content-width="' . $width .
'px"></fo:external-graphic>';
438 $html = htmlspecialchars($a_tex);
443 return "[TeX rendering failed: " . $e->getMessage() . htmlentities($a_tex) .
"]";
452 return $this->factory->image(
'', $this->output, $this->dpi)->getCacheSize();
460 $image = $this->factory->image(
'', $this->output, $this->dpi);
461 $image->clearCache();
includeMathJax(ilGlobalTemplateInterface $a_tpl=null)
Include the Mathjax javascript(s) in the page template.
Class for processing of latex formulas This class uses a sigleton pattern to store the rendering purp...
const RENDER_PNG_AS_IMG_EMBED
insertLatexImages(string $a_text, ?string $a_start='[tex]', ?string $a_end='[/tex]')
Replace all tex code within given start and end delimiters in a text If client-side rendering is enab...
Factory for objects used by ilMathJax.
Global Mathjax configuration.
static subStr(string $a_str, int $a_start, ?int $a_length=null)
ilMathJaxFactory $factory
renderMathJax(string $a_tex)
Render image from tex code using the MathJax server.
array $default_server_options
static strLen(string $a_string)
__construct(ilMathJaxConfig $config, ilMathJaxFactory $factory)
Protected constructor to force the use of an initialized instance.
getCacheSize()
Get the size of the image cache.
const RENDER_PNG_AS_FO_FILE
init(string $a_purpose=self::PURPOSE_BROWSER)
Initialize the usage for a certain purpose This must be done before any rendering call...
clearCache()
Clear the cache of rendered graphics.
static getIndependent(ilMathJaxConfig $config, ilMathJaxFactory $factory)
Get an independent instance with a specific config for use in unit tests or on the mathjax settings p...
static getInstance()
Singleton: get instance for use in ILIAS requests with a config loaded from the settings.
setDpi(int $a_dpi)
Set the dpi of the rendered images.
setEngine(string $a_engine)
Set the Rendering engine.
const RENDER_SVG_AS_IMG_EMBED
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
static strIPos(string $a_haystack, string $a_needle, ?int $a_offset=null)
setRendering(string $a_rendering)
Set the image type rendered by the server.
setZoomFactor(float $a_factor)
Set the zoom factor of the rendered images.
const RENDER_SVG_AS_XML_EMBED
const PURPOSE_DEFERRED_PDF
Repository for storing and loading the MathJax configuration.