Extension UML Code 0.4.0 unix
From MediaWiki.org
Modified MetaUML.php that should work at least in Ubuntu Linux. Major changes involve:
- Changed backslash (\) to slash (/) in file path names.
- Remove .exe extensions to program (in this case only affected mpost)
- Changed non-existent '-quiet' mpost option for '-interactive=nonstopmode'
It kind of works with simple examples but it might require finer tunning.
<?php
/**
* Parser hook extension adds a <uml> tag to wiki markup for rendering UML
* diagrams within a wiki page using MetaUML.
*
* Parameters:
* density=width passed to ImageMagic to set resolution of the image in DPI.
* redraw force diagram to be redrawn by deleting cached image.
*
*/
// Make sure we are being called properly
if( !defined( 'MEDIAWIKI' ) ) {
echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
die( -1 );
}
//Avoid unstubbing $wgParser too early on modern (1.12+) MW versions, as per r35980
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
$wgHooks['ParserFirstCallInit'][] = 'wfMetaUMLExtension';
} else {
$wgExtensionFunctions[] = 'wfMetaUMLExtension';
}
$wgExtensionCredits['parserhook'][] = array(
'name' => 'UML',
'version' => '0.4',
'author' => 'Bryan A.',
'url' => 'http://www.mediawiki.org/wiki/Extension:UML',
'description' => 'Renders a UML model from text using MetaUML.'
);
$image_format = "png";
$tmp_filename = md5(rand());
$mpost_path = "mpost";
$density = "100%";
$redraw = false;
function wfMetaUMLExtension() {
global $wgParser;
# register the extension with the WikiText parser
# the first parameter is the name of the new tag.
# In this case it defines the tag <uml> ... </uml>
# the second parameter is the callback function for
# processing the text between the tags
$wgParser->setHook( 'uml', 'renderUML' );
return true;
}
/**
* wraps a minimalistic MetaUML document around the formula and returns a string
* containing the whole document as string.
*
* @param string model in MetaUML format
* @returns minimalistic MetaUML document containing the given model
*/
function wrap_formula($MetaUML_Source) {
$string = "input metauml;\n\n";
$string .= "beginfig(1);\n";
$string .= "$MetaUML_Source\n";
$string .= "endfig;\n\n";
$string .= "end\n";
return $string;
}
/**
* Renders a MetaUML model by the using the following method:
* - write the formula into a wrapped tex-file in a temporary directory
* and change to it
* - Create an incomplete Postscript file using MikTex (mpost)
* - Patch the Postscript with some missing procedures
* - convert, trim and add transparency by using 'convert' from the
* imagemagick package.
* - Save the resulting image to the picture cache directory using an
* md5 hash as filename. Already rendered models can be found directly
* this way.
*
* @param string MetaUML model
* @returns true if the picture has been successfully saved to the picture
* cache directory
*/
function renderMetaUML($MetaUML_Source) {
global $wgMathDirectory, $wgMathPath, $wgTmpDirectory, $wgDvipsCommand;
global $wgImageMagickConvertCommand, $wgImageMagickIdentifyCommand, $image_format, $tmp_filename, $mpost_path, $density;
$MetaUML_document = wrap_formula($MetaUML_Source);
$current_dir = getcwd();
chdir($wgTmpDirectory);
// create temporary latex file
$winPath = $wgTmpDirectory."/".$tmp_filename.".mp";
$fp = fopen($winPath,"a+");
$w = fputs($fp,$MetaUML_document);
fclose($fp);
// create temporary Postscript file
#$command = $mpost_path." -quiet ".$winPath;
$command = $mpost_path." -interaction=nonstopmode ".$winPath;
$status_code = exec($command);
if(!file_exists($wgTmpDirectory."/".$tmp_filename.".1")) {
cleanTemporaryDirectory();
chdir($current_dir);
return false;
}
// Fix mpost output by adding Postscript procedures
$infile = @fopen($wgTmpDirectory."/".$tmp_filename.".1", "r");
$outfile = @fopen($wgTmpDirectory."/".$tmp_filename.".ps", "a+");
if ($infile) {
// Copy the first line (%!PS)
$buffer = fgets($infile); // , 4096);
fputs($outfile, $buffer);
// Add the missing procedures
fputs($outfile, "/ptmr8r {/ptmr8r findfont} def\n");
fputs($outfile, "/fshow {scalefont setfont show} def\n");
// Copy the rest of the file
while (!feof($infile)) {
$buffer = fgets($infile); // , 4096);
fputs($outfile, $buffer);
}
fclose($infile);
fclose($outfile);
}
// ImageMagick convert ps to image and trim picture
$command = $wgImageMagickConvertCommand." -density ".$density.
" -trim -transparent \"#FFFFFF\" ".$tmp_filename.".ps ".
$tmp_filename.".".$image_format;
$status_code = exec($command);
// copy temporary formula file to cahed formula directory
$latex_hash = md5($MetaUML_Source);
$filename = $wgMathDirectory."/uml-".$latex_hash.".".$image_format;
$status_code = copy($tmp_filename.".".$image_format,$filename);
cleanTemporaryDirectory();
if (!$status_code) {
chdir($current_dir);
return false;
}
chdir($current_dir);
return true;
}
/**
* Cleans the temporary directory
*/
function cleanTemporaryDirectory() {
global $wgTmpDirectory, $image_format, $tmp_filename;
#unlink($wgTmpDirectory."/".$tmp_filename.".mp");
unlink($wgTmpDirectory."/".$tmp_filename.".log");
unlink($wgTmpDirectory."/".$tmp_filename.".1");
unlink($wgTmpDirectory."/".$tmp_filename.".ps");
unlink($wgTmpDirectory."/".$tmp_filename.".".$image_format);
}
/**
* Tries to match the MetaUML given as argument against the cache.
* If the picture has not been rendered before, it'll
* try to render the MetaUML and drop it in the picture cache directory.
*
* @param string model in MetaUML format
* @returns the webserver based URL to a picture which contains the
* requested MetaUML model. If anything fails, the resultvalue is false.
*/
function getImageURL($MetaUML_Source) {
global $wgMathDirectory, $wgMathPath, $image_format, $redraw;
$formula_hash = md5($MetaUML_Source);
$filename = 'uml-' . $formula_hash.".".$image_format;
$full_path_filename = $wgMathDirectory."/".$filename;
if (is_file($full_path_filename) && ($redraw == true)) {
unlink($full_path_filename);
}
if (is_file($full_path_filename)) {
return $wgMathPath."/".$filename;
} else {
if (renderMetaUML($MetaUML_Source)) {
return $wgMathPath."/".$filename;
} else {
return false;
}
}
}
# The callback function for converting the input text to HTML output
function renderUML( $input, $argv ) {
global $density, $redraw, $image_format;
if (array_key_exists('density', $argv)) {
$density = $argv['density'];
}
if (array_key_exists('redraw', $argv)) {
$redraw = true;
}
if (array_key_exists('format', $argv)) {
$image_format = $argv['format'];
}
$url = getImageURL($input);
if ($url == false) {
$text = "[An error occured in MetaUML extension]";
} else {
$text = "<img src='$url'>";
}
return $text;
}