Skip to content

Instantly share code, notes, and snippets.

@kenwebb
Last active December 21, 2020 15:13
Show Gist options
  • Save kenwebb/8203728 to your computer and use it in GitHub Desktop.
Save kenwebb/8203728 to your computer and use it in GitHub Desktop.
The Lord of the Rings
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Tue Dec 31 2013 19:40:39 GMT-0500 (EST)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: The Lord of the Rings
Description: Exploring the structure of Tolkien's Lord of the Rings
Url: http://www.primordion.com/Xholon/gwt/
InternalName: fd7897a8-2a68-4ebd-bb23-981b70395841
Keywords:
My Notes
========
December 30, 2013
In this Xholon Workbook, I explore the structure of The Lord of the Rings (LOTR), J.R.R. Tolkien's three-volume fantasy novel. More generally, I'll be working out how to capture the structure of any novel, film, or other story. As an editor, at least initially, I'm using the online Xholon Workbook editor.
As much as possible, I'll use the exact spellings used in wikipedia. This will allow users to directly search wikipedia for more information. The names of characters and places will be in English alphabetical order.
Initially, I'm interested in identifying the main characters, places, and events, and how these interact with each other. I'll consider the main characters to be those identified in the wikipedia LOTR template. There is no short list of main places in wikipedia, so I'll take these from the LOTR article(s) as I see fit.
To bring those characters into this workbook, all I need to do is copy the text from the wikipedia page, and paste it into the CSH Characters tag. It appears automatically formatted as a vertical list. The only editing I need to do is to convert spaces and dashes to underlines, because Xholon will later need to convert these names into XML tags.
I've added a behavior (LotrSystembehavior) that generates the Xholon structure from the various lists.
Events, Timeline
----------------
I want to add some events, that together will make up a timeline. Querying for "lotr timeline" reveals that there's a lot of material available online. An event should include the following information:
date: 81006 = October 6 in the year 3018 of the Third Age
place: a town, region, river, or other geographical location
characters: main character, plus optional additional characters
annotation: a short semi-structured description
events are from http://en.wikipedia.org/wiki/Timeline_of_Arda
December 31, 2013
Events read the timeStep, keep track of which event is the current event, and print matching events in the out tab.
This completes the simple first version of my LOTR app.
TODO
----
- show a map of LOTR as background on a canvas
- use requirejs
- use png.js
- add x, y coordinates to places
References and Sources
----------------------
http://en.wikipedia.org/wiki/The_Lord_of_the_Rings
http://en.wikipedia.org/wiki/Template:The_Lord_of_the_Rings
http://en.wikipedia.org/wiki/Category:The_Lord_of_the_Rings
http://en.wikipedia.org/wiki/Category:Middle-earth_locations
http://lotro-wiki.com/index.php/Landmark_coordinates
http://lotr.wikia.com/wiki/File:Middle-earth.jpg
http://www.primordion.com/Xholon/gwt/wb/editwb.html
google: lotr timeline
http://lotrproject.com/timeline/
http://en.wikipedia.org/wiki/Timeline_of_Arda
http://lotr.wikia.com/wiki/Timeline_of_Arda
http://xkcd.com/657/
]]></Notes>
<_-.XholonClass>
<LotrSystem/>
<Lord_of_the_Rings/>
<!-- Character
hobbit, man, wizard, elf, dwarf, troll, orc, ent, etc.
these are active objects
-->
<Character/>
<!-- Place
anything that can have geographical coordinates
these are passive objects, or containers
-->
<Place/>
<!-- Event
something that happens at a specific time, in a specific place, involving specific characters
events are deterministic, and always happen at the same time
these are passive objects
-->
<Event superClass="Attribute_String"/>
<!-- Thing
ring
these are typically passive objects, but the one ring may be an active object (it wants to get back to Sauron)
-->
<Thing/>
<!-- collections -->
<Characters/>
<Placess/>
<Events/>
<Things/>
<!-- control and initialization -->
<CharactersControl/>
<PlacessControl/>
<EventsControl/>
<ThingsControl/>
</_-.XholonClass>
<xholonClassDetails>
</xholonClassDetails>
<LotrSystem>
<CharactersControl>
<Attribute_String>
Aragorn
Arwen
Bilbo
Boromir
Celeborn
Denethor
Elrond
Éomer
Éowyn
Faramir
Frodo
Galadriel
Gandalf
Gimli
Gollum
Legolas
Merry
Mouth_of_Sauron
Old_Man_Willow
Pippin
Radagast
Sam
Saruman
Sauron
Shelob
Théoden
Tom_Bombadil
Treebeard
Witch_king
Wormtongue
</Attribute_String>
</CharactersControl>
<PlacessControl>
<Attribute_String>
Bree
Bruinen
Lothlórien
Misty_Mountains
Mordor
Moria
Mount_Doom
Old_Forest
Rivendell
Shire
Weathertop
</Attribute_String>
</PlacessControl>
<ThingsControl>
<Attribute_String>
One_Ring
</Attribute_String>
</ThingsControl>
<EventsControl>
<!-- the years are 3018 and 3019 of the Third Age; the dates are in YYMMDD format -->
<Attribute_String>
180411,Shire,Gandalf[Frodo],"Gandalf returns to the Shire, telling Frodo Baggins he must take the Ring away"
180620,Osgiliath,Sauron,"Sauron attacks Osgiliath"
180704,Minas_Tirith,Boromir,"Boromir leaves Minas Tirith"
180710,Orthanc,Saruman[Gandalf],"Saruman imprisons Gandalf in Orthanc"
180918,Orthanc,Gandalf,"Gandalf escapes from Orthanc"
180919,Edoras,Gandalf,"Gandalf reaches Edoras and is given Shadowfax the horse"
180923,Bag_End,Frodo,"Frodo leaves Bag End"
180930,Bree,Aragorn,"Aragorn meets Frodo Baggins in the Inn of the Prancing Pony in Bree"
181006,Weathertop,Frodo,"Frodo wounded at Weathertop"
181020,Bruinen,Frodo,"Frodo crosses the ford of Bruinen"
181025,Rivendell,Council of Elrond,"Council of Elrond at Rivendell"
181225,Rivendell,Fellowship,"The Fellowship of the Ring sets out in the evening from Rivendell"
190115,Khazad-dûm,Gandalf,"Gandalf falls in Khazad-dûm while fighting a Balrog"
190225,Parth_Galen,Fellowship,"The Fellowship passes the Argonath and camp at Parth Galen. First Battle of Fords of Isen; Théodred son of Théoden is slain"
190226,Parth_Galen,Fellowship,"The breaking of the Fellowship; Boromir is killed"
190229,Parth_Galen,Merry[Pippin],"Merry and Pippin escape the orcs and meet Treebeard"
190301,Fangorn_Forest,Aragorn[Legolas Gimli Gandalf],"Aragorn, Legolas and Gimli meet the resurrected Gandalf the White in Fangorn Forest while looking for Merry and Pippin, and they head off for Edoras."
190301,Dead_Marshes,Frodo[Sam],"Frodo and Sam begin travelling through the Dead Marshes"
190303,Hornburg,,"Battle of the Hornburg"
190305,Isengard,,"Rohan's army reaches Isengard"
190307,Henneth_Annûn,Faramir[Frodo Sam],"Faramir takes Frodo and Sam to Henneth Annûn"
190308,Paths_of_the_Dead,Aragorn[Legolas Gimli],"Aragorn, Legolas and Gimli enter the Paths of the Dead"
190309,Minas_Tirith,Gandalf[Pippin],"Gandalf and Pippin arrive in Minas Tirith"
190310,Minas_Morgul,Frodo[Sam],"Frodo and Sam see the Morgul host led by the Witch-king leave Minas Morgul. An army from Morannon takes Cair Andros and marches in Anórien"
190311,Lórien,,"First assault on Lórien by Dol Guldur"
190312,Shelob_lair,Gollum[Frodo],"Gollum leads Frodo into Shelob's lair"
190313,Cirith_Ungol,Frodo,"Frodo captured by Cirith Ungol orcs"
190313,Pelargir,Aragorn,"Aragorn captures the Umbar fleet at Pelargir"
190315,"Witch-king breaks the gate of Minas Tirith in the early hours. Denethor burns himself on a pyre. Confrontation between Gandalf and the Witch-king at the gate; Horns of the Rohirrim are heard at a cockcrow. Battle of the Pelennor Fields,"Théoden King of Rohan is killed by the Witch-king; Éomer succeeds him as the eighteenth king of Rohan. Éowyn and Merry kill the Witch-king. Aragorn, Rangers, sons of Elrond and men from the southern fiefdoms of Gondor arrive in the black ships and turn the tide of battle."
190315,Morgai,Frodo[Sam],"Sam and Frodo escape and journey along the Morgai."
190315,Mirkwood,,"Battle under the trees in Mirkwood; second assault on Lórien"
190316,,,"Debate of the Captains of the West"
190317,,,"Battle of Dale. King Brand and Dáin Ironfoot fall in battle against invading Easterlings. Many Men and Dwarves take refuge in Erebor"
190318,Minas_Tirith,,"Armies leave Minas Tirith."
190318,,Frodo[Sam],"Frodo and Sam join the orc company"
190325,Slag-hills,,"The Host is surrounded on the Slag-hills."
190325,Cracks_of_Doom,Frodo[Sam Gollum],"Frodo and Sam reach the Sammath Naur. Gollum (Sméagol) seizes the One Ring and falls into the Cracks of Doom."
190325,,Sauron,"Downfall of Barad-dûr and the passing of the Dark Lord Sauron"
</Attribute_String>
</EventsControl>
<Lord_of_the_Rings/>
</LotrSystem>
<LotrSystembehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var lotrsys, app;
var beh = {
postConfigure: function() {
lotrsys = this.cnode.parent();
app = $wnd.xh.app();
$wnd.xh.param("MaxPorts", "10");
$wnd.xh.param("TimeStep", "180410");
$wnd.xh.param("TimeStepInterval", "200");
// get xhRoot
console.log(lotrsys.toString());
var xhRoot = $wnd.xh.xpath("./Lord_of_the_Rings", lotrsys);
console.log(xhRoot.toString());
// get xhcRoot
var xhcRoot = lotrsys.xhc().parent();
// get XholonHelperService
var service = $wnd.xh.service("XholonHelperService");
var node = lotrsys.first();
this.makeAll("Character", "s", node.first().text(), xhRoot, xhcRoot, service);
node = node.next();
this.makeAll("Place", "ss", node.first().text(), xhRoot, xhcRoot, service);
node = node.next();
this.makeAll("Thing", "s", node.first().text(), xhRoot, xhcRoot, service);
},
makeAll: function(tagName, pluralizer, text, xhRoot, xhcRoot, service) {
// ih
var ihStr = this.makeIhStr(tagName, text);
service.call(-2013, ihStr, xhcRoot); // ISignal.ACTION_PASTE_LASTCHILD_FROMSTRING = -2013
// csh
var cshStr = this.makeCshStr(tagName + pluralizer, text);
service.call(-2013, cshStr, xhRoot);
},
// Make an Inheritance Hierarchy XML string
makeIhStr: function(tagName, text) {
console.log("ih: " + tagName);
var classXml = "<_-.XholonClass><" + tagName + ">\n";
var arr = text.split("\n");
for (var i = 0; i < arr.length; i++) {
var str = arr[i];
if (str) {
var items = str.split(",");
classXml += " <" + items[0].trim() + "/>\n";
}
}
classXml += "</" + tagName + "></_-.XholonClass>\n";
return classXml;
},
// Make a Composite Structure Hierarchy XML string
makeCshStr: function(tagName, text) {
console.log("csh: " + tagName);
var xml = "<" + tagName + ">\n";
var arr = text.split("\n");
for (var i = 0; i < arr.length; i++) {
var str = arr[i];
if (str) {
var items = str.split(",");
xml += " <" + items[0].trim() + "/>\n";
}
}
xml += "</" + tagName + ">\n";
return xml;
}
}
]]></LotrSystembehavior>
<EventsControlbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var events, xhRoot;
var beh = {
postConfigure: function() {
events = this.cnode.parent();
xhRoot = $wnd.xh.xpath("Lord_of_the_Rings", $wnd.xh.root().first());
var service = $wnd.xh.service("XholonHelperService");
var node = events.first();
var cshStr = this.makeCshStr("Events", node.text());
service.call(-2013, cshStr, xhRoot); // ISignal.ACTION_PASTE_LASTCHILD_FROMSTRING = -2013
},
// Make a Composite Structure Hierarchy XML string
makeCshStr: function(tagName, text) {
var xml = "<" + tagName + ">\n";
var arr = text.split("\n");
for (var i = 0; i < arr.length; i++) {
var str = arr[i];
if (str) {
xml += " <Event>" + str + "</Event>\n";
}
}
xml += "</" + tagName + ">\n";
return xml;
}
}
]]></EventsControlbehavior>
<Eventsbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var events, nextEvent, nextEventArr, nextTimeStep, state;
var beh = {
postConfigure: function() {
events = this.cnode.parent();
state = 0;
nextEvent = null;
nextEventArr = null;
nextTimeStep = "0";
this.findNextEvent();
},
act: function() {
var ts = $wnd.xh.param("TimeStep");
while (nextTimeStep == ts) {
events.println(nextEventArr);
this.findNextEvent();
}
// adjust the time step to correspond with years months and days YYMMDD
// YYMM31 becomes YYMM99
if ((ts.charAt(4) == "3") && (ts.charAt(5) == "1")) {
$wnd.xh.param("TimeStep", ts.substr(0, 4) + "99");
}
if (ts == "181231") {
$wnd.xh.param("TimeStep", "190101");
}
},
findNextEvent: function() {
if (state == 0) {
nextEvent = events.first();
state = 1;
}
else if (nextEvent == null) {
nextTimeStep = "0";
return;
}
else {
nextEvent = nextEvent.next();
}
if (nextEvent.xhc().name() != "Event") {
// nextEvent must be an Eventsbehavior object
nextEvent = null;
nextTimeStep = "0";
return;
}
var text = nextEvent.text();
// the quoted annotation may include commas, so limit the size of the array to 3
nextEventArr = nextEvent.text().split(",", 3);
// now add the annotation to the array
var start = text.indexOf('"') + 1;
var end = text.indexOf('"', start);
nextEventArr.push(text.substring(start, end));
nextTimeStep = nextEventArr[0];
}
}
]]></Eventsbehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Lord of the Rings</title>
<rect id="LotrSystem" fill="#98FB98" height="50" width="50" x="25" y="0"/>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment