Added new table cache_filters for all filters to use if they need to
[moodle.git] / filter / tex / tex_filter.php
CommitLineData
c49dede8 1<?PHP
2/////////////////////////////////////////////////////////////////////////////
3// //
4// NOTICE OF COPYRIGHT //
5// //
6// Moodle - Filter for converting TeX expressions to cached gif images //
7// //
8// Copyright (C) 2004 Zbigniew Fiedorowicz fiedorow@math.ohio-state.edu //
9// Originally based on code provided by Bruno Vernier bruno@vsbeducation.ca//
10// This program is free software; you can redistribute it and/or modify //
11// it under the terms of the GNU General Public License as published by //
12// the Free Software Foundation; either version 2 of the License, or //
13// (at your option) any later version. //
14// //
15// This program is distributed in the hope that it will be useful, //
16// but WITHOUT ANY WARRANTY; without even the implied warranty of //
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
18// GNU General Public License for more details: //
19// //
20// http://www.gnu.org/copyleft/gpl.html //
21// //
22/////////////////////////////////////////////////////////////////////////////
23//-------------------------------------------------------------------------
24// NOTE: This Moodle text filter converts TeX expressions delimited
25// by either $$...$$ or by <tex...>...</tex> tags to gif images using
26// mimetex.cgi obtained from http://www.forkosh.com/mimetex.html authored by
27// John Forkosh john@forkosh.com. The mimetex.cgi ELF binary compiled for Linux i386
28// is included with this distribution.
29// Note that there may be patent restrictions on the production of gif images
30// in Canada and some parts of Western Europe and Japan until July 2004.
31//-------------------------------------------------------------------------
32// You will then need to edit your moodle/config.php to invoke tex_filter.php
33//-------------------------------------------------------------------------
34
35
36/// Edit these lines to correspond to your installation
37// File path to the directory where mathml_filter.php resides
1cdd857c 38 $CFG->filterDirectory = "$CFG->dirroot/filter/tex";
c49dede8 39// File paths to the echo binary executable
40 $CFG->echo = "/bin/echo";
41// Frequency with which cache cleanup code is called: 119 means once in 119 times
42// that the filter is invoked
43 $CFG->cacheCleanFreq = 119;
44// Time in seconds after which image gifs which haven't been viewed are considered stale
45// and are scheduled for deletion
46 $CFG->cacheCleanTime = 14*24*3600;
47// Command used to list the oldest cached gif files to be scheduled for deletion, in
48// conjunction with the value of cacheCleanTime
49 $CFG->cleanFiles = "cd ". $CFG->dataroot . "/1/tex_files;/bin/ls -tr | /usr/bin/head -20";
50
51
52/// These lines are important - the variable must match the name
53/// of the actual function below
54 $textfilter_function='tex_filter';
55
56 if (function_exists($textfilter_function)) {
57 return;
58 }
59
60
61function string_file_picture($path, $courseid=0, $height="", $width="", $link="") {
62 // Given the path to a picture file in a course, or a URL,
63 // this function includes the picture in the page.
64 global $CFG;
65 $output = "";
66 if ($height) {
67 $height = "height=\"$height\"";
68 }
69 if ($width) {
70 $width = "width=\"$width\"";
71 }
72 if ($link) {
73 $output .= "<a href=\"$link\">";
74 }
75 if (substr(strtolower($path), 0, 7) == "http://") {
76 $output .= "<img border=\"0\" $height $width src=\"$path\" />";
77
78 } else if ($courseid) {
79 $output .= "<img border=\"0\" $height $width src=\"";
80 if ($CFG->slasharguments) { // Use this method if possible for better caching
81 $output .= "$CFG->wwwroot/file.php/$courseid/$path";
82 } else {
83 $output .= "$CFG->wwwroot/file.php?file=/$courseid/$path";
84 }
85 $output .= "\" />";
86 } else {
87 $output .= "Error: must pass URL or course";
88 }
89 if ($link) {
90 $output .= "</a>";
91 }
92 return $output;
93}
94
95function tex_filter ($courseid, $text) {
96
97 global $CFG;
98 $filterDirectory = $CFG->filterDirectory;
99
1cdd857c 100
c49dede8 101 /// Do a quick check using stripos to avoid unnecessary wor
102 if (!preg_match('/<tex/i',$text) && !strstr($text,'$$')) {
103 return $text;
104 }
105
c49dede8 106 $old_umask = umask();
107
108 if (!file_exists($CFG->dataroot . "/1/")) {
109 mkdir($CFG->dataroot . "/1/",0775);
110 }
111
112 if (!file_exists($CFG->dataroot . "/1/tex_files/")) {
113 mkdir($CFG->dataroot . "/1/tex_files/",0775);
114 }
115 umask($old_umask);
116 echo "\n<!--$CFG->cleanFiles-->\n";
117 if (isadmin()) { error_reporting (E_ALL); }; //for debugging
118 $timenow = time();
119 if (!($timenow % $CFG->cacheCleanFreq)) {
120 $cleanFiles = explode("\n",`$CFG->cleanFiles`);
121 foreach ($cleanFiles as $cleanFile) {
122 $pathname = $CFG->dataroot . "/1/tex_files/" . $cleanFile;
123 if ($timenow - filemtime($pathname)>$CFG->cacheCleanTime) {
124 unlink($pathname);
125 } else {
126 break;
127 }
128 }
129 }
130
131
132 $text .= ' ';
133 preg_match_all('/\$(\$\$+?)([^\$])/s',$text,$matches);
134 for ($i=0;$i<count($matches[0]);$i++) {
135 $replacement = str_replace('$','&#x00024;',$matches[1][$i]).$matches[2][$i];
136 $text = str_replace($matches[0][$i],$replacement,$text);
137 }
138
139 if (isadmin()) { error_reporting (E_ALL); }; //for debugging
140
141 // <tex> TeX expression </tex>
142 // or $$ TeX expression $$
143
144 preg_match_all('/<tex>(.+?)<\/tex>|\$\$(.+?)\$\$/is', $text, $matches);
145 for ($i=0; $i<count($matches[0]); $i++) {
146 $texexp = $matches[1][$i] . $matches[2][$i];
147 $filename = "tex_files/". md5($texexp) . ".gif";
148 $pathname = $CFG->dataroot . "/1/" . $filename;
149
150 if (file_exists($pathname)) {
151 touch($pathname);
152 $text = str_replace( $matches[0][$i], string_file_picture($filename, 1), $text);
153 } else {
154 $texexp = str_replace('&lt;','<',$texexp);
155 $texexp = str_replace('&gt;','>',$texexp);
156 $texexp = preg_replace('!\r\n?!',' ',$texexp);
157
1cdd857c 158 $texexp = '\Large'.$texexp;
159
160 system("QUERY_STRING=;export QUERY_STRING;$filterDirectory/mimetex -d ". escapeshellarg($texexp) . " >$pathname");
c49dede8 161 $text = str_replace( $matches[0][$i], string_file_picture($filename, 1), $text);
162 }
163
164 }
165 return $text;
166};
167
168
1cdd857c 169?>