freecog.net

zenparse.js

Also see Raw version, Minified version.

   1 /* First, the JSON parser */
   2 
   3 /*
   4 Copyright (c) 2005 JSON.org
   5 Permission is hereby granted, free of charge, to any person obtaining a copy
   6 of this software and associated documentation files (the "Software"), to deal
   7 in the Software without restriction, including without limitation the rights
   8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   9 copies of the Software, and to permit persons to whom the Software is
  10 furnished to do so, subject to the following conditions:
  11 The Software shall be used for Good, not Evil.
  12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18 SOFTWARE.
  19 */
  20 Array.prototype.______array = '______array';
  21 var JSON = {
  22 org: 'http://www.JSON.org',
  23 copyright: '(c)2005 JSON.org',
  24 license: 'http://www.crockford.com/JSON/license.html',
  25 stringify: function (arg) {
  26 var c, i, l, s = '', v;
  27 switch (typeof arg) {
  28 case 'object':
  29 if (arg) {
  30 if (arg.______array == '______array') {
  31 for (i = 0; i < arg.length; ++i) {
  32 v = this.stringify(arg[i]);
  33 if (s) {
  34 s += ',';
  35 }
  36 s += v;
  37 }
  38 return '[' + s + ']';
  39 } else if (typeof arg.toString != 'undefined') {
  40 for (i in arg) {
  41 v = arg[i];
  42 if (typeof v != 'undefined' && typeof v != 'function') {
  43 v = this.stringify(v);
  44 if (s) {
  45 s += ',';
  46 }
  47 s += this.stringify(i) + ':' + v;
  48 }
  49 }
  50 return '{' + s + '}';
  51 }
  52 }
  53 return 'null';
  54 case 'number':
  55 return isFinite(arg) ? String(arg) : 'null';
  56 case 'string':
  57 l = arg.length;
  58 s = '"';
  59 for (i = 0; i < l; i += 1) {
  60 c = arg.charAt(i);
  61 if (c >= ' ') {
  62 if (c == '\\' || c == '"') {
  63 s += '\\';
  64 }
  65 s += c;
  66 } else {
  67 switch (c) {
  68 case '\b':
  69 s += '\\b';
  70 break;
  71 case '\f':
  72 s += '\\f';
  73 break;
  74 case '\n':
  75 s += '\\n';
  76 break;
  77 case '\r':
  78 s += '\\r';
  79 break;
  80 case '\t':
  81 s += '\\t';
  82 break;
  83 default:
  84 c = c.charCodeAt();
  85 s += '\\u00' + Math.floor(c / 16).toString(16) +
  86 (c % 16).toString(16);
  87 }
  88 }
  89 }
  90 return s + '"';
  91 case 'boolean':
  92 return String(arg);
  93 default:
  94 return 'null';
  95 }
  96 },
  97 parse: function (text) {
  98 var at = 0;
  99 var ch = ' ';
 100 function error(m) {
 101 throw {
 102 name: 'JSONError',
 103 message: m,
 104 at: at - 1,
 105 text: text
 106 };
 107 }
 108 function next() {
 109 ch = text.charAt(at);
 110 at += 1;
 111 return ch;
 112 }
 113 function white() {
 114 while (ch) {
 115 if (ch <= ' ') {
 116 next();
 117 } else if (ch == '/') {
 118 switch (next()) {
 119 case '/':
 120 while (next() && ch != '\n' && ch != '\r') {}
 121 break;
 122 case '*':
 123 next();
 124 for (;;) {
 125 if (ch) {
 126 if (ch == '*') {
 127 if (next() == '/') {
 128 next();
 129 break;
 130 }
 131 } else {
 132 next();
 133 }
 134 } else {
 135 error("Unterminated comment");
 136 }
 137 }
 138 break;
 139 default:
 140 error("Syntax error");
 141 }
 142 } else {
 143 break;
 144 }
 145 }
 146 }
 147 function string() {
 148 var i, s = '', t, u;
 149 if (ch == '"') {
 150 outer:          while (next()) {
 151 if (ch == '"') {
 152 next();
 153 return s;
 154 } else if (ch == '\\') {
 155 switch (next()) {
 156 case 'b':
 157 s += '\b';
 158 break;
 159 case 'f':
 160 s += '\f';
 161 break;
 162 case 'n':
 163 s += '\n';
 164 break;
 165 case 'r':
 166 s += '\r';
 167 break;
 168 case 't':
 169 s += '\t';
 170 break;
 171 case 'u':
 172 u = 0;
 173 for (i = 0; i < 4; i += 1) {
 174 t = parseInt(next(), 16);
 175 if (!isFinite(t)) {
 176 break outer;
 177 }
 178 u = u * 16 + t;
 179 }
 180 s += String.fromCharCode(u);
 181 break;
 182 default:
 183 s += ch;
 184 }
 185 } else {
 186 s += ch;
 187 }
 188 }
 189 }
 190 error("Bad string");
 191 }
 192 function array() {
 193 var a = [];
 194 if (ch == '[') {
 195 next();
 196 white();
 197 if (ch == ']') {
 198 next();
 199 return a;
 200 }
 201 while (ch) {
 202 a.push(value());
 203 white();
 204 if (ch == ']') {
 205 next();
 206 return a;
 207 } else if (ch != ',') {
 208 break;
 209 }
 210 next();
 211 white();
 212 }
 213 }
 214 error("Bad array");
 215 }
 216 function object() {
 217 var k, o = {};
 218 if (ch == '{') {
 219 next();
 220 white();
 221 if (ch == '}') {
 222 next();
 223 return o;
 224 }
 225 while (ch) {
 226 k = string();
 227 white();
 228 if (ch != ':') {
 229 break;
 230 }
 231 next();
 232 o[k] = value();
 233 white();
 234 if (ch == '}') {
 235 next();
 236 return o;
 237 } else if (ch != ',') {
 238 break;
 239 }
 240 next();
 241 white();
 242 }
 243 }
 244 error("Bad object");
 245 }
 246 function number() {
 247 var n = '', v;
 248 if (ch == '-') {
 249 n = '-';
 250 next();
 251 }
 252 while (ch >= '0' && ch <= '9') {
 253 n += ch;
 254 next();
 255 }
 256 if (ch == '.') {
 257 n += '.';
 258 while (next() && ch >= '0' && ch <= '9') {
 259 n += ch;
 260 }
 261 }
 262 if (ch == 'e' || ch == 'E') {
 263 n += 'e';
 264 next();
 265 if (ch == '-' || ch == '+') {
 266 n += ch;
 267 next();
 268 }
 269 while (ch >= '0' && ch <= '9') {
 270 n += ch;
 271 next();
 272 }
 273 }
 274 v = +n;
 275 if (!isFinite(v)) {
 276 ////error("Bad number");
 277 } else {
 278 return v;
 279 }
 280 }
 281 function word() {
 282 switch (ch) {
 283 case 't':
 284 if (next() == 'r' && next() == 'u' && next() == 'e') {
 285 next();
 286 return true;
 287 }
 288 break;
 289 case 'f':
 290 if (next() == 'a' && next() == 'l' && next() == 's' &&
 291 next() == 'e') {
 292 next();
 293 return false;
 294 }
 295 break;
 296 case 'n':
 297 if (next() == 'u' && next() == 'l' && next() == 'l') {
 298 next();
 299 return null;
 300 }
 301 break;
 302 }
 303 error("Syntax error");
 304 }
 305 function value() {
 306 white();
 307 switch (ch) {
 308 case '{':
 309 return object();
 310 case '[':
 311 return array();
 312 case '"':
 313 return string();
 314 case '-':
 315 return number();
 316 default:
 317 return ch >= '0' && ch <= '9' ? number() : word();
 318 }
 319 }
 320 return value();
 321 }
 322 };
 323 
 324 
 325 
 326 
 327 /*** end JSON ***/
 328 
 329 
 330 
 331 
 332 
 333 
 334 
 335 /* Copyright 2005 Tom W.M. */
 336 
 337 if (!document.body) { document.body = document.getElementsByTagName("body")[0]; }
 338 
 339 /** queue data **/
 340 var queue = [
 341 // student pages are handled specially
 342 new QueueItem("student","http://www.mezzoblue.com/zengarden/alldesigns/student/"),
 343 new QueueItem("student","http://www.mezzoblue.com/zengarden/alldesigns/student/002/")
 344 ]; // array of pages to visit
 345 var completed = []; // queue entries are added to this array after they are successfully (no exceptions thrown) completed
 346 var failed = []; // and vice-versa
 347 
 348 
 349 var output = []; // array of ZenEntry objects
 350 
 351 var categories = {
 352 "conceptual" : 12,
 353 "fun" : null,
 354 "minimal" : 4,
 355 "official" : 9,
 356 "specialeffects" : null,
 357 // "student" : 2, //student designs require special processing
 358 "themes" : 2,
 359 "zengarden" : 2,
 360 "allothers" : 3,
 361 };
 362 
 363 function QueueItem(cat,url) {
 364  var self = this;
 365  this.toString = function() {
 366   return self.url;
 367  };
 368  this.url = url;
 369  this.category = cat;
 370 };
 371 
 372 function createQueue() { //add some pages to the queue:
 373  var baseString = "http://www.mezzoblue.com/zengarden/alldesigns/";
 374  function lpad(num) {
 375   num = num.toString();
 376   return (num.length == 2) ? "0" + num : (num.length == 1) ? "00" + num : num;
 377  };
 378  for (cat in categories) {
 379   queue[queue.length] = new QueueItem(cat,baseString + cat + "/");
 380   if (categories[cat] != null) {
 381    for (var i = 1; i < (categories[cat]+1); i++) {
 382     queue[queue.length] = new QueueItem(cat,baseString + cat + "/" + lpad(i) + "/");
 383    }
 384   }
 385  }
 386 };
 387 
 388 createQueue(); //go ahead
 389 
 390 /*
 391 var nations = { // this isn't complete--or possibly even necessary?
 392  "United States" : "American",
 393  "Canada" : "Canadian",
 394  "Latvia" : "Latvian",
 395  "Argentina" : "Argentinan",
 396  "Italy" : "Italian",
 397  "Poland" : "Polish",
 398  "Japan" : "Japanese",
 399  "France" : "French",
 400  "United Kingdom" : "British",
 401  "Malaysia" : "Malaysian",
 402  "Australia" : "Australian",
 403  "Germany" : "",
 404  "Israel" : "",
 405  "Croatia" : "",
 406  "Singapore" : "",
 407  "Belgium" : "",
 408  "Czech Republic" : "",
 409  "" : "",
 410  "" : "",
 411  "" : "",
 412  }; */
 413 
 414 function ZenEntry(category,number,name,url,nation,cssfile,title) {
 415  this.number = number;
 416  this.name = name;
 417  this.url = url;
 418  /*this.nationality = nations[nation] || null;
 419  if (this.nationality == null) {
 420   throw "Nationality of " + nation + " is not defined.";
 421  }*/
 422  this.nation = nation;
 423  this.cssfile = cssfile;
 424  this.title = title;
 425 };
 426 
 427 function locationContains(doc,needle) {
 428  return (doc.location.href.toString().indexOf(needle) > -1);
 429 };
 430 
 431 /**** PROCESS THE PAGE ****/
 432 
 433 function processPage(queueItem,doc) {
 434  var content = doc.getElementById("mainContent");
 435  if (!content) throw "#mainContent not found";
 436  for (var i = 0; i<content.childNodes.length; i++) {
 437   if (content.childNodes[i].className && content.childNodes[i].className.match(/\s*contentarea\s*/i)) {
 438    content = content.childNodes[i];
 439    break;
 440   }
 441  }
 442  if (content == document.getElementById("mainContent")) throw "contentarea div not found";
 443  lis = content.getElementsByTagName("ul")[1].getElementsByTagName("li");
 444  for (var i = 0; i < lis.length; i++) {
 445   lis[i].style.border = "1px dotted purple";
 446   processListItem(doc,queueItem,lis[i]);
 447  }
 448 
 449 };
 450 
 451 
 452 function processListItem(doc,queueItem,li) {
 453  var nation = (li.getElementsByTagName("img")[0]) ? li.getElementsByTagName("img")[0].getAttribute("alt") : undefined;
 454  as = li.getElementsByTagName("a");
 455  
 456  var range = doc.createRange();
 457  range.selectNodeContents(li);
 458  var name = range.toString().replace(/^.*by |\s$/,"");
 459  
 460  var cssfile = as[0].getAttribute("href").replace(/^\s*http:\/\/(www\.)?csszengarden\.com\/\?cssfile=/i,"");
 461  if (cssfile.match(/^\//)) { cssfile = "http://www.csszengarden.com" + cssfile; }
 462  
 463  var number = (li.innerHTML.replace(/^\s*<img[^\>]*>\s*/i,"").match(/[0-9]{0,2}[1-9]\s/g)) ? parseInt(li.innerHTML.replace(/^\s*<img[^\>]*>\s*([0-9]{0,2}[1-9]).*/i,"$1"),10) : undefined;
 464  
 465  var category = queueItem.category;
 466  
 467  var range = doc.createRange();
 468  range.selectNodeContents(as[0]);
 469  var title = range.toString().replace(/^\s|\s$/g,"");
 470  
 471  var url = (as[1]) ? as[1].getAttribute("href") : undefined;
 472  
 473  output.push(new ZenEntry(category,number,name,url,nation,cssfile,title));
 474  sendInfo(JSON.stringify(output[output.length-1]));
 475 };
 476 
 477 /**** PROCESS THE QUEUE ****/
 478 
 479 var step = 0;
 480 
 481 function doStage() {
 482  // check for a page load
 483  if (!iframe.contentDocument ||
 484      !iframe.contentDocument.body ||
 485      !iframe.contentDocument.body.innerHTML || 
 486      !iframe.contentDocument.body.innerHTML.indexOf("© Copyright 2001 – 2005, Dave Shea, all rights reserved.") < 0
 487     ) {
 488   setTimeout(doStage,200);
 489   return;
 490  } else if (iframe.contentDocument.body.innerHTML.indexOf("error 404 - file not found") > -1) {
 491   alert("404 error accessing\n" + queue[0].toString() + "\n\nMoving on to next item.");
 492   failed.push(queue.shift());
 493   iframe.setLocation(queue[0].toString());
 494   setTimeout(doStage,500);
 495  }{
 496   var success = true;
 497   try {
 498    processPage(queue[0],iframe.contentDocument);
 499   } catch (e) {
 500    processException(e);
 501    success = false;
 502   }
 503   // advance the queue
 504   var item = queue.shift();
 505   if (success) {
 506    completed.push(item);
 507   } else {
 508    failed.push(item);
 509   }
 510   if (queue[0]) {
 511    iframe.contentDocument.body.innerHTML = "";
 512    step++;
 513    //if (step > 6) return; // limits to a certain number of pages
 514    iframe.setLocation(queue[0].toString());
 515    setTimeout(doStage,500);
 516   }
 517  }
 518 };
 519 
 520 
 521 /**** HANDLE ERRORS ****/
 522 
 523 function processException(e) {
 524  sendInfo(e);
 525 };
 526 
 527 
 528 function sendInfo(info) {
 529  data.value += "\n\n" + info.toString();
 530  data.selectionEnd = data.length-1;
 531 };
 532 
 533 
 534 function setInfo(string) {
 535  data.value = string;
 536 };
 537 
 538 /**** SET IT ALL UP ****/
 539 
 540 document.body.innerHTML = "";
 541 
 542 var iframe = document.createElement("iframe");
 543 iframe.setAttribute("style","position:absolute;right: 10px;height:300px;left:10px;top:10px;");
 544 document.body.appendChild(iframe);
 545 iframe.setLocation = function(newLocation) {
 546  this.setAttribute("src",newLocation);
 547 };
 548 
 549 var data = document.createElement("textarea");
 550 //data.setAttribute("type","text");
 551 data.setAttribute("name","data");
 552 data.style.position = "absolute";
 553 data.style.left = "10px";
 554 data.style.right = "10px";
 555 data.style.top = "320px";
 556 data.style.height = "200px";
 557 document.body.appendChild(data);
 558 
 559 /**** BEGIN ****/
 560 iframe.setLocation(queue[0]);
 561 setInfo(JSON.stringify(queue).replace(/,\{"url"/g,',\n{"url"'));
 562 setTimeout(function() { setInfo(""); doStage(); },3000);
 563 
 564 /* bookmarklet:
 565 
 566 javascript:var script = document.createElement("script"); script.setAttribute("type","text/javascript"); script.setAttribute("src","http://freecog.net/zenparse.js"); document.getElementsByTagName("head")[0].appendChild(script); void(null);
 567 
 568 */