1<?php
2/***************************************************************************
3 *   copyright            : (C) 2005 by Pascal Brachet - France            *
4 *   pbrachet_NOSPAM_xm1math.net (replace _NOSPAM_ by @)                   *
5 *   http://www.xm1math.net/phpmathpublisher/                              *
6 *                                                                         *
7 *   This program is free software; you can redistribute it and/or modify  *
8 *   it under the terms of the GNU General Public License as published by  *
9 *   the Free Software Foundation; either version 2 of the License, or     *
10 *   (at your option) any later version.                                   *
11 *                                                                         *
12 ***************************************************************************/
13
14namespace RL\PhpMathPublisher;
15
16/**
17 * \RL\PhpMathPublisher\PhpMathPublisher
18 *
19 * @author Pascal Brachet <pbrachet@xm1math.net>
20 * @author Peter Vasilevsky <tuxoiduser@gmail.com> a.k.a. Tux-oid
21 * @license GPLv2
22 */
23class PhpMathPublisher
24{
25    /**
26     * @var \RL\PhpMathPublisher\Helper
27     */
28    protected $helper;
29
30    /**
31     * @var int
32     */
33    protected $size;
34
35    /**
36     * @var string
37     */
38    protected $path;
39
40    /**
41     * Constructor
42     * @param string $imgpath where to store images
43     * @param string $webpath web path under which the sotred images are available
44     * @param int $size font-size for the formula
45     */
46    public function __construct($imgpath, $webpath, $size = 10)
47    {
48        $this->helper = new Helper();
49        $this->helper->setDirImg($imgpath);
50        $this->path = $webpath;
51        $this->size = $size;
52    }
53
54    /**
55     * Check if the wanted image already exists in the cache
56     *
57     * @param string $n the base name of the image
58     * @return int
59     */
60    protected function detectImage($n)
61    {
62        /*
63         Detects if the formula image already exists in the $dirImg cache directory.
64         In that case, the function returns a parameter (recorded in the name of the image file) which allows to align correctly the image with the text.
65         */
66        $dirImg = $this->helper->getDirImg();
67        $ret = 0;
68        $handle = opendir($dirImg);
69        while ($fi = readdir($handle)) {
70            $info = pathinfo($fi);
71            if ($fi != "." && $fi != ".." && $info["extension"] == "png" && preg_match("#^math#", $fi)) {
72                list(, $v, $name) = explode("_", $fi);
73                if ($name == $n) {
74                    $ret = $v;
75                    break;
76                }
77            }
78        }
79        closedir($handle);
80
81        return $ret;
82    }
83
84    /**
85     * Creates the formula image (if the image is not in the cache) and returns the <img src=...></img> html code.
86     *
87     * @param string $text the formula
88     * @return string
89     */
90    public function mathImage($text)
91    {
92        $dirImg = $this->helper->getDirImg();
93        $nameImg = md5(trim($text) . $this->size) . '.png';
94        $v = $this->detectImage($nameImg);
95        if ($v == 0) {
96            //the image doesn't exist in the cache directory. we create it.
97            $v = $this->renderImage($text, $dirImg . "/math_%s_" . $nameImg);
98        }
99        $vAlign = $v - 1000;
100
101        return '<img src="' . $this->path . "/math_" . $v . "_" . $nameImg . '" style="vertical-align:' . $vAlign . 'px;' . ' display: inline-block ;" alt="' . $text . '" title="' . $text . '"/>';
102    }
103
104    /**
105     * Creates an image for the given formula at the given place
106     *
107     * @param string $text the formula
108     * @param string $file where to write the file to (full path). Use %s to have the vertical alignment included
109     * @return int the alignment + 1000
110     */
111    public function renderImage($text, $file)
112    {
113        $formula = new MathExpression($this->helper->tableExpression(trim($text)), $this->helper);
114        $formula->draw($this->size);
115
116        //1000+baseline ($v) is recorded in the name of the image
117        $v = 1000 - imagesy($formula->image) + $formula->verticalBased + 3;
118        $file = sprintf($file, $v);
119        imagepng($formula->image, $file);
120        return $v;
121    }
122
123    /**
124     * @param $text
125     * @return mixed|string
126     */
127    public function mathFilter($text)
128    {
129        $text = stripslashes($text);
130        $this->size = max($this->size, 10);
131        $this->size = min($this->size, 24);
132        preg_match_all("|<m>(.*?)</m>|", $text, $regs, PREG_SET_ORDER);
133        foreach ($regs as $math) {
134            $t = str_replace('<m>', '', $math[0]);
135            $t = str_replace('</m>', '', $t);
136            $code = $this->mathImage(trim($t));
137            $text = str_replace($math[0], $code, $text);
138        }
139
140        return $text;
141    }
142
143    /**
144     * @param \RL\PhpMathPublisher\Helper $helper
145     */
146    public function setHelper($helper)
147    {
148        $this->helper = $helper;
149    }
150
151    /**
152     * @return \RL\PhpMathPublisher\Helper
153     */
154    public function getHelper()
155    {
156        return $this->helper;
157    }
158
159    /**
160     * @param string $path
161     */
162    public function setPath($path)
163    {
164        $this->path = $path;
165    }
166
167    /**
168     * @return string
169     */
170    public function getPath()
171    {
172        return $this->path;
173    }
174
175    /**
176     * @param int $size
177     */
178    public function setSize($size)
179    {
180        $this->size = $size;
181    }
182
183    /**
184     * @return int
185     */
186    public function getSize()
187    {
188        return $this->size;
189    }
190
191}
192
193