Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
Well, after some frustration, I have managed to integrate //~TagglyTags// with the StoryWiki in a way that get's me the options I wanted out of it without overwriting everything I wanted to leave alone.
While it was 'a learning experience' for me, it also resulted in my figuring out how to pull all my templates together and have a single plugin generate them as shadow tiddlers, which resolves a host of issues with my trying to keep helpfiles both accessible *and* out of the way. So, as of this moment, if you want to download this but don't need the help files, you just need the plugins and [[systemTheme(StoryWiki)]]. Everything else can be kept or ignored as required.
To do? Well, I'm still on the lookout for a plugin or upgrade that would combine XML/SVG with Tiddlers for graphics. I'm going to need to work out some details on how to work with javascript conditionals to clean up some thing - I'd like to set it up so that the plugin option panels would simply not be generated if the plugin isn't installed or activated. But for me that's getting fairly deep, and Object Oriented Programming is supremely counter-intuitive to me even when I know the language already.
Well, if anyone uses this, I had fun setting it up, and hope you like it - Pug
Well, I have a partial solution to SVG in Tiddlywiki - [[inlineSVG]] is up, and appears to work for everything that is //purely// SVG.
But at this moment it's not working right with internal references - the 'xlink' namespace, which means everything that relies upon them is broken - defs, gradients, use, et al. This is almost certainly due to incompetence on my part, and I have hopes someone can show what I'm doing wrong. My only attempt to use EMSA (javascript) inside SVG didn't work either, but I'm not going to try and solve that unless fixing xlinks doesn't fix it (and maybe not then - for my purposes static SVG images are more than sufficient.). Even as is, I'm fairly happy with it, and the basic code should be able to handle any other form of XML that the browser can handle.
Did some minor reorganization - Found the Story tabs on the bottom right weren't being used, and the new tab items were redundant with 'new here', so wiped some stuff out in favor of a Main Menu that autopopulates when you tag something 'MainMenu' - TagglyTagging pretty much takes care of it from there.
Killed what I thought was a bug in the SVG Macro that was actually an error introduced by random text copying - sadly inline SVG still not working with references, but it has some solid functionality I think.
Suspect the issue is with it creating the SVG before the DOM is finished thus the references are empty, but I haven't figured out how to fix that just yet.
Changed (Obviously) the journal entries to year-month-day format because I like that it sorts properly and I'm just not right in the head. Added and alternat one that did the same to hours and minutes to the Misc Options.
Suspect [[this|http://www.sitepoint.com/forums/showthread.php?t=555870]] is the code I need to fix this, but haven't gotten it to work yet.
[[$(document).ready()|http://docs.jquery.com/Tutorials:Introducing_$%28document%29.ready%28%29]] seems important too
Tamás IVÁN wrote me with some simple functionality updates to my inline SVG script allowing height and width to be adjusted in the parameters - I have updated the script and helpfile accordingly.
I also ran accross [[This Thread|http://groups.google.com/group/tiddlywiki/browse_thread/thread/858daeed386b0043]] on the list, which is a simple, obvious solution to cleaning up the tiddlywiki when you're not actually editing - If you downnload the wiki and need to edit, the password is currently StoryWiki and is set as a cookie. It's worth explicitly noting that without a crypt() function to compare a hash of the passwords rather than cleartext, this is only going to keep an honest person honest - the password is stored in the clear in the textfile, but gives *slightly* more functionality than, say, a checkbox. So any genuinely sensitive info should still be stored using the tiddler encryption functionality.
/***
|Name:|AdminPassword|
|Description:| A Password to allow editing <br> Note: this is an entirely insecure, unhashed password. It's useful for not permanently 'locking' the TW Read-Only every time you send out a copy. |
|Version:|1.0|
|Date:|$Date: 2010-05-24|
|Source:|http://groups.google.com/group/tiddlywiki/browse_thread/thread/858daeed386b0043|
|Author:|Pugugly001 <pugugly001@gmail.com>|
***/
//{{{
config.options.txtAdminPassword = "StoryWiki";
config.options.txtAdminPasswordInput = "";
//}}}
//{{{
if(config.options.txtAdminPasswordInput != config.options.txtAdminPassword)
{ showBackstage = false;
readOnly = true;
config.shadowTiddlers.adminpassword = 'Three';
config.shadowTiddlers.SideBarOptions = 'Type Document Password and Refresh to Edit:<<option txtAdminPasswordInput>>';
}
//}}}
/***
|''Name''|FilterTiddlersPlugin|
|''Description''|Overrides the core filterTiddlers to provide a more complete syntax compatible with default tiddlers|
|''Author''|Jon Robson|
|''Version''|0.8|
|''Date''|Nov 2008|
|''Status''|@@experimental@@;|
|''License''|BSD|
|''CoreVersion''|<...>|
|''Documentation''|<...>|
|''Usage''|
*OR syntax [field[value]]
eg. [tag[foo]] [tag[bar]]
gives you all tiddlers tagged with foo or bar
*AND syntax
[tag[foo]tag[bar]]
gives you all tiddlers tagged with foo and bar
* more powerful sorting
allows you to sort by an integer field
[tag[foo]sort(int)[priority]]
Great for improving usage of the list macro and defaultTiddlers
***/
//state transition function is a function that returns a new state.
config.extensions.finite_state_automata = function(transition_function,final_states){
this.defineTransitionFunction(transition_function);
this.final_states = final_states;
}
config.extensions.finite_state_automata.prototype={
reset: function(){
this.final_states = [];
this.transition_function= false;
}
,isFinalState: function(state){
return this.final_states.indexOf(state) != -1;
}
,run: function(startState,input){
if(this.isFinalState(startState)){
return input;
}
if(!this.transition_function){
throw "please define a transition function which takes two parameters - a state and token";
}
var state = this.transition_function(startState,input[0]);
var remaining_input = input.substr(1);
return this.run(state,remaining_input);
}
,defineFinalState: function(state){
this.final_states.push(state);
}
,defineTransitionFunction: function(f){
this.transition_function = f;
}
}
Array.prototype.concatUnique = function(items,unique){
for(var i=0; i < items.length;i++){
var item = items[i];
this.pushUnique(item);
}
return this;
}
TiddlyWiki.prototype.sortTiddlers = function(tiddlers,field,fieldType)
{
var asc = +1;
if(!fieldType)fieldType ="";
var convert;
switch(fieldType.toLowerCase()){
case "int":
convert = function(v){if(!v) return 0; else return parseInt(v);}
break;
case "float":
convert = function(v){if(!v) return 0; else return parseInt(v)};
break;
default:
convert = function(v){return v;};
}
switch(field.substr(0,1)) {
case "-":
asc = -1;
// Note: this fall-through is intentional
/*jsl:fallthru*/
case "+":
field = field.substr(1);
break;
}
if(TiddlyWiki.standardFieldAccess[field])
tiddlers.sort(function(a,b) {return a[field] < b[field] ? -asc : (a[field] == b[field] ? 0 : asc);});
else{
tiddlers.sort(function(a,b) {return convert(a.fields[field]) < convert(b.fields[field]) ? -asc : (a.fields[field] == b.fields[field] ? 0 : +asc);});
}return tiddlers;
};
//bit like getTaggedTiddlers only works on fields too
TiddlyWiki.prototype.getValueTiddlers = function(fieldName,value,tiddlers){
var negationMode = false;
if(value[0] =="!") {
value = value.substr(1);
negationMode= true;
}
var filterResult = [];
if(!tiddlers) tiddlers = store.getTiddlers();
if(fieldName == 'tag') fieldName = "tags";
for(var i=0; i < tiddlers.length; i++){
var tiddler = tiddlers[i];
var values;
if(tiddler[fieldName]){
values = tiddler[fieldName]
}
else if(tiddler.fields[fieldName]){
values = tiddler.fields[fieldName];
}
else{
values = false;
}
if(values){
if(typeof(values)== 'string' && ((values == value && !negationMode) || (negationMode && values !=value))){
filterResult.pushUnique(tiddler);
}
else if((!negationMode && values.indexOf(value) >-1) || (negationMode && values.indexOf(value) == -1)) {
filterResult.pushUnique(tiddler);
}
}
}
return filterResult;
}
TiddlyWiki.prototype.filterTiddlers = function(filter)
{
var filterResult = [];
var open = 0;
var current_state = 'A';
var value = "",field="", mem ="";
var arg1 = "",arg2="";
var andFilter = [];
var write_to_arg1 = function(ch){
if(ch != ']' && ch != "[" && ch != "\n")arg1 +=ch;
}
var write_to_arg2 = function(ch){
if(ch != ']' && ch != "[" && ch != "\n")arg2 +=ch;
}
var restart = function(){
arg1 = "";arg2= "";andFilter = [];
}
var addTiddler= function(){
arg1 =arg1.trim();
//console.log("Add tiddler","'"+arg1+"'");
var tid = store.getTiddler(arg1);
if(tid)filterResult.pushUnique(tid);
restart();
}
var tw = this;
var sort = function(tiddlers,arg1,arg2){
var stype = false;
var startType = arg1.indexOf("(") + 1;
if(startType >0) stype = arg1.substr(startType,arg1.length-startType-1);
tiddlers =tw.sortTiddlers(tiddlers,arg2,stype)
return tiddlers;
}
var applyORFilter = function(ch){
//console.log("apply or filter",arg1,arg2);
arg1 = arg1.trim();
arg2 = arg2.trim();
if(arg1.indexOf("sort") == 0) filterResult= sort(filterResult,arg1,arg2);
else {
filterResult = filterResult.concatUnique(tw.getValueTiddlers(arg1,arg2));
}
restart();
}
var applyAndFilter = function(ch){
saveAndFilterArg(ch);
//console.log("applying and filter",andFilter);
var andResult = false;
for(var i=0; i < andFilter.length; i++){
var filter = andFilter[i];
if(andResult && filter[0].indexOf("sort") == 0) andResult =sort(andResult,filter[0],filter[1])
else andResult = tw.getValueTiddlers(filter[0],filter[1],andResult);
}
filterResult = filterResult.concat(andResult);
restart();
}
var saveAndFilterArg = function(ch){
//console.log("saving filter",arg1,arg2)
andFilter.push([arg1.trim(),arg2.trim()])
arg1= "";
write_to_arg1(ch);
arg2= "";
return "I";
}
//define the transition function
var tf = function(state,token){
switch(state){
case 'A':
write_to_arg1(token);
if(token =='[') return 'B'
else if(token == ' ' || token =='\n') return "A";
else return "Y";
case 'Y':
write_to_arg1(token);
if(token ==' ' || token =='\n') {
addTiddler();
return 'Z'
}
else return "Y";
case 'B':
write_to_arg1(token);
if(token =='[') return "C";
else return "F";
case 'C':
write_to_arg1(token);
if(token ==']') return "D";
else return "C";
case 'D':
if(token ==']') {
addTiddler();
return "Z"
}
case 'F':
write_to_arg1(token);
if(token =='[') return "G";
else return "F";
case 'G':
write_to_arg2(token);
if(token ==']') return "H";
else return "G";
case 'H':
if(token ==']'){
applyORFilter(token);
return "Z";
}
else {
saveAndFilterArg(token)
return "I"
}
case 'I':
write_to_arg1(token);
if(token =='[') return "J";
else return "I";
case 'J':
write_to_arg2(token);
if(token ==']') return "K";
else return "J";
case 'K':
if(token ==']') {
applyAndFilter(token);
return "Z";
}
else {
saveAndFilterArg(token);
return 'I'
}
}
throw "the finite state automata could not parse the input."
}
var fsa= new config.extensions.finite_state_automata(tf,['Z']);
var remaining = fsa.run("A",filter);
var timeout =100;
while(timeout > 0 && remaining != ""){
remaining = fsa.run("A",remaining);
timeout -=1;
if(timeout ==0) throw "timed out with remaining input at " + remaining;
}
return filterResult;
};
/***
|!''Name:''|Generated by [[configAdvancedOptionsHardcodePlugin]]|
|!''Description:''|This Generated "~ShadowPlugin" can be used as a template for saving any and all configuration options nominally saved by cookies: simply edit as required and add the relevant tags to this shadowtiddler. |
|!''Version:''|1.0 |
|!''Date:''|May 07, 2009 |
|!''Author:''|Dynamically Generated |
|!''License:''|Dynamically Generated |
|!''~CoreVersion:''|2.2.0|
***/
//{{{
// Useful Core Options
config.options.chkSaveBackups = false; // Description: Keep backup file when saving changes
//config.options.chkAutoSave = true; // Description: Automatically save changes
//config.options.chkGenerateAnRssFeed = false; // Description: Generate an RSS feed when saving changes
config.options.chkToggleLinks = true; // Description: Clicking on links to open tiddlers causes them to close
//config.options.chkHttpReadOnly = false; // Description: Hide editing features when viewed over HTTP
config.options.chkForceMinorUpdate = false; // Description: Don't update modifier username and date when editing tiddlers
config.options.txtBackupFolder = "TiddlyWiki.Archive"; // Description: Name of folder to use for backups
config.options.txtUserName = "StoryWiki"; // Description: Default Username for signing your edits
config.options.txtSiteTitle = config.options.txtUserName; // Set Site Title to Default Username
config.options.txtSiteSubtitle = "Click here To set ["+"[SiteTitle]] and ["+"[SiteSubtitle]]"; // Set links to change the default Titles
//config.options.txtSiteTitle = "["+"["+config.options.txtUserName+"]]"; // Set Site Title to link to Username
//config.options.txtSiteSubtitle = '<<newTiddler label:"New '+config.options.txtUserName+' Story" prompt:"Start a New Story" title:"New Story" focus:title text:"New Story:" tag:story tag:"'+config.options.txtUserName+'">>'; // Create New Story Here
//WikiLinks Options
config.options.txtDisableWikiLinksList = "excludeWikiLinks";
config.options.txtDisableWikiLinksTag = "excludeWikiLinks";
config.options.chkDisableNonExistingWikiLinks = true; // Disable Automated Wiki Links for any wiki that does not already exist
//Tiddler Encryption Plugins
config.options.chkExcludeEncryptedFromSearch = true;
config.options.chkExcludeEncryptedFromLists = false;
config.options.chkShowDecryptButtonInContent = true;
//}}}
/***
|''Name:''|AdvancedOptionsreadOnly|
|''Description:''|Built in Hardcoding Option - simply add the systemConfig (Also excludeLists and excludeSearch) tag to this shadowtiddler to permanently render the tiddler "readOnly". |
| | //By it's nature this is not trivial to undo// |
|''Version:''|1.0|
|''Date:''|Mar 20, 2007|
|''Source:''|http://tiddlywiki.org/wiki/Configuration_Options|
|''Author:''|Public Domain|
|''License:''|Publicly Documented Tweak|
|''~CoreVersion:''|2.2.0|
***/
//{{{
readOnly = false; // default: true when viewed over HTTP, false when used locally -- for TiddlyWiki v2.2+ only
// Changing this to true will lock out all editing capabilities for the document once saved.
//}}}
<<SVG '
<g transform="translate(0,5)" >
<g transform="scale(4,1)" >
<path d="M 20,24 C 20,23 21.5,24.25 21.5,24.75 C 21.75,26.5 19.75,27.5 18.25,27.25 C 15.75,27 14.5,24 15,21.75 C 15.75,18 19.75,16.5 23,17.25 C 27.25,18.75 29.5,23.75 28,28 C 26.25,33.25 20.25,35.75 15.25,34 C 9,31.75 6.25,24.5 8.5,18.5 C 11,11.5 19.25,8 26,10.75 C 34,13.75 37.5,23.25 34.5,31 C 31.25,40 20.75,44. 12.25,40.5 C 2.5,36.75 0,25 2,15.25 C 6,5.5 16.75,1.5 27,3.25 C 44.5,6.5 98.75,37.25 100,20" fill="none" fill-rule="evenodd" stroke="black" stroke-width="1" />
<g transform="translate(100)" >
<g transform="rotate(180,50,20)" >
<path d="M 20,24 C 20,23 21.5,24.25 21.5,24.75 C 21.75,26.5 19.75,27.5 18.25,27.25 C 15.75,27 14.5,24 15,21.75 C 15.75,18 19.75,16.5 23,17.25 C 27.25,18.75 29.5,23.75 28,28 C 26.25,33.25 20.25,35.75 15.25,34 C 9,31.75 6.25,24.5 8.5,18.5 C 11,11.5 19.25,8 26,10.75 C 34,13.75 37.5,23.25 34.5,31 C 31.25,40 20.75,44. 12.25,40.5 C 2.5,36.75 0,25 2,15.25 C 6,5.5 16.75,1.5 27,3.25 C 44.5,6.5 98.75,37.25 100,20" fill="none" fill-rule="evenodd" stroke="black" stroke-width="1" />
</g>
</g>
</g>
</g>
'>>
{{{
<<SVG "<circle r='50' cx='50' cy='50' fill='green'/>">>
}}}
<<SVG "<circle r='50' cx='50' cy='50' fill='green'/>">>
{{{
<<SVG "<circle r='50' cx='50' cy='50' fill='green'/>">> <<SVG "<rect x='20' y='20' rx='0' ry='0' width='160' height='160' fill='blue' />">>
}}}
<<SVG "<circle r='50' cx='50' cy='50' fill='green'/>">> <<SVG "<rect x='20' y='20' rx='0' ry='0' width='160' height='160' fill='blue' />">>
/***
|Name|CopyTiddlerPlugin|
|Source|http://www.TiddlyTools.com/#CopyTiddlerPlugin|
|Version|3.2.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.3|
|Type|plugin|
|Requires||
|Overrides||
|Description|Quickly create a copy of any existing tiddler|
!!!Usage
<<<
This plugin automatically updates the default (shadow) ToolbarCommands slice definitions to insert the ''copyTiddler'' command (which appears as ''copy'' in the tiddler toolbar).
When you select the ''copy'' command, a new tiddler is opened with a title of "{{{TiddlerName (n)}}}" containing copies of the text/tags/fields from the original //source tiddler//, where ''(n)'' is the next available number (starting with 1, of course). Note: If you copy while //editing// a tiddler, the current values that are displayed in the existing tiddler editor are used (including any unsaved changes you may have made to those values), and the new tiddler is immediately opened for editing.
Note: if you are already using customized toolbar definitions, you will need to manually add the ''copyTiddler'' toolbar command to your existing ToolbarCommands tiddler, e.g.:
{{{
|EditToolbar|... copyTiddler ... |
}}}
The plugin also provides a macro that allows you to embed a ''copy'' command directly in specific tiddler content:
{{{
<<copyTiddler TidderName label:"..." prompt:"...">>
}}}
where
* ''TiddlerName'' (optional)<br>specifies the //source// tiddler to be copied. If omitted, the current containing tiddler (if any) will be copied.
* ''label:"..."'' (optional)<br>specifies text to use for the embedded link (default="copy TiddlerName")
* ''prompt:"..."'' (optional)<br>specifies mouseover 'tooltip' help text for link
//Note: to use non-default label/prompt values with the current containing tiddler, use "" for the TiddlerName//
<<<
!!!Revisions
<<<
2009.02.13 [3.2.2] in click(), fix calls to displayTiddler() to use current tiddlerElem and use getTiddlerText() to permit copying of shadow tiddler content
2009.01.30 [3.2.1] fixed handling for copying field values when in edit mode
2009.01.23 [3.2.0] refactored code and added {{{<<copyTiddler TiddlerName>>}}} macro
2008.12.18 [3.1.4] corrected code for finding next (n) value when 'sparse' handling is in effect (thanks to RussThomas for identifying and diagnosing the problem)
2008.11.14 [3.1.3] added optional 'sparse' setting (avoids 'filling in' missing numbers that may have been previously deleted)
2008.11.14 [3.1.2] added optional 'zeroPad' setting
2008.11.14 [3.1.1] moved hard-coded '(n)' regex into 'suffixPattern' object property so it can be customized
2008.09.26 [3.1.0] changed new title generation to use '(n)' suffix instead of 'Copy of' prefix
2008.05.20 [3.0.3] in handler, when copying from VIEW mode, create duplicate array from existing tags array before saving new tiddler.
2007.12.19 [3.0.2] in handler, when copying from VIEW mode, duplicate custom fields before saving new tiddler. Thanks to bug report from Ken Girard.
2007.09.26 [3.0.1] in handler, use findContainingTiddler(src) to get tiddlerElem (and title). Allows 'copy' command to find correct tiddler when transcluded using {{{<<tiddler>>}}} macro or enhanced toolbar inclusion (see [[CoreTweaks]])
2007.06.28 [3.0.0] complete re-write to handle custom fields and alternative view/edit templates
2007.05.17 [2.1.2] use store.getTiddlerText() to retrieve tiddler content, so that SHADOW tiddlers can be copied correctly when in VIEW mode
2007.04.01 [2.1.1] in copyTiddler.handler(), fix check for editor fields by ensuring that found field actually has edit=='text' attribute
2007.02.05 [2.1.0] in copyTiddler.handler(), if editor fields (textfield and/or tagsfield) can't be found (i.e., tiddler is in VIEW mode, not EDIT mode), then get text/tags values from stored tiddler instead of active editor fields. Allows use of COPY toolbar directly from VIEW mode (based on a request from LaurentCharles)
2006.12.12 [2.0.0] completely rewritten so plugin just creates a new tiddler EDITOR with a copy of the current tiddler EDITOR contents, instead of creating the new tiddler in the STORE by copying the current tiddler values from the STORE.
2005.xx.xx [1.0.0] original version by Tim Morgan
<<<
!!!Code
***/
//{{{
version.extensions.CopyTiddlerPlugin= {major: 3, minor: 2, revision: 2, date: new Date(2009,2,13)};
// automatically tweak shadow EditTemplate to add 'copyTiddler' toolbar command (following 'cancelTiddler')
config.shadowTiddlers.ToolbarCommands=config.shadowTiddlers.ToolbarCommands.replace(/cancelTiddler/,'cancelTiddler copyTiddler');
config.commands.copyTiddler = {
text: 'copy',
hideReadOnly: true,
tooltip: 'Make a copy of this tiddler',
handler: function(event,src,title) { return config.macros.copyTiddler.click(src,event); }
};
config.macros.copyTiddler = {
label: 'copy',
prompt: 'Make a copy of %0',
notitle: 'this tiddler',
prefix: '',
suffixText: ' (%0)',
suffixPattern: / \(([0-9]+)\)$/,
zeroPad: 0,
sparse: false,
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var title=params.shift();
params=paramString.parseParams('anon',null,true,false,false);
var label =getParam(params,'label',this.label+(title?' '+title:''));
var prompt =getParam(params,'prompt',this.prompt).format([title||this.notitle]);
var b=createTiddlyButton(place,label,prompt,
function(ev){return config.macros.copyTiddler.click(this,ev)});
b.setAttribute('from',title||'');
},
click: function(here,ev) {
var tiddlerElem=story.findContainingTiddler(here);
var template=tiddlerElem?tiddlerElem.getAttribute('template'):null;
var title=here.getAttribute('from');
if (!title || !title.length) {
if (!tiddlerElem) return false;
else title=tiddlerElem.getAttribute('tiddler');
}
var root=title.replace(this.suffixPattern,''); // title without suffix
// find last matching title
var last=title;
if (this.sparse) { // don't fill-in holes... really find LAST matching title
var tids=store.getTiddlers('title','excludeLists');
for (var t=0; t<tids.length; t++) if (tids[t].title.startsWith(root)) last=tids[t].title;
}
// get next number (increment from last matching title)
var n=1; var match=this.suffixPattern.exec(last); if (match) n=parseInt(match[1])+1;
var newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]);
// if not sparse mode, find the next hole to fill in...
while (store.tiddlerExists(newTitle)||document.getElementById(story.idPrefix+newTitle))
{ n++; newTitle=this.prefix+root+this.suffixText.format([String.zeroPad(n,this.zeroPad)]); }
if (!story.isDirty(title)) { // if tiddler is not being EDITED
// duplicate stored tiddler (if any)
var text=store.getTiddlerText(title,'');
var newtags=[]; var newfields={};
var tid=store.getTiddler(title); if (tid) {
for (var t=0; t<tid.tags.length; t++) newtags.push(tid.tags[t]);
store.forEachField(tid,function(t,f,v){newfields[f]=v;},true);
}
store.saveTiddler(newTitle,newTitle,text,
config.options.txtUserName,new Date(),newtags, newfields, true); // clear changecount
story.displayTiddler(tiddlerElem,newTitle,template);
} else {
story.displayTiddler(tiddlerElem,newTitle,template);
var fields=config.macros.copyTiddler.gatherFields(tiddlerElem); // get current editor fields
var newTiddlerElem=document.getElementById(story.idPrefix+newTitle);
for (var f=0; f<fields.length; f++) { // set fields in new editor
if (fields[f].name=='title') fields[f].value=newTitle; // rename title in new tiddler
var fieldElem=config.macros.copyTiddler.findField(newTiddlerElem,fields[f].name);
if (fieldElem) {
if (fieldElem.getAttribute('type')=='checkbox')
fieldElem.checked=fields[f].value;
else
fieldElem.value=fields[f].value;
}
}
}
story.focusTiddler(newTitle,'title');
return false;
},
findField: function(tiddlerElem,field) {
var inputs=tiddlerElem.getElementsByTagName('input');
for (var i=0; i<inputs.length; i++) {
if (inputs[i].getAttribute('type')=='checkbox' && inputs[i].field == field) return inputs[i];
if (inputs[i].getAttribute('type')=='text' && inputs[i].getAttribute('edit') == field) return inputs[i];
}
var tas=tiddlerElem.getElementsByTagName('textarea');
for (var i=0; i<tas.length; i++) if (tas[i].getAttribute('edit') == field) return tas[i];
var sels=tiddlerElem.getElementsByTagName('select');
for (var i=0; i<sels.length; i++) if (sels[i].getAttribute('edit') == field) return sels[i];
return null;
},
gatherFields: function(tiddlerElem) { // get field names and values from current tiddler editor
var fields=[];
// get checkboxes and edit fields
var inputs=tiddlerElem.getElementsByTagName('input');
for (var i=0; i<inputs.length; i++) {
if (inputs[i].getAttribute('type')=='checkbox')
if (inputs[i].field) fields.push({name:inputs[i].field,value:inputs[i].checked});
if (inputs[i].getAttribute('type')=='text')
if (inputs[i].getAttribute('edit')) fields.push({name:inputs[i].getAttribute('edit'),value:inputs[i].value});
}
// get textareas (multi-line edit fields)
var tas=tiddlerElem.getElementsByTagName('textarea');
for (var i=0; i<tas.length; i++)
if (tas[i].getAttribute('edit')) fields.push({name:tas[i].getAttribute('edit'),value:tas[i].value});
// get selection lists (droplist or listbox)
var sels=tiddlerElem.getElementsByTagName('select');
for (var i=0; i<sels.length; i++)
if (sels[i].getAttribute('edit')) fields.push({name:sels[i].getAttribute('edit'),value:sels[i].value});
return fields;
}
};
//}}}
/***
|Name|DeleteAllTaggedPlugin|
|Source|http://ido-xp.tiddlyspot.com/#DeleteAllTaggedPlugin|
|Version|1.0|
An adaptation of DeleteDoneTasks (Simon Baird) by Ido Magal
To use this insert {{{<<deleteAllTagged>>}}} into the desired tiddler.
/***
Example usage:
{{{<<deleteAllTagged>>}}}
<<deleteAllTagged>>
***/
//{{{
config.macros.deleteAllTagged = {
handler: function ( place,macroName,params,wikifier,paramString,tiddler ) {
var buttonTitle = "Delete Tagged w/ '"+tiddler.title+"'";
createTiddlyButton( place, buttonTitle, "Delete every tiddler tagged with '"+tiddler.title+"'", this.deleteAllTagged( tiddler.title ));
},
deleteAllTagged: function(tag) {
return function() {
var collected = [];
store.forEachTiddler( function ( title,tiddler ) {
if ( tiddler.tags.contains( tag ))
{
collected.push( title );
}
});
if ( collected.length == 0 )
{
alert( "No tiddlers found tagged with '"+tag+"'." );
}
else
{
if ( confirm( "These tiddlers are tagged with '"+tag+"'\n'"
+ collected.join( "', '" ) + "'\n\n\n"
+ "Are you sure you want to delete these?" ))
{
for ( var i=0;i<collected.length;i++ )
{
store.deleteTiddler( collected[i] );
displayMessage( "Deleted '"+collected[i]+"'" );
}
}
}
}
}
};
//}}}
The [[DisableWikiLinksList]] tiddler will disable Wikification of words listed here
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.6.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Tiddler.prototype.autoLinkWikiWords, 'wikiLink' formatter|
|Options|##Configuration|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links. To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles. You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace. This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.
Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2008.07.22 [1.6.0] hijack tiddler changed() method to filter disabled wiki words from internal links[] array (so they won't appear in the missing tiddlers list)
2007.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.DisableWikiLinksPlugin= {major: 1, minor: 6, revision: 0, date: new Date(2008,7,22)};
if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";
// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
config.formatters[i].coreHandler=config.formatters[i].handler;
config.formatters[i].handler=function(w) {
// supress any leading "~" (if present)
var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
var title=w.matchText.substr(skip);
var exists=store.tiddlerExists(title);
var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);
// check for excluded Tiddler
if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// check for specific excluded wiki words
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList);
if (t && t.length && t.indexOf(w.matchText)!=-1)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not disabling links from shadows (default setting)
if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
return this.coreHandler(w);
// check for non-existing non-shadow tiddler
if (config.options.chkDisableNonExistingWikiLinks && !exists)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not enabled, just do standard WikiWord link formatting
if (!config.options.chkDisableWikiLinks)
return this.coreHandler(w);
// just return text without linking
w.outputText(w.output,w.matchStart+skip,w.nextMatch)
}
}
Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
// if all automatic links are not disabled, just return results from core function
if (!config.options.chkDisableWikiLinks)
return this.coreAutoLinkWikiWords.apply(this,arguments);
return false;
}
Tiddler.prototype.disableWikiLinks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
this.disableWikiLinks_changed.apply(this,arguments);
// remove excluded wiki words from links array
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList,"").readBracketedList();
if (t.length) for (var i=0; i<t.length; i++)
if (this.links.contains(t[i]))
this.links.splice(this.links.indexOf(t[i]),1);
};
//}}}
{{{
<<SVG '<ellipse cx="100" cy="100" rx="90" ry="80" fill="blue" />'>>
}}}
<<SVG '<ellipse cx="100" cy="100" rx="90" ry="80" fill="blue" />'>>
/***
|Name|FileDropPlugin|
|Source|http://www.TiddlyTools.com/#FileDropPlugin|
|Version|2.1.4|
|Author|BradleyMeck and Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|drag-and-drop files/directories to create tiddlers|
''requires FireFox or another Mozilla-compatible browser.''
!!!!!Usage
<<<
This plugin automatically creates tiddlers from files that are dropped onto an open TiddlyWiki document. You can drop multiple selected files and/or folders to create many tiddlers at once. New tiddler titles are created using the filename of each dropped file (i.e., omitting the path). If a title is already in use, you are prompted to enter a new title for that file. If you drop a folder, you will be asked if you want to create a simple 'directory list' of files in a single tiddler or create one tiddler for each file in that folder.
By default, it is assumed that all dropped files contain text. However, if [[AttachFilePlugin]], [[AttachFilePluginFormatters]] and [[AttachFileMIMETypes]] are installed, then you can drop ''//binary data files//'' as well as text files. If the MIME type of a dropped file is not "text/plain", then AttachFilePlugin is used to create an 'attachment' tiddler, rather than creating a simple text tiddler.
When creating text tiddlers, you can embed a //link// to the original external file at the top of the new tiddler, in addition to (or instead of) the text content itself. The format for this link (see Configuration, below) uses embedded ''//replacement markers//'' that allow you to generate a variety of wiki-formatted output, where:
*%0 = filename (without path)
*%1 = local """file://...""" URL
*%2 = local path and filename (OS-native format)
*%3 = relative path (if subdirectory of current document directory)
*%4 = file size
*%5 = file date
*%6 = current date
*%7 = current ~TiddlyWiki username
*\n = newline
By default, the link format uses the filename (%0) and local URL (%1), enclosed within a //hidden section// syntax, like this:
{{{
/%
!link
[[%0|%1]]
!end
%/
}}}
This permits the link to be embedded along with the text content, without changing the appearance of that content when the tiddler is viewed. To display the link in your tiddler content, use:
{{{
<<tiddler TiddlerName##link>>
}}}
<<<
!!!!!Configuration
<<<
__FileDropPlugin options:__
<<option chkFileDropContent>>Copy file content into tiddlers if smaller than: <<option txtFileDropDataLimit>> bytes
//(note: excess text content will be truncated, oversized binary files will skipped, 0=no limit)//
<<option chkFileDropLink>>Generate external links to files, using this format:{{editor{<html><nowiki><textarea rows="4" onchange="
config.macros.option.propagateOption('txtFileDropLinkFormat','value',this.value.escapeLineBreaks(),'input');
"></textarea></html><<tiddler {{
var ta=place.lastChild.getElementsByTagName('textarea')[0];
var v=config.options.txtFileDropLinkFormat.unescapeLineBreaks();
ta.value=v;
"";}}>>}}}<<option chkFileDropTrimFilename>>Omit file extensions from tiddler titles
<<option chkFileDropDisplay>>Automatically display newly created tiddlers
Tag newly created tiddlers with: <<option txtFileDropTags>>
__FileDropPlugin+AttachFilePlugin options:__ //(binary file data as encoded 'base64' text)//
<<option chkFileDropAttachLocalLink>> attachment includes reference to local path/filename
>Note: if the plugin does not seem to work, enter ''about:config'' in the Firefox address bar, and make sure that {{{signed.applets.codebase_principal_support}}} is set to ''true''
<<<
!!!!!Examples (custom handler functions)
<<<
Adds a single file with confirmation and prompting for title:
{{{
config.macros.fileDrop.addEventListener('application/x-moz-file',
function(nsiFile) {
var msg='You have dropped the file:\n'
+nsiFile.path+'\n'
+'onto the page, it will be imported as a tiddler. Is that ok?'
if(confirm(msg)) {
var newDate = new Date();
var title = prompt('what would you like to name the tiddler?');
store.saveTiddler(title,title,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
}
return true;
});
}}}
Adds a single file without confirmation, using path/filename as tiddler title:
{{{
config.macros.fileDrop.addEventListener('application/x-moz-file',
function(nsiFile) {
var newDate = new Date();
store.saveTiddler(nsiFile.path,nsiFile.path,loadFile(nsiFile.path),config.options.txtUserName,newDate,[]);
story.displayTiddler(null,nsiFile.path)
return true;
});
}}}
<<<
!!!!!Revisions
<<<
2010.03.06 2.1.4 added event listener for 'dragover' (for FireFox 3.6+)
2009.10.10 2.1.3 fixed IE code error
2009.10.08 2.1.2 fixed chkFileDropContent bypass handling for binary attachments
2009.10.07 2.1.0 added chkFileDropContent and chkFileDropLink/txtFileDropLinkFormat
2009.08.19 2.0.0 fixed event listener registration for FireFox 3.5+. Also, merged with FileDropPluginConfig, with code cleanup/reduction
2008.08.11 1.5.1 added chkFileDropAttachLocalLink option to allow suppression of local path/file link
2007.xx.xx *.*.* add suspend/resume of notifications to improve performance when multiple files are handled
2007.01.01 0.9.9 extensions for AttachFilePlugin
2006.11.04 0.1.1 initial release by Bradley Meck
<<<
!!!!!Code
***/
//{{{
version.extensions.FileDropPlugin={major:2, minor:1, revision:4, date: new Date(2010,3,6)};
config.macros.fileDrop = {
customDropHandlers: [],
addEventListener: function(paramflavor,func,inFront) {
var obj={}; obj.flavor=paramflavor; obj.handler=func;
if (!inFront) this.customDropHandlers.push(obj);
else this.customDropHandlers.shift(obj);
},
dragDropHandler: function(evt) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var dragService = Components.classes['@mozilla.org/widget/dragservice;1'].getService(Components.interfaces.nsIDragService);
var dragSession = dragService.getCurrentSession();
var transferObject = Components.classes['@mozilla.org/widget/transferable;1'].createInstance();
transferObject = transferObject.QueryInterface(Components.interfaces.nsITransferable);
transferObject.addDataFlavor('application/x-moz-file');
var numItems = dragSession.numDropItems;
if (numItems>1) {
clearMessage();
displayMessage('Reading '+numItems+' files...');
store.suspendNotifications();
}
for (var i = 0; i < numItems; i++) {
dragSession.getData(transferObject, i);
var dataObj = {};
var dropSizeObj = {};
for(var ind=0; ind<config.macros.fileDrop.customDropHandlers.length; ind++) {
var item = config.macros.fileDrop.customDropHandlers[ind];
if(dragSession.isDataFlavorSupported(item.flavor)) {
transferObject.getTransferData(item.flavor, dataObj, dropSizeObj);
var droppedFile = dataObj.value.QueryInterface(Components.interfaces.nsIFile);
var result = item.handler.call(item,droppedFile);
evt.stopPropagation();
evt.preventDefault();
if (result) break;
}
}
}
if (numItems>1) {
store.resumeNotifications();
store.notifyAll();
displayMessage(numItems+' files have been processed');
}
}
}
//}}}
/***
!!!!!window event handlers
***/
//{{{
if(!window.event) {
window.addEventListener('dragdrop', // FireFox3.1-
config.macros.fileDrop.dragDropHandler, true);
window.addEventListener('drop', // FireFox3.5+
config.macros.fileDrop.dragDropHandler, true);
window.addEventListener('dragover', // FireFox3.6+
function(e){e.stopPropagation();e.preventDefault();}, true);
}
//}}}
/***
!!!!!handler for files, directories and binary attachments (see [[AttachFilePlugin]])
***/
//{{{
var defaults={
chkFileDropDisplay: true,
chkFileDropTrimFilename: false,
chkFileDropContent: true,
chkFileDropLink: true,
txtFileDropLinkFormat: '/%\\n!link\\n[[%0|%1]]\\n!end\\n%/',
txtFileDropDataLimit: '32768',
chkFileDropAttachLocalLink: true,
txtFileDropTags: ''
};
for (var id in defaults) if (config.options[id]===undefined)
config.options[id]=defaults[id];
config.macros.fileDrop.addEventListener('application/x-moz-file',function(nsiFile) {
var co=config.options; // abbrev
var header='Index of %0\n^^(as of %1)^^\n|!filename| !size | !modified |\n';
var item='|[[%0|%1]]| %2|%3|\n';
var footer='Total of %0 bytes in %1 files\n';
var now=new Date();
var files=[nsiFile];
if (nsiFile.isDirectory()) {
var folder=nsiFile.directoryEntries;
var files=[];
while (folder.hasMoreElements()) {
var f=folder.getNext().QueryInterface(Components.interfaces.nsILocalFile);
if (f instanceof Components.interfaces.nsILocalFile && !f.isDirectory()) files.push(f);
}
var msg=nsiFile.path.replace(/\\/g,'/')+'\n\n';
msg+='contains '+files.length+' files... ';
msg+='select OK to attach all files or CANCEL to create a list...';
if (!confirm(msg)) { // create a list in a tiddler
var title=nsiFile.leafName; // tiddler name is last directory name in path
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break;
title=prompt('Enter a new tiddler title',nsiFile.path.replace(/\\/g,'/'));
}
if (!title || !title.length) return true; // cancelled
var text=header.format([nsiFile.path.replace(/\\/g,'/'),now.toLocaleString()]);
var total=0;
for (var i=0; i<files.length; i++) { var f=files[i];
var name=f.leafName;
if (co.chkFileDropTrimFilename)
{ var p=name.split('.'); if (p.length>1) p.pop(); name=p.join('.'); }
var path='file:///'+f.path.replace(/\\/g,'/');
var size=f.fileSize; total+=size;
var when=new Date(f.lastModifiedTime).formatString('YYYY.0MM.0DD 0hh:0mm:0ss');
text+=item.format([name,path,size,when]);
}
text+=footer.format([total,files.length]);
var newtags=co.txtFileDropTags?co.txtFileDropTags.readBracketedList():[];
store.saveTiddler(null,title,text,co.txtUserName,now,newtags);
if (co.chkFileDropDisplay) story.displayTiddler(null,title);
return true;
}
}
if (files.length>1) store.suspendNotifications();
for (i=0; i<files.length; i++) {
var file=files[i];
if (file.isDirectory()) continue; // skip over nested directories
var type='text/plain';
var title=file.leafName; // tiddler name is file name
if (co.chkFileDropTrimFilename)
{ var p=title.split('.'); if (p.length>1) p.pop(); title=p.join('.'); }
var name=file.leafName;
var path=file.path;
var url='file:///'+path.replace(/\\/g,'/');
var size=file.fileSize;
var when=new Date(file.lastModifiedTime);
var now=new Date();
var who=config.options.txtUserName;
var h=document.location.href;
var cwd=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf('/')+1)));
var relpath=path.startsWith(cwd)?'./'+path.substr(cwd.length):path;
while (title && title.length && store.tiddlerExists(title)) {
if (confirm(config.messages.overwriteWarning.format([title]))) break;
title=prompt('Enter a new tiddler title',path.replace(/\\/g,'/'));
}
if (!title || !title.length) continue; // cancelled
if (config.macros.attach) {
type=config.macros.attach.getMIMEType(name,'');
if (!type.length)
type=prompt('Unknown file type. Enter a MIME type','text/plain');
if (!type||!type.length) continue; // cancelled
}
var newtags=co.txtFileDropTags?co.txtFileDropTags.readBracketedList():[];
if (type=='text/plain' || !co.chkFileDropContent) {
var txt=''; var fmt=co.txtFileDropLinkFormat.unescapeLineBreaks();
if (co.chkFileDropLink) txt+=fmt.format([name,url,path,relpath,size,when,now,who]);
if (co.chkFileDropContent) {
var out=loadFile(path); var lim=co.txtFileDropDataLimit;
txt+=co.txtFileDropDataLimit?out.substr(0,lim):out;
if (size>lim) txt+='\n----\nfilesize ('+size+')'
+' is larger than FileDrop limit ('+lim+')...\n'
+'additional content has been omitted';
}
store.saveTiddler(null,title,txt,co.txtUserName,now,newtags);
} else {
var embed=co.chkFileDropContent
&& (!co.txtFileDropDataLimit||size<co.txtFileDropDataLimit);
newtags.push('attachment'); newtags.push('excludeMissing');
config.macros.attach.createAttachmentTiddler(path,
now.formatString(config.macros.timeline.dateFormat),
'attached by FileDropPlugin', newtags, title,
embed, co.chkFileDropAttachLocalLink, false,
relpath, '', type,!co.chkFileDropDisplay);
}
if (co.chkFileDropDisplay) story.displayTiddler(null,title);
}
if (files.length>1) { store.resumeNotifications(); store.notifyAll(); }
return true;
})
//}}}
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* The MainMenu: Menu has been set to list (Filter) all items set with the tags <<tag author>>, <<tag story>>, <<tag draft>> or <<tag journal>>, enabling it to automatically update itself - if you have multiple chapters, if you tag the main entry with story, you can use the //copy// command in the toolbar to make the first chapter story(1). Tag it with your "Story Name" (in quotes (or {{{[[Double Brackets]]}}}if it has spaces), and each chapter will automatically be added to the story listing as you go along.
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the [[TiddlyWiki|http://www.tiddlywiki.com/]] is opened - just add the names in {{{[[double brackets]]}}} and it will automatically list them.
You'll also need to enter your username for signing your edits: <<option txtUserName>>
!Gradients do not yet work
!!!!This code works in an SVG file (in Firefox)
{{{
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0); stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0); stop-opacity:1"/>
</linearGradient>
</defs>
<ellipse cx="200" cy="190" rx="85" ry="55" style="fill:url(#orange_red)"/>
</svg>
}}}
!!!!Doesn't pull the reference and default to a fill of black
{{{
<<SVG '<defs>
<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0); stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0); stop-opacity:1"/>
</linearGradient>
</defs>
<ellipse cx="200" cy="190" rx="85" ry="55" style="fill:url(#orange_red)"/> '>>
}}}
<<SVG '<defs>
<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0); stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0); stop-opacity:1"/>
</linearGradient>
</defs>
<ellipse cx="200" cy="190" rx="85" ry="55" style="fill:url(#orange_red)"/> '>>
!This Works
{{{
<<SVG '<g id="group1" fill="green" opacity="0.9" >
<rect x="20" y="20" width="100" height="100" opacity="0.5" />
<rect x="80" y="80" width="100" height="100" fill="gray" />
</g>'>>
}}}
<<SVG '<g id="group1" fill="green" opacity="0.9" >
<rect x="20" y="20" width="100" height="100" opacity="0.5" />
<rect x="80" y="80" width="100" height="100" fill="gray" />
</g>'>>
!This does not
{{{
<<SVG '<defs>
<g id="group1" fill="green" opacity="0.9" >
<rect x="20" y="20" width="100" height="100" opacity="0.5" />
<rect x="80" y="80" width="100" height="100" fill="gray" />
</g>
</defs>
<use x="0" y="0" width="200" height="200" xlink:href="#group1" />
<use x="0" y="0" width="200" height="200" xlink:href="#group1" transform="rotate(70, 100, 100)" /> '>>
}}}
<<SVG '<defs>
<g id="group1" fill="green" opacity="0.9" >
<rect x="20" y="20" width="100" height="100" opacity="0.5" />
<rect x="80" y="80" width="100" height="100" fill="gray" />
</g>
</defs>
<use x="0" y="0" width="200" height="200" xlink:href="#group1" />
<use x="0" y="0" width="200" height="200" xlink:href="#group1" transform="rotate(70, 100, 100)" /> '>>
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{
window.hideWhenLastTest = false;
window.removeElementWhen = function(test,place) {
window.hideWhenLastTest = test;
if (test) {
removeChildren(place);
place.parentNode.removeChild(place);
}
};
merge(config.macros,{
hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( eval(paramString), place);
}},
showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !eval(paramString), place);
}},
hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAny(params), place);
}},
showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAny(params), place);
}},
hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
}},
showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
}},
hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title == params[0], place);
}},
showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title != params[0], place);
}},
'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !window.hideWhenLastTest, place);
}}
});
//}}}
/***
|''Name:''|IsDirtyPlugin|
|''Description:''|When the TiddlyWiki needs to be saved the tiddler named IsDirty contains ' * ' else it is empty. IsDirty tiddler is also appended in front of the browser page title.<br>Hint: Put it in front of your SiteTitle in your PageTemplate or in your MainMenu as an indicator.<br>For now IsDirty: <<tiddler IsDirty>>|
|''Version:''|1.0.1|
|''Date:''|Mar 20, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#IsDirtyPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.IsDirtyPlugin = {
major: 1, minor: 0, revision: 1,
date: new Date("Mar 20, 2007"),
source: 'http://tiddlywiki.bidix.info/#IsDirtyPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.setDirty = TiddlyWiki.prototype.setDirty;
bidix.initIsDirty = function()
{
var tags = "[[excludeLists]] [[excludeSearch]]";
var tiddler = store.getTiddler("IsDirty");
if (!tiddler) {
tiddler = new Tiddler("IsDirty");
//tiddler.set(title,text,modifier,modified,tags,created,fields)
tiddler.set(null,null,null,null,tags,null,null);
store.addTiddler(tiddler);
}
tiddler.set(null,"",null,null,null,null,null);
return tiddler;
};
TiddlyWiki.prototype.setDirty = function(dirty)
{
var indic = " * ";
var oldDirty = this.isDirty ();
bidix.setDirty.apply(this,arguments);
var tiddler = bidix.initIsDirty();
if (dirty)
tiddler.set(null,indic,null,null,null,null,null);
else
tiddler.set(null," ",null,null,null,null,null);
story.refreshTiddler(tiddler.title);
store.notify(tiddler.title, true);
refreshPageTitle();
};
bidix.refreshPageTitle = function()
{
document.title = wikifyPlain("IsDirty") + wikifyPlain("SiteTitle") + " - " + wikifyPlain("SiteSubtitle");
};
bidix.core.refreshPageTitle = refreshPageTitle ;
refreshPageTitle = bidix.refreshPageTitle;
bidix.initIsDirty();
//}}}
{{{
<<SVG '<line x1="10" y1="10" x2="190" y2="190" stroke="blue" stroke-width="4" />'>>
}}}
<<SVG '<line x1="10" y1="10" x2="190" y2="190" stroke="blue" stroke-width="4" />'>>
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
/***
|Name:|NewHerePlugin|
|Description:|Creates the new here and new journal macros|
|Version:|3.0 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.macros, {
newHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
},
newJournalHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
}
});
//}}}
{{{
<<SVG "<text style='fill:black; text-anchor:middle;' x='100' y='25'>Hello World!</text>
<rect x='10' y='5' width='20' height='20' fill='blue' />
<rect x='20' y='10' width='160' height='20' fill='green' opacity='0.5' />
<rect x='170' y='25' width='20' height='20' fill='blue' />">>
}}}
<<SVG "<text style='fill:black; text-anchor:middle;' x='100' y='25'>Hello World!</text>
<rect x='10' y='5' width='20' height='20' fill='blue' />
<rect x='20' y='10' width='160' height='20' fill='green' opacity='0.5' />
<rect x='170' y='25' width='20' height='20' fill='blue' />">>
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
{{{
<<SVG '<path d="M40,140 L40,100 10,100 C10,10 90,10 90,100 L60,100 60,140 M140,50 C70,180 195,180 190,100 " stroke="darkgreen" stroke-width="4" fill="url(#hill)" />'>>
}}}
<<SVG '<path d="M40,140 L40,100 10,100 C10,10 90,10 90,100 L60,100 60,140 M140,50 C70,180 195,180 190,100 " stroke="darkgreen" stroke-width="4" fill="tan" />'>>
{{{
<<SVG '<path d="M50,50 Q-30,100 50,150 100,230 150,150 230,100 150,50 100,-30 50,50" stroke="darkblue" stroke-width="4" fill="lightgreen" />'>>
}}}
<<SVG '<path d="M50,50 Q-30,100 50,150 100,230 150,150 230,100 150,50 100,-30 50,50" stroke="darkblue" stroke-width="4" fill="lightgreen" />'>>
<<SVG '<path d="M10,150 A15 15 180 0 1 70 140 A15 25 180 0 0 130 130 A15 55 180 0 1 190 120" stroke="lightgreen" stroke-width="4" fill="none" marker-mid="url(#marker2)" marker-end="url(#marker1)" />'>>
!Pattern doesn't work either - since it uses a reference, sadly no surprise
{{{
<<SVG '<defs>
<pattern id="checkerPattern" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20" viewBox="0 0 10 10">
<rect x="0" y="0" width="5" height="5" fill="lightblue"/>
<rect x="5" y="5" width="5" height="5" fill="lightblue"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#checkerPattern)"/> '>>
}}}
<<SVG '<defs>
<pattern id="checkerPattern" patternUnits="userSpaceOnUse" x="0" y="0" width="20" height="20" viewBox="0 0 10 10">
<rect x="0" y="0" width="5" height="5" fill="lightblue"/>
<rect x="5" y="5" width="5" height="5" fill="lightblue"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#checkerPattern)"/> '>>
{{{
<<SVG '<polygon points="100,10 40,180 190,60 10,60 160,180 100,10" stroke="blue" fill="darkblue" stroke-width="4" fill-rule="nonzero" />'>>
}}}
<<SVG '<polygon points="100,10 40,180 190,60 10,60 160,180 100,10" stroke="blue" fill="darkblue" stroke-width="4" fill-rule="nonzero" />'>>
{{{
<<SVG '<polyline points="10,190 20,190 20,150 50,150 50,190 80,190 80,110 110,110 110,190 140,190 140,70 170,70 170,190 190,190" stroke="blue" fill="darkblue" stroke-width="4" />'>>
}}}
<<SVG '<polyline points="10,190 20,190 20,150 50,150 50,190 80,190 80,110 110,110 110,190 140,190 140,70 170,70 170,190 190,190" stroke="blue" fill="darkblue" stroke-width="4" />'>>
Contact: Pug ugly 001 at gmail com
/***
|Name:|QuickOpenTagPlugin|
|Description:|Changes tag links to make it easier to open tags as tiddlers|
|Version:|3.0.1 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
config.quickOpenTag = {
dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE?
createTagButton: function(place,tag,excludeTiddler) {
// little hack so we can do this: <<tag PrettyTagName|RealTagName>>
var splitTag = tag.split("|");
var pretty = tag;
if (splitTag.length == 2) {
tag = splitTag[1];
pretty = splitTag[0];
}
var sp = createTiddlyElement(place,"span",null,"quickopentag");
createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
config.views.wikified.tag.tooltip.format([tag]),onClickTag);
theTag.setAttribute("tag",tag);
if (excludeTiddler)
theTag.setAttribute("tiddler",excludeTiddler);
return(theTag);
},
miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {
var tagged = store.getTaggedTiddlers(tiddler.title);
if (tagged.length > 0) {
var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,
config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);
theTag.setAttribute("tag",tiddler.title);
theTag.className = "miniTag";
}
},
allTagsHandler: function(place,macroName,params) {
var tags = store.getTags(params[0]);
var filter = params[1]; // new feature
var ul = createTiddlyElement(place,"ul");
if(tags.length == 0)
createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
for(var t=0; t<tags.length; t++) {
var title = tags[t][0];
if (!filter || (title.match(new RegExp('^'+filter)))) {
var info = getTiddlyLinkInfo(title);
var theListItem =createTiddlyElement(ul,"li");
var theLink = createTiddlyLink(theListItem,tags[t][0],true);
var theCount = " (" + tags[t][1] + ")";
theLink.appendChild(document.createTextNode(theCount));
var theDropDownBtn = createTiddlyButton(theListItem," " +
config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);
theDropDownBtn.setAttribute("tag",tags[t][0]);
}
}
},
// todo fix these up a bit
styles: [
"/*{{{*/",
"/* created by QuickOpenTagPlugin */",
".tagglyTagged .quickopentag, .tagged .quickopentag ",
" { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }",
".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }",
".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}",
"/* extra specificity to make it work right */",
"#displayArea .viewer .quickopentag a.button, ",
"#displayArea .viewer .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink ",
" { border:0px solid black; }",
"#displayArea .viewer .quickopentag a.button, ",
"#mainMenu .quickopentag a.button ",
" { margin-left:0px; padding-left:2px; }",
"#displayArea .viewer .quickopentag a.tiddlyLink, ",
"#mainMenu .quickopentag a.tiddlyLink ",
" { margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }",
"a.miniTag {font-size:150%;} ",
"#mainMenu .quickopentag a.button ",
" /* looks better in right justified main menus */",
" { margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }",
"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }",
"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }",
"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }",
"/*}}}*/",
""].join("\n"),
init: function() {
// we fully replace these builtins. can't hijack them easily
window.createTagButton = this.createTagButton;
config.macros.allTags.handler = this.allTagsHandler;
config.macros.miniTag = { handler: this.miniTagHandler };
config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;
store.addNotification("QuickOpenTagStyles",refreshStyles);
}
}
config.quickOpenTag.init();
//}}}
{{{
<<SVG "<rect x='20' y='20' rx='0' ry='0' width='160' height='160' fill='blue' />">>
}}}
<<SVG "<rect x='20' y='20' rx='0' ry='0' width='160' height='160' fill='blue' />">>
/***
|Name:|RenameTagsPlugin|
|Description:|Allows you to easily rename or delete tags across multiple tiddlers|
|Version:|3.0 ($Rev: 5501 $)|
|Date:|$Date: 2008-06-10 23:11:55 +1000 (Tue, 10 Jun 2008) $|
|Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {
prompts: {
rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
remove: "Remove the tag '%0' from %1 tidder%2?"
},
removeTag: function(tag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,tag);
}
store.resumeNotifications();
store.notifyAll();
},
renameTag: function(oldTag,newTag,tiddlers) {
store.suspendNotifications();
for (var i=0;i<tiddlers.length;i++) {
store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
store.setTiddlerTag(tiddlers[i].title,true,newTag); // add new
}
store.resumeNotifications();
store.notifyAll();
},
storeMethods: {
saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,
saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
if (title != newTitle) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0) {
// then we are renaming a tag
if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
config.renameTags.renameTag(title,newTitle,tagged);
if (!this.tiddlerExists(title) && newBody == "")
// dont create unwanted tiddler
return null;
}
}
return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created);
},
removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,
removeTiddler: function(title) {
var tagged = this.getTaggedTiddlers(title);
if (tagged.length > 0)
if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
config.renameTags.removeTag(title,tagged);
return this.removeTiddler_orig_renameTags(title);
}
},
init: function() {
merge(TiddlyWiki.prototype,this.storeMethods);
}
}
config.renameTags.init();
//}}}
/***
|''Name:''|SamplePlugin|
|''Description:''|My Description|
|''Author:''|My Name|
|''Source:''|http://tiddlywiki.org/wiki/Plugin_specs#Template |
|''~CodeRepository:''|http://trac.tiddlywiki.org/browser/Trunk/contributors/MartinBudden/plugins/ExamplePlugin.js |
|''Version:''|0.0.1|
|''Status:''|Not for release - this is a template for creating new plugins|
|''Date:''|Jan 25, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.3|
To make this example into a real TiddlyWiki plugin, you need to:
# Globally search and replace SamplePlugin with the name of your plugin
# Globally search and replace example with the name of your macro
# Update the header text above with your description, name etc
# Do the actions indicated by the !!TODO comments, namely:
## Write the code for the plugin
## Write the documentation for the plugin
!!Description
//!!TODO write a brief description of the plugin here
!!Usage
//!!TODO describe how to use the plugin - how a user should include it in their TiddlyWiki, parameters to the plugin etc
***/
//{{{
//# Ensure that the plugin is only installed once.
if(!version.extensions.SamplePlugin) {
version.extensions.SamplePlugin = {installed:true};
config.macros.example = {};
config.macros.example.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
//!!TODO write the code for the macro here
};
} //# end of 'install only once'
//}}}
/***
|Name|SaveAsPlugin|
|Source|http://www.TiddlyTools.com/#SaveAsPlugin|
|Documentation|http://www.TiddlyTools.com/#SaveAsPluginInfo|
|Version|2.4.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Save current document to a different path/filename|
This plugin automatically adds a 'save as' command to the TiddlyWiki 'backstage' menu that allows you to quickly create an exact copy of the current TiddlyWiki document. The plugin also defines a macro that you can use to place a "save as..." command link into your sidebar/mainmenu/any tiddler (or wherever you like).
>//Note: This plugin now supersedes [[NewDocumentPlugin]], which has been retired and is no longer being distributed. In addition, the HTML+CSS "snapshot" functionality previous provided by that plugin has been moved to a separate plugin. Please see [[SnapshotPlugin]] for additional information.//
!!!!!Documentation
<<<
see [[SaveAsPluginInfo]]
<<<
!!!!!Revisions
<<<
2008.09.29 [2.4.3] in getData(), convert existing TW file from UTF8 to Unicode before merging to correct handling of international characters and symbols.
| Please see [[SaveAsPluginInfo]] for additional revision details |
2006.02.03 [1.0.0] Created.
<<<
!!!!!Code
***/
//{{{
version.extensions.SaveAsPlugin= {major: 2, minor: 4, revision: 2, date: new Date(2008,9,28)};
config.macros.saveAs = {
label: "save as...",
labelparam: "label:",
prompt: "Save current document to a different path/file",
promptparam: "prompt:",
filePrompt: "Please select or enter a target path/filename",
targetparam: "target:",
defaultFilename: "new.html",
filenameparam: "filename:",
currfilekeyword: "here",
typeparam: "type:",
type_TW: "tw", type_PS: "ps", type_TX: "tx", type_NF: "nf", // file type tokens
type_map: { // map filetype param alternatives/abbreviations to token values
tiddlywiki:"tw", tw:"tw", wiki: "tw",
purestore: "ps", ps:"ps", store:"ps",
plaintext: "tx", tx:"tx", text: "tx",
newsfeed: "nf", nf:"nf", xml: "nf", rss:"nf"
},
replaceparam: "replace",
mergeparam: "merge",
quietparam: "quiet",
openparam: "open",
askParam: "ask",
askMsg: "Enter a tag filter (use * for all tiddlers, 'none' for blank document)",
emptyParam: "none",
confirmmsg: "Found %0 tiddlers matching\n\n'%1'\n\nPress OK to proceed",
mergeprompt: "%0\nalready contains tiddler definitions.\n"
+"\nPress OK to add new/revised tiddlers to current file contents."
+"\nPress Cancel to completely replace file contents",
mergestatus: "Merged %0 new/revised tiddlers and %1 existing tiddlers",
okmsg: "%0 tiddlers written to %1",
failmsg: "An error occurred while creating %1",
filter: "",
handler: function(place,macroName,params) {
if (params[0] && params[0].substr(0,this.labelparam.length)==this.labelparam)
var label=params.shift().substr(this.labelparam.length);
if (params[0] && params[0].substr(0,this.promptparam.length)==this.promptparam)
var prompt=params.shift().substr(this.promptparam.length);
if (params[0] && params[0].substr(0,this.targetparam.length)==this.targetparam)
var target=params.shift().substr(this.targetparam.length);
if (params[0] && params[0].substr(0,this.filenameparam.length)==this.filenameparam)
var filename=params.shift().substr(this.filenameparam.length);
if (params[0] && params[0].substr(0,this.typeparam.length)==this.typeparam)
var filetype=this.type_map[params.shift().substr(this.typeparam.length).toLowerCase()];
var q=(params[0] && params[0]==this.quietparam); if (q) params.shift();
var o=(params[0] && params[0]==this.replaceparam); if (o) params.shift();
var m=(params[0] && params[0]==this.mergeparam); if (m) params.shift();
var a=(params[0] && params[0]==this.openparam); if (a) params.shift();
var btn=createTiddlyButton(place,label||this.label,prompt||this.prompt,
function(){config.macros.saveAs.go(
this.getAttribute('target'),
this.getAttribute('filename'),
this.getAttribute('filetype'),
this.getAttribute('filter'),
this.getAttribute('quiet')=="true",
this.getAttribute('overwrite')=="true",
this.getAttribute('merge')=="true",
this.getAttribute('autoopen')=="true"); return false;}
);
if (target) btn.setAttribute("target",target);
if (filename) btn.setAttribute("filename",filename);
btn.setAttribute("filetype",filetype||this.type_TW);
btn.setAttribute("filter",params.join(" "));
btn.setAttribute("quiet",q?"true":"false");
btn.setAttribute("overwrite",o?"true":"false");
btn.setAttribute("merge",m?"true":"false");
btn.setAttribute("autoopen",a?"true":"false");
},
go: function(target,filename,filetype,filter,quiet,overwrite,merge,autoopen) {
var cm=config.messages; // abbreviation
var cms=config.macros.saveAs; // abbreviation
if (window.location.protocol!="file:") // make sure we are local
{ displayMessage(cm.notFileUrlError); return; }
// get tidders, confirm filtered results
var tids=cms.selectTiddlers(filter);
if (tids===false) return; // cancelled by user
if (cms.filter!=cms.emptyParam && cms.filter.length && !quiet)
if (!confirm(cms.confirmmsg.format([tids.length,cms.filter]))) return;
// get target path/filename
if (!filetype) filetype=this.type_TW;
target=target||cms.getTarget(filename,filetype==this.type_TX?'txt':'html');
if (!target) return; // cancelled by user
var link="file:///"+target.replace(/\\/g,'/');
var samefile=link==decodeURIComponent(window.location.href);
var p=getLocalPath(document.location.href);
if (samefile) {
if (config.options.chkSaveBackups) { var t=loadOriginal(p);if(t)saveBackup(p,t); }
if (config.options.chkGenerateAnRssFeed && saveRss instanceof Function) saveRss(p);
}
var notes="";
var total={val:0};
var out=this.assembleFile(target,filetype,tids,notes,quiet,overwrite,merge,total);
var ok=saveFile(target,out);
if (ok && autoopen) {
if (!samefile) window.open(link).focus();
else { store.setDirty(false); window.location.reload(); }
}
if (!quiet || !(ok && autoopen))
displayMessage((ok?this.okmsg:this.failmsg).format([total.val,target]),link);
},
selectTiddlers: function(filter) {
var cms=config.macros.saveAs; // abbreviation
cms.filter=filter||"";
if (filter==cms.emptyParam) return [];
if (!filter||!filter.length) return store.getTiddlers("title");
// get filtered tiddlers
if (filter==config.macros.saveAs.askParam) {
filter=prompt(config.macros.saveAs.askMsg,"");
if (!filter) return false; // cancelled by user
cms.filter=filter=="*"?"":filter;
if (filter=="*") return store.getTiddlers("title");
}
return store.filterTiddlers("[tag["+filter+"]]");
},
getTarget: function(defName,defExt) {
var cms=config.macros.saveAs; // abbreviation
// get new target path/filename
var newPath=getLocalPath(window.location.href);
var slashpos=newPath.lastIndexOf("/"); if (slashpos==-1) slashpos=newPath.lastIndexOf("\\");
if (slashpos!=-1) newPath=newPath.substr(0,slashpos+1); // trim filename
if (!defName||!defName.length) { // use current filename as default
var p=getLocalPath(window.location.href);
var s=p.lastIndexOf("/"); if (s==-1) s=p.lastIndexOf("\\");
if (s!=-1) defName=p.substr(s+1);
}
var defFilename=(defName||cms.defaultFilename).replace(/.html$/,'.'+defExt);
var target=cms.askForFilename(cms.filePrompt,newPath,defFilename,defExt);
if (!target) return; // cancelled by user
// if specified file does not include a path, assemble fully qualified path and filename
var slashpos=target.lastIndexOf("/"); if (slashpos==-1) slashpos=target.lastIndexOf("\\");
if (slashpos==-1) target=target+(defName||cms.defaultFilename).replace(/.html$/,'.'+defExt);
return target;
},
askForFilename: function(msg,path,file,defExt) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension=defExt||'html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP/Vista only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=(defExt=='txt')?2:3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
},
plainTextHeader:
'// Source'+':\n//\t%0\n'
+'// Title:\n//\t%1\n'
+'// Subtitle:\n//\t%2\n'
+'// Created:\n//\t%3 by %4\n'
+'// Application:\n//\tTiddlyWiki %5 / %6 %7\n',
plainTextTiddler:
'\n// ----- %0 (by %1 on %2) -----\n\n%3',
plainTextFooter:
'',
newsFeedHeader:
'<'+'?xml version="1.0"?'+'>\n'
+'<rss version="2.0">\n'
+'<channel>\n'
+'<title>%1</title>\n'
+'<link>%0</link>\n'
+'<description>%2</description>\n'
+'<language>en-us</language>\n'
+'<copyright>Copyright '+(new Date().getFullYear())+' %4</copyright>\n'
+'<pubDate>%3</pubDate>\n'
+'<lastBuildDate>%3</lastBuildDate>\n'
+'<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n'
+'<generator>TiddlyWiki %5 / %6 %7</generator>\n',
newsFeedTiddler:
'\n%0\n',
newsFeedFooter:
'</channel></rss>',
pureStoreHeader:
'<html><body>'
+'<style type="text/css">'
+' #storeArea {display:block;margin:1em;}'
+' #storeArea div {padding:0.5em;margin:1em;border:2px solid black;height:10em;overflow:auto;}'
+' #pureStoreHeading {width:100%;text-align:left;background-color:#eeeeee;padding:1em;}'
+'</style>'
+'<div id="pureStoreHeading">'
+' TiddlyWiki "PureStore" export file<br>'
+' Source'+': <b>%0</b><br>'
+' Title: <b>%1</b><br>'
+' Subtitle: <b>%2</b><br>'
+' Created: <b>%3</b> by <b>%4</b><br>'
+' TiddlyWiki %5 / %6 %7<br>'
+' Notes:<hr><pre>%8</pre>'
+'</div>'
+'<div id="storeArea">',
pureStoreTiddler:
'%0\n%1',
pureStoreFooter:
'</div><!--POST-BODY-START-->\n<!--POST-BODY-END--></body></html>',
assembleFile: function(target,filetype,tids,notes,quiet,overwrite,merge,total) {
var revised="";
var now = new Date().toLocaleString();
var src=convertUnicodeToUTF8(document.location.href);
var title = convertUnicodeToUTF8(wikifyPlain("SiteTitle").htmlEncode());
var subtitle = convertUnicodeToUTF8(wikifyPlain("SiteSubtitle").htmlEncode());
var user = convertUnicodeToUTF8(config.options.txtUserName.htmlEncode());
var twver = version.major+"."+version.minor+"."+version.revision;
var v=version.extensions.SaveAsPlugin; var pver = v.major+"."+v.minor+"."+v.revision;
var headerargs=[src,title,subtitle,now,user,twver,"SaveAsPlugin",pver,notes];
switch (filetype) {
case this.type_TX: // plain text
var header=this.plainTextHeader.format(headerargs);
var footer=this.plainTextFooter;
break;
case this.type_NF: // news feed (XML)
headerargs[0]=store.getTiddlerText("SiteUrl","");
var header=this.newsFeedHeader.format(headerargs);
var footer=this.newsFeedFooter;
break;
case this.type_PS: // PureStore (no code)
var header=this.pureStoreHeader.format(headerargs);
var footer=this.pureStoreFooter;
break;
case this.type_TW: // full TiddlyWiki
default:
var currPath=getLocalPath(window.location.href);
var original=loadFile(currPath);
if (!original) { alert(config.messages.cantSaveError); return; }
var posDiv = locateStoreArea(original);
if (!posDiv) { alert(config.messages.invalidFileError.format([currPath])); return; }
var header = original.substr(0,posDiv[0]+startSaveArea.length)+"\n";
var footer = "\n"+original.substr(posDiv[1]);
break;
}
var out=this.getData(target,filetype,tids,quiet,overwrite,merge);
var revised = header+convertUnicodeToUTF8(out.join("\n"))+footer;
// if full TW, insert page title and language attr, and reset MARKUP blocks as needed...
if (filetype==this.type_TW) {
var newSiteTitle=convertUnicodeToUTF8(getPageTitle()).htmlEncode();
revised=revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised=updateLanguageAttribute(revised);
var titles=[]; for (var i=0; i<tids.length; i++) titles.push(tids[i].title);
revised=updateMarkupBlock(revised,"PRE-HEAD",
titles.contains("MarkupPreHead")? "MarkupPreHead" :null);
revised=updateMarkupBlock(revised,"POST-HEAD",
titles.contains("MarkupPostHead")?"MarkupPostHead":null);
revised=updateMarkupBlock(revised,"PRE-BODY",
titles.contains("MarkupPreBody")? "MarkupPreBody" :null);
revised=updateMarkupBlock(revised,"POST-SCRIPT",
titles.contains("MarkupPostBody")?"MarkupPostBody":null);
}
total.val=out.length;
return revised;
},
formatItem: function(s,f,t,u) {
if (f==this.type_TW) var r=s.getSaver().externalizeTiddler(s,t);
if (f==this.type_PS) var r=this.pureStoreTiddler.format([t.title,s.getSaver().externalizeTiddler(s,t)]);
if (f==this.type_NF) var r=this.newsFeedTiddler.format([t.saveToRss(u)]);
if (f==this.type_TX) var r=this.plainTextTiddler.format([t.title,t.modifier,t.modified.toLocaleString(),t.text]);
return r||"";
},
getData: function(target,filetype,tids,quiet,overwrite,merge) {
// output selected tiddlers and gather list of titles (for use with merge)
var out=[]; var titles=[];
var url=store.getTiddlerText("SiteUrl","");
for (var i=0; i<tids.length; i++) {
out.push(this.formatItem(store,filetype,tids[i],url));
titles.push(tids[i].title);
}
// if TW or PureStore format, ask to merge with existing tiddlers (if any)
if (filetype==this.type_TW || filetype==this.type_PS) {
if (overwrite) return out; // skip merge... forced overwrite
var text=loadFile(target);
if (text && text.length) {
var remoteStore=new TiddlyWiki();
if (remoteStore.importTiddlyWiki(convertUTF8ToUnicode(text))
&& (merge||confirm(this.mergeprompt.format([target])))) {
var existing=remoteStore.getTiddlers("title");
for (var i=0; i<existing.length; i++)
if (!titles.contains(existing[i].title))
out.push(this.formatItem(remoteStore,filetype,existing[i],url));
if (!quiet) displayMessage(this.mergestatus.format([tids.length,out.length-tids.length]));
}
}
}
return out;
}
};
//}}}
//{{{
// automatically add saveAs to backstage
config.tasks.saveAs = {
text: "saveAs",
tooltip: config.macros.saveAs.prompt,
action: function(){ clearMessage(); config.macros.saveAs.go(); }
}
config.backstageTasks.splice(config.backstageTasks.indexOf("save")+1,0,"saveAs");
//}}}
/***
|Name:|SaveCloseTiddlerPlugin|
|Description:|Provides two extra toolbar commands, saveCloseTiddler and cancelCloseTiddler|
|Version:|3.0 ($Rev: 5502 $)|
|Date:|$Date: 2008-06-10 23:31:39 +1000 (Tue, 10 Jun 2008) $|
|Source:|http://mptw.tiddlyspot.com/#SaveCloseTiddlerPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
To use these you must add them to the tool bar in your EditTemplate
***/
//{{{
merge(config.commands,{
saveCloseTiddler: {
text: 'done/close',
tooltip: 'Save changes to this tiddler and close it',
handler: function(ev,src,title) {
var closeTitle = title;
var newTitle = story.saveTiddler(title,ev.shiftKey);
if (newTitle)
closeTitle = newTitle;
return config.commands.closeTiddler.handler(ev,src,closeTitle);
}
},
cancelCloseTiddler: {
text: 'cancel/close',
tooltip: 'Undo changes to this tiddler and close it',
handler: function(ev,src,title) {
// the same as closeTiddler now actually
return config.commands.closeTiddler.handler(ev,src,title);
}
}
});
//}}}
/***
|Name|SetUserNamePlugin|
|Source|http://www.TiddlyTools.com/#SetUserNamePlugin|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|prompt for TiddlyWiki username|
!!!!!Usage
<<<
{{{
<<setUserName force>>
}}}
This macro prompts for a new username if the default username ("YourName") is currently set. Use optional 'force' keyword to trigger a prompt even if username has already been set.
If you are using the default (shadow) EditTemplate definition, it will be updated to invoke this macro, via the following template syntax:
{{{
<span macro='setUserName'></span>
}}}
so that whenever a user attempts to edit/create a tiddler AND have not yet entered a username, they will be automatically prompted to enter a new username. If you are using a customized EditTemplate, you will need to edit it yourself to add the above.
<<<
!!!!!Revisions
<<<
2006.12.01 [1.0.0] initial release - converted from SetUserName inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.SetUserNamePlugin= {major: 1, minor: 0, revision: 0, date: new Date(2006,12,1)};
config.macros.setUserName = {
msg: "Please set your username",
handler: function(place,macroName,params) {
// only prompt when needed or forced
var force=params[0]&¶ms[0].toLowerCase()=="force";
if (!force && (readOnly || config.options.txtUserName!="YourName")) return;
var opt="txtUserName";
var who=prompt(this.msg,config.options[opt]);
if (!who||!who.trim().length) return; // cancelled by user
config.options[opt]=who;
saveOptionCookie(opt);
config.macros.option.propagateOption(opt,"value",config.options[opt],"input");
}
}
// add trigger to default shadow EditTemplate (custom templates: add this by hand)
config.shadowTiddlers.EditTemplate+="<span macro='setUserName'></span>";
//}}}
/%
|Name|SplitTiddler|
|Source|http://www.TiddlyTools.com/#SplitTiddler|
|Version|1.9.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|html|
|Description|split tiddler contents into separate tiddlers|
%/<html><nowiki><style>
#tiddlerSplitTiddler .tagged { display:none; }
#tiddlerSplitTiddler .label { font-size:90%;font-style:italic;white-space:nowrap; }
#tiddlerSplitTiddler table, #tiddlerSplitTiddler tr, #tiddlerSplitTiddler td
{ border:0; margin:0; padding:0; }
</style><table><tr><td><form>
<table style='width:100%'><tr><td style='width:25%'>
<div class='label'>source tiddler:</div>
<select name='src' value='' style='width:99%;padding:2px;margin:0'
title='select a tiddler containing source material'>
<option value=''>select a tiddler...</option>
</select>
</td><td style='width:25%'>
<div class='label'>target title format:</div>
<input name='titleformat' value='%0 - %1' style='width:99%'
title='format for target tiddler titles'>
</td><td style='width:25%'>
<div class='label'>output format:</div>
<input name='format' value='%4' style='width:99%'
title='format for target tiddler content'>
</td><td style='width:25%'>
<div class='label'>add tags:</div>
<input name='tags' value='' style='width:99%'
title='tags for target tiddlers'>
</td></tr></table>
<div style='font-size:80%;font-style:italic;text-align:center;color:gray'>
%0=source title, %1=first line of item, %2=first word of item, %3=item number, %4=item content
</div>
<div style='float:left;margin-right:1em'>
<div class='label'>split source content by:</div>
<div style='line-height:2.1em'>
<input type='radio' name='splitby' value='charcount'>every
<input name='charcount' value='1000' onfocus='this.select()' style='width:3em'
title='split content every N characters'> characters<br>
<input type='radio' name='splitby' value='linecount'>every
<input name='linecount' value='20' onfocus='this.select()' style='width:3em'
title='split content every N lines'> lines<br>
<input type='radio' name='splitby' value='match' CHECKED>match
<input name='sep' value='\n----\n' onfocus='this.select()' style='width:8em'
title='match character sequence to split content'><br>
<input type='checkbox' name='regexp' title='match using regular expressions (text patterns)'>use RegExp text pattern<br>
</div></div>
<div style='float:left;margin-right:1em'>
<div class='label'>options:</div>
<input type='checkbox' name='warn' checked>confirm overwrites<br>
<input type='checkbox' name='show'>show tiddlers when done<br>
<input type='checkbox' name='limit'>create only
<input name='maxtids' value='8' style='width:2em'> tiddlers<br>
<input type='checkbox' name='index' checked>create an index tiddler<br>
index item format:
<input name='indexformat' value='<<tiddler [[%0 - %1]]>>' style='width:10em'
title='%0=target tiddler title'>
</div>
<input type='button' style='float:right;height:5em;margin-top:2.5em' value='split tiddler' onclick="
var f=this.form;
if (!f.src.value.length)
{ alert('select a tiddler title'); f.src.focus(); return false; }
if (!f.titleformat.value.length)
{ alert('enter a target title format'); f.titleformat.focus(); return false; }
if (!f.src.value.length)
{ alert('enter an output item format'); f.format.focus(); return false; }
var start=new Date().getTime();
var src=store.getTiddlerText(f.src.value);
if (!src) { displayMessage('\x27'+f.src.value+'\x27 not found'); return false; }
var tags=f.tags.value;
var parts=[];
if (f.splitby[0].checked) { /* chars */
for (var i=0; i<src.length; i+=f.charcount.value)
parts.push(src.substr(i,f.charcount.value));
} else if (f.splitby[1].checked) { /* lines */
var lines=src.split('\n');
var t=''; var c=f.linecount.value;
while (lines.length) {
t+=lines.shift()+'\n'; c--;
if (!c) { parts.push(t); var c=f.linecount.value; t=''; }
}
} else { /* match text/regexp */
var sep=!f.regexp.checked?f.sep.value.unescapeLineBreaks():new RegExp(f.sep.value);
var pieces=src.split(sep);
for (var i=0; i<pieces.length; i++) if (pieces[i].length) parts.push(pieces[i]);
}
var msg='Found '+parts.length+' items in \x27'+f.src.value+'\x27. OK to proceed?';
if (!confirm(msg)) return false;
if (parts.length) store.suspendNotifications();
var pad=parts.length.toString().length;
var tids=[]; var out=[];
var srctitle=f.src.value;
var fmt=f.format.value.unescapeLineBreaks();
var titlefmt=f.titleformat.value.unescapeLineBreaks();
var indexfmt=f.indexformat.value.unescapeLineBreaks();
var max=f.limit.checked?f.maxtids.value:parts.length;
var warn=f.warn.checked;
for (var p=0; p<max; p++) {
var lines=parts[p].split('\n');
var firstline=lines[0];
var firstword=firstline.split(' ')[0];
var itemnum=String.zeroPad(p+1,pad);
if (titlefmt.indexOf('%2')!=-1) /* remove firstword if used in title */
{ var words=lines[0].split(' '); words.shift(); lines[0]=words.join(' '); var discard=!words.length; }
if (titlefmt.indexOf('%1')!=-1 || discard) /* remove firstline if used in title */
lines.shift();
var content=lines.join('\n');
var args=[srctitle,firstline,firstword,itemnum,content];
var tid=titlefmt.format(args).replace(/[\[\]\|]/g,'_');
var txt=fmt.format(args);
var tags=tags.format(args);
if (warn && store.tiddlerExists(tid) && !confirm(config.messages.overwriteWarning.format([tid]))) continue;
store.saveTiddler(tid,tid,txt,config.options.txtUserName,new Date(),tags,{});
if (f.index.checked) out.push(indexfmt.format(args));
tids.pushUnique(tid);
}
var elapsed=(new Date().getTime()-start)/1000;
if (parts.length) store.resumeNotifications();
if (tids.length) {
if (f.index.checked) {
var tid=f.src.value+'Index';
if (!warn||!store.tiddlerExists(tid)||confirm(config.messages.overwriteWarning.format([tid])))
store.saveTiddler(tid,tid,out.join('\n'),config.options.txtUserName,new Date(),[],{});
}
store.notifyAll();
if (f.show.checked) story.displayTiddlers(story.findContainingTiddler(this),tids);
displayMessage('created '+tids.length+' target tiddlers in '+elapsed+' seconds');
}
"><div style='clear:both'></div>
</form></td></tr></table></html><<tiddler {{
var list=place.lastChild.getElementsByTagName('form')[0].src;
store.forEachTiddler(function(title,tiddler){
list.options[list.length]=new Option(title,title);
});
'';}}>>
<<tiddler [[Chapter Heading]]>>
Hello - It is <<today>>.
!Mission Statement:
This ~TiddlyWiki is intended to be a [[downloadable template|http://storywiki.tiddlyspot.com/download]] for use by writers in general, and fiction writers more specifically, with options to use it to archive stories by others as well, or be used with minimal modifications for manuals, FAQ sheets, and similar navigable texts.
<<slider chkSliderWelcomeToTiddlyspot WelcomeToTiddlyspot "Welcome to TiddlySpot »" "The TiddlySpot Welcome Page">>
<<slider chkSliderStoryWikiWhy StoryWikiWhy "Why TiddlyWiki? »" "What's wrong with the way we share stories now?">>
<<slider chkSliderStoryWikiHelpFiles StoryWikiHelpFiles "Helpfiles »" "Help on formatting and modifying this file wrong with the way we share stories now?">>
<<slider chkSliderStoryWikiDailyUse StoryWikiDailyUse "Daily Use »" "General Info on Initial setup and daily use">>
<<slider chkSliderGettingStarted GettingStarted "Getting Started »" "The basic TiddlyWiki Initial Setupinfo">>
<<slider chkSliderStoryWikiSecurity StoryWikiSecurity "Security »" "How to lock or encrypt my story?">>
<<slider chkSliderStoryWikiInternals StoryWikiInternals "Internals »" "General Internals and Plugin Info">>
I have divided the Helpfiles into two (Three including these notes) broad categories, tagged and signed accordingly, <<tag TiddlyWikiHelp>> (Under the //Indices// panel), basic references for formatting ~TiddlyWiki articles, and <<tag TiddlyWikiAdmin>>(Under the //Admin Tabs// Panel), which are additional resources for how to modify ~TiddlyWiki behind the scenes. These Introductory Remarks will all be collated under the //<<tag StoryWiki>>// tag, and may be deleted or merely unlinked and left under the <<tag TiddlyWikiHelp>> tags as desired.
!!!! Other Tiddly Wiki Help Files
|!Editing Help |! ~TiddlyWiki Internals |! Introductory Info |
|<<list filter [tag[TiddlyWikiHelp]]>> |<<list filter [tag[TiddlyWikiAdmin]]>> |<<list filter [tag[StoryWiki]]>> |
To prevent confusion, <<tag TiddlyWikiPlugins>>, internal <<tag TiddlyWikiHelp>> entries, and several special system tags have been excluded from searches and lists -- They are available under the Admin Tabs Slider on the right hand column, and virtually this entire scheme can be optimized however you like from those settings.
Plugins in particular are collated under the <<tag TiddlyWikiPlugins>> subtag of <<tag TiddlyWikiAdmin>>.
I have endeavored to add only plugins that are useful for writing stories, and keeping them to whatever level of privacy you feel comfortable with, plus those required to operate on ~TiddlySpot. I am keeping an eye out for plugins that resolve certain specific limitations (I am particularly looking for one that allows XML in general, or SVG specifically.).
If you will not be adding information today, you might want to use [[Read Only Mode|#readOnly:yes]] to be extra safe. Otherwise, as noted in [[GettingStarted]], adding a username insures your entries are signed. You can do this manually, or if you so desire you can edit the plugin [[AdvancedOptionsHardcode]] (Already Active in this Wiki) to match your pen name - you will need to reload for the Wiki to reload the cookie before the change will activate.
There are two ways of stopping the built in editor, either [[ToolbarCommandsLock]] (Which hides the editor but still allows importing and saving plugins - including of course, the Toolbar) or the more permanent [[AdvancedOptionsreadOnly]] plugin (Which actually removes the ability to save changes). Neither will prevent someone from editing the underlying text file, but will protect from the average user.
If you need more advanced security, The TiddlerEncryptionPlugin can encrypt your entries with an [[SHA-1|http://en.wikipedia.org/wiki/SHA-1]] encryption scheme, rendering possession of the text file without the decryption passwords safe against any likely attempts to decrypt. //However any attempt to edit the entry ''before'' you decrypt it is quite likely to render the data irrecoverable.//
!!Why
First and foremost, because I was using ~TiddlyWiki to solve some problems at work, and think it is very useful and modifiable. Additionally, text-based files online tend to have numerous failings, and I believe ~TiddlyWiki occupies a golden mean between them.
!!!!Text files
* Pros
** They are are of course nigh universal - transferable across systems with ease, with no concerns about who receives them.
** They are the definition of simple.
* Cons
** They are also very limited, with no formatting options beyond the use of *Biff* *Bang*, and other ascii/unicode cheats.
** They have no options to be navigable.
** Pictures are of course, right out.
!!!!HTML
*Pros
** Nearly as universal as text.
** Powerful formatting capabilities.
** Navigation
** Well, almost anything you want to do.
*Cons
** Ever edit source code? For anything beyond the simplest HTML, you are either locked into //some// form of WYSIWYG editor, or have to acquire a fairly intensive skillset. With the additional of CSS and XHTML, the power and complexities only increase.
!!!!PDF Files
* Pros
** Again, nearly universal.
** All the formatting capabilities you could want
** Navigable
* Cons
** If you buy their proprietary software. Otherwise you are probably using PDF printer (or some variation thereof), and although it looks nice, the result is slightly off from what you expect. Unless of course you are familiar with postscript - you thought HTML was complex? Heh Heh
!!!!Word Processor
* Pros
** Fairly universal, depending on the program.
** Powerful formatting
** May be navigable
* Cons
** Can be expensive.
** Proprietary Standard that can, has, and will change. Does your recipient have the program? Does your recipient have the right version of the rogram?
!!!!~TiddlyWiki
* Pros
** Not quite as Universal as HTML, but nearly so. Readable in all modern browsers.
** Powerful Formatting: 90% of the flexibility for 10% of the skill.
** Highly and easily Navigable
*** Searchable
** Modifiable via javascript: 99% of the flexibility for 20% of the skill.
** Free as in speech and as in beer.
* Cons
** A given Browser may be able to read, but not write the file.
** Does not support images internally (Though can link and embed them).
** HTML Based - Although it is possible to embed XML or SVG, it is currently quite limited.
/***
|Name:|TagglyTaggingPlugin|
|Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
|Version:|3.3.1 ($Rev: 6100 $)|
|Date:|$Date: 2008-07-27 01:42:07 +1000 (Sun, 27 Jul 2008) $|
|Source:|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
merge(String.prototype,{
parseTagExpr: function(debug) {
if (this.trim() == "")
return "(true)";
var anyLogicOp = /(!|&&|\|\||\(|\))/g;
var singleLogicOp = /^(!|&&|\|\||\(|\))$/;
var spaced = this.
// because square brackets in templates are no good
// this means you can use [(With Spaces)] instead of [[With Spaces]]
replace(/\[\(/g," [[").
replace(/\)\]/g,"]] ").
// space things out so we can use readBracketedList. tricky eh?
replace(anyLogicOp," $1 ");
var expr = "";
var tokens = spaced.readBracketedList(false); // false means don't uniq the list. nice one JR!
for (var i=0;i<tokens.length;i++)
if (tokens[i].match(singleLogicOp))
expr += tokens[i];
else
expr += "tiddler.tags.contains('%0')".format([tokens[i].replace(/'/,"\\'")]); // fix single quote bug. still have round bracket bug i think
if (debug)
alert(expr);
return '('+expr+')';
}
});
merge(TiddlyWiki.prototype,{
getTiddlersByTagExpr: function(tagExpr,sortField) {
var result = [];
var expr = tagExpr.parseTagExpr();
store.forEachTiddler(function(title,tiddler) {
if (eval(expr))
result.push(tiddler);
});
if(!sortField)
sortField = "title";
result.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
return result;
}
});
config.taggly = {
// for translations
lingo: {
labels: {
asc: "\u2191", // down arrow
desc: "\u2193", // up arrow
title: "title",
modified: "modified",
created: "created",
show: "+",
hide: "-",
normal: "normal",
group: "group",
commas: "commas",
sitemap: "sitemap",
numCols: "cols\u00b1", // plus minus sign
label: "Tagged as '%0':",
exprLabel: "Matching tag expression '%0':",
excerpts: "excerpts",
descr: "descr",
slices: "slices",
contents: "contents",
sliders: "sliders",
noexcerpts: "title only",
noneFound: "(none)"
},
tooltips: {
title: "Click to sort by title",
modified: "Click to sort by modified date",
created: "Click to sort by created date",
show: "Click to show tagging list",
hide: "Click to hide tagging list",
normal: "Click to show a normal ungrouped list",
group: "Click to show list grouped by tag",
sitemap: "Click to show a sitemap style list",
commas: "Click to show a comma separated list",
numCols: "Click to change number of columns",
excerpts: "Click to show excerpts",
descr: "Click to show the description slice",
slices: "Click to show all slices",
contents: "Click to show entire tiddler contents",
sliders: "Click to show tiddler contents in sliders",
noexcerpts: "Click to show entire title only"
},
tooDeepMessage: "* //sitemap too deep...//"
},
config: {
showTaggingCounts: true,
listOpts: {
// the first one will be the default
sortBy: ["title","modified","created"],
sortOrder: ["asc","desc"],
hideState: ["show","hide"],
listMode: ["normal","group","sitemap","commas"],
numCols: ["1","2","3","4","5","6"],
excerpts: ["noexcerpts","excerpts","descr","slices","contents","sliders"]
},
valuePrefix: "taggly.",
excludeTags: ["excludeLists","excludeTagging"],
excerptSize: 50,
excerptMarker: "/%"+"%/",
siteMapDepthLimit: 25
},
getTagglyOpt: function(title,opt) {
var val = store.getValue(title,this.config.valuePrefix+opt);
return val ? val : this.config.listOpts[opt][0];
},
setTagglyOpt: function(title,opt,value) {
if (!store.tiddlerExists(title))
// create it silently
store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),"");
// if value is default then remove it to save space
return store.setValue(title,
this.config.valuePrefix+opt,
value == this.config.listOpts[opt][0] ? null : value);
},
getNextValue: function(title,opt) {
var current = this.getTagglyOpt(title,opt);
var pos = this.config.listOpts[opt].indexOf(current);
// a little usability enhancement. actually it doesn't work right for grouped or sitemap
var limit = (opt == "numCols" ? store.getTiddlersByTagExpr(title).length : this.config.listOpts[opt].length);
var newPos = (pos + 1) % limit;
return this.config.listOpts[opt][newPos];
},
toggleTagglyOpt: function(title,opt) {
var newVal = this.getNextValue(title,opt);
this.setTagglyOpt(title,opt,newVal);
},
createListControl: function(place,title,type) {
var lingo = config.taggly.lingo;
var label;
var tooltip;
var onclick;
if ((type == "title" || type == "modified" || type == "created")) {
// "special" controls. a little tricky. derived from sortOrder and sortBy
label = lingo.labels[type];
tooltip = lingo.tooltips[type];
if (this.getTagglyOpt(title,"sortBy") == type) {
label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
onclick = function() {
config.taggly.toggleTagglyOpt(title,"sortOrder");
return false;
}
}
else {
onclick = function() {
config.taggly.setTagglyOpt(title,"sortBy",type);
config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
return false;
}
}
}
else {
// "regular" controls, nice and simple
label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
onclick = function() {
config.taggly.toggleTagglyOpt(title,type);
return false;
}
}
// hide button because commas don't have columns
if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
},
makeColumns: function(orig,numCols) {
var listSize = orig.length;
var colSize = listSize/numCols;
var remainder = listSize % numCols;
var upperColsize = colSize;
var lowerColsize = colSize;
if (colSize != Math.floor(colSize)) {
// it's not an exact fit so..
upperColsize = Math.floor(colSize) + 1;
lowerColsize = Math.floor(colSize);
}
var output = [];
var c = 0;
for (var j=0;j<numCols;j++) {
var singleCol = [];
var thisSize = j < remainder ? upperColsize : lowerColsize;
for (var i=0;i<thisSize;i++)
singleCol.push(orig[c++]);
output.push(singleCol);
}
return output;
},
drawTable: function(place,columns,theClass) {
var newTable = createTiddlyElement(place,"table",null,theClass);
var newTbody = createTiddlyElement(newTable,"tbody");
var newTr = createTiddlyElement(newTbody,"tr");
for (var j=0;j<columns.length;j++) {
var colOutput = "";
for (var i=0;i<columns[j].length;i++)
colOutput += columns[j][i];
var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
wikify(colOutput,newTd);
}
return newTable;
},
createTagglyList: function(place,title,isTagExpr) {
switch(this.getTagglyOpt(title,"listMode")) {
case "group": return this.createTagglyListGrouped(place,title,isTagExpr); break;
case "normal": return this.createTagglyListNormal(place,title,false,isTagExpr); break;
case "commas": return this.createTagglyListNormal(place,title,true,isTagExpr); break;
case "sitemap":return this.createTagglyListSiteMap(place,title,isTagExpr); break;
}
},
getTaggingCount: function(title,isTagExpr) {
// thanks to Doug Edmunds
if (this.config.showTaggingCounts) {
var tagCount = config.taggly.getTiddlers(title,'title',isTagExpr).length;
if (tagCount > 0)
return " ("+tagCount+")";
}
return "";
},
getTiddlers: function(titleOrExpr,sortBy,isTagExpr) {
return isTagExpr ? store.getTiddlersByTagExpr(titleOrExpr,sortBy) : store.getTaggedTiddlers(titleOrExpr,sortBy);
},
getExcerpt: function(inTiddlerTitle,title,indent) {
if (!indent)
indent = 1;
var displayMode = this.getTagglyOpt(inTiddlerTitle,"excerpts");
var t = store.getTiddler(title);
if (t && displayMode == "excerpts") {
var text = t.text.replace(/\n/," ");
var marker = text.indexOf(this.config.excerptMarker);
if (marker != -1) {
return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
}
else if (text.length < this.config.excerptSize) {
return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
}
else {
return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
}
}
else if (t && displayMode == "contents") {
return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
}
else if (t && displayMode == "sliders") {
return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
}
else if (t && displayMode == "descr") {
var descr = store.getTiddlerSlice(title,'Description');
return descr ? " {{excerpt{" + descr + "}}}" : "";
}
else if (t && displayMode == "slices") {
var result = "";
var slices = store.calcAllSlices(title);
for (var s in slices)
result += "|%0|<nowiki>%1</nowiki>|\n".format([s,slices[s]]);
return result ? "\n{{excerpt excerptIndent{\n" + result + "}}}" : "";
}
return "";
},
notHidden: function(t,inTiddler) {
if (typeof t == "string")
t = store.getTiddler(t);
return (!t || !t.tags.containsAny(this.config.excludeTags) ||
(inTiddler && this.config.excludeTags.contains(inTiddler)));
},
// this is for normal and commas mode
createTagglyListNormal: function(place,title,useCommas,isTagExpr) {
var list = config.taggly.getTiddlers(title,this.getTagglyOpt(title,"sortBy"),isTagExpr);
if (this.getTagglyOpt(title,"sortOrder") == "desc")
list = list.reverse();
var output = [];
var first = true;
for (var i=0;i<list.length;i++) {
if (this.notHidden(list[i],title)) {
var countString = this.getTaggingCount(list[i].title);
var excerpt = this.getExcerpt(title,list[i].title);
if (useCommas)
output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
else
output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");
first = false;
}
}
return this.drawTable(place,
this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
useCommas ? "commas" : "normal");
},
// this is for the "grouped" mode
createTagglyListGrouped: function(place,title,isTagExpr) {
var sortBy = this.getTagglyOpt(title,"sortBy");
var sortOrder = this.getTagglyOpt(title,"sortOrder");
var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);
if (sortOrder == "desc")
list = list.reverse();
var leftOvers = []
for (var i=0;i<list.length;i++)
leftOvers.push(list[i].title);
var allTagsHolder = {};
for (var i=0;i<list.length;i++) {
for (var j=0;j<list[i].tags.length;j++) {
if (list[i].tags[j] != title) { // not this tiddler
if (this.notHidden(list[i].tags[j],title)) {
if (!allTagsHolder[list[i].tags[j]])
allTagsHolder[list[i].tags[j]] = "";
if (this.notHidden(list[i],title)) {
allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";
leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers
}
}
}
}
}
var allTags = [];
for (var t in allTagsHolder)
allTags.push(t);
var sortHelper = function(a,b) {
if (a == b) return 0;
if (a < b) return -1;
return 1;
};
allTags.sort(function(a,b) {
var tidA = store.getTiddler(a);
var tidB = store.getTiddler(b);
if (sortBy == "title") return sortHelper(a,b);
else if (!tidA && !tidB) return 0;
else if (!tidA) return -1;
else if (!tidB) return +1;
else return sortHelper(tidA[sortBy],tidB[sortBy]);
});
var leftOverOutput = "";
for (var i=0;i<leftOvers.length;i++)
if (this.notHidden(leftOvers[i],title))
leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";
var output = [];
if (sortOrder == "desc")
allTags.reverse();
else if (leftOverOutput != "")
// leftovers first...
output.push(leftOverOutput);
for (var i=0;i<allTags.length;i++)
if (allTagsHolder[allTags[i]] != "")
output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);
if (sortOrder == "desc" && leftOverOutput != "")
// leftovers last...
output.push(leftOverOutput);
return this.drawTable(place,
this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
"grouped");
},
// used to build site map
treeTraverse: function(title,depth,sortBy,sortOrder,isTagExpr) {
var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);
if (sortOrder == "desc")
list.reverse();
var indent = "";
for (var j=0;j<depth;j++)
indent += "*"
var childOutput = "";
if (depth > this.config.siteMapDepthLimit)
childOutput += indent + this.lingo.tooDeepMessage;
else
for (var i=0;i<list.length;i++)
if (list[i].title != title)
if (this.notHidden(list[i].title,this.config.inTiddler))
childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder,false);
if (depth == 0)
return childOutput;
else
return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title,depth) + "\n" + childOutput;
},
// this if for the site map mode
createTagglyListSiteMap: function(place,title,isTagExpr) {
this.config.inTiddler = title; // nasty. should pass it in to traverse probably
var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"),isTagExpr);
return this.drawTable(place,
this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
"sitemap"
);
},
macros: {
tagglyTagging: {
handler: function (place,macroName,params,wikifier,paramString,tiddler) {
var parsedParams = paramString.parseParams("tag",null,true);
var refreshContainer = createTiddlyElement(place,"div");
// do some refresh magic to make it keep the list fresh - thanks Saq
refreshContainer.setAttribute("refresh","macro");
refreshContainer.setAttribute("macroName",macroName);
var tag = getParam(parsedParams,"tag");
var expr = getParam(parsedParams,"expr");
if (expr) {
refreshContainer.setAttribute("isTagExpr","true");
refreshContainer.setAttribute("title",expr);
refreshContainer.setAttribute("showEmpty","true");
}
else {
refreshContainer.setAttribute("isTagExpr","false");
if (tag) {
refreshContainer.setAttribute("title",tag);
refreshContainer.setAttribute("showEmpty","true");
}
else {
refreshContainer.setAttribute("title",tiddler.title);
refreshContainer.setAttribute("showEmpty","false");
}
}
this.refresh(refreshContainer);
},
refresh: function(place) {
var title = place.getAttribute("title");
var isTagExpr = place.getAttribute("isTagExpr") == "true";
var showEmpty = place.getAttribute("showEmpty") == "true";
removeChildren(place);
addClass(place,"tagglyTagging");
var countFound = config.taggly.getTiddlers(title,'title',isTagExpr).length
if (countFound > 0 || showEmpty) {
var lingo = config.taggly.lingo;
config.taggly.createListControl(place,title,"hideState");
if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
createTiddlyElement(place,"span",null,"tagglyLabel",
isTagExpr ? lingo.labels.exprLabel.format([title]) : lingo.labels.label.format([title]));
config.taggly.createListControl(place,title,"title");
config.taggly.createListControl(place,title,"modified");
config.taggly.createListControl(place,title,"created");
config.taggly.createListControl(place,title,"listMode");
config.taggly.createListControl(place,title,"excerpts");
config.taggly.createListControl(place,title,"numCols");
config.taggly.createTagglyList(place,title,isTagExpr);
if (countFound == 0 && showEmpty)
createTiddlyElement(place,"div",null,"tagglyNoneFound",lingo.labels.noneFound);
}
}
}
}
},
// todo fix these up a bit
styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
" margin-top:0px; padding-top:0.5em; padding-left:2em;",
" margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
" color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
" border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active {",
" border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryDark]]; }",
".excerptIndent { margin-left:4em; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
".tagglyTagging .contents { border-bottom:2px solid [[ColorPalette::TertiaryPale]]; padding:0 1em 1em 0.5em;",
" margin-bottom:0.5em; }",
".tagglyTagging .indent1 { margin-left:3em; }",
".tagglyTagging .indent2 { margin-left:4em; }",
".tagglyTagging .indent3 { margin-left:5em; }",
".tagglyTagging .indent4 { margin-left:6em; }",
".tagglyTagging .indent5 { margin-left:7em; }",
".tagglyTagging .indent6 { margin-left:8em; }",
".tagglyTagging .indent7 { margin-left:9em; }",
".tagglyTagging .indent8 { margin-left:10em; }",
".tagglyTagging .indent9 { margin-left:11em; }",
".tagglyTagging .indent10 { margin-left:12em; }",
".tagglyNoneFound { margin-left:2em; color:[[ColorPalette::TertiaryMid]]; font-size:90%; font-style:italic; }",
"/*}}}*/",
""].join("\n"),
init: function() {
merge(config.macros,this.macros);
config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
store.addNotification("TagglyTaggingStyles",refreshStyles);
}
};
config.taggly.init();
//}}}
/***
InlineSlidersPlugin
By Saq Imtiaz
http://tw.lewcid.org/sandbox/#InlineSlidersPlugin
// syntax adjusted to not clash with NestedSlidersPlugin
// added + syntax to start open instead of closed
***/
//{{{
config.formatters.unshift( {
name: "inlinesliders",
// match: "\\+\\+\\+\\+|\\<slider",
match: "\\<slider",
// lookaheadRegExp: /(?:\+\+\+\+|<slider) (.*?)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
lookaheadRegExp: /(?:<slider)(\+?) (.*?)(?:>)\n((?:.|\n)*?)\n(?:<\/slider>)/mg,
handler: function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart ) {
var btn = createTiddlyButton(w.output,lookaheadMatch[2] + " "+"\u00BB",lookaheadMatch[2],this.onClickSlider,"button sliderButton");
var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
panel.style.display = (lookaheadMatch[1] == '+' ? "block" : "none");
wikify(lookaheadMatch[3],panel);
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
},
onClickSlider : function(e) {
if(!e) var e = window.event;
var n = this.nextSibling;
n.style.display = (n.style.display=="none") ? "block" : "none";
return false;
}
});
//}}}
!Does not work as of the moment
{{{
<<SVG '<script type="text/ecmascript"> <![CDATA[
var lsx = 100;
var lsy = 75;
var rsx = 310;
var rsy = 75;
function mouseMove (evt) {
var document = evt.target.ownerDocument;
var rootElem = document.rootElement;
var trans = rootElem.currentTranslate;
var scale = rootElem.currentScale;
var p = rootElem.createSVGPoint();
// Remove the current pan and zoom from the mouse coordinate
p.x = ( evt.clientX - trans.x ) / scale;
p.y = ( evt.clientY - trans.y ) / scale;
var newY = (p.y - lsy) / 4 + lsy;
var newX = (p.x - lsx) / 3 + lsx;
if (newX > 170) {
newX = 170;
}
document.getElementById("leftEye").setAttributeNS(null, "cx", newX);
document.getElementById("leftEye").setAttributeNS(null, "cy", newY);
newY = (p.y - rsy) / 4 + rsy;
newX = (p.x - rsx) / 3 + rsx;
if (newX < 230) {
newX = 230;
}
document.getElementById("rightEye").setAttributeNS(null, "cx", newX);
document.getElementById("rightEye").setAttributeNS(null, "cy", newY);
window.status = p.x + " - " + p.y;
}
]]></script>
<!-- Pattern Definition -->
<defs>
<clipPath id="eyeLeftPath">
<ellipse cx="130" cy="75" rx="90" ry="40" transform="skewX(-20)" />
</clipPath>
<clipPath id="eyeRightPath">
<ellipse cx="280" cy="75" rx="90" ry="40" transform="skewX(20)" />
</clipPath>
<radialGradient id="eyeGradient">
<stop offset="0%" stop-color="black" />
<stop offset="30%" stop-color="black" />
<stop offset="33%" stop-color="aqua" />
<stop offset="40%" stop-color="blue" />
<stop offset="80%" stop-color="mediumblue" />
<stop offset="95%" stop-color="midnightblue" />
</radialGradient>
</defs>
<rect width="100%" height="100%" fill="lavender" onmousemove="mouseMove(evt);" />
<g clip-path="url(#eyeLeftPath)" onmousemove="mouseMove(evt);">
<rect x="0" y="0" width="100%" height="100%" fill="midnightblue" />
<circle id="leftEye" cx="100" cy="75" r="100" fill="url(#eyeGradient)" />
</g>
<g clip-path="url(#eyeRightPath)" onmousemove="mouseMove(evt);">
<rect x="0" y="0" width="100%" height="100%" fill="midnightblue" />
<circle id="rightEye" cx="310" cy="75" r="100" fill="url(#eyeGradient)" />
</g>
<text x="50%" y="95%" stroke="gray" fill="gray" font-size="15" text-anchor="middle">The eye is upon us!</text>'>>
}}}
<<SVG '<script type="text/ecmascript"> <![CDATA[
var lsx = 100;
var lsy = 75;
var rsx = 310;
var rsy = 75;
function mouseMove (evt) {
var document = evt.target.ownerDocument;
var rootElem = document.rootElement;
var trans = rootElem.currentTranslate;
var scale = rootElem.currentScale;
var p = rootElem.createSVGPoint();
// Remove the current pan and zoom from the mouse coordinate
p.x = ( evt.clientX - trans.x ) / scale;
p.y = ( evt.clientY - trans.y ) / scale;
var newY = (p.y - lsy) / 4 + lsy;
var newX = (p.x - lsx) / 3 + lsx;
if (newX > 170) {
newX = 170;
}
document.getElementById("leftEye").setAttributeNS(null, "cx", newX);
document.getElementById("leftEye").setAttributeNS(null, "cy", newY);
newY = (p.y - rsy) / 4 + rsy;
newX = (p.x - rsx) / 3 + rsx;
if (newX < 230) {
newX = 230;
}
document.getElementById("rightEye").setAttributeNS(null, "cx", newX);
document.getElementById("rightEye").setAttributeNS(null, "cy", newY);
window.status = p.x + " - " + p.y;
}
]]></script>
<!-- Pattern Definition -->
<defs>
<clipPath id="eyeLeftPath">
<ellipse cx="130" cy="75" rx="90" ry="40" transform="skewX(-20)" />
</clipPath>
<clipPath id="eyeRightPath">
<ellipse cx="280" cy="75" rx="90" ry="40" transform="skewX(20)" />
</clipPath>
<radialGradient id="eyeGradient">
<stop offset="0%" stop-color="black" />
<stop offset="30%" stop-color="black" />
<stop offset="33%" stop-color="aqua" />
<stop offset="40%" stop-color="blue" />
<stop offset="80%" stop-color="mediumblue" />
<stop offset="95%" stop-color="midnightblue" />
</radialGradient>
</defs>
<rect width="100%" height="100%" fill="lavender" onmousemove="mouseMove(evt);" />
<g clip-path="url(#eyeLeftPath)" onmousemove="mouseMove(evt);">
<rect x="0" y="0" width="100%" height="100%" fill="midnightblue" />
<circle id="leftEye" cx="100" cy="75" r="100" fill="url(#eyeGradient)" />
</g>
<g clip-path="url(#eyeRightPath)" onmousemove="mouseMove(evt);">
<rect x="0" y="0" width="100%" height="100%" fill="midnightblue" />
<circle id="rightEye" cx="310" cy="75" r="100" fill="url(#eyeGradient)" />
</g>
<text x="50%" y="95%" stroke="gray" fill="gray" font-size="15" text-anchor="middle">The eye is upon us!</text>'>>
/***
|''Name:''|TiddlerAliasPlugin|
|''Version:''|1.0.0 BETA 4 (2009-03-30)|
|''Source:''|http://tiddlywiki.abego-software.de/Beta.html#TiddlerAliasPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|© 2009 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.5.0.7 or better; InternetExplorer 6.0|
!Description
Reference a tiddler through an alias (or even through many aliases). E.g. a tiddler "William Shakespeare" may also be referenced as {{{[[Shaxper]]}}}.
When editing a tiddler you may enter alternative names for the tiddler in the "Alias" field (below the tags field), similar to the way you enter tags. You may even specify multiple alias names, separated by spaces. Alias names containing spaces must be written as {{{[[...]]}}}
Also this plugin implements the "Auto Non-Space Alias" feature: for tiddlers with titles containing whitespaces an alias is automatically created that has every whitespace replaced by a dash ("-"). E.g. a tiddler called [[Tiddler with no alias defined]] can also be referenced by [[Tiddler-with-no-alias-defined]].
!Revision history
* v1.0.0 Beta 4 (2009-03-30)
** Bugfix: ToggleLinks does not work when TiddlerAliasPlugin is installed (Thanks to Jonnan West for reporting the bug)
* v1.0.0 Beta 3 (2006-09-23)
** Support "Auto Non-Space Alias" feature: For tiddler with titles containing whitespaces an alias is automatically created that has every whitespace replaced by a dash ("-")
* v1.0.0 Beta 2 (2006-09-22)
** Bugfix: Tiddler is displayed more than once when opened both through title and alias (Thanks to KenGirard for reporting)
* v1.0.0 Beta 1 (2006-09-21)
** Beta 1 release
!Code
***/
//{{{
//============================================================================
//============================================================================
// TiddlerAliasPlugin
//============================================================================
//============================================================================
// Only install once
if (!version.extensions.TiddlerAliasPlugin) {
version.extensions.TiddlerAliasPlugin = {
major: 1, minor: 0, revision: 0, beta: 4,
date: new Date(2009,2,30),
source: "http://tiddlywiki.abego-software.de/Beta.html#TiddlerAliasPlugin",
licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
copyright: "Copyright (c) abego Software GmbH, 2005-2009 (www.abego-software.de)"
};
(function() {
window.abegoTiddlerAlias = {
lingo: {
aliasPrompt: "Type alias names (i.e. alternative names for this tiddler) separated with spaces, [[use double square brackets]] if necessary"
},
editTemplateExtension: "<div class='editor' macro='edit alias'></div><div class='editorFooter'><span macro='message abegoTiddlerAlias.lingo.aliasPrompt'></span></div>"
};
var oldFetchTiddler;
var oldSaveTiddler;
var oldDisplayTiddler;
var fWithAutoNonSpaceAlias = true;
function withAutoNonSpaceAlias() {
return fWithAutoNonSpaceAlias;
}
function addNonSpaceAlias(map, title) {
var s = title.replace(/\s/g,"-");
if (s != title)
map[s] = title;
}
function calcAliases() {
var result = {};
store.forEachTiddler(function(title,tiddler) {
var s = store.getValue(tiddler,"alias");
if (s) {
var p = s.parseParams("list",null,false,true);
for(var i=1; i<p.length; i++)
result[p[i].value] = title;
}
if (withAutoNonSpaceAlias())
addNonSpaceAlias(result,title);
});
return result;
}
// Returns a map that maps an alias name to the title of the tiddler
abegoTiddlerAlias.getAliases = function() {
if (!store.aliases)
store.aliases = calcAliases();
return store.aliases;
}
// Returns the title of the tiddler for the given alias.
// When no such alias is defined but a tiddler with that name exists the alias is returned.
// Otherwise null is returned.
abegoTiddlerAlias.getAliasTitle = function(alias) {
var t = abegoTiddlerAlias.getAliases()[alias];
return t ? t : (store.fetchTiddler(alias) ? alias : null)
}
function hasEditTemplateExtension(s) {
return s.indexOf(abegoTiddlerAlias.editTemplateExtension) >= 0;
}
function addEditTemplateExtension(s) {
if (s && !hasEditTemplateExtension(s)) {
var i = s.lastIndexOf("</div>");
if (i >= 0)
return s.slice(0,i+6)+"\n"+abegoTiddlerAlias.editTemplateExtension+s.slice(i+6);
}
return null;
}
function hijackFetchTiddler() {
oldFetchTiddler = store.fetchTiddler;
store.fetchTiddler = function(title) {
var result = oldFetchTiddler.apply(this, arguments);
if (!result && title) {
title = abegoTiddlerAlias.getAliases()[title];
if (title)
result = oldFetchTiddler.apply(this, [title])
}
return result;
};
}
function hijackSaveTiddler() {
oldSaveTiddler = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function() {
var result = oldSaveTiddler.apply(this, arguments);
delete store.aliases;
return result;
}
}
function hijackDisplayTiddler() {
oldDisplayTiddler = Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly,customFields,toggle,animationSrc) {
// Ensure that a tiddler is always opened with its "original" title (not an alias)
var tiddler = store.fetchTiddler(title);
if (tiddler)
title = tiddler.title;
return oldDisplayTiddler.apply(this, [srcElement,title,template,animate,slowly,customFields,toggle,animationSrc]);
}
}
function modifyEditTemplate() {
// The shadow tiddler
var s = addEditTemplateExtension(config.shadowTiddlers["EditTemplate"]);
if (s)
config.shadowTiddlers["EditTemplate"] = s;
// The "real" tiddler (if defined)
var t = store.getTiddler("EditTemplate");
if (t && !hasEditTemplateExtension(t.text))
t.set(null,addEditTemplateExtension(t.text));
}
// Requires store is defined.
function doHijacking() {
hijackFetchTiddler();
hijackSaveTiddler();
hijackDisplayTiddler();
modifyEditTemplate();
}
// for debugging the plugin is not loaded through the systemConfig mechanism but via a script tag.
// At that point in the "store" is not yet defined. In that case hijackFetchTiddler through the restart function.
// Otherwise hijack now.
if (!store) {
var oldRestartFunc = restart;
window.restart = function() {
doHijacking();
oldRestartFunc.apply(this,arguments);
};
} else
doHijacking();
// To support the access through the "message" macro
config.abegoTiddlerAlias = abegoTiddlerAlias;
})();
} // of "install only once"
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/
//}}}
/***
|Name|TiddlerEncryptionPlugin|
|Author|Lyall Pearce|
|Source|http://www.Remotely-Helpful.com/TiddlyWiki/TiddlerEncryptionPlugin.html|
|License|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Version|3.2.1|
|~CoreVersion|2.4.0|
|Requires|None|
|Overrides|store.getSaver().externalizeTiddler(), store.getTiddler() and store.getTiddlerText()|
|Description|Encrypt/Decrypt Tiddlers with a Password key|
!!!!!Usage
<<<
* Tag a tiddler with Encrypt(prompt)
** Consider the 'prompt' something to help you remember the password with. If multiple tiddlers can be encrypted with the same 'prompt' and you will only be asked for the password once.
* Upon save, the Tiddler will be encrypted and the tag replaced with Decrypt(prompt).
** Failure to encrypt (by not entering a password) will leave the tiddler unencrypted and will leave the Encrypt(prompt) tag in place. This means that the next time you save, you will be asked for the password again.
** To have multiple tiddlers use the same password - simply use the same 'prompt'.
** Tiddlers that are encrypted may be automatically tagged 'excludeSearch' as there is no point in searching encrypted data - this is configurable by an option - you still may want to search the titles of encrypted tiddlers
** Tiddlers that are encrypted may be automatically tagged 'excludeLists', if you have them encrypted, you may also want to keep them 'hidden' - this is configurable by an option.
** Automatic removal of excludeLists and excludeSearch tags is performed, if the above two options are set, only if these two tags are the last 2 tags for a tiddler, if they are positioned somewhere else in the tags list, they will be left in place, meaning that the decrypted tiddler will not be searchable and/or will not appear in lists.
** Encrypted tiddlers are stored as displayable hex, to keep things visibly tidy, should you display an encrypted tiddler. There is nothing worse than seeing a pile of gobbledy gook on your screen. Additionally, the encrypted data is easily cut/paste/emailed if displayed in hex form.
* Tiddlers are decrypted only if you click the decrypt button or the decryptAll button, not when you load the TiddlyWiki
** If you don't display a tiddler, you won't have the option to decrypt it (unless you use the {{{<<EncryptionDecryptAll>>}}} macro)
** Tiddlers will re-encrypt automatically on save.
** Decryption of Tiddlers does not make your TiddlyWiki 'dirty' - you will not be asked to save if you leave the page.
* Errors are reported via diagnostic messages.
** Empty passwords, on save, will result in the tiddler being saved unencrypted - this should only occur with new tiddlers, decrypted tiddlers or with tiddlers who have had their 'prompt' tag changed.
** Encrypted tiddlers know if they are decrypted successfully - failure to decrypt a tiddler will ''not'' lose your data.
** Editing of an encrypted (that has not been unencrypted) tiddler will result in loss of that tiddler as the SHA1 checksums will no longer match, upon decryption. To this end, it is best that you do not check the option. You can, however edit an encrypted tiddler tag list - just do ''not'' change the tiddler contents.
** To change the password on a Tiddler, change the Encrypt('prompt') tag to a new prompt value, after decrypting the tiddler.
** You can edit the tags of an encrypted tiddler, so long as you do not edit the text.
** To change the password for all tiddlers of a particular prompt, use the {{{<<EncryptionChangePassword ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro.
** To decrypt all tiddlers of a particular "prompt string", use the {{{<<EncryptionDecryptAll ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro - this will make tiddlers encrypted with "prompt string" searchable - or prompt for all 'prompt strings', if none is supplied.
<<<
!!!!!Configuration
<<<
Useful Buttons:
<<EncryptionChangePassword>> - Change passwords of encrypted tiddlers.
<<EncryptionDecryptAll>> - Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
<<option chkExcludeEncryptedFromSearch>> - If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
<<option chkExcludeEncryptedFromLists>> - If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
<<option chkShowDecryptButtonInContent>> - If set, Encrypted Tiddlers content is replaced by <<EncryptionDecryptThis>> button. This has consequences, in the current version as, if you edit the tiddler without decrypting it, you lose the contents.
<<<
!!!!!Revision History
<<<
* 3.2.1 - Returned the <<EncryptionDecryptThis>> button as an option.
* 3.2.0 - Ditched the 'Decrypt' button showing up in the tiddler contents if the tiddler is encrypted. It caused too much pain if you edit the tiddler without decrypting it - you lost your data as it was replaced by a Decrypt Macro call! Additionally, a 'decrypt' button will now appear in the toolbar, just before the edit button, if the tiddler is encrypted. This button only appears if using core TiddlyWiki version 2.4 or above.
* 3.1.1 - Obscure bug whereby if an encrypted tiddler was a certain length, it would refuse to decrypt.
* 3.1.0 - When creating a new Encrypt(prompt) tiddler and you have not previously decrypted a tiddler with the same prompt, on save, you will be prompted for the password to encrypt the tiddler. Prior to encrypting, an attempt to decrypt all other tiddlers with the same prompt, is performed. If any tiddler fails to decrypt, the save is aborted - this is so you don't accidentally have 2 (or more!) passwords for the same prompt. Either you enter the correct password, change the prompt string and try re-saving or you cancel (and the tiddler is saved unencrypted).
* 3.0.1 - Allow Enter to be used for password entry, rather than having to press the OK button.
* 3.0.0 - Major revamp internally to support entry of passwords using forms such that passwords are no longer visible on entry. Completely backward compatible with old encrypted tiddlers. No more using the javascript prompt() function.
<<<
!!!!!Additional work
***/
//{{{
version.extensions.TiddlerEncryptionPlugin = {major: 3, minor: 2, revision: 1, date: new Date(2008,10,26)};
// where I cache the passwords - for want of a better place.
config.encryptionPasswords = new Array();
config.encryptionReEnterPasswords = false;
if(config.options.chkExcludeEncryptedFromSearch == undefined) config.options.chkExcludeEncryptedFromSearch = false;
if(config.options.chkExcludeEncryptedFromLists == undefined) config.options.chkExcludeEncryptedFromLists = false;
if(config.options.chkShowDecryptButtonInContent == undefined) config.options.chkShowDecryptButtonInContent = false;
config.macros.EncryptionChangePassword = {};
config.macros.EncryptionChangePassword.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var theButton = createTiddlyButton(place,
(params[0] && params[0].length > 0) ? params[0] : "Change Passwords",
(params[1] && params[1].length > 0) ? params[1] : "Change Passwords" + (params[2] ? " for prompt "+params[2] : ""),
onClickEncryptionChangePassword,
null,
null,
params[3]);
if(params[2] && params[2].length > 0) {
theButton.setAttribute("promptString", params[2]);
}
};
config.macros.EncryptionDecryptAll = {};
config.macros.EncryptionDecryptAll.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var theButton = createTiddlyButton(place,
(params[0] && params[0].length > 0) ? params[0] : "Decrypt All",
(params[1] && params[1].length > 0) ? params[1] : "Decrypt All Tiddlers" + ((params[2] && params[2].length > 0) ? " for prompt "+params[2] : " for a given 'prompt string'"),
onClickEncryptionDecryptAll,
null,
null,
params[3]);
if(params[2] && params[2].length > 0) {
theButton.setAttribute("promptString", params[2]);
}
};
config.macros.EncryptionDecryptThis = {};
config.macros.EncryptionDecryptThis.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var theButton = createTiddlyButton(place,
(params[0] && params[0].length > 0) ? params[0] : "Decrypt",
(params[1] && params[1].length > 0) ? params[1] : "Decrypt this Tiddler",
onClickEncryptionDecryptThis,
null,
null,
params[3]);
if(params[2] && params[2].length > 0) {
theButton.setAttribute("theTiddler", params[2]);
}
};
// toolbar button to decrypt tiddlers.
config.commands.decryptThis = {
text: "decrypt",
tooltip: "Decrypt this tiddler",
isEnabled : function(tiddler) {
// Only show decrypt button if tiddler is tagged as Decrypt(
if(tiddler.tags.join().indexOf('Decrypt(') == -1) {
return false;
} else {
return true;
}
},
handler: function(event, src, title) {
encryptionGetAndDecryptTiddler(title);
return false;
}
};
// core version 2.4 or above get a 'decrypt' button in the toolbar.
if(config.shadowTiddlers && config.shadowTiddlers.ToolbarCommands && config.shadowTiddlers.ToolbarCommands.indexOf('decryptThis') == -1) {
// put our toolbar button in before the edit button.
// won't work if editTiddler is not the default item (prefixed with plus)
config.shadowTiddlers.ToolbarCommands.replace(/\+editTiddler/,'decryptThis +editTiddler');
}
// Called by the EncryptionChangePassword macro/button
// Also invoked by the callback for password entry
function onClickEncryptionChangePassword(eventObject) {
var promptString;
if(!promptString && this.getAttribute) {
promptString = this.getAttribute("promptString");
}
// I do call this function directly
if(!promptString && typeof(eventObject) == "string") {
promptString = eventObject;
}
if(!promptString) {
promptString = prompt("Enter 'prompt string' to change password for:","");
}
if(!promptString) {
return;
}
if(! config.encryptionPasswords[promptString]) {
var changePasswordContext = {changePasswordPromptString: promptString,
callbackFunction: MyChangePasswordPromptCallback_TiddlerEncryptionPlugin};
MyPrompt_TiddlerEncryptionPlugin(promptString,"",changePasswordContext);
return;
// Callback function will re-invoke this function
}
// Decrypt ALL tiddlers for that prompt
onClickEncryptionDecryptAll(promptString);
// Now ditch the cached password, this will force the re-request for the new password, on save.
displayMessage("Save TiddlyWiki to set new password for '"+promptString+"'");
config.encryptionPasswords[promptString] = null;
// mark store as dirty so a save will be requrested.
store.setDirty(true);
autoSaveChanges();
return;
};
// Called by the password entry form when the user clicks 'OK' button.
function MyChangePasswordPromptCallback_TiddlerEncryptionPlugin(context) {
config.encryptionPasswords[context.passwordPrompt] = context.password;
onClickEncryptionChangePassword(context.changePasswordPromptString);
return;
}
// Called by the EncryptionDecryptThis macro/button
function onClickEncryptionDecryptThis() {
var theTiddler = this.getAttribute("theTiddler");
if(!theTiddler) {
return;
}
encryptionGetAndDecryptTiddler(theTiddler);
return;
};
function encryptionGetAndDecryptTiddler(title) {
config.encryptionReEnterPasswords = true;
try {
theTiddler = store.getTiddler(title);
config.encryptionReEnterPasswords = false;
story.refreshAllTiddlers();
} catch (e) {
if(e == "DecryptionFailed") {
displayMessage("Decryption failed");
return;
}
} // catch
return;
};
// called by the EncryptionDecryptAlll macro/button
// Also called by the callback after the user clicks 'OK' button on the password entry form
function onClickEncryptionDecryptAll(eventObject) {
var promptString;
if(!promptString && this.getAttribute) {
promptString = this.getAttribute("promptString");
}
// I do call this function directly
if(!promptString && typeof(eventObject) == "string") {
promptString = eventObject;
}
if(!promptString) {
promptString = "";
}
// Loop through all tiddlers, looking to see if there are any Decrypt(promptString) tagged tiddlers
// If there are, check to see if their password has been cached.
// If not, ask for the first one that is missing, that we find
// the call back function will store that password then invoke this function again,
// which will repeat the whole process. If we find all passwords have been cached
// then we will finally do the decryptAll functionality, which will then
// be able to decrypt all the required tiddlers, without prompting.
// We have to do this whole rigmarole because we are using a 'form' to enter the password
// rather than the 'prompt()' function - which shows the value of the password.
var tagToSearchFor="Decrypt("+promptString;
config.encryptionReEnterPasswords = true;
var promptGenerated = false;
store.forEachTiddler(function(store,tiddler) {
// Note, there is no way to stop the forEachTiddler iterations
if(!promptGenerated && tiddler && tiddler.tags) {
for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
var tag = tiddler.tags[ix];
var lastBracket=tag.lastIndexOf(")");
if(lastBracket >= 0) {
// Ok, tagged with Encrypt(passwordPrompt)
// extract the passwordPrompt name
var passwordPromptString=tag.substring(8,lastBracket);
if(!config.encryptionPasswords[passwordPromptString]) {
// no password cached, prompt and cache it, rather than decryptAll
// callback from prompting form will resume decryptAll attempt.
var decryptAllContext = {decryptAllPromptString: promptString,
callbackFunction: MyDecryptAllPromptCallback_TiddlerEncryptionPlugin};
MyPrompt_TiddlerEncryptionPlugin(passwordPromptString,"",decryptAllContext);
promptGenerated = true;
} // if(!config.encryptionPasswords
} // if(lastBracket
} // if(tiddler.tags[ix]..
} // for
} // if
}); // store.forEachTiddler
// If we get here, all passwords have been cached.
if(!promptGenerated) {
config.encryptionReEnterPasswords = false;
// Now do the decrypt all functionality
try {
store.forEachTiddler(function(store,tiddler) {
// Note, there is no way to stop the forEachTiddler iterations
if(tiddler && tiddler.tags) {
for(var ix=0; ix<tiddler.tags.length; ix++) {
if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
try {
CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
} catch (e) {
displayMessage("Decryption of '"+tiddler.title+"' failed.");
// throw e;
}
} // if(tiddler.tags
} // for
} // if
}); // store.forEachTiddler
displayMessage("All tiddlers" + (promptString != "" ? " for '"+promptString+"'" : "") + " have been decrypted");
} catch (e) {
if(e == "DecryptionFailed") {
return;
}
} // catch
}
return;
};
function MyDecryptAllPromptCallback_TiddlerEncryptionPlugin(context) {
config.encryptionPasswords[context.passwordPrompt] = context.password;
// restart the decryptAll process again after the user has entered a password.
onClickEncryptionDecryptAll(context.decryptAllPromptString);
return;
}
saveChanges_TiddlerEncryptionPlugin = saveChanges;
saveChanges = function(onlyIfDirty,tiddlers) {
// Loop through all tiddlers, looking to see if there are any Encrypt(string) tagged tiddlers
// If there are, check to see if their password has been cached.
// If not, ask for the first one that is missing, that we find
// the call back function will store that password then invoke this function again,
// which will repeat the whole process. If we find all passwords have been cached
// then we will finally call the original saveChanges() function, which will then
// be able to save the tiddlers.
// We have to do this whole rigmarole because we are using a 'form' to enter the password
// rather than the 'prompt()' function - which shows the value of the password.
config.encryptionReEnterPasswords = true;
var promptGenerated = false;
store.forEachTiddler(function(store,tiddler) {
if(!promptGenerated && tiddler && tiddler.tags) {
for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
if(tiddler.tags[ix].indexOf("Encrypt(") == 0) {
var tag = tiddler.tags[ix];
var lastBracket=tag.lastIndexOf(")");
if(lastBracket >= 0) {
// Ok, tagged with Encrypt(passwordPrompt)
// extract the passwordPrompt name
var passwordPrompt=tag.substring(8,lastBracket);
if(!config.encryptionPasswords[passwordPrompt]) {
// no password cached, prompt and cache it, rather than save
var saveContext = {onlyIfDirty: onlyIfDirty,
tiddlers: tiddlers,
callbackFunction: MySavePromptCallback_TiddlerEncryptionPlugin};
MyPrompt_TiddlerEncryptionPlugin(passwordPrompt,"",saveContext);
promptGenerated = true;
} // if(!config.encryptionPasswords
} // if(lastBracket
} // if(tiddler.tags[ix]..
} // for
} // if
}); // store.forEachTiddler
// If we get here, all passwords have been cached.
if(!promptGenerated) {
config.encryptionReEnterPasswords = false;
saveChanges_TiddlerEncryptionPlugin(onlyIfDirty,tiddlers);
}
return;
}
function MySavePromptCallback_TiddlerEncryptionPlugin(context) {
config.encryptionPasswords[context.passwordPrompt] = context.password;
// validate the password entered by attempting to decrypt all tiddlers
// with the same encryption prompt string.
onClickEncryptionDecryptAll(context.passwordPrompt);
// restart the save process again
saveChanges(context.onlyIfDirty, context.tiddlers);
return;
}
store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin = store.getSaver().externalizeTiddler;
store.getSaver().externalizeTiddler = function(store, tiddler) {
// Ok, got the tiddler, track down the passwordPrompt in the tags.
// track down the Encrypt(passwordPrompt) tag
if(tiddler && tiddler.tags) {
for(var g=0; g<tiddler.tags.length; g++) {
var tag = tiddler.tags[g];
if(tag.indexOf("Encrypt(") == 0) {
var lastBracket=tag.lastIndexOf(")");
if(lastBracket >= 0) {
// Ok, tagged with Encrypt(passwordPrompt)
// extract the passwordPrompt name
var passwordPrompt=tag.substring(8,lastBracket);
// Ok, Encrypt this tiddler!
var decryptedSHA1 = Crypto.hexSha1Str(tiddler.text);
var password = GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(passwordPrompt);
if(password) {
var encryptedText = TEAencrypt(tiddler.text, password);
encryptedText = StringToHext_TiddlerEncryptionPlugin(encryptedText);
tiddler.text = "Encrypted("+decryptedSHA1+")\n"+encryptedText;
// Replace the Tag with the Decrypt() tag
tiddler.tags[g]="Decrypt("+passwordPrompt+")";
// let the store know it's dirty
store.setDirty(tiddler.title, true);
// prevent searches on encrypted tiddlers, still nice to search on title though.
if(config.options.chkExcludeEncryptedFromSearch == true) {
tiddler.tags.push("excludeSearch");
}
// prevent lists of encrypted tiddlers
if(config.options.chkExcludeEncryptedFromLists == true) {
tiddler.tags.push("excludeLists");
}
} else {
// do not encrypt - no password entered
}
break;
} // if (lastBracket...
} // if(tag.indexOf(...
} // for(var g=0;...
} // if(tiddler.tags...
// Then, finally, do the save by calling the function we override.
return store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin(store, tiddler);
};
function CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler) {
if(tiddler && tiddler.tags) {
for(var g=0; g<tiddler.tags.length; g++) {
var tag = tiddler.tags[g];
if(tag.indexOf("Decrypt(") == 0) {
var lastBracket=tag.lastIndexOf(")");
if(lastBracket >= 0) {
if(tiddler.text.substr(0,10) == "Encrypted(") {
var closingSHA1Bracket = tiddler.text.indexOf(")");
var decryptedSHA1 = tiddler.text.substring(10, closingSHA1Bracket);
// Ok, tagged with Decrypt(passwordPrompt)
// extract the passwordPrompt name
var passwordPrompt=tag.substring(8,lastBracket);
// Ok, Decrypt this tiddler!
var decryptedText = tiddler.text.substr(closingSHA1Bracket+2);
decryptedText = HexToString_TiddlerEncryptionPlugin(decryptedText);
// prompt("Decryption request for Tiddler '"+tiddler.title+"'");
var password = GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(passwordPrompt);
if(password) {
decryptedText = TEAdecrypt(decryptedText, password );
var thisDecryptedSHA1 = Crypto.hexSha1Str(decryptedText);
if(decryptedSHA1 == thisDecryptedSHA1) {
tiddler.text = decryptedText;
// Replace the Tag with the Encrypt() tag
tiddler.tags[g]="Encrypt("+passwordPrompt+")";
if(tiddler.tags[tiddler.tags.length-1] == 'excludeLists') {
// Remove exclude lists only if it's the last entry
// as it's automatically put there by encryption
tiddler.tags.length--;
}
if(tiddler.tags[tiddler.tags.length-1] == 'excludeSearch') {
// Remove exclude search only if it's the last entry
// as it's automatically put there by encryption
tiddler.tags.length--;
}
} else {
// Did not decrypt, discard the password from the cache
config.encryptionPasswords[passwordPrompt] = null;
config.encryptionReEnterPasswords = false;
throw "DecryptionFailed";
}
} else {
// no password supplied, dont bother trying to decrypt
config.encryptionReEnterPasswords = false;
throw "DecryptionFailed";
}
} else {
// Tagged as encrypted but not expected format, just leave it unchanged
}
break; // out of for loop
} // if (lastBracket...
} // if(tag.indexOf(...
} // for(var g=0;...
} // if (tiddler && tags)
return tiddler;
};
store.getTiddler_TiddlerEncryptionPlugin = store.getTiddler;
store.getTiddler = function(title) {
var tiddler = store.getTiddler_TiddlerEncryptionPlugin(title);
if(tiddler) { // shadow tiddlers are not expected to be encrypted.
try {
return CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
} catch (e) {
if (config.options.chkShowDecryptButtonInContent == true) {
if(e == "DecryptionFailed") {
var tiddler = store.getTiddler("DecryptionFailed");
if(!tiddler) {
tiddler = new Tiddler();
tiddler.set(title,
"<<EncryptionDecryptThis \"Decrypt\" \"Decrypt this tiddler\" \""+title+"\">>",
config.views.wikified.shadowModifier,
version.date,[],version.date);
}
return tiddler;
} // if(e)
}
return(tiddler);
} // catch
} // if(tiddler) {
return null;
};
store.getTiddlerText_TiddlerEncryptionPlugin = store.getTiddlerText;
store.getTiddlerText = function(title,defaultText) {
// Simply retrieve the tiddler, normally, if it requires decryption, it will be decrypted
var decryptedTiddler = store.getTiddler(title);
if(decryptedTiddler) {
return decryptedTiddler.text;
}
//Ok, rather than duplicate all the core code, the above code should fail if we reach here
// let the core code take over.
return store.getTiddlerText_TiddlerEncryptionPlugin(title,defaultText);
};
// Given a prompt, search our cache to see if we have already entered the password.
// Can return null if the user enters nothing.
function MyPrompt_TiddlerEncryptionPlugin(promptString,defaultValue,context) {
if(!context) {
context = {};
}
context.passwordPrompt = promptString;
PasswordPrompt.prompt(MyPromptCallback_TiddlerEncryptionPlugin, context);
return;
}
function MyPromptCallback_TiddlerEncryptionPlugin(context) {
if(context.callbackFunction) {
context.callbackFunction(context);
} else {
config.encryptionPasswords[context.passwordPrompt] = context.password;
story.refreshAllTiddlers(true);
}
return;
}
function GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString) {
if(!config.encryptionPasswords[promptString]) {
config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin(promptString, "");
}
return config.encryptionPasswords[promptString]; // may be null, prompt can be cancelled.
}
function GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(promptString) {
if(config.encryptionReEnterPasswords) {
return GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
} else {
return config.encryptionPasswords[promptString];
}
}
// Make the encrypted tiddlies look a little more presentable.
function StringToHext_TiddlerEncryptionPlugin(theString) {
var theResult = "";
for(var i=0; i<theString.length; i++) {
var theHex = theString.charCodeAt(i).toString(16);
if(theHex.length<2) {
theResult += "0"+theHex;
} else {
theResult += theHex;
}
if(i && i % 32 == 0)
theResult += "\n";
}
return theResult;
}
function HexToString_TiddlerEncryptionPlugin(theString) {
var theResult = "";
for(var i=0; i<theString.length; i+=2) {
if(theString.charAt(i) == "\n") {
i--; // cause us to skip over the newline and resume
continue;
}
theResult += String.fromCharCode(parseInt(theString.substr(i, 2),16));
}
return theResult;
}
//
// Heavily leveraged from http://trac.tiddlywiki.org/browser/Trunk/contributors/SaqImtiaz/verticals/Hesperian/PasswordPromptPlugin.js Revision 5635
//
PasswordPrompt ={
prompt : function(callback,context){
if (!context) {
context = {};
}
var box = createTiddlyElement(document.getElementById("contentWrapper"),'div','passwordPromptBox');
box.innerHTML = store.getTiddlerText('PasswordPromptTemplate');
box.style.position = 'absolute';
this.center(box);
document.getElementById('promptDisplayField').value = context.passwordPrompt;
var passwordInputField = document.getElementById('passwordInputField');
passwordInputField.onkeyup = function(ev) {
var e = ev || window.event;
if(e.keyCode == 10 || e.keyCode == 13) { // Enter
PasswordPrompt.submit(callback, context);
}
};
passwordInputField.focus();
document.getElementById('passwordPromptSubmitBtn').onclick = function(){PasswordPrompt.submit(callback,context);};
document.getElementById('passwordPromptCancelBtn').onclick = function(){PasswordPrompt.cancel(callback,context);};
},
center : function(el){
var size = this.getsize(el);
el.style.left = (Math.round(findWindowWidth()/2) - (size.width /2) + findScrollX())+'px';
el.style.top = (Math.round(findWindowHeight()/2) - (size.height /2) + findScrollY())+'px';
},
getsize : function (el){
var x = {};
x.width = el.offsetWidth || el.style.pixelWidth;
x.height = el.offsetHeight || el.style.pixelHeight;
return x;
},
submit : function(cb,context){
context.passwordPrompt = document.getElementById('promptDisplayField').value;
context.password = document.getElementById('passwordInputField').value;
var box = document.getElementById('passwordPromptBox');
box.parentNode.removeChild(box);
cb(context);
return false;
},
cancel : function(cb,context){
var box = document.getElementById('passwordPromptBox');
box.parentNode.removeChild(box);
return false;
},
setStyles : function(){
setStylesheet(
"#passwordPromptBox dd.submit {margin-left:0; font-weight: bold; margin-top:1em;}\n"+
"#passwordPromptBox dd.submit .button {padding:0.5em 1em; border:1px solid #ccc;}\n"+
"#passwordPromptBox dt.heading {margin-bottom:0.5em; font-size:1.2em;}\n"+
"#passwordPromptBox {border:1px solid #ccc;background-color: #eee;padding:1em 2em;}",'passwordPromptStyles');
},
template : '<form action="" onsubmit="return false;" id="passwordPromptForm">\n'+
' <dl>\n'+
' <dt class="heading">Please enter the password:</dt>\n'+
' <dt>Prompt:</dt>\n'+
' <dd><input type="text" readonly id="promptDisplayField" class="display"/></dd>\n'+
' <dt>Password:</dt>\n'+
' <dd><input type="password" tabindex="1" class="input" id="passwordInputField"/></dd>\n'+
' <dd class="submit">\n'+
' <a tabindex="2" href="javascript:;" class="button" id="passwordPromptSubmitBtn">OK</a>\n'+
' <a tabindex="3" href="javascript:;" class="button" id="passwordPromptCancelBtn">Cancel</a>\n'+
' </dd>\n'+
' </dl>\n'+
'</form>',
init : function(){
config.shadowTiddlers.PasswordPromptTemplate = this.template;
this.setStyles();
}
};
PasswordPrompt.init();
// http://www.movable-type.co.uk/scripts/tea-block.html
//
// TEAencrypt: Use Corrected Block TEA to encrypt plaintext using password
// (note plaintext & password must be strings not string objects)
//
// Return encrypted text as string
//
function TEAencrypt(plaintext, password)
{
if (plaintext.length == 0) return(''); // nothing to encrypt
// 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but keep
// spaces as spaces (not '%20') so encrypted text doesn't grow too long (quick & dirty)
var asciitext = escape(plaintext).replace(/%20/g,' ');
var v = strToLongs(asciitext); // convert string to array of longs
if (v.length <= 1) v[1] = 0; // algorithm doesn't work for n<2 so fudge by adding a null
var k = strToLongs(password.slice(0,16)); // simply convert first 16 chars of password as key
var n = v.length;
var z = v[n-1], y = v[0], delta = 0x9E3779B9;
var mx, e, q = Math.floor(6 + 52/n), sum = 0;
while (q-- > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word
sum += delta;
e = sum>>>2 & 3;
for (var p = 0; p < n; p++) {
y = v[(p+1)%n];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
z = v[p] += mx;
}
}
var ciphertext = longsToStr(v);
return escCtrlCh(ciphertext);
}
//
// TEAdecrypt: Use Corrected Block TEA to decrypt ciphertext using password
//
function TEAdecrypt(ciphertext, password)
{
if (ciphertext.length == 0) return('');
var v = strToLongs(unescCtrlCh(ciphertext));
var k = strToLongs(password.slice(0,16));
var n = v.length;
var z = v[n-1], y = v[0], delta = 0x9E3779B9;
var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;
while (sum != 0) {
e = sum>>>2 & 3;
for (var p = n-1; p >= 0; p--) {
z = v[p>0 ? p-1 : n-1];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
y = v[p] -= mx;
}
sum -= delta;
}
var plaintext = longsToStr(v);
// strip trailing null chars resulting from filling 4-char blocks:
plaintext = plaintext.replace(/\0+$/,'');
return unescape(plaintext);
}
// supporting functions
function strToLongs(s) { // convert string to array of longs, each containing 4 chars
// note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
var l = new Array(Math.ceil(s.length/4));
for (var i=0; i<l.length; i++) {
// note little-endian encoding - endianness is irrelevant as long as
// it is the same in longsToStr()
l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) +
(s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
}
return l; // note running off the end of the string generates nulls since
} // bitwise operators treat NaN as 0
function longsToStr(l) { // convert array of longs back to string
var a = new Array(l.length);
for (var i=0; i<l.length; i++) {
a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF,
l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
}
return a.join(''); // use Array.join() rather than repeated string appends for efficiency
}
function escCtrlCh(str) { // escape control chars etc which might cause problems with encrypted texts
return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
}
function unescCtrlCh(str) { // unescape potentially problematic nulls and control characters
return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
}
//}}}
Tiddly Wiki Word would not normally be cross-referenced by {{{TiddlyWiki}}} however the {{{[[Tiddly Wiki Word]]}}} syntax will force [[Tiddly Wiki Word]] to be cross-referenced.
/***
|''Name''|TiddlyFileImportr|
|''Version''|0.2.7|
|''Status''|experimental|
|''Source''|https://github.com/jdlrobson/TiddlyWikiPlugins/tree/master/apps/fileimport|
|''Latest''|http://repository.tiddlyspace.com/TiddlyFileImportr|
***/
//{{{
var ImportWizard, WizardMaker;
(function($) {
window.WizardMaker = function(place, wizard) {
var steps = wizard[0];
var options = wizard[1] || {};
$("<h1 />").text(options.heading || "Wizard").appendTo(place);
var wizard = this;
$('<button class="button">restart wizard</button>').click(function(ev) {
wizard.jumpTo(0);
}).appendTo(place)[0];
this.currentStep = 0;
this.body = $('<div class="wizardBody"/>').appendTo(place)[0];
this.steps = steps;
this.values = {};
this.createStep(0);
};
WizardMaker.prototype = {
/*
OPTIONS
step: [function, options]
*/
createStep: function(stepNumber) {
$(this.body).empty();
var step = this.steps[stepNumber];
if(!step) {
throw "invalid step (" + stepNumber + ")"
}
var options = step[1] || {};
var humanStep = stepNumber + 1;
var heading = "Step " + humanStep;
if(options.heading) {
heading += ": " + options.heading;
}
$("<h2 />").text(heading).appendTo(this.body);
var container = $('<div class="wizardStep" />').appendTo(this.body)[0];
step[0](container, this);
},
next: function() {
if(this.currentStep < this.steps.length - 1) {
this.currentStep += 1;
}
this.createStep(this.currentStep);
},
jumpTo: function(step) {
this.currentStep = step;
this.createStep(step);
},
setValue: function(name, val) {
this.values[name] = val;
},
getValue: function(name) {
return this.values[name];
}
};
if(window.FileReader) {
window.ImportWizard = function(options) {
var proxy = options.proxy, saveFunction = options.save,
internalizeTiddler = options.internalizeTiddler, proxyType = options.proxyType || "GET";
return [
[
[function(body, wizard) {
$(body).html('Where do you want to import from? <select><option value="1">file</option><option value="2">the web</option></select><button class="button">ok</button>');
$("button", body).click(function(ev) {
var opt = $("select", body).val();
if(opt === "1") {
wizard.next();
} else {
wizard.jumpTo(2);
}
});
},
{ heading: "File or Web?" }],
[function(body, wizard) {
$(body).html('Browse for a file: <input type="file" size="50" name="txtBrowse"><br><hr><div class="wizardFooter"><div class="message"></div></div>');
function handleFileSelect(evt) {
reader = new FileReader();
reader.onerror = function(e, msg) {
alert("Error occurred")
};
reader.onabort = function(e) {
alert('File read cancelled');
};
reader.onload = function(e) {
var html = reader.result;
wizard.setValue("html", html);
wizard.jumpTo(3)
}
// Read in the image file as a binary string.
window.reader = reader;
reader.readAsText(evt.target.files[0]);
}
$("[type=file]", body)[0].addEventListener('change', handleFileSelect, false);
}, { heading: "Locate TiddlyWiki file" }],
[function(body, wizard) {
$(body).html('Enter the URL or pathname here: <div class="message"></div><input type="text" size="50" name="txtPath"><button class="button">open</button>');
$("button", body).click(function(ev) {
var url = proxy.replace("%0", $("input", body).val())
ajaxReq({
type: options.proxyType,
url: url,
success: function(html) {
wizard.setValue("html", html);
wizard.jumpTo(3);
},
error: function() {
$(".message").html("There is something wrong with that url please try another.");
$("input", body).addClass("error");
}
})
})
},
{ heading: "Import from Web" }],
[function(body, wizard) {
var html = wizard.getValue("html");
var doc = $(html);
var store;
$(html).each(function(i, el) {
if(el.id === "storeArea") {
store = el;
}
});
if(store) {
var tiddlers = [];
$(store).children().each(function(i, el) {
var title = $(el).attr("title");
tiddlers.push(internalizeTiddler(el));
});
$("<div />").text("Choose tiddlers that you wish to import");
var table = $("<table />").appendTo(body)[0];
$("<tr />").html('<th><input type="checkbox" checked/></th><th>title</th>').
appendTo(table)
$("input", table).change(function(ev) {
var checked = $(ev.target).is(':checked');
$("input[type=checkbox]", body).attr("checked", checked);
});
for(var i = 0; i < tiddlers.length; i++) {
var title = tiddlers[i].title;
var row = $("<tr />").data("tiddler", tiddlers[i]).appendTo(table)[0];
$("<td />").html('<input type="checkbox" checked="checked"/>').appendTo(row);
$("<td />").text(title).appendTo(row);
}
$('<button class="button">import all selected tiddlers</button>').click(function(ev) {
var tids = [];
$("input[type=checkbox]:checked").each(function(i, chk) {
var tiddler = $(chk).parents("tr").data("tiddler");
if(tiddler) {
tids.push(tiddler);
}
});
wizard.setValue("selected", tids);
wizard.jumpTo(4)
}).prependTo(body);
}
},
{ heading: "Choose tiddlers" }],
[function(body, wizard) {
var tids = wizard.getValue("selected");
$(body).text("Please wait");
// do import
var save = 0;
var complete = function() {
save += 1;
if(save === tids.length) {
wizard.jumpTo(5);
}
};
$(body).text("Please wait (Importing " + tids.length + " tiddlers)");
for(var i = 0; i < tids.length; i++) {
var tid = tids[i];
$(body).text("Please wait (Importing " + tid.title + ")");
saveFunction(tid, complete);
}
},
{ heading: "Importing" }],
[function(body, wizard) {
$(body).html("Good news! Everything is now imported.");
},
{ heading: "Finished!" }]
],
{
heading: "Import tiddlers from another file or server"
}
];
}
} else {
$("#container").addClass("error").text("Your browser is not modern enough to support this app.");
}
})(jQuery);
(function($) {
if(window.ImportWizard) {
var proxy = "%0", proxyType = "GET";
if(config.extensions.tiddlyspace) {
proxy = "/reflector?uri=%0";
proxyType: "POST";
}
var loader = new TW21Loader();
var internalizer = function(node) {
var title = $(node).attr("title");
var tiddler = new Tiddler(title);
loader.internalizeTiddler(store, tiddler, title, node);
return tiddler;
};
var importer = ImportWizard({proxy:"%0", save: function(tid, callback) {
merge(tid.fields, config.defaultCustomFields);
delete tid.fields["server.page.revision"];
delete tid.fields["server.etag"];
tid = store.saveTiddler(tid.title, tid.title, tid.text,
tid.modifier, tid.modified, tid.tags, tid.fields, null, tid.created, tid.creator);
autoSaveChanges(null, [tid]);
callback();
}, internalizeTiddler: internalizer, proxyType: proxyType });
config.macros.importTiddlers = {
handler: function(place) {
var container = $("<div />").appendTo(place)[0];
new WizardMaker(container, importer);
}
};
} else if(config.macros.importTiddlers) {
var _import = config.macros.importTiddlers.handler;
config.macros.importTiddlers.handler = function(place) {
_import.apply(this, arguments);
jQuery("<div class='annotation error' />").text("Please upgrade your browser to take advantage of the modernised file import mechanism of the TiddlyFileImportr plugin.").prependTo(place);
};
}
})(jQuery);
//}}}
!!Blockquotes
{{{<<<}}}
<<<
Blockquote
All items as needed.
<<<
{{{<<<}}}
Done
!Nested Blockquotes
{{{>}}}Level 1
> Level 1
{{{>>}}}Level 2
>>Level 2
{{{>>>}}}Level 3
>>>Level 3
Done
Convenient Javascript Bookmarklets for editing ~TiddlyWiki from http://lewcid.org/tiddlywiki-bookmarklets/
*Editing
**[[Enable Edit|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){readOnly=false;if(window.backstage){if(!backstage.button)backstage.init();backstage.show();}config.options.chkAnimate=false;refreshDisplay();}})()]]
**[[Setusername|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){var%20g=prompt('Enter%20the%20desired%20user%20name',config.options.txtUserName);var%20t=store.getTiddlers();store.suspendNotifications();for(var%20i=0;i<t.length;i++)t[i].modifier=g;store.resumeNotifications();story.refreshAllTiddlers();}})()]]
**[[Rename Tag|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){var%20oldTag=prompt('Enter%20the%20tag%20to%20rename','oldTag');var%20newTag=prompt('Rename%20tag%20'+oldTag+'%20to:','newTag');var%20t=store.getTaggedTiddlers(oldTag);store.suspendNotifications();for(var%20i=0;i<t.length;i++){t[i].tags.remove(oldTag);t[i].tags.pushUnique(newTag);}store.resumeNotifications();refreshDisplay();}})()]]
**[[Delete All Tagged|javascript:void(eval(decodeURIComponent("(function()%257B%250A%2509if(window.version%2520%2526%2526%2520window.version.title%2520%253D%253D%2520'TiddlyWiki')%257B%250A%2509%2509var%2520tag%2520%253D%2520prompt('Delete%2520tiddlers%2520with%2520the%2520tag%253A'%252C'')%253B%250A%2509%2509store.suspendNotifications()%253B%250A%2509%2509var%2520t%2520%253D%2520store.getTaggedTiddlers(tag)%253B%250A%2509%2509for(var%2520i%253D0%253Bi%253Ct.length%253Bi%252B%252B)%250A%2509%2509%2509store.removeTiddler(t%255Bi%255D.title)%253B%250A%2509%2509store.resumeNotifications()%253B%250A%2509%2509refreshDisplay()%253B%2509%2509%250A%2509%257D%250A%257D)()")))]]
**[[View Shadow Tiddler|javascript:void(eval(decodeURIComponent("(function()%257Bif(window.version%2526%2526window.version.title%253D%253D'TiddlyWiki')%257Bvar%2520shadow%253Dprompt('View%2520the%2520shadow%2520tiddler%2520called%253A')%253Bvar%2520w%253Dwindow.open()%253Bw.document.open()%253Bw.document.write('%253Chtml%253E%253Cbody%253E')%253Bw.document.write('%253Cpre%253E'%252Bconfig.shadowTiddlers%255Bshadow%255D.htmlEncode()%252B'%253C%252Fpre%253E')%253Bw.document.write('%253C%252Fbody%253E%253C%252Fhtml%253E')%253Bw.document.close()%253B%257D%257D)()")))]]
*Rescue and Maintenance
**[[Restore Shadow Tiddlers|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){for(var%20n%20in%20config.shadowTiddlers){store.suspendNotifications();store.removeTiddler(n);store.resumeNotifications();refreshAll();}}})()]]
**[[Safe Mode|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){window.location.hash='start:safe';window.location.reload(true);}})()]]
**[[Super Safe Mode|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){window.location.hash='start:safe';window.location.reload(true);for(var%20n%20in%20config.shadowTiddlers){store.suspendNotifications();store.removeTiddler(n);store.resumeNotifications();refreshAll();}}})()]]
**[[Remove Cookies|javascript:void(eval(decodeURIComponent("(function()%257BC%253Ddocument.cookie.split(%2522%253B%2520%2522)%253Bfor(d%253D%2522.%2522%252Blocation.host%253Bd%253Bd%253D(%2522%2522%252Bd).substr(1).match(%252F%255C..*%2524%252F))for(sl%253D0%253Bsl%253C2%253B%252B%252Bsl)for(p%253D%2522%252F%2522%252Blocation.pathname%253Bp%253Bp%253Dp.substring(0%252Cp.lastIndexOf('%252F')))for(i%2520in%2520C)if(c%253DC%255Bi%255D)%257Bdocument.cookie%253Dc%252B%2522%253B%2520domain%253D%2522%252Bd.slice(sl)%252B%2522%253B%2520path%253D%2522%252Bp.slice(1)%252B%2522%252F%2522%252B%2522%253B%2520expires%253D%2522%252Bnew%2520Date((new%2520Date).getTime()-1e11).toGMTString()%257D%257D)()%250A")))]]
**[[Scrub Tiddler Fields|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){store.forEachTiddler(function(title,tiddler){tiddler.fields={};});refreshDisplay();}})()]]
*Miscellaneous
**[[Tiddler Info|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){alert('TiddlyWiki%20version:%20'+version.major+'.'+version.minor+'.'+version.revision+(version.beta?'%20(beta%20'+version.beta+')':'')+'\nLast%20modified:%20'+document.lastModified);}})()]]
**[[Raw Document|javascript:void(eval(decodeURIComponent("(function()%257Bif(window.version%2526%2526window.version.title%253D%253D'TiddlyWiki')%257Bvar%2520w%253Dwindow.open()%253Bw.document.open()%253Bw.document.write('%253Chtml%253E%253Cbody%253E%253Cpre%253E')%253Bw.document.write(store.allTiddlersAsHtml().htmlEncode())%253Bw.document.write('%253C%252Fpre%253E%253C%252Fbody%253E%253C%252Fhtml%253E')%253Bw.document.close()%253B%257D%257D)()")))]]
**[[Tiddler HTML|javascript:void(eval(decodeURIComponent("(function()%257Bif(window.version%2526%2526window.version.title%253D%253D'TiddlyWiki')%257Bvar%2520title%253Dprompt('Tiddler%2520to%2520view%2520as%2520html%253A')%253Bvar%2520t%253Dstore.getTiddler(title)%253Bvar%2520stat%253DwikifyStatic(t.text%252Cnull%252Ct)%253Bvar%2520w%253Dwindow.open()%253Bw.document.open()%253Bw.document.write('%253Chtml%253E%253Cbody%253E')%253Bw.document.write('%253Cpre%253E'%252Bstat.htmlEncode()%252B'%253C%252Fpre%253E')%253Bw.document.write('%253C%252Fbody%253E%253C%252Fhtml%253E')%253Bw.document.close()%253B%257D%257D)()")))]]
**[[Tidder Raw JavaScript|javascript:void(eval(decodeURIComponent("%250A%2509if(window.version%2520%2526%2526%2520window.version.title%2520%253D%253D%2520'TiddlyWiki')%257B%250A%2509%2509var%2520title%2520%253D%2520prompt('Tiddler%2520to%2520view%2520as%2520JavaScript%2520string%253A')%253B%250A%2509%2509var%2520text%2520%253D%2520store.getTiddlerText(title).replace(%252F%2522%252Fg%252C'%255C%255C%2522').split(%2522%255Cn%2522).join('%255C%255Cn%2522%252B%255Cn%2520%2522')%253B%250A%2509%2509var%2520w%253Dwindow.open()%253B%250A%2509%2509w.document.open()%253B%250A%2509%2509w.document.write('%253Chtml%253E%253Cbody%253E')%253B%250A%2509%2509w.document.write('%253Cpre%253E'%252Btext.htmlEncode()%252B'%253C%252Fpre%253E')%253B%250A%2509%2509w.document.write('%253C%252Fbody%253E%253C%252Fhtml%253E')%253B%250A%2509%2509w.document.close()%253B%2509%2509%250A%2509%257D")))]]
|! Browser |! Compatible |! Tweaks |
| Firefox 3.x | yes | To turn off requests for permission set security.fileuri.strict_origin_policy to 'false' in about:config |
| Chrome | readonly | Write access requires the [[TiddlySaver.jar|http://www.tiddlywiki.com/TiddlySaver.jar]] Java file (Same Folder) |
|! [[excludeSearch]] |! [[excludeLists]] |! [[excludeMissing]] |! [[excludeWikiLinks]] |
|excludes a tiddler from search results |excludes a tiddler from the lists in the sidebar tabs (e.g. Timeline), as well as from the generated RSS feed |excludes a tiddler from the processing that generates the Missing Tiddlers list | excludes a tiddler from automatically wikifying words. Also overrides any auto-wikification of words listed in it as a tiddler |
|<<list filter [tag[excludeSearch]]>> |<<list filter [tag[excludeLists]]>> |<<list filter [tag[excludeMissing]]>> |<<list filter [tag[excludeWikiLinks]]>> |
!!!!See Also:
TiddlyWikiSystemTags
|! Format |! Format Style |! Output |! Notes |
| Monospace (Unformatted) | {{{ {{{ }}} {{{Monospaced}}} {{{ }}} }}} | {{{Monospaced}}} | No Space required; Inaccuracy due to Using Monospace to format itself |
| Wikification Off | {{{"""No TiddlyWiki [[Wikification]]"""}}} | """No TiddlyWiki [[Wikification]]""" |
| | {{{<nowiki>No TiddlyWiki [[Wikification]]</nowiki>}}} | <nowiki>No TiddlyWiki [[Wikification]]</nowiki> |
| Bold | {{{ ''Bold'' }}} | ''Bold'' | Two pair of single quotes, //not// one pair of double quotes |
| Strikethrough | {{{ --Strikethrough-- }}} | --Strikethrough-- |
| em-dash | {{{--}}} | -- | Note: {{{--}}}"Character" Initiates Strikethrough; {{{--}}} with spaces on either side is an em-dash |
| Underline | {{{ __Underlined__ }}} | __Underlined__ |
| Italics | {{{ //Italic// }}} | //Italic// |
| Superscript | {{{2^^3^^ = 8}}} | 2^^3^^ = 8 |
| Subscript | {{{a~~ij~~ = -a~~ji~~}}} | a~~ij~~ = -a~~ji~~ |
| Highlighted Text | {{{@@Highlighted Text@@}}} | @@Highlighted Text@@ | This actually accesses CSS Classes. Obviously to someone of skill much more power is available. |
| Color Text | {{{@@color(red):Red colored text@@}}} | @@color(red):Red colored text@@ |~|
| Invisible Tiddler Comment | {{{/%Invisible Tiddler Comment%/}}} | /% Invisible Tiddler Comment%/ |
| HTML Comment | {{{<!----- HTML comment ------>}}} | | These cause Formatting issues, not including in Output |
| Multiline Comment | {{{/* TiddlyWikiWord */}}} |
| Multiline comment with Wikification | {{{/*** TiddlyWikiWord ***/}}} |
| Tiddly Wiki Text Formatting |c
{{{!}}}Header 1
!Header 1
{{{!!}}}Header 2
!!Header 2
{{{!!!}}}Header 3
!!!Header 3
{{{----}}} Horizontal Rule
----
|! Link Style |! Format |! Example |! Notes |
|>|>|>| Internal Links (~Cross-Referencing) |
| Standard ~WikiWord | {{{TiddlyWikiWord}}} | TiddlyWikiWord | {{{TiddlyWiki}}} automatically cross-references all words mixing lowercase/capitals beyond the first letter |
| Forced ~WikiWord | {{{[[Tiddly Wiki Word]]}}} | [[Tiddly Wiki Word]] | This forces {{{TiddlyWiki}}} to cross-reference an word |
| Named ~WikiWord | {{{[[This Tiddly Wiki Word|TiddlyWikiWord]]}}} | [[This Tiddly Wiki Word|TiddlyWikiWord]] | This links a Title to a Wikiword; It also forces the cross-reference if none already existed |
| Non ~WikiWord | {{{ ~TiddlyWikiWord}}} | ~TiddlyWikiWord | Force {{{TiddlyWiki}}} to not cross-reference a word that would normally be crossreference |
| Missing ~WikiWord | | TiddlyWikiHelp | Any cross-reference that has no active content will appear as here; If the word corresponds to a tag, tiddler's so tagged will be automatically listed |
| Inline SVG | {{{<<SVG "<svg code>">>}}} | <<SVG "<circle r='50' cx='50' cy='50' fill='green'/>">> | Requires the [[inlineSVG]] Plugin. <br> There is some question how much this will do - this has only been tested on firefox, <br> and there are some indications of issues with some SVG effects. |
|>|>|>| External Links |
| Standard Link | {{{http://www.domain.tld/path}}} | http://www.tiddlywiki.com | |
| Named Link | {{{[[Website|http://www.domain.tld/path]]}}} | [[Tiddly Wiki Homepage|http://www.tiddlywiki.com]] |
| Image link | {{{[img[picturename|http://www.domain.tld/path]]}}} | [img[Google Logo|http://www.google.com/intl/en_ALL/images/logo.gif]] | |
| SVG Image | {{{<html>}}}<br>{{{<object data="}}}URL{{{" type="image/svg+xml" width="}}}y{{{" height="}}}x{{{">}}}<br>{{{<embed src="}}}URL{{{" type="image/svg+xml" width="}}}y{{{" height="}}}x{{{" />}}}<br>{{{ </object>}}}<br>{{{</html>}}} | <html> <object data="http://openclipart.org/people/oksmith/oksmith_penguin.svg" type="image/svg+xml" width="200" height="100"> <embed src="http://openclipart.org/people/oksmith/oksmith_penguin.svg" type="image/svg+xml" width=100" height="50" /> </object> </html> | First, there seems to be a lot of this you can cull, but I haven't figured out the interactions yet, even withing Firefox, nevermind other browsers. Second, there seem to be ways to inline svg into Tiddlywiki internally, which would be *really* cool, but sadly all the examples I've come across are interactive systems I have yet to figure out. If anyone figures out how to do simple, non-interactive SVG inline, I'd appreciate a heads-up [[Pugugly]] |
|>|>|>| Local Links: File Links use the same format as other external links; The file path must be preceded by the {{{file:///}}} prefix |
| {{{TiddlyWiki}}} Link Formats |c
!!Bulleted lists
{{{*}}}Dots
{{{**}}}Circles
{{{***}}}Squares
*Dots
**Circles
***Squares
!!Numbered lists
{{{#}}}Numeric
{{{##}}}Alphabetic
{{{###}}}Roman Numerals
#Numeric
##Alphabetic
###Roman Numerals
!!Definitions
{{{;Definition Term, Term}}}
{{{:Definition List, Description}}}
;Definition Term, Term
:Definition List, Description
{{{TiddlyWiki}}} and it's plugins allow for macros to be added into any tiddler via the {{{ <<macro>> }}} syntax - all 'buttons' and many other items are actually macros initiated via ~JavaScript.
{{{<<list filter [tag[TiddlyWikiMacros]]>>}}} Produces
<<list filter [tag[TiddlyWikiMacros]]>>
Inside a stylesheet the syntax changes slightly. Thus:
{{{
<div macro="showWhen tiddler.tags.contains('author')">
<div class="authorList" macro="list filter {{'[modifier ['+this.tiddler.modifier+']]'}}"></div>
</div>
}}}
!!!!More Information:
http://tiddlywiki.org/wiki/Core_Macros
http://www.tiddlywiki.com/#Macros
Several Macros take a DateFormatString as an optional argument.
This string can be a combination of ordinary text, with some special characters that get substituted by parts of the date:
|! String |! Full |! Abbreviated |! Numeric |! Leading 0 |! Other |
|! Year | {{{YYYY}}} <br> <<today YYYY>> | {{{YY}}} <br> <<today YY>> |
|! Year <br> (Week Number) | {{{wYYYY}}} <br> <<today wYYYY>> | {{{wYY}}} <br> <<today wYY>> |
|! Month | {{{MMM}}} <br> <<today MMM>> | {{{mmm}}} <br> <<today mmm>> | {{{MM}}} <br> <<today MM>> | {{{0MM}}} <br> <<today 0MM>> |
|! Week | | | {{{WW}}} <br> <<today WW>> | {{{0WW}}} <br> <<today 0WW>> |
|! Day | {{{DDD}}} <br> <<today DDD>> | {{{ddd}}} <br> <<today ddd>> | {{{DD}}} <br> <<today DD>> | {{{0DD}}} <br> <<today 0DD>> | {{{DDth}}} <br> <<today DDth>> |
|! 12 Hour Clock | | | {{{hh12}}} <br> <<today hh12>> | {{{0hh12}}} <br> <<today 0hh12>> | {{{AM}}}/{{{am}}} <br> {{{PM}}}/{{{pm}}} <br> <<today AM>>/<<today pm>> |
|! Hours | | | {{{hh}}} <br> <<today hh>> | {{{0hh}}} <br> <<today 0hh>> |
|! Minutes | | | {{{mm}}} <br> <<today mm>> | {{{0mm}}} <br> <<today 0mm>> |
|! Seconds | | | {{{ss}}} <br> <<today ss>> | {{{0ss}}} <br> <<today 0ss>> |
| Date Format Options |c
; Version Macro
: {{{<<version>>}}}
:: <<version>>
;today Macro
: {{{<<today (Optional "}}}[[DateFormatString|TiddlyWikiMacros:DateFormatString]]{{{")>>}}}
: Default: {{{<<today>>}}}
:: <<today>>
: {{{<<today "YYYY-0MM-0DD 0hh:0mm">>}}}
:: <<today "YYYY-0MM-0DD 0hh:0mm">>
|! Name |! Syntax |!Result |!Notes|
|! Search Field | {{{<<search>>}}} | <<search>> |
|! Close All Tiddlers | {{{<<closeAll>>}}} | <<closeAll>> |
|! Permaview | {{{<<permaview>>}}} | <<permaview>> |
|! Option | {{{<<option [(txt|chk)CookieName]>>}}} | <<option txtCookie>> <<option chkCookie>> | Create a checkbox/textbox to set or toggle any Cookie<br>txt/chk prefix determines cookie type |
|! Save Changes | {{{<<saveChanges>>}}} | <<saveChanges>> |
|! Message | {{{<<message>>}}} | <<message>> | -?- |
|! View | {{{<<view>>}}} | <<view>> | -?- |
|! Edit | {{{<<edit>>}}} | <<edit>> | -?- |
|! Tag Chooser | {{{<<tagChooser>>}}} | <<tagChooser>> |
|! Toolbar | {{{<<toolbar [}}}[[toolbarMacro|TiddlyWikiMacros:ToolbarMacros]]{{{] >>}}} | <<toolbar>> | Default Options are in [[ToolbarCommands]] <br> These can be edited there or overridden via [[systemTheme]] |
|! Refresh Display | {{{<<refreshDisplay>>}}} | <<refreshDisplay>> | -- |
|! Annotations | {{{<<annotations>>}}} | <<annotations>> | -?- |
|! Panels |>|>|>|
|! Import Tiddlers | {{{<<importTiddlers>>}}} | [[ImportTiddlers]] |
|! Options | {{{<<options>>}}} | [[AdvancedOptions]] |
|! Plugins | {{{<<plugins>>}}} | [[PluginManager]] |
|! Backstage | {{{<<backstage>>}}} | <<backstage>> | -?- |
|! Upgrade | {{{<<upgrade>>}}} | -- | Upgrade to current TiddlyWiki Version |
|! Sync Tiddlers | {{{<<sync>>}}} | -- | Sync Tiddlers with sync field with [[systemServer]] |
; newTiddler
: {{{<<newTiddler (Optional parameter:values)>>}}}
|!Parameter |!Description |
|label |The text of the button |
|prompt |The tooltip for the button |
|accessKey |The access key to trigger the button (specify a single letter; different browsers require a different modifier key like Alt- or Control-) |
|focus |Which of the editable fields to default the focus to (eg, "title", "text", "tags") |
|template |The template to use to display the new tiddler (defaults to EditTemplate) |
|text |The default text for the new tiddler |
|title |The default title for the new tiddler |
|tag |A single tag to be applied to the new tiddler (repeat this parameter to specify multiple tags) |
; newJournal
: {{{<<newJournal (Optional parameter:values)>>}}}
: newJournal is virtually identical to newTiddler except it treats the Title as a [[DateFormatString|TiddlyWikiMacros:DateFormatString]].
Macro's introduced by StoryWiki Plugins are listed here.
! [[CopyTiddlerPlugin]]
: {{{<<copyTiddler [TiddlerName] [Title(Default: "Tiddler Title (#)] [tooltip]>>}}}
! [[DeleteAllTaggedPlugin]]
: {{{<<deleteAllTagged [TagName]>>}}}
! [[DisableWikiLinksPlugin]]
: {{{<<option chkDisableWikiLinks>>}}}
::Disable ALL automatic WikiWord tiddler links
: {{{<<option chkAllowLinksFromShadowTiddlers>>}}}
:: ... except for WikiWords //contained in// shadow tiddlers
: {{{<<option chkDisableNonExistingWikiLinks>>}}}
:: Disable automatic WikiWord links for non-existing tiddlers
: {{{<<option txtDisableWikiLinksList>>}}}
:: Disable automatic WikiWord links for words listed in:
: {{{<<option txtDisableWikiLinksTag>>}}}
::Disable automatic WikiWord links for tiddlers tagged with:
! [[HideWhenPlugin]]
|! Used in Templates for toggling items. |>|
| {{{<<hideWhen>>}}} | {{{<<showWhen>>}}} |
| {{{<<hideWhenTagged>>}}} | {{{<<showWhenTagged>>}}} |
| {{{<<hideWhenTaggedAny>>}}} | {{{<<showWhenTaggedAny>>}}} |
| {{{<<hideWhenTaggedAll>>}}} | {{{<<showWhenTaggedAll>>}}} |
| {{{<<hideWhenExists>>}}} | {{{<<showWhenExists>>}}} |
| {{{<<hideWhenTitleIs>>}}} | {{{<<WhenTitleIs>>}}} |
| {{{<<else>>}}} |>|
![[NewHerePlugin]]
:{{{<<newHere>>}}}
:{{{<<newJournalHere>>}}}
![[SaveAsPlugin]]
:{{{<<saveAs>>}}}
![[SaveCloseTiddlerPlugin]]
//Used in Toolbar//
:{{{<<toolbar saveCloseTiddler>>}}}
:{{{<<toolbar cancelCloseTiddler>>}}}
![[SetUserNamePlugin]]
:{{{<<setUserName [force]>>}}}
![[TagglyTaggingPlugin]]
:{{{<<tagglyTagging [TagName]>>}}}
![[TiddlerEncryptionPlugin]]
: {{{<<EncryptionChangePassword>>}}}
:: Change passwords of encrypted tiddlers.
: {{{<<EncryptionDecryptAll>>}}}
:: Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
: {{{<<option chkExcludeEncryptedFromSearch>>}}}
:: If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
: {{{<<option chkExcludeEncryptedFromLists>>}}}
:: If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
: {{{<<option chkShowDecryptButtonInContent>>}}}
::If set, Encrypted Tiddlers content is replaced by {{{<<EncryptionDecryptThis>>}}} button. This has consequences, in the current version as, if you edit the tiddler without decrypting it, you lose the contents.
![[TspotSetupPlugin]]
: {{{<<option pasUploadPassword>>}}}
: {{{<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>}}}
![[UploadPlugin]]
: {{{<<upload (parameters)>>}}}
: {{{<<uploadOptions>>}}}
![[inlineSVG]]
: {{{<<svg "SVG Code">>}}}
! Unknown
: {{{<<miniTag>>}}}
|! Name |!Syntax |!Result |!Notes |
| Tagging Macro | {{{<<tagging TiddlyWikiMacros>>}}} | <<tagging TiddlyWikiMacros>> | The Tag/Tagging macros refer to items //tagged with the named// Tag/Tiddler. <br> The Tags Macro returns items the //named Tiddler is tagged with//. |
| Tag Macro | {{{<<tag TiddlyWikiMacros>>}}} | <<tag TiddlyWikiMacros>> |~|
| Tags Macro | {{{<<tags TiddlyWikiMacros>>}}} | <<tags TiddlyWikiMacros>> |~|
; Note
: A tag and a tiddler are neither mutually exclusive, nor the same thing;
: A tag is created because another Tiddler references it in the 'tags' field
: A tiddler is created because it has content created for it.
: An entry in tiddlywiki can be a tag, a tiddler, or both.
|! Name |!Syntax |!Result |!Notes |
| Tiddler Macro | {{{<<tiddler TiddlyWikiMacros>>}}} | <<tiddler TiddlyWikiMacros>> | Exactly as simple as it seems - just inserts a tiddler inline in another tiddler |
| Slider Macro | {{{<<slider chkSliderCookie TiddlyWikiMacros "TiddlyWikiMacros Slider" "TiddlyWikiMacros mouseover text">>}}} | <<slider chkSliderCookie TiddlyWikiMacros "TiddlyWikiMacros Slider" "TiddlyWikiMacros mouseover text">> |
| Tab Macro | {{{<<tabs txtTabCookie "Tab One Title" "Tab One MouseOver Text" TiddlyWikiMacros "Tab Two Title" "Tab Two MouseOver Text" TiddlyWikiMacros:VisualEffects>>}}} | <<tabs txtTabCookie "Tab One Title" "Tab One MouseOver Text" TiddlyWikiMacros "Tab Two Title" "Tab Two MouseOver Text" TiddlyWikiMacros:VisualEffects>> | Obviously, you can have more than two tabs |
| These Tiddlers can import other tiddlers from a wiki into a Tiddler |c
|! Name |!Syntax |!Result |!Notes |
| Timeline Macro | {{{<<timeline [date(modified|created)] [length] ["}}}[[DateFormatString|TiddlyWikiMacros:DateFormatString]]{{{"]>>}}} | <<timeline created 10 "YYYY-0MM-0DD">> |
| AllTags Macro | {{{<<allTags>>}}} | <<allTags>> | Does not respect the [[excludeLists]] Tag |
| List Macro | {{{<<list [type]>>}}} | <<list>> | [type]:<br> all (default)<br>missing<br>ophans<br>shadowed<br>touched<br>[[filters|TiddlyWikiMacros:filters]] |
The [[ToolbarMacro|http://www.tiddlywiki.com/#ToolbarMacro]] is used in the TiddlerTemplateMechanism to define the toolbar that appears when the mouse is hovered over a tiddler. It looks like this:
{{{
<<toolbar closeTiddler -editTiddler +jump>>
}}}
The arguments to the ToolbarMacro are a list of command names.
You can precede a command name with a "+" to specify a default command that is automatically chosen when a tiddler is double-clicked, or the ctrl-Enter key combination pressed. Similarly, precede it with "-" to specify a command to be chosen when the Escape key is pressed.
|! Name |! Syntax |!Result |!Notes|
|! Cancel Tiddler | {{{<<toolbar cancelTiddler>>}}} | <<toolbar cancelTiddler>> | Abandons any pending edits to the current tiddler and switches it the default view |
|! Close Others | {{{<<toolbar closeOthers>>}}} | <<toolbar closeOthers>> | Closes all other open tiddlers except for any that are being edited |
|! Close Tiddler | {{{<<toolbar closeTiddler>>}}} | <<toolbar closeTiddler>> | Closes the current tiddler regardless of whether it is being edited |
|! Delete Tiddler | {{{<<toolbar deleteTiddler>>}}} | <<toolbar deleteTiddler>> | Deletes the current tiddler |
|! Edit Tiddler | {{{<<toolbar editTiddler>>}}} | <<toolbar editTiddler>> | Switches the current tiddler to the current edit view |
|! View Tiddler | {{{<<toolbar viewTiddler>>}}} | <<toolbar viewTiddler>> | Switches the current tiddler to the current edit view |
|! Jump | {{{<<toolbar jump>>}}} | <<toolbar jump>> | Offers a pop-up menu to jump directly to any of the currently open tiddlers |
|! Permalink | {{{<<toolbar permalink>>}}} | <<toolbar permalink>> | Changes the browser address bar to a permalink to the current tiddler |
|! References | {{{<<toolbar references>>}}} | <<toolbar references>> | Offers a pop-up menu displaying the tiddlers that link to the current one |
|! Save Tiddler | {{{<<toolbar saveTiddler>>}}} | <<toolbar saveTiddler>> | Saves any pending edits to the current tiddler, and switches it to the default view |
|!Name |!Syntax |!Result |!Notes |
| [[GradientMacro|http://www.tiddlywiki.com/#GradientMacro]] | {{{<<gradient vert #ffffff #ffdddd #ff8888>>gradient fill>>}}} | <<gradient vert #ffffff #ffdddd #ff8888>>gradient fill>> | The first parameter can be vert or horiz to declare the direction of the gradient|
;filter
: {{{[filter[<+|->value]]}}}
::{{{<<list filter [tag[systemConfig]][sort[-modified]]>>}}} <br> //or//
::{{{<<list filter "[tag[systemConfig]] [sort[-modified]]">>}}}
[edit] Filters
Filters are designed to work by tiddler fields
However only the tag and sort fields seem to work consistently as of version 2.52 (at least within the List Macro)
* title
* tag
* created
* modified
* modifier
* sort
;Links
*[[TiddlyWiki.Org --> Filtering|http://tiddlywiki.org/wiki/Filtering]]
*[[How to list tiddlers by tags the filter tipped way|http://lewcid.org/2007/10/23/how-to-list-tiddlers-by-tags-the-filter-tipped-way/]]
<<newTiddler label:"New Plugin" prompt:"Create a new Plugin" title:"New Plugin" focus:title text:"This will need need systemconfig added to activate it:" tag:systemConfigRegistry tag:excludeLists tag:excludeSearch>>
//Any other new Plugin should be added to {{{systemConfigRegistry}}} manually//
@@The {{{systemConfigRegistry}}} tag is //not// a system tag, and imported Plugins are not automatically registered to it;@@
To Activate a Plugin, add the systemConfig tag and reload;
to Deactivate a plugin remove systemConfig tag and reload;
|! [[systemConfigRegistry]] |! [[systemConfig]] |
|<<list filter [tag[systemConfigRegistry]]>> |<<list filter [tag[systemConfig]]>> |
<<<
Note: @@By it's nature, once initiated, Hardcoding the readonly option to "true" is //not// trivial to revert.@@
<<<
<<<
Note: There is a minor, but problematic conflict between TiddlyLockPlugin and the SetUserNamePlugin. ~TiddlyLock will 'lock' the directory *before* setusername forces you to change your name from "~YourName"
This will of course mean your username does not match the username documented in the lock file, so you cannot edit or save. Changing your username between the time you start editing and save changes has the same results.
You must then delete the *.lck file in order to free the system back up.
If you save changes, change username, then edit again, there should not be an issue.
<<<
!!!!See Also:
TiddlyWikiSystemTags
PluginManager
ImportTiddlers
!!!!More Information:
[[Importing Plugins|http://tiddlywiki.org/wiki/ImportTiddlers]]
[[Tiddly Vault|http://tiddlyvault.tiddlyspot.com/]]
Additional Resources
*~Semi-Official
**[[Official TiddlyWiki website|http://www.tiddlywiki.com]]
**[[TiddlyWiki.org|http://tiddlywiki.org/wiki/Main_Page]]
**[[Community-based TiddlyWiki documentation|http://doc.tiddlywiki.org]]
**[[TiddlyWiki development|http://trac.tiddlywiki.org/]]
**[[Wikipedia Entry|http://en.wikipedia.org/wiki/TiddlyWiki]]
**[[Specifications|http://www.wikimatrix.org/show/TiddlyWiki]]
*Tutorials
**[[TwiddleWiki for the Rest of Us|http://www.giffmex.org/twfortherestofus.html]]
**[[A Cheatsheet (PDF) |http://nothickmanuals.info/doku.php/cheatsheets]]
**[[TiddlyWiki guides|http://tiddlywikiguides.org]]
*Customization
**[[TiddlyWiki themes|http://tiddlythemes.com]]
*[[TiddlySpot Wiki's|http://tiddlyspot.com]]
**[[GTDTiddlyWiki|http://shared.snapgrid.com/index.html]]
**[[MonkeyGTD|http://monkeygtd.tiddlyspot.com]]
**[[TiddlyWiki FAQ|http://twfaq.tiddlyspot.com/]]
**[[TW Help|http://twhelp.tiddlyspot.com/]]
**[[MonkeyPirateTiddlyWiki|http://mptw.tiddlyspot.com/]]
*Blogs/Lists
**[[TiddlyWiki Google group|http://groups.google.com/group/TiddlyWiki/topics]]
**[[A Software Blog|http://softwareas.com/tag/tiddlywiki]]
**[[Tiddly Learning|http://lewcid.org/category/tiddlywiki/]]
**[[Tiddly Bookmarklets|http://lewcid.org/tiddlywiki-bookmarklets/]]
TiddlyWiki has no built in SVG support, but basic SVG can be implemented with the [[inlineSVG]] plugin and {{{<<SVG "<svg code>">>}}} macro.
AlternateSyntax: {{{<<SVG height: xxx width: xxx svg:'svgcode'>>}}}
!!!SVG Information/Tutorials on the Web
*[[Scalable Vector Graphics (SVG) 1.1 Specification|http://www.w3.org/TR/SVG/]]
*[[W3C SVG Tutorial|http://www.w3schools.com/svg/default.asp]]
*[[Pike's SVG Tutorial|http://apike.ca/prog_svg.html]] (From which most of the examples here have been stolen)
!!!Examples/Tests
<<list filter [tag[TiddlyWikiSVG]]>>
{{{TiddlyWiki}}} can accept commands via the HTML "#" anchor to modify startup conditions;
Some Examples
|!Command |!Description |!Example |
| start:safe | Switches to ~SafeMode; Holds all plugins and cookies | [[Restart in Safe Mode|#start:safe]] |
| readOnly:yes | Opens a new copy in readOnly mode | [[Read Only Mode|#readOnly:yes]] |
| open:title | Opens the tiddler with the specified title | [[Tiddly Wiki Startup|#open:TiddlyWikiStartup]] |
| search:text | Performs a search for the specified text | [[Search for jwest|#search:jwest]] |
| Firefox Search | Firefox will with a defined keyword, perform a search | [[Firefox Search URL|#search:%s]] |
| IE Search | This [[Microsoft Website|http://www.microsoft.com/windows/ie/searchguide/en-en/default.mspx]] will convert search 'TEST' to an XML plugin | [[IE Search URL|#search:TEST]] |
| tag:text | Displays tiddlers tagged with the specified tag | [[Help listing|#tag:TiddlyWikiHelp]] |
| newTiddler:title | Opens a new tiddler with the specified title in edit mode | [[New Entry|#newTiddler:"New Entry"]] |
| newJournal:titleFormat | Opens a new tiddler with the specified ~DateFormatString | [[New Journal|#newJournal:"YYYY MMM DD"]] |
Many of these can be generated automatically via the permaview [[macro|TiddlyWikiMacros]]: <<permaview>>
!!!!More Information:
http://tiddlywiki.org/wiki/Startup_Parameters
http://www.tiddlywiki.com/#StartupParameters
|! [[systemConfig]] |! [[systemConfigDisable]] |! [[systemConfigForce]] |! [[systemServer]] |! [[systemTheme]] |
|marks tiddlers containing ~JavaScript code that should be executed on startup (usually plugins or macros) |prevents tiddler contents from being executed on startup (takes precedence over systemConfig and systemConfigForce) |force tiddler contents to be executed on startup |indicates that the respective tiddler contains server details for importing |Indicates themes |
|<<list filter [tag[systemConfig]]>> |<<list filter [tag[systemConfigDisable]]>> |<<list filter [tag[systemConfigForce]]>> |<<list filter [tag[systemServer]]>> |<<list filter [tag[systemTheme]]>> |
!!!!See Also:
TiddlyWikiExcludeTags
TiddlyWikiPlugins
!!!!More Information:
http://tiddlywiki.org/wiki/Tags
|! {{{|!Table heading 1 |}}} |! {{{!Table heading 2 |}}} |! {{{|!Table heading 3 |}}} |
|>|{{{|>| Span +1 Column) | }}} |
|>|>|{{{|>|>| Span +2 Columns) | }}} |
| {{{ Span +1 Row |}}} {{{|~|}}} |{{{|Align Left |}}} |
|~| {{{| Align Right| }}}|
|bgcolor(#a0ffa0):{{{| bgcolor(#a0ffa0): text |}}} | {{{| Align Center |}}} |
| {{{| Caption Table |c}}} |c
!!!!More Information:
http://tiddlywiki.org/wiki/Tables
TiddlyWikiWord is automatically cross-referenced by {{{TiddlyWiki}}} however the {{{~TiddlyWikiWord}}} syntax will force ~TiddlyWikiWord to not be cross-referenced.
{{{
<<SVG '<g transform="scale(5) translate(15, 15) rotate(20) skewX(20) skewY(5)" >
<rect x="10" y="10" width="5" height="5" fill="firebrick" />
<circle r="10" fill="seagreen" stroke="blue"/>
<rect x="5" y="5" width="12" height="2" fill="gray" stroke="silver"/>
</g>'>>
}}}
<<SVG '<g transform="scale(5) translate(15, 15) rotate(20) skewX(20) skewY(5)" >
<rect x="10" y="10" width="5" height="5" fill="firebrick" />
<circle r="10" fill="seagreen" stroke="blue"/>
<rect x="5" y="5" width="12" height="2" fill="gray" stroke="silver"/>
</g>'>>
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'storywiki';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 08/05/2010 13:42:52 | Pugugly | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . | ok |
| 08/05/2010 13:48:11 | Pugugly | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 08/05/2010 13:54:32 | Pugugly | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 08/05/2010 14:03:13 | Pugugly | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . | ok |
| 08/05/2010 14:16:51 | Pugugly | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 08/05/2010 14:18:55 | StoryWiki | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 24/05/2010 19:26:53 | StoryWiki | [[storywiki(5).html|file:///C:/Documents%20and%20Settings/jwest/My%20Documents/Downloads/storywiki(5).html]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . | failed |
| 24/05/2010 19:27:10 | StoryWiki | [[storywiki(5).html|file:///C:/Documents%20and%20Settings/jwest/My%20Documents/Downloads/storywiki(5).html]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 30/07/2010 02:36:18 | othername | [[storywiki.html|file:///home/jewest/Downloads/storywiki.html]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
| 03/07/2013 03:16:09 | StoryWiki | [[/|http://storywiki.tiddlyspot.com/]] | [[store.cgi|http://storywiki.tiddlyspot.com/store.cgi]] | . | [[index.html | http://storywiki.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
var wizard = new Wizard();
wizard.createWizard(place,this.wizardTitle);
wizard.addStep(this.step1Title,this.step1Html);
var markList = wizard.getElement("markList");
var listWrapper = document.createElement("div");
markList.parentNode.insertBefore(listWrapper,markList);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
for(n=0; n<opts.length; n++) {
var type = opts[n].name.substr(0,3);
var h = config.macros.option.types[type];
if (h && h.create) {
h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
return revised;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
/***
|''Name:''|configAdvancedOptionsHardcodePlugin|
|''Description:''|Creates an [[AdvancedOptionsHardcode]] ShadowTiddler to permanently set options normally saved by cookies. Creates shadow tiddlers for important tags. |
|''Version:''|1.0|
|''Date:''|May 07, 2009|
|''Source:''|http://storywiki.tiddlyspot.com |
|''Author:''|[[Pugugly001|mailto:pugugly001@gmail.com]] |
|''License:''|Publicly Documented Tweak|
|''~CoreVersion:''|2.2.0|
|''Notes:''|This Tiddler needs to be at or near the end of the loadout since it can only document environmental variables that exist when it loads. Any Variables created or modified after this tiddler is executed will not be reflected in the variable listing. It is worth noting that this plug-in happily grabs every variable under config.options[x], including sliders, tabs, and other trivia. |
***/
//{{{
//----------------------------------------------------------------------------------------------------
// This Plug-in name
var ThisPlugin='configAdvancedOptionsHardcodePlugin';
//----------------------------------------------------------------------------------------------------
// Target Shadowtiddler name
var TargetShadowTiddler='AdvancedOptionsHardcode';
//----------------------------------------------------------------------------------------------------
// AdvancedOptionsHardcode Headers
var header='';
header+= '/***';
header+= '\n|!\'\'Name:\'\'|Generated by ['+'['+ThisPlugin+']]|';
header+= '\n|!\'\'Description:\'\'|This Generated "~ShadowPlugin" can be used as a template for saving any and all configuration options nominally saved by cookies: simply edit as required and add the relevant tags to this shadowtiddler. |';
header+= '\n|!\'\'Version:\'\'|1.0 |';
header+= '\n|!\'\'Date:\'\'|May 07, 2009 |';
header+= '\n|!\'\'Author:\'\'|Dynamically Generated |';
header+= '\n|!\'\'License:\'\'|Dynamically Generated |';
header+= '\n|!\'\'~CoreVersion:\'\'|2.2.0|';
header+= '\n***/';
config.shadowTiddlers[TargetShadowTiddler] = header;
//----------------------------------------------------------------------------------------------------
// Generated Javascript
var body='';
body += '\n//{{{';
var x;
for (x in config.options)
{
tab = 50;
var line = '\n';
var quotes;
if (typeof(config.options[x])=="string")
{quotes='"'}
else
{quotes=''}
line += '//config.options.'+x;
while (line.length<tab){ line += " ";}
line += ' = '+quotes+config.options[x]+quotes+';';
if (config.optionsDesc[x] != undefined) {
tab+=20
while (line.length<tab){ line += " ";}
line += ' // Description: '+config.optionsDesc[x]
}
body+=line
}
body+= '\n//}}}';
config.shadowTiddlers[TargetShadowTiddler]+= body
//----------------------------------------------------------------------------------------------------
// Adding hidden but important tags to the shadow-tiddlers, plus my unofficial repositories.
// Since I prefer to have almost all of these on the 'excludeLists' search,
// I have set them to include their own listings automatically rather than relying on tagglytagging.
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.configTiddlers='These Tiddlers are used internally by the the TiddlyWiki Configuration process';
//----------------------------------------------------------------------------------------------------
//If Tagglytagging is *not* installed, use this.
//config.shadowTiddlers.excludeLists='Items tagged with ['+'[excludeLists]] are automatically excluded from most Lists\n<<list filter [tag[excludeLists]]>>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.excludeLists='Items tagged with ['+'[excludeLists]] are automatically excluded from most Lists\n(Filtered List redundant due to Taggly Tagging Plugin)';
config.shadowTiddlers.configTiddlers+='\n<<slider chkexcludeLists excludeLists "excludeLists »" "excludeLists">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.excludeSearch='Items tagged with ['+'[excludeSearch]] are automatically excluded from Searches\n<<list filter [tag[excludeSearch]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chkexcludeSearch excludeSearch "excludeSearch »" "excludeSearch">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.excludeMissing='Items tagged with ['+'[excludeMissing]] are automatically excluded from "Missing Tiddler" Processing\n<<list filter [tag[excludeMissing]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chkexcludeMissing excludeMissing "excludeMissing »" "excludeMissing">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemConfig='Javascript Plugins tagged with ['+'[systemConfig]] are automatically run during Start-up\n<<list filter [tag[systemConfig]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemConfig systemConfig "systemConfig »" "systemConfig">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemConfigDisable='Javascript Plugins tagged with ['+'[systemConfigDisable]] are automatically shut-down during Startup\n<<list filter [tag[systemConfigDisable]]';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemConfigDisable systemConfigDisable "systemConfigDisable »" "systemConfigDisable">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemConfigForce='Javascript Plug-ins tagged with ['+'[systemConfigForce]] are forced to run, despite version information, during Start-up\n<<list filter [tag[systemConfigForce]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemConfigForce systemConfigForce "systemConfigForce »" "systemConfigForce">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemServer='Servers tagged with ['+'[systemServer]] are automatically made available during the import tiddler process\n<<list filter [tag[systemServer]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemServer systemServer "systemServer »" "systemServer">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemTheme='The ['+'[systemTheme]] tag is a repository for Style sheet and layout designs\n<<list filter [tag[systemTheme]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemThemre systemTheme "systemTheme »" "systemTheme">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemConfigRegistry='The ['+'[systemConfigRegistry]] tag is an unofficial repository for plug-ins that are installed, but may or may not currently be active\n<<list filter [tag[systemConfigRegistry]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chksystemConfigRegistry systemConfigRegistry "systemConfigRegistry »" "systemConfigRegistry">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.systemRemovable='These are Tiddlers that are set to be removed en masse to prepare this wiki for offline use\n<<deleteAllTagged>>\n<<list filter [tag[systemRemovable]]>>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.TiddlyWikiAdmin='The ['+'[TiddlyWikiAdmin]] tag is an unofficial repository for Administrative help information\n<<list filter [tag[TiddlyWikiAdmin]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chkTiddlyWikiAdmin TiddlyWikiAdmin "TiddlyWikiAdmin »" "TiddlyWikiAdmin">>';
//----------------------------------------------------------------------------------------------------
config.shadowTiddlers.TiddlyWikiHelp='The ['+'[TiddlyWikiHelp]] Tag is an unofficial repository for General help information\n<<list filter [tag[TiddlyWikiHelp]]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chkTiddlyWikiHelp TiddlyWikiHelp "TiddlyWikiHelp »" "TiddlyWikiHelp">>';
//}}}
/***
|''Name:''|configTiddlyWikiMethodsPlugin|
|''Description:''|Traverses Method 'Trees' to try and figure out interelations - it's a kluge, cuz I suck. |
|''Version:''|1.0|
|''Date:''|May 07, 2009|
|''Source:''|http://storywiki.tiddlyspot.com|
|''Author:''|Pugugly001|
|''License:''| blah |
|''~CoreVersion:''|2.2.0|
|''Notes:''| blah |
***/
//{{{
//This Plugin's name
var ThisPlugin='documentTiddlyWikiMethodsPlugin';
// Target Shadowtiddler name
var TargetShadowTiddler='TiddlyWikiMethods';
//Override the Default Tiddlers when in Use
config.shadowTiddlers.DefaultTiddlers = '['+'['+TargetShadowTiddler+']]';
//TiddlyWikiMethods Headers
var header = '';
header += '/***';
header += '\n|!\'\'Name:\'\'|Generated by ['+'['+ThisPlugin+']]|';
header += '\n|!\'\'Description:\'\'|This Generated listing is designed to traverse a tiddlywiki tree finding methods. Cuz I suck at reverse engineering Object Oriented Code, and hate you all. Feel the hate. |';
header += '\n|!\'\'Version:\'\'|1.0 |';
header += '\n|!\'\'Date:\'\'|May 07, 2009 |';
header += '\n|!\'\'Author:\'\'|Dynamically Generated |';
header += '\n|!\'\'License:\'\'|Dynamically Generated |';
header += '\n|!\'\'~CoreVersion:\'\'|2.2.0|';
header += '\n***/';
config.shadowTiddlers[TargetShadowTiddler] = header;
//Generated Javascript Listing
var body = '';
var line = '';
var prefix = '*';
var treedepth = 2; // (Accounting for '\n')
body += '\n!Traversing config';
var x;
treedepth++;
var title = 'config';
var start = config;
for (x in start)
{
line = '\n'
while (line.length<treedepth){ line += prefix;}
line+= title+'.'+x;
body+=line;
treedepth++;
for (y in start[x])
{
line = '\n'
while (line.length<treedepth){ line += prefix;}
line += title+'.'+x+'.'+y;
body += line;
}
treedepth--;
}
config.shadowTiddlers[TargetShadowTiddler]+= body;
//}}}
The [[excludeWikiWords]] tag will disable wikification of all Tiddlers so tagged.
<<list filter [tag[excludeWikiWords]]>>
/***
| ''Name:'' | inlineSVG |
| ''Description:'' | A simple macro {{{<<SVG "<svg code>">>}}} to display SVG inline in TiddlyWiki. <br> I.E with all svg code self contained in the wiki |
| ''Author:'' | [[Pugugly|mailto:pugugly001@gmail.com]] |
| ''Source:'' | http://storywiki.tiddlyspot.com/#inlineSVG |
| ''Version:'' | 1.1 |
| ''Status:'' | Works. The original source for this code had comments regarding some SVG features not working, <br> so I'm uncertain as to the limits of this Macro. IVÁN, Tamás has expanded my original code to handle option width and height parameters |
| ''Date:'' | July 29th 2009 |
| ''Comments:'' | Please make comments at http://groups.google.co.uk/group/TiddlyWiki <br> Original code --stolen-- --borrowed-- . . . //gleaned// from http://softwareas.com/inline-svg |
| ''License:'' | [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
| ''Bugs:'' | Although xlink references no longer crash the xml parser, they also do not currently resolve properly <br> This breaks everything the relies upon them such as 'use', 'gradient', 'defs', et al. <br> internal scripting does not work at this time, but this may be related to the xlink issue |
| ''To Do:'' | There's no reason this can't be generalized to generic XML <br> Larger images are cutoff - I suspect there is a default height/width/viewbox <br> and I need to implement an easy way to insert x/y info |
***/
//{{{
config.macros.SVG =
{
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var prms = paramString.parseParams('svg', null, true, false);
var svg = getParam(prms,'svg') || '';
var width = getParam(prms,'width') || '100%';
var height = getParam(prms,'height') || '100%';
var svgObject = document.createElement('object');
svgObject.setAttribute('type', 'image/svg+xml');
svgObject.setAttribute('data', 'data:image/svg+xml,'+ '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="' + width + '" height="' + height + '" >'+svg+'</svg>');
jQuery(place).append(svgObject);
}
};
//}}}
/***
| ''Name:'' | inlineSVG |
| ''Description:'' | A simple macro {{{<<SVG "<svg code>">>}}} to display SVG inline in TiddlyWiki. <br> I.E with all svg code self contained in the wiki |
| ''Author:'' | [[Pugugly|mailto:pugugly001@gmail.com]] |
| ''Source:'' | http://storywiki.tiddlyspot.com/#inlineSVG |
| ''Version:'' | 1.0 |
| ''Status:'' | Works. The original source for this code had comments regarding some SVG features not working, <br> so I'm uncertain as to the limits of this Macro |
| ''Date:'' | July 29th 2009 |
| ''Comments:'' | Please make comments at http://groups.google.co.uk/group/TiddlyWiki <br> Original code --stolen-- --borrowed-- . . . //gleaned// from http://softwareas.com/inline-svg |
| ''License:'' | [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
| ''Bugs:'' | Although xlink references no longer crash the xml parser, they also do not currently resolve properly <br> This breaks everything the relies upon them such as 'use', 'gradient', 'defs', et al. <br> internal scripting does not work at this time, but this may be related to the xlink issue |
| ''To Do:'' | There's no reason this can't be generalized to generic XML <br> Larger images are cutoff - I suspect there is a default height/width/viewbox <br> and I need to implement an easy way to insert x/y info |
***/
//{{{
config.macros.SVG =
{ handler: function (place, macroName, params, wikifier, paramString, tiddler)
{ var svg = params[0]
var svgObject = document.createElement('object');
svgObject.setAttribute('type', 'image/svg+xml');
svgObject.setAttribute('data', 'data:image/svg+xml,'+ '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="100%" height="100%" >'+svg+'</svg>');
jQuery(place).append(svgObject);
}
};
//}}}
/***
|Name:|panel(DisableWikiLinksPlugin)|
|Description:|It's a panel, for use with the DisableWikiLinksPlugin|
|Version:1.0|
|Date:|$Date: 2009-07-31|
|Source:|http://storywiki.tiddlyspot.com/#panel(DisableWikiLinksPlugin)|
|Requires|storyWikiTemplatesPlugin|
|Author:|Pugugly001 <pugugly001@gmail.com>|
***/
//{{{
//----------------------------------------------------------------------------------------------------//
// DisableWikiLinkPlugin Modifications
//----------------------------------------------------------------------------------------------------//
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions += '<<slider chkSliderWikiWordPanel WikiWordPanel "WikiWord Options »" "Access WikiWord Options">>';
config.shadowTiddlers.WikiWordPanel = '<<option chkDisableWikiLinks>> Disable //all// automatic ~WikiWord tiddler links\n<<option chkAllowLinksFromShadowTiddlers>> allow ~WikiWords contained in //shadow tiddlers//\n<<option chkDisableNonExistingWikiLinks>> Disable automatic ~WikiWord links for non-existing tiddlers\n----\nDisable automatic ~WikiWord links for words listed in: <<option txtDisableWikiLinksList>>\nDisable automatic ~WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>';
if (config.options.txtDisableWikiLinksList==undefined) {
config.options.txtDisableWikiLinksList = "excludeWikiLinks"
}
if (config.options.txtDisableWikiLinksTag==undefined) {
config.options.txtDisableWikiLinksTag = "excludeWikiLinks"
}
if (config.options.txtDisableWikiLinksList == config.options.txtDisableWikiLinksTag)
{
config.shadowTiddlers[config.options.txtDisableWikiLinksList] ='The ['+'['+config.options.txtDisableWikiLinksList+']] tiddler will disable Wikification of words listed here. It will also disable wikification of all Tiddlers so tagged. \n<<list filter [tag['+config.options.txtDisableWikiLinksTag+']]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chk'+config.options.txtDisableWikiLinksList+' '+config.options.txtDisableWikiLinksList+' "'+config.options.txtDisableWikiLinksList+' »" "'+config.options.txtDisableWikiLinksList+'">>';
}
else {
config.shadowTiddlers[config.options.txtDisableWikiLinksList]='The ['+'['+config.options.txtDisableWikiLinksList+']] tiddler will disable Wikification of words listed here';
config.shadowTiddlers.configTiddlers+='\n<<slider chk'+config.options.txtDisableWikiLinksList+' '+config.options.txtDisableWikiLinksList+' "'+config.options.txtDisableWikiLinksList+' »" "'+config.options.txtDisableWikiLinksList+'">>';
config.shadowTiddlers[config.options.txtDisableWikiLinksTag]='The ['+'['+config.options.txtDisableWikiLinksTag+']] tag will disable wikification of all Tiddlers so tagged. \n<<list filter [tag['+config.options.txtDisableWikiLinksTag+']]>>';
config.shadowTiddlers.configTiddlers+='\n<<slider chk'+config.options.txtDisableWikiLinksTag+' '+config.options.txtDisableWikiLinksTag+' "'+config.options.txtDisableWikiLinksTag+' »" "'+config.options.txtDisableWikiLinksTag+'">>';
}
}
//}}}
/***
|Name:|panel(DisableWikiLinksPlugin)|
|Description:|It's a panel, for use with the TiddlerEncryptionPlugin|
|Version:1.0|
|Date:|$Date: 2009-07-31|
|Source:|http://storywiki.tiddlyspot.com/#panel(TiddlerEncryptionPlugin)|
|Requires|storyWikiTemplatesPlugin|
|Author:|Pugugly001 <pugugly001@gmail.com>|
***/
//{{{
//----------------------------------------------------------------------------------------------------//
// TiddlerEncryptionPlugin Modifications
//----------------------------------------------------------------------------------------------------//
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions += '<<slider chkSliderEncryptionPanel EncryptionPanel "Encryption Options »" "Access Encryption Options">>';
config.shadowTiddlers.EncryptionPanel = '<<EncryptionChangePassword>>\n<<EncryptionDecryptAll>>\n<<option chkExcludeEncryptedFromSearch>> ~DoNotSearch\n<<option chkExcludeEncryptedFromLists>> ~DoNotList\n<<option chkShowDecryptButtonInContent>> ~HideRawEncryption\n----\n['+'[Encryption Plugin|TiddlerEncryptionPlugin]]';
}
//}}}
/***
|Name:|panel(Tiddlyspot)|
|Description:|It's a panel, for use with the Tiddlyspot|
|Version:|1.0|
|Date:|$Date: 2009-07-31|
|Source:|http://storywiki.tiddlyspot.com/#panel(Tiddlyspot)|
|Requires|storyWikiTemplatesPlugin|
|Author:|Pugugly001 <pugugly001@gmail.com>|
***/
//{{{
//----------------------------------------------------------------------------------------------------//
// Tiddlyspot
//----------------------------------------------------------------------------------------------------//
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions += '<<slider chkSliderTiddlySpotPanel TiddlySpotPanel "TiddlySpot Options »" "Access TiddlySpot Controls">><<upload http://' + config.tiddlyspotSiteId + '.tiddlyspot.com/store.cgi index.html . . ' + config.tiddlyspotSiteId + '>>';
config.shadowTiddlers.TiddlySpotPanel = '~TiddlySpot password:\n<<option pasUploadPassword>>';
config.shadowTiddlers.TiddlySpotPanel += '\n*<<upload http://' + config.tiddlyspotSiteId + '.tiddlyspot.com/store.cgi index.html . . ' + config.tiddlyspotSiteId + '>>';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[download (go offline)|http://' + config.tiddlyspotSiteId + '.tiddlyspot.com/download]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[control panel|http://' + config.tiddlyspotSiteId + '.tiddlyspot.com/controlpanel]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[tiddlyspot.com|http://tiddlyspot.com/]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[FAQs|http://faq.tiddlyspot.com/]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[blog|http://tiddlyspot.blogspot.com/]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[support|mailto:support@tiddlyspot.com]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[feedback|mailto:feedback@tiddlyspot.com]]';
config.shadowTiddlers.TiddlySpotPanel += '\n*['+'[donate|http://tiddlyspot.com/?page=donate]]';
config.shadowTiddlers.TiddlySpotPanel += '\n----\nSee also: ['+'[Tiddly Spot Controls|TspotControls]]';
}
//}}}
/***
|Name:|storyWikiTemplatesPlugin|
|Description:|Templates to setup StoryWiki|
|Version:|0.0.1|
|Date:|$Date: 2008-07-27 01:42:07 +1000 (Sun, 27 Jul 2008) $|
|Source:|http://storywiki.tiddlyspot.com/|
|Author:|Pugugly001 <pugugly001@gmail.com>|
***/
//{{{
//----------------------------------------------------------------------------------------------------//
// StoryWikiTemplatesPlugin is designed to use systemTheme(StoryWiki)
// this assures the two are in sync when in use.
//----------------------------------------------------------------------------------------------------//
config.options.txtTheme = "systemTheme(StoryWiki)";
//----------------------------------------------------------------------------------------------------//
// Start Panels
// Double brackets have issues, even inside quotes.
// Although I'm sure there is a more elegant solution,
// separating the brackets into two concatenated strings seems to work fine.
//----------------------------------------------------------------------------------------------------//
config.shadowTiddlers.MainMenu = '<<tagglyTagging MainMenu>>';
config.shadowTiddlers.SiteTitle =config.options.txtSiteTitle;
config.shadowTiddlers.SiteSubtitle =config.options.txtSiteSubtitle;
config.shadowTiddlers.DefaultTiddlers='[tag[DefaultTiddlers]]';
//----------------------------------------------------------------------------------------------------//
// Panels and Sidebars
// To override the TiddlySpot version of SidebarOptions,
// kbTemplatesPlugin must be after TiddlySpot in the load sequence.
// Otherwise the only way to override them *and* use shadowtiddlers
// appears to be to use the tiddler macro to point them at my new shadow tiddlers.
// **Correction - looks like I can adjust the load order with the headers.
//----------------------------------------------------------------------------------------------------//
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions = 'Sign your Edits:<<option txtUserName>>';
}
config.shadowTiddlers.SideBarOptions += '<<search>><<slider chkSliderSearchPanel SearchPanel "search options »" "Change Search behavior">>';
config.shadowTiddlers.SearchPanel = '<<option chkIncrementalSearch>>Incremental Search\n<<option chkRegExpSearch>> Regular Expressions\n<<option chkCaseSensitiveSearch>> Case Sensitive';
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions += '<<saveChanges>><<slider chkSliderBackupPanel BackupPanel "Backup Options »" "Access TiddlyWiki Backup Settings">>';
config.shadowTiddlers.BackupPanel = '<<option chkSaveBackups>> Save Backups\n<<option chkAutoSave>> Save Every Change\n<<option chkForceMinorUpdate>> Minor changes\nBackup folder:\n<<option txtBackupFolder>>';
}
config.shadowTiddlers.SideBarOptions += '<<closeAll>><<permaview>>';
if (readOnly != true)
{ config.shadowTiddlers.SideBarOptions += '<<newTiddler>><<newJournal "YYYY-0MM-0DD" "journal">>';
config.shadowTiddlers.SideBarOptions += '<<slider chkSliderOptionsPanel OptionsPanel "Misc Options »" "Change TiddlyWiki advanced options">>';
config.shadowTiddlers.OptionsPanel = '<<newJournal "YYYY-0MM-0DD 0hh:0mm" "journal">>\nThese Interface Options for customising ~TiddlyWiki are saved in your browser\n<<option chkAnimate>> Enable Animations\n<<option chkToggleLinks>> Toggle Tiddlers on and off\n<<option chkAdmin>> Enable Admin Options\n[[Read Only Mode|#readOnly:yes]]\nSee also: ['+'[AdvancedOptions]], and\n['+'[AdvancedOptionsHardcode]].';
}
//----------------------------------------------------------------------------------------------------//
// New Tabs
//----------------------------------------------------------------------------------------------------//
//config.shadowTiddlers.SideBarTabs = '<<slider chkSliderTabIndex TabIndex "Indices »" "Timelines, Indices, and Helpfiles">>\n<<slider chkSliderTabWriting TabWriting "Story Tabs »" "Authors, Stories, Journals, and Drafts">>\n<<slider chkSliderTabMore TabMore "Admin Tabs »" "Internal ~TiddlyWiki indices and Helpfiles">>';
config.shadowTiddlers.SideBarTabs = '<<slider chkSliderTabIndex TabIndex "Indices »" "Timelines, Indices, and Helpfiles">>';
if (readOnly != true)
{ config.shadowTiddlers.SideBarTabs += '\n<<slider chkSliderTabMore TabMore "Admin Tabs »" "Internal ~TiddlyWiki indices and Helpfiles">>';
}
config.shadowTiddlers.TabAdmin = '~TiddlyWiki Version:<<version>>\n<<newTiddler label:"New Help File" title:"TiddlyWikiHelp.new" focus:title text:"New Helpfile:" tag:TiddlyWikiHelp tag:excludeLists tag:excludeSearch>>\n<<newTiddler label:"New Admin Help File" title:"TiddlyWikiAdmin.new" focus:title text:"New Admin:" tag:TiddlyWikiAdmin tag:excludeLists tag:excludeSearch>>\n<<newTiddler label:"New Hidden Template" title:"TiddlyWikiHiddenTemplates.new" focus:title text:"New Template:" tag:TiddlyWikiHiddenTemplates tag:excludeLists tag:excludeSearch>>\n----\n<<list filter [tag[TiddlyWikiAdmin]]>>';
config.shadowTiddlers.TabMore = '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadow" "Shadowed tiddlers" TabMoreShadowed "Help" "Administrative Help Files" TabAdmin>>';
config.shadowTiddlers.TabIndex = '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "Help" "Tiddly Wiki Editing Help" TabHelp>>';
config.shadowTiddlers.TabHelp = '<<list filter [tag[TiddlyWikiHelp]]>>';
//}}}
|''Type:''|file|
|''URL:''|http://tiddlywiki.abego-software.de/Beta.html|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.jonrobson.me.uk/development/AdvancedFilterTiddlersPlugin/index.html|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tiddlywiki.bidix.info/|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://mptw.tiddlyspot.com|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Description:''|Storywiki Main Server (Tiddlyspot)|
|''Type:''|file|
|''URL:''|http://storywiki.tiddlyspot.com/|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.remotely-helpful.com/TiddlyWiki/TiddlerEncryptionPlugin.html|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.minormania.com/tiddlylock/tiddlylock.html|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.tiddlytools.com/|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://ido-xp.tiddlyspot.com/|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
|Name|systemTheme(Default)|
|Description|Passthrough systemTheme Configurations from Shadow Tiddlers for editing purposes|
|PageTemplate|##PageTemplate|
|ViewTemplate|##ViewTemplate|
|EditTemplate|##EditTemplate|
|StyleSheet|##StyleSheet|
!PageTemplate
<!--{{{-->
[[PageTemplate]]
<!--}}}-->
!ViewTemplate
<!--{{{-->
[[systemTheme(Default)##ViewToolbar]]
[[ViewTemplate]]
<!--}}}-->
!ViewToolbar
<!--{{{-->
//Note: Neither the Tiddler for the Toolbar settings, nor the toolbar listed, need to match the shadowtiddler defaults
//<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
//Alternatively one can use this format
//<div class="toolbar" macro="toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler"></div>
<!--}}}-->
!EditTemplate
<!--{{{-->
[[systemTheme(Default)##EditToolbar]]
[[EditTemplate]]
<!--}}}-->
!EditToolbar
<!--{{{-->
//Note: Neither the Tiddler for the Toolbar settings, nor the toolbar listed, need to match the shadowtiddler defaults
//<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
//Alternatively one can use this format
//<div class="toolbar" macro="toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler"></div>
<!--}}}-->
!StyleSheet
/*{{{*/
[[StyleSheet]]
/*}}}*/
|Name|systemTheme(StoryWiki)|
|Description|StoryWiki Templates and CSS|
|PageTemplate|##PageTemplate|
|ViewTemplate|##ViewTemplate|
|EditTemplate|##EditTemplate|
|StyleSheet|##StyleSheet|
|~ViewToolbar| +editTiddler deleteTiddler copyTiddler closeOthers closeTiddler |
|~EditToolbar| -cancelTiddler +saveTiddler deleteTiddler|
|~AdminToolbar| fields syncing |
|~AuthorToolbar| copyTiddler newHere newJournal deleteTiddler|
|~ReferenceToolbar| references jump permalink |
|~ReadOnlyToolbar| closeTiddler closeOthers > permalink references +jump |
!PageTemplate
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' force='true' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
!ViewTemplate
<!--{{{-->
<!--Setting this to systemTheme(StoryWiki)##ReadOnlyToolbar will effectively lock out the editor-->
[[systemTheme(StoryWiki)##ViewToolbar]]
<div class="tagglyTagged" macro="tags"></div>
<div class='titleContainer'>
<span class='title' macro='view title'></span>
<span macro="miniTag"></span>
</div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div macro="showWhen tiddler.tags.containsAny(['css','html','pre','systemConfig']) && !tiddler.text.match('{{'+'{')">
<div class='viewer'><pre macro='view text'></pre></div>
</div>
<div macro="else">
<div class='viewer' macro='view text wikified'></div>
</div>
<div macro="showWhen tiddler.tags.contains('author')">
<div class="authorList" macro="list filter {{'[modifier ['+this.tiddler.modifier+']]'}}"></div>
</div>
<div macro="hideWhen tiddler.title == 'MainMenu'">
<div class="tagglyTagging" macro="tagglyTagging"></div>
</div>
<!--}}}-->
!ViewToolbar
<!--{{{-->
<!--Note: Neither the Tiddler for the Toolbar settings, nor the toolbar listed, need to match the shadowtiddler defaults-->
<!--<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>-->
<!--Alternatively one can use this format-->
<!--<div class="toolbar" macro="toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler"></div>-->
<div class='toolbar'>
<span macro="showWhen tiddler.tags.contains('css') || tiddler.title == 'StyleSheet'"><span macro="refreshAll"></span></span>
<span style="padding:1em;"></span>
<div macro="showWhen config.options.chkAdmin == true">
<span macro='toolbar fields syncing references'></span>
</div>
<span macro='toolbar permalink jump'></span>
<span macro='toolbar +editTiddler deleteTiddler copyTiddler'></span> <span macro='newHere label:"new here"'></span>
<span macro='newJournalHere {{config.mptwJournalFormat?config.mptwJournalFormat:"YYYY-0MM-0DD"}}'></span>
<span macro='toolbar closeTiddler closeOthers'></span>
</div>
<!--}}}-->
!EditTemplate
<!--{{{-->
[[systemTheme(StoryWiki)##EditToolbar]]
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'>
<div macro="showWhen config.options.chkAdmin == true">
<div class='editor' macro='edit alias'></div><div class='editorFooter'><span macro='message abegoTiddlerAlias.lingo.aliasPrompt'></span></div>
</div>
</span></div>
<!--}}}-->
!EditToolbar
<!--{{{-->
<!--Note: Neither the Tiddler for the Toolbar settings, nor the toolbar listed, need to match the shadowtiddler defaults-->
<!--<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>-->
<!--Alternatively one can use this format-->
<!--<div class="toolbar" macro="toolbar +saveTiddler saveCloseTiddler closeOthers -cancelTiddler cancelCloseTiddler deleteTiddler"></div>-->
<div class="toolbar">
<span macro='toolbar +saveTiddler -cancelTiddler'></span>
<div macro="showWhen config.options.chkAdmin == true">
<span macro='toolbar saveCloseTiddler closeOthers cancelCloseTiddler deleteTiddler'></span>
</div>
</div>
<!--}}}-->
!StyleSheet
/*{{{*/
[[StyleSheet]]
#mainMenu{ text-align: left; }
/*}}}*/
/***
|''Name:''|zTiddlyWikiconfigMacrosIndexer|
|''Description:''|Creates a [[TiddlyWikiMacrosIndex]] ShadowTiddler to dynamically list all Macros. |
|''Version:''|1.0|
|''Date:''|Dec 31, 2009|
|''Source:''|http://storywiki.tiddlyspot.com |
|''Author:''|[[Pugugly001|mailto:pugugly001@gmail.com]] |
|''License:''|Publicly Documented Tweak|
|''~CoreVersion:''|2.2.0|
|''Notes:''|This Tiddler needs to be at or near the end of the loadout since it can only document macros that exist when it loads. Any Variables created or modified after this tiddler is executed will not be reflected in the variable listing. It is worth noting that this plug-in happily grabs every function under config.macros[x]. |
***/
//{{{
//----------------------------------------------------------------------------------------------------
// This Plug-in name
var ThisPlugin='zTiddlyWikiconfigMacrosIndexer';
//----------------------------------------------------------------------------------------------------
// Target Shadowtiddler name
var TargetShadowTiddler='TiddlyWikiMacrosIndex';
//----------------------------------------------------------------------------------------------------
// AdvancedOptionsHardcode Headers
var header='';
header+= '/***';
header+= '\n|!\'\'Name:\'\'|Generated by ['+'['+ThisPlugin+']]|';
header+= '\n|!\'\'Description:\'\'|This Generated "~ShadowPlugin" dynamically lists all active macros. |';
header+= '\n|!\'\'Version:\'\'|1.0 |';
header+= '\n|!\'\'Date:\'\'|Dec 31, 2009 |';
header+= '\n|!\'\'Author:\'\'|Dynamically Generated |';
header+= '\n|!\'\'License:\'\'|Dynamically Generated |';
header+= '\n|!\'\'~CoreVersion:\'\'|2.2.0|';
header+= '\n***/';
config.shadowTiddlers[TargetShadowTiddler] = header;
//----------------------------------------------------------------------------------------------------
// Generated Javascript
var body='';
body += '\n//{{{';
var x;
for (x in config.macros)
{
tab = 50;
var line = '\n';
var quotes;
if (typeof(config.macros[x])=="string")
{quotes='"'}
else
{quotes=''}
line += '//config.macros.'+x;
while (line.length<tab){ line += " ";}
line += ' = '+quotes+config.macros[x]+quotes+';';
body+=line
}
body+= '\n//}}}';
config.shadowTiddlers[TargetShadowTiddler]+= body
//}}}