Skip to content

Instantly share code, notes, and snippets.

@scripting
Last active August 29, 2015 14:21
Show Gist options
  • Save scripting/d0c898357424c30a2724 to your computer and use it in GitHub Desktop.
Save scripting/d0c898357424c30a2724 to your computer and use it in GitHub Desktop.
A little Node.js app that reads an OPML file into an outline structure, and displays the structure on the console.
var request = require ("request");
var opmlParser = require ("opmlparser");
function stringMid (s, ix, len) { //8/12/14 by DW
return (s.substr (ix-1, len));
}
function filledString (ch, ct) { //6/4/14 by DW
var s = "";
for (var i = 0; i < ct; i++) {
s += ch;
}
return (s);
}
function outlineToText (theOutline, flIncludeAtts) {
var theText = "", indentlevel = 0;
if (flIncludeAtts === undefined) {
flIncludeAtts = true;
}
function visitSubs (theNode) {
if (theNode.subs != undefined) {
for (var i = 0; i < theNode.subs.length; i++) {
var sub = theNode.subs [i], attstext = "", linetext;
if (flIncludeAtts) {
for (var x in sub) {
if ((x != "subs") && (x != "text") && (x != "parent") && (x != "created")) {
if (attstext.length > 0) {
attstext += ", ";
}
attstext += x + "=" + sub [x];
}
}
if (attstext.length > 0) {
attstext = " (" + attstext + ")";
}
}
//set linetext
var linetext = sub.text;
if (linetext.length > 50) {
linetext = stringMid (linetext, 1, 50) + "...";
}
theText += filledString ("\t", indentlevel) + linetext + attstext + "\n";
indentlevel++;
visitSubs (sub);
indentlevel--;
}
}
}
visitSubs (theOutline);
return (theText);
}
function readOpml (urloutline, callback) {
var outlineArray = new Array ();
var req = request (urloutline);
var opmlparser = new opmlParser ();
var metadata = undefined;
req.on ("response", function (res) {
var stream = this;
if (res.statusCode == 200) {
stream.pipe (opmlparser);
}
});
req.on ("error", function (res) {
});
opmlparser.on ("error", function (error) {
console.log ("readOpml: opml parser error == " + error.message);
});
opmlparser.on ("readable", function () {
var outline;
while (outline = this.read ()) {
var ix = Number (outline ["#id"]);
outlineArray [ix] = outline;
if (metadata === undefined) {
metadata = this.meta;
}
}
});
opmlparser.on ("end", function () {
var theOutline = new Object ();
theOutline.parent = undefined; //this is how you can tell you hit the top in a traversal to the summit
//copy elements of the metadata object into the root of the outline
function copyone (name) {
var val = metadata [name];
if ((val !== undefined) && (val != null)) {
theOutline [name] = val;
}
}
copyone ("title");
copyone ("datecreated");
copyone ("datemodified");
copyone ("ownername");
copyone ("owneremail");
copyone ("description");
for (var i = 0; i < outlineArray.length; i++) {
var obj = outlineArray [i];
if (obj != null) {
var idparent = obj ["#parentid"], parent;
if (idparent == 0) {
parent = theOutline;
}
else {
parent = outlineArray [idparent];
}
if (parent.subs === undefined) {
parent.subs = new Array ();
}
parent.subs [parent.subs.length] = obj;
obj.parent = parent;
delete obj ["#id"];
delete obj ["#parentid"];
}
}
if (callback != undefined) {
callback (theOutline);
}
});
}
readOpml ("https://dl.dropboxusercontent.com/u/36518280/worldOutline/dave.opml", function (theOutline) {
console.log (outlineToText (theOutline));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment