r42712 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r42711‎ | r42712 | r42713 >
Date:06:01, 28 October 2008
Author:river
Status:old
Tags:
Comment:
awesome new extension to format ABC tunes in a wiki page
Modified paths:
  • /trunk/extensions/ABC (added) (history)
  • /trunk/extensions/ABC/ABC.i18n.php (added) (history)
  • /trunk/extensions/ABC/ABC.php (added) (history)

Diff [purge]

Index: trunk/extensions/ABC/ABC.i18n.php
@@ -0,0 +1,21 @@
 2+<?php
 3+/* Copyright (c) 2008 River Tarnell <river@loreley.flyingparchment.org.uk>. */
 4+/*
 5+ * Permission is granted to anyone to use this software for any purpose,
 6+ * including commercial applications, and to alter it and redistribute it
 7+ * freely. This software is provided 'as-is', without any express or implied
 8+ * warranty.
 9+ */
 10+/* $Id$ */
 11+
 12+$messages = array();
 13+
 14+$messages['en'] = array(
 15+ 'abcdesc' => 'Adds <tt>&lt;abc&gt;</tt> tag to format ABC music',
 16+ 'abcdownload' => 'Download:',
 17+ 'abcsep' => '|',
 18+ 'abcabc' => 'ABC',
 19+ 'abcpdf' => 'PDF',
 20+ 'abcps' => 'PostScript',
 21+ 'abcmidi' => 'MIDI',
 22+);
Property changes on: trunk/extensions/ABC/ABC.i18n.php
___________________________________________________________________
Name: svn:keywords
123 + Id Revision
Name: svn:eol-style
224 + native
Index: trunk/extensions/ABC/ABC.php
@@ -0,0 +1,257 @@
 2+<?php
 3+/* Copyright (c) 2008 River Tarnell <river@loreley.flyingparchment.org.uk>. */
 4+/*
 5+ * Permission is granted to anyone to use this software for any purpose,
 6+ * including commercial applications, and to alter it and redistribute it
 7+ * freely. This software is provided 'as-is', without any express or implied
 8+ * warranty.
 9+ */
 10+/* $Id$ */
 11+
 12+if (!defined('MEDIAWIKI'))
 13+ die();
 14+
 15+# The on-disk path where ABC files and rendered images / PDFs
 16+# will be placed.
 17+# Example: $abcPath = "/var/www/wiki/abc";
 18+$abcPath = false;
 19+
 20+# The HTTP path where the above directory is found.
 21+# Example: $abcURL = "/wiki/abc";
 22+$abcURL = false;
 23+
 24+# Path to the abcm2ps executable.
 25+$abcm2ps = "/usr/bin/abcm2ps";
 26+
 27+# Path to the ps2pdf executable.
 28+$abcps2pdf = "/usr/bin/ps2pdf14";
 29+
 30+# Path to the abc2midi executable.
 31+$abc2midi = "/usr/bin/abc2midi";
 32+
 33+$wgExtensionCredits['parserhooks'][] = array(
 34+ 'name' => 'ABC',
 35+ 'author' => 'River Tarnell',
 36+ 'url' => 'http://www.mediawiki.org/wiki/Extension:ABC',
 37+ 'description' => 'Adds <tt>&lt;abc&gt;</tt> tag to format ABC music',
 38+ 'descriptionmsg' => 'abcdesc'
 39+);
 40+$wgExtensionMessagesFiles['ABC'] = dirname(__FILE__) . '/ABC.i18n.php';
 41+
 42+if (defined('MW_SUPPORTS_PARSERFIRSTCALLINIT')) {
 43+ $wgHooks['ParserFirstCallInit'][] = 'efABCInit';
 44+} else {
 45+ $wgExtensionFunctions[] = 'efABCParserInit';
 46+}
 47+
 48+function
 49+efABCInit() {
 50+global $wgParser;
 51+ wfLoadExtensionMessages('ABC');
 52+ $wgParser->setHook( 'abc', 'efABCRender' );
 53+ return true;
 54+}
 55+
 56+function
 57+efABCRender($input, $args, $parser) {
 58+global $abcPath, $abcURL;
 59+ if ($abcPath == false || $abcURL == false)
 60+ return 'Error: $abcPath and $abcURL must be set to use the ABC extension.';
 61+
 62+ /*
 63+ * To avoid re-rendering the same tunes on every view,
 64+ * use the hash of the ABC content for the filename.
 65+ * This has the added benefit that rendering the same tune
 66+ * on different pages will only cause one rendering.
 67+ */
 68+ $float = "left";
 69+ if (isset($args['float']) && $args['float'] == 'right')
 70+ $float = "right";
 71+
 72+ $abc = preg_replace("/^\n+/", "", $input);
 73+ $hash = sha1($input);
 74+ $error = "";
 75+
 76+ /*
 77+ * Try to extract the title from the ABC. This is used as the
 78+ * alt text for the image.
 79+ */
 80+ $title = "Unknown song";
 81+ if (preg_match("/^T:\s*(.*)$/m", $input, $matches))
 82+ $title = $matches[1];
 83+
 84+ if (!abcCreateABC($abc, $hash, $error))
 85+ return str_replace("\n", "<br />", htmlspecialchars($error));
 86+ if (!abcCreatePS($abc, $hash, $error))
 87+ return str_replace("\n", "<br />", htmlspecialchars($error));
 88+ if (!abcCreatePNG($abc, $hash, $error))
 89+ return str_replace("\n", "<br />", htmlspecialchars($error));
 90+ if (!abcCreatePDF($abc, $hash, $error))
 91+ return str_replace("\n", "<br />", htmlspecialchars($error));
 92+ if (!abcCreateMIDI($abc, $hash, $error))
 93+ return str_replace("\n", "<br />", htmlspecialchars($error));
 94+
 95+ /*
 96+ * Succeeded to create all the output formats, return the
 97+ * output. We produce an image from the PNG, and include
 98+ * links to the ABC and PS.
 99+ */
 100+ $e_title = htmlspecialchars($title);
 101+ $e_imgpath = htmlspecialchars("$abcURL/$hash.png");
 102+ $e_abcpath = htmlspecialchars("$abcURL/$hash.abc");
 103+ $e_pspath = htmlspecialchars("$abcURL/$hash.ps");
 104+ $e_pdfpath = htmlspecialchars("$abcURL/$hash.pdf");
 105+ $e_midipath = htmlspecialchars("$abcURL/$hash.mid");
 106+
 107+ $e_abclink = "<a href=\"$e_abcpath\">" . wfMsg('abcabc') . "</a>";
 108+ $e_pslink = "<a href=\"$e_pspath\">" . wfMsg('abcps') . "</a>";
 109+ $e_pdflink = "<a href=\"$e_pdfpath\">" . wfMsg('abcpdf') . "</a>";
 110+ $e_midilink = "<a href=\"$e_midipath\">" . wfMsg('abcmidi') . "</a>";
 111+
 112+ $e_dllinks = wfMsg('abcdownload') . " " .
 113+ join(" " . wfMsg('abcsep') . " ",
 114+ array($e_abclink, $e_pslink, $e_pdflink, $e_midilink));
 115+
 116+ $output = <<<EOF
 117+<div style="float: $float; border: solid 1px #aaaaaa; margin: 0.2em;" class="abc-music">
 118+ <img src="$e_imgpath" alt="$e_title" />
 119+ <div style="text-align: center">
 120+ $e_dllinks
 121+ </div>
 122+</div>
 123+EOF;
 124+ return $output;
 125+}
 126+
 127+function
 128+abcCreateABC($abc, $hash, &$error)
 129+{
 130+global $abcPath;
 131+ if (!@file_exists($abcPath)) {
 132+ $error = "Error: $abcPath does not exist.";
 133+ return false;
 134+ }
 135+
 136+ $filename = "$abcPath/$hash.abc";
 137+ if (($f = @fopen($filename, "w")) === false) {
 138+ $last = error_get_last();
 139+ $msg = $last['msg'];
 140+ $error = "Error: cannot create $filename: $msg";
 141+ return false;
 142+ }
 143+
 144+ if (@fwrite($f, $abc) === false) {
 145+ @unlink($filename);
 146+ $last = error_get_last();
 147+ $msg = $last['msg'];
 148+ $error = "Error: cannot write to $filename: $msg";
 149+ return false;
 150+ }
 151+
 152+ if (@fclose($f) === false) {
 153+ @unlink($filename);
 154+ $last = error_get_last();
 155+ $msg = $last['msg'];
 156+ $error = "Error: cannot write to $filename: $msg";
 157+ return false;
 158+ }
 159+
 160+ return true;
 161+}
 162+
 163+function
 164+abcCreatePS($abc, $hash, &$error)
 165+{
 166+global $abcm2ps, $abcPath;
 167+ if (!@file_exists($abcm2ps)) {
 168+ $error = "Error: $abcm2ps not found.";
 169+ return false;
 170+ }
 171+
 172+ $input = "$abcPath/$hash.abc";
 173+ $output = "$abcPath/$hash.ps";
 174+
 175+ $cmd = "$abcm2ps -E $input -O $abcPath/$hash";
 176+ @exec($cmd, $cmd_out, $ret);
 177+ if ($ret != 0 || !@file_exists("$abcPath/{$hash}001.eps")) {
 178+ $error = "Error: $abcm2ps failed to convert input (ret: $ret).\n";
 179+ $error .= "Output: " . join("\n", $cmd_out);
 180+ return false;
 181+ }
 182+
 183+ if (@rename("$abcPath/{$hash}001.eps", "$abcPath/{$hash}.ps") === false) {
 184+ $error = "Error: cannot rename output file.";
 185+ return false;
 186+ }
 187+
 188+ return true;
 189+}
 190+
 191+function
 192+abcCreatePDF($abc, $hash, &$error)
 193+{
 194+global $abcps2pdf, $abcPath;
 195+ if (!@file_exists($abcps2pdf)) {
 196+ $error = "Error: $abcps2pdf not found.";
 197+ return false;
 198+ }
 199+
 200+ $input = "$abcPath/$hash.ps";
 201+ $output = "$abcPath/$hash.pdf";
 202+
 203+ $cmd = "$abcps2pdf $input $output";
 204+ @exec($cmd, $cmd_out, $ret);
 205+ if ($ret != 0 || !@file_exists("$abcPath/$hash.pdf")) {
 206+ $error = "Error: $abcps2pdf failed to convert input (ret: $ret).\n";
 207+ $error .= "Output: " . join("\n", $cmd_out);
 208+ return false;
 209+ }
 210+
 211+ return true;
 212+}
 213+
 214+function
 215+abcCreatePNG($abc, $hash, &$error)
 216+{
 217+global $wgImageMagickConvertCommand, $abcPath;
 218+ if (!$wgImageMagickConvertCommand) {
 219+ $error = "Error: ImageMagick not enabled.";
 220+ return false;
 221+ }
 222+
 223+ $input = "$abcPath/$hash.ps";
 224+ $output = "$abcPath/$hash.png";
 225+
 226+ $cmd = "$wgImageMagickConvertCommand $input $output";
 227+ @exec($cmd, $cmd_out, $ret);
 228+ if ($ret != 0 || !@file_exists($output)) {
 229+ $error = "Error: ImageMagick failed to convert input [$output] (ret: $ret).";
 230+ $error .= "Output: " . join("\n", $cmd_out);
 231+ return false;
 232+ }
 233+
 234+ return true;
 235+}
 236+
 237+function
 238+abcCreateMIDI($abc, $hash, &$error)
 239+{
 240+global $abc2midi, $abcPath;
 241+ if (!$abc2midi) {
 242+ $error = "Error: $abc2midi not found.";
 243+ return false;
 244+ }
 245+
 246+ $input = "$abcPath/$hash.abc";
 247+ $output = "$abcPath/$hash.mid";
 248+
 249+ $cmd = "$abc2midi $input -o $output";
 250+ @exec($cmd, $cmd_out, $ret);
 251+ if ($ret != 0 || !@file_exists($output)) {
 252+ $error = "Error: $abc2midi failed to convert input [$output] (ret: $ret).";
 253+ $error .= "Output: " . join("\n", $cmd_out);
 254+ return false;
 255+ }
 256+
 257+ return true;
 258+}
Property changes on: trunk/extensions/ABC/ABC.php
___________________________________________________________________
Name: svn:keywords
1259 + Id Revision
Name: svn:eol-style
2260 + native

Status & tagging log