/[drupal]/contributions/modules/graphviz_filter/graphviz_filter.module
ViewVC logotype

Contents of /contributions/modules/graphviz_filter/graphviz_filter.module

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


Revision 1.1 - (show annotations) (download) (as text)
Thu Jan 17 22:25:05 2008 UTC (22 months, 1 week ago) by kratib
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial commit
1 <?php
2 // $Id$
3 /**
4 * @file Provides new "Graphviz" filter that interprets text as DOT syntax
5 * and outputs corresponding PNG image of the graph.
6 * Uses PEAR::Image_GraphViz (http://pear.php.net/package/Image_GraphViz)
7 */
8
9 require_once('Image/GraphViz.php');
10
11 function graphviz_filter_filter($op, $delta = 0, $format = -1, $text = '') {
12 if ($op == 'list') {
13 return array(
14 0 => t('Graphviz (DOT) syntax'),
15 );
16 }
17
18 if ($op == 'description') {
19 return t('Interprets text as DOT syntax and returns a PNG image of the generated graph.');
20 }
21
22 if ($op == 'process') {
23 return _graphviz_filter_process($text);
24 }
25
26 return $text;
27 }
28
29 function graphviz_filter_filter_tips($delta, $format, $long = false) {
30 $output = t('Use <a href="@dot">DOT syntax</a> with some additional commands embedded in the comments.', array('@dot' => url('http://www.graphviz.org/Documentation.php')));
31 if ($long) {
32 $output .= t('<p />In the comments, you can specify additional arguments such as:<br />
33 <ul>
34 <li>@directed = is it a directed graph? [YES (default)|NO|TRUE|FALSE|1|0]</li>
35 <li>@command = any graphviz command such as dot, neato, twopi, etc.</li>
36 <li>@format = any graphviz output format such as png (default), gif, jpg, etc.</li>
37 <li>@title = the "title" attribute of the HTML element, i.e., the tooltip</li>
38 <li>@map = does it contain URLs? [YES|NO (default)|TRUE|FALSE|1|0]</li>
39 </ul>');
40 }
41 return $output;
42 }
43
44 function _graphviz_filter_process($text) {
45 // Create a temporary file with the DOT script.
46 $outdir = file_directory_path().'/graphviz';
47 file_check_directory($outdir, FILE_CREATE_DIRECTORY);
48 $inpath = System::mktemp();
49 file_put_contents($inpath, $text);
50
51 // Parse arguments and make sure required format is supported.
52 $args = array(
53 'directed' => TRUE,
54 'command' => '',
55 'formats' => 'png',
56 'title' => '',
57 'map' => FALSE,
58 );
59 _graphviz_parse_args($text, $args);
60
61 // Create and render the graph.
62 $G = new Image_GraphViz($args['directed']);
63 if ($args['command']) {
64 if ($args['directed']) {
65 $G->dotCommand = $args['command'];
66 }
67 else {
68 $G->neatoCommand = $args['command'];
69 }
70 }
71 if ($args['map']) { // FIXME We handle only client-side maps for now.
72 $mappath = file_create_filename(md5($text).'.map', $outdir);
73 if ($G->renderDotFile($inpath, $mappath, 'cmapx')) {
74 $args['mapfile'] = $mappath;
75 }
76 }
77
78 // Render desired formats.
79 $formats = array();
80 foreach (module_implements('graphviz_formats') as $module) {
81 $f = module_invoke($module, 'graphviz_formats');
82 $formats = array_merge($formats, array_fill_keys($f, $module));
83 }
84 $output = '';
85 foreach (explode(',', $args['formats']) as $format) {
86 $format = trim($format);
87 if (!array_key_exists($format, $formats)) {
88 $msg = t('Graphviz format %format is not supported. Please choose one of (%supported).',
89 array('%format' => $format, '%supported' => implode(', ', array_keys($formats)),
90 ));
91 drupal_set_message($msg, 'error');
92 watchdog('graphviz_filter', $msg, WATCHDOG_ERROR);
93 }
94 $module = $formats[$format];
95 $outpath = file_create_filename(md5($text).'.'.$format, $outdir);
96 if ($G->renderDotFile($inpath, $outpath, $format)) {
97 $output .= module_invoke($module, 'graphviz_render', $inpath, $outpath, $format, $args);
98 $output .= '<p />';
99 }
100 else {
101 $msg = t('There was an error rendering the Graphviz file using format %format.', array('%format' => $format));
102 drupal_set_message($msg, 'error');
103 watchdog('graphviz_filter', $msg, WATCHDOG_ERROR);
104 }
105 }
106 return $output;
107 }
108
109 function _graphviz_parse_args($text, &$args) {
110 // Parse comments in the DOT syntax to find our arguments.
111 // Taken from a discussion in http://ostermiller.org/findcomment.html
112 if (!preg_match_all("/(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)/", $text, $comments)) return;
113 foreach ($comments[0] as $comment) {
114 foreach ($args as $key => $value) {
115 if (($m = _graphviz_parse_arg($comment, $key)) !== FALSE) {
116 if (is_bool($value)) {
117 $args[$key] = preg_match("/TRUE|YES|1/i", $m) == 1;
118 }
119 else {
120 $args[$key] = trim($m);
121 }
122 }
123 }
124 }
125 }
126
127 function _graphviz_parse_arg($text, $arg) {
128 // FIXME This doesn't handle case /* @arg=value */ i.e. start and close on same line.
129 if (preg_match("/@$arg\s*?=\s*?(\w[\w\W]*?)[\r\n]/i", $text, $match)) {
130 return $match[1];
131 }
132 return FALSE;
133 }
134
135 function graphviz_filter_graphviz_formats() {
136 return array(
137 'png',
138 'jpg',
139 'gif',
140 'jpeg',
141 'jpe',
142 );
143 }
144
145 function graphviz_filter_graphviz_render($inpath, $outpath, $format, $args) {
146 $output = '<div class="graphviz-image"><img src="'.file_create_url($outpath).'" title="'.check_plain($args['title']).'" alt="'.t('graphviz_filter rendering').'" ';
147 if ($args['map'] && $args['mapfile']) {
148 $output .= 'usemap="#G" />';
149 $output .= file_get_contents($args['mapfile']);
150 $output .= "\n";
151 }
152 else {
153 $output .= ' />';
154 }
155 $output .= "</div>\n";
156 return $output;
157 }
158

  ViewVC Help
Powered by ViewVC 1.1.2