Humdrum wiki extension
The CCARH wiki includes a Humdrum music notation extension that allows Humdrum data embedded within a page to be rendered as graphical music notation.
Contents
Basic example
<humdrum>
- kern
1f;
- -
</humdrum>
The above notation was created with the Humdrum tag:
<humdrum> **kern 1f; *- </humdrum>
More complicated example
This example includes lyrics, coloring of notes with RDF records, and a transposition filter (Transposing from A-flat major in the data to C major in the notation).
<humdrum scale="55">
!!!OMD: Slow
- kern **text
- k[b-e-a-d-] *
- A-: *
- M4/4 *
- met(c) *
- *color:gold
4cc If =1 =1 (8dd-L@ Mu- 8ccJ)@ . (8b-L@ -sic_ 8a-J)@ . (8gL be_ 8a-J) . (8b-L the_ 8ccJ) . =2 =2 (8b-L food_ 8a-J) . (8gL of_ 8fJ) . 4.enN Love, 8c sing =3 =3 4f on, 4f sing 4.a- on, 8f sing =4 =4 4cc on, 4cc sing 4.ee- on, =- =-
- - *-
!!!RDF**kern: @ = marked note, color=chartreuse !!!RDF**kern: N = marked note, color=hotpink !!!filter: transpose -k c </humdrum>
which was created with the text:
<humdrum scale="55"> !!!OMD: Slow **kern **text *k[b-e-a-d-] * *A-: * *M4/4 * *met(c) * 4cc If =1 =1 (8dd-L@ Mu- 8ccJ)@ . (8b-L@ -sic_ 8a-J)@ . (8gL be_ 8a-J) . (8b-L the_ 8ccJ) . =2 =2 (8b-L food_ 8a-J) . (8gL of_ 8fJ) . 4.enN Love, 8c sing =3 =3 4f on, 4f sing 4.a- on, 8f sing =4 =4 4cc on, 4cc sing 4.ee- on, =- =- *- *- !!!RDF**kern: @ = marked note, color=chartreuse !!!RDF**kern: N = marked note, color=hotpink !!!filter: transpose -k c </humdrum>
CSV Humdrum
The standard WikiMedia page editor does not allow inserting tab characters, so either copy-and-paste humdrum text from another editor, such as http://verovio.humdrum.org, (which can also be used to validate the Humdrum data) or encode the Humdrum data in CSV format instead of TSV:
<humdrum scale="55"> !!!OMD: Slow **kern,**text *k[b-e-a-d-],* *A-:,* *M4/4,* *met(c),* 4cc,If =1,=1 (8dd-L@,Mu- 8ccJ)@,. (8b-L@,-sic_ 8a-J)@,. (8gL,be_ 8a-J),. (8b-L,the_ 8ccJ),. =2,=2 (8b-L,food_ 8a-J),. (8gL,of_ 8fJ),. 4.enN,"Love," 8c,sing =3,=3 4f,"on," 4f,sing 4.a-,"on," 8f,sing =4,=4 4cc,"on," 4cc,sing 4.ee-,"on," =-,=- *-,*- !!!RDF**kern: @ = marked note, color=chartreuse !!!RDF**kern: N = marked note, color=hotpink !!!filter: transpose -k c </humdrum>
The TSV form of Humdrum can be converted to CSV on VHV by using the alt-u command. Verovio and the humdrum-plugin library know how to convert the CSV form of Humdrum back into the TSV form for processing.
Options
The Humdrum notation extension is implemented using the humdrum javascript plugin documented at https://plugin.humdrum.org. All of the options described in that documentation can be used as attributes for the humdrum element on a wiki page. The full list of options: https://plugin/humdrum.org/options.
Here is an example that loads the Humdrum data from an external source, and it is not stored in the webpage:
<humdrum
url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3c.krn" scale="33" header="true"
></humdrum>
This musical example was created with the following text:
<humdrum url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3c.krn" scale="33" header="true" ></humdrum>
In this case, the music is downloaded from the Github repository https://github.com/craigsapp/moart-piano-sonatas, specified by the url attribute. The scale attribute sets the music notation size to 33% of the default size in verovio (the humdrum plugin uses a default of 40%), and the header tag, when set to "true", displays the title and composer information above the first system of the music.
Here is an example of downloading the same score, but only displaying measures 10 and 11 using the filter option:
<humdrum
url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3c.krn" scale="33" filter="myank -m 10-11"
></humdrum>
<humdrum url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3c.krn" scale="33" filter="myank -m 10-11" ></humdrum>
Musical incipits
There is a special option called incipit that displays only the first system of music. Here is an example of incipits for each movement of the example Mozart sonata:
Movement 1: <humdrum
url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-1.krn" scale="33" incipit="true"
></humdrum> Movement 2: <humdrum
url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-2.krn" scale="33" incipit="true"
></humdrum> Movement 3: <humdrum
url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3a.krn" scale="33" incipit="true"
></humdrum>
Created with this code:
Movement 1: <humdrum url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-1.krn" scale="33" incipit="true" ></humdrum> Movement 2: <humdrum url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-2.krn" scale="33" incipit="true" ></humdrum> Movement 3: <humdrum url="https://raw.githubusercontent.com/craigsapp/mozart-piano-sonatas/master/kern/sonata06-3a.krn" scale="33" incipit="true" ></humdrum>
Installation
If you have a wiki that uses MediaWiki, then here are instructions for allowing use of the <humdrum> tag to generate music notation on wiki pages:
(1) Place this line in the LocalSettings.php file that is located in the base directory of the wiki's website (wherever that is installed on your web server):
require_once "$IP/extensions/Humdrum/Humdrum.php";
(2) Place the following contents into a file called extensions/Humdrum/Humdrum.php in relation to the base directory of your wiki website:
<?php
/*
* humdrum-mediawiki-extension
* Humdrum music notation extension for MediaWiki.
*
* Craig Stuart Sapp <craig@ccrma.stanford.edu>
* Wed Dec 12 14:54:26 PST 2018
* Developed for use in MediaWiki 1.24
*
* This <humdrum> tag extension converts Humdrum scores into SVG images using
* the Verovio toolkit on a MediaWiki-based wiki (https://www.mediawiki.org/wiki/MediaWiki).
* The extension loads two external javascript libraries to produce SVG images
* directly within a user's web browser:
* (1) Verovio (https://www.verovio.org), using a Humdrum-aware version stored at
* https://verovio-script.humdrum.org.
* (2) humdrum-plugin (https://plugin.humdrum.org) which serves as a front-end to
* manage options for the Verovio toolkit.
* Since the extension inserts javascript code onto a webpage (which in turn inserts
* SVG images onto the page), the extension is not suitable for publically editable
* wikis (such as Wikipedia).
*
* The extension will convert a <humdrum> tag such as this:
*
* <humdrum scale="40">
* **kern
* *clefG2
* *M4/4
* 1c;
* ==
* *-
* </humdrum>
*
* into the following HTML code inserted onto the page:
*
* <script>
* displayHumdrum({
* "scale": "40"
* })
* </script>
* <script type="text/x-humdrum" id="example">
* **kern
* *clefG2
* *M4/4
* 1c;
* ==
* *-
* </script>
*
* The scale parameter sets the size of the music. Additional parameters
* are listed at https://plugin.humdrum.org/options. The first use of
* the <humdrum> tag will insert the following initializtion code:
*
* <script src="https://verovio-script.humdrum.org/scripts/verovio-toolkit.js"></script>
* <script src="https://plugin.humdrum.org/scripts/humdrum-plugin.js"></script>
* <script>var vrvToolkit = new verovio.toolkit()</script>
*
*
* Programming References:
* https://www.mediawiki.org/wiki/Manual:Tag_extensions
* https://www.mediawiki.org/wiki/Parser_extension_tags
*/
// tagCounter is used to initialize the humdrum-plugin code:
$tagCounter = 0;
$wgExtensionFunctions[] = 'wfHumdrum';
$wgExtensionCredits['parserhook'][] = array(
'name'=>'Humdrum',
'author'=>'Craig Stuart Sapp',
'url'=>'http://www.mediawiki.org/wiki/Extension:Humdrum',
'description'=>'Humdrum music notation renderer',
);
function wfHumdrum() {
new Humdrum();
}
class Humdrum {
public static function HumdrumTagSetup(Parser &$parser) {
global $tagCounter;
$tagCounter = 100;
$tagName = "humdrum";
$callback = function($input, $argv, $parser, $frame) use ($tagName) {
return Humdrum::hookHumdrum($input, $argv, $parser, $frame, $tagName);
};
$parser->setHook($tagName, $callback);
return true;
}
# Construct the extension and install it as a parser hook.
public function __construct() {
global $wgHooks;
$wgHooks['ParserFirstCallInit'][] = 'Humdrum::HumdrumTagSetup';
}
# hookHumdrum -- The hook function. Handles <humdrum></humdrum>.
# Receives the Humdrum content and <humdrum> parameters.
public static function hookHumdrum($humdrumText, $argv, $parser, $frame, $tagName) {
// prevent caching of pages using the extension
$parser->disableCache();
// Build the displayHumdrum parameters string from the tag parameters
// and insert into a <script> element.
global $tagCounter;
$source = "";
$optionContainer = "<script>displayHumdrum({";
foreach ($argv as $key => $val) {
$optionContainer .= "\t\"$key\":\t\"$val\",";
if ($key == "source") {
$source = $val;
}
}
if ($source == "") {
// create an automatic name for the notation example
$randval = rand();
$source = "humdrum-$randval";
$optionContainer .= "\t\"source\":\t\"$source\",";
}
$optionContainer = preg_replace('/,$/', "", $optionContainer);
$optionContainer .= "})</script>";
$humdrumContainer = "<script type=\"text/x-humdrum\" id=\"$source\">\n";
$humdrumContainer .= $humdrumText;
$humdrumContainer .= "</script>";
$initialization = "";
if ($tagCounter == 100) {
# Only include this code the first time an example is placed on the page.
$initialization .= "<script src=\"https://verovio-script.humdrum.org/scripts/verovio-toolkit.js\"></script>";
$initialization .= "<script src=\"https://plugin.humdrum.org/scripts/humdrum-plugin.js\"></script>";
$initialization .= "<script>var vrvToolkit = new verovio.toolkit()</script>";
}
$tagCounter++;
return array("$initialization$optionContainer$humdrumContainer", "markerType" => 'nowiki');
}
}
?>