/[drupal]/contributions/modules/drutex/drutex_render.inc
ViewVC logotype

Contents of /contributions/modules/drutex/drutex_render.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.22 - (show annotations) (download) (as text)
Wed Apr 25 23:23:49 2007 UTC (2 years, 7 months ago) by darthsteven
Branch: MAIN
CVS Tags: DRUPAL-5--1-2, HEAD
Branch point for: DRUPAL-5--2, DRUPAL-6--1
Changes since 1.21: +2 -2 lines
File MIME type: text/x-php
typo
1 <?php
2 // $Id: drutex_render.inc,v 1.21 2007/04/25 14:46:28 darthsteven Exp $
3
4 /**
5 * @file
6 * Provide environments to render maths and/or arbitrary TeX.
7 */
8
9 /**
10 * Implementation of subhook_info().
11 */
12 function drutex_render_info($format = -1) {
13 return (object) array(
14 'title' => t('LaTeX Renderer'),
15 'description' => t('Provides different environments to create rendered images (especially maths).'),
16 'toggle' => true,
17 'weight' => 0
18 );
19 }
20
21 /**
22 * Implementation of subhook_defaults().
23 */
24 function drutex_render_defaults() {
25 $D['drutex_render_active'] = true;
26
27 /* relative to drutex/templates/render */
28 $D['drutex_template_render'] = 'default.tex';
29
30 $D['drutex_pattern_render_dvipng'] = 'cd [TMP_DIR]; TEXINPUTS="[DRUTEX_DIR]//:" latex -interaction=batchmode [HASH].tex'."\n".
31 'dvipng -o [IMG_FILE] -D [DPI] -T tight [TMP_DIR]/[HASH].dvi';
32
33 $D['drutex_pattern_render_imagemagick'] = 'cd [TMP_DIR]; TEXINPUTS="[DRUTEX_DIR]//:" latex -interaction=batchmode [HASH].tex'."\n".
34 'convert -density [DPI] -trim [TMP_DIR]/[HASH].dvi [IMG_FILE]';
35
36 return $D;
37 }
38
39 /**
40 * Implementation of subhook_node2html().
41 */
42 function drutex_render_node2html() {
43 $E = array();
44
45 /* Plain TeX environment */
46 $E[] = (object) array(
47 'pattern' => '@<tex( [^>]*)?>(.+?)</tex>@se',
48 'replacement' => "drutex_render('$2', '<var>format</var>', '$1', 'tag=\"span\" class=\"plaintex\"')",
49 'weight' => -10
50 );
51
52 /* <equation> environment */
53 $E[] = (object) array(
54 'pattern' => '@<equation( [^>]*)?>(.+?)</equation>@se',
55 'replacement' => "drutex_render('\[ $2 \]', '<var>format</var>', '$1', 'tag=\"table\" class=\"displaymath\"')",
56 'weight' => -7
57 );
58
59 /* <equations> environment */
60 $E[] = (object) array(
61 'pattern' => '@<equations( [^>]*)?>(.+?)</equations>@se',
62 'replacement' => "drutex_render('\begin{align*} $2 \end{align*}', '<var>format</var>', '$1', 'tag=\"table\" class=\"displaymath\"')",
63 'weight' => -6
64 );
65
66 /* Paragraph math between $$ and $$ */
67 $E[] = (object) array(
68 'pattern' => '@(^|[^\\\\])(\$\$.*?[^\\\\]\$\$)@se',
69 'replacement' => "'$1' . drutex_render('$2', '<var>format</var>', '', 'tag=\"table\" class=\"displaymath\"')",
70 'weight' => -5
71 );
72
73 /* Paragraph math between \[ and \] */
74 $E[] = (object) array(
75 'pattern' => '@\\\\\\[(.+?)\\\\\\]@se',
76 'replacement' => "drutex_render('$0', '<var>format</var>', '', 'tag=\"table\" class=\"displaymath\"')",
77 'weight' => -5
78 );
79
80 /* Inline math (display style) between $! and $ */
81 $E[] = (object) array(
82 'pattern' => '@(^|[^\\\\])\$!(.*?[^\\\\])\$@se',
83 'replacement' => "'$1' . drutex_render('$\displaystyle $2 $', '<var>format</var>')",
84 'weight' => -4
85 );
86
87 /* Inline math between $ and $ */
88 $E[] = (object) array(
89 'pattern' => '@(^|[^\\\\])\$(.*?[^\\\\])\$@se',
90 'replacement' => "'$1' . drutex_render('$ $2 $', '<var>format</var>')",
91 'weight' => -3
92 );
93
94 /* unescape escaped dollar signs */
95 $E[] = (object) array(
96 'pattern' => '@\\\\\\$@s',
97 'replacement' => '$',
98 'weight' => 1000 /* very late */
99 );
100
101 return $E;
102 }
103
104 /**
105 * Implementation of subhook_filter_settings().
106 */
107 function drutex_render_filter_settings($format = -1) {
108 /* conversion methods */
109 $conversions = array('dvipng' => 'dvipng',
110 'imagemagick' => 'ImageMagick (convert)',
111 'custom' => 'custom');
112
113 $form["drutex_template_render_$format"] = array(
114 '#type' => 'select',
115 '#title' => t('Template'),
116 '#options' => _drutex_get_templates(),
117 '#default_value' => drutex_var_get("drutex_template_render_$format")
118 );
119
120 $form["drutex_dpi_render_$format"] = array(
121 '#type' => 'textfield',
122 '#title' => t('Resolution (DPI)'),
123 '#size' => 15,
124 '#maxlength' => 3,
125 '#default_value' => drutex_var_get("drutex_dpi_render_$format"),
126 '#description' => t('100 is small, 107 is default, 115 is big')
127 );
128
129 $form["drutex_conversion_render_$format"] = array(
130 '#type' => 'select',
131 '#title' => t('Conversion Method'),
132 '#options' => $conversions,
133 '#default_value' => drutex_var_get("drutex_conversion_render_$format")
134 );
135
136
137 /* Custom Conversion Method */
138
139 /* determine default value for <custom conversion method> */
140 $default_value = drutex_var_get("drutex_pattern_render_custom_$format");
141 if (empty($default_value)) {
142 /* get selected conversion method */
143 $conversion = drutex_var_get("drutex_conversion_render_$format");
144 $default_value = drutex_var_get("drutex_pattern_render_{$conversion}_$format");
145 }
146
147 /* description for <custom conversion method> */
148 $description = t('* Leave blank and select dvipng or ImageMagick, to display a template for one of these commands in this box.') . '<br />'
149 . t('* Every line is executed in sequence, but in its own shell (so path changes aren\'t inherited).') . '<br />'
150 . t('Placeholders available:<br />
151 [HASH] - hash (name) for the image<br />
152 [TMP_DIR] - temporary dir (automatically cleaned)<br />
153 [IMG_DIR] - directory where the images are saved<br />
154 [IMG_TYPE] - png in most cases<br />
155 [DPI] - dots per inch (see above)<br />
156 [IMG_FILE] - abbreviation for [IMG_DIR]/[HASH].[IMG_TYPE]<br />
157 [DRUTEX_DIR] - full path to DruTeX base dir');
158
159
160 $form["drutex_pattern_render_custom_$format"] = array(
161 '#type' => 'textarea',
162 '#title' => t('Conversion Method (Custom)'),
163 '#rows' => 3,
164 '#cols' => 50,
165 '#default_value' => $default_value,
166 '#description' => $description
167 );
168
169 return $form;
170 }
171
172 /**
173 * Renders $text in LaTeX.
174 */
175 function drutex_render($text, $format = -1, $attributes = '', $default_attributes = '') {
176
177 $text = _drutex_unescape($text);
178
179 if (drutex_submodule_is_active('security', $format)) {
180 if (drutex_security($text, $format) == false) {
181 return '<em class="error">Unallowed command detected!</em>';
182 }
183 }
184
185 $attributes = drutex_parse_attributes(_drutex_unescape($attributes));
186 $default_attributes = drutex_parse_attributes($default_attributes);
187 $attributes = array_merge($default_attributes, $attributes);
188
189 $image_dir = drutex_var_get("drutex_dir_images_$format");
190
191 $template_dir = drutex_var_get('drutex_dir') . '/templates/render';
192 $template_file = drutex_var_get("drutex_template_render_$format");
193 $template = $template_dir . '/' . $template_file;
194
195 $dpi = drutex_var_get("drutex_dpi_render_$format");
196
197 if (!empty($attributes['dpi']) AND is_numeric($attributes['dpi']) AND $attributes['dpi'] > 0) {
198 $dpi = $attributes['dpi'];
199 }
200
201 $image_type = drutex_var_get("drutex_imagetype_$format");
202
203 $hash = sha1($text . $displaystyle . $template . $dpi);
204 $image_file = "$image_dir/$hash.$image_type";
205
206
207 $success = TRUE;
208
209 if (!is_file($image_file)) {
210 /* create temporary dir */
211 $temporary_dir = _drutex_create_temporary_dir();
212
213 /* conversion method */
214 $conversion = drutex_var_get("drutex_conversion_render_$format");
215
216 /* command patterns */
217 $pattern_convert = drutex_var_get("drutex_pattern_render_{$conversion}_$format");
218
219 /* replacement arrays */
220 $map = array('[HASH]' => $hash, '[TMP_DIR]' => $temporary_dir, '[IMG_FILE]' => $image_file,
221 '[IMG_DIR]' => $image_dir, '[IMG_TYPE]' => $image_type, '[DPI]' => $dpi,
222 '[DRUTEX_DIR]' => drutex_var_get('drutex_dir'));
223
224 /* conversion commands (seperated by \n) */
225 $cmd_convert = str_replace(array_keys($map), $map, $pattern_convert);
226
227 /* load the appropriate template ... */
228 $handle = fopen($template, 'r');
229 $content = fread($handle, filesize($template));
230 fclose($handle);
231
232 /* ... and put the $text in there */
233 $content = str_replace('DRUTEX_REPLACE', $text, $content);
234
235 /* write $content to file, for LaTeX to read an render it */
236 file_save_data($content, "$temporary_dir/$hash.tex", FILE_EXISTS_REPLACE);
237
238 /* invoke all conversion commands */
239 $commands = explode("\n", $cmd_convert);
240
241 foreach ($commands as $cmd) {
242 $cmd = trim($cmd);
243
244 if ($cmd) {
245 exec($cmd, $cmd_output, $cmd_retval);
246
247 if (drutex_var_get("drutex_debug_$format")) {
248 $level = ($cmd_retval == 0) ? WATCHDOG_NOTICE : WATCHDOG_WARNING;
249 watchdog('DruTeX', "Command: $cmd<br />Return value: $cmd_retval", $level);
250 }
251 }
252 }
253
254 $success = is_file($image_file);
255
256 /* remove temporary dir */
257 if (!drutex_var_get("drutex_debug_$format")) {
258 _drutex_delete_dir($temporary_dir);
259 }
260 else {
261 if ($success) {
262 watchdog('DruTeX', "$image_file was created. Temporary directory was $temporary_dir.", WATCHDOG_NOTICE);
263 }
264 else {
265 watchdog('DruTeX', "$image_file couldn't be created. Temporary directory was $temporary_dir.", WATCHDOG_WARNING);
266 }
267 }
268 }
269
270 $img_url = drutex_get_image_url($format) . "/$hash.$image_type";
271
272 if ($success) {
273 $img_alt = _drutex_hide('set', check_plain($text));
274 $res = "<img class=\"teximage\" src=\"$img_url\" alt=\"$img_alt\" />";
275 }
276 else {
277 $res = '<em class="error">TeX Embedding failed!</em>';
278 }
279
280 if (!empty($attributes['tag'])) {
281 $class_attr = empty($attributes['class']) ? '' : " class=\"{$attributes['class']}\"";
282
283 if (!empty($attributes['id'])) {
284 $id = $attributes['id'];
285 $anchor = "<a name=\"$id\" id=\"$id\"></a>";
286 }
287 else {
288 $anchor = '';
289 }
290
291 if ($attributes['tag'] == 'table') {
292 $name = _drutex_references('get name by id', $attributes['id']);
293 $name = empty($name) ? '' : "($name)";
294 $res = "<table{$class_attr}><tr><td class=\"dspleft\">{$anchor}{$res}</td><td class=\"dspright\">{$name}</td></tr></table>";
295 }
296 else {
297 $tag = $attributes['tag'];
298 $res = "<{$tag}{$class_attr}>{$res}</{$tag}>";
299 }
300 }
301
302
303 return $res;
304 }
305
306 /**
307 * Get a list with templates for drutex_render.
308 */
309 function _drutex_get_templates() {
310 $dir = drupal_get_path('module', 'drutex') . '/templates/render';
311
312 $A = file_scan_directory($dir, '.*\.tex');
313 $B = array();
314
315 foreach ($A as $key => $val) {
316 $key = substr($key, strlen($dir)+1);
317 $B[$key] = $key;
318 }
319
320 return $B;
321 }

  ViewVC Help
Powered by ViewVC 1.1.2