Oh dear - I've been procrastinating. NSFW warning for some rude words in this post. Around a month ago Fiona and I stumbled across this blog post about an issue with Django. The post was very helpful and saved Fi a lot of headaches, so thanks to Harshad Sharma for that.
What caught my attention, though, was that fact that the post consists entirely of a rage comic. A rage comic, for the uninitiated, is an internet meme wherein a hilarious anecdote is retold in the form a crudely-drawn comic strip, usually full of cartoon facial expressions which are themselves internet memes. I joked that such a blog post, due to its entirely rasterised nature, would be difficult for a search engine to index. Difficult, that is, unless the comic's semantics could be encoded as text-based data. Sometimes, a joke gets out of hand.
Introducing RageML - a markup language for describing rage comics. In the age of the semantic web, information has no place being embedded in pixel data where it is difficult to extract and catalogue. Instead, the meaning of comic-based media can be encoded in a rich, standards-based machine- and human-readable language, thereby facilitating a broad spectrum of consumption methods from printed media to screen-readers.
RageML is an XML-based language, making it suitable for delivery via the internet using the HTTP protocol. The text-based nature of XML makes it human-readable whist at the same time its strictly-defined formal structure makes it ideal for parsing with software. It is also full of pointy brackets, if that's your thing.
At the root of a RageML document is the
<comic> element. The RageML namespace should be declared on the document root, as follows:
<comic xmlns="http://markfrimston.co.uk/rageml"> ... </comic>
<comic> may contain one or more
<panel> elements, each describing a panel of the comic, in reading order.
<comic> <panel> ... </panel> <panel> ... </panel> </comic>
RageML may describe up to 5 characters in the comic. These are labeled with the letters A-E. A character's presence in a panel is indicated with an element with the corresponding name. The following example demonstrates a 2-panel comic in which characters A, B and C are present but character B leaves in panel 2:
<comic> <panel> <a /> <b /> <c /> </panel> <panel> <a /> <c /> </panel> </comic>
The dialogue spoken by a character in a panel is inserted as the content of the corresponding character element. Lines of dialogue are listed in reading order regardless of the characters speaking them. The following example demonstrates dialogue spoken between 3 characters:
<panel> <b>Look at that over there</b> <c>What? Where?</c> <a>I don't see anything</a> </panel>
If a character speaks more than one line of dialogue in the same panel, the subsequent lines are described by
<x-reply> elements, where
x is the letter corresponding to the character.
<x-reply> elements must follow the
<e> elements in the panel. The following example demonstrates a conversation between 2 characters, each speaking more than one line:
<panel> <b>Check out that sweet-ass car</b> <a>More like sweet ass-car</a> <b-reply>Dude shut up</b-reply> <a-reply>You shut up</a-reply> <b-reply>No you shut up</b-reply> </panel>
The facial expression used by a character is described by one of the many face elements. The face element for the character should be the one and only child element of the corresponding character element. If a face element is used, any opening dialogue is specified as the contents of this element rather than the character element.
Some facial expressions imply accompanying dialogue. In the following example, character A speaks their dialogue with a "troll" face, while character B wears a simple "derp" face. Later character B's "rage" face implies that they are yelling "FFFFFFFFUUUUUUUUUUUUUUUUUUUU...":
<panel> <a> <trollface>I just used the last of the milk</trollface> </a> <b> <derp /> </b> </panel> <panel> <b> <rage /> </b> </panel>
Overriding Implied Dialogue
A face element with implied dialogue may contain different dialogue which overrides the default. The
<silent> element may be used to indicate that the character has no dialogue when their facial expression would otherwise imply default dialogue. In the following example, character A's dialogue is in fact "CLOSE ENOUGH" rather than the default "FUCK YEA" which the face element would otherwise imply. Character B wears the "are you serious" facial expression, but remains silent.
<panel> <b> <are-you-serious> <silent/> </are-you-serious> </b> <a> <fuck-yea>CLOSE ENOUGH</fuck-yea> </a> </panel>
As a shorthand notation, RageML allows face elements to be used without specifying a character. The face element must follow the
<e> elements, amongst the
<x-reply> elements. Such shorthand indicates the presence of some unnamed character wearing the corresponding facial expression. In the following example, lines of dialogue are exchanged between 2 unnamed characters:
<panel> <herp>herp derp derp</herp> <derp>derpy herp derp</derp> </panel>
<narration> element is used to describe opening and closing text for a panel. The element may appear as the first line of the panel, or the last line, or neither, or both. In the following example the panel is introduced with, and closes with, narration text:
<panel> <narration>Meanwhile, at the library</narration> <herp>Ssssshhhhhhhhh!</herp> <narration>But then...</narration> </panel>
Each character presence may be given a description to aid the reader in their understanding of the portrayed situation. This is achieved with the
label attribute which applies to the character elements
<e>. In the following example, characters A and B are described by label attributes:
<panel> <b label="le teacher">Did you do your homework?</b> <a label="le me">Um...</a> </panel>
The gender of a character is indicated with the
gender attribute, which applies to the character elements
<e>. Valid values for this attribute are "m" and "f" to denote male and female, respectively. In the following example, character A is indicated to be female, and character B to be male:
<panel> <a gender="f">Would you like a wormdo?</a> <b gender="m">A what?</b> </panel>
The following is a complete example demonstrating some of the features described above:
<?xml version="1.0" ?> <comic xmlns="http://markfrimston.co.uk/rageml"> <panel> <a gender="f" label="le girlfriend"> <trollface> Check out this new cola "T-abasco" </trollface> </a> <b gender="m" label="le me" /> </panel> <panel> <b /> <a> Bet you can't drink a whole bottle! </a> <pffftttchh /> </panel> <panel> <challenge-accepted /> </panel> <panel> <narration>Later...</narration> <rage /> </panel> </comic>
<comic xmlns="http://markfrimston.co.uk/rageml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://markfrimston.co.uk/rageml rageml.xsd"> ... </comic>
The author would like to note, at this point, that if you have to write a Python script to generate 900 lines of markup in order to allow all possible orderings of 5 elements, it may highlight something of a deficiency in the schema language.
A RageML document may be displayed as an image by linking it to the file
rageml.xsl, as follows:
<?xml-stylesheet type="text/xsl" href="rageml.xsl"?> <comic> ... </comic>
An example of the transform can be found here:
example.xml. Most modern web browsers are able to perform this transformation simply by opening the XML document. However, due to the same-origin policy implemented by all the major browsers, the XSL file must be located at the same domain as the RageML document itself - a small point which the author really wishes he had found out before embarking on this whole escapade.
The Future of RageML
RageML represents a bright new future for rage-comic-based content as it takes its place in the exciting and information-rich world of Web 3.0. By separating semantic meaning from visual presentation, RageML provides a simple platform for data mining whilst at the same time streamlining the delivery of the visual content itself. RageML's concise data format allows rage comic content to be communicated without superfluous pixel information, thereby helping to reduce bandwidth consumption across the world wide web. Especially 4-chan. It is surely only a matter of time before RageML becomes a web standard.