Extension:UML
| WARNING: The code or configuration described here poses a major security risk.
Site administrators: You are advised against using it until this security issue is resolved. Problem: Vulnerable to code injection attacks, because it passes user input directly to executable statements, such as exec(), passthru() or include(). This may lead to arbitrary code being run on your server, among other things Solution: strictly validate user input and/or apply escaping to all characters that have a special meaning in executable statements ^demon 12:43, 5 April 2010 (UTC) |
| This extension stores its source code on a wiki page. Please be aware that this code may be unreviewed or maliciously altered. They may contain security holes, outdated interfaces that are no longer compatible etc. Note: No localisation updates are provided for this extension by translatewiki.net. |
|
UML Release status: beta |
|||
|---|---|---|---|
| Implementation | Tag | ||
| Description | Renders a UML model from text using MetaUML | ||
| Author(s) | Bryan_a | ||
| Last version | 0.4.0 (2009-11-04) | ||
| License | No license specified | ||
| Download | see below | ||
| Example | Syncleus Technology Wiki | ||
|
|||
| Check usage and version matrix | |||
Contents |
UML is an extension written for MediaWiki that renders a UML model from text using MetaUML. This extension is especially usefull to render very good looking diagrams, but you have to make the element placement by yourself. It is not well fitted for UML sketches (quick drawing with autoplacement).
-
-
- UML, the language, is an open standard and there are other packages that use the extension ".uml," specifically starUML.
-
License [edit]
There isn't really any license associated to it.
Feel free to use it as you wish. This code can be shared without any restrictions. Be aware that, in GPL-like terms, this program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Usage [edit]
Just put a MetaUML model description between the <uml></uml> tag.
Attributes [edit]
- density=width
- passed to ImageMagick to set resolution of the image in DPI.
- format=format
- "png" (good quality, transparent background) "jpg" (white background - better for pasting into Word) etc
- redraw
- force diagram to be redrawn by deleting cached image.
Examples [edit]
Example 1:
<uml density="200">
Class.A("Point")
("+x: int",
"+y: int") ();
Class.B("Circle")
("radius: int")
("+getRadius(): int",
"+setRadius(r: int):void");
topToBottom(45)(A, B);
drawObjects(A, B);
clink(aggregationUni)(A, B)
</uml>
Example 2:
<uml redraw>
Begin.b;
Activity.eat("Eat something good", "from the kitchen");
Branch.enough;
Fork.fork("h", 50);
Activity.read("Read a book");
Activity.listen("Listen to music", "(and ignore it)");
Fork.join("h", 50);
End.e;
leftToRight.top(10)(read, listen);
Group.readListen(read, listen);
leftToRight(30)(b, eat);
topToBottom(20)(eat, enough, fork, readListen, join, e);
drawObjects(b, eat, enough, fork, readListen, join, e);
clink(transition)(b, eat);
clink(transition)(eat, enough);
link(transition)(pathStepX(enough.e, eat.e, 80));
clink(transition)(enough, fork);
clink(transition)(fork, read);
clink(transition)(fork, listen);
clink(transition)(read, join);
clink(transition)(listen, join);
clink(transition)(join, e);
item(iGuard)("still hungry")(obj.sw = enough.e + (20, 0));
item(iGuard)("had enough")(obj.nw = enough.s + (0, -4));
</uml>
Example 3:
<uml>
Begin.b;
State.reading("Reading commands")();
State.processing("Processing commands")();
End.e;
State.composite("Working")(b, reading, processing, e);
composite.info.left := composite.info.right := 10;
composite.info.drawNameLine := 1;
topToBottom(20)(b, reading, processing, e);
drawObject(composite);
clink(transition)(b, reading);
clink(transition)(reading, processing);
clink(transition)(processing, e);
ExitPoint.exit;
exit.c=(composite.right, reading.midy);
drawObject(exit);
item(iAssoc)("error")(obj.nw = exit.s);
clink(transition)(reading, exit);
State.error("Preparing error report")();
State.result("Writing result")();
End.theEnd;
topToBottom(20)(error, result, theEnd);
leftToRight(30)(exit, error);
drawObjects(error, result, theEnd);
clink(transition)(exit, error);
clink(transition)(error, result);
clink(transition)(result, theEnd);
link(transition)(rpathHorizontal(result.w, composite.right));
</uml>
Installation [edit]
Windows [edit]
- Copy & paste the code below in a file called MetaUML.php and place it in your extensions directory of your MediaWiki folder.
- Install MetaUML, ImageMagick and Ghostscript.
- Rename ImageMagic's convert.exe to imageconvert.exe to avoid confusion with Windows' convert
- Rename Ghostscript's gswin32c.exe to gs.exe
- Add "/ptmr8r /NimbusRomNo9L-Regu ;" (spaces and all) to Fontmap.GS in Ghostscript lib directory
- Put this line near the end of your LocalSettings.php in the MediaWiki root-folder to include the extension.
require_once('extensions/MetaUML.php');
Linux [edit]
--Zioalex 16:50, 4 November 2009 (UTC)
- Install imagemagick, ghostscript, texlive , texlive-metapost and texlive-fonts-recommended
- Copy & paste the code below in a file called MetaUML.php and place it in your extensions directory of your MediaWiki folder.
- Add "/ptmr8r /NimbusRomNo9L-Regu ;" (spaces and all) to Fontmap.GS in /usr/share/ghostscript/Version/Resource/Init/Fontmap.GS
- Put this line near the end of your LocalSettings.php in the MediaWiki root-folder to include the extension.
-
require_once("$IP/extensions/MetaUML.php");
-
- Create the dirs Mediawiki Root/tmp"" and Mediawiki Home/math"" and make it writable by apache user
Gentoo [edit]
-
emerge -av imagemagick ghostscript texlive texlive-metapost texlive-fontsrecommended -
cp MetaUML.php Mediawiki_Root/extensions
-
echo "/ptmr8r /NimbusRomNo9L-Regu ;" >> /usr/share/ghostscript/GS_Version/Resource/Init/Fontmap.GS
-
echo "require_once('extensions/MetaUML.php')">> Mediawiki Root/LocalSettings.php
-
mkdir Mediawiki_Root/images/tmp Mediawiki_Root/images/math
-
chown apache:apache Mediawiki Root/images/tmp Mediawiki Root/images/math
-
chmod 700 Mediawiki_Root/images/tmp Mediawiki Root/images/math
Code [edit]
Version 0.4 [edit]
<?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.exe"; $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; $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; }
Version 0.4.0 for Unix/Linux [edit]
There is another version that works with a UNIX system at /Code 0.4.0 unix.
- all \ has been coverted in /
- executables corrected for unix --Zioalex 16:50, 4 November 2009 (UTC)
