Skip to content

Instantly share code, notes, and snippets.

@dzucconi
Created May 8, 2012 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dzucconi/2635538 to your computer and use it in GitHub Desktop.
Save dzucconi/2635538 to your computer and use it in GitHub Desktop.
//
// The following program is written by Leslie Carr, IAM Research Group, Southampton University, UK
// and is based on work Zigzag(TM) work owned by Ted Nelson.
//
// This file may be distributed freely for research purposes only. No commercial product or service
// may be based on it or on any part of version of it.
// All queries should be directed to the author at lac@ecs.soton.ac.uk
//
// VERSION 0.5.2 large (40 cell) table, deleting, hopping
// VERSION 0.5.5 experimental zigzag traversal
// VERSION 0.6 clones, saving in XML, saving in HTML
//
// TO DO:
// fix keyboard focus problem
// new visualisations
//
var zzVersion = "0.6"
var zzCurrentN = 1;
var zzDimOne = "";
var zzDimTwo = "";
var zzMaxDims = 100
var zzTopDim = -1;
var zzDims = new Array(zzMaxDims)
var zzDimDescs = new Array(zzMaxDims)
var zzDimCols = new Array(zzMaxDims)
var onlyTurnAtCurrent = false
var horizonLimit = true
var maxTurns = 1
var zzTourN = 1
var zzTourSteps = new Array(zzMaxItems)
var zzExternalWindow = false
var zzMaxX = 20
var zzMaxY = 20
var zzMaxItems = 10000
var zzNegWard = 0,
zzPosWard = 1
var zzItems = new Array(zzMaxItems)
var zzLinks = new Array(zzMaxItems)
var zzFilled = new Array(zzMaxItems)
var zzFilledN = 0
var zzEditing = 0
var zzAdding = false
var zzDeleting = false
var zzChugging = false
var zzDebug = 0
var zzTitleStr = ""
var zzExplainStr = ""
var ieBrowser = document.all
var zzMarked = null
var zzLinking = false
var zzUnLinking = false
var nSaves = 0
var undefined // a variable whose value is undefined
function startUp() {
zzInitialise()
checkURLfrag()
reveal(true)
}
function reveal() {
zzClear()
zzSetDimensions()
zzRenderDimension(zzCurrentN, zzDimOne, zzDimTwo, 11, 11);
//zzRenderDimension(zzCurrentN, zzDimTwo, zzDimOne, 11, 11);
zzTour()
if (zzEditing < 1) zzNarrate()
}
function revealThis(n, x, y, d1, d2) {
var c
for (c = 0; zzDims[c] != null && zzDims[c] != d1; c++);
if (zzDims[c] != null) document.getElementById("dimSel1").selectedIndex = c;
for (c = 0; zzDims[c] != null && zzDims[c] != d2; c++);
if (zzDims[c] != null) document.getElementById("dimSel2").selectedIndex = c;
zzCurrentN = n
reveal()
}
function zzPressY() {
si = document.getElementById("dimSel1").selectedIndex
si++
if (si >= document.getElementById("dimSel1").length) si = 0
document.getElementById("dimSel1").selectedIndex = si
reveal(false);
}
function zzPressX() {
si = document.getElementById("dimSel2").selectedIndex
si++
if (si >= document.getElementById("dimSel2").length) si = 0
document.getElementById("dimSel2").selectedIndex = si
reveal(false);
}
function zzEval() {
var fs = zzContentsOf(zzCurrentN)
var fd = zzStepInDimension(zzCurrentN, "defn", 1)
var fn
if (fd > 0) {
fs = zzContentsOf(fd)
fn = new Function("n", "return " + fs)
}
else fn = new Function("n", "return " + fs + "(n)")
alert(fn(zzCurrentN))
}
function zzEvaluate(n, fs) {
var fn = new Function("n", "return " + fs)
if (n > 0) return (fn(n))
else return ""
}
function zzGoDown() {
var cl, m;
m = zzStepInDimension(zzCurrentN, zzDimOne, 1)
if (zzAdding) {
var newCell = zzMakeNewCellWithContents("Empty Cell");
zzLinkCells(zzCurrentN, newCell, zzDimOne);
if (m > 0) zzLinkCells(newCell, m, zzDimOne);
m = newCell;
zzAdding = false;
}
if (zzUnLinking) {
zzUnLinkCells(m, zzCurrentN, zzDimOne);
m = zzCurrentN;
window.status = ""
}
if (zzLinking) {
zzLinkCells(zzMarked, zzCurrentN, zzDimOne);
m = zzCurrentN;
window.status = ""
}
if (zzDeleting) {
zzUnLinkCell(m, zzDimOne);
m = zzCurrentN; // normal semantics are other way round
window.status = "Deleted cell " + m
}
if (zzChugging) {
if (m < 1) return;
zzChugCells(zzCurrentN, m, zzDimOne);
m = zzCurrentN; // normal semantics are other way round
}
if (m > 0) {
zzCurrentN = m
reveal(true)
}
}
function zzGoUp() {
var m;
m = zzStepInDimension(zzCurrentN, zzDimOne, -1)
if (zzAdding) {
var newCell = zzMakeNewCellWithContents("Empty Cell");
zzLinkCells(newCell, zzCurrentN, zzDimOne);
if (m > 0) zzLinkCells(m, newCell, zzDimOne);
m = newCell;
zzAdding = false;
}
if (zzLinking) {
zzLinkCells(zzCurrentN, zzMarked, zzDimOne);
m = zzCurrentN;
window.status = ""
}
if (zzUnLinking) {
zzUnLinkCells(zzCurrentN, m, zzDimOne);
m = zzCurrentN;
window.status = ""
}
if (zzDeleting) {
zzUnLinkCell(m, zzDimOne);
m = zzCurrentN; // normal semantics are other way round
window.status = "Deleted cell " + m
}
if (zzChugging) {
if (m < 1) return;
zzChugCells(m, zzCurrentN, zzDimOne);
m = zzCurrentN; // normal semantics are other way round
}
if (m > 0) {
zzCurrentN = m
reveal(true)
}
}
function zzGoLeft() {
var m;
m = zzStepInDimension(zzCurrentN, zzDimTwo, -1)
if (zzAdding) {
var newCell = zzMakeNewCellWithContents("Empty Cell");
zzLinkCells(newCell, zzCurrentN, zzDimTwo);
if (m > 0) zzLinkCells(m, newCell, zzDimTwo);
m = newCell;
zzAdding = false;
}
if (zzLinking) {
zzLinkCells(zzMarked, zzCurrentN, zzDimTwo);
m = zzCurrentN;
window.status = ""
}
if (zzUnLinking) {
zzUnLinkCells(zzCurrentN, m, zzDimTwo);
m = zzCurrentN;
window.status = ""
}
if (zzDeleting) {
zzUnLinkCell(m, zzDimTwo);
m = zzCurrentN; // normal semantics are other way round
window.status = "Deleted cell " + m
}
if (zzChugging) {
if (m < 1) return;
zzChugCells(m, zzCurrentN, zzDimTwo);
m = zzCurrentN; // normal semantics are other way round
}
if (m > 0) {
zzCurrentN = m
reveal(true)
}
}
function zzGoRight() {
var m;
m = zzStepInDimension(zzCurrentN, zzDimTwo, 1)
if (zzAdding) {
var newCell = zzMakeNewCellWithContents("Empty Cell");
zzLinkCells(zzCurrentN, newCell, zzDimTwo);
if (m > 0) zzLinkCells(newCell, m, zzDimTwo);
m = newCell;
zzAdding = false;
}
if (zzLinking) {
zzLinkCells(zzCurrentN, zzMarked, zzDimTwo);
window.status = ""
m = zzCurrentN;
}
if (zzUnLinking) {
zzUnLinkCells(m, zzCurrentN, zzDimTwo);
m = zzCurrentN;
window.status = ""
}
if (zzDeleting) {
zzUnLinkCell(m, zzDimTwo);
m = zzCurrentN; // normal semantics are other way round
window.status = "Deleted cell " + m
}
if (zzChugging) {
if (m < 1) return;
zzChugCells(zzCurrentN, m, zzDimTwo);
m = zzCurrentN; // normal semantics are other way round
}
if (m > 0) {
zzCurrentN = m
reveal(true)
}
}
function zzStepInDimension(n, d, direction) {
var dir
if (direction > 0) dir = zzPosWard;
else dir = zzNegWard;
var nnn = zzLinks[d];
if (nnn == null || nnn == undefined) return 0;
var nn = zzLinks[d][dir];
if (nn == null || nn == undefined) return 0
nn = zzLinks[d][dir][n];
if (nn > 1) return nn;
var i
for (i = 1; i < zzMaxItems && zzItems[i]; i++)
if (zzLinks[d][1 - dir][i] == n) return i;
return 0
//clone stuff (currently unused)
if (nn == null || nn == undefined) {
var cl
if ((cl = zzGetCell(n).clone) > 0) nn = zzLinks[d][dir][cl];
if (nn == null || nn == undefined) return 0
else return nn
}
else return nn;
}
function zzAt(x, y, s) {
if (y <= 0 || y >= zzMaxY) return
if (x <= 0 || x >= zzMaxX) return
//var o=document.getElementById("r"+y*2+"c"+x*2)
//if(o.innerText!=" ")return
//o.innerHTML=s
var coords = "r" + y * 2 + "c" + x * 2
setText(coords, s)
zzFilled[zzFilledN++] = coords
}
function zzBetween(x1, y1, x2, y2, s) {
var x = (x1 * 2 + x2 * 2) / 2
var y = (y1 * 2 + y2 * 2) / 2
if (y <= 0 || y >= zzMaxY * 2) return
if (x <= 0 || x >= zzMaxX * 2) return
//var o=document.all["r"+y+"c"+x]
//if(o.innerText!=" ")return
//o.innerHTML=s
var coords = "r" + y + "c" + x
setText(coords, s)
zzFilled[zzFilledN++] = coords
}
function zzClear() {
var a, b, o
for (a = 0; a < zzFilledN; a++) {
o = zzFilled[a]
//o.innerText=" "
setText(o, " ");
}
zzFilledN = 0
//make sure that the table is going to receive the key presses,
//not the menus!
//zzTable.focus()
//it doesn't work!
}
function zzRenderDimension(n, d, d2, x, y) {
zzRenderDimensionAux(n, d, d2, x, y, 1)
zzRenderDimensionAux(n, d, d2, x, y, -1)
}
function zzRenderDimensionAux(n, d, d2, x, y, incr) {
var n2;
while (n > 0 && x >= 0 && y > 0 && (x <= zzMaxX && y <= zzMaxY || !horizonLimit)) {
zzAt(x, y, zzRenderCell(n))
//used to check for n==zzCurrentN && ...
if ((!onlyTurnAtCurrent || n == zzCurrentN) && maxTurns >= 1 && d2 != null && d2.length > 0) {
//chase down the orthogonal dimension
zzRenderSecondaryDimensionAux(n, d2, d, x, y, 1)
zzRenderSecondaryDimensionAux(n, d2, d, x, y, -1)
}
n2 = zzStepInDimension(n, d, incr)
if (n2 != -99) { ///used to be !=0, but I want to have the arrows after the last one
var whichn;
//var glyph=unescape("%EA")
var glyph = "&#xEA;"
if (incr > 0) whichn = n;
else whichn = n2;
if (n2 == 0) glyph = ""
zzBetween(x, y, x, y + incr, "<CENTER>" + zzAvailableDimensions(whichn, -1, 1) + "<span title='" + d + ":" + n2 + "' style='text-weight: bold; font-family: Wingdings; color:" + zzColorOf(d) + "'>" + glyph + "</span>" + zzAvailableDimensions(whichn, 1, 1) + "</CENTER>");
}
y = y + incr
n = n2
}
}
function zzRenderSecondaryDimensionAux(n, d, d3, x, y, incr) {
//var glyph=unescape("%E8")
var glyph = "&#xE8;"
n = zzStepInDimension(n, d, incr)
while (n > 0 && x >= 0 && y > 0 && (x <= zzMaxX && y <= zzMaxY || !horizonLimit)) {
zzBetween(x, y, x + incr, y, zzAvailableDimensions(n, -1, 2) + zzAvailableDimensions(n, 1, 2) + "<span style='font-family: Wingdings; font-weight: bold; color:" + zzColorOf(d) + "'>" + glyph + "</span>");
x = x + incr;
zzAt(x, y, zzRenderCell(n))
if (!onlyTurnAtCurrent && maxTurns >= 2) zzRenderTertiaryDimensionAux(n, d3, x, y, 1)
if (!onlyTurnAtCurrent && maxTurns >= 2) zzRenderTertiaryDimensionAux(n, d3, x, y, -1)
n = zzStepInDimension(n, d, incr)
}
}
function zzRenderTertiaryDimensionAux(n, d, x, y, incr) {
n = zzStepInDimension(n, d, incr)
while (n > 0 && x >= 0 && y > 0 && (x <= zzMaxX && y <= zzMaxY || !horizonLimit)) {
y = y + incr;
zzAt(x, y, zzRenderCell(n))
n = zzStepInDimension(n, d, incr)
}
}
function zzRenderCell(n) {
var zzcell, res = "";
var col = "";
zzcell = zzGetCell(n)
if (zzcell == null) return
res = ""
//if(true)res+="("+n+")"
if (zzcell.clone) {
zzcell = zzGetCell(zzcell.clone);
col = " color: orange"
}
if (zzcell.title != "") res += "<b>" + zzcell.title + "</b> "
if (zzcell.eval != "") res += "<br>" + zzEvaluate(n, zzcell.eval)
if (zzcell.pic != "") {
if (res != "") res += "<br>";
res += "<img width=100 src='" + zzcell.pic + "'>";
}
if (zzContentsOf(n) != "") {
if (res != "") res += "<br>";
if (zzcell.content.substring(0, 7) == "http://") res += "<a target='_new' href='" + zzcell.content + "'>" + zzcell.content + "</a>"
else if (zzcell.content.substring(0, 3) == "C:\\") res += "<a target='_new' href='" + zzcell.content + "'>" + zzcell.content + "</a>"
else if (zzcell.content.substring(0, 3) == "C:/") res += "<a target='_new' href='" + zzcell.content + "'>" + zzcell.content + "</a>"
else res += zzcell.content;
}
var ed = ""
if (zzEditing == n && n == zzCurrentN) ed = "contentEditable='true'"
if (n == zzCurrentN) {
if (zzcell.url != "") {
// if(zzExternalWindow!=zzcell.url)window.open(zzcell.url, "zzURL")
// zzExternalWindow=zzcell.url
res += "<a href='" + zzcell.url + "' target='_new'><iframe style='zoom:20%; border-width: 6; border-style: inset' width='100%' height='500' scrolling='no' src='" + zzcell.url + "'></iframe></a>"
}
}
var clik = "";
if (n != zzCurrentN) clik = " onClick=revealThis(" + n + ",0,0,'" + zzDimOne + "','" + zzDimTwo + "')";
var st
if (n != zzCurrentN) st = "border-width:0.5pt;"
else st = "border-width:2pt; border-color:red;"
return "<CENTER" + clik + " " + ed + " style='border:solid; " + st + col + "'>" + res + "</CENTER>"
}
function zzSummarise(n) {
var zzcell, res = "",
conN;
zzcell = zzGetCell(n)
if (zzcell == null) return ""
if (zzcell.title != null) return zzcell.title
conN = zzcell.content;
if (conN == null) return ""
res = conN
if (res.length <= 12) return res
return res.substring(0, 12) + "..."
}
function zzContentsOf(n) {
var zzcell, conN;
zzcell = zzGetCell(n)
if (zzcell == null) return ""
if (zzcell.clone) return zzContentsOf(zzcell.clone);
conN = zzcell.content;
if (conN == null) return ""
return conN
}
function zzNarrativeContentsOf(n) {
var zzcell, conN, titN, res;
zzcell = zzGetCell(n)
if (zzcell == null) return ""
conN = zzcell.content;
titN = zzcell.title;
res = ""
if (titN != "") {
res = titN
}
else {
if (conN != null) res += conN
}
return "<span id=narr" + n + " contentEditable='true' onMouseEnter=zzNarrativeMouse('enter',this," + n + ") onMouseLeave=zzNarrativeMouse('leave',this," + n + ") onClick=zzNarrativeMouse('click',this," + n + ")>" + res + "</span>"
}
function zzGetCell(n) {
return zzItems[n]
}
function zzSetDimensions() {
zzDimOne = zzDims[document.getElementById("dimSel1").selectedIndex]
zzDimTwo = zzDims[document.getElementById("dimSel2").selectedIndex]
}
function zzInitialise() {
var nOpt
for (i = 0; i <= zzTopDim; i++) {
nOpt = document.createElement("OPTION")
nOpt.text = zzDimDescs[i]
nOpt.value = i
if (ieBrowser) dimSel1.add(nOpt);
else document.getElementById("dimSel1").appendChild(nOpt)
nOpt = document.createElement("OPTION")
nOpt.text = zzDimDescs[i]
nOpt.value = i
if (ieBrowser) dimSel2.add(nOpt);
else document.getElementById("dimSel2").appendChild(nOpt)
}
document.getElementById("dimSel1").selectedIndex = 0
zzDimOne = zzDims[0]
document.getElementById("dimSel2").selectedIndex = 1
zzDimTwo = zzDims[1]
//title
setText("zzTitle", zzTitleStr)
setText("zzVersion", zzVersion)
//explanation
if (zzExplainStr) setText("zzExplain", zzExplainStr)
else setText("zzExplain", "Use the arrow keys and menus (right) to zigzag through the demo, alternatively use the x,y, s, f, e, c keys like the Perl implementation.")
}
function zzSaveEdit(n) {
var oldText = zzContentsOf(n)
//replace next with the correct narrative element
var narrCell = document.getElementById["narr" + n]
var newText = null;
if (narrCell) newText = narrCell.innerText;
else newText = document.getElementById("r22c22").innerText;
//can't tell whether the editing took place in the narrative area or the cell area
//if(oldText==newText)newText=document.getElementById("r11c11").innerText;
if (oldText == newText) {
window.status = "No changes made to cell " + n + " '" + oldText + "'";
alert("No changes made to cell " + n);
return;
}
else {
window.status = "Cell " + n + " changed from '" + oldText + "' to '" + newText + "'";
}
var cell = zzGetCell(n)
if (cell.clone) zzItems[cell.clone].content = newText;
else cell.content = newText;
if (zzLinks["version"]) {
//create a new cell with the old contents
var nc = zzMakeNewCellWithContents(oldText);
var pv = zzStepInDimension(n, "version", -1)
zzLinks["version"][zzNegWard][n] = nc
zzLinks["version"][zzPosWard][nc] = n
if (pv > 1) zzLinks["version"][zzNegWard][nc] = pv
}
}
function zzMakeNewDim() {
var newDescr = prompt("Description of new dimension: ", "")
var newName = prompt("Id of dimension (one word):", "")
var newColor = prompt("Color to use for dimension: ", "black")
zzNewDim(newName, newDescr, newColor)
}
document.onkeypress = function keyHandler(e) {
var k;
if (e) k = e.which;
else k = window.event.keyCode
var ae = document.activeElement;
if (ae == null || ae == document.getElementById("zzTitle")) return;
if (zzEditing > 0) {
if (ieBrowser && k == 27) zzStopEditing();
return;
}
else if (k == 81 /* Q */ ) {
if (!ieBrowser) {
var newText = prompt("Cell contents:", "")
var cell = zzGetCell(zzCurrentN)
if (cell.clone) zzItems[cell.clone].content = newText;
else cell.content = newText;
reveal()
}
else zzStartEditing(zzCurrentN);
return;
}
if (k == 33 /* ! */ ) {
exportToXML();
return;
}
if (k == 90 /* Z */ ) {
dumpXML();
return;
}
if (k == 87 /* W */ ) {
writeJS();
return;
}
if (k == 68 /* D */ ) {
zzMakeNewDim();
return;
}
if (k == 120 || k == 88 /* X/x */ ) zzPressX()
if (k == 121 || k == 89 /* Y/y */ ) zzPressY()
if (k == 69 || k == 73 || k == 101 || k == 105 /* EeIi */ ) zzGoUp()
if (k == 67 || k == 99 || k == 44 || k == 60 /* Cc lt, */ ) zzGoDown()
if (k == 115 || k == 83 || k == 106 || k == 74 /* SsKk */ ) zzGoLeft()
if (k == 102 || k == 70 || k == 108 || k == 76 /* Ff:; */ ) zzGoRight()
if (k == 65 || k == 97 /* E/e */ ) zzEval()
if (k == 109 || k == 77 /* M/m */ ) {
zzMarked = zzCurrentN;
window.status = "Marked " + zzMarked;
}
if (k == 84 /* T */ ) { // transpose
var di1 = document.getElementById("dimSel1").selectedIndex
var di2 = document.getElementById("dimSel2").selectedIndex
document.getElementById("dimSel1").selectedIndex = di2
document.getElementById("dimSel2").selectedIndex = di1
reveal(false);
}
if (k == 116 /* t */ ) { // topple (?) back to standard dimensions
document.getElementById("dimSel1").selectedIndex = 0
document.getElementById("dimSel2").selectedIndex = 1
reveal(false);
}
if (k == 71 /* g */ ) {
zzGoto();
};
if (k == 94 /* ^ */ ) {
zzExtremeOfRank(zzDimOne, -1);
};
if (k == 118 /* v */ ) {
zzExtremeOfRank(zzDimOne, 1);
};
if (k == 91 /* [ */ ) {
zzExtremeOfRank(zzDimTwo, -1);
}
if (k == 93 /* ] */ ) {
zzExtremeOfRank(zzDimTwo, 1);
}
if (k == 45 /* - */ ) zzLinking = true;
else zzLinking = false;
if (k == 79 || k == 111 /* O/o */ ) zzCloneCell(zzCurrentN, zzMarked);
if (k == 117 /* u */ ) zzUnLinking = true;
else zzUnLinking = false;
if (k == 110 || k == 78 /* N/n */ ) zzAdding = true;
else zzAdding = false;
if (k == 35 /* # */ ) zzDeleting = true;
else zzDeleting = false;
if (k == 126 /* ~ */ ) zzChugging = true;
else zzChugging = false;
if (k == 72 /* H */ ) {
revealThis(1, 0, 0, zzDims[0], zzDims[1]);
}
if (k == 63 /* ? */ ) {
zzSaveHTML(zzTitleStr, zzScavenge())
}
if (k == 64 /* @ */ ) {
var d = "email"
//d=prompt("Scavenge for which dimension?",zzDimOne);
window.open("mailto:" + zzScavenge2(d))
}
}
function zzAvailableDimensions0() {
var availDims = ""
var c = 0
for (c = 0; zzDims[c] != null; c++) {
var d = zzDims[c]
if (d != zzDimOne && d != zzDimTwo) {
if (zzStepInDimension(zzCurrentN, d, 1) || zzStepInDimension(zzCurrentN, d, -1)) availDims += d + " "
}
}
return availDims
}
function zzAvailableDimensions1(n) {
var availDims = ""
var c = 0
for (c = 0; zzDims[c] != null; c++) {
var d = zzDims[c]
if (d != "narrative" && d != "version") {
if (zzStepInDimension(n, d, 1) || zzStepInDimension(n, d, -1)) availDims += d + " "
}
}
return availDims
}
function zzAvailableDimensions(n, delta, depth) {
var availDims = "",
nextDim = "",
summary = ""
var glyph
//if(delta<0)glyph=unescape("%ED")
//else glyph=unescape("%EE")
if (delta < 0) glyph = "&#xED;"
else glyph = "&#xEE;"
var c = 0,
n2 = 0,
dq = '"'
for (c = 0; zzDims[c] != null; c++) {
var d = zzDims[c]
if ((depth == 99) || (d != zzDimOne && d != zzDimTwo)) {
if ((n2 = zzStepInDimension(n, d, delta)) > 0) {
var d1, d2
if (depth == 1) {
d1 = zzDimOne;
d2 = d;
}
else {
d1 = d;
d2 = zzDimTwo;
}
summary = "(" + n + ") " + zzDimDescs[c] + "->" + zzSummarise(n2)
nextDim = "<a href='javascript:revealThis(" + n + ",2,3," + dq + d1 + dq + "," + dq + d2 + dq + ")' onMouseEnter='status=" + dq + summary + dq + "' title='" + summary + "' style='text-decoration: none; color: " + zzColorOf(d) + "; font-family: Wingdings; text-weight: bold;'><small><sup>" + glyph + "</sup></small></a>"
if (delta < 0) availDims = nextDim + availDims
else availDims += nextDim
nextDim = ""
}
}
}
return availDims
}
function zzTour() {
if (zzTourN < 1) return
var ts = zzTourSteps[zzTourN];
if (ts == null) {
zzTourN = 0
return
}
//ok, so are the conditions for this tour step fulfilled?
if (ts.n != zzCurrentN) return;
if (ts.down != zzDimOne) return;
if (ts.across != zzDimTwo) return;
var t = ""
t += ts.comment
t += "<br><b>" + ts.doit + "</b>";
setText("zzExplain", t)
zzTourN++
}
function doNowt() {}
function zzColorOf(d) {
var dc = 0
while (zzDims[dc] != null && zzDims[dc] != d)
dc++
if (zzDims[dc] == null) return "black"
else return zzDimCols[dc];
}
function plus(a, b) {
return a + b
}
function minus(a, b) {
return a - b
}
function times(a, b) {
return a * b
}
function divide(a, b) {
return a / b
}
function accumulate(initial, fn, n, direction, step) {
var res = initial;
n = zzStepInDimension(n, direction, step)
while (n > 0) {
res = fn(res, (1.0 * zzContentsOf(n)))
n = zzStepInDimension(n, direction, step)
}
return res
}
function zzNarrate() {
if (document.getElementById("narrative") == undefined) return
var nlast = zzCurrentN
var n = zzStepInDimension(zzCurrentN, "narrative", -1)
if (n <= 0) {
n = zzStepInDimension(zzCurrentN, "narrative", 1)
if (n <= 0) {
setText("narrative", "");
return
}
//back up to the beginning of the narrative
n = zzCurrentN
}
else {
//back up to the beginning of the narrative
while (n > 0) {
nlast = n
n = zzStepInDimension(n, "narrative", -1)
}
}
//build up the narrative
var narr = ""
var punct = "!.,;:?"
n = nlast;
while (n > 0) {
var narScrap = zzNarrativeContentsOf(n)
var lastChar = narScrap.charAt(narScrap.length - 1)
var pos = narScrap.indexOf('>')
if (punct.indexOf(narScrap.charAt(pos + 1)) >= 0) narr = narr.substring(0, narr.length - 1)
narr += narScrap + " "
n = zzStepInDimension(n, "narrative", 1)
}
setText("narrative", narr + "<hr>")
}
function zzNarrativeMouse(op, obj, n) {
if (op == "click") {
//revealThis(n,0,0,zzDimOne,zzDimTwo);
zzStartEditing(n);
}
if (zzAvailableDimensions1(n) == "") return
if (op == "enter") obj.style.backgroundColor = 'gray'
else if (op == "leave") obj.style.backgroundColor = 'white'
}
function getText(node, patt) {
var nd = node.selectSingleNode(patt);
if (nd == null) return ""
else return nd.text;
}
function zzMakeNewCell(basis) {
var c
for (c = 1; c < zzMaxItems; c++)
if (zzItems[c] == null) break;
if (c == zzMaxItems) return -1;
var o = new Object();
o.pic = ""
o.title = ""
o.eval = ""
o.url = ""
o.content = ""
if (basis > 0) {
o.content = zzItems[basis].content;
}
zzItems[c] = o;
return c;
}
function zzMakeNewCellWithContents(str) {
var c = zzMakeNewCell(0);
zzItems[c].content = str;
return c;
}
function zzStartEditing(n) {
if (n == zzEditing) return;
if (n > 0 && zzEditing > 0) zzSaveEdit(zzEditing);
zzEditing = n;
reveal();
if (false) {
// this can't work in Netscape
// and has no effect in Explorer!
//whatever I do I can't get the keypresses
//diverted
var r = document.body.createTextRange();
r.moveToElementText(document.getElementById("r22c22"));
r.select();
document.getElementById("r22c22").focus();
}
window.status = "Editing cell " + n
}
function zzStopEditing() {
if (zzEditing < 1) return;
zzSaveEdit(zzEditing);
zzEditing = 0;
reveal();
}
function zzUnLinkCells(a, b, d) {
zzLinks[d][zzNegWard][a] = null;
zzLinks[d][zzPosWard][b] = null;
}
function zzBlatFromDimension(d, a) {
var i
for (i = 1; i < zzMaxItems && zzItems[i]; i++) {
if (zzLinks[d][zzNegWard][i] == a) {
zzLinks[d][zzNegWard][i] = null;
}
}
for (i = 1; i < zzMaxItems && zzItems[i]; i++) {
if (zzLinks[d][zzPosWard][i] == a) {
zzLinks[d][zzPosWard][i] = null;
}
}
}
function zzLinkCells(a, b, d) {
//a and b can't be linked to anything else in d
zzBlatFromDimension(d, a);
zzBlatFromDimension(d, b);
zzLinks[d][zzPosWard][a] = b;
zzLinks[d][zzNegWard][b] = a;
}
function zzCloneCell(a, b) {
//a and b can't be linked to anything else in d
var zzcell, zzcell2
zzcell = zzGetCell(a)
if (zzcell == null) return
zzcell2 = zzGetCell(b)
if (zzcell2 == null) return
zzcell.clone = b;
reveal()
}
function zzNewDim(name, desc, col) {
if (zzTopDim == zzMaxDims) {
alert("Too many dimensions to create dimension '" + name + "'");
return;
}
zzTopDim++;
zzLinks[name] = new Array(2)
zzLinks[name][zzNegWard] = new Array(zzMaxItems)
zzLinks[name][zzPosWard] = new Array(zzMaxItems)
if (col == "") zzDimCols[zzTopDim] = "black"
else zzDimCols[zzTopDim] = col
var descr = desc
if (descr == "") descr = name
zzDims[zzTopDim] = name
zzDimDescs[zzTopDim] = descr
var nOpt = document.createElement("OPTION")
nOpt.text = descr
nOpt.value = zzTopDim
if (ieBrowser) dimSel1.add(nOpt);
else document.getElementById("dimSel1").appendChild(nOpt)
var nOpt2 = document.createElement("OPTION")
nOpt2.text = descr
nOpt2.value = zzTopDim
if (ieBrowser) dimSel2.add(nOpt2);
else document.getElementById("dimSel2").appendChild(nOpt2)
}
function setText(l, v) {
var e = document.getElementById(l)
if (!e) return;
if (ieBrowser) {
e.innerHTML = v;
}
else {
e.innerHTML = v
//sih(l,v)
//if(e.firstChild)e=e.firstChild
//e.nodeValue=v
}
}
function getText(l) {
var e = document.getElementById(l)
if (!e) return;
if (ieBrowser) {
return e.innerText;
}
else {
return e.innerText;
//sih(l,v)
//if(e.firstChild)e=e.firstChild
//e.nodeValue=v
}
}
function sih(id, str) {
var o = document.getElementById(id)
var r = o.ownerDocument.createRange();
r.selectNodeContents(o);
r.deleteContents();
var df = r.createContextualFragment(str);
o.appendChild(df);
}
function exportToXML() {
if (ieBrowser) newSaveData(zzTitleStr, convertToXML(), "xml")
else oldSaveData(zzTitleStr, convertToXML())
}
function writeJS() {
if (ieBrowser) newSaveData(zzTitleStr, convertToJS(), "html")
else oldSaveData(zzTitleStr, convertToJS())
}
function dumpXML() {
oldSaveData(zzTitleStr, convertToXML())
}
function newSaveData(t, d, suffix) {
nSaves++
var s = document.location.href;
var i = s.lastIndexOf('/');
if (i < 0) {
alert("Can't find document name");
return;
}
var j = s.lastIndexOf('.');
if (nSaves == 1) alert("Saving to your disk overrides browser security.\nPlease click 'Yes' on the next alert box!");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var a = fso.CreateTextFile(s.substring(i + 1, j) + "." + suffix, true);
a.Write(d);
a.Close();
if (nSaves > 1) alert("Saved file on your Desktop");
}
function oldSaveData(t, d) {
w = window.open("", "_new");
w.document.write("<H1>XML Zigzag Data: " + t + "</H1>\n")
w.document.write("<FORM method='POST' action='http://ernie.ecs.soton.ac.uk/~lac/zzWrite.cgi' >")
w.document.write("<textarea name='xmldata' rows='20' cols='80'>" + canon(d) + "</textarea>")
w.document.write("<p>The above is the raw XML that constitutes the ZigZag data. Either cut and paste it into a text editor and save it, or click on 'Save on Web'.\n");
w.document.write("<input type=submit value='Save on Web'/>\n");
w.document.write("<hr>\n<i>Zigzag for XML was written by Leslie Carr, IAM Research, University of Southampton</i>\n");
w.document.write("For more information, see the <a href='http://www.ecs.soton.ac.uk/~lac/zigzag/'>Zigzag for XML page</a>.");
w.document.close();
}
function convertToXML() {
var n
s = "<!DOCTYPE zigzag SYSTEM 'orthoplex.dtd'>\n"
s += "<?xml-stylesheet type='text/xsl' href='orthoplex.xsl'?>"
s += "<zigzag><title>" + getText("zzTitle") + "</title>\n"
//s+="<explain>"+getText("zzExplain")+"</explain>\n"
if (zzTourSteps[1]) {
s += "<tour>\n"
n = 1
while (zzTourSteps[n]) {
var ts = zzTourSteps[n]
s += "<step n='" + ts.n + "' across='" + ts.across + "' down='" + ts.down + "'>\n"
s += "<comment>" + ts.comment + "</comment>\n"
s += "<doit>" + ts.doit + "</doit>\n"
s += "</step>\n\n"
n++
}
s += "</tour>\n\n"
}
n = 0
s += "<dimensions>\n"
while (zzDims[n]) {
s += "<dimension name='" + zzDims[n] + "' description='" + zzDimDescs[n] + "'"
if (zzDimCols[n]) s += " color='" + zzDimCols[n] + "'"
s += "/>\n"
n++
}
s += "</dimensions>\n\n"
n = 1
s += "<cells>\n"
while (zzItems[n]) {
var it = zzItems[n]
s += "<cell n='" + n + "'>\n"
if (it.title) s += "<title>" + it.title + "</title>\n"
if (it.clone) s += "<content clone='" + it.clone + "'/>\n"
else s += "<content>" + it.content + "</content>\n"
if (it.pic) s += "<pic src='" + it.pic + "'/>\n"
if (it.url) s += "<url>" + it.url + "</url>\n"
if (it.eval) s += "<eval>" + it.eval + "</eval>\n"
var d = 0
while (zzDims[d]) {
var dim = zzDims[d]
var pos = "",
neg = ""
if (zzLinks[dim][zzPosWard][n] > 0) pos = " posward='" + zzLinks[dim][zzPosWard][n] + "'"
if (zzLinks[dim][zzNegWard][n] > 0) neg = " negward='" + zzLinks[dim][zzNegWard][n] + "'"
if (pos != "" || neg != "") s += "<link direction='" + dim + "'" + pos + neg + "/>"
d++
}
s += "</cell>\n"
n++
}
s += "</cells>\n"
s += "</zigzag>"
return s
}
function convertToJS() {
var n = 1
var d = 0
var s = ""
s = "<HTML>\n<HEAD>\n"
s += "<TITLE>" + getText("zzTitle") + "</TITLE>\n"
s += '<SCRIPT SRC="orthoplex.js" language="JavaScript"></SCRIPT><SCRIPT language="JavaScript">\n'
var i = 0
for (d = 0; d <= zzTopDim; d++) {
var dn = zzDims[d]
s += "zzDims[" + d + "]='" + dn + "'\n"
s += "zzDimCols[" + d + "]='" + zzDimCols[d] + "'\n"
s += "zzDimDescs[" + d + "]='" + zzDimDescs[d] + "'\n"
s += "zzLinks['" + dn + "']=new Array(2)\n"
s += "zzLinks['" + dn + "'][zzNegWard]=new Array(zzMaxItems)\n"
s += "zzLinks['" + dn + "'][zzPosWard]=new Array(zzMaxItems)\n"
}
s += "var n=0\n";
while (zzItems[n]) {
var it = zzItems[n]
s += "o=new ZZCell();\n"
if (it.title) s += "o.title='" + it.title + "'\n"
s += "o.content='" + it.content + "'\n"
if (it.pic) s += "o.pic='" + it.pic + "'\n"
if (it.url) s += "o.url='" + it.url + "'\n"
if (it.eval) s += "o.eval='" + it.eval + "'\n"
if (it.clone) s += "o.clone=" + it.clone + "\n"
s += "zzItems[" + n + "]=o;\n"
d = 0
while (zzDims[d]) {
var dim = zzDims[d]
if (zzLinks[dim][zzPosWard][n] > 0) s += "zzLinks['" + dim + "'][zzPosWard][" + n + "]=" + zzLinks[dim][zzPosWard][n] + "\n"
if (zzLinks[dim][zzNegWard][n] > 0) s += "zzLinks['" + dim + "'][zzNegWard][" + n + "]=" + zzLinks[dim][zzNegWard][n] + "\n"
d++
}
s += "n++\n"
n++
}
s += "zzTopDim=" + (d - 1) + "\n"
s += "zzTitleStr='" + getText("zzTitle") + "'\n"
s += "zzExplainStr=''\n"
s += '</SCRIPT>\n</HEAD>\n<BODY onLoad="startUp()">\n<table valign="top" border="0">\n<tr>\n<td rowspan="3">\n<H1>\n<span contentEditable="true" id="zzTitle">ZigZag Demo</span>\n</H1>\n<span id="zzExplain">Xse the arrow keys and menus (right) to zigzag through the demo, alternatively use the x,y, s, f, e, c keys like the Perl implementation.</span></td><td></td><td align="center"><input type="button" onclick="zzGoUp()" value="^"></td><td></td><td rowspan="3">\nDown: <select id="dimSel1" onChange="reveal(false)"></select>\n<br>\nAcross: <select id="dimSel2" onChange="reveal(false)"></select>\n<br>\nYou Can Turn in These Directions: <i><span id="zzOtherDirections"></span></i></td>\n</tr>\n<tr>\n<td><input type="button" onclick="zzGoLeft()" value="<"></td><td></td><td><input type="button" onclick="zzGoRight()" value=">"></td>\n</tr>\n<tr>\n<td></td><td align="center"><input type="button" onclick="zzGoDown()" value="v"></td><td></td>\n</tr>\n</table>\n<hr>\n<span id="celltext"></span>\n'
var t = '<table border="0">\n'
for (i = 1; i <= 40; i++) {
t += "<tr>\n"
for (j = 1; j <= 40; j++)
t += '<td><span id="r' + i + 'c' + j + '"></span></td>'
t += "\n</tr>\n"
}
t += '</table>\n'
s += t
s += '<hr>\n<i>Zigzag for XML was written by Leslie Carr, IAM Research, University of Southampton</i>\n<br>\nFor more information, see the <a href="http://www.ecs.soton.ac.uk/~lac/zigzag/">Zigzag for XML page</a>.<br>\n</BODY>\n</HTML>\n'
return s
}
function canon(s) {
var t = ""
var i
for (i = 0; i < s.length; i++) {
var ch = s.charAt(i)
if (ch == "<") t += "&lt;";
else if (ch == ">") t += "&gt;";
else if (ch == "&") t += "&amp;";
else t += ch
}
return t
}
function checkURLfrag() {
var s = document.location.href;
var i = s.indexOf('#');
if (i > 0) {
var frag = s.substring(i + 1, 999)
zzCurrentN = frag * 1
}
}
function zzUnLinkCell(n, d) {
var pre = zzLinks[d][zzNegWard][n]
var post = zzLinks[d][zzPosWard][n]
//alert("PRE="+zzGetCell(pre).content)
//alert("POST="+zzGetCell(post).content)
zzLinks[d][zzPosWard][n] = null;
zzLinks[d][zzNegWard][n] = null;
zzLinks[d][zzPosWard][pre] = post;
zzLinks[d][zzNegWard][post] = pre;
}
function zzChugCells(n, n2, d) {
var pre = zzLinks[d][zzNegWard][n]
var post = zzLinks[d][zzPosWard][n2]
zzLinks[d][zzPosWard][n] = post;
zzLinks[d][zzNegWard][n] = n2;
zzLinks[d][zzPosWard][n2] = n;
zzLinks[d][zzNegWard][n2] = pre;
zzLinks[d][zzPosWard][pre] = n2;
zzLinks[d][zzNegWard][post] = n;
}
function zzGoto() {
var c = prompt("Go to which cell?", zzCurrentN)
if (c > 1) {
zzCurrentN = c
reveal();
}
}
function zzScavenge() {
return hhh(zzDimOne, zzDimTwo, zzCurrentN, func, 1);
}
function hhh(d1, d2, n, fn, level) {
var res = "",
nn
while (n > 0) {
res += fn(zzScavengeCell(n), level)
if ((nn = zzStepInDimension(n, d1, 1)) > 0) res += hhh(d2, d1, nn, fn, level + 1)
n = zzStepInDimension(n, d2, 1)
}
return res
}
function zzScavengeCell(n) {
if (n > 0) return zzGetCell(n).content
else return ""
}
function zzIdentityFn(s) {
return s;
}
var funcll = 0;
function func(s, level) {
var res
if (level == 1) {
if (funcll == 0) res = "<H2>" + s + "</H2>"
else {
var ll = level
res = ""
while (ll < funcll) {
res += "</UL>"
ll++
}
res += "<H2>" + s + "</H2>"
}
}
else {
if (level > funcll) res = "<UL><LI>" + s
else if (level < funcll) {
var ll = level
res = ""
while (ll < funcll) {
res += "</UL>"
ll++
}
res += "<LI>" + s
}
else res = "<LI>" + s
}
funcll = level
return res + "\n"
}
function ggg(d, d1, d2, n) {
var res = "",
nn
while (n > 0) {
res += zzScavenge2Cell(n, d)
if ((nn = zzStepInDimension(n, d1, 1)) > 0) res += ggg(d, d2, d1, nn)
n = zzStepInDimension(n, d2, 1)
}
return res
}
function zzScavenge2(d) {
return ggg(d, zzDimOne, zzDimTwo, zzCurrentN);
}
function zzScavenge2Cell(n, d) {
var n2;
var res = ""
n2 = zzStepInDimension(n, d, 1);
if (n2 > 0) return zzGetCell(n2).content + "; "
else return ""
}
function zzSaveHTML(tit, doc) {
nSaves++
if (nSaves == 1) alert("Saving to your disk overrides browser security.\nPlease click 'Yes' on the next alert box!");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var a = fso.CreateTextFile("zigzagOut.html");
a.Write("<TITLE>" + tit + "</TITLE>\n<H1><hr>Zigzag Slice: " + tit + "<hr></H1>");
a.Write(doc);
a.Close();
if (nSaves > 1) alert("Saved zigzagOut.html in your Desktop");
}
function zzFind() {}
function zzExtremeOfRank(d, delta) {
var n, nextn
for (nextn = zzCurrentN; nextn > 0; nextn = zzStepInDimension(nextn, d, delta))
n = nextn;
zzCurrentN = n;
reveal()
}
// Define ZZCell class constructor
function ZZCell() {
this.content = "";
this.pic = "";
this.url = "";
this.title = "";
this.eval = "";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment