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;
 
  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')) {
 
  183            } elseif ($a_purpose == self::PURPOSE_EXPORT && $this->
settings->get(
'server_for_export')) {
 
  188            } elseif ($a_purpose == self::PURPOSE_PDF && $this->
settings->get(
'server_for_pdf')) {
 
  193            } elseif ($a_purpose == self::PURPOSE_DEFERRED_PDF && $this->
settings->get(
'server_for_pdf')) {
 
  200        if (!isset($this->engine) && $this->
settings->get(
'enable')) {
 
  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)) {
 
  230        if (!isset($this->engine)) {
 
  245        switch ($a_rendering) {
 
  249                $this->rendering = $a_rendering;
 
  250                $this->output = 
'svg';
 
  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));
 
  344                $tex = str_replace(
'<br>', 
'', $tex);
 
  345                $tex = str_replace(
'<br/>', 
'', $tex);
 
  346                $tex = str_replace(
'<br />', 
'', $tex);
 
  353                    switch ($this->engine) {
 
  358                            $tex = str_replace(
'<', 
'<', $tex);
 
  366                            $tex = html_entity_decode($tex, ENT_QUOTES, 
'UTF-8');
 
  377                            $replacement = 
'[tex]' . 
'base64:' . base64_encode($tex) . 
'[/tex]';
 
  383                            $replacement = htmlspecialchars($tex);
 
  398            if ($cpos >= ilStr::strlen($a_text)) {
 
  415    protected function renderMathJax($a_tex, $a_output_dir = 
null, $a_image_path = 
null)
 
  418        $options[
'math'] = $a_tex;
 
  421        switch ($this->output) {
 
  423                $options[
'svg'] = 
false;
 
  424                $options[
'png'] = 
true;
 
  430                $options[
'svg'] = 
true;
 
  431                $options[
'png'] = 
false;
 
  437        $hash = md5($a_tex . 
'#' . $this->dpi);
 
  438        $file = $this->cache_dir . 
'/' . substr($hash, 0, 4) . 
'/' . substr($hash, 4, 4) . 
'/' . $hash . $suffix;
 
  441            if (!is_file($file)) {
 
  443                if ($this->use_curl) {
 
  444                    $curl = curl_init($this->server_address);
 
  445                    curl_setopt($curl, CURLOPT_HEADER, 
false);
 
  446                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 
true);
 
  447                    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Content-type: application/json"));
 
  448                    curl_setopt($curl, CURLOPT_POST, 
true);
 
  449                    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($options));
 
  450                    curl_setopt($curl, CURLOPT_TIMEOUT, $this->server_timeout);
 
  453                    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
 
  456                    if ($status != 200) {
 
  458                        return "[TeX rendering failed: " . $lines[1] . 
" " . htmlspecialchars($a_tex) . 
"]";
 
  465                                'content' => json_encode($options),
 
  466                                'header' => 
"Content-Type: application/json\r\n",
 
  467                                'timeout' => $this->server_timeout,
 
  468                                'ignore_errors' => 
true 
  474                        return "[TeX rendering failed: " . htmlspecialchars($a_tex) . 
"]";
 
  479                @mkdir(dirname($file), 0777, 
true);
 
  486            if (isset($a_output_dir) && is_dir($a_output_dir)) {
 
  487                @copy($file, $a_output_dir . 
'/' . $hash . $suffix);
 
  488                $src = $a_image_path . 
'/' . $hash . $suffix;
 
  490                $src = ILIAS_HTTP_PATH . 
'/' . $file;
 
  494            switch ($this->output) {
 
  496                    list($width, $height) = getimagesize($file);
 
  497                    $width = round($width * $this->zoom_factor);
 
  498                    $height = round($height * $this->zoom_factor);
 
  504                    $svg = simplexml_load_file($file);
 
  505                    $width = round($svg[
'width'] * $this->zoom_factor);
 
  506                    $height = round($svg[
'height'] * $this->zoom_factor);
 
  507                    $mime = 
'image/svg+xml';
 
  513            switch ($this->rendering) {
 
  520                    $html = 
'<img src="data:' . $mime . 
';base64,' 
  522                        . 
'" style="width:' . $width . 
'; height:' . $height . 
';" />';
 
  527                    $html = 
'<img src="' . $src . 
'" style="width:' . $width . 
'; height:' . $height . 
';" />';
 
  531                    $html = 
'<fo:external-graphic src="' . realpath($file) . 
'"' 
  532                        . 
' content-height="' . $height . 
'px" content-width="' . $width . 
'px"></fo:external-graphic>';
 
  536                    $html = htmlspecialchars($a_tex);
 
  541        } 
catch (Exception 
$e) {
 
  542            return "[TeX rendering failed: " . 
$e->getMessage() . 
"]";
 
  555    protected function renderMimetex($a_tex, $a_output_dir = 
null, $a_image_path = 
null)
 
  557        $call = $this->mimetex_url . 
'?' 
  558            . rawurlencode(str_replace(
'&', 
'&', str_replace(
'>', 
'>', str_replace(
'<', 
'<', $a_tex))));
 
  560        if (empty($a_output_dir)) {
 
  561            $html = 
'<img alt="' . htmlentities($a_tex) . 
'" src="' . $call . 
'" />';
 
  563            $cnt = $this->mimetex_count++;
 
  566            $fpr = @fopen($call, 
"r");
 
  569                while (!feof($fpr)) {
 
  570                    $buf = fread($fpr, 1024);
 
  572                        if (is_int(strpos(strtoupper(substr($buf, 0, 5)), 
"GIF"))) {
 
  577                        $fpw = fopen($a_output_dir . 
"/img" . $cnt . 
"." . $suffix, 
"w");
 
  586            $html = 
'<img alt="' . htmlentities($a_tex) . 
'" src=' . $a_image_path . 
'/img"' . $cnt . 
'.' . $suffix . 
'/' . 
'" />';
 
  606        $type = array(
"k", 
"M", 
"G", 
"T");
 
  609        while (
$size >= 1024) {
 
  614        return(round(
$size, 1) . 
" " . 
$type[$counter] . 
"B");
 
An exception for terminatinating execution or to throw for unit testing.
Class for Server-side generation of latex formulas.
const RENDER_SVG_AS_IMG_FILE
renderMathJax($a_tex, $a_output_dir=null, $a_image_path=null)
Render image from tex code using the MathJax server.
renderMimetex($a_tex, $a_output_dir=null, $a_image_path=null)
Render image from tex code using mimetex.
includeMathJax($a_tpl=null)
Include Mathjax javascript in a template.
setZoomFactor($a_factor)
Set the zoom factor for images.
const RENDER_SVG_AS_IMG_EMBED
init($a_purpose=self::PURPOSE_BROWSER)
Initialize the usage This must be done before any rendering call.
clearCache()
Clear the cache of rendered graphics.
setRendering($a_rendering)
Set the image type rendered by the server.
static getInstance()
Singleton: get instance.
const RENDER_PNG_AS_IMG_FILE
const PURPOSE_DEFERRED_PDF
const RENDER_PNG_AS_IMG_EMBED
const RENDER_PNG_AS_FO_FILE
getCacheSize()
Get the size of the image cache.
const RENDER_SVG_AS_XML_EMBED
setDpi($a_dpi)
Set the dpi of the rendered images.
__construct()
Singleton: protected constructor.
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.
static strPos($a_haystack, $a_needle, $a_offset=null)
static strIPos($a_haystack, $a_needle, $a_offset=null)
static subStr($a_str, $a_start, $a_length=null)
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
static dirsize($directory)
get size of a directory or a file.
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl