From c3331cb090c6e66a85663f7b1dcb9b254d2815f5 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Thu, 8 Dec 2011 16:20:11 +0000 Subject: [PATCH] Added preliminary support for generating RSS feeds Which also included adding the shadow shadow tiddlers that are built into TiddlyWiki's source code, and are not handled by cook.rb and ginsu.rb --- js/Recipe.js | 84 +++++++++++++++++++++++++++++++++++++++++++++------ tiddlywiki.js | 44 +++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 11 deletions(-) diff --git a/js/Recipe.js b/js/Recipe.js index f96aba338..609d4416b 100755 --- a/js/Recipe.js +++ b/js/Recipe.js @@ -165,15 +165,6 @@ Recipe.prototype.processRecipeFile = function(recipe,text,contextPath) { }); }; -// Special post-processing required for certain ingredient types -Recipe.prototype.readIngredientPostProcess = { - "shadow": function(fields) { - // Add ".shadow" to the name of shadow tiddlers - fields.title = fields.title + ".shadow"; - return fields; - } -}; - // Read a tiddler file and callback with an array of hashmaps of tiddler fields. For single // tiddler files it also looks for an accompanying .meta file Recipe.prototype.readTiddlerFile = function(filepath,contextPath,callback) { @@ -284,5 +275,80 @@ Recipe.tiddlerOutputter = { } }; +// Cook an RSS file of the most recent 20 tiddlers +Recipe.prototype.cookRss = function() +{ + var me = this, + numRssItems = 20, + s = [], + d = new Date(), + u = this.store.getTiddler("SiteUrl").getParseTree().render("text/plain"), + encodeTiddlyLink = function(title) { + return title.indexOf(" ") == -1 ? title : "[[" + title + "]]"; + }, + tiddlerToRssItem = function(tiddler,uri) { + var s = "" + utils.htmlEncode(tiddler.fields.title) + "\n"; + s += "" + utils.htmlEncode(tiddler.getParseTree().render("text/html")) + "\n"; + var i; + if(tiddler.fields.tags) { + for(i=0; i\n"; + } + } + s += "" + uri + "#" + encodeURIComponent(encodeTiddlyLink(tiddler.fields.title)) + "\n"; + if(tiddler.fields.modified) { + s +="" + tiddler.fields.modified.toUTCString() + "\n"; + } + return s; + }, + getRssTiddlers = function(sortField,excludeTag) { + var r = []; + me.store.forEachTiddler(function(title,tiddler) { + if(!tiddler.hasTag(excludeTag)) { + r.push(tiddler); + } + }); + r.sort(function(a,b) { + var aa = a.fields[sortField] || 0, + bb = b.fields[sortField] || 0; +console.error("Comparing %s (%s) and %s (%s)",a.fields.title,util.inspect(a.fields[sortField],false,8),b.fields.title,util.inspect(b.fields[sortField],false,8)); + if(aa < bb) { + return -1; + } else { + if(aa > bb) { + return 1; + } else { + return 0; + } + } + }); + return r; + }; + // Assemble the header + s.push("<" + "?xml version=\"1.0\"?" + ">"); + s.push(""); + s.push(""); + s.push("" + utils.htmlEncode(this.store.getTiddler("SiteTitle").getParseTree().render("text/plain")) + ""); + if(u) + s.push("" + utils.htmlEncode(u) + ""); + s.push("" + utils.htmlEncode(this.store.getTiddler("SiteSubtitle").getParseTree().render("text/plain")) + ""); + //s.push("" + config.locale + ""); + s.push("" + d.toUTCString() + ""); + s.push("" + d.toUTCString() + ""); + s.push("http://blogs.law.harvard.edu/tech/rss"); + s.push("https://github.com/Jermolene/cook.js"); + // The body + var tiddlers = getRssTiddlers("modified","excludeLists"); + var i,n = numRssItems > tiddlers.length ? 0 : tiddlers.length-numRssItems; + for(i=tiddlers.length-1; i>=n; i--) { + s.push("\n" + tiddlerToRssItem(tiddlers[i],u) + "\n"); + } + // And footer + s.push(""); + s.push(""); + // Save it all + return s.join("\n"); +} + exports.Recipe = Recipe; diff --git a/tiddlywiki.js b/tiddlywiki.js index e65f8f62b..91fd8afbd 100644 --- a/tiddlywiki.js +++ b/tiddlywiki.js @@ -47,6 +47,40 @@ var switches = parseOptions(Array.prototype.slice.call(process.argv,2),"dummy"), lastRecipeFilepath = null, currSwitch = 0; +// Add the shadow tiddlers that are built into TiddlyWiki +var shadowShadowStore = new WikiStore(null), + shadowShadows = [ + {title: "StyleSheet", text: ""}, + {title: "MarkupPreHead", text: ""}, + {title: "MarkupPostHead", text: ""}, + {title: "MarkupPreBody", text: ""}, + {title: "MarkupPostBody", text: ""}, + {title: "TabTimeline", text: "<>"}, + {title: "TabAll", text: "<>"}, + {title: "TabTags", text: "<>"}, + {title: "TabMoreMissing", text: "<>"}, + {title: "TabMoreOrphans", text: "<>"}, + {title: "TabMoreShadowed", text: "<>"}, + {title: "AdvancedOptions", text: "<>"}, + {title: "PluginManager", text: "<>"}, + {title: "SystemSettings", text: ""}, + {title: "ToolbarCommands", text: "|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|"}, + {title: "WindowTitle", text: "<> - <>"}, + {title: "DefaultTiddlers", text: "[[GettingStarted]]"}, + {title: "MainMenu", text: "[[GettingStarted]]"}, + {title: "SiteTitle", text: "My TiddlyWiki"}, + {title: "SiteSubtitle", text: "a reusable non-linear personal web notebook"}, + {title: "SiteUrl", text: ""}, + {title: "SideBarOptions", text: '<><><><><><><>'}, + {title: "SideBarTabs", text: '<>'}, + {title: "TabMore", text: '<>'} + ]; +store.shadows.shadows = shadowShadowStore; +for(var t=0; t