Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
/***
|''Name:''|AdaptorCommandsPlugin|
|''Description:''|Commands to access hosted TiddlyWiki data|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#AdaptorCommandsPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/AdaptorCommandsPlugin.js |
|''Version:''|0.5.5|
|''Date:''|Aug 23, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.2.0|
***/
//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.AdaptorCommandsPlugin) {
version.extensions.AdaptorCommandsPlugin = {installed:true};
function getServerType(fields)
{
if(!fields)
return null;
var serverType = fields['server.type'];
if(!serverType)
serverType = fields['wikiformat'];
if(!serverType)
serverType = config.defaultCustomFields['server.type'];
return serverType;
}
function invokeAdaptor(fnName,param1,param2,context,userParams,callback,fields)
{
var serverType = getServerType(fields);
if(!serverType)
return null;
var adaptor = new config.adaptors[serverType];
if(!adaptor)
return false;
if(!config.adaptors[serverType].prototype[fnName])
return false;
adaptor.openHost(fields['server.host']);
adaptor.openWorkspace(fields['server.workspace']);
if(param1)
var ret = param2 ? adaptor[fnName](param1,param2,context,userParams,callback) : adaptor[fnName](param1,context,userParams,callback);
else
ret = adaptor[fnName](context,userParams,callback);
//adaptor.close();
//delete adaptor;
return ret;
}
function isAdaptorFunctionSupported(fnName,fields)
{
var serverType = getServerType(fields);
if(!serverType || !config.adaptors[serverType])
return false;
var fn = config.adaptors[serverType].prototype[fnName];
return fn ? true : false;
}
config.commands.getTiddler = {};
merge(config.commands.getTiddler,{
text: "get",
tooltip:"Download this tiddler",
readOnlyText: "get",
readOnlyTooltip: "Download this tiddler",
done: "Tiddler downloaded"
});
config.commands.getTiddler.isEnabled = function(tiddler)
{
return isAdaptorFunctionSupported('getTiddler',tiddler.fields);
};
config.commands.getTiddler.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(tiddler) {
var fields = tiddler.fields;
} else {
fields = String(document.getElementById(story.idPrefix + title).getAttribute("tiddlyFields"));
fields = fields ? fields.decodeHashMap() : null;
}
return invokeAdaptor('getTiddler',title,null,null,null,config.commands.getTiddler.callback,fields);
};
config.commands.getTiddler.callback = function(context,userParams)
{
if(context.status) {
var tiddler = context.tiddler;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(tiddler.title,1,true);
displayMessage(config.commands.getTiddler.done);
} else {
displayMessage(context.statusText);
}
};
config.commands.putTiddler = {};
merge(config.commands.putTiddler,{
text: "put",
tooltip: "Upload this tiddler",
hideReadOnly: true,
done: "Tiddler uploaded"
});
config.commands.putTiddler.isEnabled = function(tiddler)
{
return tiddler && tiddler.isTouched() && isAdaptorFunctionSupported('putTiddler',tiddler.fields);
};
config.commands.putTiddler.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(!tiddler)
return false;
return invokeAdaptor('putTiddler',tiddler,null,null,null,config.commands.putTiddler.callback,tiddler.fields);
};
config.commands.putTiddler.callback = function(context,userParams)
{
if(context.status) {
store.fetchTiddler(context.title).clearChangeCount();
displayMessage(config.commands.putTiddler.done);
} else {
displayMessage(context.statusText);
}
};
config.commands.revisions = {};
merge(config.commands.revisions,{
text: "revisions",
tooltip: "View another revision of this tiddler",
loading: "loading...",
done: "Revision downloaded",
revisionTooltip: "View this revision",
popupNone: "No revisions"});
config.commands.revisions.isEnabled = function(tiddler)
{
return isAdaptorFunctionSupported('getTiddlerRevisionList',tiddler.fields);
};
config.commands.revisions.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
userParams = {};
userParams.tiddler = tiddler;
userParams.src = src;
userParams.dateFormat = 'YYYY mmm 0DD 0hh:0mm';
var revisionLimit = 10;
if(!invokeAdaptor('getTiddlerRevisionList',title,revisionLimit,null,userParams,config.commands.revisions.callback,tiddler.fields))
return false;
event.cancelBubble = true;
if(event.stopPropagation)
event.stopPropagation();
return true;
};
config.commands.revisions.callback = function(context,userParams)
// The revisions are returned as tiddlers in the context.revisions array
{
var revisions = context.revisions;
popup = Popup.create(userParams.src);
Popup.show(popup,false);
if(revisions.length==0) {
createTiddlyText(createTiddlyElement(popup,'li',null,'disabled'),config.commands.revisions.popupNone);
} else {
revisions.sort(function(a,b) {return a.modified < b.modified ? +1 : -1;});
for(var i=0; i<revisions.length; i++) {
var tiddler = revisions[i];
var modified = tiddler.modified;
var revision = tiddler.fields['server.page.revision'];
var btn = createTiddlyButton(createTiddlyElement(popup,'li'),
modified.formatString(userParams.dateFormat) + ' r:' + revision,
config.commands.revisions.revisionTooltip,
function() {
config.commands.revisions.getTiddlerRevision(this.getAttribute('tiddlerTitle'),this.getAttribute('tiddlerModified'),this.getAttribute('tiddlerRevision'),this);
return false;
},
'tiddlyLinkExisting tiddlyLink');
btn.setAttribute('tiddlerTitle',userParams.tiddler.title);
btn.setAttribute('tiddlerRevision',revision);
btn.setAttribute('tiddlerModified',modified.convertToYYYYMMDDHHMM());
if(userParams.tiddler.fields['server.page.revision'] == revision || (!userParams.tiddler.fields['server.page.revision'] && i==0))
btn.className = 'revisionCurrent';
}
}
};
config.commands.revisions.getTiddlerRevision = function(title,modified,revision)
{
var tiddler = store.fetchTiddler(title);
var context = {};
context.modified = modified;
return invokeAdaptor('getTiddlerRevision',title,revision,context,null,config.commands.revisions.getTiddlerRevisionCallback,tiddler.fields);
};
config.commands.revisions.getTiddlerRevisionCallback = function(context,userParams)
{
if(context.status) {
var tiddler = context.tiddler;
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
story.refreshTiddler(tiddler.title,1,true);
displayMessage(config.commands.revisions.done);
} else {
displayMessage(context.statusText);
}
};
config.commands.saveTiddlerAndPut = {};
merge(config.commands.saveTiddlerAndPut,{
text: "done",
tooltip: "Save this tiddler and upload",
hideReadOnly: true,
done: "Tiddler uploaded"
});
config.commands.saveTiddlerAndPut.handler = function(event,src,title)
{
var newTitle = story.saveTiddler(title,event.shiftKey);
if(newTitle)
story.displayTiddler(null,newTitle);
return config.commands.putTiddler.handler(event,src,newTitle);
};
config.commands.saveTiddlerHosted = {};
merge(config.commands.saveTiddlerHosted,{
text: "done",
tooltip: "Save changes to this tiddler",
hideReadOnly: true,
done: "done"
});
config.commands.saveTiddlerHosted.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(!tiddler)
return false;
return invokeAdaptor('saveTiddlerHosted',tiddler,null,null,null,config.commands.saveTiddlerHosted.callback,tiddler.fields);
};
config.commands.saveTiddlerHosted.callback = function(context,userParams)
{
if(context.status) {
displayMessage(config.commands.saveTiddlerHosted.done);
} else {
displayMessage(context.statusText);
}
};
}//# end of 'install only once'
//}}}
/***
|''Name:''|AdaptorMacrosPlugin|
|''Description:''|Commands to access hosted TiddlyWiki data|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#AdaptorMacrosPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/AdaptorMacrosPlugin.js |
|''Version:''|0.3.8|
|''Date:''|Aug 23, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.2.0|
***/
//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.AdaptorMacrosPlugin) {
version.extensions.AdaptorMacrosPlugin = {installed:true};
// Return an array of tiddler titles that are in the given workspace on the host
TiddlyWiki.prototype.getHostedTiddlers = function(host,workspace)
{
var results = [];
if(!this.hostedTiddlers || !this.hostedTiddlers[host])
return results;
var tiddlers = this.hostedTiddlers[host][workspace];
if(tiddlers) {
for(var i=0; i<tiddlers.length; i++) {
results.push(tiddlers[i].title);
}
}
return results;
};
config.macros.viewTiddlerFields = {};
config.macros.viewTiddlerFields.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
if(tiddler instanceof Tiddler) {
var value = '';
var comma = '';
for(i in tiddler.fields) {
if (!i.match(/^temp[\._]/)) {
value += comma + i + '=' + tiddler.fields[i];
comma = ', ';
}
}
if(tiddler.created)
value += comma + 'created=' + tiddler.created.convertToYYYYMMDDHHMM();
if(tiddler.modified)
value += ', modified=' + tiddler.modified.convertToYYYYMMDDHHMM();
if(tiddler.modifier)
value += ', modifier=' + tiddler.modifier;
value += ', touched=' + (tiddler.isTouched() ? 'true' : 'false');
highlightify(value,place,highlightHack,tiddler);
}
};
config.macros.list.updatedOffline = {};
config.macros.list.updatedOffline.handler = function(params)
{
var results = [];
store.forEachTiddler(function(title,tiddler) {
if(tiddler.fields['server.host'] && tiddler.isTouched())
results.push(tiddler);
});
results.sort();
return results;
};
config.macros.list.workspaceTiddlers = {};
config.macros.list.workspaceTiddlers.prompt = "List Tiddlers in the workspace";
config.macros.list.workspaceTiddlers.handler = function(params,wikifier,paramString,tiddler)
{
var customFields = getParam(params,'fields',false);
if(!customFields)
customFields = config.defaultCustomFields;
return store.getHostedTiddlers(customFields['server.host'],customFields['server.workspace']);
};
config.macros.updateWorkspaceTiddlerList = {};
merge(config.macros.updateWorkspaceTiddlerList,{
label: "update tiddler list",
prompt: "Update list of tiddlers in workspace",
done: "List updated"});
config.macros.updateWorkspaceTiddlerList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams('anon',null,true,false,false);
var customFields = getParam(params,'fields',false);
if(!customFields)
customFields = String.encodeHashMap(config.defaultCustomFields);
var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
btn.setAttribute('customFields',customFields);
btn.setAttribute('title',tiddler.title);
};
config.macros.updateWorkspaceTiddlerList.onClick = function(e)
{
clearMessage();
var customFields = this.getAttribute("customFields");
var fields = customFields.decodeHashMap();
var userParams = {host:fields['server.host'],workspace:fields['server.workspace'],title:this.getAttribute("title")};
return invokeAdaptor('getTiddlerList',null,null,null,userParams,config.macros.updateWorkspaceTiddlerList.callback,fields);
};
config.macros.updateWorkspaceTiddlerList.callback = function(context,userParams)
{
if(context.status) {
if(!store.hostedTiddlers)
store.hostedTiddlers = {};
if(!store.hostedTiddlers[userParams.host])
store.hostedTiddlers[userParams.host] = {};
store.hostedTiddlers[userParams.host][userParams.workspace] = context.tiddlers;
displayMessage(config.macros.updateWorkspaceTiddlerList.done);
story.displayTiddler(null,userParams.title);
story.refreshTiddler(userParams.title,1,true);
} else {
displayMessage(context.statusText);
}
};
config.macros.updateWorkspaceList = {};
merge(config.macros.updateWorkspaceList,{
label: "update workspace list",
prompt: "Update list of workspaces",
done: "List updated"});
config.macros.updateWorkspaceList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams('anon',null,true,false,false);
var customFields = getParam(params,'fields',false);
if(!customFields)
customFields = String.encodeHashMap(config.defaultCustomFields);
var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
btn.setAttribute('customFields',customFields);
btn.setAttribute('title',tiddler.title);
};
config.macros.updateWorkspaceList.onClick = function(e)
{
clearMessage();
var customFields = this.getAttribute("customFields");
var fields = customFields.decodeHashMap();
var userParams = {host:fields['server.host'],callback:config.macros.updateWorkspaceList.callback};
return invokeAdaptor('getWorkspaceList',context,fields);
};
config.macros.updateWorkspaceList.callback = function(context,userParams)
{
if(context.status) {
displayMessage(config.macros.updateWorkspaceList.done);
for(var i=0; i<context.workspaces.length; i++) {
displayMessage("workspace:"+context.workspaces[i]);
}
} else {
displayMessage(context.statusText);
}
};
} // end of 'install only once'
//}}}
|!Adaptor Plugin|!Description|
|[[ExampleAdaptorPlugin]]|Example empty adaptor. You can use this as a template to write your own adaptor|
|[[ccTiddlyAdaptorPlugin]]|Adaptor for moving and converting data to and from ccTiddly wikis|
|[[JSPWikiAdaptorPlugin]]|Adaptor for moving and converting data to and from JSP Wikis|
|[[MediaWikiAdaptorPlugin]]|Adaptor for moving and converting data from MediaWikis|
|[[SocialtextAdaptorPlugin]]|Adaptor for moving and converting data to and from Socialtext Wikis|
|[[TWikiAdaptorPlugin]]|Adaptor for moving and converting data to and from TWikis|
|!Format|!Markup|!Example|
|Bold|{{{''Bold''}}} (2 single quotes)|''Bold''|
|Italic|{{{//Italic//}}}|//Italic//|
|Bold Italic|{{{''//Bold Italic//''}}}|''//Bold Italic//''|
|Underlined|{{{__Underline__}}}(2 underscores)|__Underlined__|
|Strikethough|{{{--Strikethrough--}}}<br />{{{--}}} replaced {{{==}}} for Stikethrough in TiddlyWiki 2.1|--Strikethrough--|
|Superscript|{{{Text^^Superscript^^}}}|Text^^Superscript^^|
|Subscript|{{{Text~~Subscript~~}}}|Text~~Subscript~~|
|Monospaced text|<html><code>{{{Monospaced}}}</code></html>|{{{Monospaced}}}|
|Monospaced multiline block|Put <html><code>{{{</code></html> and <html><code>}}}</code></html> on their own lines|<html><pre>{{{<br/>Monospaced<br/>Multi-line<br/>Block<br/>}}}</pre></html>|
|Highlight|{{{@@Highlight@@}}}|@@Highlight@@|
|Color|{{{@@color(green):green text@@}}}|@@color(green):green text@@ |
|~|{{{@@bgcolor(green):text@@}}}|@@bgcolor(green):text@@ |
|~|{{{@@bgcolor(#3399ff):text@@}}}|@@bgcolor(#3399ff):text@@|
|~|{{{@@bgcolor(#39f):text@@}}}|@@bgcolor(#39f):text@@|
|CSS Extended Highlights|{{{@@some css;Highlight@@}}}<br />For backwards compatibility, the following highlight syntax is also accepted:<br />{{{@@bgcolor(#ff0000):color(#ffffff):red coloured@@}}}|@@background-color:#ff0000;color:#ffffff;red coloured@@<br /><<slider AtEg ./atEg 'Extended example ...'>>|
|Custom CSS Class|<html><code>{{wrappingClass{Text that is now accentuated}}}</code></html><br />By default, the text is placed in a <span>. To use a <div> instead, insert a line break before the text (after the single {)<br />In the CSS:<br />{{{.wrappingClass {color: red;} }}}|Add .wrappingClass to StyleSheet|
|Any HTML|{{{<html><span>any</span><br />}}}<br />{{{<b>valid</b> <em>xhtml</em></html>}}}|<html><span>any</span><br /><b>valid</b> <em>xhtml</em></html>|
PageTemplate
|>|>|SiteTitle - SiteSubtitle|
|MainMenu|DefaultTiddlers<br /><br /><br /><br />ViewTemplate<br /><br />EditTemplate|SideBarOptions|
|~|~|OptionsPanel|
|~|~|AdvancedOptions|
|~|~|<<tiddler Configuration.SideBarTabs>>|
''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint
SiteUrl
SideBarTabs
|[[Timeline|TabTimeline]]|[[All|TabAll]]|[[Tags|TabTags]]|>|>|[[More|TabMore]] |
|>|>||[[Missing|TabMoreMissing]]|[[Orphans|TabMoreOrphans]]|[[Shadowed|TabMoreShadowed]]|
/***
|''Name:''|ConfluenceFormatterPlugin|
|''Description:''|Allows Tiddlers to use Confluence text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ConfluenceFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/ConfluenceFormatterPlugin.js |
|''Version:''|0.1.3|
|''Date:''|Dec 8, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
This is the ConfluenceFormatterPlugin, which allows you to insert [[Confluence|http://confluence.atlassian.com/renderer/notationhelp.action?section=all]] formated
text into a TiddlyWiki. See also http://confluence.atlassian.com/display/DOC/Confluence+Notation+Guide+Overview
The aim is not to fully emulate Confluence, but to allow you to work with Confluence content off-line
and then paste the content into your Confluence wiki later on, with the expectation that only minor
edits will be required.
To use Confluence format in a Tiddler, tag the Tiddler with ConfluenceFormat. or set the tiddler's {{{wikiformat}}} extended field to {{{confluence}}}.
Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
***/
//{{{
// Ensure that the ConfluenceFormatterPlugin is only installed once.
if(!version.extensions.ConfluenceFormatterPlugin) {
version.extensions.ConfluenceFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('ConfluenceFormatterPlugin requires TiddlyWiki 2.1 or later.');}
confluenceFormatter = {}; // 'namespace' for local functions
confluenceDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement(out,'br');
};
confluenceFormatter.createSpan = function(w)
{
createTiddlyElement(w.output,'span').innerHTML = this.text;
};
confluenceFormatter.macros = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var lm1 = lookaheadMatch[1];
var lm2 = lookaheadMatch[2];
switch(lm1) {
case 'anchor':
a = createTiddlyElement(w.output,'a');// drop anchor
t = w.tiddler ? w.tiddler.title + ':' : '';
a.setAttribute('name',t + lm2);
break;
case 'color':
var e = createTiddlyElement(w.output,'span');
e.style.color = lm2;
w.subWikifyTerm(e,/(\{color\})/mg);
return;
break;
case 'excerpt':
break;
case 'noformat':
case 'code':
break;
case 'panel':
case 'note':
case 'warning':
case 'info':
case 'tip':
var d = createTiddlyElement(w.output,'div');
var dp = createTiddlyElement(d,'div',null,'informationMacroPadding');
var t = createTiddlyElement(dp,'table',null,lm1+'Macro');
t.cellpadding='5';t.width='85%';t.cellspacing='0';t.border='0';
var tr = createTiddlyElement(t,'tr');
var td = createTiddlyElement(tr,'td');
td.width='16';td.valign='top';
var img = createTiddlyElement(td,'img');
img.src='/confluence/images/icons/emoticons/forbidden.gif';
img.width='16';img.height='16';img.align='absmiddle';img.alt='';img.border='0';
td = createTiddlyElement(tr,'td');
confluenceFormatter.subWikify(w,td,lm2);//'*'+lm1+'*<br/><br/>';
w.subWikifyTerm(td,new RegExp('(\{'+lm1+'\})','mg'));
return;
break;
case 'section':
// includes columns
break;
default:
w.outputText(w.output,w.matchStart,w.nextMatch);
return;
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
confluenceFormatter.subWikify = function(w,out,src)
{
var oldSource = w.source;
var nextMatch = w.nextMatch;
w.source = src;
w.nextMatch = 0;
w.subWikifyUnterm(out);
w.source = oldSource;
w.nextMatch = nextMatch;
};
confluenceFormatter.singleCharFormat = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[0].substr(lookaheadMatch[0].length-2,1) != ' ') {
w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
confluenceFormatter.setAttributesFromParams = function(e,p)
{
var re = /\s*(.*?)=(?:(?:"(.*?)")|(?:'(.*?)')|((?:\w|%|#)*))/mg;
var match = re.exec(p);
while(match) {
var s = match[1].unDash();
if(s=='bgcolor') {
s = 'backgroundColor';
}
try {
if(match[2]) {
e.setAttribute(s,match[2]);
} else if(match[3]) {
e.setAttribute(s,match[3]);
} else {
e.setAttribute(s,match[4]);
}
}
catch(ex) {}
match = re.exec(p);
}
};
config.confluenceFormatters = [
{
name: 'confluenceHeading',
match: '^h[1-6](?:(?:\\(.*?\\))|(?:\\{.*?\\})|(?:\\[.*?\\]))?\\. ',
lookaheadRegExp: /^h([1-6])(?:(?:\((.*?)\))|(?:\{(.*?)\})|(?:\[(.*?)\]))?\. /mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
w.subWikifyTerm(createTiddlyElement(w.output,'h'+lookaheadMatch[1]),this.termRegExp);
}
}
},
{
name: 'confluenceTable',
match: '^\\|(?:(?:.|\n)*)\\|$',
lookaheadRegExp: /^\|(?:(?:.|\n)*)\|$/mg,
cellRegExp: /(?:\|(?:[^\|]*)\|)(\n|$)?/mg,
cellTermRegExp: /((?:\x20*)\|)/mg,
handler: function(w)
{
var table = createTiddlyElement(w.output,'table');
var rowContainer = createTiddlyElement(table,'tbody');
var prevColumns = [];
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var r = this.rowHandler(w,createTiddlyElement(rowContainer,'tr'),prevColumns);
if(!r) {
w.nextMatch++;
break;
}
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
},
rowHandler: function(w,e,prevColumns)
{
this.cellRegExp.lastIndex = w.nextMatch;
var cellMatch = this.cellRegExp.exec(w.source);
while(cellMatch && cellMatch.index == w.nextMatch) {
w.nextMatch++;
var cell = createTiddlyElement(e,'td');
w.subWikifyTerm(cell,this.cellTermRegExp);
if(cellMatch[1]) {
// End of row
w.nextMatch = this.cellRegExp.lastIndex;
return true;
} else {
// Cell
w.nextMatch--;
}
this.cellRegExp.lastIndex = w.nextMatch;
cellMatch = this.cellRegExp.exec(w.source);
}
return false;
}
},
{
name: 'confluenceList',
match: '^[#\\*\\-]+ ',
lookaheadRegExp: /^(?:(#)|(\*)|(\-))+ /mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var stack = [w.output];
var currLevel = 0, currType = null;
var listLevel, listType;
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var style = lookaheadMatch[3] ? 'square' : null;
listType = lookaheadMatch[1] ? 'ol' : 'ul';
listLevel = lookaheadMatch[0].length;
w.nextMatch += listLevel;
if(listLevel > currLevel){
for(var i=currLevel; i<listLevel; i++) {
stack.push(createTiddlyElement(stack[stack.length-1],listType));
}
} else if(listLevel < currLevel) {
for(i=currLevel; i>listLevel; i--) {
stack.pop();
}
} else if(listLevel == currLevel && listType != currType) {
stack.pop();
stack.push(createTiddlyElement(stack[stack.length-1],listType));
}
currLevel = listLevel;
currType = listType;
var e = createTiddlyElement(stack[stack.length-1],'li');
e.style[config.browser.isIE ? 'list-style-type' : 'listStyleType'] = style;
w.subWikifyTerm(e,this.termRegExp);
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'confluenceBlockQuote',
match: '^bq(?:(?:\\(.*?\\))|(?:\\{.*?\\})|(?:\\[.*?\\]))?\\. ',
lookaheadRegExp: /^bq(?:(?:\((#?)(.*?)\))|(?:\{(.*?)\})|(?:\[(.*?)\]))?\. /mg,
termRegExp: /(\n)/mg,
element: 'blockquote',
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e = createTiddlyElement(w.output,this.element);
w.subWikifyTerm(e,this.termRegExp);
}
}
},
{
name: 'confluenceQuote',
match: '^{quote}\\n',
termRegExp: /(^\{quote\}[\n|$])/mg,
element: 'blockquote',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'confluenceNoformat',
match: '^{noformat}\\n',
lookaheadRegExp: /\{noformat\}((?:.|\n)*?)\{noformat\}/mg,
element: 'pre',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'confluenceRule',
match: '^---+$\\n?',
handler: function(w)
{
createTiddlyElement(w.output,'hr');
}
},
{
name: 'macro',
match: '<<',
lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
}
}
},
{
name: 'confluenceExternalLink',
match: '(?:".*?" ?):?[a-z]{2,8}:',
lookaheadRegExp: /(?:\"(.*?)(?:\((.*?)\))?\" ?):?(.*?)(?=\s|$)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var link = lookaheadMatch[3];
var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
var e = createExternalLink(w.output,link);
if(lookaheadMatch[2])
e.title = lookaheadMatch[2];
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'confluenceUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'confluenceExplicitLink',
match: '\\[',
lookaheadRegExp: /\[([^\|\]]*?)(?:(?:\])|(?:\|(.*?))\])/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
{
var text = lookaheadMatch[1];
var link = lookaheadMatch[2] ? lookaheadMatch[2] : text;
var tip = lookaheadMatch[3] ? lookaheadMatch[3] : text;
var e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
confluenceFormatter.subWikify(w,e,text);
//createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'confluenceImage',
match: '!.*?!',
lookaheadRegExp: /!(.*?)(?:\((.*?)\))?!/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var img = createTiddlyElement(w.output,'img');
img.src = lookaheadMatch[1];
if(lookaheadMatch[2]) {
img.title = lookaheadMatch[2];
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'confluenceBold',
match: '\\*(?![\\s\\*])',
lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[\s\._\-])/mg,
termRegExp: /((?!\s)\*(?=[\s\.\-_]))/mg,
element: 'strong',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceItalic',
match: '_(?![\\s_])',
lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[\s\.\*\-])/mg,
termRegExp: /((?!\s)_(?=[\s\.\*\-]))/mg,
element: 'em',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceUnderline',
match: '\\+(?![\\s|\\+])',
lookaheadRegExp: /\+(?!\s)(?:.*?)(?!\s)\+(?=\s)/mg,
termRegExp: /((?!\s)\+(?=\s))/mg,
element: 'u',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceStrike',
match: '-(?![\\s\\-])',
lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[\s\.\*_])/mg,
termRegExp: /((?!\s)-(?=[\s\.\*_]))/mg,
element: 'strike',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceSuperscript',
match: '\\^(?![\\s|\\^])',
lookaheadRegExp: /\^(?!\s)(?:.*?)(?!\s)\^(?=\s)/mg,
termRegExp: /((?!\s)\^(?=\s))/mg,
element: 'sup',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceSubscript',
match: '~(?![\\s|~])',
lookaheadRegExp: /~(?!\s)(?:.*?)(?!\s)~(?=\s)/mg,
termRegExp: /((?!\s)~(?=\s))/mg,
element: 'sub',
handler: confluenceFormatter.singleCharFormat
},
{
name: 'confluenceCitation',
match: '\\?\\?',
termRegExp: /(\?\?)/mg,
element: 'cite',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'confluenceMonospacedByChar',
match: '\\{\\{',
lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
element: 'code',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'confluenceParagraph',
match: '\\n{2,}',
handler: function(w)
{
createTiddlyElement(w.output,'p');
}
},
{
name: 'confluenceExplicitLineBreak',
match: '<br ?/?>|\\\\|\\n',
handler: function(w)
{
createTiddlyElement(w.output,'br');
}
},
{
name: 'confluenceComment',
match: '<!\\-\\-',
lookaheadRegExp: /<!\-\-((?:.|\n)*?)\-\-!>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'confluenceMdash',
match: '---',
handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '—';}
},
{
name: 'confluenceNdash',
match: '--',
handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '–';}
},
{
name: 'confluenceTrademark',
match: '\\(TM\\)',
handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '™';}
},
{
name: 'confluenceRegistered',
match: '\\(R\\)',
text: '®',
handler: confluenceFormatter.createSpan
//handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '®';}
},
{
name: 'confluenceCopyright',
match: '\\(C\\)',
handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '©';}
},
{
name: 'confluenceElipsis',
match: '\\.\\.\\.',
handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '…';}
},
{
name: 'confluenceMacros',
match: '\\{(?:[a-z]{2,16})(?:: ?.*?)?\\}',
lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
handler: confluenceFormatter.macros
},
{
name: 'confluenceHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
},
{
name: 'confluenceHtmlTag',
match: "<(?:[a-zA-Z]{2,}|a)(?:\\s*(?:(?:.*?)=[\"']?(?:.*?)[\"']?))*?>",
lookaheadRegExp: /<([a-zA-Z]+)((?:\s+(?:.*?)=["']?(?:.*?)["']?)*?)?\s*(\/)?>(?:\n?)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e =createTiddlyElement(w.output,lookaheadMatch[1]);
if(lookaheadMatch[2]) {
confluenceFormatter.setAttributesFromParams(e,lookaheadMatch[2]);
}
if(lookaheadMatch[3]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;// empty tag
} else {
w.subWikify(e,'</'+lookaheadMatch[1]+'>');
}
}
}
}/*,
{
name: 'confluenceMatchedQuotes',
match: '(?=\s)"',
lookaheadRegExp: /\"((?:.|\n)*?)\"/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
createTiddlyElement(w.output,'span').innerHTML = '“' + lookaheadMatch[1] + '”';
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
}*/
];
config.parsers.confluenceFormatter = new Formatter(config.confluenceFormatters);
config.parsers.confluenceFormatter.format = 'confluence';
config.parsers.confluenceFormatter.formatTag = 'ConfluenceFormat';
} // end of 'install only once'
//}}}
© Martin Budden 2006,2007
This TiddlyWiki is published under a [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]].
This gives you the freedom to use it pretty much however you want, including for commercial purposes, as long as you keep the copyright notice. If you do use items from this page a link back to http://www.martinswiki.com/ is appreciated.
/***
|''Name:''|CreoleFormatterPlugin|
|''Description:''|Extension of TiddlyWiki syntax to support [[Creole|http://www.wikicreole.org/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#CreoleFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/CreoleFormatterPlugin.js |
|''Version:''|0.1.8|
|''Date:''|May 7, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
This is an early release of the CreoleFormatterPlugin, which extends the TiddlyWiki syntax to support Creole
text formatting. See [[testCreoleFormat]] for an example.
The Creole formatter is different from the other formatters in that Tiddlers are not required to be
tagged: instead the Creole format adds formatting that augments TiddlyWiki's format.
The Creole formatter adds the following:
# {{{**}}} for bold
# {{{=Heading 1=}}} with 1 to 6 equals signs for headings
# {{{[[link|title]]}}} format for links (rather than TW's {{{[[title|link]]}}}).
Since Creole augments rather than replaces TW's formatting there is a problem of how to resolve a prettyLink:
the formatter has some intelligence to determine if whether a link is a TW style link or a Creole style link.
Additionally a tiddler can be tagged 'titleThenLinkFormat' or 'linkThenTitleFormat' to force resolution one
way or the other.
See: http://www.wikicreole.org/wiki/Home
Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
This is an early alpha release, with (at least) the following known issues:
# Creole image format not yet supported
***/
//{{{
// Ensure that the CreoleFormatterPlugin is only installed once.
if(!version.extensions.CreoleFormatterPlugin) {
version.extensions.CreoleFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1)) {
alertAndThrow('CreoleFormatterPlugin requires TiddlyWiki 2.1 or later.');
}
creoleFormatter = {}; // 'namespace' for local functions
creoleFormatter.heading = {
name: 'creoleHeading',
match: '^={1,6}(?!=)',
termRegExp: /(={0,6}\n+)/mg,
handler: function(w) {w.subWikifyTerm(createTiddlyElement(w.output,'h' + w.matchLength),this.termRegExp);}
};
creoleFormatter.bold = {
name: 'creoleBold',
match: '\\*\\*',
termRegExp: /(\*\*|(?=\n\n))/mg,
element: 'strong',
handler: config.formatterHelpers.createElementAndWikify
};
creoleFormatter.explicitLink = {
name: 'creoleExplicitLink',
match: '\\[\\[',
lookaheadRegExp: /\[\[(.*?)(?:\|(.*?))?\]\]/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e;
var link = lookaheadMatch[1];
var text = lookaheadMatch[2];
if(text) {
// both text and link defined, so try and workout which is which
var wlRegExp = new RegExp(config.textPrimitives.wikiLink,'mg');
wlRegExp.lastIndex = 0;
if(w.tiddler.isTagged('titleThenLinkFormat')) {
// format is [[text|link]]
link = text;
text = lookaheadMatch[1];
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
} else if(w.tiddler.isTagged('linkThenTitleFormat')) {
// standard format is [[link|text]]
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
} else if(config.formatterHelpers.isExternalLink(link)) {
e = createExternalLink(w.output,link);
} else if(config.formatterHelpers.isExternalLink(text)) {
link = text;
text = lookaheadMatch[1];
e = createExternalLink(w.output,link);
} else if(store.tiddlerExists(link)) {
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
} else if(store.tiddlerExists(text)) {
link = text;
text = lookaheadMatch[1];
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
} else if(wlRegExp.exec(text)) {
//text is a WikiWord, so assume its a tiddler link
link = text;
text = lookaheadMatch[1];
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
} else {
// assume standard link format
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
}
} else {
text = link;
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
}
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}//# end handler
};
creoleFormatter.replaceFormatters = function()
{
// replace formatters where necessary
for(var i=0; i<config.formatters.length; i++) {
// replace formatters as required
var name = config.formatters[i].name;
if(name == 'prettyLink') {
config.formatters[i] = creoleFormatter.explicitLink;
} else if(name == 'italicByChar') {
config.formatters[i].termRegExp = /(\/\/|(?=\n\n))/mg;
} else if(name == 'list') {
// require a space after the list character (required for '*' which otherwise clashes with bold
config.formatters[i].match = '^[\\*#;:]+ ';
}
}
};
creoleFormatter.replaceFormatters();
// add new formatters
config.formatters.push(creoleFormatter.heading);
config.formatters.push(creoleFormatter.bold);
}// end of 'install only once'
//}}}
/***
|''Name:''|CryptoTEAPlugin|
|''Description:''|TEA (Tiny Encryption Algorithm) and supporting Cryptographic functions|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://martinswiki.com/#CryptoTEAPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/CryptoTEAPlugin.js |
|''Version:''|0.1.7|
|''Date:''|May 7, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.3|
Based on [[Movable Type Script|http://www.movable-type.co.uk/scripts/TEAblock.html]]
***/
//{{{
// Ensure that the Crypto TEA Plugin is only installed once.
if(!version.extensions.CryptoTEAPlugin) {
version.extensions.CryptoTEAPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1) || (version.major == 2 && version.minor == 1 && version.revision <3 ))
alertAndThrow('CryptoTEAPlugin requires TiddlyWiki 2.1.3 or later.');
Crypto.b64open = "''Base64''\n/*{{{*/\n";
Crypto.b64close = "\n/*}}}*/\n''Base64''";
Crypto.b64code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
Crypto.salt = String.fromCharCode(138,200,184,222,198,210,113,77);
Crypto.iterationCount = 4;
Crypto.passphraseToKey = function(passphrase)
// Use an iterated SHA-1 hash of the salted passphrase as a reasonably good key
{
postSalt = String.fromCharCode(23,160,248,216,146,5,102,239);
var k = Crypto.sha1Str(Crypto.salt+passphrase+postSalt);
for(var i = 1;i<Crypto.iterationCount;i++)
k = Crypto.sha1(k,k.length);
return k;
};
Crypto.base64armor = function(s)
{
return Crypto.b64open + Crypto.base64encode(s) + Crypto.b64close;
};
Crypto.base64encode = function(s)
{
b64code = Crypto.b64code;
var line = '';
var b64 = '';
var maxLen4 = 60;
var i;
for(i=0;i<=s.length-3;i+=3) {
if(line.length>maxLen4) {
b64 += line + '\n';
line = '';
}
line += b64code.charAt(s.charCodeAt(i)>>>2);
line += b64code.charAt(((s.charCodeAt(i)&3)<<4) | (s.charCodeAt(i+1)>>>4));
line += b64code.charAt(((s.charCodeAt(i+1)&0x0F)<< 2) | (s.charCodeAt(i+2)>>>6));
line += b64code.charAt(s.charCodeAt(i+2)&0x3F);
}
if(i==s.length-1) {
line += b64code.charAt(s.charCodeAt(i)>>>2);
line += b64code.charAt((s.charCodeAt(i)&3)<<4);
line += '==';
} else if(i==s.length-2) {
line += b64code.charAt(s.charCodeAt(i)>>>2);
line += b64code.charAt(((s.charCodeAt(i)&3)<<4) | (s.charCodeAt(i+1)>>>4));
line += b64code.charAt((s.charCodeAt(i+1)&0x0F)<<2);
line += '=';
}
if(b64.length > maxLen4) {
b64 += line + '\n';
line = '';
}
b64 += line;
return b64;
};
Crypto.base64decode = function(s)
{
b64code = Crypto.b64code;
var i;
if((i=s.indexOf(Crypto.b64open)) >= 0)
s = s.substring(i + Crypto.b64open.length,s.length);
if((i=s.indexOf(Crypto.b64close)) >= 0)
s = s.substring(0,i);
for(i=0;i<s.length;i++) {
if(b64code.indexOf(s.charAt(i)) != -1)
break;
}
var j,c;
var sg = 0;
var n = 0;
var b = new Array();
var d = new Array();
while(i<s.length) {
for(j=0;j<4;) {
if(i>=s.length) {
if(j>0) {
displayMessage('truncated');
return b;
}
break;
}
c = b64code.indexOf(s.charAt(i));
if(c>=0) {
d[j++] = c;
} else if(s.charAt(i)=='=') {
d[j++] = 0;
sg++;
}
i++;
}
if(j==4) {
b[n++] = ((d[0]<<2) | (d[1]>>>4)) & 0xFF;
if(sg<2) {
b[n++] = ((d[1]<<4) | (d[2]>>>2)) & 0xFF;
if(sg<1)
b[n++] = ((d[2]<<6) | d[3]) & 0xFF;
}
}
}
var r = new Array(b.length);
for(i=0;i<b.length;i++)
r[i] = String.fromCharCode(b[i]);
return r.join('');
};
Crypto.TEA = {};
Crypto.TEA.name = function()
{
return 'TEA';
};
Crypto.TEA.base64encode = Crypto.base64armor;
Crypto.TEA.base64decode = Crypto.base64decode;
Crypto.TEA.encipher = function(v,k)
// Encrypt, using TEA, array v with key k
{
if(v.length == 1) {
v[1] = 0;
}
var n = v.length;
var delta = 0x9E3779B9;
var q = Math.floor(6+52/n);
n--;
var sum = 0;
var z = v[n];
var y,mx,e;
while(q-- > 0) {
sum += delta;
e = sum>>>2 & 3;
for(var p=0; p<n; p++) {
y = v[p+1];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
z = v[p] += mx;
}
y = v[0];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
z = v[n] += mx;
}
};
Crypto.TEA.decipher = function(v,k)
// Decrypt, using TEA, array v with key k
{
var n = v.length;
var delta = 0x9E3779B9;
var sum = delta*Math.floor(6+52/n);
n--;
var y = v[0];
var z,mx,e;
while(sum != 0) {
e = sum>>>2 & 3;
for(var p=n; p>0; p--) {
z = v[p-1];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
y = v[p] -= mx;
}
z = v[n];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
y = v[0] -= mx;
sum -= delta;
}
};
Crypto.TEA.encrypt = function(plaintext,passphrase)
// Encrypt the plaintext
{
if(plaintext.length == 0)
return('');// nothing to encrypt
var v = Crypto.strToBe32s(plaintext);
Crypto.TEA.encipher(v,Crypto.passphraseToKey(passphrase));
return Crypto.be32sToStr(v);
};
Crypto.TEA.encryptPassphrase = function(passphrase)
// Encrypt the passphrase with itself
{
if(passphrase.length == 0)
return('');// nothing to encrypt
var v = Crypto.strToBe32s(passphrase);
Crypto.TEA.encipher(v,Crypto.passphraseToKey(passphrase));
var s = Crypto.base64encode(Crypto.be32sToStr(v)).substr(0,20);
return s.replace(/\+/g,'a').replace(/\//g,'a').replace(/=/g,'c');
};
Crypto.TEA.decrypt = function(ciphertext,passphrase)
// Decrypt ciphertext
{
if(ciphertext.length == 0)
return('');// nothing to decrypt
var v = Crypto.strToBe32s(ciphertext);
Crypto.TEA.decipher(v,Crypto.passphraseToKey(passphrase));
var plaintext = Crypto.be32sToStr(v);
if(plaintext.search(/\0/) != -1) {
plaintext = plaintext.slice(0,plaintext.search(/\0/));
}
return plaintext;
};
} // end of 'install only once'
//}}}
/***
|''Name:''|DisableStrikeThroughPlugin|
|''Description:''|Allows you to disable TiddlyWiki's automatic linking of WikiWords|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DisableStrikeThroughPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/DisableStrikeThroughPlugin.js |
|''Version:''|0.0.1|
|''Date:''|Feb 18, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
***/
//{{{
// Ensure that the DisableStrikeThroughPlugin is only installed once.
if(!version.extensions.DisableStrikeThroughPlugin) {
version.extensions.DisableStrikeThroughPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('DisableStrikeThroughPlugin requires TiddlyWiki 2.1 or newer.');}
DisableStrikeThroughPlugin = {};
DisableStrikeThroughPlugin.replaceFormatters = function()
{
for(var i=0; i<config.formatters.length; i++) {
var name = config.formatters[i].name;
if(name == 'characterFormat') {
config.formatters[i].match = "''|//|__|\\^\\^|~~|\\{\\{\\{";
break;
} else if(name == 'strikeByChar') {
config.formatters.splice(i,1);
break;
}
}
};
DisableStrikeThroughPlugin.replaceFormatters();
} // end of 'install only once'
//}}}
/***
|''Name:''|DisableWikiLinksPlugin|
|''Description:''|Allows you to disable TiddlyWiki's automatic linking of WikiWords|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DisableWikiLinksPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/DisableWikiLinksPlugin.js |
|''Version:''|0.1.3|
|''Date:''|Aug 5, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
|''Disable WikiLinks''|<<option chkDisableWikiLinks>>|
***/
//{{{
// Ensure that the DisableWikiLinksPlugin is only installed once.
if(!version.extensions.DisableWikiLinksPlugin) {
version.extensions.DisableWikiLinksPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('DisableWikiLinksPlugin requires TiddlyWiki 2.1 or newer.');}
if (config.options.chkDisableWikiLinks==undefined)
{config.options.chkDisableWikiLinks = false;}
Tiddler.prototype.autoLinkWikiWords = function()
{
if(config.options.chkDisableWikiLinks==true)
{return false;}
return !this.isTagged('systemConfig') && !this.isTagged('excludeMissing');
};
} // end of 'install only once'
//}}}
|!Format|!Markup|!Example|
|''Headings''|{{{!!Heading 2}}}<br />{{{!!!Heading 3}}}<br />{{{!!!!Heading 4}}}<br />{{{!!!!!Heading 5}}}<br /><br />Usually avoid Heading1 as Tiddler titles are nominally Heading1.|<html><h2>Heading 2</h2><h3>Heading 3</h3><h4>Heading 4</h4><h5>Heading 5</h5></html>|
|''Lists''|{{{*Bulleted list}}}|<html><ul><li>Bulleted List</li></ul></html>|
|~|{{{#Numbered list}}}|<html><ol><li>Numbered List</li></ol></html>|
|~|Definition list<br />{{{;Term}}}<br />{{{:definition}}}|<html><dl><dt>Term</dt><dd>definition</dd></dl></html>|
|~|Lists can be mixed and nested<br />{{{*}}}Bullet<br />{{{*#}}}Number<br />{{{*#;}}}Item<br />{{{*#:}}}Definition|<html><ul><li>Bullet<ol><li>Numbered<dl><dt></dt>Item<dd>Definition</dd></dl></li></ol></li></ul></html>|
|''Block quotes''|{{{>Blockquote}}}<br />{{{>>Nested quote}}}|<html><blockquote>Blockquote<blockquote>Nested<br/> quote</blockquote></blockquote></html>|
|~|{{{<<<}}}<br />{{{multi-line}}}<br />{{{blockquote}}}<br />{{{<<<}}}|<html><blockquote>multi-line<br/>blockquote</blockquote></html>|
|''Horizontal Rule''|{{{----}}} (4 dashes on a line of their own)|<html><hr></html>|
|''Links''|Any {{{WikiWord}}} creates a link to a tiddler (whether it exists or not).<br />Note that a WikiWord has to start with a capital letter and have a further mix of upper and lower case.|[[WikiWord]]|
|~|Manual link<br />{{{[[Table of Contents]]}}} (Especially for tiddlers with spaces in their titles)|[[Table of Contents]]|
|~|{{{[[Pretty Link|Link]]}}}|[[Pretty Link|Link]]|
|~|Automatic external link {{{http://www.tiddlywiki.com}}}|http://www.tiddlywiki.com|
|~|Pretty external link<br />{{{[[My Home Page|http://www.tiddlywiki.com]]}}}|[[My Home Page|http://www.tiddlywiki.com]]|
|~|OS Folder link<br />Windows Share: {{{file://///server/share}}}<br />Windows Local: {{{file:///c:/folder/file}}}<br />Un*x Local File: {{{file://folder/file}}}<br />Relative File: {{{[[folder/file]]}}}|file://///server/share <br />file:///c:/folder/file <br />file://folder/file <br /> [[folder/file]]|
|''Images''|{{{[img[favicon.ico]]}}}<br />Note that image files are always external to the TW file|[img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Right aligned<br />{{{[>img[favicon.ico]]}}}|[>img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Left aligned<br />{{{[<img[favicon.ico]]}}}|[<img[http://www.tiddlywiki.com/favicon.ico]]|
|''Image Links''|{{{[img[fav.ico][TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][TiddlerName]]|
|~|{{{[img[fav.ico][Alias|TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][Alias|TiddlerName]]|
|~|{{{[img[fav.ico][http://www.aa.com]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][http://www.tiddlywiki.com]]|
|~|>|also see ''Links'' and ''Images'' sections in this table|
|''Inline''<br />''Comments''|{{{Not shown: /% hidden comment %/}}}<br />Text between the markers will not be shown|Not shown:/% hidden text %/|
You can save a complete copy of this site as a TiddlyWiki on your local drive by right clicking on [[this link|index.html]]
and selecting //Save link as...// or //Save target as...//. You can choose where to save the file, and what to call it (but make sure that it's saved in HTML format and with an HTML extension).
@@There can be confusing and subtle differences between different browsers. Some points to watch:@@
* If you're using Windows XP Service Pack 2 or Windows Vista, check for known [[ServicePack2Problems|http://www.tiddlywiki.com/#ServicePack2Problems]] and [[VistaIssues|http://www.tiddlywiki.com/#VistaIssues]]
* Do ''not'' use the File/Save command in your browser to save TiddlyWiki, because of [[SaveUnpredictabilities|http://www.tiddlywiki.com/#SaveUnpredictabilities]].
* Make sure that you're saving in HTML (or "page source" format), not one of the new-fangled archive formats
/***
|''Name:''|EncryptionCommandsPlugin|
|''Description:''|Toolbar commands for cryptographic functions|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://martinswiki.com/#EncryptionCommandsPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/EncryptionCommandsPlugin.js |
|''Version:''|0.1.7|
|''Date:''|Feb 4, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.3|
|''Requires''|[[CryptoTEAPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/CryptoTEAPlugin.js ]]|
{{{<<tiddler EncryptionCommandsPluginDocumentation>>}}}
***/
//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.EncryptionCommandsPlugin) {
version.extensions.EncryptionCommandsPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1) || (version.major == 2 && version.minor == 1 && version.revision <3 ))
alertAndThrow("EncryptionCommandsPlugin requires TiddlyWiki 2.1.3 or later.");
config.commands.editTiddler.isEnabled = function(tiddler)
{
return tiddler.fields.encryption ? false : true;
};
config.commands.encryptTiddler = {
hideReadOnly: true,
hideShadow: true,
encryptableTag: 'encryptable',
base64Tag: 'base64',
base64encode: null,
encryption: null
};
merge(config.commands.encryptTiddler,{
text: "encrypt",
tooltip: "Encrypt this tiddler",
passphrasePrompt: "Enter encryption passphrase"
});
config.commands.encryptTiddler.isEnabled = function(tiddler)
{
return this.encryption &&
!tiddler.isTagged('systemConfig') && !store.getValue(tiddler,'encryption') &&
(tiddler.isTagged(this.encryptableTag) || tiddler.isTagged(this.base64Tag));
};
config.commands.encryptTiddler.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(!this.isEnabled(tiddler))
return;
if(tiddler.isTagged(this.base64Tag)) {
tiddler.text = this.base64encode(tiddler.text);
var name = 'base64';
} else {
if(!this.encryption || !this.encryption.encrypt)
return;
var passphrase = prompt(this.passphrasePrompt,'');
if(!passphrase)
return;
if(this.encryption.encryptPassphrase) {
store.setValue(tiddler,'passphrase',this.encryption.encryptPassphrase(passphrase));
}
var text = this.encryption.encrypt(tiddler.text,passphrase);
tiddler.text = this.base64encode(text);
name = this.encryption.name();
}
var i = tiddler.tags.indexOf(this.encryptableTag);
if(i!=-1)
tiddler.tags.splice(i,1);
store.setValue(tiddler,'encryption',name);
store.addTiddler(tiddler);
story.saveTiddler(title,event.shiftKey);
story.refreshTiddler(title,1,true);
};
config.commands.decryptTiddler = {
hideReadOnly: true,
hideShadow: true,
encryptableTag: 'encryptable',
base64Tag: 'base64',
base64decode: null,
encryption: null
};
// localization
merge(config.commands.decryptTiddler,{
text: "decrypt",
tooltip: "Decrypt this tiddler",
passphrasePrompt: "Enter decryption passphrase",
incorrectPassphrase: "Incorrect passphrase"
});
config.commands.decryptTiddler.isEnabled = function(tiddler)
{
return store.getValue(tiddler,'encryption');
};
config.commands.decryptTiddler.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(!this.isEnabled(tiddler))
return;
if(store.getValue(tiddler,'encryption') == 'base64') {
tiddler.text = this.base64decode(tiddler.text);
var tag = 'base64';
} else {
var encryption = Crypto[store.getValue(tiddler,'encryption')];
if(!encryption || !encryption.decrypt || !encryption.base64decode)
return;
var passphrase = prompt(this.passphrasePrompt,'');
if(!passphrase)
return;
if(store.getValue(tiddler,'passphrase') && encryption.encryptPassphrase) {
if(encryption.encryptPassphrase(passphrase)!=store.getValue(tiddler,'passphrase')) {
displayMessage(config.commands.displayDecryptedTiddler.incorrectPassphrase);
return;
}
}
tiddler.text = encryption.decrypt(encryption.base64decode(tiddler.text),passphrase);
tag = this.encryptableTag;
}
tiddler.tags.pushUnique(tag);
store.setValue(tiddler,'encryption',null);
store.setValue(tiddler,'passphrase',null);
store.addTiddler(tiddler);
story.saveTiddler(title,event.shiftKey);
story.refreshTiddler(tiddler.title,1,true);
};
config.commands.displayDecryptedTiddler = {
encryptedTag: 'encryption',
base64Tag: 'base64',
base64decode: null,
encryption: null
};
// localization
merge(config.commands.displayDecryptedTiddler,{
text: "display",
tooltip: "Display this tiddler decrypted",
passphrasePrompt: "Enter decryption passphrase",
incorrectPassphrase: "Incorrect passphrase"
});
config.commands.displayDecryptedTiddler.isEnabled = function(tiddler)
{
return this.base64decode && store.getValue(tiddler,'encryption');
};
config.commands.displayDecryptedTiddler.handler = function(event,src,title)
{
var tiddler = store.fetchTiddler(title);
if(!this.isEnabled(tiddler))
return;
if(tiddler.isTagged(this.base64Tag)) {
var text = this.base64decode(tiddler.text);
} else {
var encryption = Crypto[store.getValue(tiddler,'encryption')];
if(!encryption || !encryption.decrypt || !encryption.base64decode)
return;
var passphrase = prompt(this.passphrasePrompt,'');
if(!passphrase)
return;
if(store.getValue(tiddler,'passphrase') && encryption.encryptPassphrase) {
if(encryption.encryptPassphrase(passphrase)!=store.getValue(tiddler,'passphrase')) {
displayMessage(config.commands.displayDecryptedTiddler.incorrectPassphrase);
return;
}
}
text = encryption.decrypt(encryption.base64decode(tiddler.text),passphrase);
}
var oldText = tiddler.text;
tiddler.text = text;
story.refreshTiddler(tiddler.title,DEFAULT_VIEW_TEMPLATE,true);
tiddler.text = oldText;
};
//}}}
// //Setup
//{{{
encryptionCommandPluginUpdateViewTemplate = function()
{
var title = 'ViewTemplate';
var tiddler = store.fetchTiddler(title);
if(!tiddler) {
tiddler = new Tiddler();
tiddler.title = title;
tiddler.text = config.shadowTiddlers[title];
tiddler.tags.pushUnique('excludeLists');
}
if(tiddler.text.indexOf('encryptTiddler') == -1) {
tiddler.text = tiddler.text.replace("<div class='toolbar' macro='toolbar ","<div class='toolbar' macro='toolbar encryptTiddler displayDecryptedTiddler decryptTiddler ");
store.addTiddler(tiddler);
store.setDirty(true);
}
};
encryptionCommandPluginSetFunctions = function()
{
config.commands.encryptTiddler.base64encode = Crypto.base64armor;
config.commands.encryptTiddler.encryption = Crypto.TEA;
config.commands.decryptTiddler.base64decode = Crypto.base64decode;
config.commands.displayDecryptedTiddler.base64decode = Crypto.base64decode;
};
encryptionCommandPluginUpdateViewTemplate();
encryptionCommandPluginSetFunctions();
//}}}
} // end of 'install only once'
//}}}
/***
|''Name:''|ExampleAdaptorPlugin|
|''Description:''|Example Adaptor which can be used as a basis for creating a new Adaptor|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ExampleAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ExampleAdaptorPlugin.js|
|''Version:''|0.5.3|
|''Status:''|Not for release - this is a template for creating new adaptors|
|''Date:''|Mar 11, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|
To make this example into a real TiddlyWiki adaptor, you need to:
# Globally search and replace ExampleAdpator with the name of your adaptor
# Delete any functionality not supported by you host (for example, putTiddler may not be supported)
# Do the actions indicated by the !!TODO comments, namely:
## Set the values of the main variables, eg ExampleAdaptor.serverType etc
## Fill in the uri templates in the .prototype functions
## Parse the responseText returned in the Callback functions and put the results in the appropriate variables
***/
//{{{
if(!version.extensions.ExampleAdaptorPlugin) {
version.extensions.ExampleAdaptorPlugin = {installed:true};
function ExampleAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
// !!TODO set the variables below
ExampleAdaptor.mimeType = 'text/x.';
ExampleAdaptor.serverType = 'example'; // MUST BE LOWER CASE
ExampleAdaptor.serverParsingErrorMessage = "Error parsing result from server";
ExampleAdaptor.errorInFunctionMessage = "Error in function ExampleAdaptor.%0";
ExampleAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
if(!context.host)
context.host = this.host;
context.host = ExampleAdaptor.fullHostName(context.host);
if(!context.workspace)
context.workspace = this.workspace;
return context;
};
ExampleAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
ExampleAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};
ExampleAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(host.length-1) != '/')
host = host + '/';
return host;
};
ExampleAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
// Convert a page title to the normalized form used in uris
ExampleAdaptor.normalizedTitle = function(title)
{
var n = title.toLowerCase();
n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
if(n.charAt(0)=='_')
n = n.substr(1);
return String(n);
};
// Convert a date in YYYY-MM-DD hh:mm format into a JavaScript Date object
ExampleAdaptor.dateFromEditTime = function(editTime)
{
var dt = editTime;
return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};
ExampleAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
this.host = ExampleAdaptor.fullHostName(host);
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
ExampleAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
this.workspace = workspace;
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
ExampleAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
var uriTemplate = '%0';
var uri = uriTemplate.format([context.host]);
var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getWorkspaceListCallback,context);
return typeof req == 'string' ? req : true;
};
ExampleAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
if(status) {
try {
// !!TODO: parse the responseText here
var list = [];
var item = {
title:'exampleTitle',
name:'exampleName'
};
list.push(item);
} catch (ex) {
context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ExampleAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
var uriTemplate = '%0%1';
var uri = uriTemplate.format([context.host,context.workspace]);
var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerListCallback,context);
return typeof req == 'string' ? req : true;
};
ExampleAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
// !!TODO: parse the responseText here
var list = [];
var tiddler = new Tiddler('example');
list.push(tiddler);
} catch (ex) {
context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
context.tiddlers = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ExampleAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : ExampleAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
// !!TODO set the uriTemplate
uriTemplate = '%0%1%2';
info.uri = uriTemplate.format([host,workspace,tiddler.title]);
return info;
};
ExampleAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(revision)
context.revision = revision;
return this.getTiddler(title,context,userParams,callback);
};
ExampleAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(title)
context.title = title;
if(context.revision) {
// !!TODO set the uriTemplate
var uriTemplate = '%0%1%2%3';
} else {
// !!TODO set the uriTemplate
uriTemplate = '%0%1%2';
}
uri = uriTemplate.format([context.host,context.workspace,ExampleAdaptor.normalizedTitle(title),context.revision]);
context.tiddler = new Tiddler(title);
context.tiddler.fields.wikiformat = 'exampleformat';
context.tiddler.fields['server.type'] = ExampleAdaptor.serverType;
context.tiddler.fields['server.host'] = ExampleAdaptor.minHostName(context.host);
context.tiddler.fields['server.workspace'] = context.workspace;
var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerCallback,context);
return typeof req == 'string' ? req : true;
};
ExampleAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
if(status) {
try {
// !!TODO: parse the responseText here
// !!TODO: fill in tiddler fields as available
//context.tiddler.tags = ;
//context.tiddler.fields['server.page.id'] = ;
//context.tiddler.fields['server.page.name'] = ;
//context.tiddler.fields['server.page.revision'] = String(...);
//context.tiddler.modifier = ;
//context.tiddler.modified = ExampleAdaptor.dateFromEditTime(...);
} catch (ex) {
context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
context.status = true;
} else {
context.statusText = xhr.statusText;
if(context.callback)
context.callback(context,context.userParams);
return;
}
if(context.callback)
context.callback(context,context.userParams);
};
ExampleAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
var uriTemplate = '%0%1%2';
if(!limit)
limit = 10;
var uri = uriTemplate.format([context.host,context.workspace,ExampleAdaptor.normalizedTitle(title),limit]);
var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerRevisionListCallback,context);
return typeof req == 'string' ? req : true;
};
ExampleAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
// !!TODO: parse the responseText here
var list = [];
var tiddler = new Tiddler('example');
// !!TODO: fill in tiddler fields as available
//tiddler.modified = ExampleAdaptor.dateFromEditTime();
//tiddler.modifier = ;
//tiddler.tags = ;
//tiddler.fields['server.page.id'] = ;
//tiddler.fields['server.page.name'] = ;
//tiddler.fields['server.page.revision'] = ;
list.push(tiddler);
} catch (ex) {
context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var sortField = 'server.page.revision';
list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
context.revisions = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ExampleAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.title = tiddler.title;
// !!TODO set the uriTemplate
var uriTemplate = '%0%1%2';
var host = context.host ? context.host : ExampleAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
var req = ExampleAdaptor.doHttpPOST(uri,ExampleAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,ExampleAdaptor.mimeType);
return typeof req == 'string' ? req : true;
};
ExampleAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ExampleAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[ExampleAdaptor.serverType] = ExampleAdaptor;
} //# end of 'install only once'
//}}}
/***
|''Name:''|ExampleFormatterPlugin|
|''Description:''|Example Formatter which can be used as a basis for creating a new Formatter. Allows Tiddlers to use [[example|http://www.example.com/wikitext]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ExampleFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/ExampleFormatterPlugin.js |
|''Version:''|0.1.10|
|''Status:''|Not for release - this is a template for creating new formatters|
|''Date:''|Nov 5, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|
To make this example into a real TiddlyWiki formatter, you need to:
# Globally search and replace ExampleAdpator with the name of your formatter
# Remove any format entries that are not required
# Change the existing format entries as required
# Add any new format entries that are required
***/
//{{{
// Ensure that the ExampleFormatterPlugin is only installed once.
if(!version.extensions.ExampleFormatterPlugin) {
version.extensions.ExampleFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('ExampleFormatterPlugin requires TiddlyWiki 2.1 or later.');}
exampleFormatter = {}; // 'namespace' for local functions
exampleDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement(out,'br');
};
wikify = function(source,output,highlightRegExp,tiddler)
{
if(source && source !== '') {
var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
w.output = tiddler ? createTiddlyElement(output,'p') : output;
w.subWikifyUnterm(w.output);
}
};
config.formatterHelpers.setAttributesFromParams = function(e,p)
{
var re = /\s*(.*?)=(?:(?:"(.*?)")|(?:'(.*?)')|((?:\w|%|#)*))/mg;
var match = re.exec(p);
while(match) {
var s = match[1].unDash();
if(s=='bgcolor') {
s = 'backgroundColor';
}
try {
if(match[2]) {
e.setAttribute(s,match[2]);
} else if(match[3]) {
e.setAttribute(s,match[3]);
} else {
e.setAttribute(s,match[4]);
}
}
catch(ex) {}
match = re.exec(p);
}
};
config.exampleFormatters = [
{
name: 'exampleHeading',
match: '^={1,6}(?!=)',
termRegExp: /(={0,6} *\n+)/mg,
handler: function(w)
{
w.subWikifyTerm(createTiddlyElement(w.output,'h'+w.matchLength),this.termRegExp);
}
},
{
name: 'exampleList',
match: '^[\\*#;:]+ ',
lookaheadRegExp: /^([\*#;:])+ /mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var stack = [w.output];
var currLevel = 0, currType = null;
var listLevel, listType, itemType, baseType;
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
switch(lookaheadMatch[1]) {
case '*':
listType = 'ul';
itemType = 'li';
break;
case '#':
listType = 'ol';
itemType = 'li';
break;
case ';':
listType = 'dl';
itemType = 'dt';
break;
case ':':
listType = 'dl';
itemType = 'dd';
break;
default:
break;
}
if(!baseType)
baseType = listType;
listLevel = lookaheadMatch[0].length;
w.nextMatch += lookaheadMatch[0].length;
var t;
if(listLevel > currLevel) {
for(t=currLevel; t<listLevel; t++) {
var target = (currLevel == 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
stack.push(createTiddlyElement(target,listType));
}
} else if(listType!=baseType && listLevel==1) {
w.nextMatch -= lookaheadMatch[0].length;
return;
} else if(listLevel < currLevel) {
for(t=currLevel; t>listLevel; t--)
stack.pop();
} else if(listLevel == currLevel && listType != currType) {
stack.pop();
stack.push(createTiddlyElement(stack[stack.length-1].lastChild,listType));
}
currLevel = listLevel;
currType = listType;
var e = createTiddlyElement(stack[stack.length-1],itemType);
w.subWikifyTerm(e,this.termRegExp);
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'exampleRule',
match: '^---+$\\n?',
handler: function(w)
{
createTiddlyElement(w.output,'hr');
}
},
{
name: 'macro',
match: '<<',
lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
}
}
},
{
name: 'exampleExplicitLink',
match: '\\[\\[',
lookaheadRegExp: /\[\[(.*?)(?:\|(.*?))?\]\]/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var link = lookaheadMatch[1];
var text = lookaheadMatch[2] ? lookaheadMatch[2] : link;
var e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'exampleNotWikiLink',
match: '!' + config.textPrimitives.wikiLink,
handler: function(w)
{
w.outputText(w.output,w.matchStart+1,w.nextMatch);
}
},
{
name: 'exampleWikiLink',
match: config.textPrimitives.wikiLink,
handler: function(w)
{
if(w.matchStart > 0) {
var preRegExp = new RegExp(config.textPrimitives.anyLetter,'mg');
preRegExp.lastIndex = w.matchStart-1;
var preMatch = preRegExp.exec(w.source);
if(preMatch.index == w.matchStart-1) {
w.outputText(w.output,w.matchStart,w.nextMatch);
return;
}
}
var output = w.output;
if(w.autoLinkWikiWords == true || store.isShadowTiddler(w.matchText)) {
output = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic);
}
w.outputText(output,w.matchStart,w.nextMatch);
}
},
{
name: 'exampleUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'exampleBold',
match: '\\*\\*',
termRegExp: /(\*\*|(?=\n\n))/mg,
element: 'strong',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleItalic',
match: '//',
termRegExp: /(\/\/|(?=\n\n))/mg,
element: 'em',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleUnderline',
match: '__',
termRegExp: /(__|(?=\n\n))/mg,
element: 'u',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleStrikeBy',
match: '--(?!\\s|$)',
termRegExp: /((?!\s)--|(?=\n\n))/mg,
element: 'strike',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleSuperscript',
match: '\\^\\^',
termRegExp: /(\^\^|(?=\n\n))/mg,
element: 'sup',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleSubscript',
match: '~~',
termRegExp: /(~~|(?=\n\n))/mg,
element: 'sub',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'exampleMonospaced',
match: '\\{\\{\\{',
lookaheadRegExp: /\{\{\{((?:.|\n)*?)\}\}\}/mg,
element: 'code',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'exampleParagraph',
match: '\\n{2,}',
handler: function(w)
{
w.output = createTiddlyElement(w.output,'p');
}
},
{
name: 'exampleLineBreak',
match: '\\n|<br ?/?>',
handler: function(w)
{
createTiddlyElement(w.output,'br');
}
},
{
name: 'exampleComment',
match: '<!\\-\\-',
lookaheadRegExp: /<!\-\-((?:.|\n)*?)\-\-!>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'exampleHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
},
{
name: "html",
match: "<[Hh][Tt][Mm][Ll]>",
lookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\n)*?)<\/[Hh][Tt][Mm][Ll]>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1];
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
}
];
config.parsers.exampleFormatter = new Formatter(config.exampleFormatters);
config.parsers.exampleFormatter.format = 'example';
config.parsers.exampleFormatter.formatTag = 'ExampleFormat';
} // end of 'install only once'
//}}}
/***
|''Name:''|ExamplePlugin|
|''Description:''|My Description|
|''Author:''|My Name|
|''Source:''|http://www.MyWebSite.com/#ExamplePlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MyDirectory/plugins/ExamplePlugin.js |
|''Version:''|0.0.1|
|''Status:''|Not for release - this is a template