/***\n!Metadata:\n|''Name:''|ArchivedTimeline|\n|''Description:''|Timeline archived monthly.|\n|''Version:''|0.6.1|\n|''Date:''|Jul 25, 2006|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''~CoreVersion:''|2.0.11|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n\n!Syntax/Examples:\n|{{{<<timeline [modified | created] [maxentries]>>}}}|\n!Revision History:\n|''Version''|''Date''|''Note''|\n|0.6.1|Aug 12, 2006|A great effect on config.macros.timeline.slider for Firefox, thanks Bob McElrath|\n|0.6.0|Jul 25, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|0.5.2|Jun 21, 2006|Fixed bugs for dateFormat of TW 2.1|\n|~|~|Change default dateFormat to "0DD mmm, YYYY"|\n|0.5.1|Jun 04, 2006|Added config.macros.archivedTimeline.orderBy for localization|\n|0.5.0|Apr 19, 2006|Fixed bug for twice records of the same date ()|\n|~|~|Added Date.prototype.convertToLocalYYYYMMDDHHMM<<br>>in order to backward compatible with 2.0.6-|\n|0.4.0|Apr 03, 2006|Added new parameter, {{{<<timeline [sortfield] [maxentries]>>}}}|\n|~|~|Added config.options.txtTimelineMaxentries|\n|0.3.1|Feb 04, 2006|JSLint checked|\n|0.3.0|Feb 04, 2006|Fixed several missing variable declarations|\n|0.2.0|Dec 26, 2005|changed for the new feature of Macro timeline of TW 2.0.0 beta 6|\n|0.1.0|Nov 3, 2005|Initial release|\n\n!Code section:\n***/\n//{{{\nversion.extensions.archivedTimeline = {major: 0, minor: 6, revision: 1,\n date: new Date("Aug 12, 2006"),\n name: "ArchivedTimeline",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\nconfig.options.txtTimelineMaxentries=0;\nconfig.macros.archivedTimeline = {\n tooltips: "Archives sorted by ",\n orderBy:{modified: "modified", created: "created"},\n dateFormat: "0DD mmm YYYY"\n};\nconfig.macros.timeline = config.macros.archivedTimeline;\n\nconfig.macros.timeline.handler = function(place,macroName,params) {\n var field = params[0] ? params[0] : "modified";\n\n place.appendChild(document.createTextNode(this.tooltips + this.orderBy[field]));\n var tiddlers = store.reverseLookup("tags","excludeLists",false,field);\n var lastMonth = ""; var lastDay = ""; var theText = "----\sn"; var i = 0;\n var last = (params[1])?params[1]:config.options.txtTimelineMaxentries;\n last = (isNaN(last)||last<1) ? 0:tiddlers.length-Math.min(tiddlers.length,parseInt(last));\n var cookie; var archives;\n for (var t=tiddlers.length-1; t>=last; t--) {\n var tiddler = tiddlers[t];\n var theMonth = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,6);\n var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theMonth != lastMonth) {\n if (lastMonth === "") {\n lastMonth = theMonth;\n }\n else {\n place.appendChild(document.createElement("hr"));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.dateFormat, lastMonth);\n this.slider(place,cookie,theText,archives,this.tooltips + archives);\n lastMonth = theMonth; theText = "----\sn";\n }\n }\n if(theDay != lastDay){\n theText += tiddler[field].formatString(this.dateFormat) + '\sn';\n lastDay = theDay; \n }\n theText += '* [[' + tiddler.title + ']]\sn';\n }\n place.appendChild(document.createElement("hr"));\n cookie = 'chktimeline'+(i++);\n archives = this.formatString(this.dateFormat, lastMonth);\n this.slider(place,cookie,theText,archives,this.tooltips + archives);\n place.appendChild(document.createElement("hr"));\n};\n\nconfig.macros.timeline.onClickSlider = config.macros.slider.onClickSlider;\n\nconfig.macros.timeline.slider = function(place,cookie,text,id,tooltips)\n{\n var btn = createTiddlyButton(place,id,tooltips,this.onClickSlider);\n var panel = document.createElement("div");\n panel.className = "timelineSliderPanel";\n panel.setAttribute("cookie",cookie);\n panel.style.display = config.options[cookie] ? "block" : "none";\n place.appendChild(panel);\n if(text){\n wikify(text,panel);\n }\n};\n\nconfig.macros.timeline.formatString = function(template, yyyymm)\n{\n var dateString = new Date(yyyymm.substr(0,4)+'/'+yyyymm.substr(4,2)+'/01');\n template = template.replace(/DDD|0DD|DD/g,'');\n return dateString.formatString(template);\n};\nif (!Date.prototype.convertToLocalYYYYMMDDHHMM){\n Date.prototype.convertToLocalYYYYMMDDHHMM = function(){\n return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2));\n }\n}\n//}}}
/***\n!ArchivedTimeline.zh-Hant\n***/\n//{{{\nif (typeof config.macros.archivedTimeline != "undefined"){\n merge(config.macros.archivedTimeline, {\n tooltips: "歸檔順序: ",\n orderBy: {modified: "修改日期", created: "建立日期"},\n monthFormat: "YYYY年0MM月",\n dateFormat: "YYYY年0MM月0DD日"\n });\n}\n//}}}
/***\n|Name|BetterTimelineMacro|\n|Created by|SaqImtiaz|\n|Location|http://tw.lewcid.org/#BetterTimelineMacro|\n|Version|0.5 beta|\n|Requires|~TW2.x|\n!!!Description:\nA replacement for the core timeline macro that offers more features:\n*list tiddlers with only specfic tag\n*exclude tiddlers with a particular tag\n*limit entries to any number of days, for example one week\n*specify a start date for the timeline, only tiddlers after that date will be listed.\n\n!!!Installation:\nCopy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.\nEdit the ViewTemplate to add the fullscreen command to the toolbar.\n\n!!!Syntax:\n{{{<<timeline better:true>>}}}\n''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''\n\nadditonal params:\n(use only the ones you want)\n{{{<<timeline better:true onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}\n\n''explanation of syntax:''\nonlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.\nexcludeTag: tiddlers with this tag will not be listed.\nsortBy: sort tiddlers by date modified or date created. Possible values are modified or created.\nfirstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006\nmaxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.\nmaxEntries: limit the total number of entries in the timeline.\n\n\n!!!History:\n*28-07-06: ver 0.5 beta, first release\n\n!!!Code\n***/\n//{{{\n// Return the tiddlers as a sorted array\nTiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)\n{\n var results = [];\n this.forEachTiddler(function(title,tiddler)\n {\n if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)\n if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)\n results.push(tiddler);\n });\n if(field)\n results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });\n return results;\n}\n\n\n\n//this function by Udo\nfunction getParam(params, name, defaultValue)\n{\n if (!params)\n return defaultValue;\n var p = params[0][name];\n return p ? p[0] : defaultValue;\n}\n\nwindow.old_timeline_handler= config.macros.timeline.handler;\nconfig.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n var args = paramString.parseParams("list",null,true);\n var betterMode = getParam(args, "better", "false");\n if (betterMode == 'true')\n {\n var sortBy = getParam(args,"sortBy","modified");\n var excludeTag = getParam(args,"excludeTag",undefined);\n var includeTag = getParam(args,"onlyTag",undefined);\n var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);\n var firstDayParam = getParam(args,"firstDay",undefined);\n var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";\n var lastDay = "";\n var field= sortBy;\n var maxDaysParam = getParam(args,"maxDays",undefined);\n var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;\n var maxEntries = getParam(args,"maxEntries",undefined);\n var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;\n for(var t=tiddlers.length-1; t>=last; t--)\n {\n var tiddler = tiddlers[t];\n var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))\n {\n if(theDay != lastDay)\n {\n var theDateList = document.createElement("ul");\n place.appendChild(theDateList);\n createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));\n lastDay = theDay;\n }\n var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);\n theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));\n }\n }\n }\n\n else\n {\n window.old_timeline_handler.apply(this,arguments);\n }\n}\n//}}}
/***\n|Name|BreadcrumbsPlugin|\n|Source|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|OriginalAuthor|Alan Hecht (with 2.0 update from 'jack' and revisions by Bram Chen)|\n|Version|1.5.4.0TT|\n|Author|Eric Shulman|\n|License|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Story.prototype.displayTiddler|\n|Description|show a list of tiddlers viewed during this session. Also defines "back" (previousTiddler) toolbar button and macro|\n\n!Revision History:\n__TiddlyTools (TT) variant:__\n1.5.4.0 2007.03.02 - in refreshCrumbs(), for TW2.2, look for "storyDisplay" instead of "tiddlerDisplay" but keep fallback to "tiddlerDisplay" for TW2.1 or earlier\n1.5.3.0 2007.02.24 - changed from hijack of onClickTiddlerLink to hijack of displayTiddler() so that ALL displayed tiddlers are recorded in the crumbs, including programmatically displayed tiddlers opened by macros, scripts, etc., (such as [[GotoPlugin]], among many others) in addition to those opened by clicks on links.\n1.5.2.0 2007.02.24 - eliminated global space clutter by moving function and data declarations so they are contained inside config.breadCrumbs object.\n1.5.1.0 2007.02.06 - added "previousTiddler" macro (for use in sidebar)\n1.5.0.0 2007.02.05 - added "previousTiddler" toolbar command (aka, "back")\n1.4.0.1 2006.08.04 - change spaces to tabs\n1.4.0.0 2006.08.04 - modified from 1.4.0 distro:\n<<<\nin refreshCrumbs(), set {{{display:none/block}}} instead of {{{visibility:hidden/visible}}}\nin restartHome(), check for valid crumbArea before setting style\ngeneral code cleanup/reformat using tabs to indent\n<<<\n|''Version''|''Date''|''Note''|\n|1.4.0|Aug 02, 2006|Fixed bug, the redefined onClickTiddlerLink_orig_breadCrumbs works incorrectly on IE|\n|1.3.0|Jul 20, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|1.2.0|Feb 07, 2006|change global array breadCrumbs to config.breadCrumbs by Eric's suggestion|\n|1.1.0|Feb 04, 2006|JSLint checked|\n|1.0.0|Feb 01, 2006|TW2 ready and code Cleaned-up|\n\n!Code section:\n***/\n//{{{\nversion.extensions.breadCrumbs = {major: 1, minor: 5, revision: 4, date: new Date("Mar 3, 2007")};\n\nif (Story.prototype.breadCrumbs_coreDisplayTiddler==undefined)\n Story.prototype.breadCrumbs_coreDisplayTiddler=Story.prototype.displayTiddler;\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n this.breadCrumbs_coreDisplayTiddler.apply(this,arguments);\n // if not displaying tiddler during document startup, then add it to the breadcrumbs\n // note: 'startingUp' flag is a global, set/reset by the core init() function\n if (!startingUp) config.breadCrumbs.addCrumb(title);\n}\n\nconfig.breadCrumbs = { // ELS: move all functions and data inside config.breadCrumbs object (eliminate global clutter)\n crumbs: [], // the list of current breadcrumbs\n addCrumb: function (title) { // ELS: changed from passing event, "e", to passing tiddler title\n var thisCrumb = "[[" + title + "]]";\n var ind = this.crumbs.find(thisCrumb);\n if(ind === null)\n this.crumbs.push(thisCrumb);\n else\n this.crumbs=this.crumbs.slice(0,ind+1); // ELS: use slice() to truncate array instead of just setting array length\n this.refreshCrumbs();\n return false;\n },\n refreshCrumbs: function() {\n var crumbArea = document.getElementById("breadCrumbs");\n if (!crumbArea) {\n var crumbArea = document.createElement("div");\n crumbArea.id = "breadCrumbs";\n crumbArea.style.display= "none"; // ELS changed from: crumbArea.style.visibility= "hidden";\n var targetArea= document.getElementById("tiddlerDisplay"); // TW2.1-\n if (!targetArea) targetArea = document.getElementById("storyDisplay"); // TW2.2+\n targetArea.parentNode.insertBefore(crumbArea,targetArea);\n }\n crumbArea.style.display = "block"; // ELS changed from: crumbArea.style.visibility = "visible";\n removeChildren(crumbArea);\n createTiddlyButton(crumbArea,"Home",null,this.restartHome);\n wikify(" | " + this.crumbs.join(' > '),crumbArea) // ELS: changed || to |\n },\n restartHome: function() {\n story.closeAllTiddlers();\n restart();\n config.breadCrumbs.crumbs = [];\n var crumbArea = document.getElementById("breadCrumbs");\n if (crumbArea) // ELS: added check to make sure crumbArea exists\n crumbArea.style.display = "none"; // ELS changed from: crumbArea.style.visibility = "hidden";\n }\n};\n\nconfig.commands.previousTiddler = { // ELS: added "BACK" toolbar command\n text: 'back',\n tooltip: 'view the previous tiddler',\n hideReadOnly: false,\n dateFormat: 'DDD, MMM DDth YYYY hh:0mm:0ss',\n handler: function(event,src,title) {\n var here=story.findContainingTiddler(src); if (!here) return;\n if (config.breadCrumbs.crumbs.length>1) {\n var crumb=config.breadCrumbs.crumbs[config.breadCrumbs.crumbs.length-2].replace(/\s[\s[/,'').replace(/\s]\s]/,'');\n story.displayTiddler(here,crumb);\n }\n else\n config.breadCrumbs.restartHome();\n return false;\n }\n};\n\nconfig.macros.previousTiddler= { // ELS: added "BACK" macro\n text: 'back',\n tooltip: 'view the previous tiddler',\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n createTiddlyButton(place,this.text,this.tooltip,function() {\n if (config.breadCrumbs.crumbs.length>1) {\n var crumb=config.breadCrumbs.crumbs[config.breadCrumbs.crumbs.length-2].replace(/\s[\s[/,'').replace(/\s]\s]/,'');\n story.displayTiddler(place,crumb);\n }\n else\n config.breadCrumbs.restartHome();\n });\n }\n}\n//}}}
/***\n|Name|CalendarPlugin|\n|Source|http://www.TiddlyTools.com/#CalendarPlugin|\n|Version|0.0.0|\n|Author|SteveRumsby|\n|License|unknown|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description||\n\n// // updated by Jeremy Sheeley to add cacheing for reminders\n// // see http://www.geocities.com/allredfaq/reminderMacros.html\n// // ''Changes by ELS 2006.08.23:''\n// // added handling for weeknumbers (code supplied by Martin Budden. see "wn**" comment marks)\n// // ''Changes by ELS 2005.10.30:''\n// // config.macros.calendar.handler()\n// // ^^use "tbody" element for IE compatibility^^\n// // ^^IE returns 2005 for current year, FF returns 105... fix year adjustment accordingly^^\n// // createCalendarDays()\n// // ^^use showDate() function (if defined) to render autostyled date with linked popup^^\n// // calendar stylesheet definition\n// // ^^use .calendar class-specific selectors, add text centering and margin settings^^\n\n\n!!!!!Configuration:\n<<option chkDisplayWeekNumbers>> Display week numbers //(note: Monday will be used as the start of the week)//\n|''First day of week:''|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|\n|''First day of weekend:''|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|\n\n!!!!!Syntax:\n|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|\n|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|\n|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|\n|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|\n|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|\n|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|\n\n***/\n// //Modify this section to change the text displayed for the month and day names, to a different language for example. You can also change the format of the tiddler names linked to from each date, and the colours used.\n\n//{{{\nconfig.macros.calendar = {};\n\nconfig.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];\nconfig.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];\n\nconfig.macros.calendar.weekendbg = "#c0c0c0";\nconfig.macros.calendar.monthbg = "#e0e0e0";\nconfig.macros.calendar.holidaybg = "#ffc0c0";\n\n//}}}\n// //''Code section:''\n// (you should not need to alter anything below here)//\n//{{{\nif(config.options.txtCalFirstDay == undefined)\n config.options.txtCalFirstDay = 0;\nif(config.options.txtCalStartOfWeekend == undefined)\n config.options.txtCalStartOfWeekend = 5;\nif(config.options.chkDisplayWeekNumbers == undefined)//wn**\n config.options.chkDisplayWeekNumbers = false;\nif(config.options.chkDisplayWeekNumbers)\n config.options.txtCalFirstDay = 0;\n\nconfig.macros.calendar.tiddlerformat = "0DD/0MM/YYYY"; // This used to be changeable - for now, it isn't// <<smiley :-(>> \n\nversion.extensions.calendar = { major: 0, minor: 6, revision: 0, date: new Date(2006, 1, 22)};\nconfig.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\nconfig.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead\n//}}}\n\n// //Is the given date a holiday?\n//{{{\nfunction calendarIsHoliday(date)\n{\n var longHoliday = date.formatString("0DD/0MM/YYYY");\n var shortHoliday = date.formatString("0DD/0MM");\n\n for(var i = 0; i < config.macros.calendar.holidays.length; i++) {\n if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday) {\n return true;\n }\n }\n return false;\n}\n//}}}\n\n// //The main entry point - the macro handler.\n// //Decide what sort of calendar we are creating (month or year, and which month or year)\n// // Create the main calendar container and pass that to sub-ordinate functions to create the structure.\n// ELS 2005.10.30: added creation and use of "tbody" for IE compatibility and fixup for year >1900//\n// ELS 2005.10.30: fix year calculation for IE's getYear() function (which returns '2005' instead of '105')//\n// ELS 2006.05.29: add journalDateFmt handling//\n//{{{\nconfig.macros.calendar.handler = function(place,macroName,params)\n{\n var calendar = createTiddlyElement(place, "table", null, "calendar", null);\n var tbody = createTiddlyElement(calendar, "tbody", null, null, null);\n var today = new Date();\n var year = today.getYear();\n if (year<1900) year+=1900;\n \n // get format for journal link by reading from SideBarOptions (ELS 5/29/06 - based on suggestion by Martin Budden)\n var text = store.getTiddlerText("SideBarOptions");\n this.journalDateFmt = "DD-MMM-YYYY";\n var re = new RegExp("<<(?:newJournal)([^>]*)>>","mg"); var fm = re.exec(text);\n if (fm && fm[1]!=null) { var pa=fm[1].readMacroParams(); if (pa[0]) this.journalDateFmt = pa[0]; }\n\n if (params[0] == "thismonth")\n {\n cacheReminders(new Date(year, today.getMonth(), 1, 0, 0), 31);\n createCalendarOneMonth(tbody, year, today.getMonth());\n } \n else if (params[0] == "lastmonth") {\n var month = today.getMonth()-1; if (month==-1) { month=11; year--; }\n cacheReminders(new Date(year, month, 1, 0, 0), 31);\n createCalendarOneMonth(tbody, year, month);\n }\n else if (params[0] == "nextmonth") {\n var month = today.getMonth()+1; if (month>11) { month=0; year++; }\n cacheReminders(new Date(year, month, 1, 0, 0), 31);\n createCalendarOneMonth(tbody, year, month);\n }\n else {\n if (params[0]) year = params[0];\n if(params[1])\n {\n cacheReminders(new Date(year, params[1]-1, 1, 0, 0), 31);\n createCalendarOneMonth(tbody, year, params[1]-1);\n }\n else\n {\n cacheReminders(new Date(year, 0, 1, 0, 0), 366);\n createCalendarYear(tbody, year);\n }\n }\n window.reminderCacheForCalendar = null;\n}\n//}}}\n//{{{\n//This global variable is used to store reminders that have been cached\n//while the calendar is being rendered. It will be renulled after the calendar is fully rendered.\nwindow.reminderCacheForCalendar = null;\n//}}}\n//{{{\nfunction cacheReminders(date, leadtime)\n{\n if (window.findTiddlersWithReminders == null)\n return;\n window.reminderCacheForCalendar = {};\n var leadtimeHash = [];\n leadtimeHash [0] = 0;\n leadtimeHash [1] = leadtime;\n var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);\n for(var i = 0; i < t.length; i++) {\n //just tag it in the cache, so that when we're drawing days, we can bold this one.\n window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; \n }\n}\n//}}}\n//{{{\nfunction createCalendarOneMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonth(calendar, year, mon)\n{\n var row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);\n row = createTiddlyElement(calendar, "tr", null, null, null);\n createCalendarDayHeader(row, 1);\n createCalendarDayRowsSingle(calendar, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarYear(calendar, year)\n{\n var row;\n row = createTiddlyElement(calendar, "tr", null, null, null);\n var back = createTiddlyElement(row, "td", null, null, null);\n var backHandler = function() {\n removeChildren(calendar);\n createCalendarYear(calendar, year-1);\n };\n createTiddlyButton(back, "<", "Previous year", backHandler);\n back.align = "center";\n\n var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);\n yearHeader.align = "center";\n //yearHeader.setAttribute("colSpan", 19);\n yearHeader.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?22:19);//wn**\n\n var fwd = createTiddlyElement(row, "td", null, null, null);\n var fwdHandler = function() {\n removeChildren(calendar);\n createCalendarYear(calendar, year+1);\n };\n createTiddlyButton(fwd, ">", "Next year", fwdHandler);\n fwd.align = "center";\n\n createCalendarMonthRow(calendar, year, 0);\n createCalendarMonthRow(calendar, year, 3);\n createCalendarMonthRow(calendar, year, 6);\n createCalendarMonthRow(calendar, year, 9);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonthRow(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);\n createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDayHeader(row, 3);\n createCalendarDayRows(cal, year, mon);\n}\n//}}}\n\n//{{{\nfunction createCalendarMonthHeader(cal, row, name, nav, year, mon)\n{\n var month;\n if(nav) {\n var back = createTiddlyElement(row, "td", null, null, null);\n back.align = "center";\n back.style.background = config.macros.calendar.monthbg;\n\n/*\n back.setAttribute("colSpan", 2);\n\n var backYearHandler = function() {\n var newyear = year-1;\n removeChildren(cal);\n cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);\n createCalendarOneMonth(cal, newyear, mon);\n };\n createTiddlyButton(back, "<<", "Previous year", backYearHandler);\n*/\n var backMonHandler = function() {\n var newyear = year;\n var newmon = mon-1;\n if(newmon == -1) { newmon = 11; newyear = newyear-1;}\n removeChildren(cal);\n cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);\n createCalendarOneMonth(cal, newyear, newmon);\n };\n createTiddlyButton(back, "<", "Previous month", backMonHandler);\n\n\n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n// month.setAttribute("colSpan", 3);\n// month.setAttribute("colSpan", 5);\n month.setAttribute("colSpan", config.options.chkDisplayWeekNumbers?6:5);//wn**\n\n var fwd = createTiddlyElement(row, "td", null, null, null);\n fwd.align = "center";\n fwd.style.background = config.macros.calendar.monthbg; \n\n// fwd.setAttribute("colSpan", 2);\n var fwdMonHandler = function() {\n var newyear = year;\n var newmon = mon+1;\n if(newmon == 12) { newmon = 0; newyear = newyear+1;}\n removeChildren(cal);\n cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);\n createCalendarOneMonth(cal, newyear, newmon);\n };\n createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);\n/*\n var fwdYear = createTiddlyElement(row, "td", null, null, null);\n var fwdYearHandler = function() {\n var newyear = year+1;\n removeChildren(cal);\n cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);\n createCalendarOneMonth(cal, newyear, mon);\n };\n createTiddlyButton(fwd, ">>", "Next year", fwdYearHandler);\n*/\n } else {\n month = createTiddlyElement(row, "td", null, "calendarMonthname", name)\n //month.setAttribute("colSpan", 7);\n month.setAttribute("colSpan",config.options.chkDisplayWeekNumbers?8:7);//wn**\n }\n month.align = "center";\n month.style.background = config.macros.calendar.monthbg;\n}\n//}}}\n\n//{{{\nfunction createCalendarDayHeader(row, num)\n{\n var cell;\n for(var i = 0; i < num; i++) {\n if (config.options.chkDisplayWeekNumbers) createTiddlyElement(row, "td");//wn**\n for(var j = 0; j < 7; j++) {\n var d = j + (config.options.txtCalFirstDay - 0);\n if(d > 6) d = d - 7;\n cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);\n if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))\n cell.style.background = config.macros.calendar.weekendbg;\n }\n }\n}\n//}}}\n\n//{{{\nfunction createCalendarDays(row, col, first, max, year, mon)\n{\n var i;\n if (config.options.chkDisplayWeekNumbers){\n if (first<=max) {\n var ww = new Date(year,mon,first);\n createTiddlyElement(row, "td", null, null, "w"+ww.getWeek());//wn**\n }\n else createTiddlyElement(row, "td", null, null, null);//wn**\n }\n for(i = 0; i < col; i++) {\n createTiddlyElement(row, "td", null, null, null);\n }\n var day = first;\n for(i = col; i < 7; i++) {\n var d = i + (config.options.txtCalFirstDay - 0);\n if(d > 6) d = d - 7;\n var daycell = createTiddlyElement(row, "td", null, null, null);\n var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);\n\n if(day > 0 && day <= max) {\n var celldate = new Date(year, mon, day);\n // ELS 2005.10.30: use <<date>> macro's showDate() function to create popup\n if (window.showDate) {\n showDate(daycell,celldate,"popup","DD",config.macros.calendar.journalDateFmt,true, isaWeekend); // ELS 5/29/06 - use journalDateFmt \n } else {\n if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;\n var title = celldate.formatString(config.macros.calendar.tiddlerformat);\n if(calendarIsHoliday(celldate)) {\n daycell.style.background = config.macros.calendar.holidaybg;\n }\n if(window.findTiddlersWithReminders == null) {\n var link = createTiddlyLink(daycell, title, false);\n link.appendChild(document.createTextNode(day));\n } else {\n var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);\n }\n }\n }\n day++;\n }\n}\n//}}}\n\n// //We've clicked on a day in a calendar - create a suitable pop-up of options.\n// //The pop-up should contain:\n// // * a link to create a new entry for that date\n// // * a link to create a new reminder for that date\n// // * an <hr>\n// // * the list of reminders for that date\n//{{{\nfunction onClickCalendarDate(e)\n{\n var button = this;\n var date = button.getAttribute("title");\n var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));\n\n date = dat.formatString(config.macros.calendar.tiddlerformat);\n var popup = createTiddlerPopup(this);\n popup.appendChild(document.createTextNode(date));\n var newReminder = function() {\n var t = store.getTiddlers(date);\n displayTiddler(null, date, 2, null, null, false, false);\n if(t) {\n document.getElementById("editorBody" + date).value += "\sn<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n } else {\n document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +\n " month:" + (dat.getMonth()+1) +\n " year:" + (dat.getYear()+1900) + " title: >>";\n }\n };\n var link = createTiddlyButton(popup, "New reminder", null, newReminder); \n popup.appendChild(document.createElement("hr"));\n\n var t = findTiddlersWithReminders(dat, [0,14], null, 1);\n for(var i = 0; i < t.length; i++) {\n link = createTiddlyLink(popup, t[i].tiddler, false);\n link.appendChild(document.createTextNode(t[i].tiddler));\n }\n}\n//}}}\n\n//{{{\nfunction calendarMaxDays(year, mon)\n{\n var max = config.macros.calendar.monthdays[mon];\n if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) {\n max++;\n }\n return max;\n}\n//}}}\n\n//{{{\nfunction createCalendarDayRows(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first1 < 0) first1 = first1 + 7;\n var day1 = -first1 + 1;\n var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first2 < 0) first2 = first2 + 7;\n var day2 = -first2 + 1;\n var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first3 < 0) first3 = first3 + 7;\n var day3 = -first3 + 1;\n\n var max1 = calendarMaxDays(year, mon);\n var max2 = calendarMaxDays(year, mon+1);\n var max3 = calendarMaxDays(year, mon+2);\n\n while(day1 <= max1 || day2 <= max2 || day3 <= max3) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;\n createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;\n }\n}\n//}}}\n\n//{{{\nfunction createCalendarDayRowsSingle(cal, year, mon)\n{\n var row = createTiddlyElement(cal, "tr", null, null, null);\n\n var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);\n if(first1 < 0) first1 = first1+ 7;\n var day1 = -first1 + 1;\n var max1 = calendarMaxDays(year, mon);\n\n while(day1 <= max1) {\n row = createTiddlyElement(cal, "tr", null, null, null);\n createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;\n }\n}\n//}}}\n\n// //ELS 2005.10.30: added styles\n//{{{\nsetStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");\n//}}}\n
// // override cookie settings for CalendarPlugin:\n//{{{\nconfig.options.txtCalFirstDay=6;\nconfig.options.txtCalStartOfWeekend=5;\n//}}}
/***\n|Name|CheckboxPlugin|\n|Source|http://www.TiddlyTools.com/#CheckboxPlugin|\n|Version|2.1.3|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description|Add checkboxes to your tiddler content|\n\nCheckbox states can be preserved in the document by either automatically modifying the tiddler content or setting/removing tags on specified tiddlers, or they may be saved as local cookies by assigning an optional 'chkID' to the checkbox. Add custom javascript for programmatic initialization and onClick handling for any checkbox. Also provides access to checkbox DOM element data and tracks the checkbox state in TiddlyWiki's config.options[] internal data.\n\n!!!!!Usage\n<<<\nThe checkbox syntax, including all optional parameters, is contained inside a matched set of [ and ] brackets.\n{{{ [x=id(title|tag){init_script}{onclick_script}] }}}\n\nAn alternative syntax lets you place the optional parameters ''outside'' the [ and ] brackets, and is provided for backward-compatibility with existing content that may include checkbox definitions based on earlier releases of this plugin:\n{{{ [x]=id(title|tag){init_script}{onclick_script} }}}\n\n//{{{\n[ ]or[_] and [x]or[X]\n//}}}\nSimple checkboxes. The current unchecked/checked state is indicated by the character between the {{{[}}} and {{{]}}} brackets ("_" means unchecked, "X" means checked). When you click on a checkbox, the current state is retained by directly modifying the tiddler content to place the corresponding "_" or "X" character in between the brackets\n//{{{\n[x=id]\n//}}}\nAssign an optional ID to the checkbox so you can use {{{document.getElementByID("id")}}} to manipulate the checkbox DOM element, as well as tracking the current checkbox state in {{{config.options["id"]}}}. If the ID starts with "chk" the checkbox state will also be saved in a cookie, so it can be automatically restored whenever the checkbox is re-rendered (overrides any default {{{[x]}}} or {{{[_]}}} value). If a cookie value is kept, the "_" or "X" character in the tiddler content remains unchanged, and is only applied as the default when a cookie-based value is not currently defined.\n//{{{\n[x(title|tag)] or [x(title:tag)]\n//}}}\nInitializes and tracks the current checkbox state by setting or removing ("TogglyTagging") a particular tag value from a specified tiddler. If you omit the tiddler title (and the | or : separator), the specified tag is assigned to the current tiddler. If you omit the tag value, as in {{{(title|)}}}, the default tag, {{{checked}}}, is assumed. Omitting both the title and tag, {{{()}}}, tracks the checkbox state by setting the "checked" tag on the current tiddler. When tag tracking is used, the "_" or "X" character in the tiddler content remains unchanged, and is not used to set or track the checkbox state. If a tiddler title named in the tag does not exist, the checkbox state defaults to //unselected//. When the checkbox is subsequently changed to //selected//, it will automatically (and silently) create the missing tiddler and then add the tag to it. //''NOTE: beginning with version 2.1.2 of this plugin, the "|" separator is the preferred separator between the title and tag name, as it avoids syntactic ambiguity when ":" is used within tiddler titles or tag names.''//\n//{{{\n[x{javascript}{javascript}]\n//}}}\nYou can define optional javascript code segments to add custom initialization and/or 'onClick' handling to a checkbox. The current checkbox state (and it's other DOM attributes) can be set or read from within these code segments by reference to the default context-object, 'this'.\n\nThe first code segment will be executed when the checkbox is initially displayed, so that you can programmatically determine it's starting checked/unchecked state. The second code segment (if present) is executed whenever the checkbox is clicked, so that you can perform programmed responses or intercept and override the checkbox state based on complex logic using the TW core API or custom functions defined in plugins (e.g. testing a particular tiddler title to see if certain tags are set or setting some tags when the checkbox is clicked).\n\nNote: if you want to use the default checkbox initialization processing with a custom onclick function, use this syntax: {{{ [x=id{}{javascript}] }}} \n<<<\n!!!!!Configuration\n<<<\nNormally, when a checkbox state is changed, the affected tiddlers are automatically re-rendered, so that any checkbox-dependent dynamic content can be updated. There are three possible tiddlers to be re-rendered, depending upon where the checkbox is placed, and what kind of storage method it is using.\n*''container'': the tiddler in which the checkbox is displayed. (e.g., this tiddler)\n*''tagged'': the tiddler that is being tagged (e.g., "~MyTask" when tagging "~MyTask:done")\n*''tagging'': the "tag tiddler" (e.g., "~done" when tagging "~MyTask:done")\nYou can set the default refresh handling for all checkboxes in your document by using the following javascript syntax either in a systemConfig plugin, or as an inline script. (Substitute true/false values as desired):\n{{{config.checkbox.refresh = { tagged:true, tagging:true, container:true };}}}\n\nYou can also override these defaults for any given checkbox by using an initialization function to set one or more of the refresh options. For example:\n{{{[_{this.refresh.container=false}]}}}\n<<<\n!!!!!Examples\n<<<\n//{{{\n[X] label\n[_] label\n//}}}\n>checked and unchecked static default values\n>[X] label\n>[_] label\n//{{{\n[_=demo] label\n//}}}\n>document-based value (id='demo', no cookie)\n>[_=demo] label\n//{{{\n[_=chkDemo] label\n//}}}\n>cookie-based value (id='chkDemo')\n>[_=chkDemo] label\n//{{{\n[_(CheckboxPlugin|demotag)]\n[_(CheckboxPlugin|demotag){this.refresh.tagged=this.refresh.container=false}]\n//}}}\n>tag-based value (TogglyTagging)\n>[_(CheckboxPlugin|demotag)] toggle 'demotag' (and refresh tiddler display)\n>[_(CheckboxPlugin|demotag){this.refresh.tagged=this.refresh.container=false}] toggle 'demotag' (no refresh)\n>current tags: <script>return store.getTiddler(story.findContainingTiddler(place).id.substr(7)).tags.toString();</script>\n><script label="click to view current tags">alert(store.getTiddler(story.findContainingTiddler(place).id.substr(7)).tags.toString());return false</script>\n//{{{\n[X{this.checked=true}{alert(this.checked?"on":"off")}] message box with checkbox state\n//}}}\n>custom init and onClick functions\n>[X{this.checked=true}{alert(this.checked?"on":"off")}] message box with checkbox state\nRetrieving option values:\nconfig.options['demo']=<script>return config.options['demo']?"true":"false";</script>\nconfig.options['chkDemo']=<script>return config.options['chkDemo']?"true":"false";</script>\n\n!!!!!Installation\nimport (or copy/paste) the following tiddlers into your document:\n''CheckboxPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n2006.05.04 - 2.1.3 fix use of findContainingTiddler() to check for a non-null return value, so that checkboxes won't crash when used outside of tiddler display context (such as in header, sidebar or mainmenu)\n2006.03.11 - 2.1.2 added "|" as delimiter to tag-based storage syntax (e.g. "tiddler|tag") to avoid parsing ambiguity when tiddler titles or tag names contain ":". Using ":" as a delimiter is still supported but is deprecated in favor of the new "|" usage. Based on a problem reported by JeffMason.\n2006.02.25 - 2.1.0 added configuration options to enable/disable forced refresh of tiddlers when toggling tags\n2006.02.23 - 2.0.4 when toggling tags, force refresh of the tiddler containing the checkbox.\n2006.02.23 - 2.0.3 when toggling tags, force refresh of the 'tagged tiddler' so that tag-related tiddler content (such as "to-do" lists) can be re-rendered.\n2006.02.23 - 2.0.2 when using tag-based storage, allow use [[ and ]] to quote tiddler or tag names that contain spaces:\n{{{[x([[Tiddler with spaces]]:[[tag with spaces]])]}}}\n2006.01.10 - 2.0.1 when toggling tags, force refresh of the 'tagging tiddler'. For example, if you toggle the "systemConfig" tag on a plugin, the corresponding "systemConfig" TIDDLER will be automatically refreshed (if currently displayed), so that the 'tagged' list in that tiddler will remain up-to-date.\n2006.01.04 - 2.0.0 update for ~TW2.0\n2005.12.27 - 1.1.2 Fix lookAhead regExp handling for {{{[x=id]}}}, which had been including the "]" in the extracted ID. \nAdded check for "chk" prefix on ID before calling saveOptionCookie()\n2005.12.26 - 1.1.2 Corrected use of toUpperCase() in tiddler re-write code when comparing {{{[X]}}} in tiddler content with checkbox state. Fixes a problem where simple checkboxes could be set, but never cleared.\n2005.12.26 - 1.1.0 Revise syntax so all optional parameters are included INSIDE the [ and ] brackets. Backward compatibility with older syntax is supported, so content changes are not required when upgrading to the current version of this plugin. Based on a suggestion by GeoffSlocock\n2005.12.25 - 1.0.0 added support for tracking checkbox state using tags ("TogglyTagging")\nRevised version number for official post-beta release.\n2005.12.08 - 0.9.3 support separate 'init' and 'onclick' function definitions.\n2005.12.08 - 0.9.2 clean up lookahead pattern\n2005.12.07 - 0.9.1 only update tiddler source content if checkbox state is actually different. Eliminates unnecessary tiddler changes (and 'unsaved changes' warnings)\n2005.12.07 - 0.9.0 initial BETA release\n<<<\n!!!!!Credits\n<<<\nThis feature was created by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.CheckboxPlugin = {major: 2, minor: 1, revision:3 , date: new Date(2006,5,4)};\n//}}}\n\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n//{{{\nconfig.checkbox = { refresh: { tagged:true, tagging:true, container:true } };\nconfig.formatters.push( {\n name: "checkbox",\n match: "\s\s[[xX_ ][\s\s]\s\s=\s\s(\s\s{]",\n lookahead: "\s\s[([xX_ ])(\s\s])?(=[^\s\ss\s\s(\s\s]{]+)?(\s\s([^\s\s)]*\s\s))?({[^}]*})?({[^}]*})?(\s\s])?",\n handler: function(w)\n {\n var lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n {\n // get params\n var checked=lookaheadMatch[1];\n var id=lookaheadMatch[3];\n var tag=lookaheadMatch[4];\n var fn_init=lookaheadMatch[5];\n var fn_click=lookaheadMatch[6];\n // create checkbox element\n var c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick=onClickCheckbox;\n c.srcpos=w.matchStart+1; // remember location of "X"\n c.container=story.findContainingTiddler(w.output); if (c.container) c.container=c.container.id.substr(7); // tiddler containing checkbox\n c.refresh = { };\n c.refresh.container=config.checkbox.refresh.container;\n c.refresh.tagged=config.checkbox.refresh.tagged;\n c.refresh.tagging=config.checkbox.refresh.tagging;\n w.output.appendChild(c);\n // set default state\n c.checked=(checked.toUpperCase()=="X");\n // get/set state by ID\n if (id) {\n c.id=id.substr(1); // trim off leading "="\n if (config.options[c.id]!=undefined)\n c.checked=config.options[c.id];\n else\n config.options[c.id]=c.checked;\n }\n // get/set state by tag\n if (tag) {\n c.tiddler=c.container;\n c.tag=tag.substr(1,tag.length-2).trim(); // trim off parentheses\n var pos=c.tag.indexOf("|"); if (pos==-1) var pos=c.tag.indexOf(":");\n if (pos==0) { c.tag=tag.substr(1); }\n if (pos>0) { c.tiddler=c.tag.substr(0,pos).replace(/\s[\s[/g,"").replace(/\s]\s]/g,""); c.tag=c.tag.substr(pos+1); }\n c.tag.replace(/\s[\s[/g,"").replace(/\s]\s]/g,"");\n if (!c.tag.length) c.tag="checked";\n var t=store.getTiddler(c.tiddler);\n c.checked = (t && t.tags)?(t.tags.find(c.tag)!=null):false;\n }\n if (fn_init) c.fn_init=fn_init.trim().substr(1,fn_init.length-2); // trim off surrounding { and } delimiters\n if (fn_click) c.fn_click=fn_click.trim().substr(1,fn_click.length-2);\n c.init=true; c.onclick(); c.init=false; // compute initial state and save in tiddler/config/cookie\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n }\n)\n//}}}\n\n//{{{\nfunction onClickCheckbox()\n{\n if (this.fn_init)\n // custom function hook to set initial state (run only once)\n { try { eval(this.fn_init); this.fn_init=null; } catch(e) { displayMessage("Checkbox init error: "+e.toString()); } }\n else if (this.fn_click)\n // custom function hook to override or react to changes in checkbox state\n { try { eval(this.fn_click) } catch(e) { displayMessage("Checkbox click error: "+e.toString()); } }\n if (this.id)\n // save state in config AND cookie (only when ID starts with 'chk')\n { config.options[this.id]=this.checked; if (this.id.substr(0,3)=="chk") saveOptionCookie(this.id); }\n if ((!this.id || this.id.substr(0,3)!="chk") && !this.tag) {\n // save state in tiddler content only if not using cookie or tag tracking\n var t=story.findContainingTiddler(this); if (t) {\n var t=store.getTiddler(t.id.substr(7));\n if (this.checked!=(t.text.substr(this.srcpos,1).toUpperCase()=="X")) { // if changed\n t.set(null,t.text.substr(0,this.srcpos)+(this.checked?"X":"_")+t.text.substr(this.srcpos+1),null,null,t.tags);\n store.setDirty(true);\n }\n }\n }\n if (this.tag) {\n var t=store.getTiddler(this.tiddler);\n if (!t) { t=(new Tiddler()); t.set(this.tiddler,"",config.options.txtUserName,(new Date()),null); store.addTiddler(t); } \n var tagged=(t.tags && t.tags.find(this.tag)!=null);\n if (this.checked && !tagged) { t.tags.push(this.tag); store.setDirty(true); }\n if (!this.checked && tagged) { t.tags.splice(t.tags.find(this.tag),1); store.setDirty(true); }\n // if tag state has been changed, force a display update\n if (this.checked!=tagged) {\n if (this.refresh.tagged) story.refreshTiddler(this.tiddler,null,true); // the TAGGED tiddler\n if (this.refresh.tagging) story.refreshTiddler(this.tag,null,true); // the TAGGING tiddler\n }\n }\n // refresh containing tiddler (but not during initial rendering, or we get an infinite loop!)\n if (!this.init && this.refresh.container && this.container!=this.tiddler)\n story.refreshTiddler(this.container,null,true); // the tiddler CONTAINING the checkbox\n return true;\n}\n//}}}
/***\n| Name|CloseOnCancelPlugin|\n| Description|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|\n| Version|3.0 ($Rev: 1845 $)|\n| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source|http://mptw.tiddlyspot.com/#CloseOnCancelPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\nmerge(config.commands.cancelTiddler,{\n\n handler_orig_closeUnsaved: config.commands.cancelTiddler.handler,\n\n handler: function(event,src,title) {\n this.handler_orig_closeUnsaved(event,src,title);\n if (!store.tiddlerExists(title) && !store.isShadowTiddler(title))\n story.closeTiddler(title,true);\n return false;\n }\n\n});\n\n//}}}\n\n
/***\n|Name|CollapseTiddlersPlugin|\n|Source|http://gensoft.revhost.net/Collapse.html|\n|Version|0.0.0|\n|Author|Bradley Meck|\n|License|unknown|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires|CollapsedTemplate|\n|Overrides||\n|Description|show/hide content of a tiddler while leaving tiddler title visible|\n\n|ELS 2/24/2006: added fallback to "CollapsedTemplate" if "WebCollapsedTemplate" is not found |\n|ELS 2/6/2006: added check for 'readOnly' flag to use alternative "WebCollapsedTemplate" |\n\n***/\n\nconfig.commands.collapseTiddler = {\ntext: "fold",\ntooltip: "Collapse this tiddler",\nhandler: function(event,src,title)\n{\nvar e = story.findContainingTiddler(src);\nif(e.getAttribute("template") != config.tiddlerTemplates[DEFAULT_EDIT_TEMPLATE]){\nvar t = (readOnly&&store.tiddlerExists("WebCollapsedTemplate"))?"WebCollapsedTemplate":"CollapsedTemplate";\nif (!store.tiddlerExists(t)) { alert("Can't find 'CollapsedTemplate'"); return; }\nif(e.getAttribute("template") != t ){\ne.setAttribute("oldTemplate",e.getAttribute("template"));\nstory.displayTiddler(null,title,t);\n}\n}\n}\n}\n\nconfig.commands.expandTiddler = {\ntext: "unfold",\ntooltip: "Expand this tiddler",\nhandler: function(event,src,title)\n{\nvar e = story.findContainingTiddler(src);\nstory.displayTiddler(null,title,e.getAttribute("oldTemplate"));\n}\n}\n\nconfig.macros.collapseAll = {\nhandler: function(place,macroName,params,wikifier,paramString,tiddler){\ncreateTiddlyButton(place,"Collapse All","",function(){\nstory.forEachTiddler(function(title,tiddler){\nif(tiddler.getAttribute("template") != config.tiddlerTemplates[DEFAULT_EDIT_TEMPLATE])\nvar t = (readOnly&&store.tiddlerExists("WebCollapsedTemplate"))?"WebCollapsedTemplate":"CollapsedTemplate";\nif (!store.tiddlerExists(t)) { alert("Can't find 'CollapsedTemplate'"); return; }\nstory.displayTiddler(null,title,t);\n})})\n}\n}\n\nconfig.macros.expandAll = {\nhandler: function(place,macroName,params,wikifier,paramString,tiddler){\ncreateTiddlyButton(place,"Expand All","",function(){\nstory.forEachTiddler(function(title,tiddler){\nvar t = (readOnly&&store.tiddlerExists("WebCollapsedTemplate"))?"WebCollapsedTemplate":"CollapsedTemplate";\nif (!store.tiddlerExists(t)) { alert("Can't find 'CollapsedTemplate'"); return; }\nif(tiddler.getAttribute("template") == t) story.displayTiddler(null,title,tiddler.getAttribute("oldTemplate"));\n})})\n}\n}\n\nconfig.commands.collapseOthers = {\ntext: "focus",\ntooltip: "Expand this tiddler and collapse all others",\nhandler: function(event,src,title)\n{\nvar e = story.findContainingTiddler(src);\nstory.forEachTiddler(function(title,tiddler){\nif(tiddler.getAttribute("template") != config.tiddlerTemplates[DEFAULT_EDIT_TEMPLATE]){\nvar t = (readOnly&&store.tiddlerExists("WebCollapsedTemplate"))?"WebCollapsedTemplate":"CollapsedTemplate";\nif (!store.tiddlerExists(t)) { alert("Can't find 'CollapsedTemplate'"); return; }\nif (e==tiddler) t=e.getAttribute("oldTemplate");\n//////////\n// ELS 2006.02.22 - removed this line. if t==null, then the *current* view template, not the default "ViewTemplate", will be used.\n// if (!t||!t.length) t=!readOnly?"ViewTemplate":"WebViewTemplate";\n//////////\nstory.displayTiddler(null,title,t);\n}\n})\n}\n}
<!--{{{-->\n<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 1830 $) --->\n\n<div class='toolbar'>\n <span macro="showWhenTagged systemConfig">\n <span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>\n </span>\n <span style="padding:1em;"></span>\n <span style="padding-right:2.45em;" macro='tagger'></span>\n <span class='toolbar' macro='toolbar expandTiddler collapseOthers'></span>\n <span macro='toolbar closeTiddler closeOthers fullscreen +editTiddler deleteTiddler undoChanges permalink references jump revision'></span>\n <span macro='newHere label:"new here"'></span>\n <span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:"MM/0DD/YY"}}'></span>\n</div>\n\n<div class="tagglyTagged" macro="tags"></div>\n\n<div class='titleContainer'>\n <span class='title' macro='view title'></span>\n <span macro="miniTag"></span>\n</div>\n\n<div class='subtitle'>\n <span macro='view modifier link'></span>,\n <span macro='view modified date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>\n (<span macro='message views.wikified.createdPrompt'></span>\n <span macro='view created date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>)\n</div>\n\n<!--}}}-->\n
Background: #fff\nForeground: #000\nPrimaryPale: #9cf\nPrimaryLight: #18f\nPrimaryMid: #04b\nPrimaryDark: #014\nSecondaryPale: #ffc\nSecondaryLight: #fe8\nSecondaryMid: #db4\nSecondaryDark: #841\nTertiaryPale: #eee\nTertiaryLight: #ccc\nTertiaryMid: #999\nTertiaryDark: #666\nError: #f88\n
<!--{{{-->\n<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></div>\n<div class='title' macro='view title'></div>\n<div class='editor' macro='edit tags' style='display:none;'></div>\n<div class='GuestSign' >\n 請簽名:<span macro='option txtUserName'></span>(暱稱,任何語文皆可)<br />留言內容:</div>\n<div class='editor' macro='edit text'></div>\n<!--}}}-->
/***\n|''Name:''|CommentPlugin|\n|''Source:''| |\n|''Author:''|Tim Morgan (modified by Bram Chen|\n|''Desc:''|''Adds "comments" to any TiddlyWiki or adaptation.''|\n| |Used in conjunction with the RecentPlugin, one can have a decent forum environment.|\n\n''Translation sample 1:''\n{{{\nconfig.CommentPlugin.CPlingo = {\n dateFormat: "YYYY年0MM月0DD日 0hh:0mm:0ss",\n CommentInTitle: " 迴響 ",\n comments:"迴響",\n add:"回應 U+00BB.",\n edit:"編輯",\n tooltips:"發表關於此文的相關意見",\n Title: "%0 迴響 %1",\n CommenteditTemplate: {yourName: "請簽名:", nickName: "(中英文暱稱)", comments: "留言內容:"}\n};\n}}}\n''Translation sample 2:''\n{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips:" Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n };\n}}}\n\n''Revision history:''\n* v0.7.0 (Nov 09, 2006)\n** Minor changes, more easier to be translated (Bram)\n* v0.6.0 (Nov 09, 2006)\n** Runs compatibly with TW 2.1.0+ (Bram)\n* v0.5.0 (Jun 15, 2006)\n** Fixed bug for feature of CommentEditTemplate (bug reported by MilchFlasche, fixed by Bram)\n** Fixed bug in redefined TiddlyWiki.prototype.saveTiddler (Bram)\n* v0.4.0 (Jun 03, 2006) Added CommentEditTemplate (Bram)\n* v0.3.0 (Jun 01, 2006) Some minor changes for readOnly mode (Bram)\n* v0.2.0 (Apr 04, 2006) Fixed bug for only_on_tags (Bram)\n* v0.1.0 (Mar 13, 2006) Modified by Bram Chen.\n***/\n// //''Code section:''\n//{{{\nconfig.CommentPlugin = {\n CPlingo:{\n dateFormat: "DD MMM YYYY 0hh:0mm:0ss",\n CommentInTitle: " Comment ",\n comments: "comments",\n add: "New Comment Here...",\n edit: "Edit",\n tooltips:" Create a new comment tiddler associated with this tiddler",\n Title: "%0 Comment %1",\n CommenteditTemplate: {yourName: "Your Name: ", nickName: "(nick name)", comments: "Comment: "}\n },\n only_on_tags: ['Public'],\n not_on_tags: ['about'],\n // "true" or "false"...\n fold_comments: true,\n default_fold: true,\n max_comment_count: 500\n};\n\nvar CPlingo = config.CommentPlugin.CPlingo;\nconfig.CommentPlugin.only_on_tags.push(CPlingo.comments);\n\nfunction in_array(item, arr){\n for(var i=0;i<arr.length;i++){\n if(item==arr[i]) {return true;}\n }\n};\n\nfunction one_in_array(items, arr){\n for(var i=0;i<items.length;i++){\n if(in_array(items[i], arr)){return true;}\n }\n return false\n};\n\nfunction get_parent(tiddler){\n while(in_array(CPlingo.comments, tiddler.tags)){\n tiddler=store.fetchTiddler(tiddler.tags[0]);\n }\n return tiddler\n};\n\nfunction count_comments(title){\n var tagged=store.getTaggedTiddlers(title);\n var count=0;\n for(var i=0;i<tagged.length;i++){\n if(in_array(CPlingo.comments, tagged[i].tags)){\n count+=count_comments(tagged[i].title)+1;\n }\n }\n return count\n};\nconfig.shadowTiddlers.ViewTemplate += "\sn<div class='comments' macro='comments'></div>";\n\nconfig.shadowTiddlers.CommentEditTemplate="<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></div><div class='title' macro='view title'></div><div class='editor' macro='edit tags' style='display:none;'></div><div class='GuestSign' >" + CPlingo.CommenteditTemplate.yourName + "<span macro='option txtUserName'></span>" + CPlingo.CommenteditTemplate.nickName + "<br />" + CPlingo.CommenteditTemplate.comments + "</div><div class='editor' macro='edit text'></div>";\nconfig.tiddlerTemplates[3]="CommentEditTemplate";\nvar COMMENT_EDIT_TEMPLATE = 3;\n\nconfig.shadowTiddlers.CommentPluginStyle = '\sn/*{{{*/\sn.commentTags ul{list-style:none; padding-left:0px;margin: 0 0 3px 0;} .commentTags li{display:inline;color:#999;} .commentTags li a.button{color:#999;} .comment{border-left:1px solid #ccc; margin-top:10px; margin-left:10px; padding:5px;} .newCommentLink{padding-top:10px} .tagging, .selected .tagging, .tiddler .tagging{display:none;} .comment a.button{padding:0px; font-size:smaller;}\sn/*}}}*/';\nconfig.shadowTiddlers.StyleSheet += config.shadowTiddlers.CommentPluginStyle;\nconfig.macros.newCommentLink = {\n label: CPlingo.add,\n prompt: CPlingo.tooltips,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler && store.tiddlerExists(tiddler.title) && !readOnly && (!window.zw || zw.loggedIn || zw.anonEdit)) {\n if(config.CommentPlugin.only_on_tags.length>0 && !one_in_array(tiddler.tags, config.CommentPlugin.only_on_tags)) return;\n if(config.CommentPlugin.not_on_tags.length>0 && one_in_array(tiddler.tags, config.CommentPlugin.not_on_tags)) return;\n var onclick = function(e) {\n var e = (e)?e:window.event;\n var theTarget = resolveTarget(e);\n var titlex=tiddler.title.split(CPlingo.CommentInTitle)[0];\n var title = (tiddler.title.indexOf(CPlingo.CommentInTitle)!=-1)? titlex : tiddler.title;\n title = CPlingo.Title.format([title,(new Date()).formatString(CPlingo.dateFormat)]);\n var comment = store.createTiddler(title);\n comment.text = '';\n comment.tags = [tiddler.title, CPlingo.comments, 'excludeLists'];\n readOnly = false;\n story.displayTiddler(theTarget, title, COMMENT_EDIT_TEMPLATE);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n story.focusTiddler(title,"text");\n return false;\n }\n createTiddlyButton(place, this.label, this.prompt, onclick);\n }\n }\n};\nconfig.macros.comments = {\n dateFormat: CPlingo.dateFormat,\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n if(tiddler.title==CPlingo.comments) return;\n var comments = store.getTaggedTiddlers(tiddler.title, 'created');\n var count = count_comments(tiddler.title);\n if(comments.length>0 && !in_array(CPlingo.comments, tiddler.tags) && config.CommentPlugin.fold_comments) {\n var show = createTiddlyElement(place, 'p');\n show.innerHTML = '<a href="#" onclick="var e=document.getElementById(\s'comments'+tiddler.title+'\s');e.style.display=e.style.display==\s'block\s'?\s'none\s':\s'block\s';return false;">' + CPlingo.comments +'('+count+') »</a>';\n }\n var place = createTiddlyElement(place, 'div', 'comments'+tiddler.title, 'comments');\n if(comments.length>0 && !in_array(CPlingo.comments, tiddler.tags) && config.CommentPlugin.fold_comments && config.CommentPlugin.default_fold)\n place.style.display = 'none';\n else\n place.style.display = 'block';\n for(var i=0; i<comments.length; i++) {\n if(!in_array(CPlingo.comments, comments[i].tags))continue;\n var container = createTiddlyElement(place, 'div', null, 'comment');\n var title = createTiddlyElement(container, 'strong');\n var link = createTiddlyLink(title, comments[i].modifier, true);\n createTiddlyElement(title, 'span', null, null, ', '+comments[i].created.formatString(this.dateFormat));\n/* -- remove editable option for security concern\n if(comments[i].modifier == config.options.txtUserName) {\n createTiddlyElement(title, 'span', null, null, ' (');\n var edit = createTiddlyLink(title, comments[i].title);\n edit.innerHTML = CPlingo.edit;\n createTiddlyElement(title, 'span', null, null, ')');\n }\n*/\n wikify('\sn'+comments[i].text+'\sn',container);\n config.macros.comments.handler(container,null,null,null,null,comments[i]);\n }\n readOnly = false;\n config.macros.newCommentLink.handler(place,null,null,null,null,tiddler);\n// wikify('<'+'<newCommentLink>>',place);\n readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;\n }\n};\nvar CPCloseTiddlers = [];\nTiddlyWiki.prototype.CommentPlugin_saveTiddler = TiddlyWiki.prototype.saveTiddler;\nTiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n tags=(typeof tags == "string") ? tags.readBracketedList() : tags;\n if(in_array(CPlingo.comments, tags)){\n newBody=newBody.htmlDecode(); // comment this line, for working with HTMLAreaPackage\n newBody=newBody.substr(0,config.CommentPlugin.max_comment_count);\n newBody=newBody.htmlEncode(); // comment this line, for working with HTMLAreaPackage\n }\n var t = this.CommentPlugin_saveTiddler(title,newTitle,newBody,modifier,modified,tags);\n if(in_array(CPlingo.comments, tags)) {\n var original = config.CommentPlugin.default_fold;\n config.CommentPlugin.default_fold = false;\n story.refreshTiddler(get_parent(t).title, DEFAULT_VIEW_TEMPLATE, true);\n config.CommentPlugin.default_fold = original;\n CPCloseTiddlers.push(newTitle);\n setTimeout("story.closeTiddler(CPCloseTiddlers.pop(), true)", 500);\n }\n return t;\n};\nStory.prototype.chooseTemplateForTiddler = function(title,template)\n{\n if(!template)\n template = DEFAULT_VIEW_TEMPLATE;\n if(template == DEFAULT_VIEW_TEMPLATE\n || template == DEFAULT_EDIT_TEMPLATE\n || template == COMMENT_EDIT_TEMPLATE)\n template = config.tiddlerTemplates[template];\n return template;\n};\n//}}}
/***\n!CommentPlugin.zh-Hant\nNote: CommentPlugin 0.7.0+ modified by BramChen is required.\n***/\n//{{{\nif (typeof config.CommentPlugin != 'undefined'){\n merge(config.CommentPlugin.CPlingo, {\n dateFormat: "YYYY年0MM月0DD日 0hh:0mm:0ss",\n CommentInTitle: " 迴響 ",\n comments:"迴響",\n add:"回應 »",\n edit:"編輯",\n tooltips:"發表關於此文的相關意見",\n Title: "%0 迴響 %1",\n CommenteditTemplate: {yourName: "請簽名:", nickName: "(中英文暱稱)", comments: "留言內容:"}\n });\n CPlingo = config.CommentPlugin.CPlingo;\n merge(config.macros.newCommentLink, {\n label: CPlingo.add,\n prompt: CPlingo.tooltips\n });\n merge(config.macros.comments, {\n dateFormat: CPlingo.dateFormat\n });\nconfig.CommentPlugin.only_on_tags.push(CPlingo.comments);\nconfig.shadowTiddlers.CommentEditTemplate="<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler wikibar'></div><div class='title' macro='view title'></div><div class='editor' macro='edit tags' style='display:none;'></div><div class='GuestSign' >" + CPlingo.CommenteditTemplate.yourName + "<span macro='option txtUserName'></span>" + CPlingo.CommenteditTemplate.nickName + "<br />" + CPlingo.CommenteditTemplate.comments + "</div><div class='editor' macro='edit text'></div>";\n}\n//}}}
\n/*{{{*/\n.commentTags ul{list-style:none; padding-left:0px;margin: 0 0 3px 0;} .commentTags li{display:inline;color:#999;} .commentTags li a.button{color:#999;} .comment{border-left:1px solid #ccc; margin-top:10px; margin-left:10px; padding:5px;} .newCommentLink{padding-top:10px} .tagging, .selected .tagging, .tiddler .tagging{display:none;} .comment a.button{padding:0px; font-size:smaller;}\n/*}}}*/
/***\n!CommentTabPlugin.zh-Hant\nNote: CommentPlugin and CommentTabPlugin modified by BramChen is required.\n***/\n//{{{\nif (typeof config.macros.tiddlerComments != 'undefined'){\n config.shadowTiddlers.TabTimeline = "<<tabs txtTimelineTab 文章 最近更新的文章 TabTimelineTiddlers " + config.CommentPlugin.CPlingo.comments + " 最近的回應" + ' TabTimelineComments>>';\n config.macros.tiddlerComments.dateFormat = "YYYY年0MM月0DD日";\n}\n//}}}
//''Breaks the Timeline tab into "Tiddlers" and "Comments".''//\n//Makes sense with the CommentPlugin.//\n\n{{{\nfunction in_array(item, arr){for(var i=0;i<arr.length;i++)if(item==arr[i])return true};\nfunction get_parent(tiddler){while(tiddler && in_array(config.CommentPlugin.CPlingo.comments, tiddler.tags)) tiddler=store.fetchTiddler(tiddler.tags[0]);return tiddler};\nconfig.options.txtTimelineTab = 'timelineTab'; // huh?\nconfig.shadowTiddlers.TabTimelineTiddlers = config.shadowTiddlers.TabTimeline;\nconfig.shadowTiddlers.TabTimeline = "<<tabs txtTimelineTab Tiddlers Tiddlers TabTimelineTiddlers "+ config.CommentPlugin.CPlingo.comments + config.CommentPlugin.CPlingo.CommentInTitle + " TabTimelineComments>>";\nconfig.shadowTiddlers.TabTimelineComments = "<<tiddlerComments>>";\n\nconfig.macros.tiddlerComments = {\n dateFormat: 'DD MMM YYYY',\n handler: function(place,macroName,params)\n {\n var field = params[0] ? params[0] : "modified";\n var comments = store.reverseLookup("tags",CPlingo.comments,true,field);\n var lastDay = "";\n for (var c=comments.length-1; c>=0; c--)\n {\n if(comments[c].tags.length == 0) continue;\n var tiddler = get_parent(comments[c]);\n if(!tiddler) continue;\n var theDay = comments[c][field].convertToLocalYYYYMMDDHHMM().substr(0,8);\n if(theDay != lastDay)\n {\n var theDateList = document.createElement("ul");\n place.appendChild(theDateList);\n createTiddlyElement(theDateList,"li",null,"listTitle",comments[c][field].formatString(this.dateFormat));\n lastDay = theDay;\n }\n var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);\n var link = createTiddlyLink(place,comments[c].title);\n link.innerHTML = comments[c].modifier + ' on ' + tiddler.title;\n link.setAttribute("tiddlyLink",tiddler.title);\n theDateListItem.appendChild(link);\n }\n }\n};\n}}}
//{{{\nconfig.options.chkHttpReadOnly = false; // means web visitors can experiment with your site by clicking edit\nconfig.options.chkInsertTabs = true; // tab inserts a tab when editing a tiddler\nconfig.views.wikified.defaultText = ""; // don't need message when a tiddler doesn't exist\nconfig.views.editor.defaultText = ""; // don't need message when creating a new tiddler \n//}}}\n
/***\n|''Name:''|DataTiddlerPlugin|\n|''Version:''|1.0.6 (2006-08-26)|\n|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|\n|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|\n|''Licence:''|[[BSD open source license]]|\n|''TiddlyWiki:''|1.2.38+, 2.0|\n|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|\n!Description\nEnhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).\n\nSuch tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers. \n\n''//Example: "Table with all December Expenses"//''\n{{{\n<<forEachTiddler\n where\n 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'\n write\n '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\sn"'\n>>\n}}}\n//(This assumes that expenses are stored in tiddlers tagged with "expense".)//\n<<forEachTiddler\n where\n 'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'\n write\n '"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\sn"'\n>>\nFor other examples see DataTiddlerExamples.\n\n\n\n\n''Access and Modify Tiddler Data''\n\nYou can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields. \n\nThese values can be accessed and modified through the following Tiddler methods:\n|!Method|!Example|!Description|\n|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|\n|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|\n|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|\n|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|\n|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|\n\nAlternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.\n|!Method|!Description|\n|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|\n|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|\n|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|\n|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|\n|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|\n//(For details on the various functions see the detailed comments in the source code.)//\n\n\n''Data Representation in a Tiddler''\n\nThe data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]]. \n\n//''Data Section Example:''//\n{{{\n<data>{"isVIP":true,"user":"John Brown","age":34}</data>\n}}}\n\nThe data section is not displayed when viewing the tiddler (see also "The showData Macro").\n\nBeside the data section a tiddler may have all kind of other content.\n\nTypically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.\n\n\n''Saving Changes''\n\nThe "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.\n\n\n''Notifications''\n\nNo notifications are sent when a tiddler's data value is changed through the "setData" methods. \n\n''Escape Data Section''\nIn case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.\n\n\n''The showData Macro''\n\nBy default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:\n\n''Syntax:'' \n|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|\n|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|\n|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|\n|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|\n\n\n!Revision history\n* v1.0.6 (2006-08-26) \n** Removed misleading comment\n* v1.0.5 (2006-02-27) (Internal Release Only)\n** Internal\n*** Make "JSLint" conform\n* v1.0.4 (2006-02-05)\n** Bugfix: showData fails in TiddlyWiki 2.0\n* v1.0.3 (2006-01-06)\n** Support TiddlyWiki 2.0\n* v1.0.2 (2005-12-22)\n** Enhancements:\n*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.\n*** Improved (JSON) error messages.\n** Bugs fixed: \n*** References are not updated when using the DataTiddler.\n*** Changes to compound objects are not always saved.\n*** "~</data>" is not rendered correctly (expected "</data>")\n* v1.0.1 (2005-12-13)\n** Features: \n*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed\n** Bugs fixed: \n*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)\n* v1.0.0 (2005-12-12)\n** initial version\n\n!Code\n***/\n//{{{\n//============================================================================\n//============================================================================\n// DataTiddlerPlugin\n//============================================================================\n//============================================================================\n\n// Ensure that the DataTiddler Plugin is only installed once.\n//\nif (!version.extensions.DataTiddlerPlugin) {\n\n\n\nversion.extensions.DataTiddlerPlugin = {\n major: 1, minor: 0, revision: 6,\n date: new Date(2006, 7, 26), \n type: 'plugin',\n source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"\n};\n\n// For backward compatibility with v1.2.x\n//\nif (!window.story) window.story=window; \nif (!TiddlyWiki.prototype.getTiddler) {\n TiddlyWiki.prototype.getTiddler = function(title) { \n var t = this.tiddlers[title]; \n return (t !== undefined && t instanceof Tiddler) ? t : null; \n };\n}\n\n//============================================================================\n// DataTiddler Class\n//============================================================================\n\n// ---------------------------------------------------------------------------\n// Configurations and constants \n// ---------------------------------------------------------------------------\n\nfunction DataTiddler() {\n}\n\nDataTiddler = {\n // Function to stringify a JavaScript value, producing the text for the data section content.\n // (Must match the implementation of DataTiddler.parse.)\n //\n stringify : null,\n \n\n // Function to parse the text for the data section content, producing a JavaScript value.\n // (Must match the implementation of DataTiddler.stringify.)\n //\n parse : null\n};\n\n// Ensure access for IE\nwindow.DataTiddler = DataTiddler;\n\n// ---------------------------------------------------------------------------\n// Data Accessor and Mutator\n// ---------------------------------------------------------------------------\n\n\n// Returns the value of the given data field of the tiddler.\n// When no such field is defined or its value is undefined\n// the defaultValue is returned.\n// \n// @param tiddler either a tiddler name or a tiddler\n//\nDataTiddler.getData = function(tiddler, field, defaultValue) {\n var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;\n if (!(t instanceof Tiddler)) {\n throw "Tiddler expected. Got "+tiddler;\n }\n\n return DataTiddler.getTiddlerDataValue(t, field, defaultValue);\n};\n\n\n// Sets the value of the given data field of the tiddler to\n// the value. When the value is equal to the defaultValue\n// no value is set (and the field is removed)\n//\n// Changing data of a tiddler will not trigger notifications.\n// \n// @param tiddler either a tiddler name or a tiddler\n//\nDataTiddler.setData = function(tiddler, field, value, defaultValue) {\n var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;\n if (!(t instanceof Tiddler)) {\n throw "Tiddler expected. Got "+tiddler+ "("+t+")";\n }\n\n DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);\n};\n\n\n// Returns the data object of the tiddler, with a property for every field.\n//\n// The properties of the returned data object may only be read and\n// not be modified. To modify the data use DataTiddler.setData(...) \n// or the corresponding Tiddler method.\n//\n// If no data section is defined a new (empty) object is returned.\n//\n// @param tiddler either a tiddler name or a Tiddler\n//\nDataTiddler.getDataObject = function(tiddler) {\n var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;\n if (!(t instanceof Tiddler)) {\n throw "Tiddler expected. Got "+tiddler;\n }\n\n return DataTiddler.getTiddlerDataObject(t);\n};\n\n// Returns the text of the content of the data section of the tiddler.\n//\n// When no data section is defined for the tiddler null is returned \n//\n// @param tiddler either a tiddler name or a Tiddler\n// @return [may be null]\n//\nDataTiddler.getDataText = function(tiddler) {\n var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;\n if (!(t instanceof Tiddler)) {\n throw "Tiddler expected. Got "+tiddler;\n }\n\n return DataTiddler.readDataSectionText(t);\n};\n\n\n// ---------------------------------------------------------------------------\n// Internal helper methods (must not be used by code from outside this plugin)\n// ---------------------------------------------------------------------------\n\n// Internal.\n//\n// The original JSONError is not very user friendly, \n// especially it does not define a toString() method\n// Therefore we extend it here.\n//\nDataTiddler.extendJSONError = function(ex) {\n if (ex.name == 'JSONError') {\n ex.toString = function() {\n return ex.name + ": "+ex.message+" ("+ex.text+")";\n };\n }\n return ex;\n};\n\n// Internal.\n//\n// @param t a Tiddler\n//\nDataTiddler.getTiddlerDataObject = function(t) {\n if (t.dataObject === undefined) {\n var data = DataTiddler.readData(t);\n t.dataObject = (data) ? data : {};\n }\n \n return t.dataObject;\n};\n\n\n// Internal.\n//\n// @param tiddler a Tiddler\n//\nDataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {\n var value = DataTiddler.getTiddlerDataObject(tiddler)[field];\n return (value === undefined) ? defaultValue : value;\n};\n\n\n// Internal.\n//\n// @param tiddler a Tiddler\n//\nDataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {\n var data = DataTiddler.getTiddlerDataObject(tiddler);\n var oldValue = data[field];\n \n if (value == defaultValue) {\n if (oldValue !== undefined) {\n delete data[field];\n DataTiddler.save(tiddler);\n }\n return;\n }\n data[field] = value;\n DataTiddler.save(tiddler);\n};\n\n// Internal.\n//\n// Reads the data section from the tiddler's content and returns its text\n// (as a String).\n//\n// Returns null when no data is defined.\n//\n// @param tiddler a Tiddler\n// @return [may be null]\n//\nDataTiddler.readDataSectionText = function(tiddler) {\n var matches = DataTiddler.getDataTiddlerMatches(tiddler);\n if (matches === null || !matches[2]) {\n return null;\n }\n return matches[2];\n};\n\n// Internal.\n//\n// Reads the data section from the tiddler's content and returns it\n// (as an internalized object).\n//\n// Returns null when no data is defined.\n//\n// @param tiddler a Tiddler\n// @return [may be null]\n//\nDataTiddler.readData = function(tiddler) {\n var text = DataTiddler.readDataSectionText(tiddler);\n try {\n return text ? DataTiddler.parse(text) : null;\n } catch(ex) {\n throw DataTiddler.extendJSONError(ex);\n }\n};\n\n// Internal.\n// \n// Returns the serialized text of the data of the given tiddler, as it\n// should be stored in the data section.\n//\n// @param tiddler a Tiddler\n//\nDataTiddler.getDataTextOfTiddler = function(tiddler) {\n var data = DataTiddler.getTiddlerDataObject(tiddler);\n return DataTiddler.stringify(data);\n};\n\n\n// Internal.\n// \nDataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {\n var index = s.indexOf(subString, startIndex);\n while ((index > 0) && (s[index-1] == '~')) { \n index = s.indexOf(subString, index+1);\n }\n return index;\n};\n\n// Internal.\n//\nDataTiddler.getDataSectionInfo = function(text) {\n // Special care must be taken to handle "<data>" and "</data>" texts inside\n // a data section. \n // Also take care not to use an escaped <data> (i.e. "~<data>") as the start \n // of a data section. (Same for </data>)\n\n // NOTE: we are explicitly searching for a data section that contains a JSON\n // string, i.e. framed with braces. This way we are little bit more robust in\n // case the tiddler contains unescaped texts "<data>" or "</data>". This must\n // be changed when using a different stringifier.\n\n var startTagText = "<data>{";\n var endTagText = "}</data>";\n\n var startPos = 0;\n\n // Find the first not escaped "<data>".\n var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);\n if (startDataTagIndex < 0) {\n return null;\n }\n\n // Find the *last* not escaped "</data>".\n var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);\n if (endDataTagIndex < 0) {\n return null;\n }\n var nextEndDataTagIndex;\n while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {\n endDataTagIndex = nextEndDataTagIndex;\n }\n\n return {\n prefixEnd: startDataTagIndex, \n dataStart: startDataTagIndex+(startTagText.length)-1, \n dataEnd: endDataTagIndex, \n suffixStart: endDataTagIndex+(endTagText.length)\n };\n};\n\n// Internal.\n// \n// Returns the "matches" of a content of a DataTiddler on the\n// "data" regular expression. Return null when no data is defined\n// in the tiddler content.\n//\n// Group 1: text before data section (prefix)\n// Group 2: content of data section\n// Group 3: text behind data section (suffix)\n//\n// @param tiddler a Tiddler\n// @return [may be null] null when the tiddler contains no data section, otherwise see above.\n//\nDataTiddler.getDataTiddlerMatches = function(tiddler) {\n var text = tiddler.text;\n var info = DataTiddler.getDataSectionInfo(text);\n if (!info) {\n return null;\n }\n\n var prefix = text.substr(0,info.prefixEnd);\n var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);\n var suffix = text.substr(info.suffixStart);\n \n return [text, prefix, data, suffix];\n};\n\n\n// Internal.\n//\n// Saves the data in a <data> block of the given tiddler (as a minor change). \n//\n// The "chkAutoSave" and "chkForceMinorUpdate" options are respected. \n// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.\n//\n// Notifications are not send. \n//\n// This method should only be called when the data really has changed. \n//\n// @param tiddler\n// the tiddler to be saved.\n//\nDataTiddler.save = function(tiddler) {\n\n var matches = DataTiddler.getDataTiddlerMatches(tiddler);\n\n var prefix;\n var suffix;\n if (matches === null) {\n prefix = tiddler.text;\n suffix = "";\n } else {\n prefix = matches[1];\n suffix = matches[3];\n }\n\n var dataText = DataTiddler.getDataTextOfTiddler(tiddler);\n var newText = \n (dataText !== null) \n ? prefix + "<data>" + dataText + "</data>" + suffix\n : prefix + suffix;\n if (newText != tiddler.text) {\n // make the change in the tiddlers text\n \n // ... see DataTiddler.MyTiddlerChangedFunction\n tiddler.isDataTiddlerChange = true;\n \n // ... do the action change\n tiddler.set(\n tiddler.title,\n newText,\n config.options.txtUserName, \n config.options.chkForceMinorUpdate? undefined : new Date(),\n tiddler.tags);\n\n // ... see DataTiddler.MyTiddlerChangedFunction\n delete tiddler.isDataTiddlerChange;\n\n // Mark the store as dirty.\n store.dirty = true;\n \n // AutoSave if option is selected\n if(config.options.chkAutoSave) {\n saveChanges();\n }\n }\n};\n\n// Internal.\n//\nDataTiddler.MyTiddlerChangedFunction = function() {\n // Remove the data object from the tiddler when the tiddler is changed\n // by code other than DataTiddler code. \n //\n // This is necessary since the data object is just a "cached version" \n // of the data defined in the data section of the tiddler and the \n // "external" change may have changed the content of the data section.\n // Thus we are not sure if the data object reflects the data section \n // contents. \n // \n // By deleting the data object we ensure that the data object is \n // reconstructed the next time it is needed, with the data defined by\n // the data section in the tiddler's text.\n \n // To indicate that a change is a "DataTiddler change" a temporary\n // property "isDataTiddlerChange" is added to the tiddler.\n if (this.dataObject && !this.isDataTiddlerChange) {\n delete this.dataObject;\n }\n \n // call the original code.\n DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);\n};\n\n\n//============================================================================\n// Formatters\n//============================================================================\n\n// This formatter ensures that "~<data>" is rendered as "<data>". This is used to \n// escape the "<data>" of a data section, just in case someone really wants to use\n// "<data>" as a text in a tiddler and not start a data section.\n//\n// Same for </data>.\n//\nconfig.formatters.push( {\n name: "data-escape",\n match: "~<\s\s/?data>",\n\n handler: function(w) {\n w.outputText(w.output,w.matchStart + 1,w.nextMatch);\n }\n} );\n\n\n// This formatter ensures that <data>...</data> sections are not rendered.\n//\nconfig.formatters.push( {\n name: "data",\n match: "<data>",\n\n handler: function(w) {\n var info = DataTiddler.getDataSectionInfo(w.source);\n if (info && info.prefixEnd == w.matchStart) {\n w.nextMatch = info.suffixStart;\n } else {\n w.outputText(w.output,w.matchStart,w.nextMatch);\n }\n }\n} );\n\n\n//============================================================================\n// Tiddler Class Extension\n//============================================================================\n\n// "Hijack" the changed method ---------------------------------------------------\n\nDataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;\nTiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;\n\n// Define accessor methods -------------------------------------------------------\n\n// Returns the value of the given data field of the tiddler. When no such field \n// is defined or its value is undefined the defaultValue is returned.\n//\n// When field is undefined (or null) the data object is returned. (See \n// DataTiddler.getDataObject.)\n//\n// @param field [may be null, undefined]\n// @param defaultValue [may be null, undefined]\n// @return [may be null, undefined]\n//\nTiddler.prototype.data = function(field, defaultValue) {\n return (field) \n ? DataTiddler.getTiddlerDataValue(this, field, defaultValue)\n : DataTiddler.getTiddlerDataObject(this);\n};\n\n// Sets the value of the given data field of the tiddler to the value. When the \n// value is equal to the defaultValue no value is set (and the field is removed).\n//\n// @param value [may be null, undefined]\n// @param defaultValue [may be null, undefined]\n//\nTiddler.prototype.setData = function(field, value, defaultValue) {\n DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);\n};\n\n\n//============================================================================\n// showData Macro\n//============================================================================\n\nconfig.macros.showData = {\n // Standard Properties\n label: "showData",\n prompt: "Display the values stored in the data section of the tiddler"\n};\n\nconfig.macros.showData.handler = function(place,macroName,params) {\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n // Parse the optional "JSON"\n var showInJSONFormat = false;\n if ((i < params.length) && params[i] == "JSON") {\n i++;\n showInJSONFormat = true;\n }\n \n var tiddlerName = story.findContainingTiddler(place).id.substr(7);\n if (i < params.length) {\n tiddlerName = params[i];\n i++;\n }\n\n // --- Processing ------------------------------------------\n try {\n if (showInJSONFormat) {\n this.renderDataInJSONFormat(place, tiddlerName);\n } else {\n this.renderDataAsTable(place, tiddlerName);\n }\n } catch (e) {\n this.createErrorElement(place, e);\n }\n};\n\nconfig.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {\n var text = DataTiddler.getDataText(tiddlerName);\n if (text) {\n createTiddlyElement(place,"pre",null,null,text);\n }\n};\n\nconfig.macros.showData.renderDataAsTable = function(place,tiddlerName) {\n var text = "|!Name|!Value|\sn";\n var data = DataTiddler.getDataObject(tiddlerName);\n if (data) {\n for (var i in data) {\n var value = data[i];\n text += "|"+i+"|"+DataTiddler.stringify(value)+"|\sn";\n }\n }\n \n wikify(text, place);\n};\n\n\n// Internal.\n//\n// Creates an element that holds an error message\n// \nconfig.macros.showData.createErrorElement = function(place, exception) {\n var message = (exception.description) ? exception.description : exception.toString();\n return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);\n};\n\n// ---------------------------------------------------------------------------\n// Stylesheet Extensions (may be overridden by local StyleSheet)\n// ---------------------------------------------------------------------------\n//\nsetStylesheet(\n ".showDataError{color: #ffffff;background-color: #880000;}",\n "showData");\n\n\n} // of "install only once"\n// Used Globals (for JSLint) ==============\n\n// ... TiddlyWiki Core\n/*global createTiddlyElement, saveChanges, store, story, wikify */\n// ... DataTiddler\n/*global DataTiddler */\n// ... JSON\n/*global JSON */\n \n\n/***\n!JSON Code, used to serialize the data\n***/\n/*\nCopyright (c) 2005 JSON.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the "Software"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe Software shall be used for Good, not Evil.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n/*\n The global object JSON contains two methods.\n\n JSON.stringify(value) takes a JavaScript value and produces a JSON text.\n The value must not be cyclical.\n\n JSON.parse(text) takes a JSON text and produces a JavaScript value. It will\n throw a 'JSONError' exception if there is an error.\n*/\nvar JSON = {\n copyright: '(c)2005 JSON.org',\n license: 'http://www.crockford.com/JSON/license.html',\n/*\n Stringify a JavaScript value, producing a JSON text.\n*/\n stringify: function (v) {\n var a = [];\n\n/*\n Emit a string.\n*/\n function e(s) {\n a[a.length] = s;\n }\n\n/*\n Convert a value.\n*/\n function g(x) {\n var c, i, l, v;\n\n switch (typeof x) {\n case 'object':\n if (x) {\n if (x instanceof Array) {\n e('[');\n l = a.length;\n for (i = 0; i < x.length; i += 1) {\n v = x[i];\n if (typeof v != 'undefined' &&\n typeof v != 'function') {\n if (l < a.length) {\n e(',');\n }\n g(v);\n }\n }\n e(']');\n return;\n } else if (typeof x.toString != 'undefined') {\n e('{');\n l = a.length;\n for (i in x) {\n v = x[i];\n if (x.hasOwnProperty(i) &&\n typeof v != 'undefined' &&\n typeof v != 'function') {\n if (l < a.length) {\n e(',');\n }\n g(i);\n e(':');\n g(v);\n }\n }\n return e('}');\n }\n }\n e('null');\n return;\n case 'number':\n e(isFinite(x) ? +x : 'null');\n return;\n case 'string':\n l = x.length;\n e('"');\n for (i = 0; i < l; i += 1) {\n c = x.charAt(i);\n if (c >= ' ') {\n if (c == '\s\s' || c == '"') {\n e('\s\s');\n }\n e(c);\n } else {\n switch (c) {\n case '\sb':\n e('\s\sb');\n break;\n case '\sf':\n e('\s\sf');\n break;\n case '\sn':\n e('\s\sn');\n break;\n case '\sr':\n e('\s\sr');\n break;\n case '\st':\n e('\s\st');\n break;\n default:\n c = c.charCodeAt();\n e('\s\su00' + Math.floor(c / 16).toString(16) +\n (c % 16).toString(16));\n }\n }\n }\n e('"');\n return;\n case 'boolean':\n e(String(x));\n return;\n default:\n e('null');\n return;\n }\n }\n g(v);\n return a.join('');\n },\n/*\n Parse a JSON text, producing a JavaScript value.\n*/\n parse: function (text) {\n var p = /^\ss*(([,:{}\s[\s]])|"(\s\s.|[^\sx00-\sx1f"\s\s])*"|-?\sd+(\s.\sd*)?([eE][+-]?\sd+)?|true|false|null)\ss*/,\n token,\n operator;\n\n function error(m, t) {\n throw {\n name: 'JSONError',\n message: m,\n text: t || operator || token\n };\n }\n\n function next(b) {\n if (b && b != operator) {\n error("Expected '" + b + "'");\n }\n if (text) {\n var t = p.exec(text);\n if (t) {\n if (t[2]) {\n token = null;\n operator = t[2];\n } else {\n operator = null;\n try {\n token = eval(t[1]);\n } catch (e) {\n error("Bad token", t[1]);\n }\n }\n text = text.substring(t[0].length);\n } else {\n error("Unrecognized token", text);\n }\n } else {\n token = operator = undefined;\n }\n }\n\n\n function val() {\n var k, o;\n switch (operator) {\n case '{':\n next('{');\n o = {};\n if (operator != '}') {\n for (;;) {\n if (operator || typeof token != 'string') {\n error("Missing key");\n }\n k = token;\n next();\n next(':');\n o[k] = val();\n if (operator != ',') {\n break;\n }\n next(',');\n }\n }\n next('}');\n return o;\n case '[':\n next('[');\n o = [];\n if (operator != ']') {\n for (;;) {\n o.push(val());\n if (operator != ',') {\n break;\n }\n next(',');\n }\n }\n next(']');\n return o;\n default:\n if (operator !== null) {\n error("Missing value");\n }\n k = token;\n next();\n return k;\n }\n }\n next();\n return val();\n }\n};\n\n/***\n!Setup the data serialization\n***/\n\nDataTiddler.format = "JSON";\nDataTiddler.stringify = JSON.stringify;\nDataTiddler.parse = JSON.parse;\n\n//}}}\n\n
/***\n|Name|DatePlugin|\n|Source|http://www.TiddlyTools.com/#DatePlugin|\n|Version|2.2.1|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description||\n\nThere are quite a few calendar generators, reminders, to-do lists, 'dated tiddlers' journals, blog-makers and GTD-like schedule managers that have been built around TW. While they all have different purposes, and vary in format, interaction, and style, in one way or another each of these plugins displays and/or uses date-based information to make finding, accessing and managing relevant tiddlers easier. This plugin provides a general approach to embedding dates and date-based links/menus within tiddler content.\n\nThis plugin display formatted dates, for the specified year, month, day using number values or mathematical expressions such as (Y+1) or (D+30). Optionally, you can create a link from the formatted output to a 'dated tiddler' for quick blogging or create a popup menu that includes the dated tiddler link plus links to changes made on that date as well as links to any pending reminders for the coming 31 days (if the RemindersPlugin is installed). This plugin also provides a public API for easily incorporating formatted date output (with or without the links/popups) into other plugins, such as calendar generators, etc.\n!!!!!Usage\n<<<\nWhen installed, this plugin defines a macro: {{{<<date [mode] [date] [format] [linkformat]>>}}}. All of the macro parameters are optional and, in it's simplest form, {{{<<date>>}}}, it is equivalent to the ~TiddlyWiki core macro, {{{<<today>>}}}.\n\nHowever, where {{{<<today>>}}} simply inserts the current date/time in a predefined format (or custom format, using {{{<<today [format]>>}}}), the {{{<<date>>}}} macro's parameters take it much further than that:\n* [mode] is either ''display'', ''link'' or ''popup''. If omitted, it defaults to ''display''. This param let's you select between simply displaying a formatted date, or creating a link to a specific 'date titled' tiddler or a popup menu containing a dated tiddler link, plus links to changes and reminders.\n* [date] lets you enter ANY date (not just today) as ''year, month, and day values or simple mathematical expressions'' using pre-defined variables, Y, M, and D for the current year, month and day, repectively. You can display the modification date of the current tiddler by using the keyword: ''tiddler'' in place of the year, month and day parameters. Use ''tiddler://name-of-tiddler//'' to display the modification date of a specific tiddler. You can also use keywords ''today'' or ''filedate'' to refer to these //dynamically changing// date/time values. \n* [format] and [linkformat] uses standard ~TiddlyWiki date formatting syntax. The default is "YYYY.0MM.0DD"\n>^^''DDD'' - day of week in full (eg, "Monday"), ''DD'' - day of month, ''0DD'' - adds leading zero^^\n>^^''MMM'' - month in full (eg, "July"), ''MM'' - month number, ''0MM'' - adds leading zero^^\n>^^''YYYY'' - full year, ''YY'' - two digit year, ''hh'' - hours, ''mm'' - minutes, ''ss'' - seconds^^\n>^^//note: use of hh, mm or ss format codes is only supported with ''tiddler'', ''today'' or ''filedate'' values//^^\n* [linkformat] - specify an alternative date format so that the title of a 'dated tiddler' link can have a format that differs from the date's displayed format\n\nIn addition to the macro syntax, DatePlugin also provides a public javascript API so that other plugins that work with dates (such as calendar generators, etc.) can quickly incorporate date formatted links or popups into their output:\n\n''{{{showDate(place, date, mode, format, linkformat, autostyle, weekend)}}}'' \n\nNote that in addition to the parameters provided by the macro interface, the javascript API also supports two optional true/false parameters:\n* [autostyle] - when true, the font/background styles of formatted dates are automatically adjusted to show the date's status: 'today' is boxed, 'changes' are bold, 'reminders' are underlined, while weekends and holidays (as well as changes and reminders) can each have a different background color to make them more visibly distinct from each other.\n* [weekend] - true indicates a weekend, false indicates a weekday. When this parameter is omitted, the plugin uses internal defaults to automatically determine when a given date falls on a weekend.\n<<<\n!!!!!Examples\n<<<\nThe current date: <<date>>\nThe current time: <<date today "0hh:0mm:0ss">>\nToday's blog: <<date link today "DDD, MMM DDth, YYYY">>\nRecent blogs/changes/reminders: <<date popup Y M D-1 "yesterday">> <<date popup today "today">> <<date popup Y M D+1 "tomorrow">>\nThe first day of next month will be a <<date Y M+1 1 "DDD">>\nThis tiddler (DatePlugin) was last updated on: <<date tiddler "DDD, MMM DDth, YYYY">>\nThe SiteUrl was last updated on: <<date tiddler:SiteUrl "DDD, MMM DDth, YYYY">>\nThis document was last saved on <<date filedate "DDD, MMM DDth, YYYY at 0hh:0mm:0ss">>\n<<date 2006 07 24 "MMM DDth, YYYY">> will be a <<date 2006 07 24 "DDD">>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''DatePlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2006.05.09 [2.2.1]'' added "todaybg" handling to set background color of current date. Also, honor excludeLists tag when getting lists of tiddlers. Based on suggestions by Mark Hulme.\n''2006.05.05 [2.2.0]'' added "linkedbg" handling to set background color when a 'dated tiddler' exists. Based on a suggestion by Mark Hulme.\n''2006.03.08 [2.1.2]'' add 'override leadtime' flag param in call to findTiddlersWithReminders(), and add "Enter a title" default text to new reminder handler. Thanks to Jeremy Sheeley for these additional tweaks.\n''2006.03.06 [2.1.0]'' hasReminders() nows uses window.reminderCacheForCalendar[] when present. If calendar cache is not present, indexReminders() now uses findTiddlersWithReminders() with a 90-day look ahead to check for reminders. Also, switched default background colors for autostyled dates: reminders are now greenish ("c0ffee") and holidays are now reddish ("ffaace").\n''2006.02.14 [2.0.5]'' when readOnly is set (by TW core), omit "new reminders..." popup menu item and, if a "dated tiddler" does not already exist, display the date as simple text instead of a link.\n''2006.02.05 [2.0.4]'' added var to variables that were unintentionally global. Avoids FireFox 1.5.0.1 crash bug when referencing global variables\n''2006.01.18 [2.0.3]'' In 1.2.x the tiddler editor's text area control was given an element ID=("tiddlerBody"+title), so that it was easy to locate this field and programmatically modify its content. With the addition of configuration templates in 2.x, the textarea no longer has an ID assigned. To find this control we now look through all the child nodes of the tiddler editor to locate a "textarea" control where attribute("edit") equals "text", and then append the new reminder to the contents of that control.\n''2006.01.11 [2.0.2]'' correct 'weekend' override detection logic in showDate()\n''2006.01.10 [2.0.1]'' allow custom-defined weekend days (default defined in config.macros.date.weekend[] array)\nadded flag param to showDate() API to override internal weekend[] array\n''2005.12.27 [2.0.0]'' Update for TW2.0\nAdded parameter handling for 'linkformat'\n''2005.12.21 [1.2.2]'' FF's date.getYear() function returns 105 (for the current year, 2005). When calculating a date value from Y M and D expressions, the plugin adds 1900 to the returned year value get the current year number. But IE's date.getYear() already returns 2005. As a result, plugin calculated date values on IE were incorrect (e.g., 3905 instead of 2005). Adding +1900 is now conditional so the values will be correct on both browsers.\n''2005.11.07 [1.2.1]'' added support for "tiddler" dynamic date parameter\n''2005.11.06 [1.2.0]'' added support for "tiddler:title" dynamic date parameter\n''2005.11.03 [1.1.2]'' when a reminder doesn't have a specified title parameter, use the title of the tiddler that contains the reminder as "fallback" text in the popup menu. Based on a suggestion from BenjaminKudria.\n''2005.11.03 [1.1.1]'' Temporarily bypass hasReminders() logic to avoid excessive overhead from generating the indexReminders() cache. While reminders can still appear in the popup menu, they just won't be indicated by auto-styling the date number that is displayed. This single change saves approx. 60% overhead (5 second delay reduced to under 2 seconds).\n''2005.11.01 [1.1.0]'' corrected logic in hasModifieds() and hasReminders() so caching of indexed modifieds and reminders is done just once, as intended. This should hopefully speed up calendar generators and other plugins that render multiple dates...\n''2005.10.31 [1.0.1]'' documentation and code cleanup\n''2005.10.31 [1.0.0]'' initial public release\n''2005.10.30 [0.9.0]'' pre-release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.date = {major: 2, minor: 2, revision: 1, date: new Date(2006,5,9)};\n//}}}\n\n//{{{\nconfig.macros.date = {\n format: "YYYY.0MM.0DD", // default date display format\n linkformat: "YYYY.0MM.0DD", // 'dated tiddler' link format\n linkedbg: "#babb1e", // "babble"\n todaybg: "#ffab1e", // "fable"\n weekendbg: "#c0c0c0", // "cocoa"\n holidaybg: "#ffaace", // "face"\n modifiedsbg: "#bbeeff", // "beef"\n remindersbg: "#c0ffee", // "coffee"\n holidays: [ "01/01", "07/04", "07/24", "11/24" ], // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)\n weekend: [ 1,0,0,0,0,0,1 ] // [ day index values: sun=0, mon=1, tue=2, wed=3, thu=4, fri=5, sat=6 ]\n};\n//}}}\n\n//{{{\nconfig.macros.date.handler = function(place,macroName,params)\n{\n // do we want to see a link, a popup, or just a formatted date?\n var mode="display";\n if (params[0]=="display") { mode=params[0]; params.shift(); }\n if (params[0]=="popup") { mode=params[0]; params.shift(); }\n if (params[0]=="link") { mode=params[0]; params.shift(); }\n // get the date\n var now = new Date();\n var date = now;\n if (!params[0] || params[0]=="today")\n { params.shift(); }\n else if (params[0]=="filedate")\n { date=new Date(document.lastModified); params.shift(); }\n else if (params[0]=="tiddler")\n { date=store.getTiddler(story.findContainingTiddler(place).id.substr(7)).modified; params.shift(); }\n else if (params[0].substr(0,8)=="tiddler:")\n { var t; if ((t=store.getTiddler(params[0].substr(8)))) date=t.modified; params.shift(); }\n else {\n var y = eval(params.shift().replace(/Y/ig,(now.getYear()<1900)?now.getYear()+1900:now.getYear()));\n var m = eval(params.shift().replace(/M/ig,now.getMonth()+1));\n var d = eval(params.shift().replace(/D/ig,now.getDate()+0));\n date = new Date(y,m-1,d);\n }\n // date format with optional custom override\n var format=this.format; if (params[0]) format=params.shift();\n var linkformat=this.linkformat; if (params[0]) linkformat=params.shift();\n showDate(place,date,mode,format,linkformat);\n}\n//}}}\n\n//{{{\nwindow.showDate=showDate;\nfunction showDate(place,date,mode,format,linkformat,autostyle,weekend)\n{\n if (!mode) mode="display";\n if (!format) format=config.macros.date.format;\n if (!linkformat) linkformat=config.macros.date.linkformat;\n if (!autostyle) autostyle=false;\n\n // format the date output\n var title = date.formatString(format);\n var linkto = date.formatString(linkformat);\n\n // just show the formatted output\n if (mode=="display") { place.appendChild(document.createTextNode(title)); return; }\n\n // link to a 'dated tiddler'\n var link = createTiddlyLink(place, linkto, false);\n link.appendChild(document.createTextNode(title));\n link.title = linkto;\n link.date = date;\n link.format = format;\n link.linkformat = linkformat;\n\n // if using a popup menu, replace click handler for dated tiddler link\n // with handler for popup and make link text non-italic (i.e., an 'existing link' look)\n if (mode=="popup") {\n link.onclick = onClickDatePopup;\n link.style.fontStyle="normal";\n }\n\n // format the popup link to show what kind of info it contains (for use with calendar generators)\n if (!autostyle) return;\n if (hasModifieds(date))\n { link.style.fontStyle="normal"; link.style.fontWeight="bold"; }\n if (hasReminders(date))\n { link.style.textDecoration="underline"; }\n if(isToday(date))\n { link.style.border="1px solid black"; }\n\n if( (weekend!=undefined?weekend:isWeekend(date)) && (config.macros.date.weekendbg!="") )\n { place.style.background = config.macros.date.weekendbg; }\n if(isHoliday(date)&&(config.macros.date.holidaybg!=""))\n { place.style.background = config.macros.date.holidaybg; }\n if (hasModifieds(date)&&(config.macros.date.modifiedsbg!=""))\n { place.style.background = config.macros.date.modifiedsbg; }\n if (store.tiddlerExists(linkto)&&(config.macros.date.linkedbg!=""))\n { place.style.background = config.macros.date.linkedbg; }\n if (hasReminders(date)&&(config.macros.date.remindersbg!=""))\n { place.style.background = config.macros.date.remindersbg; }\n if(isToday(date)&&(config.macros.date.todaybg!=""))\n { place.style.background = config.macros.date.todaybg; }\n}\n//}}}\n\n//{{{\nfunction isToday(date) // returns true if date is today\n { var now=new Date(); return ((now-date>=0) && (now-date<86400000)); }\n\nfunction isWeekend(date) // returns true if date is a weekend\n { return (config.macros.date.weekend[date.getDay()]); }\n\nfunction isHoliday(date) // returns true if date is a holiday\n{\n var longHoliday = date.formatString("0MM/0DD/YYYY");\n var shortHoliday = date.formatString("0MM/0DD");\n for(var i = 0; i < config.macros.date.holidays.length; i++) {\n var holiday=config.macros.date.holidays[i];\n if (holiday==longHoliday||holiday==shortHoliday) return true;\n }\n return false;\n}\n//}}}\n\n//{{{\n// Event handler for clicking on a day popup\nfunction onClickDatePopup(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var popup = createTiddlerPopup(this);\n if(popup) {\n // always show dated tiddler link (or just date, if readOnly) at the top...\n if (!readOnly || store.tiddlerExists(this.date.formatString(this.linkformat)))\n createTiddlyLink(popup,this.date.formatString(this.linkformat),true);\n else\n createTiddlyText(popup,this.date.formatString(this.linkformat));\n addModifiedsToPopup(popup,this.date,this.format);\n addRemindersToPopup(popup,this.date,this.linkformat);\n }\n scrollToTiddlerPopup(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n//{{{\nfunction indexModifieds() // build list of tiddlers, hash indexed by modification date\n{\n var modifieds= { };\n var tiddlers = store.getTiddlers("title","excludeLists");\n for (var t = 0; t < tiddlers.length; t++) {\n var date = tiddlers[t].modified.formatString("YYYY0MM0DD")\n if (!modifieds[date])\n modifieds[date]=new Array();\n modifieds[date].push(tiddlers[t].title);\n }\n return modifieds;\n}\nfunction hasModifieds(date) // returns true if date has modified tiddlers\n{\n if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();\n return (config.macros.date.modifieds[date.formatString("YYYY0MM0DD")]!=undefined);\n}\n\nfunction addModifiedsToPopup(popup,when,format)\n{\n if (!config.macros.date.modifieds) config.macros.date.modifieds = indexModifieds();\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n var mods = config.macros.date.modifieds[when.formatString("YYYY0MM0DD")];\n if (mods) {\n mods.sort();\n var e=createTiddlyElement(popup,"div",null,null,"changes:");\n for(var t=0; t<mods.length; t++) {\n var link=createTiddlyLink(popup,mods[t],false);\n link.appendChild(document.createTextNode(indent+mods[t]));\n createTiddlyElement(popup,"br",null,null,null);\n }\n }\n}\n//}}}\n\n//{{{\nfunction indexReminders(date,leadtime) // build list of tiddlers with reminders, hash indexed by reminder date\n{\n var reminders = { };\n if(window.findTiddlersWithReminders!=undefined) { // reminder plugin is installed\n // DEBUG var starttime=new Date();\n var t = findTiddlersWithReminders(date, [0,leadtime], null, null, 1);\n for(var i=0; i<t.length; i++) reminders[t[i].matchedDate]=true;\n // DEBUG var out="Found "+t.length+" reminders in "+((new Date())-starttime+1)+"ms\sn";\n // DEBUG out+="startdate: "+date.toLocaleDateString()+"\sn"+"leadtime: "+leadtime+" days\sn\sn";\n // DEBUG for(var i=0; i<t.length; i++) { out+=t[i].matchedDate.toLocaleDateString()+" "+t[i].params.title+"\sn"; }\n // DEBUG alert(out);\n }\n return reminders;\n}\n\nfunction hasReminders(date) // returns true if date has reminders\n{\n if (window.reminderCacheForCalendar)\n return window.reminderCacheForCalendar[date]; // use calendar cache\n if (!config.macros.date.reminders)\n config.macros.date.reminders = indexReminders(date,90); // create a 90-day leadtime reminder cache\n return (config.macros.date.reminders[date]);\n}\n\nfunction addRemindersToPopup(popup,when,format)\n{\n if(window.findTiddlersWithReminders==undefined) return; // reminder plugin not installed\n\n var indent = String.fromCharCode(160)+String.fromCharCode(160);\n var reminders=findTiddlersWithReminders(when, [0,31],null,null,1);\n var e=createTiddlyElement(popup,"div",null,null,"reminders:"+(!reminders.length?" none":""));\n for(var t=0; t<reminders.length; t++) {\n link = createTiddlyLink(popup,reminders[t].tiddler,false);\n var diff=reminders[t].diff;\n diff=(diff<1)?"Today":((diff==1)?"Tomorrow":diff+" days");\n var txt=(reminders[t].params["title"])?reminders[t].params["title"]:reminders[t].tiddler;\n link.appendChild(document.createTextNode(indent+diff+" - "+txt));\n createTiddlyElement(popup,"br",null,null,null);\n }\n if (readOnly) return; // omit "new reminder..." link\n var link = createTiddlyLink(popup,indent+"new reminder...",true); createTiddlyElement(popup,"br");\n var title = when.formatString(format);\n link.title="add a reminder to '"+title+"'";\n link.onclick = function() {\n // show tiddler editor\n story.displayTiddler(null, title, 2, null, null, false, false);\n // find body 'textarea'\n var c =document.getElementById("tiddler" + title).getElementsByTagName("*");\n for (var i=0; i<c.length; i++) if ((c[i].tagName.toLowerCase()=="textarea") && (c[i].getAttribute("edit")=="text")) break;\n // append reminder macro to tiddler content\n if (i<c.length) {\n if (store.tiddlerExists(title)) c[i].value+="\sn"; else c[i].value="";\n c[i].value += "<<reminder";\n c[i].value += " day:"+when.getDate();\n c[i].value += " month:"+(when.getMonth()+1);\n c[i].value += " year:"+when.getFullYear();\n c[i].value += ' title:"Enter a title" >>';\n }\n };\n}\n//}}}\n
[[HotKey]]\n[[Gallery]]\n[[NEWSHOW]]
[[MptwEditTemplate]]\n
/***\n| Name:|ExtentTagButtonPlugin|\n| Description:|Adds a New tiddler button in the tag drop down|\n| Version:|3.0 ($Rev: 1845 $)|\n| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source:|http://mptw.tiddlyspot.com/#ExtendTagButtonPlugin|\n| Author:|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\n\n// can't hijack a click handler. must redefine this entirely.\n// would be good to refactor in the core...\n// this version copied from 2.1.3 core\n\n// Event handler for clicking on a tiddler tag\nfunction onClickTag(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var popup = Popup.create(this);\n var tag = this.getAttribute("tag");\n var title = this.getAttribute("tiddler");\n if(popup && tag)\n {\n var tagged = store.getTaggedTiddlers(tag);\n var titles = [];\n var li,r;\n for(r=0;r<tagged.length;r++)\n if(tagged[r].title != title)\n titles.push(tagged[r].title);\n var lingo = config.views.wikified.tag;\n\n wikify("<<newTiddler label:'New tiddler' tag:"+tag+">>",createTiddlyElement(popup,"li")); // <---- the only modification\n\n if(titles.length > 0)\n {\n var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);\n openAll.setAttribute("tag",tag);\n createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");\n for(r=0; r<titles.length; r++)\n {\n createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);\n }\n }\n else\n createTiddlyText(createTiddlyElement(popup,"li",null,"disabled"),lingo.popupNone.format([tag]));\n createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");\n var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);\n createTiddlyText(h,lingo.openTag.format([tag]));\n }\n Popup.show(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n\n//}}}\n\n
//{{{\n// WebSnapr - Preview Bubble Javascript\n// Written by Juan Xavier Larrea\n// Adapted for TW by Saq Imtiaz\n// requires [[this image|bg.png]]\n\nfunction applyStyleString(obj,str) {\n if(document.all && !window.opera) {\n obj.style.setAttribute("cssText",str);\n } else {\n obj.setAttribute("style",str);\n }\n}\n\n// Point this variable to the correct location of the bg.png file\nvar bubbleImagePath = 'bg.png';\n\nfunction getElementsByClassName(oElm, strTagName, strClassName){\n var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);\n var arrReturnElements = new Array();\n strClassName = strClassName.replace(/\s-/g, "\s\s-");\n var oRegExp = new RegExp("(^|\s\ss)" + strClassName + "(\s\ss|$)");\n var oElement;\n for(var i=0; i<arrElements.length; i++){\n oElement = arrElements[i]; \n if(oRegExp.test(oElement.className)){\n arrReturnElements.push(oElement);\n } \n }\n return (arrReturnElements)\n}\n\nfunction bindBubbles(e){\n lbActions=getElementsByClassName(document,"a","externalLink");\n for(i=0;i<lbActions.length;i++){\n addEvent(lbActions[i],"mouseover",attachBubble,false);\n addEvent(lbActions[i],"mouseout",detachBubble,false);\n lbActions[i].title = '';\n }\n}\n\nfunction attachBubble(_b){\n var _c;\n if(_b["srcElement"]){\n _c=_b["srcElement"];\n }else{\n _c=_b["target"];\n }\n if (_c.href == undefined){\n _c=_c.parentNode;\n }\n var _d=_c.href;\n var _e=findPosX(_c) +5;\n var _f=findPosY(_c) +17; \n var _10=document.createElement("div");\n document.getElementsByTagName("body")[0].appendChild(_10);\n _10.className="previewbubble";\n applyStyleString(_10,"text-align: center; z-index: 99999; position: absolute; top: "+_f+"px ; left: "+_e+"px ; width: 240px; height: 190px; padding: 0; margin: 0;");\n if (config.browser.isIE)\n _10.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + bubbleImagePath + "',sizingMethod='image')";\n else\n _10.style.background= "url("+ bubbleImagePath +") no-repeat";\n var img=document.createElement("img");\n _10.appendChild(img);\n\n applyStyleString(img,"padding-top: 0; padding-left: 0; padding-right: 0; padding-bottom: 0; margin-top: 27px; margin-left: 12px; margin-bottom: 0; margin-right: 0; border: 0");\n img.setAttribute("src","http://images.websnapr.com/?url="+_d);\n img.setAttribute("width",202);\n img.setAttribute("height",152);\n img.setAttribute("alt","Snapshot");\n}\n\nfunction detachBubble(_12){\n lbActions=getElementsByClassName(document,"div","previewbubble");\n for(i=0;i<lbActions.length;i++){\n lbActions[i].parentNode.removeChild(lbActions[i]);\n }\n}\n\nold_websnapr_refreshTiddler = Story.prototype.refreshTiddler;\nStory.prototype.refreshTiddler = function(title,template,force)\n{\n var tiddlerElem = old_websnapr_refreshTiddler.apply(this,arguments);\n bindBubbles();\n return tiddlerElem;\n}\n//}}}
!FAQ is compiled from tiddlers with a certain tag.\n<<faqlist byTag faqlistFAQ title hr>>
// //''Name:'' FAQ List\n// //''Version:'' 1.4 for TW 2.0.0\n// //''Author:'' AlanHecht\n// //''Type:'' [[Macro|Macros]]\n\n// //''Description:'' FAQ List lets you compile a list of Frequently Asked Questions and present them in a cascading style for the viewer. Each question is turned into a link that will toggle the view of the answer text. The list can be compiled either from all tiddlers containing a certain tag or from a single tiddler that contains all the needed questions and answers.\n\n// //''Syntax:'' << {{{ faqlist mode source sortBy hrSeparator }}} >>\n// // ''faqlist:'' the macro call (required)\n// // ''mode:'' either "byTag" or "byTitle" (required)\n// // ''source:'' the associated tag or tiddler title (required)\n// // ''sortBy:'' if byTag, sort can be "title," "modifier," "modified." If byTitle, sort can be "question" and will reorder the questions in alphabetical order. (this parameter is optional; use "null" if you don't want a sort order, but want to use "hr" as the last paramter)\n// // ''hrSeparator:'' if "hr" is included at the end of the call string, each question/answer set will be separated by a horizontal rule.\n// //Examples: (edit these two tiddlers to see the syntax used for each)\n// // • [[FAQ Method One]] (compiled from tiddlers tagged with a certain tag)\n// // • [[FAQ Method Two]] (compiled using the content of a single tiddler)\n// // • @@color(#ff0000):''New!''@@ [[FAQ Method Three]] (uses the {{{<<tiddler>>}}} macro to pull the faq questions from a single tiddler and the answers from other tiddlers...very cool!)\n\n// //''Directions:'' <<tiddler StartupBehaviorDirections>> <<tiddler MacroDirections>>\n\n// //''Notes:'' If you choose to use byTitle mode where the entire set of questions/answers comes from a single tiddler, the syntax for the tiddler content is as follows:\n// // • Each question must be a single line (i.e. no hard returns) but can wrap as needed\n// // • The answer to a question begins on the next line after the question and can be as long as needed. It can also include hard returns as part of the answer text, but it cannot include empty lines (i.e. an empty line is the result of pressing enter twice).\n// // • Each question/answer set must be seperated by two hard returns (i.e. must have a single, blank line between them.\n// // Refer to [[FAQ Tiddler Sample]] for an example.\n\n// //''Known Issues:'' If a user clicks too quickly to toggle a FAQ entry on/off, they will go into tiddler edit mode. This should be corrected in the future by allowing web-hosted versions of the faq to disable double-clicking.\n\n// //''Revision History:''\n// // v0.1.0 (01 August 2005): initial release\n// // v0.1.1 (04 August 2005): Fixed an endless loop bug (thanks to Kevin Kleinfelter).\n// // v0.1.2 (19 October 2005): Fixed TW compatibility .32 bugs (newline for block quote and e.preventDefault by Clint Checketts)\n// // v0.1.3 (01 November 2005): Thanks to Clint's work, I fixed a similar "jump to top" problem when using the expand & collapse buttons. Also added the description for [[FAQ Method Three]]\n// // v0.1.4 (05 January 2006): Created a special version of FaqList to work with TW v2.0.0\n\n\n// //''Code section:''\nversion.extensions.faqlist = {major: 0, minor: 1, revision: 4, date: new Date("Jan 05, 2006")};\nconfig.macros.faqlist = {\n bulletCollapse: ">",\n bulletExpand: "∨",\n expandButton: {title: "Expand All", tooltip: "Open all items for reading"},\n collapseButton: {title: "Collapse All", tooltip: "Close all items"}\n};\nconfig.macros.faqlist.handler = function(place,macroName,params)\n{\n lingo = config.macros.faqlist;\n var mode = params[0].toLowerCase();\n var list = [];\n switch(mode)\n {\n case "bytag":\n var tagged = store.getTaggedTiddlers(params[1], params[2]);\n for(t=0; t<tagged.length; t++)\n {\n var title = tagged[t].title;\n list[t] = [title,store.getTiddlerText(title)];\n }\n var subTitle = store.fetchTiddler(title).getSubtitle();\n break;\n case "bytitle":\n var faqText = store.getTiddlerText(params[1]);\n var faqItems = faqText.split("\sn\sn");\n if(params[2] == "question")\n faqItems.sort();\n for(t=0; t<faqItems.length; t++)\n {\n list[t] = [faqItems[t].substring(0,faqItems[t].indexOf("\sn")),faqItems[t].substring(faqItems[t].indexOf("\sn")+1)];\n }\n var subTitle = null;\n break;\n }\n \n var faqHeading = place.appendChild(document.createElement("span"));\n faqHeading.appendChild(createTiddlyButton(faqHeading,lingo.expandButton.title,lingo.expandButton.tooltip,faqExpandAll));\n faqHeading.appendChild(createTiddlyButton(faqHeading,lingo.collapseButton.title,lingo.collapseButton.tooltip,faqCollapseAll));\n faqHeading.appendChild(document.createElement("p"));\n var faqBody = place.appendChild(document.createElement("span"));\n for(var t=0; t<list.length; t++)\n {\n var title = list[t][0];\n\n var content = "<<<\sn" + list[t][1] + "=\sn<<<\sn";\n var theClass = "tiddlyLinkExisting tiddlyLink";\n var itemHeading = faqBody.appendChild(document.createElement("span"));\n itemHeading.appendChild(document.createTextNode(config.macros.faqlist.bulletCollapse + " "));\n createTiddlyButton(itemHeading,title,subTitle,faqToggleThis,theClass);\n var itemBody = faqBody.appendChild(document.createElement("span"));\n itemBody.style.display = "none";\n itemBody.className = "itemBody";\n wikify(content,itemBody,null,null);\n faqBody.appendChild(itemBody);\n faqBody.appendChild(document.createElement("p"));\n if(params[3] == "hr")\n faqBody.appendChild(document.createElement("hr"));\n }\n}\n\nfunction faqToggleThis(e)\n{\n var content = this.parentNode.nextSibling;\n var shown = content.style.display;\n if(shown == "none")\n {\n content.style.display = "inline";\n this.previousSibling.nodeValue = config.macros.faqlist.bulletExpand + " ";\n }\n else\n {\n content.style.display = "none";\n this.previousSibling.nodeValue = config.macros.faqlist.bulletCollapse + " ";\n }\n}\n\nfunction faqExpandAll(e)\n{\n for(t=0; t<this.parentNode.nextSibling.childNodes.length; t++)\n {\n if(this.parentNode.nextSibling.childNodes[t].className == "itemBody")\n {\n this.parentNode.nextSibling.childNodes[t].style.display = "inline";\n this.parentNode.nextSibling.childNodes[t].previousSibling.childNodes[0].nodeValue = config.macros.faqlist.bulletExpand + " ";\n }\n }\n// e.preventDefault();\n}\n\nfunction faqCollapseAll(e)\n{\n for(t=0; t<this.parentNode.nextSibling.childNodes.length; t++)\n {\n if(this.parentNode.nextSibling.childNodes[t].className == "itemBody")\n {\n this.parentNode.nextSibling.childNodes[t].style.display = "none";\n this.parentNode.nextSibling.childNodes[t].previousSibling.childNodes[0].nodeValue = config.macros.faqlist.bulletCollapse + " ";\n }\n }\n// e.preventDefault();\n}\n
/***\n|Name|FontSizePlugin|\n|Created by|SaqImtiaz|\n|Location|http://tw.lewcid.org/#FontSizePlugin|\n|Version|1.0|\n|Requires|~TW2.x|\n!Description:\nResize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.\nYou can customize the maximum and minimum allowed sizes.\n(only affects tiddler content text, not any other text)\n\nAlso, you can load a TW file with a font-size specified in the url.\nEg: http://tw.lewcid.org/#font:110\n\n!Demo:\nTry using the font-size buttons in the sidebar, or in the MainMenu above.\n\n!Installation:\nCopy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.\nThen put {{{<<fontSize "font-size:">>}}} in your SideBarOptions tiddler, or anywhere else that you might like.\n\n!Usage\n{{{<<fontSize>>}}} results in <<fontSize>>\n{{{<<fontSize font-size: >>}}} results in <<fontSize font-size:>>\n\n!Customizing:\nThe buttons and prefix text are wrapped in a span with class fontResizer, for easy css styling.\nTo change the default font-size, and the maximum and minimum font-size allowed, edit the config.fontSize.settings section of the code below.\n\n!Notes:\nThis plugin assumes that the initial font-size is 100% and then increases or decreases the size by 10%. This stepsize of 10% can also be customized.\n\n!History:\n*27-07-06, version 1.0 : prevented double clicks from triggering editing of containing tiddler.\n*25-07-06, version 0.9\n\n!Code\n***/\n\n//{{{\nconfig.fontSize={};\n\n//configuration settings\nconfig.fontSize.settings =\n{\n defaultSize : 100, // all sizes in %\n maxSize : 200,\n minSize : 40,\n stepSize : 10\n};\n\n//startup code\nvar fontSettings = config.fontSize.settings;\n\nif (!config.options.txtFontSize)\n {config.options.txtFontSize = fontSettings.defaultSize;\n saveOptionCookie("txtFontSize");}\nsetStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\sn","fontResizerStyles");\nsetStylesheet("#contentWrapper .fontResizer .button {display:inline;font-size:105%; font-weight:bold; margin:0 1px; padding: 0 3px; text-align:center !important;}\sn .fontResizer {margin:0 0.5em;}","fontResizerButtonStyles");\n\n//macro\nconfig.macros.fontSize={};\nconfig.macros.fontSize.handler = function (place,macroName,params,wikifier,paramString,tiddler)\n{\n\n var sp = createTiddlyElement(place,"span",null,"fontResizer");\n sp.ondblclick=this.onDblClick;\n if (params[0])\n createTiddlyText(sp,params[0]);\n createTiddlyButton(sp,"+","increase font-size",this.incFont);\n createTiddlyButton(sp,"=","reset font-size",this.resetFont);\n createTiddlyButton(sp,"–","decrease font-size",this.decFont);\n}\n\nconfig.macros.fontSize.onDblClick = function (e)\n{\n if (!e) var e = window.event;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return false;\n}\n\nconfig.macros.fontSize.setFont = function ()\n{\n saveOptionCookie("txtFontSize");\n setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\sn","fontResizerStyles");\n}\n\nconfig.macros.fontSize.incFont=function()\n{\n if (config.options.txtFontSize < fontSettings.maxSize)\n config.options.txtFontSize = (config.options.txtFontSize*1)+fontSettings.stepSize;\n config.macros.fontSize.setFont();\n}\n\nconfig.macros.fontSize.decFont=function()\n{\n\n if (config.options.txtFontSize > fontSettings.minSize)\n config.options.txtFontSize = (config.options.txtFontSize*1) - fontSettings.stepSize;\n config.macros.fontSize.setFont();\n}\n\nconfig.macros.fontSize.resetFont=function()\n{\n\n config.options.txtFontSize=fontSettings.defaultSize;\n config.macros.fontSize.setFont();\n}\n\nconfig.paramifiers.font =\n{\n onstart: function(v)\n {\n config.options.txtFontSize = v;\n config.macros.fontSize.setFont();\n }\n};\n//}}}
/***\n|''Name:''|ForEachTiddlerPlugin|\n|''Version:''|1.0.6 (2006-09-16)|\n|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|\n|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|\n|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|\n|''Copyright:''|© 2005-2006 [[abego Software|http://www.abego-software.de]]|\n|''TiddlyWiki:''|1.2.38+, 2.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n!Description\n\nCreate customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.\n\n''Syntax:'' \n|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|\n|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|\n|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|\n|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|\n|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|\n|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|\n|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|\n|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|\n\nSee details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].\n\n!Revision history\n* v1.0.6 (2006-09-16)\n** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.\n** Support "begin", "end" and "none" expressions in "write" action\n* v1.0.5 (2006-02-05)\n** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.\n** Support Firefox 1.5.0.1\n** Internal\n*** Make "JSLint" conform\n*** "Only install once"\n* v1.0.4 (2006-01-06)\n** Support TiddlyWiki 2.0\n* v1.0.3 (2005-12-22)\n** Features: \n*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) \n*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)\n** Enhancements:\n*** Improved error messages on InternetExplorer.\n* v1.0.2 (2005-12-10)\n** Features: \n*** context object also holds reference to store (TiddlyWiki)\n** Fixed Bugs: \n*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)\n* v1.0.1 (2005-12-08)\n** Features: \n*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".\n*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.\n*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).\n*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .\n*** Improved script evaluation (for where/sort clause and write scripts).\n* v1.0.0 (2005-11-20)\n** initial version\n\n!Code\n***/\n//{{{\n\n \n//============================================================================\n//============================================================================\n// ForEachTiddlerPlugin\n//============================================================================\n//============================================================================\n\n// Only install once\nif (!version.extensions.ForEachTiddlerPlugin) {\n\nif (!window.abego) window.abego = {};\n\nversion.extensions.ForEachTiddlerPlugin = {\n major: 1, minor: 0, revision: 6, \n date: new Date(2006,8,16), \n source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",\n licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",\n copyright: "Copyright (c) abego Software GmbH, 2005-2006 (www.abego-software.de)"\n};\n\n// For backward compatibility with TW 1.2.x\n//\nif (!TiddlyWiki.prototype.forEachTiddler) {\n TiddlyWiki.prototype.forEachTiddler = function(callback) {\n for(var t in this.tiddlers) {\n callback.call(this,t,this.tiddlers[t]);\n }\n };\n}\n\n//============================================================================\n// forEachTiddler Macro\n//============================================================================\n\nversion.extensions.forEachTiddler = {\n major: 1, minor: 0, revision: 5, date: new Date(2006,2,5), provider: "http://tiddlywiki.abego-software.de"};\n\n// ---------------------------------------------------------------------------\n// Configurations and constants \n// ---------------------------------------------------------------------------\n\nconfig.macros.forEachTiddler = {\n // Standard Properties\n label: "forEachTiddler",\n prompt: "Perform actions on a (sorted) selection of tiddlers",\n\n // actions\n actions: {\n addToList: {},\n write: {}\n }\n};\n\n// ---------------------------------------------------------------------------\n// The forEachTiddler Macro Handler \n// ---------------------------------------------------------------------------\n\nconfig.macros.forEachTiddler.getContainingTiddler = function(e) {\n while(e && !hasClass(e,"tiddler"))\n e = e.parentNode;\n var title = e ? e.getAttribute("tiddler") : null; \n return title ? store.getTiddler(title) : null;\n};\n\nconfig.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n // config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);\n\n if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n // Parse the "in" clause\n var tiddlyWikiPath = undefined;\n if ((i < params.length) && params[i] == "in") {\n i++;\n if (i >= params.length) {\n this.handleError(place, "TiddlyWiki path expected behind 'in'.");\n return;\n }\n tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the where clause\n var whereClause ="true";\n if ((i < params.length) && params[i] == "where") {\n i++;\n whereClause = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the sort stuff\n var sortClause = null;\n var sortAscending = true; \n if ((i < params.length) && params[i] == "sortBy") {\n i++;\n if (i >= params.length) {\n this.handleError(place, "sortClause missing behind 'sortBy'.");\n return;\n }\n sortClause = this.paramEncode(params[i]);\n i++;\n\n if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {\n sortAscending = params[i] == "ascending";\n i++;\n }\n }\n\n // Parse the script\n var scriptText = null;\n if ((i < params.length) && params[i] == "script") {\n i++;\n scriptText = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the action. \n // When we are already at the end use the default action\n var actionName = "addToList";\n if (i < params.length) {\n if (!config.macros.forEachTiddler.actions[params[i]]) {\n this.handleError(place, "Unknown action '"+params[i]+"'.");\n return;\n } else {\n actionName = params[i]; \n i++;\n }\n } \n \n // Get the action parameter\n // (the parsing is done inside the individual action implementation.)\n var actionParameter = params.slice(i);\n\n\n // --- Processing ------------------------------------------\n try {\n this.performMacro({\n place: place, \n inTiddler: tiddler,\n whereClause: whereClause, \n sortClause: sortClause, \n sortAscending: sortAscending, \n actionName: actionName, \n actionParameter: actionParameter, \n scriptText: scriptText, \n tiddlyWikiPath: tiddlyWikiPath});\n\n } catch (e) {\n this.handleError(place, e);\n }\n};\n\n// Returns an object with properties "tiddlers" and "context".\n// tiddlers holds the (sorted) tiddlers selected by the parameter,\n// context the context of the execution of the macro.\n//\n// The action is not yet performed.\n//\n// @parameter see performMacro\n//\nconfig.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {\n\n var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);\n\n var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;\n context["tiddlyWiki"] = tiddlyWiki;\n \n // Get the tiddlers, as defined by the whereClause\n var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);\n context["tiddlers"] = tiddlers;\n\n // Sort the tiddlers, when sorting is required.\n if (parameter.sortClause) {\n this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);\n }\n\n return {tiddlers: tiddlers, context: context};\n};\n\n// Returns the (sorted) tiddlers selected by the parameter.\n//\n// The action is not yet performed.\n//\n// @parameter see performMacro\n//\nconfig.macros.forEachTiddler.getTiddlers = function(parameter) {\n return this.getTiddlersAndContext(parameter).tiddlers;\n};\n\n// Performs the macros with the given parameter.\n//\n// @param parameter holds the parameter of the macro as separate properties.\n// The following properties are supported:\n//\n// place\n// whereClause\n// sortClause\n// sortAscending\n// actionName\n// actionParameter\n// scriptText\n// tiddlyWikiPath\n//\n// All properties are optional. \n// For most actions the place property must be defined.\n//\nconfig.macros.forEachTiddler.performMacro = function(parameter) {\n var tiddlersAndContext = this.getTiddlersAndContext(parameter);\n\n // Perform the action\n var actionName = parameter.actionName ? parameter.actionName : "addToList";\n var action = config.macros.forEachTiddler.actions[actionName];\n if (!action) {\n this.handleError(parameter.place, "Unknown action '"+actionName+"'.");\n return;\n }\n\n var actionHandler = action.handler;\n actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);\n};\n\n// ---------------------------------------------------------------------------\n// The actions \n// ---------------------------------------------------------------------------\n\n// Internal.\n//\n// --- The addToList Action -----------------------------------------------\n//\nconfig.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {\n // Parse the parameter\n var p = 0;\n\n // Check for extra parameters\n if (parameter.length > p) {\n config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);\n return;\n }\n\n // Perform the action.\n var list = document.createElement("ul");\n place.appendChild(list);\n for (var i = 0; i < tiddlers.length; i++) {\n var tiddler = tiddlers[i];\n var listItem = document.createElement("li");\n list.appendChild(listItem);\n createTiddlyLink(listItem, tiddler.title, true);\n }\n};\n\nabego.parseNamedParameter = function(name, parameter, i) {\n var beginExpression = null;\n if ((i < parameter.length) && parameter[i] == name) {\n i++;\n if (i >= parameter.length) {\n throw "Missing text behind '%0'".format([name]);\n }\n \n return config.macros.forEachTiddler.paramEncode(parameter[i]);\n }\n return null;\n}\n\n// Internal.\n//\n// --- The write Action ---------------------------------------------------\n//\nconfig.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {\n // Parse the parameter\n var p = 0;\n if (p >= parameter.length) {\n this.handleError(place, "Missing expression behind 'write'.");\n return;\n }\n\n var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);\n p++;\n\n // Parse the "begin" option\n var beginExpression = abego.parseNamedParameter("begin", parameter, p);\n if (beginExpression !== null) \n p += 2;\n var endExpression = abego.parseNamedParameter("end", parameter, p);\n if (endExpression !== null) \n p += 2;\n var noneExpression = abego.parseNamedParameter("none", parameter, p);\n if (noneExpression !== null) \n p += 2;\n\n // Parse the "toFile" option\n var filename = null;\n var lineSeparator = undefined;\n if ((p < parameter.length) && parameter[p] == "toFile") {\n p++;\n if (p >= parameter.length) {\n this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");\n return;\n }\n \n filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));\n p++;\n if ((p < parameter.length) && parameter[p] == "withLineSeparator") {\n p++;\n if (p >= parameter.length) {\n this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");\n return;\n }\n lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);\n p++;\n }\n }\n \n // Check for extra parameters\n if (parameter.length > p) {\n config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);\n return;\n }\n\n // Perform the action.\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);\n var count = tiddlers.length;\n var text = "";\n if (count > 0 && beginExpression)\n text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);\n \n for (var i = 0; i < count; i++) {\n var tiddler = tiddlers[i];\n text += func(tiddler, context, count, i);\n }\n \n if (count > 0 && endExpression)\n text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);\n\n if (count == 0 && noneExpression) \n text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);\n \n\n if (filename) {\n if (lineSeparator !== undefined) {\n lineSeparator = lineSeparator.replace(/\s\sn/mg, "\sn").replace(/\s\sr/mg, "\sr");\n text = text.replace(/\sn/mg,lineSeparator);\n }\n saveFile(filename, convertUnicodeToUTF8(text));\n } else {\n var wrapper = createTiddlyElement(place, "span");\n wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);\n }\n};\n\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// Internal.\n//\nconfig.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {\n return {\n place : placeParam, \n whereClause : whereClauseParam, \n sortClause : sortClauseParam, \n sortAscending : sortAscendingParam, \n script : scriptText,\n actionName : actionNameParam, \n actionParameter : actionParameterParam,\n tiddlyWikiPath : tiddlyWikiPathParam,\n inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.\n viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result\n };\n};\n\n// Internal.\n//\n// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of \n// the given path.\n//\nconfig.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {\n if (!idPrefix) {\n idPrefix = "store";\n }\n var lenPrefix = idPrefix.length;\n \n // Read the content of the given file\n var content = loadFile(this.getLocalPath(path));\n if(content === null) {\n throw "TiddlyWiki '"+path+"' not found.";\n }\n \n // Locate the storeArea div's\n var posOpeningDiv = content.indexOf(startSaveArea);\n var posClosingDiv = content.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1)) {\n throw "File '"+path+"' is not a TiddlyWiki.";\n }\n var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);\n \n // Create a "div" element that contains the storage text\n var myStorageDiv = document.createElement("div");\n myStorageDiv.innerHTML = storageText;\n myStorageDiv.normalize();\n \n // Create all tiddlers in a new TiddlyWiki\n // (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)\n var tiddlyWiki = new TiddlyWiki();\n var store = myStorageDiv.childNodes;\n for(var t = 0; t < store.length; t++) {\n var e = store[t];\n var title = null;\n if(e.getAttribute)\n title = e.getAttribute("tiddler");\n if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)\n title = e.id.substr(lenPrefix);\n if(title && title !== "") {\n var tiddler = tiddlyWiki.createTiddler(title);\n tiddler.loadFromDiv(e,title);\n }\n }\n tiddlyWiki.dirty = false;\n\n return tiddlyWiki;\n};\n\n\n \n// Internal.\n//\n// Returns a function that has a function body returning the given javaScriptExpression.\n// The function has the parameters:\n// \n// (tiddler, context, count, index)\n//\nconfig.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {\n var script = context["script"];\n var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";\n var fullText = (script ? script+";" : "")+functionText+";theFunction;";\n return eval(fullText);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {\n var result = [];\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);\n tiddlyWiki.forEachTiddler(function(title,tiddler) {\n if (func(tiddler, context, undefined, undefined)) {\n result.push(tiddler);\n }\n });\n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {\n var message = "Extra parameter behind '"+actionName+"':";\n for (var i = firstUnusedIndex; i < parameter.length; i++) {\n message += " "+parameter[i];\n }\n this.handleError(place, message);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {\n var result = \n (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) \n ? 0\n : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)\n ? -1 \n : +1; \n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {\n var result = \n (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) \n ? 0\n : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)\n ? +1 \n : -1; \n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {\n // To avoid evaluating the sortClause whenever two items are compared \n // we pre-calculate the sortValue for every item in the array and store it in a \n // temporary property ("forEachTiddlerSortValue") of the tiddlers.\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);\n var count = tiddlers.length;\n var i;\n for (i = 0; i < count; i++) {\n var tiddler = tiddlers[i];\n tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);\n }\n\n // Do the sorting\n tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);\n\n // Delete the temporary property that holds the sortValue. \n for (i = 0; i < tiddlers.length; i++) {\n delete tiddlers[i].forEachTiddlerSortValue;\n }\n};\n\n\n// Internal.\n//\nconfig.macros.forEachTiddler.trace = function(message) {\n displayMessage(message);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {\n var message ="<<"+macroName;\n for (var i = 0; i < params.length; i++) {\n message += " "+params[i];\n }\n message += ">>";\n displayMessage(message);\n};\n\n\n// Internal.\n//\n// Creates an element that holds an error message\n// \nconfig.macros.forEachTiddler.createErrorElement = function(place, exception) {\n var message = (exception.description) ? exception.description : exception.toString();\n return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);\n};\n\n// Internal.\n//\n// @param place [may be null]\n//\nconfig.macros.forEachTiddler.handleError = function(place, exception) {\n if (place) {\n this.createErrorElement(place, exception);\n } else {\n throw exception;\n }\n};\n\n// Internal.\n//\n// Encodes the given string.\n//\n// Replaces \n// "$))" to ">>"\n// "$)" to ">"\n//\nconfig.macros.forEachTiddler.paramEncode = function(s) {\n var reGTGT = new RegExp("\s\s$\s\s)\s\s)","mg");\n var reGT = new RegExp("\s\s$\s\s)","mg");\n return s.replace(reGTGT, ">>").replace(reGT, ">");\n};\n\n// Internal.\n//\n// Returns the given original path (that is a file path, starting with "file:")\n// as a path to a local file, in the systems native file format.\n//\n// Location information in the originalPath (i.e. the "#" and stuff following)\n// is stripped.\n// \nconfig.macros.forEachTiddler.getLocalPath = function(originalPath) {\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1)\n originalPath = originalPath.substr(0,hashPos);\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s"); \n return localPath;\n};\n\n// ---------------------------------------------------------------------------\n// Stylesheet Extensions (may be overridden by local StyleSheet)\n// ---------------------------------------------------------------------------\n//\nsetStylesheet(\n ".forEachTiddlerError{color: #ffffff;background-color: #880000;}",\n "forEachTiddler");\n\n//============================================================================\n// End of forEachTiddler Macro\n//============================================================================\n\n\n//============================================================================\n// String.startsWith Function\n//============================================================================\n//\n// Returns true if the string starts with the given prefix, false otherwise.\n//\nversion.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.startsWith = function(prefix) {\n var n = prefix.length;\n return (this.length >= n) && (this.slice(0, n) == prefix);\n};\n\n\n\n//============================================================================\n// String.endsWith Function\n//============================================================================\n//\n// Returns true if the string ends with the given suffix, false otherwise.\n//\nversion.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.endsWith = function(suffix) {\n var n = suffix.length;\n return (this.length >= n) && (this.right(n) == suffix);\n};\n\n\n//============================================================================\n// String.contains Function\n//============================================================================\n//\n// Returns true when the string contains the given substring, false otherwise.\n//\nversion.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.contains = function(substring) {\n return this.indexOf(substring) >= 0;\n};\n\n//============================================================================\n// Array.indexOf Function\n//============================================================================\n//\n// Returns the index of the first occurance of the given item in the array or \n// -1 when no such item exists.\n//\n// @param item [may be null]\n//\nversion.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.indexOf = function(item) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] == item) {\n return i;\n }\n }\n return -1;\n};\n\n//============================================================================\n// Array.contains Function\n//============================================================================\n//\n// Returns true when the array contains the given item, otherwise false. \n//\n// @param item [may be null]\n//\nversion.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.contains = function(item) {\n return (this.indexOf(item) >= 0);\n};\n\n//============================================================================\n// Array.containsAny Function\n//============================================================================\n//\n// Returns true when the array contains at least one of the elements \n// of the item. Otherwise (or when items contains no elements) false is returned.\n//\nversion.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.containsAny = function(items) {\n for(var i = 0; i < items.length; i++) {\n if (this.contains(items[i])) {\n return true;\n }\n }\n return false;\n};\n\n\n//============================================================================\n// Array.containsAll Function\n//============================================================================\n//\n// Returns true when the array contains all the items, otherwise false.\n// \n// When items is null false is returned (even if the array contains a null).\n//\n// @param items [may be null] \n//\nversion.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.containsAll = function(items) {\n for(var i = 0; i < items.length; i++) {\n if (!this.contains(items[i])) {\n return false;\n }\n }\n return true;\n};\n\n\n} // of "install only once"\n\n// Used Globals (for JSLint) ==============\n// ... DOM\n/*global document */\n// ... TiddlyWiki Core\n/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, \n displayMessage, endSaveArea, hasClass, loadFile, saveFile, \n startSaveArea, store, wikify */\n//}}}\n\n\n/***\n!Licence and Copyright\nCopyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice, this\nlist of conditions and the following disclaimer in the documentation and/or other\nmaterials provided with the distribution.\n\nNeither the name of abego Software nor the names of its contributors may be\nused to endorse or promote products derived from this software without specific\nprior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n***/\n\n
/***\n<<checkForDataTiddlerPlugin>>\n|''Name:''|FormTiddlerPlugin|\n|''Version:''|1.0.5 (2006-02-24)|\n|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|\n|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|\n|''Licence:''|[[BSD open source license]]|\n|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|\n|''Requires:''|DataTiddlerPlugin|\n|''TiddlyWiki:''|1.2.38+, 2.0|\n|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|\n!Description\nUse form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).\n\n''Syntax:'' \n|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|\n|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|\n\n|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|\n|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|\n|//buttonLabel//|The label of the button|\n|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|\n|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|\n|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|\n\nFor details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].\n\n!Revision history\n* v1.0.5 (2006-02-24)\n** Removed "debugger;" instruction\n* v1.0.4 (2006-02-07)\n** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)\n* v1.0.3 (2006-02-05)\n** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)\n* v1.0.2 (2006-01-06)\n** Support TiddlyWiki 2.0\n* v1.0.1 (2005-12-22)\n** Features: \n*** Support InternetExplorer\n*** Added newTiddlerWithForm Macro\n* v1.0.0 (2005-12-14)\n** initial version\n\n!Code\n***/\n//{{{\n\n//============================================================================\n//============================================================================\n// FormTiddlerPlugin\n//============================================================================\n//============================================================================\n\n\nversion.extensions.FormTiddlerPlugin = {\n major: 1, minor: 0, revision: 5,\n date: new Date(2006, 2, 24), \n type: 'plugin',\n source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"\n};\n\n// For backward compatibility with v1.2.x\n//\nif (!window.story) window.story=window; \nif (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; } \n\n//============================================================================\n// formTiddler Macro\n//============================================================================\n\n// -------------------------------------------------------------------------------\n// Configurations and constants \n// -------------------------------------------------------------------------------\n\nconfig.macros.formTiddler = {\n // Standard Properties\n label: "formTiddler",\n version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},\n prompt: "Edit tiddler data using forms",\n\n // Define the "setters" that set the values of INPUT elements of a given type\n // (must match the corresponding "getter")\n setter: { \n button: function(e, value) {/*contains no data */ },\n checkbox: function(e, value) {e.checked = value;},\n file: function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},\n hidden: function(e, value) {e.value = value;},\n password: function(e, value) {e.value = value;},\n radio: function(e, value) {e.checked = (e.value == value);},\n reset: function(e, value) {/*contains no data */ },\n "select-one": function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},\n "select-multiple": function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},\n submit: function(e, value) {/*contains no data */},\n text: function(e, value) {e.value = value;},\n textarea: function(e, value) {e.value = value;}\n },\n\n // Define the "getters" that return the value of INPUT elements of a given type\n // Return undefined to not store any data.\n getter: { \n button: function(e, value) {return undefined;},\n checkbox: function(e, value) {return e.checked;},\n file: function(e, value) {return e.value;},\n hidden: function(e, value) {return e.value;},\n password: function(e, value) {return e.value;},\n radio: function(e, value) {return e.checked ? e.value : undefined;},\n reset: function(e, value) {return undefined;},\n "select-one": function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},\n "select-multiple": function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},\n submit: function(e, value) {return undefined;},\n text: function(e, value) {return e.value;},\n textarea: function(e, value) {return e.value;}\n }\n};\n\n\n// -------------------------------------------------------------------------------\n// The formTiddler Macro Handler \n// -------------------------------------------------------------------------------\n\nconfig.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {\n return;\n }\n \n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n\n // get the name of the form template tiddler\n var formTemplateName = undefined;\n if (i < params.length) {\n formTemplateName = params[i];\n i++;\n }\n\n if (!formTemplateName) {\n config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");\n return;\n }\n\n\n // --- Processing ------------------------------------------\n\n // Get the form template text. \n // (This contains the INPUT elements for the form.)\n var formTemplateTiddler = store.getTiddler(formTemplateName);\n if (!formTemplateTiddler) {\n config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");\n return;\n }\n var templateText = formTemplateTiddler.text;\n if(!templateText) {\n // Shortcut: when template text is empty we do nothing.\n return;\n }\n\n // Get the name of the tiddler containing this "formTiddler" macro\n // (i.e. the tiddler, that will be edited and that contains the data)\n var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);\n\n // Append a "form" element. \n var formName = "form"+formTemplateName+"__"+tiddlerName;\n var e = document.createElement("form");\n e.setAttribute("name", formName);\n place.appendChild(e);\n\n // "Embed" the elements defined by the templateText (i.e. the INPUT elements) \n // into the "form" element we just created\n wikify(templateText, e);\n\n // Initialize the INPUT elements.\n config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));\n}\n\n\n// -------------------------------------------------------------------------------\n// Form Data Access \n// -------------------------------------------------------------------------------\n\n// Internal.\n//\n// Initialize the INPUT elements of the form with the values of their "matching"\n// data fields in the tiddler. Also setup the onChange handler to ensure that\n// changes in the INPUT elements are stored in the tiddler's data.\n//\nconfig.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {\n // config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");\n\n // find the form\n var form = config.macros.formTiddler.findForm(formName);\n if (!form) {\n return;\n }\n\n try {\n var elems = form.elements;\n for (var i = 0; i < elems.length; i++) {\n var c = elems[i];\n \n var setter = config.macros.formTiddler.setter[c.type];\n if (setter) {\n var value = data[c.name];\n if (value != null) {\n setter(c, value);\n }\n c.onchange = onFormTiddlerChange;\n } else {\n config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");\n }\n }\n } catch(e) {\n config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);\n }\n}\n\n\n// Internal.\n//\n// @return [may be null]\n//\nconfig.macros.formTiddler.findForm = function(formName) {\n // We must manually iterate through the document's forms, since\n // IE does not support the "document[formName]" approach\n\n var forms = window.document.forms;\n for (var i = 0; i < forms.length; i++) {\n var form = forms[i];\n if (form.name == formName) {\n return form;\n }\n }\n\n return null;\n}\n\n\n// Internal.\n//\nconfig.macros.formTiddler.setSelectOneValue = function(element,value) {\n var n = element.options.length;\n for (var i = 0; i < n; i++) {\n element.options[i].selected = element.options[i].value == value;\n }\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.setSelectMultipleValue = function(element,value) {\n var values = {};\n for (var i = 0; i < value.length; i++) {\n values[value[i]] = true;\n }\n \n var n = element.length;\n for (var i = 0; i < n; i++) {\n element.options[i].selected = !(!values[element.options[i].value]);\n }\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.getSelectOneValue = function(element) {\n var i = element.selectedIndex;\n return (i >= 0) ? element.options[i].value : null;\n}\n\n// Internal.\n//\nconfig.macros.formTiddler.getSelectMultipleValue = function(element) {\n var values = [];\n var n = element.length;\n for (var i = 0; i < n; i++) {\n if (element.options[i].selected) {\n values.push(element.options[i].value);\n }\n }\n return values;\n}\n\n\n\n// -------------------------------------------------------------------------------\n// Helpers \n// -------------------------------------------------------------------------------\n\n// Internal.\n//\nconfig.macros.formTiddler.checkForExtensions = function(place,macroName) {\n if (!version.extensions.DataTiddlerPlugin) {\n config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");\n return false;\n }\n return true;\n}\n\n// Internal.\n//\n// Displays a trace message in the "TiddlyWiki" message pane.\n// (used for debugging)\n//\nconfig.macros.formTiddler.trace = function(s) {\n displayMessage("Trace: "+s);\n}\n\n// Internal.\n//\n// Display some error message in the "TiddlyWiki" message pane.\n//\nconfig.macros.formTiddler.displayFormTiddlerError = function(s) {\n alert("FormTiddlerPlugin Error: "+s);\n}\n\n// Internal.\n//\n// Creates an element that holds an error message\n// \nconfig.macros.formTiddler.createErrorElement = function(place, message) {\n return createTiddlyElement(place,"span",null,"formTiddlerError",message);\n}\n\n// Internal.\n//\n// Returns the name of the tiddler containing the given element.\n// \nconfig.macros.formTiddler.getContainingTiddlerName = function(element) {\n return story.findContainingTiddler(element).id.substr(7);\n}\n\n// -------------------------------------------------------------------------------\n// Event Handlers \n// -------------------------------------------------------------------------------\n\n// This function must be called by the INPUT elements whenever their\n// data changes. Typically this is done through an "onChange" handler.\n//\nfunction onFormTiddlerChange (e) {\n // config.macros.formTiddler.trace("onFormTiddlerChange "+e);\n\n if (!e) var e = window.event;\n\n var target = resolveTarget(e);\n var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);\n var getter = config.macros.formTiddler.getter[target.type];\n if (getter) {\n var value = getter(target);\n DataTiddler.setData(tiddlerName, target.name, value);\n } else {\n config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");\n }\n}\n\n// ensure that the function can be used in HTML event handler\nwindow.onFormTiddlerChange = onFormTiddlerChange;\n\n\n// -------------------------------------------------------------------------------\n// Stylesheet Extensions (may be overridden by local StyleSheet)\n// -------------------------------------------------------------------------------\n\nsetStylesheet(\n ".formTiddlerError{color: #ffffff;background-color: #880000;}",\n "formTiddler");\n\n\n//============================================================================\n// checkForDataTiddlerPlugin Macro\n//============================================================================\n\nconfig.macros.checkForDataTiddlerPlugin = {\n // Standard Properties\n label: "checkForDataTiddlerPlugin",\n version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},\n prompt: "Check if the DataTiddlerPlugin exists"\n}\n\nconfig.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {\n config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);\n}\n\n\n\n//============================================================================\n// newTiddlerWithForm Macro\n//============================================================================\n\nconfig.macros.newTiddlerWithForm = {\n // Standard Properties\n label: "newTiddlerWithForm",\n version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},\n prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"\n}\n\nconfig.macros.newTiddlerWithForm.handler = function(place,macroName,params) {\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n\n // get the name of the form template tiddler\n var formTemplateName = undefined;\n if (i < params.length) {\n formTemplateName = params[i];\n i++;\n }\n\n if (!formTemplateName) {\n config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");\n return;\n }\n\n // get the button label\n var buttonLabel = undefined;\n if (i < params.length) {\n buttonLabel = params[i];\n i++;\n }\n\n if (!buttonLabel) {\n config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");\n return;\n }\n\n // get the (optional) tiddlerName script and "askUser"\n var tiddlerNameScript = undefined;\n var askUser = false;\n if (i < params.length) {\n tiddlerNameScript = params[i];\n i++;\n\n if (i < params.length && params[i] == "askUser") {\n askUser = true;\n i++;\n }\n }\n\n // --- Processing ------------------------------------------\n\n if(!readOnly) {\n var onClick = function() {\n var tiddlerName;\n if (tiddlerNameScript) {\n try {\n tiddlerName = eval(tiddlerNameScript);\n } catch (ex) {\n }\n }\n if (!tiddlerName || askUser) {\n tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");\n }\n while (tiddlerName && store.getTiddler(tiddlerName)) {\n tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\sn\sn"+"Please specify a tiddler name.", tiddlerName);\n }\n\n // tiddlerName is either null (user canceled) or a name that is not yet in the store.\n if (tiddlerName) {\n var body = "<<formTiddler [["+formTemplateName+"]]>>";\n var tags = [];\n store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);\n story.displayTiddler(null,tiddlerName,1);\n }\n }\n\n createTiddlyButton(place,buttonLabel,buttonLabel,onClick);\n }\n}\n\n//}}}\n\n\n/***\n!Licence and Copyright\nCopyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice, this\nlist of conditions and the following disclaimer in the documentation and/or other\nmaterials provided with the distribution.\n\nNeither the name of abego Software nor the names of its contributors may be\nused to endorse or promote products derived from this software without specific\nprior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n***/\n
/***\n|Name|FullScreenPlugin|\n|Created by|SaqImtiaz|\n|Location|http://tw.lewcid.org/#FullScreenPlugin|\n|Version|1.1|\n|Requires|~TW2.x|\n!Description:\nToggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.\n\n!Demo:\nClick the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.\n\n!Installation:\nCopy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.\nEdit the ViewTemplate to add the fullscreen command to the toolbar.\n\n!History:\n*25-07-06: ver 1.1\n*20-07-06: ver 1.0\n\n!Code\n***/\n//{{{\nvar lewcidFullScreen = false;\n\nconfig.commands.fullscreen =\n{\n text:" ↕ ",\n tooltip:"Fullscreen mode"\n};\n\nconfig.commands.fullscreen.handler = function (event,src,title)\n{\n if (lewcidFullScreen == false)\n {\n lewcidFullScreen = true;\n setStylesheet('#sidebar, .header, #mainMenu{display:none;} #displayArea{margin:0em 0 0 0 !important;}',"lewcidFullScreenStyle");\n }\n else\n {\n lewcidFullScreen = false;\n setStylesheet(' ',"lewcidFullScreenStyle");\n }\n}\n\nconfig.macros.fullscreen={};\nconfig.macros.fullscreen.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n var label = params[0]||" ↕ ";\n var tooltip = params[1]||"Fullscreen mode";\n createTiddlyButton(place,label,tooltip,config.commands.fullscreen.handler);\n}\n\nvar lewcid_fullscreen_closeTiddler = Story.prototype.closeTiddler;\nStory.prototype.closeTiddler =function(title,animate,slowly)\n{\n lewcid_fullscreen_closeTiddler.apply(this,arguments);\n if (story.isEmpty() && lewcidFullScreen == true)\n config.commands.fullscreen.handler();\n}\n\n\nSlider.prototype.lewcidStop = Slider.prototype.stop;\nSlider.prototype.stop = function()\n{\n this.lewcidStop();\n if (story.isEmpty() && lewcidFullScreen == true)\n config.commands.fullscreen.handler();\n}\n//}}}
*蘭嶼 東清灣\n<<gallery list 'http://cyberisland.ndap.org.tw/upload/album/2754_1.JPG' 'http://cyberisland.ndap.org.tw/upload/album/2755_1.JPG'\n'http://cyberisland.ndap.org.tw/upload/album/2756_1.JPG'\n>>
// //''Name:'' Gallery Plugin\n// //''Version:'' <<getversion gallery>> (<<getversiondate gallery "DDMMM YYYY">>)\n// //''Author:'' BradleyMeck\n// //''Type:'' [[Macro|Macros]]\n// //''Description:'' Inserts a small slideshow gallery element into the page\n// //''Syntax:'' << {{{gallery list image1 image2...}}}>> or <<{{{gallery number-expression image selectthisnumberinaddress endingnumber incrementby}}}>>\n// //''Directions:'' <<tiddler MacroDirections>>\n// //''Notes:''\n// //''Revision History:''\n// // v0.0.0 (10 September 2005): initial release\n\n// //''Code section:''\nversion.extensions.gallery = {major: 0, minor: 1, revision: 1, date:\nnew Date("Jul 20, 2005")};\nconfig.macros.gallery = {}\nconfig.macros.gallery.handler = function(place,macroName,params)\n{\n var box = createTiddlyElement(place,"table",null,"gallery","");\n box.style.width="100%";\n box.style.border="1px solid black";\n var image = document.createElement("img");\n image.currentNumber = 1;\n image.type = params[0];\n image.data = new Array();\n image.src = params[1];\n\n if(image.type == "list"){\n for(var i = 1; i < params.length; i++ ){\n image.data[i-1] = params[i];\n }\n }\n\n if(image.type == "number-expression"){\n var s = params[1].replace(/[^\sd]+/gi,",")\n if(s.charAt(0)==","){\n s=s.substring(1,s.length)\n }\n if(s.charAt(s.length-1)==","){\n s=s.substring(0,s.length-1)\n }\n var numbers = s.split(",")\n\n if(numbers[0] == ""){\n alert("No Numbers, Cannot Complete Slideshow")\n return;\n }\n\n var startlength = 0;\n var firstnumber = 0;\n var lastnumber = new Number(numbers[0])\n var incrementby = 1;\n var format = numbers[0].length;\n var selectedNumber = 0;\n\n if(params[2]){\n selectedNumber = params[2]-1;\n }\n\n if(params.length >= 5){\n firstnumber = new Number(numbers[selectedNumber]);\n lastnumber = new Number(params[3]);\n incrementby = new Number(params[4]);\n format = numbers[selectedNumber].length;\n }\n\n var startstring;\n if(numbers.length == 1){\n startstring =params[1].substring(0,params[1].indexOf(numbers[0]));\n }\n else{\n s = params[1]\n startlength = 0;\n for(var i = 0; i <= selectedNumber; i++){\n startlength += s.indexOf(numbers[i]);\n startlength += numbers[i].length;\n s = params[1].substring(startlength,params[1].length);\n }\n startstring = params[1].substring(0,startlength-(numbers[selectedNumber].length));\n }\n\n\n var endstring = params[1].substring(startstring.length+format,params[1].length);\n var count = 0;\n for(var i = firstnumber; i <= lastnumber; i += incrementby){\n count = i;\n var c=Math.pow(10,format);\n var formatting = "";\n while((c/=10)>9){\n if(i<c){\n formatting +="0"\n }\n }\n image.data[i-firstnumber] = startstring + formatting + i + endstring;\n }\n }\n\n var centerrowofgallery = document.createElement("tr");\n var leftsideofgallery = document.createElement("td");\n var middleofgallery = document.createElement("td");\n var rightsideofgallery = document.createElement("td");\n\n\n leftsideofgallery.appendChild(createTiddlyButton(place,"Previous","See Previous Image",function (){--image.currentNumber;if(image.currentNumber<0){image.currentNumber = image.data.length-1;}image.src=image.data[image.currentNumber];}))\n leftsideofgallery.style.textAlign="left";\n\n middleofgallery.appendChild(image);\n middleofgallery.style.textAlign="center";\n\n\n rightsideofgallery.appendChild(createTiddlyButton(place,"Forward","See Next Image",function (){++image.currentNumber;if(image.currentNumber>image.data.length-1){image.currentNumber = 0;}image.src=image.data[image.currentNumber];}));\n rightsideofgallery.style.textAlign="right";\n\n centerrowofgallery.appendChild(leftsideofgallery);\n centerrowofgallery.appendChild(middleofgallery);\n centerrowofgallery.appendChild(rightsideofgallery);\n\n box.appendChild(centerrowofgallery);\n}
/***\n''Name:'' GenRssPlugin\n''Source:'' http://www.sourceforge.net/projects/ptw/\n''Author:'' BramChen\n''Type:'' Plugin\n''Description:'' \n* This plugin add a "xml-stylesheet" processing into the rss file generated by TW.\n* Resources used: \n** rssfeed.xsl\n** rssfeed.css\n** xsl.css\n<<<\n''Descriptions:''\n* if 'config.options.txtGenRssTags is empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n* you can add the macro <<option txtGenRssTags>> to some configure tiddler, eg 'AdvancedOptions' for changing the tag list,\n* and add <<option txtRssItems>> to change number of rsfeed item.\n''Revision History:''\n* v0.2.0 (Mar 30 2006)\n** add a new feature that rssfeed limited to tiddlers taged with the tag list specified in 'config.options.txtGenRssTags'.\n** add config.options.txtRssItems.\n** if it's empty then the outputs limited to 'config.numRssItems' except tiddlers taged with 'excludeLists'.\n** you can add the macro <<option txtGenRssTags>> to some configure tiddler, eg 'AdvancedOptions' for changing the tag list.\n* v0.1.1 (Feb 04 2006)\n** JSLint checked\nv0.1.0 (Feb 1, 2006) \n* initial release\n***/\n// //''Code section:''\n//{{{\nversion.extensions.genRss = {major: 0, minor: 2, revision: 0,\n date: new Date("Mar 30, 2006"),\n info: {\n type: "Macro",\n name: "GenRssPlugin",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n }\n};\n\nwindow.generateRss_ori = window.generateRss;\n\nconfig.options.txtGenRssTags = "";\nconfig.options.txtRssItems = "20";\n\nwindow.generateRss = function () {\n var rssTags = config.options.txtGenRssTags.readBracketedList();\n var numRssItems = config.options.txtRssItems;\n var s = [];\n var d = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n // Assemble the header\n s.push("<" + "?xml version=\s"1.0\s" encoding=\s"utf-8\s"?" + ">");\n s.push("<" + "?xml-stylesheet type=\s"text/xsl\s" href=\s"rss/rssfeed.xsl\s"?" +">");\n s.push("<" + "?xml-stylesheet type=\s"text/css\s" href=\s"rss/rssfeed.css\s"?" +">");\n s.push("<" + "rss version=\s"2.0\s">");\n s.push("<channel>");\n s.push("<title>" + wikifyPlain("SiteTitle").htmlEncode() + "</title>");\n if(u)\n s.push("<link>" + u.htmlEncode() + "</link>");\n s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");\n s.push("<language>en-us</language>");\n s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");\n s.push("<pubDate>" + d.toGMTString() + "</pubDate>");\n s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");\n s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");\n s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");\n // The body\n var tiddlers = store.getTiddlers("modified","excludeLists");\n var n = numRssItems > tiddlers.length ? 0 : tiddlers.length-numRssItems;\n for (var t=tiddlers.length-1; t>=n; t--){\n var f=(rssTags.length===0);\n for (var i = 0; i<rssTags.length; i++){\n if (tiddlers[t].tags.find(rssTags[i])!=null){f=true;break;}\n }\n if (f){s.push(tiddlers[t].saveToRss(u));}\n }\n // And footer\n s.push("</channel>");\n s.push("</rss>");\n // Save it all\n return s.join("\sn");\n};\n//}}}
/***\n| Name|HideWhenPlugin|\n| Description|Allows conditional inclusion/exclusion in templates|\n| Version|3.0 ($Rev: 1845 $)|\n| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source|http://mptw.tiddlyspot.com/#HideWhenPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\nFor use in ViewTemplate and EditTemplate. Example usage:\n{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}\n{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}\n***/\n//{{{\n\nwindow.removeElementWhen = function(test,place) {\n if (test) {\n removeChildren(place);\n place.parentNode.removeChild(place);\n }\n};\n\nmerge(config.macros,{\n\n hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( eval(paramString), place);\n }},\n\n showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( !eval(paramString), place);\n }},\n\n hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( tiddler.tags.containsAll(params), place);\n }},\n\n showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( !tiddler.tags.containsAll(params), place);\n }},\n\n hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( tiddler.tags.containsAny(params), place);\n }},\n\n showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( !tiddler.tags.containsAny(params), place);\n }},\n\n hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( tiddler.tags.containsAll(params), place);\n }},\n\n showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( !tiddler.tags.containsAll(params), place);\n }},\n\n hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);\n }},\n\n showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);\n }}\n\n});\n\n//}}}\n\n
<<tagCloud>>
<<top>>\n<<toggleSideBar " '' hide>>\n<<jump j '' top>>\n<<fullscreen f>>\n
/***\n|Name|HoverMenuPlugin|\n|Created by|SaqImtiaz|\n|Location|http://tw.lewcid.org/#HoverMenuPlugin|\n|Version|1.11|\n|Requires|~TW2.x|\n!Description:\nProvides a hovering menu on the edge of the screen for commonly used commands, that scrolls with the page.\n\n!Demo:\nObserve the hovering menu on the right edge of the screen.\n\n!Installation:\nCopy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.\nTo customize your HoverMenu, edit the HoverMenu shadow tiddler.\n\nTo customize whether the menu sticks to the right or left edge of the screen, and its start position, edit the HoverMenu configuration settings part of the code below. It's well documented, so don't be scared!\n\nThe menu has an id of hoverMenu, in case you want to style the buttons in it using css.\n\n!Notes:\nSince the default HoverMenu contains buttons for toggling the side bar and jumping to the top of the screen and to open tiddlers, the ToggleSideBarMacro, JumpMacro and the JumpToTopMacro are included in this tiddler, so you dont need to install them separately. Having them installed separately as well could lead to complications.\n\nIf you dont intend to use these three macros at all, feel free to remove those sections of code in this tiddler.\n\n!To Do:\n* rework code to allow multiple hovering menus in different positions, horizontal etc.\n* incorporate code for keyboard shortcuts that correspond to the buttons in the hovermenu\n\n!History:\n*03-08-06, ver 1.1.2: compatibility fix with SelectThemePlugin\n*03-08-06, ver 1.11: fixed error with button tooltips\n*27-07-06, ver 1.1 : added JumpMacro to hoverMenu\n*23-07-06\n\n!Code\n***/\n\n/***\nstart HoverMenu plugin code\n***/\n//{{{\nconfig.hoverMenu={};\n//}}}\n\n/***\nHoverMenu configuration settings\n***/\n//{{{\nconfig.hoverMenu.settings={\n align: 'right', //align menu to right or left side of screen, possible values are 'right' and 'left' \n x: 100, // horizontal distance of menu from side of screen, increase to your liking.\n y: 158 //vertical distance of menu from top of screen at start, increase or decrease to your liking\n };\n//}}}\n\n//{{{\n//continue HoverMenu plugin code\nconfig.hoverMenu.handler=function()\n{ \n if (!document.getElementById("hoverMenu"))\n {\n var theMenu = createTiddlyElement(document.getElementById("contentWrapper"), "div","hoverMenu");\n theMenu.setAttribute("refresh","content");\n theMenu.setAttribute("tiddler","HoverMenu");\n var menuContent = store.getTiddlerText("HoverMenu");\n wikify(menuContent,theMenu);\n }\n\n var Xloc = this.settings.x;\n Yloc =this.settings.y;\n var ns = (navigator.appName.indexOf("Netscape") != -1);\n function SetMenu(id)\n {\n var GetElements=document.getElementById?document.getElementById(id):document.all?document.all[id]:document.layers[id];\n if(document.layers)GetElements.style=GetElements;\n GetElements.sP=function(x,y){this.style[config.hoverMenu.settings.align]=x +"px";this.style.top=y +"px";};\n GetElements.x = Xloc;\n GetElements.y = findScrollY();\n GetElements.y += Yloc;\n return GetElements;\n }\n window.LoCate_XY=function()\n {\n var pY = findScrollY();\n ftlObj.y += (pY + Yloc - ftlObj.y)/15;\n ftlObj.sP(ftlObj.x, ftlObj.y);\n setTimeout("LoCate_XY()", 10);\n }\n ftlObj = SetMenu("hoverMenu");\n LoCate_XY();\n};\n\nwindow.old_lewcid_hovermenu_restart = restart;\nrestart = function()\n{\n window.old_lewcid_hovermenu_restart();\n config.hoverMenu.handler();\n};\n\nsetStylesheet(\n"#hoverMenu .imgLink, #hoverMenu .imgLink:hover {border:none; padding:0px; float:right; margin-bottom:2px; margin-top:0px;}\sn"+\n"#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#18f; color:#FFF; padding:0 5px; float:right; margin-bottom:4px;}\sn"+\n"#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#fff; background:#000; padding:0 5px; float:right; margin-bottom:4px;}\sn"+\n"#hoverMenu .button {width:100%; text-align:center}"+\n"#hoverMenu { position:absolute; width:7px;}\sn"+\n"\sn","hoverMenuStyles");\n\n\nconfig.macros.renameButton={};\nconfig.macros.renameButton.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n\n if (place.lastChild.tagName!="BR")\n {\n place.lastChild.firstChild.data = params[0];\n if (params[1]) {place.lastChild.title = params[1];}\n }\n};\n\nconfig.shadowTiddlers["HoverMenu"]="<<top>>\sn<<toggleSideBar>><<renameButton '>' >>\sn<<jump j '' top>>\sn<<saveChanges>><<renameButton s 'Save TiddlyWiki'>>\sn<<newTiddler>><<renameButton n>>\sn";\n//}}}\n//end HoverMenu plugin code\n\n//Start ToggleSideBarMacro code\n//{{{\nconfig.macros.toggleSideBar={};\n\nconfig.macros.toggleSideBar.settings={\n styleHide : "#sidebar { display: none;}\sn"+"#contentWrapper #displayArea { margin-right: 1em;}\sn"+"",\n styleShow : " ",\n arrow1: "«",\n arrow2: "»"\n};\n\nconfig.macros.toggleSideBar.handler=function (place,macroName,params,wikifier,paramString,tiddler)\n{\n var tooltip= params[1]||'toggle sidebar';\n var mode = (params[2] && params[2]=="hide")? "hide":"show";\n var arrow = (mode == "hide")? this.settings.arrow1:this.settings.arrow2;\n var label= (params[0]&¶ms[0]!='.')?params[0]+" "+arrow:arrow;\n var theBtn = createTiddlyButton(place,label,tooltip,this.onToggleSideBar,"button HideSideBarButton");\n if (mode == "hide")\n { \n (document.getElementById("sidebar")).setAttribute("toggle","hide");\n setStylesheet(this.settings.styleHide,"ToggleSideBarStyles");\n }\n};\n\nconfig.macros.toggleSideBar.onToggleSideBar = function(){\n var sidebar = document.getElementById("sidebar");\n var settings = config.macros.toggleSideBar.settings;\n if (sidebar.getAttribute("toggle")=='hide')\n {\n setStylesheet(settings.styleShow,"ToggleSideBarStyles");\n sidebar.setAttribute("toggle","show");\n this.firstChild.data= (this.firstChild.data).replace(settings.arrow1,settings.arrow2);\n }\n else\n { \n setStylesheet(settings.styleHide,"ToggleSideBarStyles");\n sidebar.setAttribute("toggle","hide");\n this.firstChild.data= (this.firstChild.data).replace(settings.arrow2,settings.arrow1);\n }\n\n return false;\n}\n\nsetStylesheet(".HideSideBarButton .button {font-weight:bold; padding: 0 5px;}\sn","ToggleSideBarButtonStyles");\n//}}}\n//end ToggleSideBarMacro code\n\n//start JumpToTopMacro code\n//{{{\nconfig.macros.top={};\nconfig.macros.top.handler=function(place,macroName)\n{\n createTiddlyButton(place,"^","jump to top",this.onclick);\n}\nconfig.macros.top.onclick=function()\n{\n window.scrollTo(0,0);\n};\n\nconfig.commands.top =\n{\n text:" ^ ",\n tooltip:"jump to top"\n};\n\nconfig.commands.top.handler = function(event,src,title)\n{\n window.scrollTo(0,0);\n}\n//}}}\n//end JumpToStartMacro code\n\n//start JumpMacro code\n//{{{\nconfig.macros.jump= {};\nconfig.macros.jump.handler = function (place,macroName,params,wikifier,paramString,tiddler)\n{\n var label = (params[0] && params[0]!=".")? params[0]: 'jump';\n var tooltip = (params[1] && params[1]!=".")? params[1]: 'jump to an open tiddler';\n var top = (params[2] && params[2]=='top') ? true: false; \n\n var btn =createTiddlyButton(place,label,tooltip,this.onclick);\n if (top==true)\n btn.setAttribute("top","true")\n}\n\nconfig.macros.jump.onclick = function(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var top = theTarget.getAttribute("top");\n var popup = Popup.create(this);\n if(popup)\n {\n if(top=="true")\n {createTiddlyButton(createTiddlyElement(popup,"li"),'Top ↑','Top of TW',config.macros.jump.top);\n createTiddlyElement(popup,"hr");}\n \n story.forEachTiddler(function(title,element) {\n createTiddlyLink(createTiddlyElement(popup,"li"),title,true);\n });\n }\n Popup.show(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return false;\n}\n\nconfig.macros.jump.top = function()\n{\n window.scrollTo(0,0);\n}\n//}}}\n//end JumpMacro code\n\n//utility functions\n//{{{\nPopup.show = function(unused,slowly)\n{\n var curr = Popup.stack[Popup.stack.length-1];\n var rootLeft = findPosX(curr.root);\n var rootTop = findPosY(curr.root);\n var rootHeight = curr.root.offsetHeight;\n var popupLeft = rootLeft;\n var popupTop = rootTop + rootHeight;\n var popupWidth = curr.popup.offsetWidth;\n var winWidth = findWindowWidth();\n if (isChild(curr.root,'hoverMenu'))\n var x = config.hoverMenu.settings.x;\n else\n var x = 0;\n if(popupLeft + popupWidth+x > winWidth)\n popupLeft = winWidth - popupWidth -x;\n if (isChild(curr.root,'hoverMenu'))\n {curr.popup.style.right = x + "px";}\n else\n curr.popup.style.left = popupLeft + "px";\n curr.popup.style.top = popupTop + "px";\n curr.popup.style.display = "block";\n addClass(curr.root,"highlight");\n if(config.options.chkAnimate)\n anim.startAnimating(new Scroller(curr.popup,slowly));\n else\n window.scrollTo(0,ensureVisible(curr.popup));\n}\n\nwindow.isChild = function(e,parentId) {\n while (e != null) {\n var parent = document.getElementById(parentId);\n if (parent == e) return true;\n e = e.parentNode;\n }\n return false;\n};\n//}}}\n\n\n
// //''Name:'' ImageLink\n// //''Version:'' <<getversion imglink>> (<<getversiondate imglink "DD MMM YYYY">>)\n// //''Author:'' AlanHecht\n// //''Type:'' [[Macro|Macros]]\n\n// //''Description:'' Inserts an external image file as a hyperlink to a URL, a tiddler, or a javascript function.\n\n// //''Syntax:'' << {{{imglink imageSrc linkTo "altText" borderSize width height}}} >>\n// //Examples: \n// //<<imglink fractalveg.jpg http://www.tiddlywiki.com#EmbeddedImages "Nice broccoli!" 1 auto 41>> (webpage link, includes height) //IE will not display properly//*\n\n// //<<imglink fractalveg.jpg test.htm "Nice broccoli!" 1 85 41>> (link to local file, includes both width & height parameters)\n\n// //<<imglink fractalveg.jpg self null 1 84 41>> (image with null alt text that links to itself using 'self')\n\n// //<<imglink fractalveg.jpg null "Cool!" 4 79 38>> (image with "null" link but takes advantage of other parameters)\n\n// //<<imglink brixhamharbour.jpg HelloThere "Click to learn more!" 1>> (local image that links to a tiddler)\n\n// //<<imglink http://www.tiddlywiki.com/brixhamharbour.jpg "sampleFunction('You called a function!')" "Click to call a function!" 1>> (image from the web that calls a function)\n\n// //''Directions:'' <<tiddler MacroDirections>> Also, you do not need to copy the sampleFunction() function that appears at the bottom of the code section. It is used simply to demo this macro calling a function.\n\n// //''Notes:'' Optional border value is set at zero unless you specify another value. If you choose to set a border, you may also want to change the color for the border in the code section below or using the CustomStyleSheet. If you specify width and height, you ''must'' provide a border value (use 0 for no border) .\n// //If any of your macro parameters contain spaces, then surround the phrase in quote marks, otherwise quotes are not needed.\n// //If you use imglink to call a function (useful for adding interface buttons, etc.), the macro will first try to test whether the function exists. If you typed the name of the function incorrectly, you will receive an error when the macro runs. If the function does exist, then it is called with all the parameters you specified.\n// //*If you set an image width, some browsers (like IE) will require that you set the height value as well. For browsers that will autosize, you can replace the actual width/height value with the word {{{auto}}}.\n\n// //''Known Issues:'' This macro will not work if called from within a table.\n\n// //''Revision History:''\n// // v0.1.0 (22 July 2005): initial release\n// // v0.1.1 (22 July 2005): added support for linking to local files as well as no link at all\n// // v0.1.2 (15 August 2005): fixed an issue with self-linking images (note: the syntax for these image links changed to 'self')\n\n\n// //''Code section:''\nversion.extensions.imglink = {major: 0, minor: 1, revision: 2, date: new Date("Aug 15, 2005")};\nconfig.macros.imglink = {}\nconfig.macros.imglink.handler = function(place,macroName,params)\n{\nvar theLink = null;\nvar theAction = null;\nvar data = params;\nvar linkTo = data[1];\nvar box = createTiddlyElement(place,"span",null,"imgLinkBox",String.fromCharCode(160));\nbox.style.position = "relative";\nif(data[2] && data[2]!="null")\n box.title = data[2];\nvar theImage = document.createElement("img");\ntheImage.src = data[0];\ntheImage.className = "linkedImg";\ntheImage.style.position = "relative";\ntheImage.style.verticalAlign = "top";\ntheImage.border = data[3] ? data[3] : 0;\ntheImage.style.borderColor = "black";\nif(data[4] && data[4]!="auto")\n theImage.width = data[4];\nif(data[5] && data[5]!="auto")\n theImage.height = data[5];\n\nvar tiddlerText = store.getTiddlerText(linkTo);\nvar func = linkTo.substring(0,data[1].indexOf("("));\n// test for tiddler link\nif(tiddlerText)\n {\n theLink = document.createElement("a");\n theAction = function() {displayTiddler(this,linkTo,1,null,null,null,false,false);};\n theLink.onclick = theAction;\n theLink.href = "javascript:;";\n }\n// test for function call\nelse if(window[func] || typeof eval(func)=="function")\n {\n theLink = document.createElement("a");\n theAction = function() {eval(linkTo);};\n theLink.onclick = theAction;\n theLink.href = "javascript:;";\n }\n// test for link to image view\nelse if(linkTo == "self")\n {\n theLink = document.createElement("a");\n theLink.href = theImage.src;\n if(config.options.chkOpenInNewWindow)\n theLink.target = "_blank";\n }\n// test for no link\nelse if(linkTo == null || linkTo == "null")\n {\n theLink = document.createElement("span");\n }\nelse\n {\n theLink = document.createElement("a");\n theLink.href = data[1];\n if(config.options.chkOpenInNewWindow)\n theLink.target = "_blank";\n }\n\ntheLink.appendChild(theImage);\n//box.width=theImage.offsetWidth;\n//box.height=theImage.offsetHeight;\nbox.appendChild(theLink);\n}\n\n\n// //''The following function is not needed and is for demo purposes only''\nfunction sampleFunction(message)\n{\nalert(message);\n}
/***\n|Name|InlineJavascriptPlugin|\n|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|\n|Version|1.6.0|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description|Insert Javascript executable code directly into your tiddler content.|\n\n''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.\n!!!!!Usage\n<<<\nWhen installed, this plugin adds new wiki syntax for surrounding tiddler content with {{{<script>}}} and {{{</script>}}} markers, so that it can be treated as embedded javascript and executed each time the tiddler is rendered.\n\n''Deferred execution from an 'onClick' link''\nBy including a {{{label="..."}}} parameter in the initial {{{<script>}}} marker, the plugin will create a link to an 'onclick' script that will only be executed when that specific link is clicked, rather than running the script each time the tiddler is rendered. You may also include a {{{title="..."}}} parameter to specify the 'tooltip' text that will appear whenever the mouse is moved over the onClick link text\n\n''External script source files:''\nYou can also load javascript from an external source URL, by including a src="..." parameter in the initial {{{<script>}}} marker (e.g., {{{<script src="demo.js"></script>}}}). This is particularly useful when incorporating third-party javascript libraries for use in custom extensions and plugins. The 'foreign' javascript code remains isolated in a separate file that can be easily replaced whenever an updated library file becomes available.\n\n''Display script source in tiddler output''\nBy including the keyword parameter "show", in the initial {{{<script>}}} marker, the plugin will include the script source code in the output that it displays in the tiddler.\n\n''Defining javascript functions and libraries:''\nAlthough the external javascript file is loaded while the tiddler content is being rendered, any functions it defines will not be available for use until //after// the rendering has been completed. Thus, you cannot load a library and //immediately// use it's functions within the same tiddler. However, once that tiddler has been loaded, the library functions can be freely used in any tiddler (even the one in which it was initially loaded).\n\nTo ensure that your javascript functions are always available when needed, you should load the libraries from a tiddler that will be rendered as soon as your TiddlyWiki document is opened. For example, you could put your {{{<script src="..."></script>}}} syntax into a tiddler called LoadScripts, and then add {{{<<tiddler LoadScripts>>}}} in your MainMenu tiddler.\n\nSince the MainMenu is always rendered immediately upon opening your document, the library will always be loaded before any other tiddlers that rely upon the functions it defines. Loading an external javascript library does not produce any direct output in the tiddler, so these definitions should have no impact on the appearance of your MainMenu.\n\n''Creating dynamic tiddler content''\nAn important difference between this implementation of embedded scripting and conventional embedded javascript techniques for web pages is the method used to produce output that is dynamically inserted into the document:\n* In a typical web document, you use the document.write() function to output text sequences (often containing HTML tags) that are then rendered when the entire document is first loaded into the browser window.\n* However, in a ~TiddlyWiki document, tiddlers (and other DOM elements) are created, deleted, and rendered "on-the-fly", so writing directly to the global 'document' object does not produce the results you want (i.e., replacing the embedded script within the tiddler content), and completely replaces the entire ~TiddlyWiki document in your browser window.\n* To allow these scripts to work unmodified, the plugin automatically converts all occurences of document.write() so that the output is inserted into the tiddler content instead of replacing the entire ~TiddlyWiki document.\n\nIf your script does not use document.write() to create dynamically embedded content within a tiddler, your javascript can, as an alternative, explicitly return a text value that the plugin can then pass through the wikify() rendering engine to insert into the tiddler display. For example, using {{{return "thistext"}}} will produce the same output as {{{document.write("thistext")}}}.\n\n//Note: your script code is automatically 'wrapped' inside a function, {{{_out()}}}, so that any return value you provide can be correctly handled by the plugin and inserted into the tiddler. To avoid unpredictable results (and possibly fatal execution errors), this function should never be redefined or called from ''within'' your script code.//\n\n''Accessing the ~TiddlyWiki DOM''\nThe plugin provides one pre-defined variable, 'place', that is passed in to your javascript code so that it can have direct access to the containing DOM element into which the tiddler output is currently being rendered.\n\nAccess to this DOM element allows you to create scripts that can:\n* vary their actions based upon the specific location in which they are embedded\n* access 'tiddler-relative' information (use findContainingTiddler(place))\n* perform direct DOM manipulations (when returning wikified text is not enough)\n<<<\n!!!!!Examples\n<<<\nan "alert" message box:\n><script show>\n alert('InlineJavascriptPlugin: this is a demonstration message');\n</script>\ndynamic output:\n><script show>\n return (new Date()).toString();\n</script>\nwikified dynamic output:\n><script show>\n return "link to current user: [["+config.options.txtUserName+"]]";\n</script>\ndynamic output using 'place' to get size information for current tiddler:\n><script show>\n if (!window.story) window.story=window;\n var title=story.findContainingTiddler(place).id.substr(7);\n return title+" is using "+store.getTiddlerText(title).length+" bytes";\n</script>\ncreating an 'onclick' button/link that runs a script:\n><script label="click here" title="clicking this link will show an 'alert' box" show>\n if (!window.story) window.story=window;\n alert("Hello World!\snlinktext='"+place.firstChild.data+"'\sntiddler='"+story.findContainingTiddler(place).id.substr(7)+"'");\n</script>\nloading a script from a source url:\n>http://www.TiddlyTools.com/demo.js contains:\n>>{{{function demo() { alert('this output is from demo(), defined in demo.js') } }}}\n>>{{{alert('InlineJavascriptPlugin: demo.js has been loaded'); }}}\n><script src="demo.js" show>\n return "loading demo.js..."\n</script>\n><script label="click to execute demo() function" show>\n demo()\n</script>\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''InlineJavascriptPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2007.02.19 [1.6.0]'' added support for title="..." to specify mouseover tooltip when using an onclick (label="...") script\n''2006.10.16 [1.5.2]'' add newline before closing '}' in 'function out_' wrapper. Fixes error caused when last line of script is a comment.\n''2006.06.01 [1.5.1]'' when calling wikify() on script return value, pass hightlightRegExp and tiddler params so macros that rely on these values can render properly\n''2006.04.19 [1.5.0]'' added 'show' parameter to force display of javascript source code in tiddler output\n''2006.01.05 [1.4.0]'' added support 'onclick' scripts. When label="..." param is present, a button/link is created using the indicated label text, and the script is only executed when the button/link is clicked. 'place' value is set to match the clicked button/link element.\n''2005.12.13 [1.3.1]'' when catching eval error in IE, e.description contains the error text, instead of e.toString(). Fixed error reporting so IE shows the correct response text. Based on a suggestion by UdoBorkowski\n''2005.11.09 [1.3.0]'' for 'inline' scripts (i.e., not scripts loaded with src="..."), automatically replace calls to 'document.write()' with 'place.innerHTML+=' so script output is directed into tiddler content. Based on a suggestion by BradleyMeck\n''2005.11.08 [1.2.0]'' handle loading of javascript from an external URL via src="..." syntax\n''2005.11.08 [1.1.0]'' pass 'place' param into scripts to provide direct DOM access \n''2005.11.08 [1.0.0]'' initial release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.inlineJavascript= {major: 1, minor: 6, revision: 0, date: new Date(2007,2,19)};\n\nconfig.formatters.push( {\n name: "inlineJavascript",\n match: "\s\s<script",\n lookahead: "\s\s<script(?: src=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?(?: label=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?(?: title=\s\s\s"((?:.|\s\sn)*?)\s\s\s")?( show)?\s\s>((?:.|\s\sn)*?)\s\s</script\s\s>",\n\n handler: function(w) {\n var lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {\n if (lookaheadMatch[1]) { // load a script library\n // make script tag, set src, add to body to execute, then remove for cleanup\n var script = document.createElement("script"); script.src = lookaheadMatch[1];\n document.body.appendChild(script); document.body.removeChild(script);\n }\n if (lookaheadMatch[5]) { // there is script code\n if (lookaheadMatch[4]) // show inline script code in tiddler output\n wikify("{{{\sn"+lookaheadMatch[0]+"\sn}}}\sn",w.output);\n if (lookaheadMatch[2]) { // create a link to an 'onclick' script\n // add a link, define click handler, save code in link (pass 'place'), set link attributes\n var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",lookaheadMatch[2]);\n link.onclick=function(){try{return(eval(this.code))}catch(e){alert(e.description?e.description:e.toString())}}\n link.code="function _out(place){"+lookaheadMatch[5]+"\sn};_out(this);"\n link.setAttribute("title",lookaheadMatch[3]?lookaheadMatch[3]:"");\n link.setAttribute("href","javascript:;");\n link.style.cursor="pointer";\n }\n else { // run inline script code\n var code="function _out(place){"+lookaheadMatch[5]+"\sn};_out(w.output);"\n code=code.replace(/document.write\s(/gi,'place.innerHTML+=(');\n try { var out = eval(code); } catch(e) { out = e.description?e.description:e.toString(); }\n if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);\n }\n }\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n }\n} )\n//}}}
//{{{\nconfig.formatters.unshift( {\n name: "inlinesliders",\n match: "\s\s+\s\s+\s\s+\s\s+|\s\s<slider",\n lookaheadRegExp: /(?:\s+\s+\s+\s+|<slider) (\sw*)(?:>?)\sn((?:.|\sn)*?)\sn(?:====|<\s/slider>)/mg,\n handler: function(w)\n {\n this.lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = this.lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart )\n {\n var btn = createTiddlyButton(w.output,lookaheadMatch[1] + " "+"\su00BB",lookaheadMatch[1],this.onClickSlider,"button sliderButton");\n var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");\n panel.style.display = "none";\n wikify(lookaheadMatch[2],panel);\n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n }\n },\n onClickSlider : function(e)\n {\n if(!e) var e = window.event;\n var n = this.nextSibling;\n n.style.display = (n.style.display=="none") ? "block" : "none";\n return false;\n }\n})\n//}}}
//{{{\nconfig.formatters.unshift( {\n name: "inlinetabs",\n match: "\s\s<tabs",\n lookaheadRegExp: /(?:<tabs (.*)>\sn)((?:.|\sn)*?)(?:\sn<\s/tabs>)/mg,\n handler: function(w)\n {\n this.lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = this.lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n {\n var cookie = lookaheadMatch[1];\n var wrapper = createTiddlyElement(null,"div",null,cookie);\n var tabset = createTiddlyElement(wrapper,"div",null,"tabset");\n tabset.setAttribute("cookie",cookie);\n var validTab = false;\n var firstTab = '';\n var tabregexp = /(?:<tab (.*)>)(?:(?:\sn)?)((?:.|\sn)*?)(?:<\s/tab>)/mg;\n while((m = tabregexp.exec(lookaheadMatch[2])) != null)\n {\n if (firstTab == '') firstTab = m[1];\n var tab = createTiddlyButton(tabset,m[1],m[1],story.onClickInlineTab,"tab tabUnselected");\n tab.setAttribute("tab",m[1]);\n tab.setAttribute("content",m[2]);\n tab.title = m[1];\n if(config.options[cookie] == m[1])\n validTab = true;\n }\n if(!validTab)\n config.options[cookie] = firstTab;\n w.output.appendChild(wrapper);\n story.switchInlineTab(tabset,config.options[cookie]);\n w.nextMatch = this.lookaheadRegExp.lastIndex;\n }\n }\n})\n\nStory.prototype.switchInlineTab = function(tabset,tab)\n{\n var cookie = tabset.getAttribute("cookie");\n var theTab = null\n var nodes = tabset.childNodes;\n for(var t=0; t<nodes.length; t++)\n if(nodes[t].getAttribute && nodes[t].getAttribute("tab") == tab)\n {\n theTab = nodes[t];\n theTab.className = "tab tabSelected";\n }\n else\n nodes[t].className = "tab tabUnselected"\n if(theTab)\n {\n if(tabset.nextSibling && tabset.nextSibling.className == "tabContents")\n tabset.parentNode.removeChild(tabset.nextSibling);\n var tabContent = createTiddlyElement(null,"div",null,"tabContents");\n tabset.parentNode.insertBefore(tabContent,tabset.nextSibling);\n wikify(theTab.getAttribute("content"),tabContent);\n if(cookie)\n {\n config.options[cookie] = tab;\n saveOptionCookie(cookie);\n }\n }\n}\n \nStory.prototype.onClickInlineTab = function(e)\n{\n story.switchInlineTab(this.parentNode,this.getAttribute("tab"));\n return false;\n}\n//}}}
//{{{\nStory.prototype.tiddlerHistory= [];\nStory.prototype.maxTiddlers = 3;\nStory.prototype.closedHistory=[];\nStory.prototype.closedHistoryMax = 10;\n\nArray.prototype.moveToEnd = function(item)\n{\n this.remove(item);\n this.push(item);\n}\n\nStory.prototype.old_history_displayTiddler = Story.prototype.displayTiddler;\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n this.tiddlerHistory.moveToEnd(title);\n this.closedHistory.remove(title);\n var closeCount = this.tiddlerHistory.length - this.maxTiddlers;\n if (closeCount > 0)\n {\n var count = this.tiddlerHistory.splice (0,closeCount);\n for (var i=0; i<count.length;i++)\n {\n story.closeTiddler(count[i],false);\n }\n }\n story.old_history_displayTiddler(null,title,template,animate,slowly);\n}\n\nStory.prototype.old_history_closeTiddler = Story.prototype.closeTiddler;\nStory.prototype.closeTiddler = function(title,animate,slowly)\n{\n this.tiddlerHistory.remove(title);\n this.closedHistory.remove(title);\n this.closedHistory.unshift(title);\n story.old_history_closeTiddler.apply(this,arguments);\n}\n\nStory.prototype.displayTiddlers = function(srcElement,titles,template,animate,slowly)\n{\n for(var t = titles.length-1;t>=0;t--)\n {\n this.tiddlerHistory.moveToEnd(titles[t]);\n this.closedHistory.remove(titles[t]);\n this.old_history_displayTiddler(srcElement,titles[t],template,animate,slowly);\n }\n}\n\nconfig.commands.history={\n text: "history",\n tooltip: "re-open a closed tiddler"};\n\nconfig.commands.history.handler = function(event,src,title)\n{\n var popup = Popup.create(src);\n if(popup)\n {\n if (!story.closedHistory.length)\n createTiddlyText(popup,"No history");\n else\n {\n var c = Math.min(story.closedHistory.length,story.closedHistoryMax);\n for (i=0; i<c;i++ )\n {\n createTiddlyLink(createTiddlyElement(popup,"li"),story.closedHistory[i],true);\n }\n }\n }\n Popup.show(popup,false);\n event.cancelBubble = true;\n if (event.stopPropagation) event.stopPropagation();\n return false;\n}\n//}}}
<<fontSize "font-size:">>[[影像時代]][[影像閱讀]][[影像繽紛]][[影像數位化]][[影像同盟]]
<!--{{{-->\n<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>\n<!--}}}-->\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>典藏數位之美</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>
[[MonkeyPirateTiddlyWiki|http://mptw.tiddlyspot.com]] is a distribution of [[TiddlyWiki|http://www.tiddlywiki.com/]] created by Simon Baird. See [[the web site|http://mptw.tiddlyspot.com/]] for more information.\n!!Upgrading ~MonkeyPirateTiddlyWiki\nThis "empty" ~MonkeyPirateTiddlyWiki file comes pre-installed with the core ~MonkeyPirateTiddlyWiki plugins. You can upgrade these core plugins to the latest version by doing the following:\n* Click ImportTiddlers\n* Click "Choose..." and select "~MptwUpgradeURL"\n* Click "fetch"\n* Click the checkbox in the first column heading to select all tiddlers\n* Click "More actions..." and select "Import these tiddlers"\n* Click "OK" to confirm you want to overwrite the tiddlers\n* Save and reload\n
/***\n| Name|MptwLayoutPlugin|\n| Description|A package containing templates and css for the MonkeyPirateTiddlyWiki layout|\n| Version|3.0 ($Rev: 1845 $)|\n| Source|http://mptw.tiddlyspot.com/#MptwLayoutPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n!Notes\nPresumes you have TagglyTaggingPlugin installed. To enable this you should have a PageTemplate containing {{{[[MptwPageTemplate]]}}} and similar for ViewTemplate and EditTemplate.\n***/\n//{{{\n// used in MptwViewTemplate\nconfig.mptwDateFormat = 'DD/MM/YY';\nconfig.mptwJournalFormat = 'Journal DD/MM/YY';\n//config.mptwDateFormat = 'MM/0DD/YY';\n//config.mptwJournalFormat = 'Journal MM/0DD/YY';\n\nconfig.shadowTiddlers.GettingStarted += "\sn\snSee also MonkeyPirateTiddlyWiki.";\n\n//}}}\n\n//{{{\nmerge(config.shadowTiddlers,{\n\n'MptwEditTemplate':[\n "<!--{{{-->",\n "<!--- http://mptw.tiddlyspot.com/#MptwEditTemplate ($Rev: 1829 $) --->",\n "<div class=\s"toolbar\s" macro=\s"toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler\s"></div>",\n "<div class=\s"title\s" macro=\s"view title\s"></div>",\n "<div class=\s"editLabel\s">Title</div><div class=\s"editor\s" macro=\s"edit title\s"></div>",\n "<div class=\s"editLabel\s">Tags</div><div class=\s"editor\s" macro=\s"edit tags\s"></div>",\n "<div class=\s"editorFooter\s"><span macro=\s"message views.editor.tagPrompt\s"></span><span macro=\s"tagChooser\s"></span></div>",\n "<div macro=\s"showWhenExists EditPanelTemplate\s">[[EditPanelTemplate]]</div>",\n "<div class=\s"editor\s" macro=\s"edit text\s"></div>",\n "<!--}}}-->",\n ""\n].join("\sn"),\n\n'MptwPageTemplate':[\n "<!--{{{-->",\n "<!-- http://mptw.tiddlyspot.com/#MptwPageTemplate ($Rev: 1829 $) -->",\n "<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>",\n " <div class='headerShadow'>",\n " <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> ",\n " <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",\n " </div>",\n " <div class='headerForeground'>",\n " <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> ",\n " <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>",\n " </div>",\n "</div>",\n "<!-- horizontal MainMenu -->",\n "<div id='topMenu' refresh='content' tiddler='MainMenu'></div>",\n "<!-- original MainMenu menu -->",\n "<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->",\n "<div id='sidebar'>",\n " <div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>",\n " <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>",\n "</div>",\n "<div id='displayArea'>",\n " <div id='messageArea'></div>",\n " <div id='tiddlerDisplay'></div>",\n "</div>",\n "<!--}}}-->",\n ""\n].join("\sn"),\n\n'MptwStyleSheet':[\n "/*{{{*/",\n "/* http://mptw.tiddlyspot.com/#MptwStyleSheet ($Rev: 1860 $) */",\n "",\n "/* a contrasting background so I can see where one tiddler ends and the other begins */",\n "body {",\n " background: [[ColorPalette::TertiaryLight]];",\n "}",\n "",\n "/* sexy colours and font for the header */",\n ".headerForeground {",\n " color: [[ColorPalette::PrimaryPale]];",\n "}",\n ".headerShadow, .headerShadow a {",\n " color: [[ColorPalette::PrimaryMid]];",\n "}",\n "",\n "/* separate the top menu parts */",\n ".headerForeground, .headerShadow {",\n " padding: 1em 1em 0;",\n "}",\n "",\n ".headerForeground, .headerShadow {",\n " font-family: 'Trebuchet MS' sans-serif;",\n " font-weight:bold;",\n "}",\n ".headerForeground .siteSubtitle {",\n " color: [[ColorPalette::PrimaryLight]];",\n "}",\n ".headerShadow .siteSubtitle {",\n " color: [[ColorPalette::PrimaryMid]];",\n "}",\n "",\n "/* make shadow go and down right instead of up and left */",\n ".headerShadow {",\n " left: 1px;",\n " top: 1px;",\n "}",\n "",\n "/* prefer monospace for editing */",\n ".editor textarea {",\n " font-family: 'Consolas' monospace;",\n "}",\n "",\n "/* sexy tiddler titles */",\n ".title {",\n " font-size: 250%;",\n " color: [[ColorPalette::PrimaryLight]];",\n " font-family: 'Trebuchet MS' sans-serif;",\n "}",\n "",\n "/* more subtle tiddler subtitle */",\n ".subtitle {",\n " padding:0px;",\n " margin:0px;",\n " padding-left:0.5em;",\n " font-size: 90%;",\n " color: [[ColorPalette::TertiaryMid]];",\n "}",\n ".subtitle .tiddlyLink {",\n " color: [[ColorPalette::TertiaryMid]];",\n "}",\n "",\n "/* a little bit of extra whitespace */",\n ".viewer {",\n " padding-bottom:3px;",\n "}",\n "",\n "/* don't want any background color for headings */",\n "h1,h2,h3,h4,h5,h6 {",\n " background: [[ColorPalette::Background]];",\n " color: [[ColorPalette::Foreground]];",\n "}",\n "",\n "/* give tiddlers 3d style border and explicit background */",\n ".tiddler {",\n " background: [[ColorPalette::Background]];",\n " border-right: 2px [[ColorPalette::TertiaryMid]] solid;",\n " border-bottom: 2px [[ColorPalette::TertiaryMid]] solid;",\n " margin-bottom: 1em;",\n " padding-bottom: 2em;",\n "}",\n "",\n "/* make options slider look nicer */",\n "#sidebarOptions .sliderPanel {",\n " border:solid 1px [[ColorPalette::PrimaryLight]];",\n "}",\n "",\n "/* the borders look wrong with the body background */",\n "#sidebar .button {",\n " border-style: none;",\n "}",\n "",\n "/* this means you can put line breaks in SidebarOptions for readability */",\n "#sidebarOptions br {",\n " display:none;",\n "}",\n "/* undo the above in OptionsPanel */",\n "#sidebarOptions .sliderPanel br {",\n " display:inline;",\n "}",\n "",\n "/* horizontal main menu stuff */",\n "#displayArea {",\n " margin: 1em 15.7em 0em 1em; /* use the freed up space */",\n "}",\n "#topMenu br {",\n " display: none;",\n "}",\n "#topMenu {",\n " background: [[ColorPalette::PrimaryMid]];",\n " color:[[ColorPalette::PrimaryPale]];",\n "}",\n "#topMenu {",\n " padding:2px;",\n "}",\n "#topMenu .button, #topMenu .tiddlyLink, #topMenu a {",\n " margin-left: 0.5em;",\n " margin-right: 0.5em;",\n " padding-left: 3px;",\n " padding-right: 3px;",\n " color: [[ColorPalette::PrimaryPale]];",\n " font-size: 115%;",\n "}",\n "#topMenu .button:hover, #topMenu .tiddlyLink:hover {",\n " background: [[ColorPalette::PrimaryDark]];",\n "}",\n "",\n "/* for Tagger Plugin, thanks sb56637 */",\n ".popup li a {",\n " display:inline;",\n "}",\n "",\n "/* make it print a little cleaner */",\n "@media print {",\n " #topMenu {",\n " display: none ! important;",\n " }",\n " /* not sure if we need all the importants */",\n " .tiddler {",\n " border-style: none ! important;",\n " margin:0px ! important;",\n " padding:0px ! important;",\n " padding-bottom:2em ! important;",\n " }",\n " .tagglyTagging .button, .tagglyTagging .hidebutton {",\n " display: none ! important;",\n " }",\n " .headerShadow {",\n " visibility: hidden ! important;",\n " }",\n " .tagglyTagged .quickopentag, .tagged .quickopentag {",\n " border-style: none ! important;",\n " }",\n " .quickopentag a.button, .miniTag {",\n " display: none ! important;",\n " }",\n "}",\n "/*}}}*/",\n ""\n].join("\sn"),\n\n'MptwViewTemplate':[\n "<!--{{{-->",\n "<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 1830 $) --->",\n "",\n "<div class='toolbar'>",\n " <span macro=\s"showWhenTagged systemConfig\s">",\n " <span macro=\s"toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'\s"></span>",\n " </span>",\n " <span style=\s"padding:1em;\s"></span>",\n " <span macro='toolbar closeTiddler closeOthers +editTiddler deleteTiddler undoChanges permalink references jump'></span>",\n " <span macro='newHere label:\s"new here\s"'></span>",\n " <span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:\s"MM/0DD/YY\s"}}'></span>",\n "</div>",\n "",\n "<div class=\s"tagglyTagged\s" macro=\s"tags\s"></div>",\n "",\n "<div class='titleContainer'>",\n " <span class='title' macro='view title'></span>",\n " <span macro=\s"miniTag\s"></span>",\n "</div>",\n "",\n "<div class='subtitle'>",\n " <span macro='view modifier link'></span>,",\n " <span macro='view modified date {{config.mptwDateFormat?config.mptwDateFormat:\s"MM/0DD/YY\s"}}'></span>",\n " (<span macro='message views.wikified.createdPrompt'></span>",\n " <span macro='view created date {{config.mptwDateFormat?config.mptwDateFormat:\s"MM/0DD/YY\s"}}'></span>)",\n "</div>",\n "",\n "<div macro=\s"showWhenExists ViewPanelTemplate\s">[[ViewPanelTemplate]]</div>",\n "",\n "<div macro=\s"hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\s">",\n " <div class='viewer' macro='view text wikified'></div>",\n "</div>",\n "<div macro=\s"showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')\s">",\n " <div class='viewer'><pre macro='view text'></pre></div>",\n "</div>",\n "",\n "<div macro=\s"showWhenExists ViewDashboardTemplate\s">[[ViewDashboardTemplate]]</div>",\n "",\n "<div class=\s"tagglyTagging\s" macro=\s"tagglyTagging\s"></div>",\n "",\n "<!--}}}-->",\n ""\n].join("\sn")\n\n});\n//}}}\n
<!--{{{-->\n<!-- http://mptw.tiddlyspot.com/#MptwPageTemplate ($Rev: 1829 $) -->\n<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>\n <div class='headerShadow'>\n <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> \n <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n </div>\n <div class='headerForeground'>\n <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> \n <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n </div>\n</div>\n<!-- horizontal MainMenu -->\n<div id='topMenu' refresh='content' tiddler='MainMenu'></div>\n<!-- original MainMenu menu -->\n<!-- <div id='mainMenu' refresh='content' tiddler='MainMenu'></div> -->\n<div id='sidebar'>\n <div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n <div id='messageArea'></div>\n <div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->\n
For upgrading directly from tiddlyspot. See [[ImportTiddlers]].\nURL: /proxy/mptw.tiddlyspot.com/upgrade.html\n
For upgrading. See [[ImportTiddlers]].\nURL: http://mptw.tiddlyspot.com/upgrade.html\n
<!--{{{-->\n<!--- http://mptw.tiddlyspot.com/#MptwViewTemplate ($Rev: 1830 $) --->\n<div class='comments' macro='comments'></span>\n<div class='toolbar'>\n <span macro="showWhenTagged systemConfig">\n <span macro="toggleTag systemConfigDisable . '[[disable|systemConfigDisable]]'"></span>\n </span>\n <span style="padding:1em;"></span>\n <span style="padding-right:2.45em;" macro='tagger'></span>\n <span class='toolbar' macro='toolbar collapseTiddler collapseOthers '></span>\n <span macro='toolbar closeTiddler closeOthers fullscreen +editTiddler deleteTiddler undoChanges permalink references jump revision'></span>\n <span macro='newHere label:"new here"'></span>\n <span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:"MM/0DD/YY"}}'></span>\n</div>\n\n<div class="tagglyTagged" macro="tags"></div>\n\n<div class='titleContainer'>\n <span class='title' macro='view title'></span>\n <span macro="miniTag"></span>\n</div>\n\n<div class='subtitle'>\n <span macro='view modifier link'></span>,\n <span macro='view modified date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>\n (<span macro='message views.wikified.createdPrompt'></span>\n <span macro='view created date {{config.mptwDateFormat?config.mptwDateFormat:"MM/0DD/YY"}}'></span>)\n \n </div>\n\n<div macro="showWhenExists ViewPanelTemplate">[[ViewPanelTemplate]]</div>\n\n<div macro="hideWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">\n <div class='viewer' macro='view text wikified'></div>\n</div>\n<div macro="showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">\n <div class='viewer'><pre macro='view text'></pre></div>\n</div>\n\n<div macro="showWhenExists ViewDashboardTemplate">[[ViewDashboardTemplate]]</div>\n\n<div class="tagglyTagging" macro="tagglyTagging"></div>\n\n<!--}}}-->\n
[img[http://cyberisland.ndap.org.tw/upload/album/2759_1.jpg]]\n[[數位島嶼|http://cyberisland.ndap.org.tw/]]\n呈現臺灣多樣性為主的網路相片平台,包含有多位名家的攝影作品\n近期並舉辦再現美麗島攝影比賽,非常吸引人喔!!\nhttp://content.ndap.org.tw/main/doc_detail.php?doc_id=1057
/***\n|Name|NestedSlidersPlugin|\n|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|\n|Version|2.0.2|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Slider.prototype.stop|\n|Description|Make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content.|\n\n++++!!!!![Configuration]>\nDebugging messages for 'lazy sliders' deferred rendering:\n<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering\n<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered\n===\n++++!!!!![Usage]>\nWhen installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created. This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.\n\nAdditional optional syntax elements let you specify\n*default to open\n*cookiename\n*heading level\n*floater (with optional CSS width value)\n*mouse auto rollover\n*custom class/label/tooltip/accesskey\n*automatic blockquote\n*deferred rendering\nThe complete syntax, using all options, is:\n//{{{\n++++(cookiename)!!!!!^width^*{{class{[label=key|tooltip]}}}>...\ncontent goes here\n===\n//}}}\nwhere:\n* {{{+++}}} (or {{{++++}}}) and {{{===}}}^^\nmarks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.^^\n* {{{(cookiename)}}}^^\nsaves the slider opened/closed state, and restores this state whenever the slider is re-rendered.^^\n* {{{!}}} through {{{!!!!!}}}^^\ndisplays the slider label using a formatted headline (Hn) style instead of a button/link style^^\n* {{{^width^}}} (or just {{{^}}})^^\nmakes the slider 'float' on top of other content rather than shifting that content downward. 'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.). If omitted, the default width is "auto" (i.e., fit to content)^^\n* {{{*}}}^^\nautomatically opens/closes slider on "rollover" as well as when clicked^^\n* {{{{{class{[label=key|tooltip]}}}}}}^^\nuses custom label/tooltip/accesskey. {{{{{class{...}}}}}}, {{{=key}}} and {{{|tooltip}}} are optional. 'class' is any valid CSS class name, used to style the slider label text. 'key' must be a ''single letter only''. Default labels/tootips are: ">" (more) and "<" (less), with no default access key assignment.^^\n* {{{">"}}} //(without the quotes)//^^\nautomatically adds blockquote formatting to slider content^^\n* {{{"..."}}} //(without the quotes)//^^\ndefers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//^^\n\n//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//\n===\n++++!!!!![Examples]>\nsimple in-line slider: \n{{{\n+++\n content\n===\n}}}\n+++\n content\n===\n----\nuse a custom label and tooltip: \n{{{\n+++[label|tooltip]\n content\n===\n}}}\n+++[label|tooltip]\n content\n===\n----\ncontent automatically blockquoted: \n{{{\n+++>\n content\n===\n}}}\n+++>\n content\n===\n----\nall options combined //(default open, cookie, heading, sized floater, rollover, class, label/tooltip/key, blockquoted, deferred)//\n{{{\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n}}}\n++++(testcookie)!!!^30em^*{{big{[label=Z|click or press Alt-Z to open]}}}>...\n content\n===\n----\ncomplex nesting example:\n{{{\n+++^[get info...=I|click for information or press Alt-I]\n put some general information here, plus a floating slider with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n}}}\n+++^[get info...=I|click for information or press Alt-I]\n put some general information here, plus a floating slider with more specific info:\n +++^10em^[view details...|click for details]\n put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===\n ===\n===\n===\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)\n<<<\n!!!!!Revision History\n<<<\n''2007.03.01 - 2.0.2'' for TW2.2+, hijack Morpher.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends\n''2007.03.01 - 2.0.1'' in hijack for Slider.prototype.stop, use apply() to pass params to core function\n|please see [[NestedSlidersPluginHistory]] for additional revision details|\n''2005.11.03 - 1.0.0'' initial public release\n<<<\n!!!!!Credits\n<<<\nThis feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.nestedSliders = {major: 2, minor: 0, revision: 2, date: new Date(2007,3,2)};\n//}}}\n\n//{{{\n// options for deferred rendering of sliders that are not initially displayed\nif (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;\nif (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;\n\n// default styles for 'floating' class\nsetStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \s\n background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");\n//}}}\n\n//{{{\nconfig.formatters.push( {\n name: "nestedSliders",\n match: "\s\sn?\s\s+{3}",\n terminator: "\s\ss*\s\s={3}\s\sn?",\n lookahead: "\s\sn?\s\s+{3}(\s\s+)?(\s\s([^\s\s)]*\s\s))?(\s\s!*)?(\s\s^(?:[^\s\s^\s\s*\s\s[\s\s>]*\s\s^)?)?(\s\s*)?(?:\s\s{\s\s{([\s\sw]+[\s\ss\s\sw]*)\s\s{)?(\s\s[[^\s\s]]*\s\s])?(?:\s\s}{3})?(\s\s>)?(\s\s.\s\s.\s\s.)?\s\ss*",\n handler: function(w)\n {\n // defopen=lookaheadMatch[1]\n // cookiename=lookaheadMatch[2]\n // header=lookaheadMatch[3]\n // panelwidth=lookaheadMatch[4]\n // rollover=lookaheadMatch[5]\n // class=lookaheadMatch[6]\n // label=lookaheadMatch[7]\n // blockquote=lookaheadMatch[8]\n // deferred=lookaheadMatch[9]\n\n lookaheadRegExp = new RegExp(this.lookahead,"mg");\n lookaheadRegExp.lastIndex = w.matchStart;\n var lookaheadMatch = lookaheadRegExp.exec(w.source)\n if(lookaheadMatch && lookaheadMatch.index == w.matchStart)\n {\n // location for rendering button and panel\n var place=w.output;\n\n // default to closed, no cookie, no accesskey\n var show="none"; var title=">"; var tooltip="show"; var cookie=""; var key="";\n\n // extra "+", default to open\n if (lookaheadMatch[1])\n { show="block"; title="<"; tooltip="hide"; }\n\n // cookie, use saved open/closed state\n if (lookaheadMatch[2]) {\n cookie=lookaheadMatch[2].trim().slice(1,-1);\n cookie="chkSlider"+cookie;\n if (config.options[cookie]==undefined)\n { config.options[cookie] = (show=="block") }\n if (config.options[cookie])\n { show="block"; title="<"; tooltip="hide"; }\n else\n { show="none"; title=">"; tooltip="show"; }\n }\n\n // parse custom label/tooltip/accesskey: [label=X|tooltip]\n if (lookaheadMatch[7]) {\n title = lookaheadMatch[7].trim().slice(1,-1);\n var pos=title.indexOf("|");\n if (pos!=-1) { tooltip = title.substr(pos+1,title.length); title=title.substr(0,pos); }\n if (title.substr(title.length-2,1)=="=") { key=title.substr(title.length-1,1); title=title.slice(0,-2); }\n if (pos==-1) tooltip += " "+title; // default tooltip: "show/hide <title>"\n }\n\n // create the button\n if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link\n var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;\n var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,lookaheadMatch[6],title);\n btn.onclick=onClickNestedSlider;\n btn.setAttribute("href","javascript:;");\n btn.setAttribute("title",tooltip);\n }\n else\n var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,lookaheadMatch[6]);\n\n // set extra button attributes\n btn.sliderCookie = cookie; // save the cookiename (if any) in the button object\n btn.defOpen=lookaheadMatch[1]!=null; // save default open/closed state (boolean)\n btn.keyparam=key; // save the access key letter ("" if none)\n if (key.length) {\n btn.setAttribute("accessKey",key); // init access key\n btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus\n }\n\n // "non-click" MouseOver open/close slider\n if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;\n\n // create slider panel\n var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";\n var panel=createTiddlyElement(place,"div",null,panelClass,null);\n panel.button = btn; // so the slider panel know which button it belongs to\n panel.defaultPanelWidth=(lookaheadMatch[4] && lookaheadMatch[4].length>2)?lookaheadMatch[4].slice(1,-1):""; // save requested panel size\n btn.sliderPanel=panel;\n panel.style.display = show;\n panel.style.width=panel.defaultPanelWidth;\n\n // render slider (or defer until shown) \n w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;\n if ((show=="block")||!lookaheadMatch[9]) {\n // render now if panel is supposed to be shown or NOT deferred rendering\n w.subWikify(lookaheadMatch[8]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);\n // align slider/floater position with button\n window.adjustSliderPos(place,btn,panel,panelClass);\n }\n else {\n var src = w.source.substr(w.nextMatch);\n var endpos=findMatchingDelimiter(src,"+++","===");\n panel.setAttribute("raw",src.substr(0,endpos));\n panel.setAttribute("blockquote",lookaheadMatch[8]?"true":"false");\n panel.setAttribute("rendered","false");\n w.nextMatch += endpos+3;\n if (w.source.substr(w.nextMatch,1)=="\sn") w.nextMatch++;\n if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\sn\sn"+panel.getAttribute("raw"));\n }\n }\n }\n }\n)\n\n// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)\nfunction findMatchingDelimiter(src,starttext,endtext) {\n var startpos = 0;\n var endpos = src.indexOf(endtext);\n // check for nested delimiters\n while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {\n // count number of nested 'starts'\n var startcount=0;\n var temp = src.substring(startpos,endpos-1);\n var pos=temp.indexOf(starttext);\n while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }\n // set up to check for additional 'starts' after adjusting endpos\n startpos=endpos+endtext.length;\n // find endpos for corresponding number of matching 'ends'\n while (startcount && endpos!=-1) {\n endpos = src.indexOf(endtext,endpos+endtext.length);\n startcount--;\n }\n }\n return (endpos==-1)?src.length:endpos;\n}\n//}}}\n\n//{{{\nwindow.onClickNestedSlider=function(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n var theLabel = theTarget.firstChild.data;\n var theSlider = theTarget.sliderPanel\n var isOpen = theSlider.style.display!="none";\n // if using default button labels, toggle labels\n if (theLabel==">") theTarget.firstChild.data = "<";\n else if (theLabel=="<") theTarget.firstChild.data = ">";\n // if using default tooltips, toggle tooltips\n if (theTarget.getAttribute("title")=="show")\n theTarget.setAttribute("title","hide");\n else if (theTarget.getAttribute("title")=="hide")\n theTarget.setAttribute("title","show");\n if (theTarget.getAttribute("title")=="show "+theLabel)\n theTarget.setAttribute("title","hide "+theLabel);\n else if (theTarget.getAttribute("title")=="hide "+theLabel)\n theTarget.setAttribute("title","show "+theLabel);\n // deferred rendering (if needed)\n if (theSlider.getAttribute("rendered")=="false") {\n if (config.options.chkDebugLazySliderRender)\n alert("rendering '"+theLabel+"':\sn\sn"+theSlider.getAttribute("raw"));\n var place=theSlider;\n if (theSlider.getAttribute("blockquote")=="true")\n place=createTiddlyElement(place,"blockquote");\n wikify(theSlider.getAttribute("raw"),place);\n theSlider.setAttribute("rendered","true");\n }\n // show/hide the slider\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n theSlider.style.display = isOpen ? "none" : "block";\n // reset to default width (might have been changed via plugin code)\n theSlider.style.width=theSlider.defaultPanelWidth;\n // align slider/floater position with target button\n if (!isOpen) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);\n // if showing panel, set focus to first 'focus-able' element in panel\n if (theSlider.style.display!="none") {\n var ctrls=theSlider.getElementsByTagName("*");\n for (var c=0; c<ctrls.length; c++) {\n var t=ctrls[c].tagName.toLowerCase();\n if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")\n { ctrls[c].focus(); break; }\n }\n }\n if (this.sliderCookie && this.sliderCookie.length) {\n config.options[this.sliderCookie]=!isOpen;\n if (config.options[this.sliderCookie]!=this.defOpen)\n saveOptionCookie(this.sliderCookie);\n else { // remove cookie if slider is in default display state\n var ex=new Date(); ex.setTime(ex.getTime()-1000);\n document.cookie = this.sliderCookie+"=novalue; path=/; expires="+ex.toGMTString();\n }\n }\n return false;\n}\n\n// TW2.1 and earlier:\n// hijack Slider animation handler 'stop' handler so overflow is visible after animation has completed\nSlider.prototype.coreStop = Slider.prototype.stop;\nSlider.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n\n// TW2.2+\n// hijack Morpher animation handler 'stop' handler so overflow is visible after animation has completed\nif (version.major+.1*version.minor+.01*version.revision>=2.2) {\n Morpher.prototype.coreStop = Morpher.prototype.stop;\n Morpher.prototype.stop = function()\n { this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }\n}\n\n// adjust panel position based on button position\nif (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {\n if (panelClass=="floatingPanel") {\n var left=0;\n var top=btn.offsetHeight; \n if (place.style.position!="relative") {\n var left=findPosX(btn);\n var top=findPosY(btn)+btn.offsetHeight;\n var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;\n if (p) { left-=findPosX(p); top-=findPosY(p); }\n }\n if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth-15;\n panel.style.left=left+"px"; panel.style.top=top+"px";\n }\n}\n\nfunction getWindowWidth() {\n if(document.width!=undefined)\n return document.width; // moz (FF)\n if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )\n return document.documentElement.clientWidth; // IE6\n if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )\n return document.body.clientWidth; // IE4\n if(window.innerWidth!=undefined)\n return window.innerWidth; // IE - general\n return 0; // unknown\n}\n//}}}
<html>\n<style>\n.rolodex table {\nborder: 0px solid;\nbackground-color:#eeeff;\n}\n\n.rolodex tr, .rolodex td {\nborder: 0px solid;\n}\n</style>\n<span class="rolodex">\n <table>\n <tr>\n <td align="right"><b>Author(s):</b></td>\n <td colspan="3"><input name=author type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Article title (put in "quotes"):</b></td>\n <td colspan="3"><input name=articletitle type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Journal Title:</b></td>\n <td colspan="3"><input name=journalinfo type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Volume (year): page numbers:</b></td>\n <td colspan="3"><input name=pagenumbers type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Call number:</b></td>\n <td colspan="3"><input name=callnumber type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Where I keep it:</b></td>\n <td colspan="3"><input name=location type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>Primary topic:</b></td>\n <td colspan="3"><input name=primtopic type=text style="width:180%" /></td></tr>\n <tr></span> </html>\n1. In viewing mode, add data to form fields\n2. In edit mode, add your notes below and in the bottom window add extra tags for any additional topics\n3. In edit mode, add an url for an image of the magazine or journal cover at the top of the tiddler if you wish. Here's how: {{{[img[YOUR URL HERE]]}}}\n\n! Notes\n
<html>\n<style>\n.rolodex table {\nborder: 0px solid;\nbackground-color:#eeeff;\n}\n\n.rolodex tr, .rolodex td {\nborder: 0px solid;\n}\n</style>\n<span class="rolodex">\n <table>\n <tr>\n <td align="right"><b>作者:</b></td>\n <td colspan="3"><input name=author type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>書名:</b></td>\n <td colspan="3"><input name=booktitle type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>出版社:</b></td>\n <td colspan="3"><input name=pubinfo type=text style="font-style:italic; width:180%;" /></td></tr>\n <tr>\n <td align="right"><b>編號:</b></td>\n <td colspan="3"><input name=callnumber type=text style="width:180%" /></td></tr>\n <tr>\n<td align="right"><b>已購買:</b></td>\n<input name=mine type=checkbox /></td></tr>\n <td align="right"><b>購買地點:</b></td>\n <td colspan="3"><input name=location type=text style="width:180%" /></td></tr>\n <tr>\n <td align="right"><b>主題:</b></td>\n <td colspan="3"><input name=primtopic type=text style="width:180%" /></td></tr>\n <tr>\n</span> </html>\n! Notes\n
/***\n| Name:|NewHerePlugin|\n| Description:|Creates the new here and new journal macros|\n| Version:|3.0 ($Rev: 1845 $)|\n| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|\n| Author:|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\nmerge(config.macros, {\n newHere: {\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);\n }\n },\n newJournalHere: {\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);\n }\n }\n});\n\n//}}}\n\n
<!--{{{-->\n<div class='header'>\n <div class='gradient' macro='gradient vert #FF8614 #DA4A0D '>\n <div class='titleLine' >\n <span class='searchBar' macro='search'></span>\n <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> \n <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n </div>\n<div id='topMenu' refresh='content' tiddler='MainMenu'></div>\n </div>\n</div>\n<div id='bodywrapper'>\n<div id='sidebar'>\n <div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n <div id='messageArea'></div>\n <div id='tiddlerDisplay'></div>\n</div>\n<div id='contentFooter' refresh='content' tiddler='contentFooter'></div>\n</div>\n\n<!--}}}-->
/***\n|Name|PlayerPlugin|\n|Source|http://www.TiddlyTools.com/#PlayerPlugin|\n|Version|1.0.1|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description|Embed a media player in a tiddler|\n\n!!!!!Usage\n<<<\n{{{<<player [type] [URL] [width] [height] [hidecontrols]>>}}}\n\nwhere ''type'' is optional, and is one of the following: ''windows'', ''realone'', ''quicktime'', ''flash'' or ''image''. If the media type is not specified, the plugin automatically detects Windows, Real, QuickTime, Flash video or JPG/GIF images by matching known file extensions and/or specialized streaming-media transfer protocols (such as RTSP:). For unrecognized media types, the plugin assumes WindowsMedia (the player with the most users... *sigh*)\n\n''If you use [[AttachFilePlugin]] to encode and store a media file within your document, you can play embedded media content by using the title of the //attachment tiddler//'' as a parameter in place of the usual reference to an external URL. When playing an attached media content, you should always explicitly specify the media type parameter, because the name used for the attachment tiddler may not contain a known file extension from which a default media type can be readily determined.\n<<<\n!!!!!Configuration\n<<<\nDefault player size:\nwidth: <<option txtPlayerDefaultWidth>> height: <<option txtPlayerDefaultHeight>>\n<<<\n!!!!!Examples\n<<<\n+++[Windows Media]...\nTimes Square Live Webcam\n{{{<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>}}}\n<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>\n===\n+++[RealOne]...\nBBC London: Live and Recorded news\n{{{<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>}}}\n<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>\n===\n+++[Quicktime]...\nAmerica Free TV: Classic Comedy\n{{{<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>}}}\n<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>\n===\n+++[Flash]...\nAsteroids arcade game\n{{{<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>}}}\n<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>\nGoogle Video\n{{{<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774 400 326>>}}}\n<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774 400 326>>\nYouTube Video\n{{{<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>}}}\n<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>\n===\n+++[Still Images]...\nGIF (best for illustrations, animations, diagrams, etc.)\n{{{<<player id=7 image images/meow.gif auto auto>>}}}\n<<player id=7 image images/meow.gif auto auto>>\nJPG (best for photographs, scanned images, etc.)\n{{{<<player id=8 image images/meow2.jpg 200 150>>}}}\n<<player id=8 image images/meow2.jpg 200 150>>\n===\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''PlayerPlugin '' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for macro handling^^\n<<<\n!!!!!Revision History\n<<<\n''2006.12.06 [1.0.1]'' in handler(), corrected check for config.macros.attach (instead of config.macros.attach.getAttachment) so that player plugin will work when AttachFilePlugin is NOT installed. (Thanks to Phillip Ehses for bug report)\n''2006.11.30 [1.0.0]'' support embedded media content using getAttachment() API defined by AttachFilePlugin or AttachFilePluginFormatters. Also added support for 'image' type to render JPG/GIF still images\n''2006.02.26 [0.7.0]'' major re-write. handles default params better. create/recreate player objects via loadURL() API for use with interactive forms and scripts.\n''2006.01.27 [0.6.0]'' added support for 'extra' macro params to pass through to object parameters\n''2006.01.19 [0.5.0]'' Initial ALPHA release\n''2005.12.23 [0.0.0]'' Started\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\n<<<\n!!!!!Code\n***/\n\n// // macro definition\n\n//{{{\nversion.extensions.player = {major: 1, minor: 0, revision: 1, date: new Date(2006,12,6)};\n\nconfig.macros.player = {};\nconfig.macros.player.html = {};\nconfig.macros.player.handler= function(place,macroName,params) {\n var id=null;\n if (params[0].substr(0,3)=="id=") id=params.shift().substr(3);\n var type="";\n if ((params[0]=="windows")||(params[0]=="realone")||(params[0]=="quicktime")||(params[0]=="flash")||(params[0]=="image"))\n type=params.shift();\n var url=params.shift(); if (!url || !url.trim().length) url="";\n if (url.length && config.macros.attach!=undefined) // if AttachFilePlugin is installed\n if ((tid=store.getTiddler(url))!=null && tid.isTagged("attachment")) // if URL is attachment tiddler title\n url=config.macros.attach.getAttachment(url); // replace TiddlerTitle with attachment-expanded URL\n var width=params.shift();\n var height=params.shift();\n var show=(params.shift()=='hidecontrols')?"0":"1"; \n var extras=""; while (params[0]!=undefined) extras+="<param name='"+params.shift()+"' value='"+params.shift()+"'> ";\n this.loadURL(place,id,type,url,width,height,show,extras);\n}\n\nif (config.options.txtPlayerDefaultWidth==undefined) config.options.txtPlayerDefaultWidth="100%";\nif (config.options.txtPlayerDefaultHeight==undefined) config.options.txtPlayerDefaultHeight="480"; // can't use "100%"... player height doesn't stretch right :-(\n\nconfig.macros.player.loadURL=function(place,id,type,url,width,height,show,extras) {\n\n if (id==undefined) id="tiddlyPlayer";\n if (!width) var width=config.options.txtPlayerDefaultWidth;\n if (!height) var height=config.options.txtPlayerDefaultHeight;\n if (url && (!type || !type.length)) { // determine type from URL\n u=url.toLowerCase();\n if ((u.indexOf('mms')!=-1)||(u.indexOf('.asx')!=-1)||(u.indexOf('.wvx')!=-1)||(u.indexOf('.wmv')!=-1)||(u.indexOf('.mp3')!=-1))\n var type="windows";\n else if ((u.indexOf('rtsp')!=-1)||(u.indexOf('.ram')!=-1)||(u.indexOf('.rpm')!=-1)||(u.indexOf('.rm' )!=-1)||(u.indexOf('.ra' )!=-1))\n var type="realone";\n else if ((u.indexOf('.mov')!=-1)||(u.indexOf('.qt' )!=-1))\n var type="quicktime";\n else if ((u.indexOf('.swf')!=-1)||(u.indexOf('.flv')!=-1))\n var type="flash";\n else if ((u.indexOf('.jpg')!=-1)||(u.indexOf('.gif')!=-1))\n var type="image";\n }\n if (!type) var type="none";\n if (!url) var url="";\n if (show===undefined) var show=true;\n if (!extras) var extras="";\n if (type=="none" && url.trim().length) url="<br>unrecognized media type:<br>"+url;\n if (type=="realone") height-=show?60:0; // leave room for controls\n if (type=="windows") show=show?"1":"0"; // player-specific param value\n if (type=="realone") show=show?"block":"none";\n if (type=="quicktime") show=show?"true":"false";\n if (type=="image") show=show?"block":"none";\n\n // create containing div for player HTML\n // and add or replace player in TW DOM structure\n var newplayer = document.createElement("div");\n newplayer.playerType=type;\n newplayer.setAttribute("id",id+"_div");\n var existing = document.getElementById(id+"_div");\n if (existing && !place) place=existing.parentNode;\n if (!existing)\n place.appendChild(newplayer);\n else {\n if (place==existing.parentNode) place.replaceChild(newplayer,existing)\n else { existing.parentNode.removeChild(existing); place.appendChild(newplayer); }\n }\n\n var html=config.macros.player.html[type];\n html=html.replace(/%i%/mg,id);\n html=html.replace(/%w%/mg,width);\n html=html.replace(/%h%/mg,height);\n html=html.replace(/%u%/mg,url);\n html=html.replace(/%s%/mg,show);\n html=html.replace(/%x%/mg,extras);\n newplayer.innerHTML=html;\n}\n//}}}\n\n// // Player-specific API functions: isReady(id), isPlaying(id), toggleControls(id), showControls(id,flag)\n\n//{{{\n// status values:\n// Windows: 0=Undefined, 1=Stopped, 2=Paused, 3=Playing, 4=ScanForward, 5=ScanReverse\n// 6=Buffering, 7=Waiting, 8=MediaEnded, 9=Transitioning, 10=Ready, 11=Reconnecting\n// RealOne: 0=Stopped, 1=Contacting, 2=Buffering, 3=Playing, 4=Paused, 5=Seeking\n// QuickTime: 'Waiting', 'Loading', 'Playable', 'Complete', 'Error:###'\n// Flash: 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete\nconfig.macros.player.isReady=function(id)\n{\n var d=document.getElementById(id+"_div"); if (!d) return false;\n var p=document.getElementById(id); if (!p) return false;\n if (d.playerType=='windows') return !((p.playState==0)||(p.playState==7)||(p.playState==9)||(p.playState==11));\n if (d.playerType=='realone') return (p.GetPlayState()>1);\n if (d.playerType=='quicktime') return !((p.getPluginStatus()=='Waiting')||(p.getPluginStatus()=='Loading'));\n if (d.playerType=='flash') return (p.ReadyState>2);\n return true;\n}\nconfig.macros.player.isPlaying=function(id)\n{\n var d=document.getElementById(id+"_div"); if (!d) return false;\n var p=document.getElementById(id); if (!p) return false;\n if (d.playerType=='windows') return (p.playState==3);\n if (d.playerType=='realone') return (p.GetPlayState()==3);\n if (d.playerType=='quicktime') return (p.getPluginStatus()=='Complete');\n if (d.playerType=='flash') return (p.ReadyState<4);\n return false;\n}\nconfig.macros.player.showControls=function(id,flag) {\n var d=document.getElementById(id+"_div"); if (!d) return false;\n var p=document.getElementById(id); if (!p) return false;\n if (d.playerType=='windows') { p.ShowControls=flag; p.ShowStatusBar=flag; }\n if (d.playerType=='realone') { alert('show/hide controls not available'); }\n if (d.playerType=='quicktime') // if player not ready, retry in one second\n { if (this.isReady(id)) p.setControllerVisible(flag); else setTimeout('config.macros.player.showControls("'+id+'",'+flag+')',1000); }\n if (d.playerType=='flash') { alert('show/hide controls not available'); }\n}\nconfig.macros.player.toggleControls=function(id) {\n var d=document.getElementById(id+"_div"); if (!d) return false;\n var p=document.getElementById(id); if (!p) return false;\n if (d.playerType=='windows') var flag=!p.ShowControls;\n if (d.playerType=='realone') var flag=true; // TBD\n if (d.playerType=='quicktime') var flag=!p.getControllerVisible();\n if (d.playerType=='flash') var flag=true; // TBD\n this.showControls(id,flag);\n}\nconfig.macros.player.fullScreen=function(id) {\n var d=document.getElementById(id+"_div"); if (!d) return false;\n var p=document.getElementById(id); if (!p) return false;\n if (d.playerType=='windows') p.DisplaySize=3;\n if (d.playerType=='realone') p.SetFullScreen();\n if (d.playerType=='quicktime') { alert('full screen not available'); }\n if (d.playerType=='flash') { alert('full screen not available'); }\n}\n//}}}\n\n// // Player HTML\n\n//{{{\n// placeholder (no player)\nconfig.macros.player.html.none=' \s\n <table id="%i%" width="%w%" height="%h%" style="background-color:#111;border:0;margin:0;padding:0;"> \s\n <tr style="background-color:#111;border:0;margin:0;padding:0;"> \s\n <td width="%w%" height="%h%" style="background-color:#111;color:#ccc;border:0;margin:0;padding:0;text-align:center;"> \s\n \s\n %u% \s\n \s\n </td></tr></table>';\n//}}}\n\n//{{{\n// JPG/GIF still images\nconfig.macros.player.html.image='\s\n <img width="%w%" height="%h%" style="display:%s%;" src="%u%">';\n//}}}\n\n//{{{\n// Windows Media Player\n// v7.1 ID: classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6\n// v9 ID: classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95\nconfig.macros.player.html.windows=' \s\n <object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \s\n classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" \s\n codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" \s\n align="baseline" border="0" \s\n standby="Loading Microsoft Windows Media Player components..." \s\n type="application/x-oleobject"> \s\n <param name="FileName" value="%u%"> <param name="ShowControls" value="%s%"> \s\n <param name="ShowPositionControls" value="1"> <param name="ShowAudioControls" value="1"> \s\n <param name="ShowTracker" value="1"> <param name="ShowDisplay" value="0"> \s\n <param name="ShowStatusBar" value="1"> <param name="AutoSize" value="1"> \s\n <param name="ShowGotoBar" value="0"> <param name="ShowCaptioning" value="0"> \s\n <param name="AutoStart" value="1"> <param name="AnimationAtStart" value="1"> \s\n <param name="TransparentAtStart" value="0"> <param name="AllowScan" value="1"> \s\n <param name="EnableContextMenu" value="1"> <param name="ClickToPlay" value="1"> \s\n <param name="InvokeURLs" value="1"> <param name="DefaultFrame" value="datawindow"> \s\n %x% \s\n <embed src="%u%" style="margin:0;padding:0;" \s\n align="baseline" border="0" width="%w%" height="%h%" \s\n type="application/x-mplayer2" \s\n pluginspage="http://www.microsoft.com/windows/windowsmedia/download/default.asp" \s\n name="%i%" showcontrols="%s%" showpositioncontrols="1" \s\n showaudiocontrols="1" showtracker="1" showdisplay="0" \s\n showstatusbar="%s%" autosize="1" showgotobar="0" showcaptioning="0" \s\n autostart="1" autorewind="0" animationatstart="1" transparentatstart="0" \s\n allowscan="1" enablecontextmenu="1" clicktoplay="0" invokeurls="1" \s\n defaultframe="datawindow"> \s\n </embed> \s\n </object>';\n//}}}\n\n//{{{\n// RealNetworks' RealOne Player\nconfig.macros.player.html.realone=' \s\n <table width="%w%" style="border:0;margin:0;padding:0;"><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \s\n <object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \s\n CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \s\n <PARAM NAME="CONSOLE" VALUE="player"> \s\n <PARAM NAME="CONTROLS" VALUE="ImageWindow"> \s\n <PARAM NAME="AUTOSTART" Value="true"> \s\n <PARAM NAME="MAINTAINASPECT" Value="true"> \s\n <PARAM NAME="NOLOGO" Value="true"> \s\n <PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \s\n <PARAM NAME="SRC" VALUE="%u%"> \s\n %x% \s\n <EMBED width="%w%" height="%h%" controls="ImageWindow" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;" \s\n name="%i%" \s\n src="%u%" \s\n console=player \s\n maintainaspect=true \s\n nologo=true \s\n backgroundcolor=#333333 \s\n autostart=true> \s\n </OBJECT> \s\n </td></tr><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \s\n <object id="%i%_controls" width="%w%" height="60" style="margin:0;padding:0;display:%s%" \s\n CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \s\n <PARAM NAME="CONSOLE" VALUE="player"> \s\n <PARAM NAME="CONTROLS" VALUE="All"> \s\n <PARAM NAME="NOJAVA" Value="true"> \s\n <PARAM NAME="MAINTAINASPECT" Value="true"> \s\n <PARAM NAME="NOLOGO" Value="true"> \s\n <PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \s\n <PARAM NAME="SRC" VALUE="%u%"> \s\n %x% \s\n <EMBED WIDTH="%w%" HEIGHT="60" NOJAVA="true" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;display:%s%" \s\n controls="All" \s\n name="%i%_controls" \s\n src="%u%" \s\n console=player \s\n maintainaspect=true \s\n nologo=true \s\n backgroundcolor=#333333> \s\n </OBJECT> \s\n </td></tr></table>';\n//}}}\n\n//{{{\n// QuickTime Player\nconfig.macros.player.html.quicktime=' \s\n <OBJECT ID="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \s\n CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" \s\n CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab"> \s\n <PARAM name="SRC" VALUE="%u%"> \s\n <PARAM name="AUTOPLAY" VALUE="true"> \s\n <PARAM name="CONTROLLER" VALUE="%s%"> \s\n <PARAM name="BGCOLOR" VALUE="#333333"> \s\n <PARAM name="SCALE" VALUE="aspect"> \s\n <PARAM name="SAVEEMBEDTAGS" VALUE="true"> \s\n %x% \s\n <EMBED name="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \s\n SRC="%u%" \s\n AUTOPLAY="true" \s\n SCALE="aspect" \s\n CONTROLLER="%s%" \s\n BGCOLOR="#333333" \s\n EnableJavaSript="true" \s\n PLUGINSPAGE="http://www.apple.com/quicktime/download/"> \s\n </EMBED> \s\n </OBJECT>';\n//}}}\n\n//{{{\n// Flash Player\nconfig.macros.player.html.flash='\s\n <object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \s\n classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \s\n codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"> \s\n <param name="movie" value="%u%"> \s\n <param name="quality" value="high"> \s\n <param name="SCALE" value="exactfit"> \s\n <param name="bgcolor" value="333333"> \s\n %x% \s\n <embed name="%i%" src="%u%" style="margin:0;padding:0;" \s\n height="%h%" width="%w%" quality="high" \s\n pluginspage="http://www.macromedia.com/go/getflashplayer" \s\n type="application/x-shockwave-flash" scale="exactfit"> \s\n </embed> \s\n </object>';\n//}}}
/***\n|''Name:''|~PopupMacro|\n|''Version:''|1.0.0 (2006-05-09)|\n|''Source:''|http://tw.lewcid.org/#PopupMacro|\n|''Author:''|Saq Imtiaz|\n|''Description:''|Create popups with custom content|\n|''Documentation:''|[[PopupMacro Documentation|PopupMacroDocs]]|\n|''~Requires:''|TW Version 2.0.8 or better|\n***/\n// /%\n{{{\nconfig.macros.popup = {};\nconfig.macros.popup.arrow = (document.all?"▼":"▾");\nconfig.macros.popup.handler = function(place,macroName,params,wikifier,paramString,theTiddler) {\n\n if (!params[0] || !params[1]) \n {createTiddlyError(place,'missing macro parameters','missing label or content parameter');\n return false;};\n \n var label = params[0];\n var source = (params[1]).replace(/\s$\s)\s)/g,">>"); \n var nestedId = params[2]? params[2]: 'nestedpopup'; \n\n var onclick = function(event) {\n if(!event){var event = window.event;}\n var theTarget = resolveTarget(event);\n var nested = (!isNested(theTarget));\n \n if ((Popup.stack.length > 1)&&(nested==true)) {Popup.removeFrom(1);}\n else if(Popup.stack.length > 0 && nested==false) {Popup.removeFrom(0);};\n \n var theId = (nested==false)? "popup" : nestedId; \n var popup = createTiddlyElement(document.body,"ol",theId,"popup",null);\n Popup.stack.push({root: button, popup: popup});\n\n wikify(source,popup);\n Popup.show(popup,true);\n event.cancelBubble = true;\n if (event.stopPropagation) event.stopPropagation();\n return false;\n }\n var button = createTiddlyButton(place, label+this.arrow,label, onclick, null);\n};\n\nwindow.isNested = function(e) {\n while (e != null) {\n var contentWrapper = document.getElementById("contentWrapper");\n if (contentWrapper == e) return true;\n e = e.parentNode;\n }\n return false;\n};\n\nsetStylesheet(\n".popup, .popup a, .popup a:visited {color: #fff;}\sn"+\n".popup a:hover {background: #014; color: #fff; border: none;}\sn"+\n".popup li , .popup ul, .popup ol {list-style:none !important; margin-left:0.3em !important; margin-right:0.3em; font-size:100%; padding-top:0.5px !important; padding:0px !important;}\sn"+\n"#nestedpopup {background:#2E5ADF; border: 1px solid #0331BF; margin-left:1em; }\sn"+\n"",\n"CustomPopupStyles");\n\nconfig.shadowTiddlers.PopupMacroDocs="The documentation is available [[here.|http://tw.lewcid.org/#PopupMacroDocs]]";\n}}}\n//%/
/***\n| Name|QuickOpenTagPlugin|\n| Description|Changes tag links to make it easier to open tags as tiddlers|\n| Version|3.0 ($Rev: 1845 $)|\n| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n***/\n//{{{\nconfig.quickOpenTag = {\n\n dropdownChar: (document.all ? "\su25bc" : "\su25be"), // the little one doesn't work in IE?\n\n createTagButton: function(place,tag,excludeTiddler) {\n // little hack so we can to <<tag PrettyTagName|RealTagName>>\n var splitTag = tag.split("|");\n var pretty = tag;\n if (splitTag.length == 2) {\n tag = splitTag[1];\n pretty = splitTag[0];\n }\n \n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyText(createTiddlyLink(sp,tag,false),pretty);\n \n var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,\n config.views.wikified.tag.tooltip.format([tag]),onClickTag);\n theTag.setAttribute("tag",tag);\n if (excludeTiddler)\n theTag.setAttribute("tiddler",excludeTiddler);\n return(theTag);\n },\n\n miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {\n var tagged = store.getTaggedTiddlers(tiddler.title);\n if (tagged.length > 0) {\n var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,\n config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n },\n\n allTagsHandler: function(place,macroName,params) {\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul");\n if(tags.length == 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++) {\n var theListItem = createTiddlyElement(theDateList,"li");\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n var theDropDownBtn = createTiddlyButton(theListItem," " +\n config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n },\n\n // todo fix these up a bit\n styles: [\n"/*{{{*/",\n"/* created by QuickOpenTagPlugin */",\n".tagglyTagged .quickopentag, .tagged .quickopentag ",\n" { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }",\n".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }",\n".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}",\n"/* extra specificity to make it work right */",\n"#displayArea .viewer .quickopentag a.button, ",\n"#displayArea .viewer .quickopentag a.tiddyLink, ",\n"#mainMenu .quickopentag a.tiddyLink, ",\n"#mainMenu .quickopentag a.tiddyLink ",\n" { border:0px solid black; }",\n"#displayArea .viewer .quickopentag a.button, ",\n"#mainMenu .quickopentag a.button ",\n" { margin-left:0px; padding-left:2px; }",\n"#displayArea .viewer .quickopentag a.tiddlyLink, ",\n"#mainMenu .quickopentag a.tiddlyLink ",\n" { margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }",\n"a.miniTag {font-size:150%;} ",\n"#mainMenu .quickopentag a.button ",\n" /* looks better in right justified main menus */",\n" { margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }", \n"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }",\n"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }",\n"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }",\n"/*}}}*/",\n ""].join("\sn"),\n\n init: function() {\n // we fully replace these builtins. can't hijack them easily\n window.createTagButton = this.createTagButton;\n config.macros.allTags.handler = this.allTagsHandler;\n config.macros.miniTag = { handler: this.miniTagHandler };\n config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;\n store.addNotification("QuickOpenTagStyles",refreshStyles);\n }\n}\n\nconfig.quickOpenTag.init();\n\n//}}}\n
/***\n|Name|RearrangeTiddlersPlugin|\n|Source|http://www.TiddlyTools.com/#RearrangeTiddlersPlugin|\n|Version|0.0.0|\n|Author|Joe Raii|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Story.prototype.refreshTiddler|\n|Description|drag tiddlers by title to re-order story column display|\n\nadapted from: http://www.cs.utexas.edu/~joeraii/dragn/#Draggable\nchanges by ELS:\n* hijack refreshTiddler() instead of overridding createTiddler()\n* find title element by className instead of elementID\n* set cursor style via code instead of stylesheet\n* set tooltip help text\n* set tiddler "position:relative" when starting drag event, restore saved value when drag ends\n* update 2006.08.07: use getElementsByTagName("*") to find title element, even when it is 'buried' deep in tiddler DOM elements (due to custom template usage)\n* update 2007.03.01: use apply() to invoke hijacked core function\n\n***/\n//{{{\n\nStory.prototype.rearrangeTiddlersHijack_refreshTiddler = Story.prototype.refreshTiddler;\nStory.prototype.refreshTiddler = function(title,template,unused1,unused2,unused3,unused4,unused5)\n{\n this.rearrangeTiddlersHijack_refreshTiddler.apply(this,arguments);\n var theTiddler = document.getElementById(this.idPrefix + title); if (!theTiddler) return;\n var theHandle;\n var children=theTiddler.getElementsByTagName("*");\n for (var i=0; i<children.length; i++) if (hasClass(children[i],"title")) { theHandle=children[i]; break; }\n if (!theHandle) return theTiddler;\n\n Drag.init(theHandle, theTiddler, 0, 0, null, null);\n theHandle.style.cursor="move";\n theHandle.title="drag title to re-arrange tiddlers"\n theTiddler.onDrag = function(x,y,myElem) {\n if (this.style.position!="relative")\n { this.savedstyle=this.style.position; this.style.position="relative"; }\n y = myElem.offsetTop;\n var next = myElem.nextSibling;\n var prev = myElem.previousSibling;\n if (next && y + myElem.offsetHeight > next.offsetTop + next.offsetHeight/2) { \n myElem.parentNode.removeChild(myElem);\n next.parentNode.insertBefore(myElem, next.nextSibling);//elems[pos+1]);\n myElem.style["top"] = -next.offsetHeight/2+"px";\n }\n if (prev && y < prev.offsetTop + prev.offsetHeight/2) { \n myElem.parentNode.removeChild(myElem);\n prev.parentNode.insertBefore(myElem, prev);\n myElem.style["top"] = prev.offsetHeight/2+"px";\n }\n };\n theTiddler.onDragEnd = function(x,y,myElem) {\n myElem.style["top"] = "0px";\n if (this.savedstyle!=undefined)\n this.style.position=this.savedstyle;\n }\n return theTiddler;\n}\n\n/**************************************************\n * dom-drag.js\n * 09.25.2001\n * www.youngpup.net\n **************************************************\n * 10.28.2001 - fixed minor bug where events\n * sometimes fired off the handle, not the root.\n **************************************************/\n\nvar Drag = {\n obj:null,\n\n init:\n function(o, oRoot, minX, maxX, minY, maxY) {\n o.onmousedown = Drag.start;\n o.root = oRoot && oRoot != null ? oRoot : o ;\n if (isNaN(parseInt(o.root.style.left))) o.root.style.left="0px";\n if (isNaN(parseInt(o.root.style.top))) o.root.style.top="0px";\n o.minX = typeof minX != 'undefined' ? minX : null;\n o.minY = typeof minY != 'undefined' ? minY : null;\n o.maxX = typeof maxX != 'undefined' ? maxX : null;\n o.maxY = typeof maxY != 'undefined' ? maxY : null;\n o.root.onDragStart = new Function();\n o.root.onDragEnd = new Function();\n o.root.onDrag = new Function();\n },\n\n start:\n function(e) {\n var o = Drag.obj = this;\n e = Drag.fixE(e);\n var y = parseInt(o.root.style.top);\n var x = parseInt(o.root.style.left);\n o.root.onDragStart(x, y, Drag.obj.root);\n o.lastMouseX = e.clientX;\n o.lastMouseY = e.clientY;\n if (o.minX != null) o.minMouseX = e.clientX - x + o.minX;\n if (o.maxX != null) o.maxMouseX = o.minMouseX + o.maxX - o.minX;\n if (o.minY != null) o.minMouseY = e.clientY - y + o.minY;\n if (o.maxY != null) o.maxMouseY = o.minMouseY + o.maxY - o.minY;\n document.onmousemove = Drag.drag;\n document.onmouseup = Drag.end;\n Drag.obj.root.style["z-index"] = "10";\n return false;\n },\n\n drag:\n function(e) {\n e = Drag.fixE(e);\n var o = Drag.obj;\n var ey = e.clientY;\n var ex = e.clientX;\n var y = parseInt(o.root.style.top);\n var x = parseInt(o.root.style.left);\n var nx, ny;\n if (o.minX != null) ex = Math.max(ex, o.minMouseX);\n if (o.maxX != null) ex = Math.min(ex, o.maxMouseX);\n if (o.minY != null) ey = Math.max(ey, o.minMouseY);\n if (o.maxY != null) ey = Math.min(ey, o.maxMouseY);\n nx = x + (ex - o.lastMouseX);\n ny = y + (ey - o.lastMouseY);\n Drag.obj.root.style["left"] = nx + "px";\n Drag.obj.root.style["top"] = ny + "px";\n Drag.obj.lastMouseX = ex;\n Drag.obj.lastMouseY = ey;\n Drag.obj.root.onDrag(nx, ny, Drag.obj.root);\n return false;\n },\n\n end:\n function() {\n document.onmousemove = null;\n document.onmouseup = null;\n Drag.obj.root.style["z-index"] = "0";\n Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style["left"]), parseInt(Drag.obj.root.style["top"]), Drag.obj.root);\n Drag.obj = null;\n },\n\n fixE:\n function(e) {\n if (typeof e == 'undefined') e = window.event;\n if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;\n if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;\n return e;\n }\n};\n//}}}\n
/***\n|''Name:''|RecentPlugin|\n|''Source:''| |\n|''Author:''|Tim Morgan (modified by Bram Chen)|\n|''Desc:''|Shows DefaultTiddlers + most recently modified tiddlers as default when any TiddlyWiki or adaptation is first loaded.|\n| |copy this tiddler's contents to a new tiddler on your site and tag it "systemConfig".|\n''Syntax:'' {{{}}}\n\n''Revision history:''\n* v0.1.0 (Mar 13, 2006) modified by Bram Chen.\n***/\n// //''Code section:''\n//{{{\nvar num = 15;\nvar ignore_tags = ['systemConfig', 'systemTiddlers'];\nvar CPlingo = config.CommentPlugin.CPlingo;\nfunction in_array(item, arr){for(var i=0;i<arr.length;i++)if(item==arr[i])return true};\nfunction get_parent(tiddler){while(tiddler && in_array(CPlingo.comments, tiddler.tags)) tiddler=store.fetchTiddler(tiddler.tags[0]);return tiddler};\nfunction unique_list(list){var l=[];for(i=0;i<list.length;i++)if(!in_array(list[i], l))l.push(list[i]);return l};\nfunction get_recent_tiddlers(){\n var tiddlers = store.getTiddlers('modified');\n var names = store.getTiddlerText("DefaultTiddlers").readBracketedList();\n var ignore_tiddlers = [];\n for(var i=0; i<ignore_tags.length; i++)\n ignore_tiddlers=ignore_tiddlers.concat(store.getTaggedTiddlers(ignore_tags[i]));\n for(var i=tiddlers.length-1; i>=0; i--) {\n if(in_array(CPlingo.comments, tiddlers[i].tags)) {\n var t = get_parent(tiddlers[i]);\n if(t)names.push(t.title)\n }\n else if(!in_array(tiddlers[i], ignore_tiddlers))\n names.push(tiddlers[i].title);\n }\n return unique_list(names).slice(0, num);\n}\nvar names = get_recent_tiddlers();\n_restart = restart\nrestart = function() {\n if(window.location.hash) _restart();\n else story.displayTiddlers(null,names);\n}\n//}}}
/***\n| Name:|RenameTagsPlugin|\n| Description:|Allows you to easily rename or delete tags across multiple tiddlers|\n| Version:|3.0 ($Rev: 1845 $)|\n| Date:|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|\n| Author:|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\nRename a tag and you will be prompted to rename it in all its tagged tiddlers.\n***/\n//{{{\nconfig.renameTags = {\n\n prompts: {\n rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",\n remove: "Remove the tag '%0' from %1 tidder%2?"\n },\n\n removeTag: function(tag,tiddlers) {\n store.suspendNotifications();\n for (var i=0;i<tiddlers.length;i++) {\n store.setTiddlerTag(tiddlers[i].title,false,tag);\n }\n store.resumeNotifications();\n store.notifyAll();\n },\n\n renameTag: function(oldTag,newTag,tiddlers) {\n store.suspendNotifications();\n for (var i=0;i<tiddlers.length;i++) {\n store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old\n store.setTiddlerTag(tiddlers[i].title,true,newTag); // add new\n }\n store.resumeNotifications();\n store.notifyAll();\n },\n\n storeMethods: {\n\n saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,\n\n saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields) {\n if (title != newTitle) {\n var tagged = this.getTaggedTiddlers(title);\n if (tagged.length > 0) {\n // then we are renaming a tag\n if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))\n config.renameTags.renameTag(title,newTitle,tagged);\n\n if (!this.tiddlerExists(title) && newBody == "")\n // dont create unwanted tiddler\n return null;\n }\n }\n return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields);\n },\n\n removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,\n\n removeTiddler: function(title) {\n var tagged = this.getTaggedTiddlers(title);\n if (tagged.length > 0)\n if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))\n config.renameTags.removeTag(title,tagged);\n return this.removeTiddler_orig_renameTags(title);\n }\n\n },\n\n init: function() {\n merge(TiddlyWiki.prototype,this.storeMethods);\n }\n}\n\nconfig.renameTags.init();\n\n//}}}\n\n
/***\n| Name|SaveCloseTiddlerPlugin|\n| Description|Provides two extra toolbar commands, saveCloseTiddler and cancelCloseTiddler|\n| Version|3.0 ($Rev: 1845 $)|\n| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source|http://mptw.tiddlyspot.com/#SaveCloseTiddlerPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\nTo use these you must add them to the tool bar in your EditTemplate\n***/\n//{{{\nmerge(config.commands,{\n\n saveCloseTiddler: {\n text: 'done/close',\n tooltip: 'Undo changes to this tiddler and close it',\n handler: function(e,src,title) {\n config.commands.saveTiddler.handler(e,src,title);\n config.commands.closeTiddler.handler(e,src,title);\n return false;\n }\n },\n\n cancelCloseTiddler: {\n text: 'cancel/close',\n tooltip: 'Save changes to this tiddler and close it',\n handler: function(e,src,title) {\n config.commands.cancelTiddler.handler(e,src,title);\n config.commands.closeTiddler.handler(e,src,title);\n return false;\n }\n }\n\n});\n\n//}}}\n\n
<<showUpdates onlyTag:news maxEntries:8>>\n{{{<<showUpdates onlyTag:news maxEntries:8>>}}}\n\n----\n\n<<showUpdates onlyTag:news write:'(index==0? countLine + "\sn{{blog{\sn":"")+(index<8?"!!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +tiddler.modified.formatString(" - DD/MM/YY")+"@@\sn" +"{{excerpt{\sn"+tiddler.text.substr(0,100)+"...\sn[[read more...|"+tiddler.title+"]]\sn}}}\sn":"")+(index==count-1?"}}}":"")' >>\n\n{{{\n<<showUpdates\nonlyTag:news\nwrite:\n'(index==0? countLine + "\sn{{blog{\sn":"")+\n(index<8?"!!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +tiddler.modified.formatString(" - DD/MM/YY")+"@@\sn" +"{{excerpt{\sn"+tiddler.text.substr(0,100)+"...\sn[[read more...|"+tiddler.title+"]]\sn}}}\sn":"")+\n(index==count-1?"}}}":"")' \n>>\n}}}\n\nthis one requires the following css in your StyleSheet:\n//{{{\n.blog h2, .blog h3, .blog h4{\n margin:0;\n padding:0;\n border-bottom:none;\n}\n.blog {margin-left:1.5em;} \n\n.blog .excerpt {\n margin:0;\n margin-top:0.3em;\n padding: 0;\n margin-left:1em;\n padding-left:1em;\n font-size:90%;\n border-left:1px solid #ddd;\n}\n//}}}
/***\n|Name|ShowUpdatesPlugin|\n|Created by|SaqImtiaz|\n|Version|0.2 |\n|Requires|~TW2.x|\n!!!Description:\nAllows you to list tiddlers that have changed since the users last visit. You can list only all changed tiddlers, or filter them to only show tiddlers that have or do not have a specific tag. By default a simple list of the titles of changed tiddlers is created. However, using an extremely versatile syntax you can provide a custom template for the generated text.\n\n!!!Examples: \n[[ShowUpdatesDocs]]\n\n!!!Installation:\nCopy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.\n\n!!!Syntax:\n{{{<<showUpdates>>}}}\nadditional optional params:\n{{{<showUpdates excludeTag:TagToExclude onlyTag:TagToList maxEntries:10 write:CustomWriteParameter >>}}}\nexcludeTag: ~TagToExclude\nonlyTag: ~TagToList\nmaxEntries: max number of entries displayed when there are no updates. (default is 10, which can be changed in the config.macros.showUpdates.settings part of the code)\nwrite: if a write parameter is not provided, an un-numbered list of the updates is generated. Alternatively, you can specify a custom 'template' for the text generated. The syntax for the write parameter is identical to that of the forEachTiddler macro. Additonal documentation on this syntax will be provided soon.\nSome of the variables available in the write parameter are 'index', 'count' and 'lastVisit' where lastVisit is the date of the last visit in the format YYYYMMDDHHMM. Also areUpdates is a boolean that is true if there are new updates since the users last visit.\n\n!!!To Do:\n*refactor code to facilitate translations\n*a streamlined version without the custom write parameter\n\n\n!!!Code\n***/\n//{{{\nwindow.lewcidLastVisit = '';\nwindow.old_lewcid_whatsnew_restart = window.restart;\nwindow.restart = function()\n{\n if(config.options.txtLastVisit)\n lewcidLastVisit= config.options.txtLastVisit;\n config.options.txtLastVisit = (new Date()).convertToYYYYMMDDHHMM();\n saveOptionCookie('txtLastVisit');\n window.old_lewcid_whatsnew_restart();\n}\n\nTiddlyWiki.prototype.lewcidGetTiddlers = function(field,excludeTag,includeTag,updatesOnly)\n{\n var results = [];\n this.forEachTiddler(function(title,tiddler)\n {\n if(excludeTag == undefined || !tiddler.isTagged(excludeTag))\n if(includeTag == undefined || tiddler.isTagged(includeTag))\n if ( updatesOnly == false || tiddler.modified.convertToYYYYMMDDHHMM()>lewcidLastVisit)\n results.push(tiddler);\n });\n if(field)\n results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });\n return results;\n}\n\nconfig.macros.showUpdates={};\nconfig.macros.showUpdates.settings =\n{\n maxEntries: 10 //max items to show, if there are no updates since last visit\n}\n\nconfig.macros.showUpdates.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n var args = paramString.parseParams("list",null,true);\n var write = getParam(args, "write", undefined);\n var onlyTag = getParam(args, "onlyTag", undefined);\n var excludeTag = getParam(args, "excludeTag", undefined);\n var sortBy = "modified";\n var maxEntries = getParam(args,"maxEntries",this.settings.maxEntries);\n\n if (lewcidLastVisit) \n {var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,true);\n var areUpdates = tiddlers.length>0? true:false;}\n\n if (!lewcidLastVisit)\n {var countLine = "!!Recent Updates:";\n var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);\n var areUpdates = false;}\n else if (tiddlers.length == 0)\n {var countLine = "!!@@color:red;No new updates@@ since your last visit. @@color:#999;font-size:70%;" + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@\sn!!Recent Updates:";\n var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);}\n else\n {var countLine ="!!@@color:red;"+ tiddlers.length + "@@ new " + (tiddlers.length==1?"update":"updates") + " since your last visit: @@color:#999;font-size:70%;" + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@";}\n\n tiddlers = tiddlers.reverse();\n var lastVisit = lewcidLastVisit? lewcidLastVisit:undefined;\n var count = areUpdates == true? tiddlers.length : maxEntries;\n var sp = createTiddlyElement(place,"span","showUpdates");\n if (write==undefined)\n {\n wikify(countLine,sp);\n var list = createTiddlyElement(sp,"ul");\n for (var i = 0; i < count; i++)\n {\n var tiddler = tiddlers[i];\n createTiddlyLink(createTiddlyElement(list,"li"), tiddler.title, true);\n }\n }\n else\n {\n var list = '';\n for (var index = 0; index < count; index++) {\n var tiddler = tiddlers[index];\n list += eval(write); }\n wikify(list, sp);\n }\n}\n//}}}
<<calendar thismonth>><script><<closeAll>><<permaview>>\n<<newTiddler title:"開始輸入書名" label:"new book" text:{{"<<formTiddler NewBookTemplate\s>\s>"}} tag:"圖書">><<newTiddler title:"開始輸入文章標題" label:"new article" text:{{"<<formTiddler NewArticleTemplate\s>\s>"}} tag:"論文">><<newTiddler>><<newJournal 'DD MMM YYYY'>>\n<<saveChanges>><<tiddler TspotSidebar>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>>
/***\n|Name|SinglePageModePlugin|\n|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|\n|Version|2.3.1|\n|Author|Eric Shulman - ELS Design Studios|\n|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides|Story.prototype.displayTiddler(), Story.prototype.displayTiddlers()|\n|Description|Display tiddlers one at a time with automatic update of URL (permalink). Also, options to always open tiddlers at top/bottom of page|\n\nNormally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing.\n\n!!!!!Usage\n<<<\nSinglePageMode allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time. When SinglePageMode is enabled, the title of the current tiddler is automatically displayed in the browser window's titlebar and the browser's location URL is updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler.\n\nEven when SinglePageMode is disabled (i.e., displaying multiple tiddlers is permitted), you can reduce the potential for confusion by enable TopOfPageMode, which forces tiddlers to always open at the top of the page instead of being displayed following the tiddler containing the link that was clicked.\n<<<\n!!!!!Configuration\n<<<\nWhen installed, this plugin automatically adds checkboxes in the AdvancedOptions tiddler so you can enable/disable the plugin behavior. For convenience, these checkboxes are also included here:\n\n<<option chkSinglePageMode>> Display one tiddler at a time\n<<option chkTopOfPageMode>> Always open tiddlers at the top of the page\n<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page\n//(note: if both settings are selected, "top of page" is used)//\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SinglePageModePlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for SinglePageMode handling^^\n\nWhen installed, this plugin automatically adds checkboxes in the ''shadow'' AdvancedOptions tiddler so you can enable/disable this behavior. However, if you have customized your AdvancedOptions, you will need to ''manually add these checkboxes to your customized tiddler.''\n<<<\n!!!!!Revision History\n<<<\n''2007.03.03 [2.3.1]'' fix typo when adding BPM option to AdvancedOptions (prevented checkbox from appearing)\n''2007.03.03 [2.3.0]'' added support for BottomOfPageMode (BPM) based on request from DaveGarbutt\n''2007.02.06 [2.2.3]'' in Story.prototype.displayTiddler(), use convertUnicodeToUTF8() for correct I18N string handling when creating URL hash string from tiddler title (based on bug report from BidiX)\n''2007.01.08 [2.2.2]'' use apply() to invoke hijacked core functions\n''2006.07.04 [2.2.1]'' in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.\n''2006.06.01 [2.2.0]'' added chkTopOfPageMode (TPM) handling\n''2006.02.04 [2.1.1]'' moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals\n''2005.12.27 [2.1.0]'' hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list). Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers\n''2005.12.27 [2.0.0]'' Update for TW2.0\n''2005.11.24 [1.1.2]'' When the back and forward buttons are used, the page now changes to match the URL. Based on code added by Clint Checketts\n''2005.10.14 [1.1.1]'' permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them\n''2005.10.14 [1.1.0]'' added automatic setting of window title and location bar ('auto-permalink'). feature suggestion by David Dickens.\n''2005.10.09 [1.0.1]'' combined documentation and code in a single tiddler\n''2005.08.15 [1.0.0]'' Initial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\nSupport for BACK/FORWARD buttons adapted from code developed by Clint Checketts\n<<<\n!!!!!Code\n***/\n//{{{\nversion.extensions.SinglePageMode= {major: 2, minor: 3, revision: 1, date: new Date(2007,3,3)};\n\nif (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSinglePageMode>> Display one tiddler at a time";\n\nif (config.options.chkTopOfPageMode==undefined) config.options.chkTopOfPageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkTopOfPageMode>> Always open tiddlers at the top of the page";\n\nif (config.options.chkBottomOfPageMode==undefined) config.options.chkBottomOfPageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page";\n\nconfig.SPMTimer = 0;\nconfig.lastURL = window.location.hash;\nfunction checkLastURL()\n{\n if (!config.options.chkSinglePageMode)\n { window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }\n if (config.lastURL == window.location.hash)\n return;\n var tiddlerName = convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1)));\n tiddlerName=tiddlerName.replace(/\s[\s[/,"").replace(/\s]\s]/,""); // strip any [[ ]] bracketing\n if (tiddlerName.length) story.displayTiddler(null,tiddlerName,1,null,null);\n}\n\nif (Story.prototype.SPM_coreDisplayTiddler==undefined) Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n if (config.options.chkSinglePageMode) {\n window.location.hash = encodeURIComponent(convertUnicodeToUTF8(String.encodeTiddlyLink(title)));\n config.lastURL = window.location.hash;\n document.title = wikifyPlain("SiteTitle") + " - " + title;\n story.closeAllTiddlers();\n if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);\n }\n if (config.options.chkTopOfPageMode) { story.closeTiddler(title); srcElement=null; }\n else if (config.options.chkBottomOfPageMode) { story.closeTiddler(title); srcElement="bottom"; }\n this.SPM_coreDisplayTiddler.apply(this,arguments);\n if (config.options.chkTopOfPageMode) window.scrollTo(0,0); // make sure top of page is visible\n else if (config.options.chkBottomOfPageMode) {\n var display=document.getElementById("tiddlerDisplay"); // for TW2.1-\n if (!display) var display=document.getElementById("storyDisplay"); // for TW2.2+\n window.scrollTo(0,ensureVisible(display.lastChild)); // make sure last tiddler is visible\n }\n}\n\nif (Story.prototype.SPM_coreDisplayTiddlers==undefined) Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;\nStory.prototype.displayTiddlers = function(srcElement,titles,template,unused1,unused2,animate,slowly)\n{\n // suspend single-page mode (and/or top/bottom display options) when showing multiple tiddlers\n var saveSPM=config.options.chkSinglePageMode; config.options.chkSinglePageMode=false;\n var saveTPM=config.options.chkTopOfPageMode; config.options.chkTopOfPageMode=false;\n var saveBPM=config.options.chkBottomOfPageMode; config.options.chkBottomOfPageMode=false;\n this.SPM_coreDisplayTiddlers.apply(this,arguments);\n config.options.chkBottomOfPageMode=saveBPM;\n config.options.chkTopOfPageMode=saveTPM;\n config.options.chkSinglePageMode=saveSPM;\n}\n//}}}
影像閱讀時代與影像數位化
典藏數位之美
/***\n\n''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''\n\n|Name|SplashScreenPlugin|\n|Created by|SaqImtiaz|\n|Location|http://tw.lewcid.org/#SplashScreenPlugin|\n|Version|0.21 |\n|Requires|~TW2.08+|\n!Description:\nProvides a simple splash screen that is visible while the TW is loading.\n\n!Installation\nCopy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.\n\n!Customizing\nOnce the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.\n\n!History\n* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.\n* 26-06-06 : version 0.2, first release\n\n!Code\n***/\n//{{{\nvar old_lewcid_splash_restart=restart;\n\nrestart = function()\n{ if (document.getElementById("SplashScreen"))\n document.getElementById("SplashScreen").style.display = "none";\n if (document.getElementById("contentWrapper"))\n document.getElementById("contentWrapper").style.display = "block";\n \n old_lewcid_splash_restart();\n \n if (splashScreenInstall)\n {if(config.options.chkAutoSave)\n {saveChanges();}\n displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");\n }\n}\n\n\nvar oldText = store.getTiddlerText("MarkupPreHead");\nif (oldText.indexOf("SplashScreen")==-1)\n {var siteTitle = store.getTiddlerText("SiteTitle");\n var splasher='\sn\sn<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';\n if (! store.tiddlerExists("MarkupPreHead"))\n {var myTiddler = store.createTiddler("MarkupPreHead");}\n else\n {var myTiddler = store.getTiddler("MarkupPreHead");}\n myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);\n store.setDirty(true);\n var splashScreenInstall = true;\n}\n//}}}
\n[[SideBarWG]]\n\n/***\n!Top Menu Styles\n***/\n/*{{{*/\n#topMenu br {display:none; }\n#topMenu { background: #000 ; color:#fff;padding: 1em 1em;}\n/*}}}*/\n\n/***\n!General\n***/\n/*{{{*/\nbody {\n background: #444;\n margin: 0 auto;\n}\n\n #contentWrapper{\n background: #fff;\n border: 0;\n margin: 0 auto;\n width: 792px;\n padding:0;\n}\n/*}}}*/\n\n/***\n!Header rules\n***/\n/*{{{*/\n.titleLine{\n margin: 68px 3em 0em 0em;\nmargin-left:1.7em;\nmargin-bottom: 28px;\n padding: 0;\n text-align: left;\n color: #fff;\n}\n\n.siteTitle {\n font-size: 3em;\n font-weight: bold;\n}\n\n.siteSubtitle {\n font-size: 1.5em;\n display: block;\n margin: .5em auto 1em;\n}\n\n.gradient {margin: 0 auto;}\n\n\n\n.header {\n background: #fff; \n margin: 0 0em;\n padding:0 12px;\n\n}\n/*}}}*/\n\n/***\n!Display Area\n***/\n/*{{{*/\n#bodywrapper {margin:0 12px; padding:0;background:#fff; height:1%}\n\n#displayArea{\n margin: 0em 16em 0em 1em;\n text-align: left;\n \n}\n\n.tiddler {\n padding: 1em 1em 0em 0em;\n}\n\nh1,h2,h3,h4,h5 { color: #000; background: transparent; padding-bottom:2px; border-bottom: 1px dotted #666; }\n.title {color:#900; font-size:1.8em; border-bottom:1px solid #333; padding-bottom:0.3px;}\n.subtitle { font-size:90%; color:#ccc; padding-left:0.25em; margin-top:0.1em; }\n\n.shadow .title {\n color: #aaa;\n}\n\n.tagClear{\n clear: none; \n}\n\n* html .viewer pre {\n margin-left: 0em;\n}\n\n* html .editor textarea, * html .editor input {\n width: 98%;\n}\n\n.tiddler {margin-bottom:1em; padding-bottom:0em;}\n\n\n.toolbar .button {color:#bbb; border:none;}\n.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n#sidebar .highlight, #sidebar .marked {background:transparent;}\n\n.tagging, .tagged {\n border: 1px solid #eee;\n background-color: #F7F7F7;\n}\n\n.selected .tagging, .selected .tagged {\n background-color: #eee;\n border: 1px solid #bbb;\n}\n\n .tagging .listTitle, .tagged .listTitle {\n color: #bbb;\n}\n\n.selected .tagging .listTitle, .selected .tagged .listTitle {\n color: #222; \n}\n\n\n.tagging .button:hover, .tagged .button:hover {\n border: none; background:transparent; text-decoration:underline; color:#000;\n}\n\n.tagging .button, .tagged .button {\n color:#aaa;\n}\n\n.selected .tagging .button, .selected .tagged .button {\n color:#000;\n}\n\n.viewer blockquote {\n border-left: 3px solid #000;\n}\n\n.viewer pre, .viewer code {\n border: 1px dashed #ccc;\n background: #eee;}\n\n.viewer hr {\n border: 0;\n border-top: solid 1px #333;\n margin: 0 8em;\n color: #333;\n}\n\n.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n.viewer .highlight, .viewer .marked {text-decoration:none;}\n\n#sidebarTabs .highlight, #sidebarTabs .marked {color:#000; text-decoration:none;}\n\n.tabSelected {\n color: #000;\n background: #fff;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n.viewer .tabSelected:hover{color:#000;}\n\n.viewer .tabSelected {font-weight:bold;}\n\n.tabUnselected {\n color: #999;\n background: #eee;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: solid 1px #ccc;\n padding-bottom:1px;\n}\n\n.tabContents {\n background: #fff;\n color: #000;\n}\n/*}}}*/\n/***\n!!!Tables\n***/\n/*{{{*/\n.viewer table {\n border: 1px solid #000;\n}\n\n.viewer th, thead td {\n background: #000;\n border: 1px solid #000;\n color: #fff;\n}\n\n.viewer td, .viewer tr {\n border: 1px solid #111; padding:4px;\n}\n/*}}}*/\n\n\n/***\n!!!Editor area\n***/\n/*{{{*/\n.editor input, .editor textarea {\n border: 1px solid #ccc;\n}\n\n.editor {padding-top:0.3em;}\n\n.editor textarea:focus, .editor input:focus {\n border: 1px solid #333;\n}\n/*}}}*/\n\n/***\n!Sidebar\n***/\n/*{{{*/\n#sidebar{\nposition:relative;\nfloat:right;\nmargin-bottom:1em;\ndisplay:inline;\nwidth: 16em;\n}\n\n#sidebarOptions .sliderPanel {\n background: #eee; border:1px solid #ccc;\n}\n\n/*}}}*/\n\n/***\n!Body Footer rules\n***/\n/*{{{*/\n#contentFooter {\n text-align: center;\n clear: both;\n color:#fff;\n background: #000;\n padding: 1em 2em;\nfont-weight:bold;\n}\n\n/*}}}*/\n/***\n!Link Styles\n***/\n/*{{{*/\na{\n color: #444;\n}\n\na:hover{\n color: #FF6600;\n background:#fff;\n}\n\n\n.button {\n color: #000;\n border: 1px solid #fff;\n}\n\n.button:hover {\n color: #fff;\n background: #ff8614;\n border-color: #000;\n}\n\n.button:active {\n color: #fff;\n background: #ff8614;\n border: 1px solid #000;\n}\n\n.tiddlyLink {border-bottom: 1px dotted #000;}\n.tiddlyLink:hover {border-bottom: 1px dotted #FF6600;} \n\n.titleLine a {border-bottom: 1px dotted #FF9900;}\n\n.titleLine a:hover {border-bottom: 1px dotted #fff;}\n\n.siteTitle a, .siteSubtitle a{\n color: #fff;\n}\n\n.viewer .button {border: 1px solid #ff8614; font-weight:bold;}\n.viewer .button:hover, .viewer .marked, .viewer .highlight{background:#ff8614; color:#fff; font-weight:bold; border: 1px solid #000;}\n\n#topMenu .button, #topMenu .tiddlyLink, #topMenu .externalLink {\n margin-left:0.5em; margin-right:0.5em;\n padding-left:3px; padding-right:3px;\n color:white; font-weight:bold;\n}\n#topMenu .button:hover, #topMenu .tiddlyLink:hover, #topMenu .externalLink:hover { background:#000; color:#FF8814}\n\n#topMenu a{border:none;}\n/*}}}*/\n\n/***\n!Message Area /%=================================================%/\n***/\n/*{{{*/\n#messageArea {\n border: 4px dotted #ff8614;\n background: #000;\n color: #fff;\n font-size:90%;\n}\n\n#messageArea .button {\n padding: 0.2em;\n color: #000;\n background: #fff;\n text-decoration:none;\n font-weight:bold;\n border:1px solid #000; \n}\n\n#messageArea a {color:#fff;}\n\n#messageArea a:hover {color:#ff8614; background:transparent;}\n\n#messageArea .button:hover {background: #FF8614; color:#fff; border:1px solid #fff; }\n\n/*}}}*/\n\n/***\n!Popup /%=================================================%/\n***/\n/*{{{*/\n.popup {\n background: #ff8814;\n border: 1px solid #333;\n}\n\n.popup hr {\n color: #333;\n background: #333;\n border-bottom: 1px;\n}\n\n.popup li.disabled {\n color: #333;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #ff8614;\n color: #fff;\n border: none;\n text-decoration:underline;\n}\n\n.searchBar {float:right; font-size:1em;}\n.searchBar .button {display:block; border:none; color:#ccc; }\n.searchBar .button:hover{border:none; color:#eee;}\n\n.searchBar input{\n border: 1px inset #000; background:#EFDFD1; width:10em; margin:0;\n}\n\n.searchBar input:focus {\n border: 1px inset #000; background:#fff;\n}\n\n*html .titleLine {margin-right:1.3em;}\n\n*html .searchBar .button {margin-left:1.7em;}\n\n .HideSideBarButton {float:right;} \n/*}}}*/\n\n.blog h2, .blog h3, .blog h4{\n margin:0;\n padding:0;\nborder-bottom:none;\n}\n.blog {margin-left:1.5em;} \n\n\n.blog .excerpt {\n margin:0;\nmargin-top:0.3em;\n padding: 0;\n margin-left:1em;\n padding-left:1em;\n font-size:90%;\n border-left:1px solid #ddd;\n}\n\n#tiddlerWhatsNew h1, #tiddlerWhatsNew h2 {border-bottom:none;}\ndiv[tags~="RecentUpdates"], div[tags~="lewcidExtension"] {margin-bottom: 2em;}\n\n#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#f37211; color:#fff; padding:0 5px; float:right; margin-bottom:4px;}\n#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#f37211; background:#000; padding:0 5px; float:right; margin-bottom:4px;}\n\n#topMenu .fontResizer {float:right;}\n\n#topMenu .fontResizer .button{border:1px solid #000;}\n#topMenu .fontResizer .button:hover {border:1px solid #f37211; color:#fff;}\n#sidebarTabs .txtMainTab .tiddlyLinkExisting {\n font-weight: normal;\n font-style: normal;\n}\n\n#sidebarTabs .txtMoreTab .tiddlyLinkExisting {\n font-weight: bold;\n font-style: normal;\n}\n\n.block a{display:block;}\n\n
<<timeline better:true firstDay:20070329 >>\n<<tabs txtTimelineTab Tiddlers Tiddlers TabTimelineTiddlers comments Comment TabTimelineComments>>
/***\n|Name|TagCloudPlugin|\n|Source|http://www.TiddlyTools.com/#TagCloudPlugin|\n|Version|0.0.0|\n|Author|Clint Checketts|\n|License|unknown|\n|~CoreVersion|2.1|\n|Type|plugin|\n|Requires||\n|Overrides||\n|Description||\n\n!Usage\n<<tagCloud>>\n\n!Code\n***/\n//{{{\nversion.extensions.tagCloud = {major: 1, minor: 0 , revision: 0, date: new Date(2006,2,04)};\n//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman\n\nconfig.macros.tagCloud = {\n noTags: "No tag cloud created because there are no tags.",\n tooltip: "%1 tiddlers tagged with '%0'"\n};\n\nconfig.macros.tagCloud.handler = function(place,macroName,params) {\n \nvar tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);\n\nvar tags = store.getTags();\nfor (var t=0; t<tags.length; t++) {\n for (var p=0;p<params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = "";\n}\n\n if(tags.length == 0) \n createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);\n //Findout the maximum number of tags\n var mostTags = 0;\n for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){\n if (tags[t][1] > mostTags) mostTags = tags[t][1];\n }\n //divide the mostTags into 4 segments for the 4 different tagCloud sizes\n var tagSegment = mostTags / 4;\n\n for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){\n var tagCloudElement = createTiddlyElement(tagCloudWrapper,"span",null,null,null);\n tagCloudWrapper.appendChild(document.createTextNode(" "));\n var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));\n theTag.setAttribute("tag",tags[t][0]);\n }\n\n};\n\nsetStylesheet(".tagCloud span{height: 1.8em;margin: 3px;}.tagCloud1{font-size: 1.2em;}.tagCloud2{font-size: 1.4em;}.tagCloud3{font-size: 1.6em;}.tagCloud4{font-size: 1.8em;}.tagCloud5{font-size: 1.8em;font-weight: bold;}","tagCloudsStyles");\n//}}}
/***\n|''Name:''|~TaggerPlugin|\n|''Version:''|1.0.1 (2006-06-01)|\n|''Source:''|http://tw.lewcid.org//#TaggerPlugin|\n|''Author:''|SaqImtiaz|\n|''Description:''|Provides a drop down listing current tiddler tags, and allowing toggling of tags.|\n|''Documentation:''|[[TaggerPluginDocumentation]]|\n|''Source Code:''|[[TaggerPluginSource]]|\n|''~TiddlyWiki:''|Version 2.0.8 or better|\n***/\n//{{{\n\nconfig.tagger={\n defaults:{\n label: 'Tags: ',\n tooltip: 'Manage tiddler tags',\n taglist: 'true',\n excludeTags: '',\n notags: 'tiddler has no tags',\n aretags: 'current tiddler tags:',\n toggletext: 'add tags:'\n }\n};\n\nconfig.macros.tagger={};\nconfig.macros.tagger.arrow = (document.all?"▼":"▾"); // the fat one is the only one that works in IE\nconfig.macros.tagger.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n var defaults = config.tagger.defaults;\n var nAV = paramString.parseParams('tagman', null, true);\n var label = ((nAV[0].label)&&(nAV[0].label[0])!='.')?nAV[0].label[0]+this.arrow: defaults.label+this.arrow;\n var tooltip = ((nAV[0].tooltip)&&(nAV[0].tooltip[0])!='.')?nAV[0].tooltip[0]: defaults.tooltip;\n var taglist = ((nAV[0].taglist)&&(nAV[0].taglist[0])!='.')?nAV[0].taglist[0]: defaults.taglist;\n var exclude = ((nAV[0].exclude)&&(nAV[0].exclude[0])!='.')?(nAV[0].exclude[0]).readBracketedList(): defaults.excludeTags.readBracketedList();\n if ((nAV[0].source)&&(nAV[0].source[0])!='.')var source = nAV[0].source[0];\n if (source&&!store.getTiddler(source)) return false;\n\n var onclick = function(e) {\n if (!e) var e = window.event;\n var popup = Popup.create(this);\n var tagsarray = store.getTags();\n var tags=new Array();\n\n for (var i=0; i<tagsarray.length; i++){\n tags.push(tagsarray[i][0]);}\n\n if (source)\n {var sourcetiddler=store.getTiddler(source);\n tags=sourcetiddler.tags.sort();}\n\n var currentTags = tiddler.tags.sort();\n\n var createButtons=function(text,theTag,tooltipPrefix){\n var sp = createTiddlyElement(createTiddlyElement(popup,"li"),"span",null,"tagger");\n var theToggle = createTiddlyButton(sp,text,tooltipPrefix+" '"+theTag+"'",taggerOnToggle,"button","toggleButton");\n theToggle.setAttribute("tiddler",tiddler.title);\n theToggle.setAttribute("tag",theTag);\n insertSpacer(sp);\n if (window.createTagButton_orig_mptw)\n createTagButton_orig_mptw(sp,theTag);\n else\n createTagButton(sp,theTag);\n }\n\n createTiddlyElement(popup,"li",null,"listTitle",(tiddler.tags.length == 0 ? defaults.notags : defaults.aretags));\n\n for (var t=0; t<currentTags.length; t++){\n createButtons("[x]",currentTags[t],"remove tag ");\n }\n\n createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n\n if (taglist!='false')\n { createTiddlyElement(popup,"li",null,"listTitle",defaults.toggletext);\n for (var i=0; i<tags.length; i++){\n if (!tiddler.tags.contains(tags[i])&&!exclude.contains(tags[i]))\n {createButtons("[ ]",tags[i],"add tag ");\n }\n }\n createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n }\n\n var newTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Create new tag"),null,taggerOnToggle);\n newTagButton.setAttribute("tiddler",tiddler.title);\n if (source) newTagButton.setAttribute("source",source);\n\n Popup.show(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n };\n\n createTiddlyButton(place,label,tooltip,onclick,"button","taggerDrpBtn");\n};\n\nwindow.taggerOnToggle = function(e) {\n var tag = this.getAttribute("tag");\n var title = this.getAttribute("tiddler");\n var tiddler = store.getTiddler(title);\n if (!tag)\n {\n var newtag=prompt("Enter new tag:","");\n if (newtag!=''&&newtag!=null)\n {\n var tag=newtag;\n if (this.getAttribute("source"))\n {var sourcetiddler = store.getTiddler(this.getAttribute("source"));\n sourcetiddler.tags.pushUnique(newtag);}\n }\n else\n {return false;};\n }\n if (!tiddler || !tiddler.tags)\n {store.saveTiddler(title,title,'',config.options.txtUserName,new Date(),tag);}\n else\n {if (tiddler.tags.find(tag)==null)\n {tiddler.tags.push(tag)}\n else if(!newtag)\n {tiddler.tags.splice(tiddler.tags.find(tag),1)};\n store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags);};\n story.refreshTiddler(title,null,true);\n if(config.options.chkAutoSave)\n saveChanges();\n return false;\n};\n\nsetStylesheet(\n ".tagger a.button {font-weight: bold;display:inline; padding:0px;}\sn"+\n ".tagger #toggleButton {padding-left:2px; padding-right:2px; margin-right:1px; font-size:110%;}\sn"+\n "#nestedtagger {background:#2E5ADF; border: 1px solid #0331BF;}\sn"+\n ".popup .listTitle {color:#000;}\sn"+\n "",\n"TaggerStyles");\n\nwindow.lewcidTiddlerSwapTag = function (tiddler, oldTag, newTag){\n for (var i = 0; i < tiddler.tags.length; i++)\n if (tiddler.tags[i] == oldTag) {\n tiddler.tags[i] = newTag;\n return true;}\n return false;\n}\n\nwindow.lewcidRenameTag = function(e) {\n var tag=this.getAttribute("tag");\n var newtag=prompt("Rename tag '"+tag+"' to:",tag);\n\n if ((newtag==tag)||(newtag==null)) {return false;}\n\n if(store.tiddlerExists(newtag))\n {if(confirm(config.messages.overwriteWarning.format([newtag.toString()])))\n story.closeTiddler(newtag,false,false);\n else\n return null;}\n\n tagged=store.getTaggedTiddlers(tag);\n if (tagged.length!=0){\n for (var j = 0; j < tagged.length; j++)\n lewcidTiddlerSwapTag(tagged[j],tag,newtag);}\n\n if (store.tiddlerExists(tag))\n {store.saveTiddler(tag,newtag);}\n if (document.getElementById("tiddler"+tag))\n {var oldTagTiddler = document.getElementById(story.idPrefix + tag);\n var before= story.positionTiddler(oldTagTiddler);\n var place = document.getElementById(story.container);\n story.closeTiddler(tag,false,false);\n story.createTiddler(place,before,newtag,null);\n story.saveTiddler(newtag);}\n if(config.options.chkAutoSave)\n saveChanges();\n return false;\n}\n\n\nwindow.onClickTag=function(e)\n{\n if (!e) var e = window.event;\n var theTarget = resolveTarget(e);\n\n var nested = (!isNested(theTarget));\n if ((Popup.stack.length > 1)&&(nested==true)) {Popup.removeFrom(1);}\n else if(Popup.stack.length > 0 && nested==false) {Popup.removeFrom(0);};\n\n var theId = (nested==false)? "popup" : "nestedtagger";\n var popup = createTiddlyElement(document.body,"ol",theId,"popup",null);\n Popup.stack.push({root: this, popup: popup});\n\n var tag = this.getAttribute("tag");\n var title = this.getAttribute("tiddler");\n if(popup && tag)\n {\n var tagged = store.getTaggedTiddlers(tag);\n var titles = [];\n var li,r;\n for(r=0;r<tagged.length;r++)\n if(tagged[r].title != title)\n titles.push(tagged[r].title);\n var lingo = config.views.wikified.tag;\n if(titles.length > 0)\n {\n var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);\n openAll.setAttribute("tag",tag);\n createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n for(r=0; r<titles.length; r++)\n {\n createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);\n }\n }\n else\n createTiddlyText(createTiddlyElement(popup,"li",null,"disabled"),lingo.popupNone.format([tag]));\n createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);\n createTiddlyText(h,lingo.openTag.format([tag]));\n\n createTiddlyElement(createTiddlyElement(popup,"li"),"hr");\n\n var renameTagButton = createTiddlyButton(createTiddlyElement(popup,"li"),("Rename tag '"+tag+"'"),null,lewcidRenameTag);\n renameTagButton.setAttribute("tag",tag)\n }\n Popup.show(popup,false);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n\nif (!window.isNested)\n window.isNested = function(e) {\n while (e != null) {\n var contentWrapper = document.getElementById("contentWrapper");\n if (contentWrapper == e) return true;\n e = e.parentNode;\n }\n return false;\n };\n\nconfig.shadowTiddlers.TaggerPluginDocumentation="The documentation is available [[here.|http://tw.lewcid.org/#TaggerPluginDocumentation]]";\n\nconfig.shadowTiddlers.TaggerPluginSource="The uncompressed source code is available [[here.|http://tw.lewcid.org/#TaggerPluginSource]]";\n//}}}
/***\n| Name|TagglyTaggingPlugin|\n| Description|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|\n| Version|3.0 ($Rev: 1898 $)|\n| Date|$Date: 2007-03-20 14:38:33 +1000 (Tue, 20 Mar 2007) $|\n| Source|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n!Notes\nSee http://mptw.tiddlyspot.com/#TagglyTagging\n***/\n//{{{\nconfig.taggly = {\n\n // for translations\n lingo: {\n labels: {\n asc: "\su2191", // down arrow\n desc: "\su2193", // up arrow\n title: "title",\n modified: "modified",\n created: "created",\n show: "+",\n hide: "-",\n normal: "normal",\n group: "group",\n commas: "commas",\n sitemap: "sitemap",\n numCols: "cols\su00b1", // plus minus sign\n label: "Tagged as '%0':",\n excerpts: "excerpts",\n noexcerpts: "no excerpts"\n },\n\n tooltips: {\n title: "Click to sort by title",\n modified: "Click to sort by modified date",\n created: "Click to sort by created date",\n show: "Click to show tagging list",\n hide: "Click to hide tagging list",\n normal: "Click to show a normal ungrouped list",\n group: "Click to show list grouped by tag",\n sitemap: "Click to show a sitemap style list",\n commas: "Click to show a comma separated list",\n numCols: "Click to change number of columns"\n }\n },\n\n config: {\n showTaggingCounts: true,\n listOpts: {\n // the first one will be the default\n sortBy: ["title","modified","created"],\n sortOrder: ["asc","desc"],\n hideState: ["show","hide"],\n listMode: ["normal","group","sitemap","commas"],\n numCols: ["1","2","3","4","5","6"],\n excerpts: ["noexcerpts","excerpts"]\n },\n valuePrefix: "taggly.",\n excludeTags: ["excludeLists","excludeTagging"],\n excerptSize: 50,\n excerptMarker: "/%"+"%/"\n },\n\n getTagglyOpt: function(title,opt) {\n var val = store.getValue(title,this.config.valuePrefix+opt);\n return val ? val : this.config.listOpts[opt][0];\n },\n\n setTagglyOpt: function(title,opt,value) {\n if (!store.tiddlerExists(title))\n // create it silently\n store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),null);\n // if value is default then remove it to save space\n return store.setValue(title,\n this.config.valuePrefix+opt,\n value == this.config.listOpts[opt][0] ? null : value);\n },\n\n getNextValue: function(title,opt) {\n var current = this.getTagglyOpt(title,opt);\n var pos = this.config.listOpts[opt].indexOf(current);\n // a little usability enhancement. actually it doesn't work right for grouped or sitemap\n var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);\n var newPos = (pos + 1) % limit;\n return this.config.listOpts[opt][newPos];\n },\n\n toggleTagglyOpt: function(title,opt) {\n var newVal = this.getNextValue(title,opt);\n this.setTagglyOpt(title,opt,newVal);\n }, \n\n createListControl: function(place,title,type) {\n var lingo = config.taggly.lingo;\n var label;\n var tooltip;\n var onclick;\n\n if ((type == "title" || type == "modified" || type == "created")) {\n // "special" controls. a little tricky. derived from sortOrder and sortBy\n label = lingo.labels[type];\n tooltip = lingo.tooltips[type];\n\n if (this.getTagglyOpt(title,"sortBy") == type) {\n label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];\n onclick = function() {\n config.taggly.toggleTagglyOpt(title,"sortOrder");\n return false;\n }\n }\n else {\n onclick = function() {\n config.taggly.setTagglyOpt(title,"sortBy",type);\n config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);\n return false;\n }\n }\n }\n else {\n // "regular" controls, nice and simple\n label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];\n tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];\n onclick = function() {\n config.taggly.toggleTagglyOpt(title,type);\n return false;\n }\n }\n\n // hide button because commas don't have columns\n if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))\n createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");\n },\n\n makeColumns: function(orig,numCols) {\n var listSize = orig.length;\n var colSize = listSize/numCols;\n var remainder = listSize % numCols;\n\n var upperColsize = colSize;\n var lowerColsize = colSize;\n\n if (colSize != Math.floor(colSize)) {\n // it's not an exact fit so..\n upperColsize = Math.floor(colSize) + 1;\n lowerColsize = Math.floor(colSize);\n }\n\n var output = [];\n var c = 0;\n for (var j=0;j<numCols;j++) {\n var singleCol = [];\n var thisSize = j < remainder ? upperColsize : lowerColsize;\n for (var i=0;i<thisSize;i++) \n singleCol.push(orig[c++]);\n output.push(singleCol);\n }\n\n return output;\n },\n\n drawTable: function(place,columns,theClass) {\n var newTable = createTiddlyElement(place,"table",null,theClass);\n var newTbody = createTiddlyElement(newTable,"tbody");\n var newTr = createTiddlyElement(newTbody,"tr");\n for (var j=0;j<columns.length;j++) {\n var colOutput = "";\n for (var i=0;i<columns[j].length;i++) \n colOutput += columns[j][i];\n var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class\n wikify(colOutput,newTd);\n }\n return newTable;\n },\n\n createTagglyList: function(place,title) {\n switch(this.getTagglyOpt(title,"listMode")) {\n case "group": return this.createTagglyListGrouped(place,title); break;\n case "normal": return this.createTagglyListNormal(place,title,false); break;\n case "commas": return this.createTagglyListNormal(place,title,true); break;\n case "sitemap":return this.createTagglyListSiteMap(place,title); break;\n }\n },\n\n getTaggingCount: function(title) {\n // thanks to Doug Edmunds\n if (this.config.showTaggingCounts) {\n var tagCount = store.getTaggedTiddlers(title).length;\n if (tagCount > 0)\n return " ("+tagCount+")";\n }\n return "";\n },\n\n getExcerpt: function(inTiddlerTitle,title) {\n if (this.getTagglyOpt(inTiddlerTitle,"excerpts") == "excerpts") {\n var t = store.getTiddler(title);\n if (t) {\n var text = t.text.replace(/\sn/," ");\n var marker = text.indexOf(this.config.excerptMarker);\n if (marker != -1) {\n return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";\n }\n else if (text.length < this.config.excerptSize) {\n return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";\n }\n else {\n return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";\n }\n }\n }\n return "";\n },\n\n notHidden: function(t,inTiddler) {\n if (typeof t == "string") \n t = store.getTiddler(t);\n return (!t || !t.tags.containsAny(this.config.excludeTags) ||\n (inTiddler && this.config.excludeTags.contains(inTiddler)));\n },\n\n // this is for normal and commas mode\n createTagglyListNormal: function(place,title,useCommas) {\n\n var list = store.getTaggedTiddlers(title,this.getTagglyOpt(title,"sortBy"));\n\n if (this.getTagglyOpt(title,"sortOrder") == "desc")\n list = list.reverse();\n\n var output = [];\n var first = true;\n for (var i=0;i<list.length;i++) {\n if (this.notHidden(list[i],title)) {\n var countString = this.getTaggingCount(list[i].title);\n var excerpt = this.getExcerpt(title,list[i].title);\n if (useCommas)\n output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);\n else\n output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\sn");\n\n first = false;\n }\n }\n\n return this.drawTable(place,\n this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),\n useCommas ? "commas" : "normal");\n },\n\n // this is for the "grouped" mode\n createTagglyListGrouped: function(place,title) {\n var sortBy = this.getTagglyOpt(title,"sortBy");\n var sortOrder = this.getTagglyOpt(title,"sortOrder");\n\n var list = store.getTaggedTiddlers(title,sortBy);\n\n if (sortOrder == "desc")\n list = list.reverse();\n\n var leftOvers = []\n for (var i=0;i<list.length;i++)\n leftOvers.push(list[i].title);\n\n var allTagsHolder = {};\n for (var i=0;i<list.length;i++) {\n for (var j=0;j<list[i].tags.length;j++) {\n\n if (list[i].tags[j] != title) { // not this tiddler\n\n if (this.notHidden(list[i].tags[j],title)) {\n\n if (!allTagsHolder[list[i].tags[j]])\n allTagsHolder[list[i].tags[j]] = "";\n\n if (this.notHidden(list[i],title)) {\n allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"\n + this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\sn";\n\n leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers\n\n }\n }\n }\n }\n }\n\n var allTags = [];\n for (var t in allTagsHolder)\n allTags.push(t);\n\n var sortHelper = function(a,b) {\n if (a == b) return 0;\n if (a < b) return -1;\n return 1;\n };\n\n allTags.sort(function(a,b) {\n var tidA = store.getTiddler(a);\n var tidB = store.getTiddler(b);\n if (sortBy == "title") return sortHelper(a,b);\n else if (!tidA && !tidB) return 0;\n else if (!tidA) return -1;\n else if (!tidB) return +1;\n else return sortHelper(tidA[sortBy],tidB[sortBy]);\n });\n\n var leftOverOutput = "";\n for (var i=0;i<leftOvers.length;i++)\n if (this.notHidden(leftOvers[i],title))\n leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\sn";\n\n var output = [];\n\n if (sortOrder == "desc")\n allTags.reverse();\n else if (leftOverOutput != "")\n // leftovers first...\n output.push(leftOverOutput);\n\n for (var i=0;i<allTags.length;i++)\n if (allTagsHolder[allTags[i]] != "")\n output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\sn" + allTagsHolder[allTags[i]]);\n\n if (sortOrder == "desc" && leftOverOutput != "")\n // leftovers last...\n output.push(leftOverOutput);\n\n return this.drawTable(place,\n this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),\n "grouped");\n\n },\n\n // used to build site map\n treeTraverse: function(title,depth,sortBy,sortOrder) {\n\n var list = store.getTaggedTiddlers(title,sortBy);\n if (sortOrder == "desc")\n list.reverse();\n\n var indent = "";\n for (var j=0;j<depth;j++)\n indent += "*"\n\n var childOutput = "";\n for (var i=0;i<list.length;i++)\n if (list[i].title != title)\n if (this.notHidden(list[i].title,this.config.inTiddler))\n childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder);\n\n if (depth == 0)\n return childOutput;\n else\n return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title) + "\sn" + childOutput;\n },\n\n // this if for the site map mode\n createTagglyListSiteMap: function(place,title) {\n this.config.inTiddler = title; // nasty. should pass it in to traverse probably\n var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"));\n return this.drawTable(place,\n this.makeColumns(output.split(/(?=^\s*\s[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic\n "sitemap"\n );\n },\n\n macros: {\n tagglyTagging: {\n handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n var refreshContainer = createTiddlyElement(place,"div");\n // do some refresh magic to make it keep the list fresh - thanks Saq\n refreshContainer.setAttribute("refresh","macro");\n refreshContainer.setAttribute("macroName",macroName);\n refreshContainer.setAttribute("title",tiddler.title);\n this.refresh(refreshContainer);\n },\n\n refresh: function(place) {\n var title = place.getAttribute("title");\n removeChildren(place);\n if (store.getTaggedTiddlers(title).length > 0) {\n var lingo = config.taggly.lingo;\n config.taggly.createListControl(place,title,"hideState");\n if (config.taggly.getTagglyOpt(title,"hideState") == "show") {\n createTiddlyElement(place,"span",null,"tagglyLabel",lingo.labels.label.format([title]));\n config.taggly.createListControl(place,title,"title");\n config.taggly.createListControl(place,title,"modified");\n config.taggly.createListControl(place,title,"created");\n config.taggly.createListControl(place,title,"listMode");\n config.taggly.createListControl(place,title,"excerpts");\n config.taggly.createListControl(place,title,"numCols");\n config.taggly.createTagglyList(place,title);\n }\n }\n }\n }\n },\n\n // todo fix these up a bit\n styles: [\n"/*{{{*/",\n"/* created by TagglyTaggingPlugin */",\n".tagglyTagging { padding-top:0.5em; }",\n".tagglyTagging li.listTitle { display:none; }",\n".tagglyTagging ul {",\n" margin-top:0px; padding-top:0.5em; padding-left:2em;",\n" margin-bottom:0px; padding-bottom:0px;",\n"}",\n".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",\n".tagglyTagging table { margin:0px; padding:0px; }",\n".tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }",\n".tagglyTagging .button, .tagglyTagging .hidebutton {",\n" color:[[ColorPalette::TertiaryLight]]; font-size:90%;",\n" border:0px; padding-left:0.3em;padding-right:0.3em;",\n"}",\n".tagglyTagging .button:hover, .hidebutton:hover {",\n" background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",\n"}",\n".selected .tagglyTagging .button { display:inline; }",\n".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",\n".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",\n".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",\n".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",\n".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",\n".tagglyTagging ul ul li {margin-left:0.5em; }",\n".editLabel { font-size:90%; padding-top:0.5em; }",\n".tagglyTagging .commas { padding-left:1.8em; }",\n"/* not technically tagglytagging but will put them here anyway */",\n".tagglyTagged li.listTitle { display:none; }",\n".tagglyTagged li { display: inline; font-size:90%; }",\n".tagglyTagged ul { margin:0px; padding:0px; }",\n".excerpt { color:[[ColorPalette::TertiaryMid]]; }",\n"/*}}}*/",\n ""].join("\sn"),\n\n init: function() {\n merge(config.macros,this.macros);\n config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;\n store.addNotification("TagglyTaggingStyles",refreshStyles);\n }\n};\n\nconfig.taggly.init();\n\n//}}}\n\n
//{{{\n// based on Sweet Titles (c) Creative Commons 2005\n// http://creativecommons.org/licenses/by-sa/2.5/\n// Author: Dustin Diaz | http://www.dustindiaz.com\n// Adapted to TW for tiddler previews by Saq Imtiaz\nconfig.linkPreview ={\n tiddlyLinkPreview : true,\n externalLinkPreview : false,\n customTiddlerPreview : true\n}\n\nif (config.linkPreview.customTiddlerPreview)\n {\n Tiddler.prototype.getSubtitle = function()\n {\n return (this.text.length>0 ? this.text.substr(0,110) : "(no text)");\n }\n }\n\nif (config.linkPreview.tiddlyLinkPreview)\n {\n old_tiddlerPreview_createTiddlyButton=createTiddlyButton;\n window.createTiddlyButton = function (theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey)\n {\n var theButton = old_tiddlerPreview_createTiddlyButton.apply(this,arguments);\n if (theButton.className.indexOf('tiddlyLink')!=-1)\n {\n theButton = setLinkPreview(theButton);\n }\n return theButton;\n }\n }\n\nfunction setLinkPreview (theButton)\n{\n theButton.setAttribute("tip",theButton.getAttribute("title"));\n addEvent(theButton,'mouseover',sweetTitles.tipOver);\n addEvent(theButton,'mouseout',sweetTitles.tipOut);\n theButton.setAttribute("title","");\n return theButton;\n}\n\nif (config.linkPreview.externalLinkPreview)\n {\n old_tiddlerPreview_createExternalLink=createExternalLink;\n window.createExternalLink = function(place,url)\n {\n var theLink = old_tiddlerPreview_createExternalLink(place,url);\n theLink = setLinkPreview(theLink);\n return(theLink);\n }\n }\n\nwindow.old_lewcid_pt_restart = restart;\nrestart = function()\n{\n window.old_lewcid_pt_restart();\n sweetTitles.init();\n};\n\nwindow.refreshTiddlyLink = function(e,title)\n{\n var i = getTiddlyLinkInfo(title,e.className);\n e.className = i.classes;\n if (!e.getAttribute('tip'))\n e.title = i.subTitle;\n}\n\nsetStylesheet("body div#toolTip { position:absolute;z-index:1000;width:220px;background:#000;border:2px double #fff;text-align:left;padding:5px;min-height:1em;-moz-border-radius:5px; }\sn body div#toolTip p { margin:0;padding:2px;color:#fff;font:11px/12px verdana,arial,sans-serif; font-weight:bold; word-break:normal;display:block;overflow:hidden;}","linkPreviewStyles");\n\nvar sweetTitles = { \n xCord : 0, // @Number: x pixel value of current cursor position\n yCord : 0, // @Number: y pixel value of current cursor position\n tipElements : ['a','abbr','acronym'], // @Array: Allowable elements that can have the toolTip\n obj : Object, // @Element: That of which you're hovering over\n tip : Object, // @Element: The actual toolTip itself\n active : 0, // @Number: 0: Not Active || 1: Active\n init : function() {\n this.tip = createTiddlyElement(document.getElementsByTagName('body')[0],"div","toolTip");\n this.tip.style.top = '0';\n this.tip.style.visibility = 'hidden';\n },\n updateXY : function(e) {\n var theTarget = resolveTarget(e);\n sweetTitles.xCord = findPosX(theTarget);\n sweetTitles.yCord = findPosY(theTarget);\n },\n tipOut: function() {\n if ( window.tID ) {\n clearTimeout(tID);\n }\n if ( window.opacityID ) {\n clearTimeout(opacityID);\n }\n sweetTitles.tip.style.visibility = 'hidden';\n },\n tipOver : function(e) {\n sweetTitles.obj = this;\n tID = window.setTimeout("sweetTitles.tipShow()",500);\n sweetTitles.updateXY(e);\n },\n tipShow : function() { \n var scrX = Number(this.xCord);\n var scrY = Number(this.yCord);\n var tp = parseInt(scrY+15);\n var lt = parseInt(scrX+10);\n var anch = this.obj;\n this.tip.innerHTML = "<p>"+anch.getAttribute('tip')+"<em></em></p>";\n this.tip.style.left = ( parseInt(findWindowWidth()+findScrollX()) < parseInt(this.tip.offsetWidth+lt) )? parseInt(lt-(this.tip.offsetWidth))+'px' : this.tip.style.left = lt+'px';\n this.tip.style.top = ( parseInt(findWindowHeight()+findScrollY()) < parseInt(this.tip.offsetHeight+tp) ) ? parseInt(tp-(this.tip.offsetHeight+15))+'px': this.tip.style.top = tp+5+'px';\n this.tip.style.visibility = 'visible';\n this.tip.style.opacity = '.1';\n this.tipFade(10);\n },\n tipFade: function(opac) {\n var passed = parseInt(opac);\n var newOpac = parseInt(passed+10);\n if ( newOpac < 80 ) {\n this.tip.style.opacity = '.'+newOpac;\n this.tip.style.filter = "alpha(opacity:"+newOpac+")";\n opacityID = window.setTimeout("sweetTitles.tipFade('"+newOpac+"')",20);\n }\n else { \n this.tip.style.opacity = '.80';\n this.tip.style.filter = "alpha(opacity:80)";\n }\n }\n};\n//}}}
/***\n| Name|ToggleTagPlugin|\n| Description|Makes a checkbox which toggles a tag in a tiddler|\n| Version|3.0 ($Rev: 1845 $)|\n| Date|$Date: 2007-03-16 15:19:22 +1000 (Fri, 16 Mar 2007) $|\n| Source|http://tiddlyspot.com/mptw/#ToggleTagMacro|\n| Author|Simon Baird <simon.baird@gmail.com>|\n| License|http://mptw.tiddlyspot.com/#TheBSDLicense|\n!Usage\n{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}\n* TagName - the tag to be toggled, default value "checked"\n* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler\n* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'\n(If a parameter is '.' then the default will be used)\n\nExamples:\n\n|Code|Description|Example|h\n|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|\n|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|\n|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|\n|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|\n|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|\nNotes:\n* If TiddlerName doesn't exist it will be silently created\n* Set label to '-' to specify no label\n* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2\n\n!Known issues\n* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing\n\n***/\n//{{{\n\nmerge(config.macros,{\n\n toggleTag: {\n\n doRefreshAll: true,\n createIfRequired: true,\n shortLabel: "[[%0]]",\n longLabel: "[[%0]] [[%1]]",\n\n handler: function(place,macroName,params,wikifier,paramString,tiddler) {\n var tag = (params[0] && params[0] != '.') ? params[0] : "checked";\n var title = (params[1] && params[1] != '.') ? params[1] : tiddler.title;\n var defaultLabel = (title == tiddler.title ? this.shortLabel : this.longLabel);\n var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;\n label = (label == '-' ? '' : label);\n var theTiddler = title == tiddler.title ? tiddler : store.getTiddler(title);\n var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {\n if (!store.tiddlerExists(title)) {\n if (config.macros.toggleTag.createIfRequired) {\n var content = store.getTiddlerText(title); // just in case it's a shadow\n store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);\n }\n else \n return false;\n }\n store.setTiddlerTag(title,this.checked,tag);\n return true;\n });\n }\n }\n});\n\n//}}}\n\n
/***\nRequired by Tiddlyspot\n***/\n//{{{\n\nconfig.options.chkHttpReadOnly = false; // make it so you can by default see edit controls via http\n\nif (window.location.protocol != "file:")\n config.options.chkGTDLazyAutoSave = false; // disable autosave in d3\n\nconfig.tiddlyspotSiteId = 'yenny';\n\n// probably will need to redo this for TW 2.2\nwith (config.shadowTiddlers) {\n SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';\n SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");\n OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");\n DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[Welcome to Tiddlyspot]] ");\n MainMenu = MainMenu.replace(/^/,"[[Welcome to Tiddlyspot]] ");\n}\n\nmerge(config.shadowTiddlers,{\n\n'Welcome to Tiddlyspot':[\n "This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",\n "<<tiddler TspotControls>>",\n "See also GettingStarted.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \s"save to web\s" button in the column on the right.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \s"upload\s" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."\n].join("\sn"),\n\n'TspotControls':[\n "| tiddlyspot password:|<<option pasUploadPassword>>|",\n "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<<br>>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",\n "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"\n].join("\sn"),\n\n'TspotSidebar':[\n "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"\n].join("\sn"),\n\n'TspotOptions':[\n "tiddlyspot password:",\n "<<option pasUploadPassword>>",\n ""\n].join("\sn")\n\n});\n//}}}\n
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 25/3/2007 11:45:47 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 25/3/2007 11:55:30 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 25/3/2007 20:22:31 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 25/3/2007 23:34:42 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 25/3/2007 23:41:42 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 25/3/2007 23:42:17 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 25/3/2007 23:47:42 | YourName | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 0:4:7 | YourName | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 26/3/2007 0:7:12 | YourName | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 26/3/2007 0:16:36 | YourName | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 11:33:9 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 11:55:54 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 12:3:36 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 14:7:51 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 14:58:38 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 15:25:32 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 16:24:16 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 16:34:53 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 16:42:28 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 16:58:25 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 17:3:42 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 26/3/2007 17:7:21 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 17:54:1 | yenny | [[index.html|http://yenny.tiddlyspot.com/index.html]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 26/3/2007 23:15:55 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 11:31:32 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 12:5:9 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 12:53:32 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 12:57:8 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:5:45 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:8:22 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:28:7 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:37:54 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:46:41 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:49:27 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 13:54:26 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:6:22 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:10:6 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 28/3/2007 14:12:39 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:15:25 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:35:13 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:37:31 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:51:48 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:54:26 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:55:22 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 14:56:14 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 15:3:1 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 16:29:47 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 16:41:44 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 16:47:14 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:0:9 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:5:57 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:13:17 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:16:12 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:18:27 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 28/3/2007 17:21:10 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 30/3/2007 9:9:51 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 30/3/2007 9:16:43 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 1:44:22 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 1:53:25 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 2:1:8 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 11:10:10 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 12:55:5 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 13:11:31 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 13:16:23 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 13:30:41 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 14:28:39 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/4/2007 14:32:23 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/4/2007 21:18:10 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/4/2007 21:27:53 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 9/5/2007 21:27:42 | YourName | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 10/5/2007 13:55:25 | yenny | [[/|http://yenny.tiddlyspot.com/]] | [[store.cgi|http://yenny.tiddlyspot.com/store.cgi]] | . | index.html | . |
/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|3.4.5|\n|''Date:''|Oct 15, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|\n|''Documentation:''|http://tiddlywiki.bidix.info/#UploadDoc|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''~CoreVersion:''|2.0.0|\n|''Browser:''|Firefox 1.5; InternetExplorer 6.0; Safari|\n|''Include:''|config.lib.file; config.lib.log; config.lib.options; PasswordTweak|\n|''Require:''|[[UploadService|http://tiddlywiki.bidix.info/#UploadService]]|\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 4, revision: 5, \n date: new Date(2006,9,15),\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n documentation: 'http://tiddlywiki.bidix.info/#UploadDoc',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',\n coreVersion: '2.0.0',\n browser: 'Firefox 1.5; InternetExplorer 6.0; Safari'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 1}, \n date: new Date(2006,8,19)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 3, date: new Date(2006,8,30),\n type: 'tweak',\n source: 'http://tiddlywiki.bidix.info/#PasswordTweak'\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) \n {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.className = "txtOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "pasOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n backupFileStored: "Previous file backuped in %0",\n crossDomain: "Certainly a cross-domain isue: access to an other site isn't allowed",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileLocked: "Files is locked: You are not allowed to Upload",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n passwordEmpty: "Unable to upload, your password is empty",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.toDirUrl(storeUrl, uploadDir, username)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.toRootUrl = function (storeUrl, username)\n{\n return root = (this.dirname(storeUrl)?this.dirname(storeUrl):this.dirname(document.location.toString()));\n}\nconfig.macros.upload.toDirUrl = function (storeUrl, uploadDir, username)\n{\n var root = this.toRootUrl(storeUrl, username);\n if (uploadDir && uploadDir != '.')\n root = root + '/' + uploadDir;\n return root;\n}\nconfig.macros.upload.toFileUrl = function (storeUrl, toFilename, uploadDir, username)\n{\n return this.toDirUrl(storeUrl, uploadDir, username) + '/' + toFilename;\n}\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n if (!password || password === '') {\n alert(config.macros.upload.messages.passwordEmpty);\n return;\n }\n if (storeUrl === '') {\n storeUrl = config.macros.upload.defaultStoreScript;\n }\n if (config.lib.file.dirname(storeUrl) === '') {\n storeUrl = config.lib.file.dirname(document.location.toString())+'/'+storeUrl;\n }\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n // Check that file is not locked\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n if (BidiX.GroupAuthoring.lock.isLocked() && !BidiX.GroupAuthoring.lock.isMyLock()) {\n alert(config.macros.upload.messages.fileLocked);\n return;\n }\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n var toDir = config.macros.upload.toDirUrl(storeUrl, toFilename, uploadDir, username);\n displayMessage(config.macros.upload.messages.aboutToUpload.format([toDir]), toDir);\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, rssPath, uploadDir, username);\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [toFileUrl]), toFileUrl);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = this.download(storeUrl, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = revised.replaceChunk("<!--PRE-HEAD-START--"+">","<!--PRE-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPreHead","") + "\sn");\n revised = revised.replaceChunk("<!--POST-HEAD-START--"+">","<!--POST-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPostHead","") + "\sn");\n revised = revised.replaceChunk("<!--PRE-BODY-START--"+">","<!--PRE-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPreBody","") + "\sn");\n revised = revised.replaceChunk("<!--POST-BODY-START--"+">","<!--POST-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPostBody","") + "\sn");\n\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n if (responseText.indexOf("destfile:") > 0) {\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9, \n responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n toFileUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + destfile;\n }\n else {\n toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [toFileUrl]), toFileUrl);\n if (backupDir && responseText.indexOf("backupfile:") > 0) {\n var backupFile = responseText.substring(responseText.indexOf("backupfile:")+11, \n responseText.indexOf("\sn", responseText.indexOf("backupfile:")));\n toBackupUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + backupFile;\n displayMessage(config.macros.upload.messages.backupFileStored.format(\n [toBackupUrl]), toBackupUrl);\n }\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n // erase local lock\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n BidiX.GroupAuthoring.lock.eraseLock();\n // change mtime with new mtime after upload\n var mtime = responseText.substr(responseText.indexOf("mtime:")+6);\n BidiX.GroupAuthoring.lock.mtime = mtime;\n }\n \n \n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');}\n }\n catch (e) {}\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir;\n // add lock attributes to sheader\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n var l = BidiX.GroupAuthoring.lock.myLock;\n sheader += ";lockuser=" + l.user\n + ";mtime=" + l.mtime\n + ";locktime=" + l.locktime;\n }\n sheader += ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n //strailer = "--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //request.open("POST", storeUrl, true, username, password);\n try {\n request.open("POST", storeUrl, true); \n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent + "\snStatus: "+request.status.statusText);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\nconfig.macros.upload.download = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n //request.open("GET", document.location.toString(), true, username, password);\n try {\n request.open("GET", document.location.toString(), true);\n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n \n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]) + "\snStatus: "+request.status.statusText);\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nsetStylesheet(\n ".pasOptionInput {width: 11em;}\sn"+\n ".txtOptionInput.txtUploadStoreUrl {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadFilename {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadDir {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadBackupDir {width: 25em;}\sn"+\n "",\n "UploadOptionsStyles");\nif (document.location.toString().substr(0,4) == "http") {\n config.options.chkAutoSave = false; \n saveOptionCookie('chkAutoSave');\n}\nconfig.shadowTiddlers.UploadDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadDoc ]]\sn"; \n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n\nconfig.macros.saveChanges.handler_orig_UploadPlugin = config.macros.saveChanges.handler;\n\nconfig.macros.saveChanges.handler = function(place)\n{\n if ((!readOnly) && (document.location.toString().substr(0,4) != "http"))\n createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);\n};\n\n//}}}\n////===\n\n
[[MptwViewTemplate]]
MultiRssPlugin\n - install, save your TW and reload.\n - edit the MultiRssConfig shadow tiddler to configure your rss feeds.\n - to trigger rss saves manually, use the {{{<<saveRss>>}}} macro\n - or just set the generate rss feed option and the feeds will be generated on each save\n - major code optimization planned for ~TW2.2\n - coming up: compatibility with MTS\n\nInlineTabsPlugin\n - create tabs from just one tiddler using an easy {{{<tabs></tabs>}}} syntax.\n - [[Demo|TabDemo]]\n\nInlineSlidersPlugin\n - a super light weight plugin that lets you create sliders inline using a {{{<slider></slider>}}} syntax, or the {{{++++ ====}}} syntax for compatibility with the ~NestedSlidersPlugin from tiddlytools.com. Terrific for when you don't need the extra bells, but just want to create simple inline sliders.\n++++ Demo\nThis is an example slider\n====\n\nLimitOpenTiddlersPlugin:\n - new tiddlers open at the top\n - max n tiddlers allowed open at any time. Right now n is set to 3\n - when the n+1 tiddler is opened, the oldest (bottom) open tiddler is closed\n - optional history command in the toolbar that show z number of last closed tiddlers.\n - z and n are userconfigurable\n\nTiddlerPreviewsPlugin\n - replace default tiddler tooltips with stylish excerpts of the tiddler text. Mouse over the tiddler links in the timeline for a demo.\n - easily configure whether to use them for either tiddlyLinks or externalLinks or both.\n - works better for tiddlers with normal text as opposed to code.\n - can use with Simon's [[TiddlerExcerptTooltip|http://mptw2.tiddlyspot.com/#TiddlerExcerptTooltip]] to customize the tooltip!\n - customize appearance with css\n - (adapt for inline definitions etc)\n\nExternalLinkPreviewPlugin\nthe websnapr preview script ported to TW. Not really my cup of tea, but gave it a go after someone asked on the group. What is cool is that this plays well with the TiddlerPreviewsPlugin. (unfortunately their servers seems to be bogged down sometimes)\nTry mousing over these links:\n - http://www.google.com\n - http://www.cricinfo.com\n\n\n\n\n\n\n\n\n\n\n\n\n
/***\n!Metadata:\n|''Name:''|XMLReader|\n|''Description:''||\n|''Version:''|1.2.0|\n|''Date:''|Jul 20, 2006|\n|''Source:''|http://sourceforge.net/project/showfiles.php?group_id=150646|\n|''Author:''|BramChen (bram.chen (at) gmail (dot) com)|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License]]|\n|''~CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.5+; InternetExplorer 6.0|\n!Syntax:\n{{{<<xmlreader withDesc|noDesc|asHtml rssfeed.xml|http://www.example.com/rssfeed.rdf>>}}}\n!Revision History:\n|''Version''|''Date''|''Note''|\n|1.2.0|Jul 20, 2006|Runs compatibly with TW 2.1.0 (rev #403+)|\n|1.1.0|Jul 10, 2006)|change xmlhttp.send(null)/send() to xmlhttp.send("") for more compatibility for some browsers|\n|1.0.0|Mar 11, 2006|Initial release|\n|~|~|This macro is reworked from RssNewsMacro, but it can be easy to extended to support different structure of xml document from rss feeds|\n|~|~|You could uninstall the RssNewsMacro, but still use the original syntax,<<br>>{{{<<rssfeed withDesc|noDesc|asHtml rssfeed.xml|http://www.example.com/rssfeed.rdf>>}}}|\n\n!Code section:\n***/\n\n//{{{\nversion.extensions.xmlreader = {major: 1, minor: 2, revision: 0,\n date: new Date("Jul 20, 2006"),\n name: "XMLReader",\n type: "Macro",\n author: "BramChen",\n source: "http://sourceforge.net/project/showfiles.php?group_id=150646"\n};\nconfig.macros.xmlreader= {\n itemStructure:{title:'Title',link:'Link',pubDate:'PubDate',description:'Desc'},\n// rsTemplate:function(){var t='';for (var i in itemStructure){t+='_'+itemStructure[i]}},\n rsTemplate:'_pubDate\sn**[[_title|_link]]_description',\n items: {Elm: "%0Elm", Text: "_%0"},\n keyItem: "item",\n dateFormat: "DDD, DD MMM YYYY",\n msg:{\n permissionDenied: "Permission to read preferences was denied.",\n errorInDataRetriveing: "Problem retrieving XML data: %0",\n invalidXML: "Invalid XML retrieved from: %0",\n urlNotAccessible: "Access to %0 is not allowed,\snPlease check the setting of your browser:\sn1.For Gecko based, you should set the 'signed.applets.codebase_principal_support' to be true, in about:config.\sn2.For IE, you should add this web site to your trust list."\n },\n cache: [], // url => request\n withDesc: null,\n xmlURL: null,\n groupBy: null,\n xmlhttp: null,\n place:null\n};\n\nconfig.macros.xmlreader.handler = function(place,macroName,params){\n this.withDesc = params[0];\n this.xmlURL = params[1];\n this.place=place;\n if (this.cache[this.xmlURL]) {\n wikify("^^(//from cache//)^^\sn",place);\n this.processResponse(this.xmlURL,this.cache[this.xmlURL]);\n }\n else {\n this.asyncGet(this.xmlURL,this.processResponse);\n }\n};\n\nconfig.macros.xmlreader.asyncGet = function (xmlURL,callback){\n var xmlhttp;\n try {xmlhttp=new XMLHttpRequest();}\n catch (e) {\n try {xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");}\n catch (e) {\n try {xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}\n catch (e) { displayMessage(e.description?e.description:e.toString());}\n }\n }\n if (!xmlhttp){\n return;\n }\n this.xmlhttp = xmlhttp;\n if (window.netscape){\n if (!this.testURL(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n }\n// if (xmlhttp.overrideMimeType) {xmlhttp.overrideMimeType('text/xml');}\n\n xmlhttp.onreadystatechange=function(){\n var xmlhttp = config.macros.xmlreader.xmlhttp;\n if (xmlhttp.readyState==4) {\n if (xmlhttp.status==200 || xmlhttp.status===0) {\n if (callback) callback(xmlURL,xmlhttp);\n }\n else {\n displayMessage(config.macros.xmlreader.msg.errorInDataRetriveing.format([xmlhttp.statusText]));\n }\n }\n };\n try {\n var url=xmlURL+(xmlURL.indexOf('?')<0?'?':'&')+'nocache='+Math.random();\n xmlhttp.open("GET",url,true);\n xmlhttp.send("");\n }\n catch (e) {\n wikify(e.toString()+this.msg.urlNotAccessible.format([xmlURL]), this.place);\n }\n};\n\nconfig.macros.xmlreader.processResponse = function(xmlURL,xmlhttp){\n if (window.netscape){\n if (!config.macros.xmlreader.testURL(xmlURL)){\n try {netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n }\n if (xmlhttp.responseXML){\n config.macros.xmlreader.cache[xmlURL] = xmlhttp;\n config.macros.xmlreader.genLists(xmlhttp.responseXML);\n }\n else {\n wikify("<html>"+xmlhttp.responseText+"</html>", this.place);\n displayMessage(this.msg.invalidXML.format([xmlURL]));\n }\n};\n \nconfig.macros.xmlreader.genLists = function(xml){\n var itemList = xml.getElementsByTagName(this.keyItem);\n var itemStructure = this.itemStructure;\n var items = this.items;\n var rsLists='', rssItem; this.groupBy='';\n for (var i=0; i<itemList.length; i++){\n var itemElms=[],itemTexts=[];\n var rsTemplate=this.rsTemplate;\n for (var j in itemStructure){\n var itemElm = items.Elm.format([j]);\n var itemText = items.Text.format([j]);\n itemElms[itemElm] = itemList[i].getElementsByTagName(j).item(0);\n if(itemElms[itemElm]){\n var theTitle = itemStructure[j];\n var theText = (itemElms[itemElm].firstChild)?itemElms[itemElm].firstChild.nodeValue:'';\n rsTemplate=this.convertTemplate(rsTemplate,j,theText);\n }\n else {\n rsTemplate = rsTemplate.replace('_'+j, '');\n }\n }\n rsLists += rsTemplate;\n }\n wikify(rsLists,this.place);\n};\n \nconfig.macros.xmlreader.convertTemplate = function(rsTemplate,j,theText){\n switch (j){\n case 'title':\n rsTemplate = rsTemplate.replace(/_title/,theText.replace(/\s[|\s]/g,''));\n break;\n case 'link':\n rsTemplate = rsTemplate.replace(/_link/, theText);\n break;\n case 'pubDate':\n theText = this.formatString(this.dateFormat, theText);\n if (this.groupBy == theText){\n rsTemplate = rsTemplate.replace(/_pubDate/, '');\n }\n else{\n rsTemplate = rsTemplate.replace(/_pubDate/, '\sn* '+theText);\n this.groupBy = theText;\n }\n break;\n case 'description':\n var regexpDesc = new RegExp("withDesc|asHtml","g");\n if (regexpDesc.exec(this.withDesc) && theText){\n var _description = theText.replace(/\sn/g,' ');\n _description =_description.replace(/<br \s/>/ig,'\sn'); \n if (version.extensions.nestedSliders){\n _description = ((this.withDesc == "asHtml")?"<html>"+_description+"</html>":_description);\n rsTemplate = rsTemplate.replace(/_description/,'+++[...]'+_description+'\sn===\sn');\n }\n else {\n rsTemplate = rsTemplate.replace(/_description/,_description+'\sn');\n }\n }\n else {\n rsTemplate = rsTemplate.replace(/_description/,'');\n }\n break;\n }\n return (rsTemplate);\n};\n \nconfig.macros.xmlreader.formatString = function(template, theDate){\n var dateString = new Date(theDate);\n template = template.replace(/hh|mm|ss/g,'');\n return dateString.formatString(template);\n};\nconfig.macros.xmlreader.testURL = function (url){\n var rsURL={protocol: '', host: '', hostname:'', port:'', path: ''};\n if (url.indexOf(':') == -1) {\n return true;\n }\n rsURL.protocol = url.substr(0,url.indexOf(":")+1);\n var s1 = url.substr(url.lastIndexOf("//")+2);\n var i = s1.indexOf(':');\n if (i != -1){\n rsURL.host=s1.substr(0,s1.indexOf("/"));\n rsURL.hostname = s1.substr(0,i);\n var s2 = s1.substr(i+1);\n var j = s2.indexOf("/");\n if ( j != -1){\n rsURL.port = s2.substr(0, j);\n rsURL.path = s2.substr(j);\n }\n else {\n rsURL.port = s2;\n }\n }\n else {\n if (s1.indexOf("/") != -1){\n rsURL.host = s1.substr(0,s1.indexOf("/"));\n rsURL.hostname = rsURL.host;\n rsURL.path = s1.substr(s1.indexOf("/"));\n }\n else {\n rsURL.host = s1;\n rsURL.hostname = s1;\n }\n }\n var curLoc = document.location;\n// var curPort = curLoc.host.substr(curLoc.host.indexOf(":")+1);\n var result = (curLoc.protocol == rsURL.protocol && curLoc.host == rsURL.host);\n return (result);\n};\n//}}}\n// // ''Redefine RssNewsMacro''\n//{{{\nconfig.macros.rssfeed=config.macros.xmlreader;\n//}}}
<<formTiddler NewBookTemplate>><data>{"author":"Walter Benjamin","booktitle":"啟迪:本雅明文選","pubinfo":"牛津大學出版社(香港)","callnumber":"0195909755","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/237/452677955_26d3f1282c_o.jpg'\n'http://farm1.static.flickr.com/244/452657810_a2ea9a981b_o.jpg' >>\n===\n
<<formTiddler NewBookTemplate>><data>{"author":"Ales Erjavec (胡菊蘭,張雲鵬 譯) ","booktitle":"圖像時代","pubinfo":"吉林人民出版社(長春)","callnumber":"7206041116","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/169/452646508_076702dd17_o.jpg'\n'http://farm1.static.flickr.com/180/452646750_c994195a43_o.jpg'\n'http://farm1.static.flickr.com/238/452667497_55dcfffbf1_o.jpg'\n'http://farm1.static.flickr.com/153/452667571_5759d0b82a_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"callnumber":"7309047478","author":"孟建,Stefan Friedrich 編","booktitle":"圖像時代視覺文化傳播的理論詮釋","pubinfo":"復旦大學出版社(上海)","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/192/452651836_bad95459d2_o.jpg'\n'http://farm1.static.flickr.com/194/452652062_25812fb3b5_o.jpg'\n'http://farm1.static.flickr.com/233/452672647_4be8d388af_o.jpg'\n'http://farm1.static.flickr.com/246/452652438_acc3973810_o.jpg'\n'http://farm1.static.flickr.com/233/452652648_fca794b11a_o.jpg'>>\n===
\nTiddlyWiki uses Wiki style markup, a way of lightly "tagging" plain text so it can be transformed into HTML. Go into edit mode by double-clicking this tiddler or pressing the 'edit' button in the hidden menu above to see the code for the following formatting samples.\n\n! Header Samples\n!Header 1\n!!Header 2\n!!!Header 3\n!!!!Header 4\n!!!!!Header 5\n\n! Unordered Lists:\n* Lists are where it's at\n* Just use an asterisk and you're set\n** To nest lists just add more asterisks...\n***...like this\n* The circle makes a great bullet because once you've printed a list you can mark off completed items\n* You can also nest mixed list types\n## Like this\n\n! Ordered Lists\n# Ordered lists are pretty neat too\n# If you're handy with HTML and CSS you could customize the [[numbering scheme|http://www.w3schools.com/css/pr_list-style-type.asp]]\n## To nest, just add more octothorpes (pound signs)...\n### Like this\n* You can also\n** Mix list types\n*** like this\n# Pretty neat don't you think?\n\n! Tiddler links\nTo create a Tiddler link, just use mixed-case WikiWord, or use [[brackets]] for NonWikiWordLinks. This is how the GTD style [[@Action]] lists are created. \n\nNote that existing Tiddlers are in bold and empty Tiddlers are in italics. See CreatingTiddlers for details.\n\n! External Links\nYou can link to [[external sites|http://google.com]] with brackets. You can also LinkToFolders on your machine or network shares.\n\n! Images\nEdit this tiddler to see how it's done.\n[img[http://img110.echo.cx/img110/139/gorilla8nw.jpg]]\n\n!Tables\n|!th1111111111|!th2222222222|\n|>| colspan |\n| rowspan |left|\n|~| right|\n|colored| center |\n|caption|c\n\nFor a complex table example, see PeriodicTable.\n\n! Horizontal Rules\nYou can divide a tiddler into\n----\nsections by typing four dashes on a line by themselves.\n\n! Blockquotes\n<<<\nThis is how you do an extended, wrapped blockquote so you don't have to put angle quotes on every line.\n<<<\n>level 1\n>level 1\n>>level 2\n>>level 2\n>>>level 3\n>>>level 3\n>>level 2\n>level 1\n\n! Other Formatting\n''Bold''\n==Strike==\n__Underline__\n//Italic//\nSuperscript: 2^^3^^=8\nSubscript: a~~ij~~ = -a~~ji~~\n@@highlight@@\n@@color(green):green colored@@\n@@bgcolor(#ff0000):color(#ffffff):red colored@@
<<formTiddler NewBookTemplate>><data>{"author":"吳瓊 等編","booktitle":"形象的修辭:廣告與當代社會理論","pubinfo":"中國人民大學出版社(北京)","callnumber":"7300069525","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/195/452649164_65a87c18a1_o.jpg'\n'http://farm1.static.flickr.com/235/452649358_66898eea44_o.jpg'\n'http://farm1.static.flickr.com/204/452669883_5588b8620f_o.jpg'\n>>\n===
建置中
<<toggleTag 文章 >>
建置中
建置中
<<forEachTiddler\nwhere\n'tiddler.tags.contains("圖書") && tiddler.data("booktitle")'\nsortBy 'tiddler.data("author")'\nwrite\n'"{{justfine{"+tiddler.data("author")+",}}} {{italic{"+tiddler.data("booktitle")+".}}} "+tiddler.data("pubinfo")+" [[here|"+tiddler.title+"]]<br>\sn"' \n>>\n
<<formTiddler NewBookTemplate>><data>{"author":"Susanne Langer ","booktitle":"情感與形式","pubinfo":"千華(台北)","callnumber":"957624160x","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/240/452667855_820b5816a6_o.jpg'\n'http://farm1.static.flickr.com/242/452647470_d3b381dfcd_o.jpg'\n'http://farm1.static.flickr.com/212/452668111_3c99cadf3c_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"callnumber":"9573221292","booktitle":"攝影的哲學思考","author":"Vilem Flusser (李文吉譯)","pubinfo":"遠流出版社(台北)","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/253/452643228_0b80b1ce5c_o.jpg'\n'http://farm1.static.flickr.com/190/452664033_597b5e4068_o.jpg'\n'http://farm1.static.flickr.com/211/452643490_902a0a8242_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Mary Warner Marien (郝紅尉 等譯)","pubinfo":"山東畫報出版社(濟南)","booktitle":"攝影與攝影批評家:1839年至1900年間的文化史","callnumber":"7807131659","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/253/452670765_68fdc51999_o.jpg'\n'http://farm1.static.flickr.com/213/452650594_5bea670f37_o.jpg'\n'http://farm1.static.flickr.com/199/452650822_492da42b82_o.jpg'\n'http://farm1.static.flickr.com/239/452650976_3c34c5e5da_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Harald Johnson(邱芳信譯)","booktitle":"數位列印/輸出聖經","pubinfo":"旗標(台北)","callnumber":"9574421929","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/181/452654758_37d3340195_o.jpg'\n'http://farm1.static.flickr.com/230/452655310_32e6291b7f_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Rafael C. Gonzalez,Richard E. Woods(繆紹綱編譯)","booktitle":"數位影像處理","pubinfo":"普林斯頓國際有限公司(台北)","callnumber":"9867594118","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/243/452678251_5d637f8abb_o.jpg'\n'http://farm1.static.flickr.com/194/452678733_fd7630460a_o.jpg'\n'http://farm1.static.flickr.com/181/452658654_5d5af8abb4_o.jpg'\n'http://farm1.static.flickr.com/223/452678981_ebfd0790c0_o.jpg'\n'http://farm1.static.flickr.com/208/452679179_145d52d44d_o.jpg'\n'http://farm1.static.flickr.com/224/452662323_5ae7f52568_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"John Paul Caponigro (陳賢錫譯)","booktitle":"數位相片專業設計講堂","pubinfo":"旗標(台北)","callnumber":"9574422356","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/192/452673387_2685ff0269_o.jpg'\n'http://farm1.static.flickr.com/187/452673503_c379fbf896_o.jpg'\n'http://farm1.static.flickr.com/186/452673747_5a0e145fec_o.jpg'\n'http://farm1.static.flickr.com/167/452653620_bb9a3cb833_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"M. Galer,L. Horvat(司大宇譯)","booktitle":"數字圖像處理技巧","pubinfo":"浙江攝影出版社(杭州)","callnumber":"7805369887","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/170/452655710_685805f1f5_o.jpg'\n'http://farm1.static.flickr.com/237/452656360_38226baee9_o.jpg'\n'http://farm1.static.flickr.com/203/452676825_18f32efcd9_o.jpg'\n'http://farm1.static.flickr.com/174/452677009_0ec5354416_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Guy Ernest Dobord 著(王昭風 譯)","booktitle":"景觀社會","pubinfo":"南京大學出版社(南京)","callnumber":"730504508x","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/175/452648456_eab28e1c6e_o.jpg'\n'http://farm1.static.flickr.com/175/452669083_edea4e25df_o.jpg'\n'http://farm1.static.flickr.com/181/452669347_92545728d5_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Douglas Kellner 編(陳維振,陳明達,王峰 譯) ","booktitle":"波德里亞:批判性的讀本","pubinfo":"江蘇人民出版社(南京)","callnumber":"721403672x","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/215/452662459_b97ecea5d2_o.jpg'\n'http://farm1.static.flickr.com/234/452642030_77d9740a9a_o.jpg'\n'http://farm1.static.flickr.com/185/452662745_f3f0ebfdc0_o.jpg'\n'http://farm1.static.flickr.com/199/452662859_8cdf17b16a_o.jpg'>>\n===
test
<<formTiddler NewBookTemplate>><data>{"author":"Mark Poster 著(範靜嘩 譯)","pubinfo":"南京大學出版社(南京)","booktitle":"第二媒介時代","callnumber":"7305035378","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/198/452663005_14a45d483a_o.jpg'\n'http://farm1.static.flickr.com/228/452642600_912164714a_o.jpg'\n'http://farm1.static.flickr.com/237/452642766_e651b8d45b_o.jpg'\n'http://farm1.static.flickr.com/182/452663533_2265d558d6_o.jpg'\n'http://farm1.static.flickr.com/224/452663663_e56541a521_o.jpg'>>\n===
+++[一、前言|tooltip]\n 美國國會圖書館在網路上提供了相當豐富的數位化項目,除部分項目有特殊限制外,大多數免費提供非商業性使用的下載,但若需要更高品質的影像或進行商業性使用,美國國會圖書館亦設立「複製服務」 ,以方便讀者使用美國國會圖書館的高品質影像。這些服務希望滿足學者、出版商、圖書館、機構、研究人員和一般民眾等,對於國會圖書館館藏的影印、照片、微縮膠捲或者數位影像複製的需求。其規定皆符合美國版權法和相關限制。不過由於圖書館的複製服務沒有另外的撥款預算,因此皆是藉由索費以維持複製產品和服務的運作。以下針對其中訂購數位影像複製品的需求略作說明。\n===\n\n+++[二、訂購方式|tooltip]\n 1. 資料搜尋:\n(1) 預訂現有數位影像之項目:\n國會圖書館線上展示的影像,可製成數位印刷品。若要尋找所需影像,可透過美國記憶(American Memory)進行搜尋,或者透過虛擬閱覽室如[「印刷及攝影部門」或者「地理及地圖部門」等。\n(2) 預訂需掃描原始材料的項目︰\n除訂購現有數位影像外,國會圖書館亦提供數位化原始材料的服務,如掃描地圖、微縮膠捲,或者其他來自圖書館收藏的原始的材料。若要要尋找項目,可使用國會圖書館線上目錄,大約有1200萬筆資料,包括圖書館裡的圖書、期刊、電腦檔案、手稿、地圖材料、音樂、錄音和視覺材料。 (不過並非全部材料都適用於掃描)\n2. 紀錄訂購項目編號:\n所有攝影、複印和微縮膠捲的複製訂單,必須包括圖書編號或複製編號,若是數位影像服務則必須包括數位身分證明(例如︰ bbc 1378, 或者 g3721p rr001110.)。通常,訂單必須有圖書編號或複製編號,才得以確認預訂的材料。圖書編號或複製編號在線上目錄和出版品都有。若以上都沒發現圖書編號或複製編號,則必須進一步透過顧客搜尋,或透過保管資料的閱覽室的搜尋服務。\n3. 根據需求選擇訂貨單,包含影印、微捲複製或攝影、數位影像複製兩種格式,攝影、數位影像複製訂貨單可以從服務處的網站下載(請參見附件)。完成後即可直接至國會圖書館訂購,或透過傳真、寄信或者電子郵件等方式。\n4. 此外,國會圖書館亦提供緊急訂購服務,使用急件服務,訂單將在10個工作日內完成,但相對的價錢亦會提高,例如數位化複製的緊急服務訂單,價錢為原價的3倍。\n===\n\n+++[三、收費方式|tooltip]\n根據不同的館藏品及複製方式、運送方式等不同的要求,皆列有不同的收費標準:\n| !服務項目 | !金額 | !備註 |\n|把現有的.tiff 檔案複製到CD-ROM |22.00美元/個| |\n|數位彩色噴墨列印|22.00 美元 /英尺|最多36"(寬)|\n|從原件掃描|50.00 美元 /次|除非另有需求,否則解析度是300 dpi,而且並非全部資料都可掃描。|\n|>| !數位黑白照片印刷 |形式和價格是針對現有的數位影像而言,最大為50" x 204 "。影像也可列印在特別的媒介上,如帆布或塑膠。數位彩色或黑白底片,以及彩色幻燈片也有提供。必須另行聯繫報價的服務。|\n|8 " X 10"|25.00 美元|~|\n|11 " X 14"|33.00 美元|~|\n|16 " X 20"|40.00 美元|~|\n|20 " X 24"|58.00 美元|~|\n|30 " X 40"|126.00 美元|~|\n|>| !數位彩色黑白照片印刷 |~|\n|8 " X 10"|40.00 美元|~|\n|11 " X 14"|53.00 美元|~|\n|16 " X 20"|80.00 美元|~|\n|20 " X 24"|126.00 美元|~|\n|30 " X 40"|308.00 美元|~|\n|>|>| !微縮膠捲或者縮微膠片掃描至CD-ROM |\n|自動資料掃描為.tiff 圖像|0.75美元 / 張|300 dpi,後製編輯,QC,並且複製到CD-ROM|\n|.tiff 變換為PDF|0.90 美元/張|僅限圖像|\n|.tiff 變換為PDF 並進行文字辨識|1.05 美元/張|只提供英語列刷書材料|\n|每個訂貨最少費用|20.00 美元| |\n\n===
美國國會圖書館(以下簡稱國會圖書館)的宗旨是:「向國會和美國人民提供他的資料,維護和保存世界性知識和創造性的館藏,為子孫後代服務。」該宗旨表明了國會圖書館包含有為立法及為國家服務的職能,而這也決定國會圖書館藏書性質及結構。\n國會圖書館創建於1800年,根據約翰.亞當斯總統于1800年4月24日簽署的「為美國政府的遷移及所需設備進一步做好準備法案」第五款的規定,撥款總數五千美元「用于購置位於華盛頓市的國會所需添置的圖書,並為收藏這批圖書配備適當的庫房。」第一任館長約翰.貝克利于1802年四月出版了國會圖書館的藏書目錄,其時共收錄圖書九百六十四冊、地圖和圖表九張。這些館藏當中,主要是工具書,尤其是收藏法律方面的訊息,供立法者使用。1812年該館曾遭焚燬,1815年杰弗遜總統(當時已退休)出售6487冊個人藏書給國會,用於重建國會圖書館。由於這批書的範圍已超出原館藏範圍(法律、歷史),杰弗遜隨後表示國會議員應涉及任何主題,並在國會引起辯論。最後國會仍購置杰弗遜這一批私人藏書,不僅使國會圖書館的藏書增加了一倍,同時也改變了該館藏書和機構的性質。藉由圖書館藏書範圍的不斷擴大,成為該館既為國會又為全國其他部門和讀者擴大服務的基礎,這亦是國會圖書館歷史上最重要的藏書建設。1851年,國會遭逢大火,使國會圖書館中的藏書,焚燬三分之二(當時館藏約55000冊),1859年國會更廢止向國會圖書館版權繳送的法律,該館不能再依據1846年通過的版權繳送法規,接受圖書和小冊子。 \n這現象直到斯波福特擔任館長方有改變,在斯波福特擔任館長的最初幾年,他促使國會批准六項保證國會圖書館履行國家職能的法案和決議:\n 1.為擴建位於國會大廈的圖書館提供一筆撥款。(此項法案子1865年初獲准。)\n 2.1865年版權修正案再次肯定把繳送本納入國會圖書館館藏。\n 3.1866年斯密森學會圖書館的全配藏書,轉給國會圖書館保存。\n 4.1867年以十萬美元向歷史學家和檔案學家被得.福斯私人圖書館購買的圖書,成為國會圖書館美國歷史文獻資料和古版書的藏書基礎。\n 5.1867年通過的國際交換決議,為國會圖書館擴大收藏國外公開發行的官方正式文獻奠定了堅實的基礎。\n 6.1870年版權法頒布之后,所有版權登記和繳送活動均由國會圖書館統一進行。\n 斯被福特在藏書建設方面最顯著的功績,就是在1870年把美國的全部繳送本和版權登記活動,完全集中到國會圖書館。版權法確保該館能不斷地補充收藏美國的出版物。它規定在美國進行版權登記的圖書、小冊子、地圖、印刷品和樂譜必須向國會圖書館繳送二冊(張)。根據l 981年的統計,它已收藏470多種語文的圖書資料共達78,641,212件,其中包括:\n 1.圖書18,930,905冊(珍本書35,000種);\n 2.古今世界地圖、地圖冊、地球儀等3,624,347件;\n 3.手稿33,391,320件(包括23位美國總統的珍貴手稿)﹔\n 4.法律資料1,700,000條;\n 5.微縮資料3,477,685件;\n 6.樂譜、音樂資料3,668,063件﹔\n 7.科技報告1,295,185件﹔\n 8.圖片、版畫、建築草圖等10,000,000件﹔\n 9.各種電影片281,271片﹔\n 10.盲文讀物與視聽資料4,000,000件﹔\n 11.各種報紙400,000冊。\n 12.以及大量的期刊、政府出版品和其它連續性出版品等。\n 此外,國會圖書館在中文文獻的收藏方面也極為豐富,它是外國圖書館中收藏中文圖書最多的圖書館之一。從l 9世紀40年代就開始收藏,到1912年入藏的中文書籍已達16,900冊。以後陸續通過不同途徑廣為搜集,即使在二次大戰期間仍自重慶購買。至l 984年底,國會館收藏的中文圖書已達50餘萬冊。\n另有中文期刊、報紙、微縮膠卷等文獻。目前共擁有近8,000種中文期刊,其中。特別應當提出的是,該館藏有我國許多有歷史性的知名善本和珍貴資料。如:1924年在杭州西湖雷峰塔內發現的我國于975年刊印的佛經《一切如來經》﹔1403-140 7年間我國歷史上最大的類書《永樂大典》的殘卷﹔1728年在北京以活字銅版刊印的中國第二大類書《(欽定)古今圖書集成》。此外,還藏有宋、金、元、明、清各代善本共約2,000餘種,以及大量的中國地方志,藏、蒙、滿、納西等文字的資料。\n 20世紀,隨著文獻載體形式的增加,國會又陸續增設國會圖書館的附屬機構,如1931年建立國家盲人和殘疾人圖書館,收藏資料供殘疾讀者使用。1976年到1977年,相繼成立美國民俗中心、美國電視和廣播資源庫及圖書中心。1988年成立全國影片保護委員會。並於1990年創立「美國記憶」並擴展為全國數位圖書館計畫,該計畫的目標是透過網際網路,提供500萬件藏品開放使用。數位化對象主要為美國的歷史文獻,包括歷史照片、手稿、歷史檔案及其他文獻等。該計畫曾在1992至1993年間,以分發CD-ROM的方式在44個中小學校、學院、大學進行了用戶評價測試,結果獲得了廣泛好評。\n 在管理方面,國會圖書館的藏品主要由「圖書館服務部」負責,以下介紹主要組別:\n+++[一、公共服務館藏|tooltip]\n 1. 地理與地圖組:\n地理和地圖組負責收藏地圖、地圖冊、地球儀以及與地圖和製圖有關的唯讀光碟。該組在全國數位圖書館計畫中,負責制定地圖傳遞標準。並與國會研究服務部合作開發該組的地理資訊系統(GISs)資源。該組擁有包括內戰時期地圖、美國鐵路圖、美國城市全圖等在內的450萬件地圖館藏,並陸續產生數位化替代品。\n\n2. 手稿組:\n手稿組收藏國家級檔案和手稿資料,共收藏了23位總統、若干位最高法院法官、著名作家、發明家和文人的文件及全國性重要組織的檔案。該組的資料劃分為12000個大類,有的類別只有幾個文件,有的類別則需幾千個盒子才能容納。全國數位圖書館計畫從該組取用了若干檔案作為數位化的示範處理。該組不願意讓館藏數位化,部分原因是,手稿組尚有大批未經加工處理的積壓資料。該組員工認為,將積壓館藏資料整理加工使之見諸於世,比數位化更為急迫。\n\n3. 影片、廣播和錄音組\n影片、廣播和錄音組擁有100萬件錄音製品、20萬盒影片館藏。這些館藏中絕大多數資料仍處於版權保護範圍之內,因而限制了國會圖書館建立數位化資料的進度。但特別是早期的影片,已經實現數位化並於全國數位圖書館展示。\n\n4. 圖片和照片組:\n出於保護和使用的目的,圖片和照片組曾經制訂過一項建立數位複本的長期計畫。該組1350萬件藏品當中,約有十分之一已陸續納入全國數位圖書館計畫。\n\n5. 連續出版品和政府出版品組:\n連續出版品和政府出版品組共有7萬種期刊、1400種報紙以及聯邦政府的出版品,通過與各資源庫的連接,可以提供各種線上電子版報紙和電子期刊。該組並未開始收集數位化的期刊或者印本期刊的電子版的形式。另外該組亦負責收藏微縮膠捲。該組很少介入全國數位圖書館計畫,部分原因涉及私營出版商的權益,部分原因是因為技術問題。如報紙的顯示技術,還難以令人滿意。\n\n6. 善本和特藏組:\n該組已入藏了500,000餘件圖書、小冊子、單面印刷品和有關文獻。它們或是某種書籍的最初版本,或是與著者或某個事件有關,或是一種非常稀有而又有價值的文獻。該組藏書的三分之一按國會分類法排架。其中有在裝訂、印刷史上占重要地位的貴重書刊或具有歷史意義的文獻。其餘三分之二分組入藏,如杰弗遜藏書、制紙史藏書等。\n===\n\n+++[二、地區研究館藏|tooltip]\n1.亞洲組:\n該組管理漢文、韓文、日文以及南亞資料,並擁有這些文獻的專家。漢文藏書始自1869年清朝皇帝933冊贈品,現在擁有藏書50餘萬。\n 韓文圖書有65,000冊,以韓國出版的近期出版品為主。\n日文圖書存606,000冊,其中除大量的文學、歷史和日本憲法以外,還有日本外務省1868到1945年的檔案微縮膠捲。 \n\n2.非洲與中東組:\n該組的主要任務是補充本組館藏,協助研究人員查找資料,編輯書目和指南。\n 藏書包括:希伯來文、依地文、敘利亞文、阿拉米文、波斯文、阿拉伯文、阿姆哈拉文等大約114,000冊。\n 非洲藏書包括除農業和醫學以外的各主要門類。其中大部分資料,特別是經濟、歷史、語言、文學等類,都分別收藏在國會圖書館的普通書庫和期刊書庫中。有關手稿、地圖、微捲、音樂、報紙、圖片、照片等特種資料亦分別歸各有關部門保管。\n\n3.歐洲組:\n該組是西方國家收藏斯拉夫語文圖書最多的部門。1901年只擁有俄文圖書569本,1907年增至12,000本,這批書已成為現在斯拉夫語言藏書的核心。二次大戰後又有大量增加。\n 近年來,歐洲組每年大約為30,000人服務,其中一半是電話咨詢。1970年,歐洲組在館內閱覽的資料已從每年的22,000件增至60,000件。近年又有所增加。\n \n4.拉丁美洲組:\n該組成立于1939年。其所藏西班牙文及葡文兩種語文的圖書資料在數量上居於世界前列。其中歷史、文學和社會科學藏書尤為豐富。該部除收藏這些圖書外,還出版書目和指南,以便讀者更好地加以利用。\n===
<<formTiddler NewBookTemplate>><data>{"author":"Stuart Hall 編(徐亮 陸興華 譯) ","booktitle":"表徵:文化表像與意指實踐","pubinfo":"商務印書館(北京)","callnumber":"7100035732","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/240/452666807_1b6a59eed9_o.jpg'\n'http://farm1.static.flickr.com/167/452646388_aff161913b_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"Monique Sicard","booktitle":"視覺工廠:圖像誕生的關鍵故事","pubinfo":"邊城出版(台北)","callnumber":"9572991582","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/190/452647854_3d88eac1e2_o.jpg'\n'http://farm1.static.flickr.com/174/452668705_fa3be248fd_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"吳瓊 編","pubinfo":"中國人民大學出版社(北京)","booktitle":"視覺文化的奇觀:視覺文化總論","mine":true,"callnumber":"7300069517"}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/238/452670057_bb13ca923b_o.jpg'\n'http://farm1.static.flickr.com/167/452670247_94b8672ab6_o.jpg'\n'http://farm1.static.flickr.com/199/452670375_e8f22f01cb_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"booktitle":"視覺研究導論:影像的思考","author":"Gillian Rose","pubinfo":"群學(台北)","callnumber":"9868107644","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/199/452664351_b3f444d449_o.jpg'\n'http://farm1.static.flickr.com/202/452643864_c85a18fc55_o.jpg'\n'http://farm1.static.flickr.com/236/452664631_4a91207ba0_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"author":"William Norman Bryson (郭楊 等譯)","booktitle":"視覺與繪畫:注視的邏輯","pubinfo":"浙江攝影出版社(杭州)","callnumber":"780686122x","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/179/452656962_258e033b7a_o.jpg'\n'http://farm1.static.flickr.com/206/452657206_234ae48464_o.jpg'\n'http://farm1.static.flickr.com/225/452677713_6a4e0aaad1_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"booktitle":"計算機視覺","callnumber":"7111159721","mine":true,"author":"Linda G. Shapiro ,George C. Stockman","pubinfo":"機械工業出版社(北京)"}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/242/452665105_cf450b41d5_o.jpg'\n'http://farm1.static.flickr.com/224/452644738_e338115aa4_o.jpg'\n'http://farm1.static.flickr.com/206/452665529_559e5f0920_o.jpg'\n'http://farm1.static.flickr.com/246/452665845_b4911296b5_o.jpg'\n'http://farm1.static.flickr.com/205/452645374_fdc09f0291_o.jpg'\n'http://farm1.static.flickr.com/188/452666353_fb1fb63dd8_o.jpg'\n'http://farm1.static.flickr.com/201/452646076_e9c33f87f7_o.jpg'>>\n===
<<formTiddler NewBookTemplate>><data>{"callnumber":"9578900775","author":"Susan Sontag","pubinfo":"唐山(台北)","booktitle":"論攝影","mine":true}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/239/452671747_9476796446_o.jpg'\n'http://farm1.static.flickr.com/217/452651518_2e29c4994e_o.jpg'\n'http://farm1.static.flickr.com/177/452651606_cb102b47da_o.jpg'\n>>\n===
<<formTiddler NewBookTemplate>><data>{"callnumber":"7501327386","mine":true,"booktitle":"資源數字化標準問題研究","author":"彭緒庶 蔣穎","pubinfo":"北京圖書館出版社(北京)"}</data>\n+++[書影|tooltip]\n <<gallery list 'http://farm1.static.flickr.com/254/452674097_1fc31cb32d_o.jpg'\n'http://farm1.static.flickr.com/199/452674569_776f0407af_o.jpg'\n'http://farm1.static.flickr.com/170/452654370_ab57ac7ce3_o.jpg'>>\n===
<<formTiddler NewBookTemplate>>