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()) {
185 if (!isset($this->engine)) {
191 if (!isset($this->engine)) {
192 $this->engine = self::ENGINE_NONE;
204 case self::ENGINE_CLIENT:
205 case self::ENGINE_SERVER:
206 case self::ENGINE_DEFERRED:
207 $this->engine = $a_engine;
210 $this->engine = self::ENGINE_NONE;
221 switch ($a_rendering) {
222 case self::RENDER_SVG_AS_XML_EMBED:
223 case self::RENDER_SVG_AS_IMG_EMBED:
224 $this->rendering = $a_rendering;
225 $this->output = self::OUTPUT_SVG;
228 case self::RENDER_PNG_AS_IMG_EMBED:
229 case self::RENDER_PNG_AS_FO_FILE:
230 $this->rendering = $a_rendering;
231 $this->output = self::OUTPUT_PNG;
251 $this->zoom_factor = $a_factor;
260 if ($this->config->isClientEnabled()) {
261 $tpl = $a_tpl ?? $this->
factory->template();
263 if (!empty($this->config->getClintPolyfillUrl())) {
264 $tpl->addJavaScript($this->config->getClintPolyfillUrl());
266 if (!empty($this->config->getClientScriptUrl())) {
267 $tpl->addJavaScript($this->config->getClientScriptUrl());
283 public function insertLatexImages(
string $a_text, ?
string $a_start =
'[tex]', ?
string $a_end =
'[/tex]'): string
286 if ($this->engine === self::ENGINE_NONE) {
291 $a_start = str_replace(
"\\",
"", $a_start ??
'[tex]');
292 $a_end = str_replace(
"\\",
"", $a_end ??
'[/tex]');
297 while (is_int($spos =
ilStr::strIPos($a_text, $a_start, $cpos))) {
305 $tex = base64_decode(substr($tex, 7));
309 $tex = str_replace(array(
'<br>',
'<br/>',
'<br />'),
'', $tex);
312 $tex = preg_replace(
"/\\\\([RZN])([^a-zA-Z])/",
"\\mathbb{" .
"$1" .
"}" .
"$2", $tex);
319 switch ($this->engine) {
320 case self::ENGINE_CLIENT:
324 $tex = str_replace(
'<',
'<', $tex);
325 $replacement = $this->config->getClientLimiterStart() . $tex
326 . $this->config->getClientLimiterEnd();
329 case self::ENGINE_SERVER:
333 $tex = html_entity_decode($tex, ENT_QUOTES,
'UTF-8');
337 case self::ENGINE_DEFERRED:
339 $replacement =
'[tex]' .
'base64:' . base64_encode($tex) .
'[/tex]';
360 if ($cpos >= ilStr::strlen($a_text)) {
374 $options[
'math'] = $a_tex;
377 switch ($this->output) {
378 case self::OUTPUT_PNG:
379 $options[
'svg'] =
false;
380 $options[
'png'] =
true;
384 case self::OUTPUT_SVG:
386 $options[
'svg'] =
true;
387 $options[
'png'] =
false;
392 $image = $this->
factory->image($a_tex, $this->output, $this->dpi);
395 if (!$image->exists()) {
397 $image->write(
$server->call($options));
401 switch ($this->output) {
402 case self::OUTPUT_PNG:
403 [$width, $height] = getimagesize($image->absolutePath());
404 $width = round($width * $this->zoom_factor);
405 $height = round($height * $this->zoom_factor);
409 case self::OUTPUT_SVG:
411 $svg = simplexml_load_string(file_get_contents($image->absolutePath()));
412 $width = round($svg[
'width'] * $this->zoom_factor);
413 $height = round($svg[
'height'] * $this->zoom_factor);
414 $mime =
'image/svg+xml';
419 switch ($this->rendering) {
420 case self::RENDER_SVG_AS_XML_EMBED:
421 $html = $image->read();
424 case self::RENDER_SVG_AS_IMG_EMBED:
425 case self::RENDER_PNG_AS_IMG_EMBED:
426 $html =
'<img src="data:' . $mime .
';base64,' 427 . base64_encode($image->read())
428 .
'" style="width:' . $width .
'; height:' . $height .
';" />';
431 case self::RENDER_PNG_AS_FO_FILE:
432 $html =
'<fo:external-graphic src="' . $image->absolutePath() .
'"' 433 .
' content-height="' . $height .
'px" content-width="' . $width .
'px"></fo:external-graphic>';
437 $html = htmlspecialchars($a_tex);
442 return "[TeX rendering failed: " . $e->getMessage() . htmlentities($a_tex) .
"]";
451 return $this->
factory->image(
'', $this->output, $this->dpi)->getCacheSize();
459 $image = $this->
factory->image(
'', $this->output, $this->dpi);
460 $image->clearCache();
Class for processing of latex formulas This class uses a sigleton pattern to store the rendering purp...
static strIPos(string $a_haystack, string $a_needle, int $a_offset=0)
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
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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.
includeMathJax(?ilGlobalTemplateInterface $a_tpl=null)
Include the Mathjax javascript(s) in the page template.
setEngine(string $a_engine)
Set the Rendering engine.
const RENDER_SVG_AS_IMG_EMBED
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.