Extension:Metapost
From MediaWiki.org
|
Release status: stable |
|||
|---|---|---|---|
| Implementation | Tag | ||
| Description | Include METAPOST graphics on a Mediawiki page using the <metapost> tag | ||
| Author(s) | LEE Sau Dan (李守敦) | ||
| Last Version | 1.7 (2008-11-13T05:43:08) | ||
| MediaWiki | 1.9 - 1.12 | ||
| License | No license specified | ||
| Download | http://www.cs.hku.hk/~sdlee/Metapost/Metapost.php.gz | ||
|
|||
|
check usage (experimental) |
|||
Contents |
[edit] What can this extension do?
This extension adds a new tag <metapost> to allow wiki page authors to include METAPOST graphics into wiki pages.
The following software is required for this extension to work:
- METAPOST (version >= 0.993)
- ImageMagick (version >= 6.2)
- Ghostscript
[edit] Usage
The following wiki page content will render a page like this one.
This is a demo:
<metapost>
input boxes;%
beginfig(0)
path p[];
p1 = fullcircle xscaled 30 yscaled 100 rotated 75;
p2 = ((.2,0) .. (.5,.1) .. (.7,.4) .. (.9,.7)
.. (.9,1) .. (.5,1) ..(.3, .7) .. (.3, .4) .. cycle)
scaled 70 shifted (-50,-50);
fill p1 withcolor .5[red, white];
fill p2 withcolor .5[red+green, white];
begingroup
save t,u;
(t1-0, u1) = subpath(0,2) of p1 intersectiontimes p2;
(t2-2, u2) = subpath(2,4) of p1 intersectiontimes p2;
(t3-4, u3) = subpath(4,6) of p1 intersectiontimes p2;
(t4-6, u4) = subpath(6,8) of p1 intersectiontimes p2;
p3 = subpath(t2, t3) of p1
-- subpath(t1, 0) of p1 & subpath(8,t4) of p1
-- cycle;
endgroup;
draw p3;
boxit.line1(btex MetaPost diagram etex);
boxit.line2(btex containing \TeX\ symbols etex);
boxit.line3(btex embedded in etex);
boxit.line4(btex a Wikipedia page etex);
(0,0) = line1.s - line2.n
= line2.s - line3.n
= line3.s - line4.n;
drawoptions(withcolor .5blue);
drawunboxed(line1);
drawoptions(withcolor .5red);
drawunboxed(line2);
drawoptions(withcolor .5green);
drawunboxed(line3);
drawoptions(withcolor .5(red+blue));
drawunboxed(line4);
drawoptions(withcolor .5(blue+green));
draw btex $\int_{-\infty}^{+\infty} e^{-{1\over2}z^2} dz
= \sqrt{2\pi}$ etex
rotated 15
shifted(-30,0);
endfig;
</metapost>
That's all folks!
[edit] Installation
- Download the gzipped source code
- Decompress the file and rename it to Metapost.php
- Put Metapost.php into your MediaWiki extensions directory.
- Change LocalSettings.php to load the extension. (See #Changes to LocalSettings.php)
[edit] Parameters
These parameters can be set in LocalSettings.php after Metapost.php is loaded:
| Parameter | Description | Default Value |
|---|---|---|
| $wgMetaPostSettings->metapostCommand | Command to invoke METAPOST | "/usr/bin/mpost" |
| $wgMetaPostSettings->convertCommand | Command to invoke ImageMagick's convert command | "/usr/bin/convert" |
| $wgMetaPostSettings->convertDPIDefault | DPI (dots-per-inch) to use to render the image. | "144" |
[edit] Changes to LocalSettings.php
require_once("$IP/extensions/Metapost.php");
[edit] Code
Please fetch it from http://www.cs.hku.hk/~sdlee/Metapost/Metapost.php.gz
[edit] New version of this extension
As the above link leads nowhere and the implementation is nowhere to be found, I endeavored to write a new version of this extension, as following:
<?php /** * Parser hook extension adds a <metapost> tag to wiki markup for rendering * Metapost diagrams within a wiki page. * Adapted from MetaUML extension. * * Parameters: * density=width passed to ImageMagic to set rendering density. * input=pkg_1,pkg_2,...pkg_n Metapost packages to load in prologue. * redraw Force redraw. * format Target format to use (PNG/SVG), later is * only supported by metapost-1.2 and is not * yet implemented here. * */ // 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 ); } class MetapostSettings { var $metapostCommand, $convertCommand; var $density, $format, $inputs, $redraw; function __construct() { global $wgImageMagickConvertCommand; $this->metapostCommand = "/usr/bin/mpost"; $this->convertCommand = $wgImageMagickConvertCommand; $this->density = "100%"; $this->format = "png"; $this->inputs = array(); $this->redraw = false; } } $wgMetapostSettings = new MetapostSettings(); //Avoid unstubbing $wgParser too early on modern (1.12+) MW versions, as per r35980 if (defined('MW_SUPPORTS_PARSERFIRSTCALLINIT')) { $wgHooks['ParserFirstCallInit'][] = 'wfMetapostExtension'; } else { $wgExtensionFunctions[] = 'wfMetapostExtension'; } $wgExtensionCredits['parserhook'][] = array( 'name' => 'Metapost', 'version' => '0.2', 'author' => 'Alex Dubov', 'url' => 'http://www.mediawiki.org/wiki/Extension:Metapost', 'description' => 'Renders a Metapost diagram.' ); function wfMetapostExtension() { global $wgParser; $wgParser->setHook('metapost', 'renderMetapost'); return true; } class MetapostRenderer { var $settings; var $src, $hash; var $src_path, $ltx_src_path, $dst_path, $dst_url; var $old_cwd, $cwd; function get_hash_path() { $path = '/' . substr($this->hash, 0, 1) . '/' . substr($this->hash, 1, 1) . '/' . substr($this->hash, 2, 1); return $path; } function __construct($src) { global $wgMathDirectory, $wgMathPath, $wgTmpDirectory; $this->settings = new MetaPostSettings; $this->old_cwd = getcwd(); $this->src = $src; $this->hash = hash('md5', $src); wfDebugLog('Metapost', "Calculated src hash: " . $this->hash); $dest_dir = $wgMathDirectory . $this->get_hash_path(); if (!is_dir($dest_dir)) { mkdir($dest_dir, 0755, true); } if (!is_dir($wgTmpDirectory)) { mkdir($wgTmpDirectory, 0755); } $this->src_path = $wgTmpDirectory . '/' . $this->hash; $this->ltx_src_path = $wgTmpDirectory . "/ltx-" . $this->hash; $this->dst_path = $dest_dir . '/' . $this->hash . '.' . $this->settings->format; $this->dst_url = $wgMathPath . $this->get_hash_path() . '/' . $this->hash . '.' . $this->settings->format; chdir($wgTmpDirectory); wfDebugLog('Metapost', "src_path: " . $this->src_path); wfDebugLog('Metapost', "dst_path: " . $this->dst_path); wfDebugLog('Metapost', "dst_url: " . $this->dst_url); } function __destruct() { $er = error_reporting(E_ALL ^ E_WARNING); unlink($this->src_path . ".mp"); unlink($this->src_path . ".mpx"); unlink($this->ltx_src_path . ".mpx"); unlink($this->ltx_src_path . ".tmp"); unlink($this->src_path . ".1"); unlink($this->src_path . ".log"); chdir($this->old_cwd); error_reporting($er); } function create_metapost() { $fd = fopen($this->src_path . ".mp", "wb"); fwrite($fd, "prologues := 1;\nnonstopmode;\n\n"); foreach ($this->settings->inputs as $inp) { fwrite($fd, "input " . $inp . ";\n"); } fwrite($fd, "\nbeginfig(1);\n"); fwrite($fd, $this->src); fwrite($fd, "\nendfig;\n\nend\n"); fclose($fd); } function create_image() { $mpost_cmd = wfEscapeShellArg($this->settings->metapostCommand) . " " . $this->src_path . ".mp"; wfDebugLog('Metapost', "mpost stage: " . $mpost_cmd); exec($mpost_cmd); if (!file_exists($this->src_path . ".1")) { return false; } if (file_exists($this->ltx_src_path . ".tmp")) { wfDebugLog('Metapost', "mpost stage ltx: " . $mpost_cmd); exec($mpost_cmd); } if (!file_exists($this->src_path . ".1")) { return false; } $conv_cmd = wfEscapeShellArg($this->settings->convertCommand) . " -density " . wfEscapeShellArg($this->settings->density) . " -trim -transparent \"#FFFFFF\" " . wfEscapeShellArg($this->src_path . ".1") . " " . wfEscapeShellArg($this->dst_path); wfDebugLog('Metapost', "convert stage: " . $conv_cmd); exec($conv_cmd); if (!file_exists($this->dst_path)) { return false; } return true; } function get_image_url() { if (is_file($this->dst_path) && ($this->settings->redraw == true)) { unlink($this->dst_path); } if (is_file($this->dst_path)) { return $this->dst_url; } else { $this->create_metapost(); if ($this->create_image()) { return $this->dst_url; } else { return false; } } } } # The callback function for converting the input text to HTML output function renderMetapost($src, $argv) { $renderer = new MetapostRenderer($src); global $wgMetapostSettings; if (array_key_exists('density', $argv)) { $renderer->settings->density = $argv['density']; } if (array_key_exists('redraw', $argv)) { $renderer->settings->redraw = true; } if (array_key_exists('input', $argv)) { $c_inp = explode(',', $argv['input']); $renderer->settings->inputs = array_unique(array_merge($wgMetapostSettings->inputs, $c_inp)); } if (array_key_exists('format', $argv)) { if ($argv['format'] != "png") { return "[Formats other than PNG are not yet supported]"; } } $url = $renderer->get_image_url(); if ($url == false) { $text = "[An error occured in Metapost extension]"; } else { $text = "<img src='$url'>"; } return $text; }
[edit] See also
- Extension:GraphViz
- Another cool extension for embedding graphics. Indeed, the source code of the Metapost extension is branched off from the source code of the GraphiViz extension!
- Gnuplot extension
- Useful for plotting graphs against a function or a set of data