May 22, 2007 \nDear Badminton World: \nThe Pennsylvania York Badminton Tournament is here, June 16-17, 2007 in York, PA. After a 6 year run, the New Jersey Open tournament is ended and the PA York tournament fills the slot on the third weekend of June. Go to USbadminton.net and register before June 6 to avoid late fees. Don’t \nbe confused if you see the title: PA Open. This was the original tournament name until USA Badminton made us change it. The web site may still say PA Open but it really is PA York Badminton Tournament. Thanks to Eric Miller and George for setting up the new web site. Remember \nto log in, then hit register, pick the tournament, pick your events, then pick your partner’s from the drop-down list. Print out the registration form \ntwice and mail one copy with your payment as directed. No online payment has been set up for this tournament. The tournament information is in the attached file. See you at the tournament. \nDaryl Jones \nTournament Director \nPA York Badminton Tournament \n\n\nPENNSYLVANIA YORK BADMINTON TOURNAMENT \n\nJUNE 16-17, 2007
''Posted 2006Oct31'' -- New\nSample pdf download from a badminton techniques book.\n[[Tactics: Deception at the Net Sampler|http://instructoons.com/book/]]\n\n''Posted 2006Oct27'' -- Announcement\n@@Badminton World Cup 2006@@, Yi Yang, China.\nOct 24 - 28\nhttp://www.yumaoqiu.net.cn/new/news/default.asp?cataid=79\n\n''Posted 2006Oct18'' -- Announcement\nThere will be a @@{{{tournament}}}@@ in Bryn Athyn, Pennsylvania. It is opened for registration:\n<<reminder year:2006 month:11 day:10 title:"@@2006 ~Mid-Atlantic Badminton Classic@@" format:"TITLE on DATE">> til Nov 12\nhttp://bima.astro.umd.edu/~teuben/badminton/mida/\n\n
''Posted 2006Dec20'' -- Announcement\n@@[[2007 National Capital ("DC") Open|http://www.astro.umd.edu/~teuben/badminton/dcopen/]]@@ (January 19-21) is opened for registration:\nhttp://bima.astro.umd.edu/dcopen/register07.html\n\n''Posted 2006Dec19'' -- Announcement\nSonny Werblin will be closing from 2006Dec25(Mon)-2007Jan01(Mon). Merry Christmas and Happy New Year!\nhttp://recreation.rutgers.edu/schedule/index.html\n\n''Posted 2006Dec06'' -- Announcement\nCalling for @@~RUBad logo design@@. Please do not hesitate and send us what is in your mind. Please contact rubad@eden.rutgers.edu .\n\n''Posted 2006Nov20'' -- Announcement\nSonny Werblin closing from Nov22(Wed, 7pm)-Nov26(Sun). Happy Thanksgiving!\nhttp://recreation.rutgers.edu/schedule/index.html\n\n''Posted 2006Nov14'' -- Announcement\nBadminton in the 15th Asian Game, Doha, Qatar (Dec1-9)\n@@Asian Game Badminton@@ Dec1 til Dec 9\nhttp://www.doha-2006.com/gis/menuroot/schedule/ScheduleBySport.aspx?id=42
''Posted 2007Jan30'' -- Announcement\n@@[[Mainline ABC Doubles|http://pa.usbadminton.net/mainline/]]@@ in Bryn Mawr College, PA - 1.5hours from Piscataway (February10; Deadline:February1)\nLet's go have fun!\n\n''Posted 2007Jan25'' -- Announcement\n@@[[2007 Yonex Korea Open|http://www.koreaopen.or.kr/]]@@ (January 23-28)\n[[Draw/Schedule|http://www.tournamentsoftware.com/sport/draws.aspx?id=13214]]\n\n''Posted 2007Jan25'' -- New\nUpdated [[Link]] and [[Rotation of play/Scoring]] section. We recommend all to adopt the new 21 rally point system (see [[Rotation of play/Scoring]]).\n\n''Posted 2007Jan22'' -- Announcement\nCongratulation to Derek and his brother Henrik. Both of them have won men's double in C category. Derek have won the men's single in Collegiate (U) category whereas Henrik has won second place in men's single for D category.\n\n''Posted 2007Jan19'' -- Announcement\n@@[[2007 Proton Malaysia Open|http://www.tournamentsoftware.com/sport/draws.aspx?id=13163]]@@ (January 16-21)\n[[Schedule|http://www.tournamentsoftware.com/sport/matches.aspx?id=13163]]\n\n''Posted 2007Jan17'' -- Announcement\n@@[[2007 National Capital ("DC") Open|http://www.astro.umd.edu/~teuben/badminton/dcopen/]]@@ (January 19-21)
''Posted 2007Mac08'' -- Announcement\nSonny Werblin is going to closed earlier (9pm) during the spring break. We will not have club reserved time (Mon 9-11pm) for spring break. However, we could play during the spring break before 9pm (~Mon-Thurs). [[Sonny Spring break schedule|http://www.recreation.rutgers.edu/schedule/nextweek.html]]\n\n''Posted 2007Mac08'' -- Announcement\n@@2007 Yonex All England Open@@ (March 6 - March 11)\n[[Result/Schedule|http://www.horizonsolutions.tv/alleng07/110290605107ibzz10main.php]]\n\n''Posted 2007Feb17'' -- New\n[[Link]] section updated.\n\n''Posted 2007Feb14'' -- Announcement\nNew club reserved time. Monday 9pm-11pm Sonny Werblin. Please do join us. It's not just playing time. We will have sets of drills for members to practice. Good opportunity to improve your skills.\n\n''Posted 2007Feb13'' -- New\n[[Photo/Video]] section added.\n\n''Posted 2007Feb5'' -- Announcement\n@@[[Cook/Douglas Badminton Intramural|http://cdrec.rutgers.edu/ims/]]@@ (February24-25)
\n''Posted 2007May29'' -- Announcement\nSummer session started. New [[Schedule]]?\n\n''Posted 2007May29'' -- Announcement\n@@[[2007 PA York Open|http://badminton-tourney.info/2007PA_York.htm]]@@ (former NJ Open), June 16-17, [[Penn State York campus|http://maps.google.com/maps?f=d&hl=en&saddr=08854&daddr=1031+Edgecomb+Avenue,+york,+pa&sll=39.904469,-76.619682&sspn=0.116145,0.32135&ie=UTF8&ll=40.136891,-75.893555&spn=0.925986,2.570801&z=9&om=1]].\nSee message from tournament director, Daryl Jones here: [[07PAOpen]].\nRegistration deadline: June 6 (late fees applies after the date)\n\n''Posted 2007May29'' -- Announcement\n@@[[2007 PBA YMCA Tournament|http://badminton-tourney.info/Phoenixville-Branch_YMCA.htm]]@@(1 day Round Robin Doubles), June 9, [[YMCA Phoenixville, PA|http://maps.google.com/maps?f=d&hl=en&saddr=08854&daddr=400+E+Pothouse+Rd,+Phoenixville,+PA&sll=40.136891,-75.893555&sspn=0.925986,2.570801&ie=UTF8&ll=40.250184,-74.814148&spn=0.92444,2.570801&z=9&om=1]].\nRegistration deadline: June 2\n\n''Posted 2007May1'' -- Announcement\nSonny Werblin will be closed earlier during the period of April 30-May 13. Please refer to http://recreation.rutgers.edu/schedule/index.html\n\n''Posted 2007May1'' -- New\n@@[[2007 Rutgers Badminton Club Tournament Photo|http://picasaweb.google.com/rubadminton/070430RubadTourney]]\n\n''Posted 2007April19'' -- Announcement\n@@[[2007 Rutgers Badminton Club Tournament]]@@ April 23, 7-11pm @ Sonny Werblin, Multisport (Busch campus).\n\n''Posted 2007April11'' -- Announcement\nThere will be no reservation at Loree, again, this coming Sunday, April 15. Let's go to Sonny Werblin to play on Saturday, April 14, instead, suggested time: 1pm-3pm.\n\n''Posted 2007April04'' -- Announcement\n@@[[2007 Rutgers Badminton Club Tournament]]@@ is opened for registration.
''Posted 2007September27'' -- Announcement\nWe will have a @@friendly tournament with NJIT badminton club@@ on October 13. Please feel free to participate. It will be a good chance to meet other badminton fans in the area. We urge everyone to participate. Please send an email to lam_derek@yahoo.com.hk for further information if you are interested.\n\n''Posted 2007September24'' -- Announcement\n- CORRECTION:: Saturday 1pm-5pm club reserved time is in Cook/Douglas Recreation Center NOT Loree.\n- Due to the football game, Rutgers vs. Maryland, practice at Cook/Douglas Recreation Center (1pm-5pm) on Sept. 29 will be cancelled.\n\n''Posted 2007September14'' -- Announcement\nSorry for the late notice:: due to the football game, Rutgers vs. Norfolk, practice at Loree (1pm-5pm) on Sept. 15 will be cancelled.\n\n''Posted 2007September10'' -- New\nWelcome back, please check the new [[Schedule]].\n\n''Posted 2007August15'' -- Announcement\n@@[[2007 World Championship|http://www.tournamentsoftware.com/sport/draws.aspx?id=16313]]@@ (August13-19)\n
\n''Posted 2007October31'' -- Announcement\n@@1 day Doubles Badminton Tourney@@ at Sonny Werblin Recreation Center, Busch campus, Rutgers, on November 4 (Sunday, 1pm). Please register via email to Sue Beaudrow (beaudrow@rci.rutgers.edu).\n\n''Posted 2007October13'' -- Announcement\nThank you to all from NJIT and all from Rutgers for participating in the friendly tournament.\n\n''Posted 2007October11'' -- Announcement\nFriendly tournament with NJIT, October 13 (Saturday).\nLocation changed to @@[[Sonny Werblin|http://maps.rutgers.edu/building.aspx?id=297]] Recreation Center@@, Multisport Bay 1.\n\n''Posted 2007October6'' -- Announcement\nPractice tomorrow at "Cook/Douglas Recreation Center" from 1pm-5pm.\n\n''Posted 2007October5'' -- Announcement\n@@2007 Mr. Kon Cup Badminton Tournament@@ is opened for registration. Please contact Derek for registration form (lam_derek@yahoo.com.hk). The registration deadline is October12.
''Posted 2008January24'' -- Announcement/News\n-Welcome back... New [[Schedule]]\n-@@[[2008 Mainline Double|http://pa.usbadminton.net/mainline/]]@@, Feb9 is opened for registration (Registration fee will be covered by the club).\n-@@Rutgers Badminton Intramural Singles@@, each Monday from February 4 to March 24, registration deadline Jan27(via [[Internet|http://activenet2.active.com/rutgersrec/]]), Jan28 (in person)\n\n\n''Posted 2007November2'' -- Announcement\n-- @@FREE ~RUBad t-shirt@@ for members (those who paid the dues). Please let Derek know your size of preference by emailing to lam_derek@yahoo.com.hk as soon as possible.\n-- Hopefully, we will be able to play this Saturday (Nov 3) at Cook/Douglas Recreation Center from 1pm-5pm. The person-in-charged from Rutgers Recreation has been so kind to assure us that we should be able to play this time. For the past 2 months, it has just been some minor technical difficulties and miscommunications. We apologize deeply for the disappointments on behalf of the Recreation Center and let's cross our fingers for this coming Saturday.\n\n
<<newReminder>>\n\n''Posted 2008October3'' -- Announcement\nWe'll be meeting today at the usual time, 7pm, in Werblin.\nWe've been making some progress in setting up some deals to get @@discounts@@ on at least @@racquets@@ - we'll mention this at the meeting to get a feel for who might want to purchase anything through us.\nWe will start to @@collect dues@@ today and in the next ~3 weeks.\nSee you on the courts,\nRobert\n\n''Posted 2008September25'' -- Announcement\nRUBAD's third meeting is Friday, 9/26, at the usual time and place. Don't worry about trying to stagger arrival times this time, haha.\nThings will run mostly the same as last time though probably with a few switch-ups, namely we're likely not doing "King(s) of the Court" for the full time period.\nAt this meeting, the sign-in sheets will have a few additional columns asking if you are interested in:\n-Competitive play\n-RUBAD T-shirt/other apparel\n-Badminton shoes\n-Badminton racquet\nPrices are still being worked out, but we're trying to get a general idea of who's interested in what.\nWe'll be trying to sell/get you guys to sell various RUBAD-branded things for the purpose of fundraising for the club sometime further into the semester.\nSee you guys on the courts!\n\n\n''Posted 2008September18'' -- Announcement\nRUBad's second meeting is on 9/19/08.\nIMPORTANT: In order to avoid chaos, we're testing out ways of staggering arrival times in some kind of orderly fashion, so:\nFirst names A-M, please arrive at ~6:50pm.\nFirst names N-Z, please arrive at ~7:50pm.\n* NOTE: If you prefer to arrive with friends, go ahead and do so. The alphabetical staggering above is more of a guideline than any strict rule.\nWe understand that this is not necessarily the most efficient way to do things, but we also figure that by the meeting after this, we'll have a good idea of who's more likely to stay. Also by then we should have more club hours set.\nOur basic plan for the meeting to make the best use of everyone's time:\nCourt 1:\nServing practice.\nCourt 2 and between courts:\nPracticing the "clear".\nCourt 3:\nKing of the Court!\nWe'll explain this if and when we see you there ;)\nAnd for those waiting, the Wall Rally Drill to improve footwork, reflexes, and general strength of arm and wrist muscles used in badminton.\nIn terms of equipment that we can lend, we're still short on racquets - one of the things on our to-do list is to see where we can buy a reasonable amount of usable racquets, at least until we establish a more permanent group of RUBad members.\nWe'll give you guys some info about dues (amount, benefits, etc) and we'll likely start collecting them next week.\nLooking forwards to seeing you all there!\n\n''Posted 2008September13'' -- Announcement\nRUBad's second meeting is on 9/19/08.\nIMPORTANT: In order to avoid chaos, we're testing out ways of staggering arrival times in some kind of orderly fashion, so:\nFirst names A-M, please arrive at ~6:50pm.\nFirst names N-Z, please arrive at ~7:50pm.\n* NOTE: If you prefer to arrive with friends, go ahead and do so. The alphabetical staggering above is more of a guideline than any strict rule.\nWe understand that this is not necessarily the most efficient way to do things, but we also figure that by the meeting after this, we'll have a good idea of who's more likely to stay. Also by then we should have more club hours set.\nOur basic plan for the meeting to make the best use of everyone's time:\nCourt 1:\nServing practice.\nCourt 2 and between courts:\nPracticing the "clear".\nCourt 3:\nKing of the Court!\nWe'll explain this if and when we see you there ;)\nAnd for those waiting, the Wall Rally Drill to improve footwork, reflexes, and general strength of arm and wrist muscles used in badminton.\nIn terms of equipment that we can lend, we're still short on racquets - one of the things on our to-do list is to see where we can buy a reasonable amount of usable racquets, at least until we establish a more permanent group of RUBad members.\nWe'll give you guys some info about dues (amount, benefits, etc) and we'll likely start collecting them next week.\nLooking forwards to seeing you all there!\n\n\n''Posted 2008September13'' -- Announcement\nThe number of people who showed up for the first meeting took us a bit by surprise, actually. The next meeting, Friday 9/19, will be more organized.\nThanks to those of you who braved the rain and weather to make the meeting!\n\n\n''Posted 2008September08'' -- Announcement\n-welcome back. Please check out our new schedule [[Schedule]].\n-RU Badminton Club's first fall '08 meeting is on Friday, 9/12, at 7pm. We look forwards to seeing you there!\n-Please fill out Form G (http://itms.rutgers.edu:16080/ssps/) if you have not already done so for this semester.\nYou will NOT be allowed to play if you have not filled out this form - the people in charge are being very strict about this, so please try to fill it out beforehand - we'll try to have a laptop there for anyone who hasn't been able to fill it out.\n\n\n''Archive''\n[[200711200801]]\n[[200710]]\n[[200708/09]]\n[[200704/05]]\n[[200702/03]]\n[[200701]]\n[[200611/12]]\n[[200610]]\n\n
<<newReminder>>\n\n<<reminder year:2008 month:9 day:19 title:"''[[sonnyWerblin0919:1900-2100]]''" >>\n<<reminder year:2008 month:9 day:26 title:"''sonny werblin''(7pm-9pm)" >>\n<<reminder year:2008 month:10 day:3 title:"sonnyWerblin1003:1900-2100" >>\n<<reminder year:2008 month:10 day:10 title:"sonnyWerblin1010:1900-2100" >>
<<calendar thismonth>>
/***\n|''Name:''|CalendarPlugin|\n|''Source:''|http://www.TiddlyTools.com/#CalendarPlugin|\n|''Author:''|SteveRumsby|\n|''License:''|unknown|\n|''~CoreVersion:''|2.0.10|\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<<reminder year:2006 month:10 day:19 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:10 day:22 title:"''loree''(11am-3pm)" >>\n<<reminder year:2006 month:10 day:24 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:10 day:26 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:10 day:29 title:"''sonny werblin''(1pm-3pm)" >>\n<<reminder year:2006 month:10 day:31 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:11 day:2 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:11 day:5 title:"''loree''(11am-3pm)" >>\n<<reminder year:2006 month:11 day:7 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:11 day:9 title:"''no badminton" center closing at 3pm >>\n<<reminder year:2006 month:11 day:12 title:"''loree''(11am-3pm)" >>\n<<reminder year:2006 month:11 day:14 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:11 day:16 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:11 day:19 title:"''loree''(11am-3pm)" >>\n<<reminder year:2006 month:11 day:21 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:11 day:23 title:"''sonny werblin'' no badminton" >>\n<<reminder year:2006 month:11 day:26 title:"''loree'' no badminton" >>\n<<reminder year:2006 month:11 day:30 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:12 day:5 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:12 day:7 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2006 month:12 day:3 title:"''loree''(11am-1pm)" >>\n<<reminder year:2006 month:12 day:10 title:"''loree''(11am-3pm)" >>\n<<reminder year:2006 month:12 day:12 title:"''sonny werblin''(8pm-10pm)" >>\n<<reminder year:2006 month:12 day:14 title:"''sonny werblin''(????)" >>\n<<reminder year:2006 month:12 day:16 title:"''loree''no more badminton until further notice" >>\n<<reminder year:2006 month:12 day:19 title:"''sonny werblin''(7pm-9pm)" >>\n<<reminder year:2006 month:12 day:21 title:"''sonny werblin''(????)" >>\n<<reminder year:2007 month:1 day:21 title:"''loree''(1-5pm)" >>\n<<reminder year:2007 month:1 day:28 title:"''loree''(1pm-5pm)" >>\n<<reminder year:2007 month:2 day:4 title:"''loree''(1pm-5pm)" >>\n<<reminder year:2007 month:2 day:11 title:"''no loree''" >>\n<<reminder year:2007 month:2 day:18 title:"''loree'' (1-5pm)" >>\n<<reminder year:2007 month:2 day:10 title:"''Bryn Mawr Mainline ABC Doubles''" >>\n<<reminder year:2007 month:2 day:19 title:"''sonny werblin''(9pm-11pm)" >>\n<<reminder year:2007 month:2 day:25 title:"''no loree''" >>\n<<reminder year:2007 month:2 day:26 title:"''sonny werblin''(9pm-11pm)" >>\n<<reminder year:2007 month:3 day:4 title:"''no loree''" >>\n<<reminder year:2007 month:3 day:5 title:"''sonny werblin''(9pm-11pm)" >>\n<<reminder year:2007 month:3 day:11 title:"''no loree''" >>\n<<reminder year:2007 month:3 day:12 title:"''no club reserved time''" >>\n<<reminder year:2007 month:3 day:25 title:"''loree''(1pm-5pm)" >>\n<<reminder year:2007 month:3 day:26 title:"''sonny werblin''(9pm-11pm)" >>\n<<reminder year:2007 month:4 day:1 title:"''no loree''" >>\n<<reminder year:2007 month:4 day:8 title:"''no loree''" >>\n<<reminder year:2007 month:4 day:16 title:"''~RUBad tournament''" >>\n<<reminder year:2007 month:4 day:23 title:"''~RUBad tournament'' (7pm-11pm)" >>\n<<reminder year:2007 month:4 day:9 title:"''sonny werblin'' (9pm-11pm)" >>\n<<reminder year:2007 month:4 day:15 title:"''no loree''" >>\n<<reminder year:2007 month:4 day:22 title:"''loree''(1pm-5pm)" >>\n<<reminder year:2007 month:4 day:14 title:"''sonny werblin''(1pm-3pm)" >>\n<<reminder year:2007 month:4 day:30 title:"''~RUBad tournament'' (7pm-11pm)" >>\n<<reminder year:2007 month:9 day:10 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:9 day:17 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:9 day:24 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:10 day:1 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:9 day:15 title:"''NO loree''" >>\n<<reminder year:2007 month:9 day:22 title:"''loree''(1pm-5pm)" >>\n<<reminder year:2007 month:9 day:29 title:"''no cook/douglas''" >>\n<<reminder year:2007 month:10 day:13 title:"''friendly tournament w/ NJIT @ sonny werblin'' (1pm-5pm)" >>\n<<reminder year:2007 month:10 day:6 title:"''cook/douglas'' (1pm-5pm)" >>\n<<reminder year:2007 month:10 day:15 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:10 day:22 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:10 day:29 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:11 day:4 title:"''1 day Doubles Badminton Tourney'' at Rutgers" >>\n<<reminder year:2007 month:11 day:5 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:11 day:12 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:11 day:19 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2007 month:11 day:26 title:"''sonny werblin''(8pm-11pm)" >>\n<<reminder year:2008 month:9 day:12 title:"''sonny werblin''(7pm-9pm) " >>\n
@@20070423 & 30 - 2007 Rutgers Badminton Club Tournament, Busch campus, Rutgers@@\nClub doubles tournament.\nPhoto:\nhttp://picasaweb.google.com/rubadminton/070430RubadTourney\n\n\n@@20070224-25 2007 Cook/Douglas Badminton Intramural, Rutgers, NJ@@\nIntramural organized by Cook/Douglas Recreation Center. Offering Singles and Doubles events. The best 4 from the first round round robin played second round knocked-out. \nResult:\n1st place of Singles: ''Amit Priyadarshi''\n1st place of Doubles: ''Amit Priyadarshi'', ''Debajyoti Nandi''\nPhoto:\nTo be announced.\nVideo:\nTo be announced.\n\n\n@@20070210 Mainline ABC Doubles, Bryn Mawr, PA@@\nA round robin double tournament hosted by Bryn Mawr Badminton Team. Each match 2 games. Each game 21 rally points. The one with accumulated highest total rally points of all matches was the subgroup winner. Winners of subgroups played second round round robin. There were 8 of us from Rutgers Badminton Club participated. \nAchievement: \n3rd place of Men's Double Group B: ''Derek Lam'', Henrik Lam\n1st place of Men's Double Group C: ''Kwang Huei Low'', Mike Zu\n1st place of Women's Double Group C: ''Amrutha Donaiah'', Sharon\n[[Photo|http://picasaweb.google.com/rubadminton]]:\n[[Intermission|http://picasaweb.google.com/rubadminton/070210MainlineDoubleIntermission]]/[[Men's Double C|http://picasaweb.google.com/rubadminton/070210MainlineDoubleMenSDoubleC]]/[[Women's Double B/C|http://picasaweb.google.com/rubadminton/070210MainlineDoubleWomenSDoubleBC]]/[[Men's Double B|http://picasaweb.google.com/rubadminton/070210MainlineDoubleMenSDoubleB]]/[[Mixed Double B|http://picasaweb.google.com/rubadminton/070210MainlineDoubleMixedDoubleB]]\n[[Video|http://eden.rutgers.edu/~rubad/video/070210-mainlineDouble]]:\n[[Men's Double C|http://www.eden.rutgers.edu/~rubad/video/070210-mainlineDouble/mdC.html]]/[[Women's Double C|http://www.eden.rutgers.edu/~rubad/video/070210-mainlineDouble/wdC.html]]/[[Men's Double B|http://www.eden.rutgers.edu/~rubad/video/070210-mainlineDouble/mdB.html]]/[[Mixed Double B|http://www.eden.rutgers.edu/~rubad/video/070210-mainlineDouble/mxdB.html]]\n\n@@20070119-21 2007 National Capital Open, College Park, MD@@\nThe DC Open is an annual USAB sanctioned badminton tournament in the D.C. area. \nAchievement: \n1st place of Men's Single Collegiate group: ''Derek Lam''\n1st place of Men's Double Group C: ''Derek Lam'', Henrik Lam\nPhoto:\n[[Men's Double Group C|http://picasaweb.google.com/rubadminton/070119DcOpenMdC]]\n[[Men's Single Group CDU|http://picasaweb.google.com/rubadminton/070119DcOpenMsCDU]]\nVideo:\nTo be announced.\n\n
rubad@eden.rutgers.edu\n
/***\n|''Name:''|DatePlugin|\n|''Source:''|http://www.TiddlyTools.com/#DatePlugin|\n|''Author:''|Eric Shulman - ELS Design Studios|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|''~CoreVersion:''|2.0.10|\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
// // date plugin calendar colors\n//{{{\nconfig.macros.date.holidays=[ "01/01", "07/04", "07/24", "11/24" ]; // NewYearsDay, IndependenceDay(US), Eric's Birthday (hooray!), Thanksgiving(US)\nconfig.macros.date.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\nconfig.macros.date.format="YYYY.0MM.0DD"; // default date display format\nconfig.macros.date.linkformat="YYYY.0MM.0DD"; // 'dated tiddler' link format\nconfig.macros.date.weekendbg="#c0c0c0";\nconfig.macros.date.holidaybg="#ffaace";\nconfig.macros.date.modifiedsbg="#bbeeff";\nconfig.macros.date.linkedbg="#babb1e";\nconfig.macros.date.remindersbg="#c0ffee";\n//}}}\n
[[Main]]\n[[Announcement/New]]
~TiddlyWiki is a single HTML file. If you want to save a complete copy of this site, including all the the text, you can use this [[this link|index.html]]. Right click on this link and click "save target as" or "save link as".\n\nNote:\nThere can be confusing and subtle differences between different browsers. Some points to watch:@@\n* Do ''not'' use the File/Save command in your browser to save ~TiddlyWiki.\n* Make sure that you're saving in HTML (or "page source" format), not one of the new-fangled archive formats\n
<div class="toolbar" macro="toolbar +saveTiddler closeOthers cancelTiddler deleteTiddler"></div><!-- removed - from cancelTiddler -->\n<div class="title" macro="view title"></div>\n<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>\n<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>\n<!-- <div class="editLabel">Tags</div><div class="editor" macro="editCommaTags"></div> -->\n<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser"></span></div>\n<div class="editor" macro="edit text"></div>\n<br/>
<<exportTiddlers inline>>
/***\n''Export Tiddlers Plugin for TiddlyWiki version 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#ExportTiddlersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen many people edit copies of the same TiddlyWiki document, the ability to easily copy and share these changes so they can then be redistributed to the entire group is very important. This ability is also very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)\n\nExportTiddlersPlugin let you ''select and extract tiddlers from your ~TiddlyWiki documents and save them to a local file'' or a remote server (requires installation of compatible server-side scripting, still under development...). An interactive control panel lets you specify a destination, and then select which tiddlers to export. A convenient 'selection filter' helps you pick desired tiddlers by specifying a combination of modification dates, tags, or tiddler text to be matched or excluded. ''Tiddler data can be output as ~TiddlyWiki "storeArea ~DIVs" that can be imported into another ~TiddlyWiki or as ~RSS-compatible XML that can be published for RSS syndication.''\n\n!!!!!Inline interface (live)\n<<<\n<<exportTiddlers inline>>\n<<<\n!!!!!Usage\n<<<\nOptional "special tiddlers" used by this plugin:\n* SiteUrl^^\nURL for official server-published version of document being viewed (used in XML export)\ndefault: //none//^^\n* SiteHost^^\nhost name/address for remote server (e.g., "www.server.com" or "192.168.1.27")\ndefault: //none//^^\n* SitePost^^\nremote path/filename for submitting changes (e.g., "/cgi-bin/submit.cgi")\ndefault: //none//^^\n* SiteParams^^\narguments (if any) for server-side receiving script\ndefault: //none//^^\n* SiteNotify^^\naddresses (if any) for sending automatic server-side email notices\ndefault: //none//^^\n* SiteID^^\nusername or other authorization identifier for login-controlled access to remote server\ndefault: current TiddlyWiki username (e.g., "YourName")^^\n* SiteDate^^\nstored date/time stamp for most recent published version of document\ndefault: current document.modified value (i.e., the 'file date')^^\n<<<\n!!!!!Example\n<<<\n<<exportTiddlers>>\n<<<\n!!!!!Installation\n<<<\nImport (or copy/paste) the following tiddlers into your document:\n''ExportTiddlersPlugin'' (tagged with <<tag systemConfig>>)\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add {{{<<exportTiddlers>>}}} macro^^\n<<<\n!!!!!Revision History\n<<<\n''2006.05.11 [2.2.2]''\nin createExportPanel, removed call to addNotification() to no longer auto-refresh the list every time a tiddler is changed. Instead, call refreshExportList(0) only when the panel is first rendered and each time it is made visible. Prevents unneeded feedback messages from being displayed and increases overall document performance, since the listbox is no longer being updated each time a tiddler is saved.\n''2006.05.02 [2.2.1]''\nUse displayMessage() to show number of selected tiddlers instead of updating listbox 'header' item after each selection. Prevents awkward 'scroll-to-top' behavior that made multi-select via ctrl-click nearly impossible. Reported by Paul Reiber.\n''2006.04.29 [2.2.0]''\nNew features: "Notes" are free-form text that is inserted in the header of a TWDIV export file. When exporting to a server, the "notify" checkbox indicates that server-side script processing should send an email message when the export file is stored on the server. Comma-separated addresses may be typed in, or pre-defined in the SiteNotify tiddler.\n''2006.03.29 [2.1.3]''\nadded calls to convertUnicodeToUTF8() for generated output, so it better handles international characters.\n''2006.02.12 [2.1.2]''\nadded var to unintended global 'tags' in matchTags(). Avoids FF1501 bug when filtering by tags. (based on report by TedPavlic)\n''2006.02.04 [2.1.1]''\nadded var to variables that were unintentionally global. Avoids FireFox 1.5.0.1 crash bug when referencing global variables\n''2006.02.02 [2.1.0]''\nAdded support for output of complete TiddlyWiki documents. Let's you use ExportTiddlers to generate 'starter' documents from selected tiddlers.\n''2006.01.21 [2.0.1]''\nDefer initial panel creation and only register a notification function when panel first is created\nin saveChanges 'hijack', create panel as needed. Note: if window.event is not available to identify the click location, the export panel is positioned relative to the 'tiddlerDisplay' element of the TW document.\n''2005.12.27 [2.0.0]''\nUpdate for TW2.0\nDefer initial panel creation and only register a notification function when panel first is created\n''2005.12.24 [0.9.5]''\nMinor adjustments to CSS to force correct link colors regardless of TW stylesheet selection\n''2005.12.16 [0.9.4]''\nDynamically create/remove exportPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.\n''2005.11.15 [0.9.2]''\nadded non-Ajax post function to bypass javascript security restrictions on cross-domain I/O. Moved AJAX functions to separate tiddler (no longer needed here). Generalized HTTP server to support UnaWiki servers\n''2005.11.08 [0.9.1]''\nmoved HTML, CSS and control initialization into exportInit() function and call from macro handler instead of at load time. This allows exportPanel to be placed within the same containing element as the "export tiddlers" button, so that relative positioning can be achieved.\n''2005.10.28 [0.9.0]''\nadded 'select opened tiddlers' feature\nBased on a suggestion by Geoff Slocock\n''2005.10.24 [0.8.3]''\nCorrected hijack of 'save changes' when using http:\n''2005.10.18 [0.8.2]''\nadded AJAX functions\n''2005.10.18 [0.8.1]''\nCorrected timezone handling when filtering for date ranges.\nImproved error checking/reporting for invalid filter values and filters that don't match any tiddlers.\nExporting localfile-to-localfile is working for IE and FF\nExporting server-to-localfile works in IE (after ActiveX warnings), but has security issues in FF\nCross-domain exporting (localfile/server-to-server) is under development\nCookies to remember filter settings - coming soon\nMore style tweaks, minor text changes and some assorted layout cleanup.\n''2005.10.17 [0.8.0]''\nFirst pre-release.\n''2005.10.16 [0.7.0]''\nfilter by tags\n''2005.10.15 [0.6.0]''\nfilter by title/text\n''2005.10.14 [0.5.0]''\nexport to local file (DIV or XML)\n''2005.10.14 [0.4.0]''\nfilter by start/end date\n''2005.10.13 [0.3.0]''\npanel interaction\n''2005.10.11 [0.2.0]''\npanel layout\n''2005.10.10 [0.1.0]''\ncode framework\n''2005.10.09 [0.0.0]''\ndevelopment started\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n// // +++[version]\n//{{{\nversion.extensions.exportTiddlers = {major: 2, minor: 2, revision: 2, date: new Date(2006,5,2)};\n//}}}\n// //===\n\n// // +++[macro handler]\n//{{{\nconfig.macros.exportTiddlers = {\n label: "export tiddlers",\n prompt: "Copy selected tiddlers to an export document",\n datetimefmt: "0MM/0DD/YYYY 0hh:0mm:0ss" // for "filter date/time" edit fields\n};\n\nconfig.macros.exportTiddlers.handler = function(place,macroName,params) {\n if (params[0]!="inline")\n { createTiddlyButton(place,this.label,this.prompt,onClickExportMenu); return; }\n var panel=createExportPanel(place);\n panel.style.position="static";\n panel.style.display="block";\n}\n\nfunction createExportPanel(place) {\n var panel=document.getElementById("exportPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.exportTiddlers.css,"exportTiddlers");\n panel=createTiddlyElement(place,"span","exportPanel",null,null)\n panel.innerHTML=config.macros.exportTiddlers.html;\n exportShowPanel(document.location.protocol);\n exportInitFilter();\n refreshExportList(0);\n return panel;\n}\n\nfunction onClickExportMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("exportPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createExportPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n if (panel.style.display!="none") refreshExportList(0); // update list when panel is made visible\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n// //===\n\n// // +++[Hijack saveChanges] diverts 'notFileUrlError' to display export control panel instead\n//{{{\nwindow.coreSaveChanges=window.saveChanges;\nwindow.saveChanges = function()\n{\n if (document.location.protocol=="file:") { coreSaveChanges(); return; }\n var e = window.event;\n var parent=e?resolveTarget(e).parentNode:document.body;\n var panel = document.getElementById("exportPanel");\n if (panel==undefined || panel.parentNode!=parent) panel=createExportPanel(parent);\n exportShowPanel(document.location.protocol);\n if (parent==document.body) { panel.style.left="30%"; panel.style.top="30%"; }\n panel.style.display = "block" ;\n}\n//}}}\n// //===\n\n// // +++[IE needs explicit scoping] for functions called by browser events\n//{{{\nwindow.onClickExportMenu=onClickExportMenu;\nwindow.onClickExportButton=onClickExportButton;\nwindow.exportShowPanel=exportShowPanel;\nwindow.exportShowFilterFields=exportShowFilterFields;\nwindow.refreshExportList=refreshExportList;\n//}}}\n// //===\n\n// // +++[CSS] for floating export control panel\n//{{{\nconfig.macros.exportTiddlers.css = '\s\n#exportPanel {\s\n display: none; position:absolute; z-index:12; width:35em; right:105%; top:6em;\s\n background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n padding: 0.5em; margin:0em; -moz-border-radius:1em;\s\n}\s\n#exportPanel a, #exportPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\s\n#exportPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\s\n#exportPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\s\n#exportPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\s\n#exportPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\s\n#exportPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%; }\s\n#exportPanel textarea { width:98%;padding:0px;margin:0px;overflow:auto;font-size:8pt; }\s\n#exportPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px; }\s\n#exportPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\s\n#exportPanel .rad { width:auto;border:0 }\s\n#exportPanel .chk { width:auto;border:0 }\s\n#exportPanel .btn { width:auto; }\s\n#exportPanel .btn1 { width:98%; }\s\n#exportPanel .btn2 { width:48%; }\s\n#exportPanel .btn3 { width:32%; }\s\n#exportPanel .btn4 { width:24%; }\s\n#exportPanel .btn5 { width:19%; }\s\n';\n//}}}\n// //===\n\n// // +++[HTML] for export control panel interface\n//{{{\nconfig.macros.exportTiddlers.html = '\s\n<!-- output target and format -->\s\n<table cellpadding="0" cellspacing="0"><tr><td width=50%>\s\n export to\s\n <select size=1 id="exportTo" onchange="exportShowPanel(this.value);">\s\n <option value="file:" SELECTED>this computer</option>\s\n <option value="http:">web server (http)</option>\s\n <option value="https:">secure web server (https)</option>\s\n <option value="ftp:">file server (ftp)</option>\s\n </select>\s\n</td><td width=50%>\s\n output format\s\n <select id="exportFormat" size=1>\s\n <option value="DIV">TiddlyWiki export file</option>\s\n <option value="TW">TiddlyWiki document</option>\s\n <option value="XML">RSS feed (XML)</option>\s\n </select>\s\n</td></tr></table>\s\n\s\n<!-- export to local file -->\s\n<div id="exportLocalPanel" style="margin-top:5px;">\s\nlocal path/filename<br>\s\n<input type="file" id="exportFilename" size=57 style="width:100%"><br>\s\n</div><!--panel-->\s\n\s\n<!-- export to http server -->\s\n<div id="exportHTTPPanel" style="display:none;margin-top:5px;">\s\n<table><tr><td align=left>\s\n server location, script, and parameters<br>\s\n</td><td align=right>\s\n <input type="checkbox" class="chk" id="exportNotify"\s\n onClick="document.getElementById(\s'exportSetNotifyPanel\s').style.display=this.checked?\s'block\s':\s'none\s'"> notify\s\n</td></tr></table>\s\n<input type="text" id="exportHTTPServerURL" onfocus="this.select()"><br>\s\n<div id="exportSetNotifyPanel" style="display:none">\s\n send email notices to<br>\s\n <input type="text" id="exportNotifyTo" onfocus="this.select()"><br>\s\n</div>\s\n</div><!--panel-->\s\n\s\n<!-- export to ftp server -->\s\n<div id="exportFTPPanel" style="display:none;margin-top:5px;">\s\n<table cellpadding="0" cellspacing="0" width="32%"><tr valign="top"><td>\s\n host server<br>\s\n <input type="text" id="exportFTPHost" onfocus="this.select()"><br>\s\n</td><td width="32%">\s\n username<br>\s\n <input type="text" id="exportFTPID" onfocus="this.select()"><br>\s\n</td><td width="32%">\s\n password<br>\s\n <input type="password" id="exportFTPPW" onfocus="this.select()"><br>\s\n</td></tr></table>\s\nFTP path/filename<br>\s\n<input type="text" id="exportFTPFilename" onfocus="this.select()"><br>\s\n</div><!--panel-->\s\n\s\n<!-- notes -->\s\nnotes<br>\s\n<textarea id="exportNotes" rows=3 cols=40 style="height:4em;margin-bottom:5px;" onfocus="this.select()"></textarea> \s\n\s\n<!-- list of tiddlers -->\s\n<table><tr align="left"><td>\s\n select:\s\n <a href="JavaScript:;" id="exportSelectAll"\s\n onclick="onClickExportButton(this)" title="select all tiddlers">\s\n &nbsp;all&nbsp;</a>\s\n <a href="JavaScript:;" id="exportSelectChanges"\s\n onclick="onClickExportButton(this)" title="select tiddlers changed since last save">\s\n &nbsp;changes&nbsp;</a> \s\n <a href="JavaScript:;" id="exportSelectOpened"\s\n onclick="onClickExportButton(this)" title="select tiddlers currently being displayed">\s\n &nbsp;opened&nbsp;</a> \s\n <a href="JavaScript:;" id="exportToggleFilter"\s\n onclick="onClickExportButton(this)" title="show/hide selection filter">\s\n &nbsp;filter&nbsp;</a> \s\n</td><td align="right">\s\n <a href="JavaScript:;" id="exportListSmaller"\s\n onclick="onClickExportButton(this)" title="reduce list size">\s\n &nbsp;&#150;&nbsp;</a>\s\n <a href="JavaScript:;" id="exportListLarger"\s\n onclick="onClickExportButton(this)" title="increase list size">\s\n &nbsp;+&nbsp;</a>\s\n</td></tr></table>\s\n<select id="exportList" multiple size="10" style="margin-bottom:5px;"\s\n onchange="refreshExportList(this.selectedIndex)">\s\n</select><br>\s\n</div><!--box-->\s\n\s\n<!-- selection filter -->\s\n<div id="exportFilterPanel" style="display:none">\s\n<table><tr align="left"><td>\s\n selection filter\s\n</td><td align="right">\s\n <a href="JavaScript:;" id="exportHideFilter"\s\n onclick="onClickExportButton(this)" title="hide selection filter">hide</a>\s\n</td></tr></table>\s\n<div class="box">\s\n<input type="checkbox" class="chk" id="exportFilterStart" value="1"\s\n onclick="exportShowFilterFields(this)"> starting date/time<br>\s\n<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\s\n <select size=1 id="exportFilterStartBy" onchange="exportShowFilterFields(this);">\s\n <option value="0">today</option>\s\n <option value="1">yesterday</option>\s\n <option value="7">a week ago</option>\s\n <option value="30">a month ago</option>\s\n <option value="site">SiteDate</option>\s\n <option value="file">file date</option>\s\n <option value="other">other (mm/dd/yyyy hh:mm)</option>\s\n </select>\s\n</td><td width="50%">\s\n <input type="text" id="exportStartDate" onfocus="this.select()"\s\n onchange="document.getElementById(\s'exportFilterStartBy\s').value=\s'other\s';">\s\n</td></tr></table>\s\n<input type="checkbox" class="chk" id="exportFilterEnd" value="1"\s\n onclick="exportShowFilterFields(this)"> ending date/time<br>\s\n<table cellpadding="0" cellspacing="0"><tr valign="center"><td width="50%">\s\n <select size=1 id="exportFilterEndBy" onchange="exportShowFilterFields(this);">\s\n <option value="0">today</option>\s\n <option value="1">yesterday</option>\s\n <option value="7">a week ago</option>\s\n <option value="30">a month ago</option>\s\n <option value="site">SiteDate</option>\s\n <option value="file">file date</option>\s\n <option value="other">other (mm/dd/yyyy hh:mm)</option>\s\n </select>\s\n</td><td width="50%">\s\n <input type="text" id="exportEndDate" onfocus="this.select()"\s\n onchange="document.getElementById(\s'exportFilterEndBy\s').value=\s'other\s';">\s\n</td></tr></table>\s\n<input type="checkbox" class="chk" id=exportFilterTags value="1"\s\n onclick="exportShowFilterFields(this)"> match tags<br>\s\n<input type="text" id="exportTags" onfocus="this.select()">\s\n<input type="checkbox" class="chk" id=exportFilterText value="1"\s\n onclick="exportShowFilterFields(this)"> match titles/tiddler text<br>\s\n<input type="text" id="exportText" onfocus="this.select()">\s\n</div> <!--box-->\s\n</div> <!--panel-->\s\n\s\n<!-- action buttons -->\s\n<div style="text-align:center">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportFilter" value="apply filter">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportStart" value="export tiddlers">\s\n<input type=button class="btn3" onclick="onClickExportButton(this)"\s\n id="exportClose" value="close">\s\n</div><!--center-->\s\n';\n//}}}\n// //===\n\n// // +++[initialize interface]>\n// // +++[exportShowPanel(which)]\n//{{{\nfunction exportShowPanel(which) {\n var index=0; var panel='exportLocalPanel';\n switch (which) {\n case 'file:':\n case undefined:\n index=0; panel='exportLocalPanel'; break;\n case 'http:':\n index=1; panel='exportHTTPPanel'; break;\n case 'https:':\n index=2; panel='exportHTTPPanel'; break;\n case 'ftp:':\n index=3; panel='exportFTPPanel'; break;\n default:\n alert("Sorry, export to "+which+" is not yet available");\n break;\n }\n exportInitPanel(which);\n document.getElementById('exportTo').selectedIndex=index;\n document.getElementById('exportLocalPanel').style.display='none';\n document.getElementById('exportHTTPPanel').style.display='none';\n document.getElementById('exportFTPPanel').style.display='none';\n document.getElementById(panel).style.display='block';\n}\n//}}}\n// //===\n\n// // +++[exportInitPanel(which)]\n//{{{\nfunction exportInitPanel(which) {\n switch (which) {\n case "file:": // LOCAL EXPORT PANEL: file/path:\n // ** no init - security issues in IE **\n break;\n case "http:": // WEB EXPORT PANEL\n case "https:": // SECURE WEB EXPORT PANEL\n // url\n if (store.tiddlerExists("unawiki_download")) {\n var theURL=store.getTiddlerText("unawiki_download");\n theURL=theURL.replace(/\s[\s[download\s|/,'').replace(/\s]\s]/,'');\n var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";\n var theHost=store.getTiddlerText(title);\n if (!theHost || !theHost.length) theHost=document.location.host;\n if (!theHost || !theHost.length) theHost=title;\n }\n // server script/params\n var title=(store.tiddlerExists("unawiki_host"))?"unawiki_host":"SiteHost";\n var theHost=store.getTiddlerText(title);\n if (!theHost || !theHost.length) theHost=document.location.host;\n if (!theHost || !theHost.length) theHost=title;\n // get POST\n var title=(store.tiddlerExists("unawiki_post"))?"unawiki_post":"SitePost";\n var thePost=store.getTiddlerText(title);\n if (!thePost || !thePost.length) thePost="/"+title;\n // get PARAMS\n var title=(store.tiddlerExists("unawiki_params"))?"unawiki_params":"SiteParams";\n var theParams=store.getTiddlerText(title);\n if (!theParams|| !theParams.length) theParams=title;\n var serverURL = which+"//"+theHost+thePost+"?"+theParams;\n document.getElementById("exportHTTPServerURL").value=serverURL;\n // get NOTIFY\n var theAddresses=store.getTiddlerText("SiteNotify");\n if (!theAddresses|| !theAddresses.length) theAddresses="SiteNotify";\n document.getElementById("exportNotifyTo").value=theAddresses;\n break;\n case "ftp:": // FTP EXPORT PANEL\n // host\n var siteHost=store.getTiddlerText("SiteHost");\n if (!siteHost || !siteHost.length) siteHost=document.location.host;\n if (!siteHost || !siteHost.length) siteHost="SiteHost";\n document.getElementById("exportFTPHost").value=siteHost;\n // username\n var siteID=store.getTiddlerText("SiteID");\n if (!siteID || !siteID.length) siteID=config.options.txtUserName;\n document.getElementById("exportFTPID").value=siteID;\n // password\n document.getElementById("exportFTPPW").value="";\n // file/path\n document.getElementById("exportFTPFilename").value="";\n break;\n }\n}\n//}}}\n// //===\n\n// // +++[exportInitFilter()]\n//{{{\nfunction exportInitFilter() {\n // start date\n document.getElementById("exportFilterStart").checked=false;\n document.getElementById("exportStartDate").value="";\n // end date\n document.getElementById("exportFilterEnd").checked=false;\n document.getElementById("exportEndDate").value="";\n // tags\n document.getElementById("exportFilterTags").checked=false;\n document.getElementById("exportTags").value="";\n // text\n document.getElementById("exportFilterText").checked=false;\n document.getElementById("exportText").value="";\n // show/hide filter input fields\n exportShowFilterFields();\n}\n//}}}\n// //===\n\n// // +++[exportShowFilterFields(which)]\n//{{{\nfunction exportShowFilterFields(which) {\n var show;\n\n show=document.getElementById('exportFilterStart').checked;\n document.getElementById('exportFilterStartBy').style.display=show?"block":"none";\n document.getElementById('exportStartDate').style.display=show?"block":"none";\n var val=document.getElementById('exportFilterStartBy').value;\n document.getElementById('exportStartDate').value\n =getFilterDate(val,'exportStartDate').formatString(config.macros.exportTiddlers.datetimefmt);\n if (which && (which.id=='exportFilterStartBy') && (val=='other'))\n document.getElementById('exportStartDate').focus();\n\n show=document.getElementById('exportFilterEnd').checked;\n document.getElementById('exportFilterEndBy').style.display=show?"block":"none";\n document.getElementById('exportEndDate').style.display=show?"block":"none";\n var val=document.getElementById('exportFilterEndBy').value;\n document.getElementById('exportEndDate').value\n =getFilterDate(val,'exportEndDate').formatString(config.macros.exportTiddlers.datetimefmt);\n if (which && (which.id=='exportFilterEndBy') && (val=='other'))\n document.getElementById('exportEndDate').focus();\n\n show=document.getElementById('exportFilterTags').checked;\n document.getElementById('exportTags').style.display=show?"block":"none";\n\n show=document.getElementById('exportFilterText').checked;\n document.getElementById('exportText').style.display=show?"block":"none";\n}\n//}}}\n// //===\n// //===\n\n// // +++[onClickExportButton(which): control interactions]\n//{{{\nfunction onClickExportButton(which)\n{\n // DEBUG alert(which.id);\n var theList=document.getElementById('exportList'); if (!theList) return;\n var count = 0;\n var total = store.getTiddlers('title').length;\n switch (which.id)\n {\n case 'exportFilter':\n count=filterExportList();\n var panel=document.getElementById('exportFilterPanel');\n if (count==-1) { panel.style.display='block'; break; }\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage("filtered "+formatExportMessage(count,total));\n if (count==0) { alert("No tiddlers were selected"); panel.style.display='block'; }\n break;\n case 'exportStart':\n exportTiddlers();\n break;\n case 'exportHideFilter':\n case 'exportToggleFilter':\n var panel=document.getElementById('exportFilterPanel')\n panel.style.display=(panel.style.display=='block')?'none':'block';\n break;\n case 'exportSelectChanges':\n var lastmod=new Date(document.lastModified);\n for (var t = 0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n var tiddler=store.getTiddler(theList.options[t].value); if (!tiddler) continue;\n theList.options[t].selected=(tiddler.modified>lastmod);\n count += (tiddler.modified>lastmod)?1:0;\n }\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(formatExportMessage(count,total));\n if (count==0) alert("There are no unsaved changes");\n break;\n case 'exportSelectAll':\n for (var t = 0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=true;\n count += 1;\n }\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(formatExportMessage(count,count));\n break;\n case 'exportSelectOpened':\n for (var t = 0; t < theList.options.length; t++) theList.options[t].selected=false;\n var tiddlerDisplay = document.getElementById("tiddlerDisplay");\n for (var t=0;t<tiddlerDisplay.childNodes.length;t++) {\n var tiddler=tiddlerDisplay.childNodes[t].id.substr(7);\n for (var i = 0; i < theList.options.length; i++) {\n if (theList.options[i].value!=tiddler) continue;\n theList.options[i].selected=true; count++; break;\n }\n }\n document.getElementById("exportStart").disabled=(count==0);\n clearMessage(); displayMessage(formatExportMessage(count,total));\n if (count==0) alert("There are no tiddlers currently opened");\n break;\n case 'exportListSmaller': // decrease current listbox size\n var min=5;\n theList.size-=(theList.size>min)?1:0;\n break;\n case 'exportListLarger': // increase current listbox size\n var max=(theList.options.length>25)?theList.options.length:25;\n theList.size+=(theList.size<max)?1:0;\n break;\n case 'exportClose':\n document.getElementById('exportPanel').style.display='none';\n break;\n }\n}\n//}}}\n// //===\n\n// // +++[list display]\n//{{{\nfunction formatExportMessage(count,total)\n{\n var txt=total+' tiddler'+((total!=1)?'s':'')+" - ";\n txt += (count==0)?"none":(count==total)?"all":count;\n txt += " selected for export";\n return txt;\n}\n\nfunction refreshExportList(selectedIndex)\n{\n var theList = document.getElementById("exportList");\n var sort;\n if (!theList) return;\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) sort='modified';\n if (selectedIndex==1) sort='title';\n if (selectedIndex==2) sort='modified';\n if (selectedIndex==3) sort='modifier';\n\n // get the alphasorted list of tiddlers\n var tiddlers = store.getTiddlers('title');\n // unselect headings and count number of tiddlers actually selected\n var count=0;\n for (var i=0; i<theList.options.length; i++) {\n if (theList.options[i].value=="") theList.options[i].selected=false;\n count+=theList.options[i].selected?1:0;\n }\n // disable "export" button if no tiddlers selected\n document.getElementById("exportStart").disabled=(count==0);\n // update listbox heading to show selection count\n if (theList.options.length) { clearMessage(); displayMessage(formatExportMessage(count,tiddlers.length)); }\n\n // if a [command] item, reload list... otherwise, no further refresh needed\n if (selectedIndex>3) return;\n\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=\n new Option(tiddlers.length+" tiddlers in document", "",false,false);\n theList.options[i++]=\n new Option(((sort=="title" )?">":indent)+' [by title]', "",false,false);\n theList.options[i++]=\n new Option(((sort=="modified")?">":indent)+' [by date]', "",false,false);\n theList.options[i++]=\n new Option(((sort=="modifier")?">":indent)+' [by author]', "",false,false);\n // output the tiddler list\n switch(sort)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modifier":\n case "modified":\n var tiddlers = store.getTiddlers(sort);\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a[sort] == b[sort]) return(0); else return (a[sort] > b[sort]) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++)\n {\n var tiddler = tiddlers[t];\n var theSection = "";\n if (sort=="modified") theSection=tiddler.modified.toLocaleDateString();\n if (sort=="modifier") theSection=tiddler.modifier;\n if (theSection != lastSection)\n {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n}\n//}}}\n// //===\n\n// // +++[list filtering]\n//{{{\nfunction getFilterDate(val,id)\n{\n var result=0;\n switch (val) {\n case 'site':\n var timestamp=store.getTiddlerText("SiteDate");\n if (!timestamp) timestamp=document.lastModified;\n result=new Date(timestamp);\n break;\n case 'file':\n result=new Date(document.lastModified);\n break;\n case 'other':\n result=new Date(document.getElementById(id).value);\n break;\n default: // today=0, yesterday=1, one week=7, two weeks=14, a month=31\n var now=new Date(); var tz=now.getTimezoneOffset()*60000; now-=tz;\n var oneday=86400000;\n if (id=='exportStartDate')\n result=new Date((Math.floor(now/oneday)-val)*oneday+tz);\n else\n result=new Date((Math.floor(now/oneday)-val+1)*oneday+tz-1);\n break;\n }\n // DEBUG alert('getFilterDate('+val+','+id+')=='+result+"\snnow="+now);\n return result;\n}\n\nfunction filterExportList()\n{\n var theList = document.getElementById("exportList"); if (!theList) return -1;\n\n var filterStart=document.getElementById("exportFilterStart").checked;\n var val=document.getElementById("exportFilterStartBy").value;\n var startDate=getFilterDate(val,'exportStartDate');\n\n var filterEnd=document.getElementById("exportFilterEnd").checked;\n var val=document.getElementById("exportFilterEndBy").value;\n var endDate=getFilterDate(val,'exportEndDate');\n\n var filterTags=document.getElementById("exportFilterTags").checked;\n var tags=document.getElementById("exportTags").value;\n\n var filterText=document.getElementById("exportFilterText").checked;\n var text=document.getElementById("exportText").value;\n\n if (!(filterStart||filterEnd||filterTags||filterText)) {\n alert("Please set the selection filter");\n document.getElementById('exportFilterPanel').style.display="block";\n return -1;\n }\n if (filterStart&&filterEnd&&(startDate>endDate)) {\n var msg="starting date/time:\sn"\n msg+=startDate.toLocaleString()+"\sn";\n msg+="is later than ending date/time:\sn"\n msg+=endDate.toLocaleString()\n alert(msg);\n return -1;\n }\n\n // scan list and select tiddlers that match all applicable criteria\n var total=0;\n var count=0;\n for (var i=0; i<theList.options.length; i++) {\n // get item, skip non-tiddler list items (section headings)\n var opt=theList.options[i]; if (opt.value=="") continue;\n // get tiddler, skip missing tiddlers (this should NOT happen)\n var tiddler=store.getTiddler(opt.value); if (!tiddler) continue; \n var sel=true;\n if ( (filterStart && tiddler.modified<startDate)\n || (filterEnd && tiddler.modified>endDate)\n || (filterTags && !matchTags(tiddler,tags))\n || (filterText && (tiddler.text.indexOf(text)==-1) && (tiddler.title.indexOf(text)==-1)))\n sel=false;\n opt.selected=sel;\n count+=sel?1:0;\n total++;\n }\n return count;\n}\n//}}}\n\n//{{{\nfunction matchTags(tiddler,cond)\n{\n if (!cond||!cond.trim().length) return false;\n\n // build a regex of all tags as a big-old regex that \n // OR's the tags together (tag1|tag2|tag3...) in length order\n var tgs = store.getTags();\n if ( tgs.length == 0 ) return results ;\n var tags = tgs.sort( function(a,b){return (a[0].length<b[0].length)-(a[0].length>b[0].length);});\n var exp = "(" + tags.join("|") + ")" ;\n exp = exp.replace( /(,[\sd]+)/g, "" ) ;\n var regex = new RegExp( exp, "ig" );\n\n // build a string such that an expression that looks like this: tag1 AND tag2 OR NOT tag3\n // turns into : /tag1/.test(...) && /tag2/.test(...) || ! /tag2/.test(...)\n cond = cond.replace( regex, "/$1\s\s|/.test(tiddlerTags)" );\n cond = cond.replace( /\ssand\ss/ig, " && " ) ;\n cond = cond.replace( /\ssor\ss/ig, " || " ) ;\n cond = cond.replace( /\ss?not\ss/ig, " ! " ) ;\n\n // if a boolean uses a tag that doesn't exist - it will get left alone \n // (we only turn existing tags into actual tests).\n // replace anything that wasn't found as a tag, AND, OR, or NOT with the string "false"\n // if the tag doesn't exist then /tag/.test(...) will always return false.\n cond = cond.replace( /(\ss|^)+[^\s/\s|&!][^\ss]*/g, "false" ) ;\n\n // make a string of the tags in the tiddler and eval the 'cond' string against that string \n // if it's TRUE then the tiddler qualifies!\n var tiddlerTags = (tiddler.tags?tiddler.tags.join("|"):"")+"|" ;\n try { if ( eval( cond ) ) return true; }\n catch( e ) { displayMessage("Error in tag filter '" + e + "'" ); }\n return false;\n}\n//}}}\n// //===\n\n// // +++[output data formatting]>\n// // +++[exportHeader(format)]\n//{{{\nfunction exportHeader(format)\n{\n switch (format) {\n case "TW": return exportTWHeader();\n case "DIV": return exportDIVHeader();\n case "XML": return exportXMLHeader();\n }\n}\n//}}}\n// //===\n\n// // +++[exportFooter(format)]\n//{{{\nfunction exportFooter(format)\n{\n switch (format) {\n case "TW": return exportDIVFooter();\n case "DIV": return exportDIVFooter();\n case "XML": return exportXMLFooter();\n }\n}\n//}}}\n// //===\n\n// // +++[exportTWHeader()]\n//{{{\nfunction exportTWHeader()\n{\n // Get the URL of the document\n var originalPath = document.location.toString();\n // Check we were loaded from a file URL\n if(originalPath.substr(0,5) != "file:")\n { alert(config.messages.notFileUrlError); return; }\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#"); if(hashPos != -1) 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 // Load the original file\n var original = loadFile(localPath);\n if(original == null)\n { alert(config.messages.cantSaveError); return; }\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 { alert(config.messages.invalidFileError.format([localPath])); return; }\n return original.substr(0,posOpeningDiv+startSaveArea.length)\n}\n//}}}\n// //===\n\n// // +++[exportDIVHeader()]\n//{{{\nfunction exportDIVHeader()\n{\n var out=[];\n var now = new Date();\n var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());\n var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());\n var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());\n var twver = version.major+"."+version.minor+"."+version.revision;\n var pver = version.extensions.exportTiddlers.major+"."\n +version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;\n out.push("<html><body>");\n out.push("<style type=\s"text/css\s">");\n out.push("#storeArea {display:block;margin:1em;}");\n out.push("#storeArea div");\n out.push("{padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}");\n out.push("#javascriptWarning");\n out.push("{width:100%;text-align:left;background-color:#eeeeee;padding:1em;}");\n out.push("</style>");\n out.push("<div id=\s"javascriptWarning\s">");\n out.push("TiddlyWiki export file<br>");\n out.push("Source: <b>"+convertUnicodeToUTF8(document.location.toString())+"</b><br>");\n out.push("Title: <b>"+title+"</b><br>");\n out.push("Subtitle: <b>"+subtitle+"</b><br>");\n out.push("Created: <b>"+now.toLocaleString()+"</b> by <b>"+user+"</b><br>");\n out.push("TiddlyWiki "+twver+" / "+"ExportTiddlersPlugin "+pver+"<br>");\n out.push("Notes:<hr><pre>"+document.getElementById("exportNotes").value.replace(regexpNewLine,"<br>")+"</pre>");\n out.push("</div>");\n out.push("<div id=\s"storeArea\s">");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportDIVFooter()]\n//{{{\nfunction exportDIVFooter()\n{\n var out=[];\n out.push("</div></body></html>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportXMLHeader()]\n//{{{\nfunction exportXMLHeader()\n{\n var out=[];\n var now = new Date();\n var u = store.getTiddlerText("SiteUrl",null);\n var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());\n var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());\n var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());\n var twver = version.major+"."+version.minor+"."+version.revision;\n var pver = version.extensions.exportTiddlers.major+"."\n +version.extensions.exportTiddlers.minor+"."+version.extensions.exportTiddlers.revision;\n out.push("<" + "?xml version=\s"1.0\s"?" + ">");\n out.push("<rss version=\s"2.0\s">");\n out.push("<channel>");\n out.push("<title>" + title + "</title>");\n if(u) out.push("<link>" + convertUnicodeToUTF8(u.htmlEncode()) + "</link>");\n out.push("<description>" + subtitle + "</description>");\n out.push("<language>en-us</language>");\n out.push("<copyright>Copyright " + now.getFullYear() + " " + user + "</copyright>");\n out.push("<pubDate>" + now.toGMTString() + "</pubDate>");\n out.push("<lastBuildDate>" + now.toGMTString() + "</lastBuildDate>");\n out.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");\n out.push("<generator>TiddlyWiki "+twver+" plus ExportTiddlersPlugin "+pver+"</generator>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportXMLFooter()]\n//{{{\nfunction exportXMLFooter()\n{\n var out=[];\n out.push("</channel></rss>");\n return out;\n}\n//}}}\n// //===\n\n// // +++[exportData()]\n//{{{\nfunction exportData(theList,theFormat)\n{\n // scan export listbox and collect DIVs or XML for selected tiddler content\n var out=[];\n for (var i=0; i<theList.options.length; i++) {\n // get item, skip non-selected items and section headings\n var opt=theList.options[i]; if (!opt.selected||(opt.value=="")) continue;\n // get tiddler, skip missing tiddlers (this should NOT happen)\n var thisTiddler=store.getTiddler(opt.value); if (!thisTiddler) continue; \n if (theFormat=="TW") out.push(convertUnicodeToUTF8(thisTiddler.saveToDiv()));\n if (theFormat=="DIV") out.push(convertUnicodeToUTF8(thisTiddler.title+"\sn"+thisTiddler.saveToDiv()));\n if (theFormat=="XML") out.push(convertUnicodeToUTF8(thisTiddler.saveToRss()));\n }\n return out;\n}\n//}}}\n// //===\n// //===\n\n// // +++[exportTiddlers(): output selected data to local or server]\n//{{{\nfunction exportTiddlers()\n{\n var theList = document.getElementById("exportList"); if (!theList) return;\n\n // get the export settings\n var theProtocol = document.getElementById("exportTo").value;\n var theFormat = document.getElementById("exportFormat").value;\n\n // assemble output: header + tiddlers + footer\n var theData=exportData(theList,theFormat);\n var count=theData.length;\n var out=[]; var txt=out.concat(exportHeader(theFormat),theData,exportFooter(theFormat)).join("\sn");\n var msg="";\n switch (theProtocol) {\n case "file:":\n var theTarget = document.getElementById("exportFilename").value.trim();\n if (!theTarget.length) msg = "A local path/filename is required\sn";\n if (!msg && saveFile(theTarget,txt))\n msg=count+" tiddler"+((count!=1)?"s":"")+" exported to local file";\n else if (!msg)\n msg+="An error occurred while saving to "+theTarget;\n break;\n case "http:":\n case "https:":\n var theTarget = document.getElementById("exportHTTPServerURL").value.trim();\n if (!theTarget.length) msg = "A server URL is required\sn";\n if (document.getElementById('exportNotify').checked)\n theTarget+="&notify="+encodeURIComponent(document.getElementById('exportNotifyTo').value);\n if (document.getElementById('exportNotes').value.trim().length)\n theTarget+="&notes="+encodeURIComponent(document.getElementById('exportNotes').value);\n if (!msg && exportPost(theTarget+encodeURIComponent(txt)))\n msg=count+" tiddler"+((count!=1)?"s":"")+" exported to "+theProtocol+" server";\n else if (!msg)\n msg+="An error occurred while saving to "+theTarget;\n break;\n case "ftp:":\n default:\n msg="Sorry, export to "+theLocation+" is not yet available";\n break;\n }\n clearMessage(); displayMessage(msg,theTarget);\n}\n//}}}\n// //===\n\n// // +++[exportPost(url): cross-domain post] uses hidden iframe to submit url and capture responses\n//{{{\nfunction exportPost(url)\n{\n var f=document.getElementById("exportFrame"); if (f) document.body.removeChild(f);\n f=document.createElement("iframe"); f.id="exportFrame";\n f.style.width="0px"; f.style.height="0px"; f.style.border="0px";\n document.body.appendChild(f);\n var d=f.document;\n if (f.contentDocument) d=f.contentDocument; // For NS6\n else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6\n d.location.replace(url);\n return true;\n}\n//}}}\n// //===\n
First come first serve.\n5min warmup and 1x21points.\nShall let the next group play after completed a game.\nShall play doubles when there are people waiting.\n\n\n''21 Rally Points Scoring System''\nThe side that first scored 21 points shall win, unless…\nAt 20 all, the side which gains a 2 point lead first, wins that game.\nAt 29 all, the side scoring the 30th point, wins that game.\n\nThe side winning a rally adds a point to its score (regardless of who is serving) and earns the next servicing right.\n\nOrder of server:\nEven score or beginning of the game – right service court\nOdd score – left service court\n\nDoubles\nThere is only one serve for each team. The side that wins the servicing right serves according to the “order of server”.\nThe players do not change their respective service courts until they win a point when their side is serving.\n\nReferences:\nhttp://www.badminton-information.com/badminton_21_points.html\nhttp://www.internationalbadminton.org/newrallypointsystem.asp
<<importTiddlers inline>>
/***\n''Import Tiddlers Plugin for TiddlyWiki version 1.2.x, 2.0 and 2.1beta''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#ImportTiddlersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen many people share and edit copies of the same TiddlyWiki document, the ability to quickly collect all these changes back into a single, updated document that can then be redistributed to the entire group is very important. This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents. It can also be very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)\n\n!!!!!Interactive interface\n<<<\n{{{<<importTiddlers>>}}}\ncreates "import tiddlers" link. click to show/hide import control panel\n\n{{{<<importTiddlers inline>>}}}\ncreates import control panel directly in tiddler content\n\n<<importTiddlers inline>>\n\nPress ''[browse]'' to select a TiddlyWiki document file to import. You can also type in the path/filename or a remote document URL (starting with http://)and press ''[open]''. //Note: There may be some delay to permit the browser time to access and load the document before updating the listbox with the titles of all tiddlers that are available to be imported.//\n\nSelect one or more titles from the listbox (hold CTRL or SHIFT while clicking to add/remove the highlight from individual list items). You can press ''[select all]'' to quickly highlight all tiddler titles in the list. Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time. When you have chosen the tiddlers you want to import and entered any extra tags, press ''[import]'' to begin copying them to the current TiddlyWiki document.\n\n''select: all, new, changes, or differences''\n\nYou can click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list. This makes it very quick and easy to find and import just the updated tiddlers you are interested in:\n>''"all"'' selects ALL tiddlers from the import source document, even if they have not been changed.\n>''"new"'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' selects only tiddlers that exist in both documents but that are newer in the source document\n>''"differences"'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)\n\n''Import Tagging:''\n\nTiddlers that have been imported can be automatically tagged, so they will be easier to find later on, after they have been added to your document. New tags are entered into the "add tags" input field, and then //added// to the existing tags for each tiddler as it is imported.\n\n''Skip, Rename, Merge, or Replace:''\n\nWhen importing a tiddler whose title is identical to one that already exists, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''[skip]'', ''[rename]'', ''[merge]'' and ''[replace]''.\n\nTo bypass importing this tiddler, press ''[skip]''. To import the tiddler with a different name (so that both the tiddlers will exist when the import is done), enter a new title in the input field and then press ''[rename]''. Press ''[merge]'' to combine the content from both tiddlers into a single tiddler. Press ''[replace]'' to overwrite the existing tiddler with the imported one, discarding the previous tiddler content.\n\n//Note: if both the title ''and'' modification date/////time match, the imported tiddler is assumed to be identical to the existing one, and will be automatically skipped (i.e., not imported) without asking.//\n\n''Import Report History''\n\nWhen tiddlers are imported, a report is generated into ImportedTiddlers, indicating when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom. It also includes a list with the title, date and author of each tiddler that was imported.\n\nWhen the import process is completed, the ImportedTiddlers report is automatically displayed for your review. If more tiddlers are subsequently imported, a new report is //added// to ImportedTiddlers, above the previous report (i.e., at the top of the tiddler), so that a reverse-chronological history of imports is maintained.\n\nIf a cumulative record is not desired, the ImportedTiddlers report may be deleted at any time. A new ImportedTiddlers report will be created the next time tiddlers are imported.\n\nNote: You can prevent the ImportedTiddlers report from being generated for any given import activity by clearing the "create a report" checkbox before beginning the import processing.\n\n<<<\n!!!!!non-interactive 'load tiddlers' macro\n<<<\nUseful for automated installation/update of plugins and other tiddler content.\n\n{{{<<loadTiddlers "label:load tiddlers from %0" http://www.tiddlytools.com/example.html confirm>>}}}\n<<loadTiddlers "label:load tiddlers from %0" http://www.tiddlytools.com/example.html confirm>>\n\nSyntax:\n{{{<<loadTiddlers label:text prompt:text filter source quiet confirm>>}}}\n\n''label:text'' and ''prompt:text''\n>defines link text and tooltip (prompt) that can be clicked to trigger the load tiddler processing. If a label is NOT provided, then no link is created and loadTiddlers() is executed whenever the containing tiddler is rendered.\n''filter'' (optional) determines which tiddlers will be automatically selected for importing. Use one of the following keywords:\n>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.\n>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler\n>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)\n>''"tiddler:~TiddlerName"'' retrieves only the specific tiddler named in the parameter.\n>''"tag:text"'' retrieves only the tiddlers tagged with the indicated text.\n''source'' (required) is the location of the imported document. It can be either a local document path/filename in whatever format your system requires, or a remote web location (starting with "http://" or "https://")\n>use the keyword ''ask'' to prompt for a source location whenever the macro is invoked\n''"quiet"'' (optional)\n>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc). Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified. This ensures that changes to your document cannot occur without any visible indication at all.\n''"confirm"'' (optional)\n>adds interactive confirmation. A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.\n<<<\n!!!!!Installation\n<<<\ncopy/paste the following tiddlers into your document:\n''ImportTiddlersPlugin'' (tagged with <<tag systemConfig>>)\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add "< < ImportTiddlers > >" macro^^\n\n''Quick Installation Tip #1:''\nIf you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.\n<<<\n!!!!!Revision History\n<<<\n''2006.07.29 [3.0.5]'' added noChangeMsg to loadTiddlers processing. if not 'quiet' mode, reports skipped tiddlers.\n''2006.04.18 [3.0.4]'' in loadTiddlers.handler, fixed parsing of "prompt:" param. Also, corrected parameters mismatch in loadTiddlers() callback function definition (order of params was wrong, resulting in filters NOT being applied)\n''2006.04.12 [3.0.3]'' moved many display messages to macro properties for easier L10N translations via 'lingo' definitions.\n''2006.04.12 [3.0.2]'' additional refactoring of 'core candidate' code. Proposed API now defines "loadRemoteFile()" for XMLHttpRequest processing with built in fallback for handling local filesystem access, and readTiddlersFromHTML() to process the resulting source HTML content.\n''2006.04.04 [3.0.1]'' in refreshImportList(), when using [by tags], tiddlers without tags are now included in a new "untagged" psuedo-tag list section\n''2006.04.04 [3.0.0]'' Separate non-interactive {{{<<importTiddlers...>>}}} macro functionality for incorporation into TW2.1 core and renamed as {{{<<loadTiddlers>>}}} macro. New parameters for loadTiddlers: ''label:text'' and ''prompt:text'' for link creation, ''ask'' for filename/URL, ''tag:text'' for filtering, "confirm" for accept/reject of individual inbound tiddlers. Also, ImportedTiddlers report generator output has been simplified and "importReplace/importPublic" tags and associated "force" param (which were rarely, if ever, used) has been dropped.\n''2006.03.30 [2.9.1]'' when extracting store area from remote URL, look for "</body>" instead of "</body>\sn</html>" so it will match even if the "\sn" is absent from the source.\n''2006.03.30 [2.9.0]'' added optional 'force' macro param. When present, autoImportTiddlers() bypasses the checks for importPublic and importReplace. Based on a request from Tom Otvos.\n''2006.03.28 [2.8.1]'' in loadImportFile(), added checks to see if 'netscape' and 'x.overrideMimeType()' are defined (IE does *not* define these values, so we bypass this code)\nAlso, when extracting store area from remote URL, explicitly look for "</body>\sn</html>" to exclude any extra content that may have been added to the end of the file by hosting environments such as GeoCities. Thanks to Tom Otvos for finding these bugs and suggesting some fixes.\n''2006.02.21 [2.8.0]'' added support for "tiddler:TiddlerName" filtering parameter in auto-import processing\n''2006.02.21 [2.7.1]'' Clean up layout problems with IE. (Use tables for alignment instead of SPANs styled with float:left and float:right)\n''2006.02.21 [2.7.0]'' Added "local file" and "web server" radio buttons for selecting dynamic import source controls in ImportPanel. Default file control is replaced with URL text input field when "web server" is selected. Default remote document URL is defined in SiteURL tiddler. Also, added option for prepending SiteProxy URL as prefix to remote URL to mask cross-domain document access (requires compatible server-side script)\n''2006.02.17 [2.6.0]'' Removed "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences. Also fixed initialization handling for "add new tags" so that checkbox state is correctly tracked when panel is first displayed.\n''2006.02.16 [2.5.4]'' added checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.\n''2006.02.14 [2.5.3]'' FF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()\n''2006.02.10 [2.5.2]'' corrected unintended global variable in importReport().\n''2006.02.05 [2.5.1]'' moved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals\n''2006.01.18 [2.5.0]'' added checkbox for "create a report". Default is to create/update the ImportedTiddlers report. Clear the checkbox to skip this step.\n''2006.01.15 [2.4.1]'' added "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic\n''2006.01.15 [2.4.0]'' Added support for tagging individual tiddlers with importSkip, importReplace, and/or importPrivate to control which tiddlers can be overwritten or shared with others when using auto-import macro syntax. Defaults are to SKIP overwriting existing tiddlers with imported tiddlers, and ALLOW your tiddlers to be auto-imported by others.\n''2006.01.15 [2.3.2]'' Added "ask" parameter to confirm each tiddler before importing (for use with auto-importing)\n''2006.01.15 [2.3.1]'' Strip TW core scripts from import source content and load just the storeArea into the hidden IFRAME. Makes loading more efficient by reducing the document size and by preventing the import document from executing its TW initialization (including plugins). Seems to resolve the "Found 0 tiddlers" problem. Also, when importing local documents, use convertUTF8ToUnicode() to convert the file contents so support international characters sets.\n''2006.01.12 [2.3.0]'' Reorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest. Let's processing continue while waiting for remote hosts to respond to URL requests. Added non-interactive 'batch' macro mode, using parameters to specify which tiddlers to import, and from what document source. Improved error messages and diagnostics, plus an optional 'quiet' switch for batch mode to eliminate //most// feedback.\n''2006.01.11 [2.2.0]'' Added "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck\n''2006.01.09 [2.1.1]'' When a URL is typed in, and then the "open" button is pressed, it generates both an onChange event for the file input and a click event for open button. This results in multiple XMLHttpRequest()'s which seem to jam things up quite a bit. I removed the onChange handling for file input field. To open a file (local or URL), you must now explicitly press the "open" button in the control panel.\n''2006.01.08 [2.1.0]'' IMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements. Adapted from example code and techniques courtesy of Jonny LeRoy.\n''2006.01.06 [2.0.2]'' When refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.\n''2006.01.04 [2.0.1]'' When "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.\n''2005.12.27 [2.0.0]'' Update for TW2.0\nDefer initial panel creation and only register a notification function when panel first is created\n''2005.12.22 [1.3.1]'' tweak formatting in importReport() and add 'discard report' link to output\n''2005.12.03 [1.3.0]'' Dynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding. Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)\n''2005.11.29 [1.2.1]'' fixed formatting of 'detail info' in importReport()\n''2005.11.11 [1.2.0]'' added 'inline' param to embed controls in a tiddler\n''2005.11.09 [1.1.0]'' only load HTML and CSS the first time the macro handler is called. Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.\n''2005.10.25 [1.0.5]'' fixed typo in importReport() that prevented reports from being generated\n''2005.10.09 [1.0.4]'' combined documentation with plugin code instead of using separate tiddlers\n''2005.08.05 [1.0.3]'' moved CSS and HTML definitions into plugin code instead of using separate tiddlers\n''2005.07.27 [1.0.2]'' core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.23 [1.0.1]'' added parameter checks and corrected addNotification() usage\n''2005.07.20 [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// // ''MACRO DEFINITION''\n//{{{\n// Version\nversion.extensions.importTiddlers = {major: 3, minor: 0, revision: 5, date: new Date(2006,7,29)};\n\n// IE needs explicit global scoping for functions/vars called from browser events\nwindow.onClickImportButton=onClickImportButton;\nwindow.refreshImportList=refreshImportList;\n\n// default cookie/option values\nif (!config.options.chkImportReport) config.options.chkImportReport=true;\n\nconfig.macros.importTiddlers = { };\nconfig.macros.importTiddlers = {\n label: "import tiddlers",\n prompt: "Copy tiddlers from another document",\n foundMsg: "Found %0 tiddlers in %1",\n countMsg: "%0 tiddlers selected for import",\n importedMsg: "Imported %0 of %1 tiddlers from %2",\n src: "", // path/filename or URL of document to import (retrieved from SiteUrl tiddler)\n proxy: "", // URL for remote proxy script (retrieved from SiteProxy tiddler)\n useProxy: false, // use specific proxy script in front of remote URL\n inbound: null, // hash-indexed array of tiddlers from other document\n newTags: "", // text of tags added to imported tiddlers\n addTags: true, // add new tags to imported tiddlers\n listsize: 8, // # of lines to show in imported tiddler list\n importTags: true, // include tags from remote source document when importing a tiddler\n keepTags: true, // retain existing tags when replacing a tiddler\n index: 0, // current processing index in import list\n sort: "" // sort order for imported tiddler listbox\n};\n\nconfig.macros.importTiddlers.handler = function(place,macroName,params) {\n if (!config.macros.loadTiddlers.handler)\n { alert("importTiddlers error: this plugin requires LoadTiddlersPlugin or TiddlyWiki 2.1+"); return; }\n if (!params[0]) // LINK TO FLOATING PANEL\n createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);\n else if (params[0]=="inline") {// // INLINE TIDDLER CONTENT\n createImportPanel(place);\n document.getElementById("importPanel").style.position="static";\n document.getElementById("importPanel").style.display="block";\n }\n else config.macros.loadTiddlers.handler(place,macroName,params); // FALLBACK: PASS TO LOADTIDDLERS\n}\n//}}}\n\n// // ''INTERFACE DEFINITION''\n\n// // Handle link click to create/show/hide control panel\n//{{{\nfunction onClickImportMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("importPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createImportPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n// // Create control panel: HTML, CSS, register for notification\n//{{{\nfunction createImportPanel(place) {\n var panel=document.getElementById("importPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.importTiddlers.css,"importTiddlers");\n panel=createTiddlyElement(place,"span","importPanel",null,null)\n panel.innerHTML=config.macros.importTiddlers.html;\n store.addNotification(null,refreshImportList); // refresh listbox after every tiddler change\n refreshImportList();\n var siteURL=store.getTiddlerText("SiteUrl"); if (!siteURL) siteURL="";\n document.getElementById("importSourceURL").value=siteURL;\n config.macros.importTiddlers.src=siteURL;\n var siteProxy=store.getTiddlerText("SiteProxy"); if (!siteProxy) siteProxy="SiteProxy";\n document.getElementById("importSiteProxy").value=siteProxy;\n config.macros.importTiddlers.proxy=siteProxy;\n return panel;\n}\n//}}}\n\n// // CSS\n//{{{\nconfig.macros.importTiddlers.css = '\s\n#importPanel {\s\n display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\s\n background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\s\n padding: 0.5em; margin:0em; -moz-border-radius:1em;\s\n}\s\n#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\s\n#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\s\n#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\s\n#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\s\n#importPanel select { width:98%;margin:0px;font-size:8pt;line-height:110%;}\s\n#importPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\s\n#importPanel .box { border:1px solid black; padding:3px; margin-bottom:5px; background:#f8f8f8; -moz-border-radius:5px;}\s\n#importPanel .topline { border-top:2px solid black; padding-top:3px; margin-bottom:5px; }\s\n#importPanel .rad { width:auto; }\s\n#importPanel .chk { width:auto; margin:1px;border:0; }\s\n#importPanel .btn { width:auto; }\s\n#importPanel .btn1 { width:98%; }\s\n#importPanel .btn2 { width:48%; }\s\n#importPanel .btn3 { width:32%; }\s\n#importPanel .btn4 { width:24%; }\s\n#importPanel .btn5 { width:19%; }\s\n#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\s\n#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\s\n#importCollisionPanel { display:none; margin:0.5em 0em 0em 0em; }\s\n';\n//}}}\n\n// // HTML \n//{{{\nconfig.macros.importTiddlers.html = '\s\n<!-- source and report -->\s\n<table><tr><td align=left>\s\n import from\s\n <input type="radio" class="rad" name="importFrom" value="file" CHECKED\s\n onClick="document.getElementById(\s'importLocalPanel\s').style.display=this.checked?\s'block\s':\s'none\s';\s\n document.getElementById(\s'importHTTPPanel\s').style.display=!this.checked?\s'block\s':\s'none\s'"> local file\s\n <input type="radio" class="rad" name="importFrom" value="http"\s\n onClick="document.getElementById(\s'importLocalPanel\s').style.display=!this.checked?\s'block\s':\s'none\s';\s\n document.getElementById(\s'importHTTPPanel\s').style.display=this.checked?\s'block\s':\s'none\s'"> web server\s\n</td><td align=right>\s\n <input type=checkbox class="chk" id="chkImportReport" checked\s\n onClick="config.options[\s'chkImportReport\s']=this.checked;"> create a report\s\n</td></tr></table>\s\n<!-- import from local file -->\s\n<div id="importLocalPanel" style="display:block;margin-bottom:5px;margin-top:5px;padding-top:3px;border-top:1px solid #999">\s\nlocal document path/filename:<br>\s\n<input type="file" id="fileImportSource" size=57 style="width:100%"\s\n onKeyUp="config.macros.importTiddlers.src=this.value"\s\n onChange="config.macros.importTiddlers.src=this.value;">\s\n</div><!--panel-->\s\n\s\n<!-- import from http server -->\s\n<div id="importHTTPPanel" style="display:none;margin-bottom:5px;margin-top:5px;padding-top:3px;border-top:1px solid #999">\s\n<table><tr><td align=left>\s\n remote document URL:<br>\s\n</td><td align=right>\s\n <input type="checkbox" class="chk" id="importUseProxy"\s\n onClick="config.macros.importTiddlers.useProxy=this.checked;\s\n document.getElementById(\s'importSiteProxy\s').style.display=this.checked?\s'block\s':\s'none\s'"> use a proxy script\s\n</td></tr></table>\s\n<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"\s\n onKeyUp="config.macros.importTiddlers.proxy=this.value"\s\n onChange="config.macros.importTiddlers.proxy=this.value;">\s\n<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"\s\n onKeyUp="config.macros.importTiddlers.src=this.value"\s\n onChange="config.macros.importTiddlers.src=this.value;">\s\n</div><!--panel-->\s\n\s\n<table><tr><td align=left>\s\n select:\s\n <a href="JavaScript:;" id="importSelectAll"\s\n onclick="onClickImportButton(this)" title="select all tiddlers">\s\n &nbsp;all&nbsp;</a>\s\n <a href="JavaScript:;" id="importSelectNew"\s\n onclick="onClickImportButton(this)" title="select tiddlers not already in destination document">\s\n &nbsp;added&nbsp;</a> \s\n <a href="JavaScript:;" id="importSelectChanges"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been updated in source document">\s\n &nbsp;changes&nbsp;</a> \s\n <a href="JavaScript:;" id="importSelectDifferences"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been added or are different from existing tiddlers">\s\n &nbsp;differences&nbsp;</a> \s\n <a href="JavaScript:;" id="importToggleFilter"\s\n onclick="onClickImportButton(this)" title="show/hide selection filter">\s\n &nbsp;filter&nbsp;</a> \s\n</td><td align=right>\s\n <a href="JavaScript:;" id="importListSmaller"\s\n onclick="onClickImportButton(this)" title="reduce list size">\s\n &nbsp;&#150;&nbsp;</a>\s\n <a href="JavaScript:;" id="importListLarger"\s\n onclick="onClickImportButton(this)" title="increase list size">\s\n &nbsp;+&nbsp;</a>\s\n <a href="JavaScript:;" id="importListMaximize"\s\n onclick="onClickImportButton(this)" title="maximize/restore list size">\s\n &nbsp;=&nbsp;</a>\s\n</td></tr></table>\s\n<select id="importList" size=8 multiple\s\n onchange="setTimeout(\s'refreshImportList(\s'+this.selectedIndex+\s')\s',1)">\s\n <!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\s\n</select>\s\n<input type=checkbox class="chk" id="chkAddTags" checked\s\n onClick="config.macros.importTiddlers.addTags=this.checked;">add new tags &nbsp;\s\n<input type=checkbox class="chk" id="chkImportTags" checked\s\n onClick="config.macros.importTiddlers.importTags=this.checked;">import source tags &nbsp;\s\n<input type=checkbox class="chk" id="chkKeepTags" checked\s\n onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing tags<br>\s\n<input type=text id="txtNewTags" size=15 onKeyUp="config.macros.importTiddlers.newTags=this.value" autocomplete=off>\s\n<div align=center>\s\n <input type=button id="importOpen" class="importButton" style="width:32%" value="open"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importStart" class="importButton" style="width:32%" value="import"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importClose" class="importButton" style="width:32%" value="close"\s\n onclick="onClickImportButton(this)">\s\n</div>\s\n<div id="importCollisionPanel">\s\n tiddler already exists:\s\n <input type=text id="importNewTitle" size=15 autocomplete=off">\s\n <div align=center>\s\n <input type=button id="importSkip" class="importButton" style="width:23%" value="skip"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importRename" class="importButton" style="width:23%" value="rename"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importMerge" class="importButton" style="width:23%" value="merge"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importReplace" class="importButton" style="width:23%" value="replace"\s\n onclick="onClickImportButton(this)">\s\n </div>\s\n</div>\s\n';\n//}}}\n\n// // Control interactions\n//{{{\nfunction onClickImportButton(which)\n{\n // DEBUG alert(which.id);\n var theList = document.getElementById('importList');\n if (!theList) return;\n var thePanel = document.getElementById('importPanel');\n var theCollisionPanel = document.getElementById('importCollisionPanel');\n var theNewTitle = document.getElementById('importNewTitle');\n var count=0;\n switch (which.id)\n {\n case 'fileImportSource':\n case 'importOpen': // load import source into hidden frame\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n if (config.macros.importTiddlers.src=="") break;\n // Load document into hidden iframe so we can read it's DOM and fill the list\n loadRemoteFile(config.macros.importTiddlers.src, function(src,txt) {\n var tiddlers = readTiddlersFromHTML(txt);\n var count=tiddlers?tiddlers.length:0;\n displayMessage(config.macros.importTiddlers.foundMsg.format([count,src]));\n config.macros.importTiddlers.inbound=tiddlers;\n window.refreshImportList(0);\n });\n break;\n case 'importSelectAll': // select all tiddler list items (i.e., not headings)\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=true;\n count++;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectNew': // select tiddlers not in current document\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=!store.tiddlerExists(theList.options[t].value);\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectChanges': // select tiddlers that are updated from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value==""||!store.tiddlerExists(theList.options[t].value)) continue;\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified>0); // updated tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectDifferences': // select tiddlers that are new or different from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n if (!store.tiddlerExists(theList.options[t].value)) { theList.options[t].selected=true; count++; continue; }\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified!=0); // changed tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importToggleFilter': // show/hide filter\n case 'importFilter': // apply filter\n alert("coming soon!");\n break;\n case 'importStart': // initiate the import processing\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.index=0;\n config.macros.importTiddlers.index=importTiddlers(0);\n importStopped();\n break;\n case 'importClose': // unload imported tiddlers or hide the import control panel\n // if imported tiddlers not loaded, close the import control panel\n if (!config.macros.importTiddlers.inbound) { thePanel.style.display='none'; break; }\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n break;\n case 'importSkip': // don't import the tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status='skipped after asking'; // mark item as skipped\n theCollisionPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index+1); // resume with NEXT item\n importStopped();\n break;\n case 'importRename': // change name of imported tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status = 'renamed from '+theImported.title; // mark item as renamed\n theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title\n theItem.value = theNewTitle.value; // change the listbox item text\n theItem.text = theNewTitle.value; // change the listbox item text\n theCollisionPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importMerge': // join existing and imported tiddler content\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n var theText = theExisting.text+'\sn----\sn^^merged from: ';\n theText +='[['+config.macros.importTiddlers.src+'#'+theItem.value+'|'+config.macros.importTiddlers.src+'#'+theItem.value+']]^^\sn';\n theText +='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\sn'+theImported.text;\n var theDate = new Date();\n var theTags = theExisting.getTags()+' '+theImported.getTags();\n theImported.set(null,theText,null,theDate,theTags);\n theImported.status = 'merged with '+theExisting.title; // mark item as merged\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");\n theImported.status += ' by '+theExisting.modifier;\n theCollisionPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with this item\n importStopped();\n break;\n case 'importReplace': // substitute imported tiddler for existing tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n theImported.status = 'replaces '+theExisting.title; // mark item for replace\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");\n theImported.status += ' by '+theExisting.modifier;\n theCollisionPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importListSmaller': // decrease current listbox size, minimum=5\n if (theList.options.length==1) break;\n theList.size-=(theList.size>5)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListLarger': // increase current listbox size, maximum=number of items in list\n if (theList.options.length==1) break;\n theList.size+=(theList.size<theList.options.length)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListMaximize': // toggle listbox size between current and maximum\n if (theList.options.length==1) break;\n theList.size=(theList.size==theList.options.length)?config.macros.importTiddlers.listsize:theList.options.length;\n break;\n }\n}\n//}}}\n\n// // refresh listbox\n//{{{\nfunction refreshImportList(selectedIndex)\n{\n var theList = document.getElementById("importList");\n if (!theList) return;\n // if nothing to show, reset list content and size\n if (!config.macros.importTiddlers.inbound) \n {\n while (theList.length > 0) { theList.options[0] = null; }\n theList.options[0]=new Option('please open a document...',"",false,false);\n theList.size=config.macros.importTiddlers.listsize;\n return;\n }\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) config.macros.importTiddlers.sort='title'; // heading\n if (selectedIndex==1) config.macros.importTiddlers.sort='title';\n if (selectedIndex==2) config.macros.importTiddlers.sort='modified';\n if (selectedIndex==3) config.macros.importTiddlers.sort='tags';\n if (selectedIndex>3) {\n // display selected tiddler count\n for (var t=0,count=0; t < theList.options.length; t++) count+=(theList.options[t].selected&&theList.options[t].value!="")?1:0;\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n return; // no refresh needed\n }\n\n // get the alphasorted list of tiddlers (optionally, filter out unchanged tiddlers)\n var tiddlers=config.macros.importTiddlers.inbound;\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=new Option(tiddlers.length+' tiddler'+((tiddlers.length!=1)?'s are':' is')+' in the document',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="title" )?">":indent)+' [by title]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="modified")?">":indent)+' [by date]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="tags")?">":indent)+' [by tags]',"",false,false);\n // output the tiddler list\n switch(config.macros.importTiddlers.sort)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modified":\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++) {\n var tiddler = tiddlers[t];\n var theSection = tiddler.modified.toLocaleDateString();\n if (theSection != lastSection) {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n case "tags":\n var theTitles = {}; // all tiddler titles, hash indexed by tag value\n var theTags = new Array();\n for(var t=0; t<tiddlers.length; t++) {\n var title=tiddlers[t].title;\n var tags=tiddlers[t].tags;\n if (!tags || !tags.length) {\n if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }\n theTitles["untagged"].push(title);\n }\n else for(var s=0; s<tags.length; s++) {\n if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }\n theTitles[tags[s]].push(title);\n }\n }\n theTags.sort();\n for(var tagindex=0; tagindex<theTags.length; tagindex++) {\n var theTag=theTags[tagindex];\n theList.options[i++]=new Option(theTag,"",false,false);\n for(var t=0; t<theTitles[theTag].length; t++)\n theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n if (theList.size<config.macros.importTiddlers.listsize) theList.size=config.macros.importTiddlers.listsize;\n if (theList.size>theList.options.length) theList.size=theList.options.length;\n}\n//}}}\n\n// // re-entrant processing for handling import with interactive collision prompting\n//{{{\nfunction importTiddlers(startIndex)\n{\n if (!config.macros.importTiddlers.inbound) return -1;\n\n var theList = document.getElementById('importList');\n if (!theList) return;\n var t;\n // if starting new import, reset import status flags\n if (startIndex==0)\n for (var t=0;t<config.macros.importTiddlers.inbound.length;t++)\n config.macros.importTiddlers.inbound[t].status="";\n for (var i=startIndex; i<theList.options.length; i++)\n {\n // if list item is not selected or is a heading (i.e., has no value), skip it\n if ((!theList.options[i].selected) || ((t=theList.options[i].value)==""))\n continue;\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==t) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theImported.title);\n // avoid redundant import for tiddlers that are listed multiple times (when 'by tags')\n if (theImported.status=="added")\n continue;\n // don't import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n continue;\n // if tiddler exists and import not marked for replace or merge, stop importing\n if (theExisting && (theImported.status.substr(0,7)!="replace") && (theImported.status.substr(0,5)!="merge"))\n return i;\n // assemble tags (remote + existing + added)\n var newTags = "";\n if (config.macros.importTiddlers.importTags)\n newTags+=theImported.getTags() // import remote tags\n if (config.macros.importTiddlers.keepTags && theExisting)\n newTags+=" "+theExisting.getTags(); // keep existing tags\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newTags+=" "+config.macros.importTiddlers.newTags; // add new tags\n theImported.set(null,null,null,null,newTags.trim());\n // set the status to 'added' (if not already set by the 'ask the user' UI)\n theImported.status=(theImported.status=="")?'added':theImported.status;\n // do the import!\n store.addTiddler(theImported);\n store.setDirty(true);\n }\n return(-1); // signals that we really finished the entire list\n}\n//}}}\n\n//{{{\nfunction importStopped()\n{\n var theList = document.getElementById('importList');\n var theNewTitle = document.getElementById('importNewTitle');\n if (!theList) return;\n if (config.macros.importTiddlers.index==-1)\n importReport(); // import finished... generate the report\n else\n {\n // DEBUG alert('import stopped at: '+config.macros.importTiddlers.index);\n // import collision... show the collision panel and set the title edit field\n document.getElementById('importCollisionPanel').style.display='block';\n theNewTitle.value=theList.options[config.macros.importTiddlers.index].value;\n }\n}\n//}}}\n\n// // ''REPORT GENERATOR''\n//{{{\nfunction importReport(quiet)\n{\n if (!config.macros.importTiddlers.inbound) return;\n // DEBUG alert('importReport: start');\n\n // if import was not completed, the collision panel will still be open... close it now.\n var panel=document.getElementById('importCollisionPanel'); if (panel) panel.style.display='none';\n\n // get the alphasorted list of tiddlers\n var tiddlers = config.macros.importTiddlers.inbound;\n // gather the statistics\n var count=0;\n for (var t=0; t<tiddlers.length; t++)\n if (tiddlers[t].status && tiddlers[t].status.trim().length && tiddlers[t].status.substr(0,7)!="skipped") count++;\n\n // generate a report\n if (count && config.options.chkImportReport) {\n // get/create the report tiddler\n var theReport = store.getTiddler('ImportedTiddlers');\n if (!theReport) { theReport= new Tiddler(); theReport.title = 'ImportedTiddlers'; theReport.text = ""; }\n // format the report content\n var now = new Date();\n var newText = "On "+now.toLocaleString()+", "+config.options.txtUserName\n newText +=" imported "+count+" tiddler"+(count==1?"":"s")+" from\sn[["+config.macros.importTiddlers.src+"|"+config.macros.importTiddlers.src+"]]:\sn";\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newText += "imported tiddlers were tagged with: \s""+config.macros.importTiddlers.newTags+"\s"\sn";\n newText += "<<<\sn";\n for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status) newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\sn";\n newText += "<<<\sn";\n newText += "<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n newText += "onclick=\s"story.closeTiddler('"+theReport.title+"'); store.deleteTiddler('"+theReport.title+"');\s" ";\n newText += "value=\s"discard report\s"></html>";\n // update the ImportedTiddlers content and show the tiddler\n theReport.text = newText+((theReport.text!="")?'\sn----\sn':"")+theReport.text;\n theReport.modifier = config.options.txtUserName;\n theReport.modified = new Date();\n store.addTiddler(theReport);\n if (!quiet) { story.displayTiddler(null,theReport.title,1,null,null,false); story.refreshTiddler(theReport.title,1,true); }\n }\n\n // reset status flags\n for (var t=0; t<config.macros.importTiddlers.inbound.length; t++) config.macros.importTiddlers.inbound[t].status="";\n\n // refresh display if tiddlers have been loaded\n if (count) { store.setDirty(true); store.notifyAll(); }\n\n // always show final message when tiddlers were actually loaded\n if (count) displayMessage(config.macros.importTiddlers.importedMsg.format([count,tiddlers.length,config.macros.importTiddlers.src]));\n}\n//}}}\n\n/***\n!!!!!TW 2.1beta Core Code Candidate\n//The following section is a preliminary 'code candidate' for incorporation of non-interactive 'load tiddlers' functionality into TW2.1beta. //\n***/\n//{{{\n// default cookie/option values\nif (!config.options.chkImportReport) config.options.chkImportReport=true;\n\nconfig.macros.loadTiddlers = {\n label: "",\n prompt: "add/update tiddlers from '%0'",\n askMsg: "Please enter a local path/filename or a remote URL",\n openMsg: "Opening %0",\n openErrMsg: "Could not open %0 - error=%1",\n readMsg: "Read %0 bytes from %1",\n foundMsg: "Found %0 tiddlers in %1",\n nochangeMsg: "'%0' is up-to-date... skipped.",\n loadedMsg: "Loaded %0 of %1 tiddlers from %2"\n};\n\nconfig.macros.loadTiddlers.handler = function(place,macroName,params) {\n var label=(params[0] && params[0].substr(0,6)=='label:')?params.shift().substr(6):this.label;\n var prompt=(params[0] && params[0].substr(0,7)=='prompt:')?params.shift().substr(7):this.prompt;\n var filter="updates";\n if (params[0] && (params[0]=='all' || params[0]=='new' || params[0]=='changes' || params[0]=='updates'\n || params[0].substr(0,8)=='tiddler:' || params[0].substr(0,4)=='tag:'))\n filter=params.shift();\n var src=params.shift(); if (!src || !src.length) return; // filename is required\n var quiet=(params[0]=="quiet"); if (quiet) params.shift();\n var ask=(params[0]=="confirm"); if (ask) params.shift();\n if (label.trim().length) {\n // link triggers load tiddlers from another file/URL and then applies filtering rules to add/replace tiddlers in the store\n createTiddlyButton(place,label.format([src]),prompt.format([src]), function() {\n if (src=="ask") src=prompt(config.macros.loadTiddlers.askMsg);\n loadRemoteFile(src,loadTiddlers,quiet,ask,filter);\n })\n }\n else {\n // load tiddlers from another file/URL and then apply filtering rules to add/replace tiddlers in the store\n if (src=="ask") src=prompt(config.macros.loadTiddlers.askMsg);\n loadRemoteFile(src,loadTiddlers,quiet,ask,filter);\n }\n}\n\nfunction loadTiddlers(src,html,quiet,ask,filter)\n{\n var tiddlers = readTiddlersFromHTML(html);\n var count=tiddlers?tiddlers.length:0;\n if (!quiet) displayMessage(config.macros.loadTiddlers.foundMsg.format([count,src]));\n var count=0;\n if (tiddlers) for (var t=0;t<tiddlers.length;t++) {\n var theInbound = tiddlers[t];\n var theExisting = store.getTiddler(theInbound.title);\n if (theInbound.title=='ImportedTiddlers')\n continue; // skip "ImportedTiddlers" history from the other document...\n\n // apply the all/new/changes/updates filter (if any)\n if (filter && filter!="all") {\n if ((filter=="new") && theExisting) // skip existing tiddlers\n continue;\n if ((filter=="changes") && !theExisting) // skip new tiddlers\n continue;\n if ((filter.substr(0,4)=="tag:") && theInbound.tags.find(filter.substr(4))==null) // must match specific tag value\n continue;\n if ((filter.substr(0,8)=="tiddler:") && theInbound.title!=filter.substr(8)) // must match specific tiddler name\n continue;\n if (store.tiddlerExists(theInbound.title) && ((theExisting.modified.getTime()-theInbound.modified.getTime())>=0))\n { if (!quiet) displayMessage(config.macros.loadTiddlers.nochangeMsg.format([theInbound.title])); continue; }\n }\n // get confirmation if required\n if (ask && !confirm((theExisting?"Update":"Add")+" tiddler '"+theInbound.title+"'\snfrom "+src))\n { tiddlers[t].status="skipped - cancelled by user"; continue; }\n // DO IT!\n store.addTiddler(theInbound);\n tiddlers[t].status=theExisting?"updated":"added"\n count++;\n }\n if (count) {\n // refresh display\n store.setDirty(true);\n store.notifyAll();\n // generate a report\n if (config.options.chkImportReport) {\n // get/create the report tiddler\n var theReport = store.getTiddler('ImportedTiddlers');\n if (!theReport) { theReport= new Tiddler(); theReport.title = 'ImportedTiddlers'; theReport.text = ""; }\n // format the report content\n var now = new Date();\n var newText = "On "+now.toLocaleString()+", "+config.options.txtUserName+" loaded "+count+" tiddlers from\sn[["+src+"|"+src+"]]:\sn";\n newText += "<<<\sn";\n for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status) newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\sn";\n newText += "<<<\sn";\n newText += "<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n newText += "onclick=\s"story.closeTiddler('"+theReport.title+"'); store.deleteTiddler('"+theReport.title+"');\s" ";\n newText += "value=\s"discard report\s"></html>";\n // update the ImportedTiddlers content and show the tiddler\n theReport.text = newText+((theReport.text!="")?'\sn----\sn':"")+theReport.text;\n theReport.modifier = config.options.txtUserName;\n theReport.modified = new Date();\n store.addTiddler(theReport);\n if (!quiet) { story.displayTiddler(null,theReport.title,1,null,null,false); story.refreshTiddler(theReport.title,1,true); }\n }\n }\n // always show final message when tiddlers were actually loaded\n if (!quiet||count) displayMessage(config.macros.loadTiddlers.loadedMsg.format([count,tiddlers.length,src]));\n}\n\nfunction loadRemoteFile(src,callback,quiet,ask,filter) {\n if (src==undefined || !src.length) return null; // filename is required\n if (!quiet) clearMessage();\n if (!quiet) displayMessage(config.macros.loadTiddlers.openMsg.format([src]));\n if (src.substr(0,4)!="http" && src.substr(0,4)!="file") { // if not a URL, fallback to read from local filesystem\n var txt=loadFile(src);\n if ((txt==null)||(txt==false)) // file didn't load\n { if (!quiet) displayMessage(config.macros.loadTiddlers.openErrMsg.format([src,"(unknown)"])); }\n else {\n if (!quiet) displayMessage(config.macros.loadTiddlers.readMsg.format([txt.length,src]));\n if (callback) callback(src,convertUTF8ToUnicode(txt),quiet,ask,filter);\n }\n }\n else {\n var x; // get an request object\n try {x = new XMLHttpRequest()} // moz\n catch(e) {\n try {x = new ActiveXObject("Msxml2.XMLHTTP")} // IE 6\n catch (e) {\n try {x = new ActiveXObject("Microsoft.XMLHTTP")} // IE 5\n catch (e) { return }\n }\n }\n // setup callback function to handle server response(s)\n x.onreadystatechange = function() {\n if (x.readyState == 4) {\n if (x.status==0 || x.status == 200) {\n if (!quiet) displayMessage(config.macros.loadTiddlers.readMsg.format([x.responseText.length,src]));\n if (callback) callback(src,x.responseText,quiet,ask,filter);\n }\n else {\n if (!quiet) displayMessage(config.macros.loadTiddlers.openErrMsg.format([src,x.status]));\n }\n }\n }\n // get privileges to read another document's DOM via http:// or file:// (moz-only)\n if (typeof(netscape)!="undefined") {\n try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); }\n catch (e) { if (!quiet) displayMessage(e.description?e.description:e.toString()); }\n }\n // send the HTTP request\n try {\n var url=src+(src.indexOf('?')<0?'?':'&')+'nocache='+Math.random();\n x.open("GET",src,true);\n if (x.overrideMimeType) x.overrideMimeType('text/html');\n x.send(null);\n }\n catch (e) {\n if (!quiet) {\n displayMessage(config.macros.loadTiddlers.openErrMsg.format([src,"(unknown)"]));\n displayMessage(e.description?e.description:e.toString());\n }\n }\n }\n}\n\nfunction readTiddlersFromHTML(html)\n{\n // extract store area from html \n var start=html.indexOf('<div id="storeArea">');\n var end=html.indexOf('</body>',start);\n var sa="<html><body>"+html.substring(start,end)+"</body></html>";\n\n // load html into iframe document\n var f=document.getElementById("loaderFrame"); if (f) document.body.removeChild(f);\n f=document.createElement("iframe"); f.id="loaderFrame";\n f.style.width="0px"; f.style.height="0px"; f.style.border="0px";\n document.body.appendChild(f);\n var d=f.document;\n if (f.contentDocument) d=f.contentDocument; // For NS6\n else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6\n d.open(); d.writeln(sa); d.close();\n\n // read tiddler DIVs from storeArea DOM element \n var sa = d.getElementById("storeArea");\n if (!sa) return null;\n sa.normalize();\n var nodes = sa.childNodes;\n if (!nodes || !nodes.length) return null;\n var tiddlers = [];\n for(var t = 0; t < nodes.length; t++) {\n var title = null;\n if(nodes[t].getAttribute)\n title = nodes[t].getAttribute("tiddler");\n if(!title && nodes[t].id && (nodes[t].id.substr(0,5) == "store"))\n title = nodes[t].id.substr(5);\n if(title && title != "")\n tiddlers.push((new Tiddler()).loadFromDiv(nodes[t],title));\n }\n return tiddlers;\n}\n//}}}
On Thursday, October 19, 2006 3:43:17 AM, RUBad imported 1 tiddler from\n[[http://www.tiddlywiki.com/|http://www.tiddlywiki.com/]]:\n<<<\n#[[CalendarPlugin]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>\n----\nOn 30 September 2006 2:16:17, RUBad imported 1 tiddler from\n[[C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html|C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html]]:\n<<<\n#[[ReminderSyntax]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>\n----\nOn 30 September 2006 2:15:20, RUBad imported 1 tiddler from\n[[C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html|C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html]]:\n<<<\n#[[ReminderMacros]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>\n----\nOn 29 September 2006 16:56:20, RUBad imported 3 tiddlers from\n[[C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html|C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html]]:\n<<<\n#[[NewHereCommand]] - added\n#[[QuickOpenTagPlugin]] - added\n#[[RenameTagsPlugin]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>\n----\nOn 29 September 2006 16:54:12, RUBad imported 4 tiddlers from\n[[C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html|C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html]]:\n<<<\n#[[CalendarPlugin]] - added\n#[[CalendarPluginConfig]] - added\n#[[DatePlugin]] - added\n#[[DatePluginConfig]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>\n----\nOn 29 September 2006 16:53:57, RUBad imported 1 tiddler from\n[[C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html|C:\sDocuments and Settings\skwang\sDesktop\swiki\sdemosite-mptw2.html]]:\n<<<\n#[[TagglyListPlugin]] - added\n<<<\n<html><input type="button" href="javascript:;" onclick="story.closeTiddler('ImportedTiddlers'); store.deleteTiddler('ImportedTiddlers');" value="discard report"></html>
The Sonny Werblin Recreation Center have open court time available for everyone who have access to the Recreation Center. However, if you are looking for more than just recreation badminton, please come to one of our club reserved time. We are still 'recreational' but with a bit of 'competitiveness' in it. The point is we love the sports and are always trying to learn and improve as we play. We have players ranging from beginners to advance level. You will be able to fit in no matter what level you are and will soon be able to improve your badminton skills. \nWhat to expect:\n1. Plastic birdies and some club racquets.\n\n2. Players sharing their personal badminton tricks to each others. \n\n3. If permit, formal coaching.\n\n4. We will participate in competitiion, both intramural and outside tournament. Competition is not as scary as it sound. It is definitely the way to make one become much more passionate about the sports. Example: http://www.eden.rutgers.edu/~rubad/#Photo/Video\n\n5. Etc.\n\nTo join:\n1. Come and try out during one of our club practice time.\n\n2. Fill out the roaster and related forms:\nPlease fill out Form G (http://itms.rutgers.edu:16080/ssps/) if you have not already done so for this semester.\nYou will NOT be allowed to play if you have not filled out this form - the people in charge are being very strict about this, so please try to fill it out beforehand - we'll try to have a laptop there for anyone who hasn't been able to fill it out.\n\n3. Pay dues (annual membership fees).\n\n
''USA Badminton Region 1'' [[(About)|http://www.northeastbadminton.net/AboutUs.asp]]\nhttp://www.northeastbadminton.net/\nThis website is the result of an initiative "to actively provide, encourage and further the growth and development of the sport of badminton in Region 1" (northeast region). ([[News|http://www.northeastbadminton.net/News.asp]], [[Events|http://www.northeastbadminton.net/Calendar.asp]], [[Where to play|http://www.northeastbadminton.net/Where2PlayList.asp]])\n\n\n''World Badminton''\nhttp://www.worldbadminton.com/\nFirst place to go when you need to know something about badminton. It provides worldwide information and links about badminton. ([[Tournaments|http://www.worldbadminton.com/tournaments/index.html]], [[Videos|http://www.worldbadminton.com/videos/]], [[Where to play|http://www.worldbadminton.com/whereToPlay/]], [[Equipment|http://www.worldbadminton.com/#equipment]], [[Organizations|http://www.worldbadminton.com/#organizations]], [[Badminton Pages|http://www.worldbadminton.com/badpages.htm]])\nRecommended reading:\n[[Multimedia Instructional Materials|http://www.worldbadminton.com/drills/instructional_multimedia_lowres.htm]] & etc. etc. etc. (The website is full of information. Recommend spending time to explore thoroughly.)\n\n\n''International Badminton Federation (IBF)''\nhttp://www.internationalbadminton.org/\nThe official website of badminton with updated information of competition around the world. ([[Calendar|http://www.internationalbadminton.org/refreesumpires.asp]], [[Latest News|http://www.internationalbadminton.org/newsmain.asp]], [[Ranking|http://www.internationalbadminton.org/worldranking.asp]])\n\n\n''Badminton glossary''\nhttp://www.hickoksports.com/glossary/gbadmint.shtml#atop\nSome badminton jargon a badminton fan ought to know.\n\n\n''Advanced Badminton Techniques''\nhttp://instructoons.com/book/\nSample pdf download from a badminton techniques book.\n\n\n''~Badminton-Information.com'' - added 2007Jan25\nhttp://www.badminton-information.com/index.html\nA fun and casual site with wide range of information about badminton. \nRecommended:\n[[Badminton game!!!|http://www.badminton-information.com/badminton-game.html]]\n\n\n''~YouTube rubadminton playlist'' - added 2007Feb17\nhttp://www.youtube.com/view_play_list?p=9733F041D994582A\nSome instructional videos on ~YouTube.\n\n\n''NJIT Badminton Club'' - added 2007Oct13\nhttp://groups.google.com/group/njit-badminton-club
The purpose of Rutgers (New Jersey) Badminton Club is to foster interest in badminton. Members will meet on a weekly basis to play badminton.\nAnyone with access to the Rutgers recreation center is more than welcome to join in.\n''Goals''\nIt's an exciting time to be part of RU Badminton - we are working hard in the hopes of raising Rutgers' badminton program to a higher and more competitive level. Many other colleges have large badminton programs - it's past time that we expand Rutgers' Badminton as well.\nWe are in the process of contacting others colleges/universities in the interest of setting up friendly competitions.\n''Dues''\n@@$15@@\nWe're giving members a "buffer" zone of ~2-4 weeks to test out the club. At the same time, we are also testing things out to see what works best.\n''Racquets/Equipment''\nRUBAD currently owns a few racquets for general use, but at our first meeting this semester we discovered that we had nowhere near enough.\nYou are encouraged to bring your own racquet.\nWe are in the process of seeing if we can get discounts on badminton gear (i.e. racquets, shoes) for RUBAD members, and we'll keep you all updated.\n''Please note''\nPlease feel free to message any of the officers with suggestions - anything you think could be done to improve the quality of the program that we're trying to grow, anything you'd like to see, let us know!
[[Main]]\n[[Schedule]]\n[[Guideline on the court]]\n[[Competed]]\n[[Officer]]\n\n[[Join]]\n\n[[Announcement/New]]\n[[Reminder]]\n\n[[Link]]\n[[Contact]]\n\n\n\nBest view with:\n[[Firefox|http://www.mozilla.com/firefox/central/]]\n\nPowered by:\n[[TiddlyWiki|http://www.tiddlywiki.com/]]\n\n\n
/***\n|Name|NewHereCommand|\n|Source|http://simonbaird.com/mptw/#NewHereCommand|\n|Version|1.0|\n\nCode originally by ArphenLin. Small tweak by SimonBaird\nhttp://aiddlywiki.sourceforge.net/NewHere_demo.html#NewHereCommand\nTo use this you must edit your ViewTemplate and add newHere to the toolbar div, eg\n{{{<div class='toolbar' macro='toolbar ... newHere'></div>}}}\n***/\n\n//{{{\n\nconfig.commands.newHere = {\n text: 'new here',\n tooltip: 'Create a new tiddler tagged as this tiddler',\n handler: function(e,src,title) {\n if (!readOnly) {\n clearMessage();\n var t=document.getElementById('tiddler'+title);\n story.displayTiddler(t,config.macros.newTiddler.title,DEFAULT_EDIT_TEMPLATE);\n story.setTiddlerTag(config.macros.newTiddler.title, title, 0);\n story.focusTiddler(config.macros.newTiddler.title,"title");\n return false;\n }\n }\n};\n\n//}}}
''President''\nRobert Yu\n\n''Vice president''\nChristopher Carroll\n\n''Secretary''\nKimberly Zhang \n\n''Treasurer''\nSiew Yen Chai\n\n''Coordinator''\nBilal Nadeem\n\n
<div class='header' macro='gradient vert #18f #04b'>\n<div class='headerShadow'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n</div>\n<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>\n<div id='sidebar'>\n<div id='sideBarContent' refresh='content' tiddler='sideBarContent'></div>\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| Name:|QuickOpenTagPlugin|\n| Purpose:|Makes tag links into a Taggly style open tag plus a normal style drop down menu|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#QuickOpenTagPlugin|\n| Requires:|TW 2.x|\n| Version|1.1 (7-Feb-06)|\n\n!History\n* Version 1.1 (07/02/2006)\n** Fix Firefox 1.5.0.1 crashes\n** Updated by ~BidiX[at]~BidiX.info\n* Version 1.0 (?/01/2006)\n** First release\n\n***/\n//{{{\n\n//⊻ ⊽ ⋁ ▼ \n\nwindow.createTagButton_orig_mptw = createTagButton;\nwindow.createTagButton = function(place,tag,excludeTiddler) {\n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyLink(sp,tag,true,"button");\n var theTag = createTiddlyButton(sp,config.macros.miniTag.dropdownchar,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\nconfig.macros.miniTag = {handler: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.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n}};\n\nconfig.macros.miniTag.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE\n\nconfig.macros.allTags.handler = function(place,macroName,params)\n{\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul",null,null,null);\n if(tags.length === 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++)\n {\n var theListItem =createTiddlyElement(theDateList,"li",null,null,null);\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n\n var theDropDownBtn = createTiddlyButton(theListItem," "+config.macros.miniTag.dropdownchar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n};\n\n\nsetStylesheet(\n ".quickopentag { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }\sn"+\n ".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }\sn"+\n ".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}\sn"+\n "a.miniTag {font-size:150%;}\sn"+\n "",\n"QuickOpenTagStyles");\n\n//}}}\n\n/***\n<html>&#x22bb; &#x22bd; &#x22c1; &#x25bc; &#x25be;</html>\n***/\n
<<newReminder>>\n\n<<showReminders>>\n\n
/***\n|''Name:''|ReminderPlugin|\n|''Version:''|2.3.8 (Mar 9, 2006)|\n|''Source:''|http://www.geocities.com/allredfaq/reminderMacros.html|\n|''Author:''|Jeremy Sheeley(pop1280 [at] excite [dot] com)|\n|''Licence:''|[[BSD open source license]]|\n|''Macros:''|reminder, showreminders, displayTiddlersWithReminders, newReminder|\n|''TiddlyWiki:''|2.0+|\n|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|\n\n!Description\nThis plugin provides macros for tagging a date with a reminder. Use the {{{reminder}}} macro to do this. The {{{showReminders}}} and {{{displayTiddlersWithReminder}}} macros automatically search through all available tiddlers looking for upcoming reminders.\n\n!Installation\n* Create a new tiddler in your tiddlywiki titled ReminderPlugin and give it the {{{systemConfig}}} tag. The tag is important because it tells TW that this is executable code.\n* Double click this tiddler, and copy all the text from the tiddler's body.\n* Paste the text into the body of the new tiddler in your TW.\n* Save and reload your TW.\n* You can copy some examples into your TW as well. See [[Simple examples]], [[Holidays]], [[showReminders]] and [[Personal Reminders]]\n\n!Syntax:\n|>|See [[ReminderSyntax]] and [[showRemindersSyntax]]|\n\n!Revision history\n* v2.3.8 (Mar 9, 2006)\n**Bug fix: A global variable had snuck in, which was killing FF 1.5.0.1\n**Feature: You can now use TIDDLER and TIDDLERNAME in a regular reminder format\n* v2.3.6 (Mar 1, 2006)\n**Bug fix: Reminders for today weren't being matched sometimes.\n**Feature: Solidified integration with DatePlugin and CalendarPlugin\n**Feature: Recurring reminders will now return multiple hits in showReminders and the calendar.\n**Feature: Added TIDDLERNAME to the replacements for showReminders format, for plugins that need the title without brackets.\n* v2.3.5 (Feb 8, 2006)\n**Bug fix: Sped up reminders lots. Added a caching mechanism for reminders that have already been matched.\n* v2.3.4 (Feb 7, 2006)\n**Bug fix: Cleaned up code to hopefully prevent the Firefox 1.5.0.1 crash that was causing lots of plugins \nto crash Firefox. Thanks to http://www.jslint.com\n* v2.3.3 (Feb 2, 2006)\n**Feature: newReminder now has drop down lists instead of text boxes.\n**Bug fix: A trailing space in a title would trigger an infinite loop.\n**Bug fix: using tag:"birthday !reminder" would filter differently than tag:"!reminder birthday"\n* v2.3.2 (Jan 21, 2006)\n**Feature: newReminder macro, which will let you easily add a reminder to a tiddler. Thanks to Eric Shulman (http://www.elsdesign.com) for the code to do this.\n** Bug fix: offsetday was not working sometimes\n** Bug fix: when upgrading to 2.0, I included a bit to exclude tiddlers tagged with excludeSearch. I've reverted back to searching through all tiddlers\n* v2.3.1 (Jan 7, 2006)\n**Feature: 2.0 compatibility\n**Feature AlanH sent some code to make sure that showReminders prints a message if no reminders are found.\n* v2.3.0 (Jan 3, 2006)\n** Bug Fix: Using "Last Sunday (-0)" as a offsetdayofweek wasn't working.\n** Bug Fix: Daylight Savings time broke offset based reminders (for example year:2005 month:8 day:23 recurdays:7 would match Monday instead of Tuesday during DST.\n\n!Code\n***/\n//{{{\n\n//============================================================================\n//============================================================================\n// ReminderPlugin\n//============================================================================\n//============================================================================\n\nversion.extensions.ReminderPlugin = {major: 2, minor: 3, revision: 8, date: new Date(2006,3,9), source: "http://www.geocities.com/allredfaq/reminderMacros.html"};\n\n//============================================================================\n// Configuration\n// Modify this section to change the defaults for \n// leadtime and display strings\n//============================================================================\n\nconfig.macros.reminders = {};\nconfig.macros["reminder"] = {};\nconfig.macros["newReminder"] = {};\nconfig.macros["showReminders"] = {};\nconfig.macros["displayTiddlersWithReminders"] = {};\n\nconfig.macros.reminders["defaultLeadTime"] = [0,6000];\nconfig.macros.reminders["defaultReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY";\nconfig.macros.reminders["defaultShowReminderMessage"] = "DIFF: TITLE on DATE ANNIVERSARY -- TIDDLER";\nconfig.macros.reminders["defaultAnniversaryMessage"] = "(DIFF)";\nconfig.macros.reminders["untitledReminder"] = "Untitled Reminder";\nconfig.macros.reminders["noReminderFound"] = "Couldn't find a match for TITLE in the next LEADTIMEUPPER days."\nconfig.macros.reminders["todayString"] = "Today";\nconfig.macros.reminders["tomorrowString"] = "Tomorrow";\nconfig.macros.reminders["ndaysString"] = "DIFF days";\nconfig.macros.reminders["emtpyShowRemindersString"] = "There are no upcoming events";\n\n\n//============================================================================\n// Code\n// You should not need to edit anything \n// below this. Make sure to edit this tiddler and copy \n// the code from the text box, to make sure that \n// tiddler rendering doesn't interfere with the copy \n// and paste.\n//============================================================================\n\n// This line is to preserve 1.2 compatibility\n if (!story) var story=window; \n//this object will hold the cache of reminders, so that we don't\n//recompute the same reminder over again.\nvar reminderCache = {};\n\nconfig.macros.showReminders.handler = function showReminders(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var leadtime = [0,14];\n paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) || \n (paramHash["month"] != null) || \n (paramHash["day"] != null) || \n (paramHash["dayofweek"] != null);\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n {\n //If they've entered a day, we need to make \n //sure to find it. We'll reset the \n //leadtime a few lines down.\n paramHash["leadtime"] = [-10000, 10000];\n }\n }\n var matchedDate = now;\n if (bProvidedDate)\n {\n var leadTimeLowerBound = new Date().getMidnight().addDays(paramHash["leadtime"][0]);\n var leadTimeUpperBound = new Date().getMidnight().addDays(paramHash["leadtime"][1]);\n matchedDate = findDateForReminder(paramHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound); \n }\n\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n var elem = createTiddlyElement(place,"span",null,null, null);\n var mess = "";\n if (arr.length == 0)\n {\n mess += config.macros.reminders.emtpyShowRemindersString; \n }\n for (var j = 0; j < arr.length; j++)\n {\n if (paramHash["format"] != null)\n {\n arr[j]["params"]["format"] = paramHash["format"];\n }\n else\n {\n arr[j]["params"]["format"] = config.macros.reminders["defaultShowReminderMessage"];\n }\n mess += getReminderMessageForDisplay(arr[j]["diff"], arr[j]["params"], arr[j]["matchedDate"], arr[j]["tiddler"]);\n mess += "\sn";\n }\n wikify(mess, elem, null, null);\n};\n\n\nconfig.macros.displayTiddlersWithReminders.handler = function displayTiddlersWithReminders(place,macroName,params)\n{\n var now = new Date().getMidnight();\n var paramHash = {};\n var leadtime = [0,14];\n paramHash = getParamsForReminder(params);\n var bProvidedDate = (paramHash["year"] != null) || \n (paramHash["month"] != null) || \n (paramHash["day"] != null) || \n (paramHash["dayofweek"] != null);\n if (paramHash["leadtime"] != null)\n {\n leadtime = paramHash["leadtime"];\n if (bProvidedDate)\n {\n //If they've entered a day, we need to make \n //sure to find it. We'll reset the leadtime \n //a few lines down.\n paramHash["leadtime"] = [-10000,10000];\n }\n }\n var matchedDate = now;\n if (bProvidedDate)\n {\n var leadTimeLowerBound = new Date().getMidnight().addDays(paramHash["leadtime"][0]);\n var leadTimeUpperBound = new Date().getMidnight().addDays(paramHash["leadtime"][1]);\n matchedDate = findDateForReminder(paramHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound); \n }\n var arr = findTiddlersWithReminders(matchedDate, leadtime, paramHash["tag"], paramHash["limit"]);\n for (var j = 0; j < arr.length; j++)\n {\n displayTiddler(null, arr[j]["tiddler"], 0, null, false, false, false);\n }\n};\n\nconfig.macros.reminder.handler = function reminder(place,macroName,params)\n{\n var dateHash = getParamsForReminder(params);\n if (dateHash["hidden"] != null)\n {\n return;\n }\n var leadTime = dateHash["leadtime"];\n if (leadTime == null)\n {\n leadTime = config.macros.reminders["defaultLeadTime"]; \n }\n var leadTimeLowerBound = new Date().getMidnight().addDays(leadTime[0]);\n var leadTimeUpperBound = new Date().getMidnight().addDays(leadTime[1]);\n var matchedDate = findDateForReminder(dateHash, new Date().getMidnight(), leadTimeLowerBound, leadTimeUpperBound);\n if (!window.story) \n {\n window.story=window; \n }\n if (!store.getTiddler) \n {\n store.getTiddler=function(title) {return this.tiddlers[title];};\n }\n var title = window.story.findContainingTiddler(place).id.substr(7);\n if (matchedDate != null)\n {\n var diff = matchedDate.getDifferenceInDays(new Date().getMidnight());\n var elem = createTiddlyElement(place,"span",null,null, null);\n var mess = getReminderMessageForDisplay(diff, dateHash, matchedDate, title);\n wikify(mess, elem, null, null);\n }\n else\n {\n createTiddlyElement(place,"span",null,null, config.macros.reminders["noReminderFound"].replace("TITLE", dateHash["title"]).replace("LEADTIMEUPPER", leadTime[1]).replace("LEADTIMELOWER", leadTime[0]).replace("TIDDLERNAME", title).replace("TIDDLER", "[[" + title + "]]") );\n }\n};\n\nconfig.macros.newReminder.handler = function newReminder(place,macroName,params)\n{\n var today=new Date().getMidnight();\n var formstring = '<html><form>Year: <select name="year"><option value="">Every year</option>';\n for (var i = 0; i < 5; i++)\n {\n formstring += '<option' + ((i == 0) ? ' selected' : '') + ' value="' + (today.getFullYear() +i) + '">' + (today.getFullYear() + i) + '</option>';\n }\n formstring += '</select>&nbsp;&nbsp;Month:<select name="month"><option value="">Every month</option>';\n for (i = 0; i < 12; i++)\n {\n formstring += '<option' + ((i == today.getMonth()) ? ' selected' : '') + ' value="' + (i+1) + '">' + config.messages.dates.months[i] + '</option>';\n }\n formstring += '</select>&nbsp;&nbsp;Day:<select name="day"><option value="">Every day</option>';\n for (i = 1; i < 32; i++)\n {\n formstring += '<option' + ((i == (today.getDate() )) ? ' selected' : '') + ' value="' + i + '">' + i + '</option>';\n }\n\nformstring += '</select>&nbsp;&nbsp;Reminder Title:<input type="text" size="40" name="title" value="please enter a title" onfocus="this.select();"><input type="button" value="ok" onclick="addReminderToTiddler(this.form)"></form></html>';\n\n var panel = config.macros.slider.createSlider(place,null,"New Reminder","Open a form to add a new reminder to this tiddler");\n wikify(formstring ,panel,null,store.getTiddler(params[1]));\n};\n\n// onclick: process input and insert reminder at 'marker'\nwindow.addReminderToTiddler = function(form) {\n if (!window.story) \n {\n window.story=window; \n }\n if (!store.getTiddler) \n {\n store.getTiddler=function(title) {return this.tiddlers[title];};\n }\n var title = window.story.findContainingTiddler(form).id.substr(7);\n var tiddler=store.getTiddler(title);\n var txt='\sn<<reminder ';\n if (form.year.value != "")\n txt += 'year:'+form.year.value + ' ';\n if (form.month.value != "")\n txt += 'month:'+form.month.value + ' ';\n if (form.day.value != "")\n txt += 'day:'+form.day.value + ' ';\n txt += 'title:"'+form.title.value+'" ';\n txt +='>>';\n tiddler.set(null,tiddler.text + txt);\n window.story.refreshTiddler(title,1,true);\n store.setDirty(true);\n};\n\nfunction hasTag(tiddlerTags, tagFilters)\n{\n //Make sure we respond well to empty tiddlerTaglists or tagFilterlists\n if (tagFilters.length==0 || tiddlerTags.length==0)\n {\n return true;\n }\n\n var bHasTag = false;\n \n /*bNoPos says: "'till now there has been no check using a positive filter"\n Imagine a filterlist consisting of 1 negative filter:\n If the filter isn't matched, we want hasTag to be true.\n Yet bHasTag is still false ('cause only positive filters cause bHasTag to change)\n \n If no positive filters are present bNoPos is true, and no negative filters are matched so we have not returned false\n Thus: hasTag returns true.\n \n If at any time a positive filter is encountered, we want at least one of the tags to match it, so we turn bNoPos to false, which\n means bHasTag must be true for hasTag to return true*/\n var bNoPos=true;\n \nfor (var t3 = 0; t3 < tagFilters.length; t3++)\n {\n for(var t2=0; t2<tiddlerTags.length; t2++)\n {\n if (tagFilters[t3].length > 1 && tagFilters[t3].charAt(0) == '!') \n {\n if (tiddlerTags[t2] == tagFilters[t3].substring(1))\n {\n //If at any time a negative filter is matched, we return false\n return false;\n }\n }\n else \n {\n if (bNoPos)\n {\n //We encountered the first positive filter\n bNoPos=false;\n }\n if (tiddlerTags[t2] == tagFilters[t3])\n {\n //A positive filter is matched. As long as no negative filter is matched, hasTag will return true\n bHasTag=true;\n }\n }\n }\n }\n return (bNoPos || bHasTag);\n};\n\n//This function searches all tiddlers for the reminder //macro. It is intended that other plugins (like //calendar) will use this function to query for \n//upcoming reminders.\n//The arguments to this function filter out reminders //based on when they will fire.\n//\n//ARGUMENTS:\n//baseDate is the date that is used as "now". \n//leadtime is a two element int array, with leadtime[0] \n// as the lower bound and leadtime[1] as the\n// upper bound. A reasonable default is [0,14]\n//tags is a space-separated list of tags to use to filter \n// tiddlers. If a tag name begins with an !, then \n// only tiddlers which do not have that tag will \n// be considered. For example "examples holidays" \n// will search for reminders in any tiddlers that \n// are tagged with examples or holidays and \n// "!examples !holidays" will search for reminders \n// in any tiddlers that are not tagged with \n// examples or holidays. Pass in null to search \n// all tiddlers.\n//limit. If limit is null, individual reminders can \n// override the leadtime specified earlier. \n// Pass in 1 in order to override that behavior.\n\nwindow.findTiddlersWithReminders = function findTiddlersWithReminders(baseDate, leadtime, tags, limit)\n{\n//function(searchRegExp,sortField,excludeTag)\n// var macroPattern = "<<([^>\s\s]+)(?:\s\s*)([^>]*)>>";\n var macroPattern = "<<(reminder)(.*)>>";\n var macroRegExp = new RegExp(macroPattern,"mg");\n var matches = store.search(macroRegExp,"title","");\n var arr = [];\n var tagsArray = null;\n if (tags != null)\n {\n tagsArray = tags.split(" ");\n }\n for(var t=matches.length-1; t>=0; t--)\n {\n if (tagsArray != null)\n {\n //If they specified tags to filter on, and this tiddler doesn't \n //match, skip it entirely.\n if ( ! hasTag(matches[t].tags, tagsArray))\n {\n continue;\n }\n }\n\n var targetText = matches[t].text;\n do {\n // Get the next formatting match\n var formatMatch = macroRegExp.exec(targetText);\n if(formatMatch && formatMatch[1] != null && formatMatch[1].toLowerCase() == "reminder")\n {\n //Find the matching date.\n \n var params = formatMatch[2] != null ? formatMatch[2].readMacroParams() : {};\n var dateHash = getParamsForReminder(params);\n if (limit != null || dateHash["leadtime"] == null)\n {\n if (leadtime == null)\n dateHash["leadtime"] = leadtime;\n else\n {\n dateHash["leadtime"] = [];\n dateHash["leadtime"][0] = leadtime[0];\n dateHash["leadtime"][1] = leadtime[1];\n }\n }\n if (dateHash["leadtime"] == null)\n dateHash["leadtime"] = config.macros.reminders["defaultLeadTime"]; \n var leadTimeLowerBound = baseDate.addDays(dateHash["leadtime"][0]);\n var leadTimeUpperBound = baseDate.addDays(dateHash["leadtime"][1]);\n var matchedDate = findDateForReminder(dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound);\n while (matchedDate != null)\n {\n var hash = {};\n hash["diff"] = matchedDate.getDifferenceInDays(baseDate);\n hash["matchedDate"] = new Date(matchedDate.getFullYear(), matchedDate.getMonth(), matchedDate.getDate(), 0, 0);\n hash["params"] = cloneParams(dateHash);\n hash["tiddler"] = matches[t].title;\n hash["tags"] = matches[t].tags;\n arr.pushUnique(hash);\n if (dateHash["recurdays"] != null || (dateHash["year"] == null))\n {\n leadTimeLowerBound = leadTimeLowerBound.addDays(matchedDate.getDifferenceInDays(leadTimeLowerBound)+ 1);\n matchedDate = findDateForReminder(dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound);\n }\n else matchedDate = null;\n }\n }\n }while(formatMatch);\n }\n if(arr.length > 1) //Sort the array by number of days remaining.\n {\n arr.sort(function (a,b) {if(a["diff"] == b["diff"]) {return(0);} else {return (a["diff"] < b["diff"]) ? -1 : +1; } });\n }\n return arr;\n};\n\n//This function takes the reminder macro parameters and\n//generates the string that is used for display.\n//This function is not intended to be called by \n//other plugins.\n window.getReminderMessageForDisplay= function getReminderMessageForDisplay(diff, params, matchedDate, tiddlerTitle)\n{\n var anniversaryString = "";\n var reminderTitle = params["title"];\n if (reminderTitle == null)\n {\n reminderTitle = config.macros.reminders["untitledReminder"];\n }\n if (params["firstyear"] != null)\n {\n anniversaryString = config.macros.reminders["defaultAnniversaryMessage"].replace("DIFF", (matchedDate.getFullYear() - params["firstyear"]));\n }\n var mess = "";\n var diffString = "";\n if (diff == 0)\n {\n diffString = config.macros.reminders["todayString"];\n }\n else if (diff == 1)\n {\n diffString = config.macros.reminders["tomorrowString"];\n }\n else\n {\n diffString = config.macros.reminders["ndaysString"].replace("DIFF", diff);\n }\n var format = config.macros.reminders["defaultReminderMessage"];\n if (params["format"] != null)\n {\n format = params["format"];\n }\n mess = format;\n//HACK! -- Avoid replacing DD in TIDDLER with the date\n mess = mess.replace(/TIDDLER/g, "TIDELER");\n mess = matchedDate.formatStringDateOnly(mess);\n mess = mess.replace(/TIDELER/g, "TIDDLER");\n if (tiddlerTitle != null)\n {\n mess = mess.replace(/TIDDLERNAME/g, tiddlerTitle);\n mess = mess.replace(/TIDDLER/g, "[[" + tiddlerTitle + "]]");\n }\n \n mess = mess.replace("DIFF", diffString).replace("TITLE", reminderTitle).replace("DATE", matchedDate.formatString("DDD MMM DD, YYYY")).replace("ANNIVERSARY", anniversaryString);\n return mess;\n};\n\n// Parse out the macro parameters into a hashtable. This\n// handles the arguments for reminder, showReminders and \n// displayTiddlersWithReminders.\nwindow.getParamsForReminder = function getParamsForReminder(params)\n{\n var dateHash = {};\n var type = "";\n var num = 0;\n var title = "";\n for(var t=0; t<params.length; t++)\n {\n var split = params[t].split(":");\n type = split[0].toLowerCase();\n var value = split[1];\n for (var i=2; i < split.length; i++)\n {\n value += ":" + split[i];\n }\n if (type == "nolinks" || type == "limit" || type == "hidden")\n {\n num = 1;\n }\n else if (type == "leadtime")\n {\n var leads = value.split("...");\n if (leads.length == 1)\n {\n leads[1]= leads[0];\n leads[0] = 0;\n }\n leads[0] = parseInt(leads[0], 10);\n leads[1] = parseInt(leads[1], 10);\n num = leads;\n }\n else if (type == "offsetdayofweek")\n {\n if (value.substr(0,1) == "-")\n {\n dateHash["negativeOffsetDayOfWeek"] = 1;\n value = value.substr(1);\n }\n num = parseInt(value, 10);\n }\n else if (type != "title" && type != "tag" && type != "format")\n {\n num = parseInt(value, 10);\n }\n else\n {\n title = value;\n t++;\n while (title.substr(0,1) == '"' && title.substr(title.length - 1,1) != '"' && params[t] != undefined)\n {\n title += " " + params[t++];\n }\n //Trim off the leading and trailing quotes\n if (title.substr(0,1) == "\s"" && title.substr(title.length - 1,1)== "\s"")\n {\n title = title.substr(1, title.length - 2);\n t--;\n }\n num = title;\n }\n dateHash[type] = num;\n }\n //date is synonymous with day\n if (dateHash["day"] == null)\n {\n dateHash["day"] = dateHash["date"];\n }\n return dateHash;\n};\n\n//This function finds the date specified in the reminder \n//parameters. It will return null if no match can be\n//found. This function is not intended to be used by\n//other plugins.\nwindow.findDateForReminder= function findDateForReminder( dateHash, baseDate, leadTimeLowerBound, leadTimeUpperBound)\n{\n if (baseDate == null)\n {\n baseDate = new Date().getMidnight();\n }\n var hashKey = baseDate.convertToYYYYMMDDHHMM();\n for (var k in dateHash)\n {\n hashKey += "," + k + "|" + dateHash[k];\n }\n hashKey += "," + leadTimeLowerBound.convertToYYYYMMDDHHMM();\n hashKey += "," + leadTimeUpperBound.convertToYYYYMMDDHHMM();\n if (reminderCache[hashKey] == null)\n {\n //If we don't find a match in this run, then we will\n //cache that the reminder can't be matched.\n reminderCache[hashKey] = false;\n }\n else if (reminderCache[hashKey] == false)\n {\n //We've already tried this date and failed\n return null;\n }\n else\n {\n return reminderCache[hashKey];\n }\n \n var bOffsetSpecified = dateHash["offsetyear"] != null || \n dateHash["offsetmonth"] != null || \n dateHash["offsetday"] != null || \n dateHash["offsetdayofweek"] != null || \n dateHash["recurdays"] != null;\n \n // If we are matching the base date for a dayofweek offset, look for the base date a \n //little further back.\n var tmp1leadTimeLowerBound = leadTimeLowerBound; \n if ( dateHash["offsetdayofweek"] != null)\n {\n tmp1leadTimeLowerBound = leadTimeLowerBound.addDays(-6); \n }\n var matchedDate = baseDate.findMatch(dateHash, tmp1leadTimeLowerBound, leadTimeUpperBound);\n if (matchedDate != null)\n {\n var newMatchedDate = matchedDate;\n if (dateHash["recurdays"] != null)\n {\n while (newMatchedDate.getTime() < leadTimeLowerBound.getTime())\n {\n newMatchedDate = newMatchedDate.addDays(dateHash["recurdays"]);\n }\n }\n else if (dateHash["offsetyear"] != null || \n dateHash["offsetmonth"] != null || \n dateHash["offsetday"] != null || \n dateHash["offsetdayofweek"] != null)\n {\n var tmpdateHash = cloneParams(dateHash);\n tmpdateHash["year"] = dateHash["offsetyear"];\n tmpdateHash["month"] = dateHash["offsetmonth"];\n tmpdateHash["day"] = dateHash["offsetday"];\n tmpdateHash["dayofweek"] = dateHash["offsetdayofweek"];\n var tmpleadTimeLowerBound = leadTimeLowerBound;\n var tmpleadTimeUpperBound = leadTimeUpperBound;\n if (tmpdateHash["offsetdayofweek"] != null)\n {\n if (tmpdateHash["negativeOffsetDayOfWeek"] == 1)\n {\n tmpleadTimeLowerBound = matchedDate.addDays(-6);\n tmpleadTimeUpperBound = matchedDate;\n\n }\n else\n {\n tmpleadTimeLowerBound = matchedDate;\n tmpleadTimeUpperBound = matchedDate.addDays(6);\n }\n\n }\n newMatchedDate = matchedDate.findMatch(tmpdateHash, tmpleadTimeLowerBound, tmpleadTimeUpperBound);\n //The offset couldn't be matched. return null.\n if (newMatchedDate == null)\n {\n return null;\n }\n }\n if (newMatchedDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))\n {\n reminderCache[hashKey] = newMatchedDate;\n return newMatchedDate;\n }\n }\n return null;\n};\n\n//This does much the same job as findDateForReminder, but\n//this one doesn't deal with offsets or recurring \n//reminders.\nDate.prototype.findMatch = function findMatch(dateHash, leadTimeLowerBound, leadTimeUpperBound)\n{\n\n var bSpecifiedYear = (dateHash["year"] != null);\n var bSpecifiedMonth = (dateHash["month"] != null);\n var bSpecifiedDay = (dateHash["day"] != null);\n var bSpecifiedDayOfWeek = (dateHash["dayofweek"] != null);\n if (bSpecifiedYear && bSpecifiedMonth && bSpecifiedDay)\n {\n return new Date(dateHash["year"], dateHash["month"]-1, dateHash["day"], 0, 0);\n }\n var bMatchedYear = !bSpecifiedYear;\n var bMatchedMonth = !bSpecifiedMonth;\n var bMatchedDay = !bSpecifiedDay;\n var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;\n if (bSpecifiedDay && bSpecifiedMonth && !bSpecifiedYear && !bSpecifiedDayOfWeek)\n {\n\n //Shortcut -- First try this year. If it's too small, try next year.\n var tmpMidnight = this.getMidnight();\n var tmpDate = new Date(this.getFullYear(), dateHash["month"]-1, dateHash["day"], 0,0);\n if (tmpDate.getTime() < leadTimeLowerBound.getTime())\n {\n tmpDate = new Date((this.getFullYear() + 1), dateHash["month"]-1, dateHash["day"], 0,0);\n }\n if ( tmpDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))\n {\n return tmpDate;\n }\n else\n {\n return null;\n }\n }\n\n var newDate = leadTimeLowerBound; \n while (newDate.isBetween(leadTimeLowerBound, leadTimeUpperBound))\n {\n var tmp = testDate(newDate, dateHash, bSpecifiedYear, bSpecifiedMonth, bSpecifiedDay, bSpecifiedDayOfWeek);\n if (tmp != null)\n return tmp;\n newDate = newDate.addDays(1);\n }\n};\n\nfunction testDate(testMe, dateHash, bSpecifiedYear, bSpecifiedMonth, bSpecifiedDay, bSpecifiedDayOfWeek)\n{\n var bMatchedYear = !bSpecifiedYear;\n var bMatchedMonth = !bSpecifiedMonth;\n var bMatchedDay = !bSpecifiedDay;\n var bMatchedDayOfWeek = !bSpecifiedDayOfWeek;\n if (bSpecifiedYear)\n {\n bMatchedYear = (dateHash["year"] == testMe.getFullYear());\n }\n if (bSpecifiedMonth)\n {\n bMatchedMonth = ((dateHash["month"] - 1) == testMe.getMonth() );\n }\n if (bSpecifiedDay)\n {\n bMatchedDay = (dateHash["day"] == testMe.getDate());\n }\n if (bSpecifiedDayOfWeek)\n {\n bMatchedDayOfWeek = (dateHash["dayofweek"] == testMe.getDay());\n }\n\n if (bMatchedYear && bMatchedMonth && bMatchedDay && bMatchedDayOfWeek)\n {\n return testMe;\n }\n};\n\n//Returns true if the date is in between two given dates\nDate.prototype.isBetween = function isBetween(lowerBound, upperBound)\n{\n return (this.getTime() >= lowerBound.getTime() && this.getTime() <= upperBound.getTime());\n}\n//Return a new date, with the time set to midnight (0000)\nDate.prototype.getMidnight = function getMidnight()\n{\n return new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0);\n};\n// Add the specified number of days to a date.\nDate.prototype.addDays = function addDays(numberOfDays)\n{\n return new Date(this.getFullYear(), this.getMonth(), this.getDate() + numberOfDays, 0, 0);\n};\n//Return the number of days between two dates.\nDate.prototype.getDifferenceInDays = function getDifferenceInDays(otherDate)\n{\n//I have to do it this way, because this way ignores daylight savings\n var tmpDate = this.addDays(0);\n if (this.getTime() > otherDate.getTime())\n {\n var i = 0;\n for (i = 0; tmpDate.getTime() > otherDate.getTime(); i++)\n {\n tmpDate = tmpDate.addDays(-1);\n }\n return i;\n }\n else\n {\n var i = 0;\n for (i = 0; tmpDate.getTime() < otherDate.getTime(); i++)\n {\n tmpDate = tmpDate.addDays(1);\n }\n return i * -1;\n }\n return 0;\n};\nfunction cloneParams(what) {\n var tmp = {};\n for (var i in what) {\n tmp[i] = what[i];\n }\n return tmp;\n}\n// Substitute date components into a string\nDate.prototype.formatStringDateOnly = function formatStringDateOnly(template)\n{\n template = template.replace("YYYY",this.getFullYear());\n template = template.replace("YY",String.zeroPad(this.getFullYear()-2000,2));\n template = template.replace("MMM",config.messages.dates.months[this.getMonth()]);\n template = template.replace("0MM",String.zeroPad(this.getMonth()+1,2));\n template = template.replace("MM",this.getMonth()+1);\n template = template.replace("DDD",config.messages.dates.days[this.getDay()]);\n template = template.replace("0DD",String.zeroPad(this.getDate(),2));\n template = template.replace("DD",this.getDate());\n return template;\n};\n\n//}}}
The reminder macro can take the following arguments.\n\n!!!!date syntax\n* @@{{{year:NUMBER}}}@@ - The four digit representation of the year (for example {{{year:2046}}} or {{{year:1999}}}\n* @@{{{month:NUMBER}}}@@ - The numerical representation of the month (for example {{{month:1}}} for January, {{{month:12}}} for December)\n* @@{{{day:NUMBER}}}@@ - The numerical representation of the day of the month (for example {{{day:15}}} will match the 15th day of the month)\n* @@{{{dayofweek:NUMBER}}}@@ - The numerical representation of the day of the week. Valid values are in the range of 0-6. {{{dayofweek:0}}} will match Sunday, and {{{dayofweek:6}}} will match Saturday.\n\n!!!!offsets\n* @@{{{offsetdayofweek:NUMBER}}}@@ - The numerical representation of a day of the week. Valid values are in the range of 0-6. 0 will match Sunday, and 6 will match Saturday. If offsetdayofweek is specified, the year, month, day and dayofweek will be matched as usual, and the reminder will be set to the next occurence of the day of the week specified by offsetdayofweek. For example, the first Thursday of the month can be specified as {{{day:1 offsetdayofweek:4}}} and the second Thursday can be specified as {{{day:8 offsetdayofweek4}}} If offsetdayofweek is negative, the search will be performed backward. For example, the last Thursday in August can be found by {{{month:8 day:31 offsetdayofweek:-4}}}\n* @@{{{recurdays:NUMBER}}}@@ - If recurdays is set, then the reminder will fire on the base date specified by year, month, day, and dayofweek and also every N days afterward. For example, if the reminder is specified with {{{year:2005 month:8 day:16 recurdays:2}}} it will match August 16, 18, 20, etc. Please make sure that you fully specify year, month and day in any recurring reminder.\n\n!!!!leadtime\n* @@{{{leadtime:NUMBER}}}@@ - Use this to specify when this reminder will appear in [[showReminders]]. If a reminder has a leadtime of 2, it will only show up in showReminders if it will be matched in the next two days. Likewise, a reminder with a leadtime of 60 will show up in showReminders even if showReminders has a lower leadtime. showReminders can override this behavior with the limit argument.\n\n!!!!Reminder display options\n* @@{{{title:"STRING"}}}@@ - A string used to identify this reminder when it is shown in a list of reminders. For example, {{{title:"New Year's Day"}}} or {{{title:"Elvis' Birthday"}}}. You can put standard TiddlyWiki formatting in the title.\n* @@{{{format:"STRING"}}}@@ - Use this argument to override the default string used for display. You can put standard TiddlyWiki formatting in the format. The following substitutions will be made in the string before it is displayed.\n** DIFF will be replaced with the one of the strings "Today", "Tommorrow", or "N days", where N is the number of days between now and the date of the reminder. \n** TITLE will be replaced with the title of the reminder\n** DATE will be replaced with the matched date of the reminder.\n** ANNIVERSARY will be replaced with the number of years since between the matched date and firstyear\nThe default string is "DIFF: TITLE on DATE ANNIVERSARY"\n* @@{{{firstyear:NUMBER}}}@@ - The first year that a reminder occurred, in four digit format. For example {{{firstyear:2001}}}. This is used when calculating the number of years that a reminder has happened.\n* @@{{{hidden}}}@@ - If this option is present, the reminder will not be displayed in the regular view of the tiddler. You can use this to have reminders for [[displayTiddlersWithReminders]] to find, without having the countdown appear. See [[Season's Greetings example]] for an example.\n\n
/***\n| Name:|RenameTagsPlugin|\n| Purpose:|Allows you to easily rename tags|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#RenameTagsPlugin|\n| Version:|1.0.1 (5-Mar-06)|\n\n!Description\nIf you rename a tiddler/tag that is tagging other tiddlers this plugin will ask you if you want to rename the tag in each tiddler where it is used. This is essential if you use tags and ever want to rename them. To use it, open the tag you want to rename as a tiddler (it's the last option in the tag popup menu), edit it, rename it and click done. You will asked if you want to rename the tag. Click OK to rename the tag in the tiddlers that use it. Click Cancel to not rename the tag.\n\n!Example\nTry renaming [[Plugins]] or [[CSS]] on this site.\n\n!History\n* 1.0.1 (5-Mar-06) - Added feature to allow renaming of tags without side-effect of creating a tiddler\n* 1.0.0 (5-Mar-06) - First working version\n\n!Code\n***/\n//{{{\n\nversion.extensions.RenameTagsPlugin = {\n major: 1, minor: 0, revision: 0,\n date: new Date(2006,3,5),\n source: "http://simonbaird.com/mptw/#RenameTagsPlugin"\n};\n\nconfig.macros.RenameTagsPlugin = {};\nconfig.macros.RenameTagsPlugin.prompt = "Rename the tag '%0' to '%1' in %2 tidder%3?";\n\n// these are very useful, perhaps they should be in the core\nif (!store.addTag) {\n store.addTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n };\n};\n\nif (!store.removeTag) {\n store.removeTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n };\n};\n\nstore.saveTiddler_orig_tagrename = store.saveTiddler;\nstore.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n if (title != newTitle && this.getTaggedTiddlers(title).length > 0) {\n // then we are renaming a tag\n var tagged = this.getTaggedTiddlers(title);\n if (confirm(config.macros.RenameTagsPlugin.prompt.format([title,newTitle,tagged.length,tagged.length>1?"s":""]))) {\n for (var i=0;i<tagged.length;i++) {\n store.removeTag(tagged[i].title,title);\n store.addTag(tagged[i].title,newTitle);\n // if tiddler is visible refresh it to show updated tag\n story.refreshTiddler(tagged[i].title,false,true);\n }\n }\n if (!this.tiddlerExists(title) && newBody == "") {\n // dont create unwanted tiddler\n return null;\n }\n }\n return this.saveTiddler_orig_tagrename(title,newTitle,newBody,modifier,modified,tags);\n}\n\n//}}}\n\n
Open court time:\n''Multisport Bay1, [[Sonny Werblin|http://maps.rutgers.edu/building.aspx?id=297]], Busch campus ([[Opening Hours|http://recreation.rutgers.edu/Facilities/Default.asp]])''\nMondays - Thursdays: 5-9pm.\nFridays: 5-7pm.\n\nClub time:\n''Multisport Bay1, [[Sonny Werblin|http://maps.rutgers.edu/building.aspx?id=297]], Busch campus ([[Opening Hours|http://recreation.rutgers.edu/Facilities/Default.asp]])''\nEvery Friday 7:00pm - 9:00pm\n\nWorking to request more Club time...\n
[[Rutgers Badminton Club|http://www.eden.rutgers.edu/~rubad/]]
~RUBad
/***\n|Name|TagglyListPlugin|\n|Created by|SimonBaird|\n|Location|http://simonbaird.com/mptw/#TagglyListPlugin|\n|Version|1.1.2 25-Apr-06|\n|Requires|See TagglyTagging|\n\n!History\n* 1.1.2 (25-Apr-2006) embedded TagglyTaggingStyles. No longer need separated tiddler for styles.\n* 1.1.1 (6-Mar-2006) fixed bug with refreshAllVisible closing tiddlers being edited. Thanks Luke Blanshard.\n\n***/\n\n/***\n!Setup and config\n***/\n//{{{\n\nversion.extensions.TagglyListPlugin = {\n major: 1, minor: 1, revision: 2,\n date: new Date(2006,4,25),\n source: "http://simonbaird.com/mptw/#TagglyListPlugin"\n};\n\nconfig.macros.tagglyList = {};\nconfig.macros.tagglyListByTag = {};\nconfig.macros.tagglyListControl = {};\nconfig.macros.tagglyListWithSort = {};\nconfig.macros.hideSomeTags = {};\n\n// change this to your preference\nconfig.macros.tagglyListWithSort.maxCols = 6;\n\nconfig.macros.tagglyList.label = "Tagged as %0:";\n\n// the default sort options. set these to your preference\nconfig.macros.tagglyListWithSort.defaults = {\n sortBy:"title", // title|created|modified\n sortOrder: "asc", // asc|desc\n hideState: "show", // show|hide\n groupState: "nogroup", // nogroup|group\n numCols: 1\n};\n\n// these tags will be ignored by the grouped view\nconfig.macros.tagglyListByTag.excludeTheseTags = [\n "systemConfig",\n "TiddlerTemplates"\n];\n\nconfig.macros.tagglyListControl.tags = {\n title:"sortByTitle", \n modified: "sortByModified", \n created: "sortByCreated",\n asc:"sortAsc", \n desc:"sortDesc",\n hide:"hideTagged", \n show:"showTagged",\n nogroup:"noGroupByTag",\n group:"groupByTag",\n cols1:"list1Cols",\n cols2:"list2Cols",\n cols3:"list3Cols",\n cols4:"list4Cols",\n cols5:"list5Cols",\n cols6:"list6Cols",\n cols7:"list7Cols",\n cols8:"list8Cols",\n cols9:"list9Cols" \n}\n\n// note: should match config.macros.tagglyListControl.tags\nconfig.macros.hideSomeTags.tagsToHide = [\n "sortByTitle",\n "sortByCreated",\n "sortByModified",\n "sortDesc",\n "sortAsc",\n "hideTagged",\n "showTagged",\n "noGroupByTag",\n "groupByTag",\n "list1Cols",\n "list2Cols",\n "list3Cols",\n "list4Cols",\n "list5Cols",\n "list6Cols",\n "list7Cols",\n "list8Cols",\n "list9Cols"\n];\n\n\n//}}}\n/***\n\n!Utils\n***/\n//{{{\n// from Eric\nfunction isTagged(title,tag) {\n var t=store.getTiddler(title); if (!t) return false;\n return (t.tags.find(tag)!=null);\n}\n\n// from Eric\nfunction toggleTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)==null) t.tags.push(tag);\n else t.tags.splice(t.tags.find(tag),1);\n}\n\nfunction addTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n}\n\nfunction removeTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n}\n\n// from Udo\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};\nArray.prototype.contains = function(item) {\n return (this.indexOf(item) >= 0);\n}\n//}}}\n/***\n\n!tagglyList\ndisplays a list of tagged tiddlers. \nparameters are sortField and sortOrder\n***/\n//{{{\n\n// not used at the moment...\nfunction sortedListOfOtherTags(tiddler,thisTag) {\n var list = tiddler.tags.concat(); // so we are working on a clone..\n for (var i=0;i<config.macros.hideSomeTags.tagsToHide.length;i++) {\n if (list.find(config.macros.hideSomeTags.tagsToHide[i]) != null)\n list.splice(list.find(config.macros.hideSomeTags.tagsToHide[i]),1); // remove hidden ones\n }\n for (var i=0;i<config.macros.tagglyListByTag.excludeTheseTags.length;i++) {\n if (list.find(config.macros.tagglyListByTag.excludeTheseTags[i]) != null)\n list.splice(list.find(config.macros.tagglyListByTag.excludeTheseTags[i]),1); // remove excluded ones\n }\n list.splice(list.find(thisTag),1); // remove thisTag\n return '[[' + list.sort().join("]] [[") + ']]';\n}\n\nfunction sortHelper(a,b) {\n if (a == b) return 0;\n else if (a < b) return -1;\n else return +1;\n}\n\nconfig.macros.tagglyListByTag.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n\n if (sortOrder == "desc")\n result = result.reverse();\n\n var leftOvers = []\n for (var i=0;i<result.length;i++) {\n leftOvers.push(result[i].title);\n }\n\n var allTagsHolder = {};\n for (var i=0;i<result.length;i++) {\n for (var j=0;j<result[i].tags.length;j++) {\n\n if ( \n result[i].tags[j] != tiddler.title // not this tiddler\n && config.macros.hideSomeTags.tagsToHide.find(result[i].tags[j]) == null // not a hidden one\n && config.macros.tagglyListByTag.excludeTheseTags.find(result[i].tags[j]) == null // not excluded\n ) {\n if (!allTagsHolder[result[i].tags[j]])\n allTagsHolder[result[i].tags[j]] = "";\n allTagsHolder[result[i].tags[j]] += "**[["+result[i].title+"]]\sn";\n\n if (leftOvers.find(result[i].title) != null)\n leftOvers.splice(leftOvers.find(result[i].title),1); // remove from leftovers. at the end it will contain the leftovers...\n }\n }\n }\n\n\n var allTags = [];\n for (var t in allTagsHolder)\n allTags.push(t);\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 markup = "";\n\n if (sortOrder == "desc") {\n allTags.reverse();\n }\n else {\n // leftovers first...\n for (var i=0;i<leftOvers.length;i++)\n markup += "*[["+leftOvers[i]+"]]\sn";\n } \n\n for (var i=0;i<allTags.length;i++)\n markup += "*[["+allTags[i]+"]]\sn" + allTagsHolder[allTags[i]];\n\n if (sortOrder == "desc") {\n // leftovers last...\n for (var i=0;i<leftOvers.length;i++)\n markup += "*[["+leftOvers[i]+"]]\sn";\n }\n\n wikify(markup,place);\n}\n\nconfig.macros.tagglyList.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n var numCols = params[2] ? params[2] : 1;\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n if (sortOrder == "desc")\n result = result.reverse();\n\n var listSize = result.length;\n var colSize = listSize/numCols;\n var remainder = listSize % numCols;\n\n var upperColsize;\n var lowerColsize;\n if (colSize != Math.floor(colSize)) {\n // it's not an exact fit so..\n lowerColsize = Math.floor(colSize);\n upperColsize = Math.floor(colSize) + 1;\n }\n else {\n lowerColsize = colSize;\n upperColsize = colSize;\n }\n\n var markup = "";\n var c=0;\n\n var newTaggedTable = createTiddlyElement(place,"table");\n var newTaggedBody = createTiddlyElement(newTaggedTable,"tbody");\n var newTaggedTr = createTiddlyElement(newTaggedBody,"tr");\n\n for (var j=0;j<numCols;j++) {\n var foo = "";\n var thisSize;\n\n if (j<remainder)\n thisSize = upperColsize;\n else\n thisSize = lowerColsize;\n\n for (var i=0;i<thisSize;i++) \n foo += ( "*[[" + result[c++].title + "]]\sn"); // was using splitList.shift() but didn't work in IE;\n\n var newTd = createTiddlyElement(newTaggedTr,"td",null,"tagglyTagging");\n wikify(foo,newTd);\n\n }\n\n};\n\n/* snip for later.....\n //var groupBy = params[3] ? params[3] : "t.title.substr(0,1)";\n //var groupBy = params[3] ? params[3] : "sortedListOfOtherTags(t,tiddler.title)";\n //var groupBy = params[3] ? params[3] : "t.modified";\n var groupBy = null; // for now. groupBy here is working but disabled for now.\n\n var prevGroup = "";\n var thisGroup = "";\n\n if (groupBy) {\n result.sort(function(a,b) {\n var t = a; var aSortVal = eval(groupBy); var aSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal = eval(groupBy); var bSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal2 = eval(groupBy);\n return (aSortVal == bSortVal ?\n (aSortVal2 == bSortVal2 ? 0 : (aSortVal2 < bSortVal2 ? -1 : +1)) // yuck\n : (aSortVal < bSortVal ? -1 : +1));\n });\n }\n\n if (groupBy) {\n thisGroup = eval(groupBy);\n if (thisGroup != prevGroup)\n markup += "*[["+thisGroup+']]\sn';\n markup += "**[["+t.title+']]\sn';\n prevGroup = thisGroup;\n }\n\n\n\n*/\n\n\n//}}}\n\n/***\n\n!tagglyListControl\nUse to make the sort control buttons\n***/\n//{{{\n\nfunction getSortBy(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortBy;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["title"])) return "title";\n else if (tiddler.tags.contains(usetags["modified"])) return "modified";\n else if (tiddler.tags.contains(usetags["created"])) return "created";\n else return defaultVal;\n}\n\nfunction getSortOrder(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortOrder;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["asc"])) return "asc";\n else if (tiddler.tags.contains(usetags["desc"])) return "desc";\n else return defaultVal;\n}\n\nfunction getHideState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.hideState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["hide"])) return "hide";\n else if (tiddler.tags.contains(usetags["show"])) return "show";\n else return defaultVal;\n}\n\nfunction getGroupState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.groupState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["group"])) return "group";\n else if (tiddler.tags.contains(usetags["nogroup"])) return "nogroup";\n else return defaultVal;\n}\n\nfunction getNumCols(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.numCols; // an int\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n for (var i=1;i<=config.macros.tagglyListWithSort.maxCols;i++)\n if (tiddler.tags.contains(usetags["cols"+i])) return i;\n return defaultVal;\n}\n\n\nfunction getSortLabel(title,which) {\n // TODO. the strings here should be definable in config\n var by = getSortBy(title);\n var order = getSortOrder(title);\n var hide = getHideState(title);\n var group = getGroupState(title);\n if (which == "hide") return (hide == "show" ? "−" : "+"); // 0x25b8;\n else if (which == "group") return (group == "group" ? "normal" : "grouped");\n else if (which == "cols") return "cols±"; // &plusmn;\n else if (by == which) return which + (order == "asc" ? "↓" : "↑"); // &uarr; &darr;\n else return which;\n}\n\nfunction handleSortClick(title,which) {\n var currentSortBy = getSortBy(title);\n var currentSortOrder = getSortOrder(title);\n var currentHideState = getHideState(title);\n var currentGroupState = getGroupState(title);\n var currentNumCols = getNumCols(title);\n\n var tags = config.macros.tagglyListControl.tags;\n\n // if it doesn't exist, lets create it..\n if (!store.getTiddler(title))\n store.saveTiddler(title,title,"",config.options.txtUserName,new Date(),null);\n\n if (which == "hide") {\n // toggle hide state\n var newHideState = (currentHideState == "hide" ? "show" : "hide");\n removeTag(title,tags[currentHideState]);\n if (newHideState != config.macros.tagglyListWithSort.defaults.hideState)\n toggleTag(title,tags[newHideState]);\n }\n else if (which == "group") {\n // toggle hide state\n var newGroupState = (currentGroupState == "group" ? "nogroup" : "group");\n removeTag(title,tags[currentGroupState]);\n if (newGroupState != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags[newGroupState]);\n }\n else if (which == "cols") {\n // toggle num cols\n var newNumCols = currentNumCols + 1; // confusing. currentNumCols is an int\n if (newNumCols > config.macros.tagglyListWithSort.maxCols || newNumCols > store.getTaggedTiddlers(title).length)\n newNumCols = 1;\n removeTag(title,tags["cols"+currentNumCols]);\n if (("cols"+newNumCols) != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags["cols"+newNumCols]);\n }\n else if (currentSortBy == which) {\n // toggle sort order\n var newSortOrder = (currentSortOrder == "asc" ? "desc" : "asc");\n removeTag(title,tags[currentSortOrder]);\n if (newSortOrder != config.macros.tagglyListWithSort.defaults.sortOrder)\n toggleTag(title,tags[newSortOrder]);\n }\n else {\n // change sortBy only\n removeTag(title,tags["title"]);\n removeTag(title,tags["created"]);\n removeTag(title,tags["modified"]);\n\n if (which != config.macros.tagglyListWithSort.defaults.sortBy)\n toggleTag(title,tags[which]);\n }\n\n store.setDirty(true); // save is required now.\n story.refreshTiddler(title,false,true); // force=true\n}\n\nconfig.macros.tagglyListControl.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var onclick = function(e) {\n if (!e) var e = window.event;\n handleSortClick(tiddler.title,params[0]);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return false;\n };\n createTiddlyButton(place,getSortLabel(tiddler.title,params[0]),"Click to change sort options",onclick,params[0]=="hide"?"hidebutton":"button");\n}\n//}}}\n/***\n\n!tagglyListWithSort\nput it all together..\n***/\n//{{{\nconfig.macros.tagglyListWithSort.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n if (tiddler && store.getTaggedTiddlers(tiddler.title).length > 0)\n // todo make this readable\n wikify(\n "<<tagglyListControl hide>>"+\n (getHideState(tiddler.title) != "hide" ? \n '<html><span class="tagglyLabel">'+config.macros.tagglyList.label.format([tiddler.title])+' </span></html>'+\n "<<tagglyListControl title>><<tagglyListControl modified>><<tagglyListControl created>><<tagglyListControl group>>"+(getGroupState(tiddler.title)=="group"?"":"<<tagglyListControl cols>>")+"\sn" + \n "<<tagglyList" + (getGroupState(tiddler.title)=="group"?"ByTag ":" ") + getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+" "+getNumCols(tiddler.title)+">>" // hacky\n // + \sn----\sn" +\n //"<<tagglyList "+getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+">>"\n : ""),\n place,null,tiddler);\n}\n\nconfig.macros.tagglyTagging = { handler: config.macros.tagglyListWithSort.handler };\n\n\n//}}}\n/***\n\n!hideSomeTags\nSo we don't see the sort tags.\n(note, they are still there when you edit. Will that be too annoying?\n***/\n//{{{\n\n// based on tags.handler\nconfig.macros.hideSomeTags.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n var theList = createTiddlyElement(place,"ul");\n if(params[0] && store.tiddlerExists[params[0]])\n tiddler = store.getTiddler(params[0]);\n var lingo = config.views.wikified.tag;\n var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;\n createTiddlyElement(theList,"li",null,"listTitle",prompt.format([tiddler.title]));\n for(var t=0; t<tiddler.tags.length; t++)\n if (!this.tagsToHide.contains(tiddler.tags[t])) // this is the only difference from tags.handler...\n createTagButton(createTiddlyElement(theList,"li"),tiddler.tags[t],tiddler.title);\n\n}\n\n//}}}\n/***\n\n!Refresh everything when we save a tiddler. So the tagged lists never get stale. Is this too slow???\n***/\n//{{{\n\nfunction refreshAllVisible() {\n story.forEachTiddler(function(title,element) {\n if (element.getAttribute("dirty") != "true") \n story.refreshTiddler(title,false,true);\n });\n}\n\nstory.saveTiddler_orig_mptw = story.saveTiddler;\nstory.saveTiddler = function(title,minorUpdate) {\n var result = this.saveTiddler_orig_mptw(title,minorUpdate);\n refreshAllVisible();\n return result;\n}\n\nstore.removeTiddler_orig_mptw = store.removeTiddler;\nstore.removeTiddler = function(title) {\n this.removeTiddler_orig_mptw(title);\n refreshAllVisible();\n}\n\nconfig.shadowTiddlers.TagglyTaggingStyles = "/***\snTo use, add {{{[[TagglyTaggingStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also ViewTemplate, EditTemplate and TagglyTagging.\sn***/\sn/*{{{*/\sn.tagglyTagged li.listTitle { display:none;}\sn.tagglyTagged li { display: inline; font-size:90%; }\sn.tagglyTagged ul { margin:0px; padding:0px; }\sn.tagglyTagging { padding-top:0.5em; }\sn.tagglyTagging li.listTitle { display:none;}\sn.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }\sn\sn/* .tagglyTagging .tghide { display:inline; } */\sn\sn.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\sn.tagglyTagging table { margin:0px; padding:0px; }\sn\sn\sn.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\sn.tagglyTagging .button, .tagglyTagging .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}\sn.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }\sn.selected .tagglyTagging .button { display:inline; }\sn\sn.tagglyTagging .hidebutton { color:white; } /* has to be there so it takes up space. tweak if you're not using a white tiddler bg */\sn.selected .tagglyTagging .hidebutton { color:#aaa }\sn\sn.tagglyLabel { color:#aaa; font-size:90%; }\sn\sn.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\sn.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\sn.tagglyTagging ul ul li {margin-left:0.5em; }\sn\sn.editLabel { font-size:90%; padding-top:0.5em; }\sn/*}}}*/\sn";\n\nrefreshStyles("TagglyTaggingStyles");\n\n\n//}}}\n\n// // <html>&#x25b8;&#x25be;&minus;&plusmn;</html>
<<newReminder>>\n<<reminder year:2007 month:6 day:9 title:"''PBA YMCA Tournament''" >>\n<<reminder year:2007 month:6 day:16 title:"''PA York Open''" >>\n<<reminder year:2007 month:6 day:17 title:"''PA York Open''" >>
<div class="toolbar" macro="toolbar -closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>\n<div><span class="title" macro="view title"></span><span class="miniTag" macro="miniTag"></span></div>\n<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date [[DD MMM YYYY]]'></span> (created <span macro='view created date [[DD MMM YYYY]]'></span>)</div>\n<div class="tagglyTagged" macro="hideSomeTags"></div>\n<div class="viewer" macro="view text wikified"></div>\n<div class="tagglyTagging" macro="tagglyTagging"></div>
Type the text for 'New Tiddler'
Type the text for 'calendar'
Type the text for 'content'
[[ExportTiddlersPanel]]\n[[ExportTiddlersPlugin]]\n[[ImportTiddlersPanel]]\n[[ImportTiddlersPlugin]]
Type the text for 'includeNew'
Type the text for 'reminder'
<<calendar thismonth>>\nDays __underlined__ have reminders set.\n!!!Upcoming meets\n<<showReminders leadtime:7 format:"|DIFF|TITLE|" >>\n
Suggested readings:\n''Grips:''\nhttp://www.badminton-information.com/badminton_grip.html\n\n''Serve:''\nWe are going to concentrate on 'low serve', first.\nhttp://www.badminton-information.com/badminton_serve.html\n\n''Clear:''\nWhat is clear?\nhttp://www.hickoksports.com/glossary/gbadmint.shtml#ctop\nHow to do it?\nhttp://www.badminton-information.com/badminton_clears.html\nCan you show me?\nhttp://www.sportunterricht.de/lksport/clear.html
Type the text for 'tagglyTagging'