|''URL:''|http://tiddlywiki.abego-software.de/|
|''Description:''|UdoBorkowski's Extensions for TiddlyWiki|
|''Author:''|UdoBorkowski|
{{{
Adaptor.close()
}}}
Should only be called after the last callback has completed
Closes an adaptor, severing the connection to the workspace and host (see ServerAdaptorConcepts).
* [[Adaptor.close]] shouldn't be called while there are outstanding callbacks
* [[Adaptor.close]] must be called to ensure that all pending write operations are completed
''Parameters:''
None.
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
{{{
Adaptor.getTiddler(title,context,userParams,callback)
}}}
Retrieves a named tiddler from an adaptor opened to a workspace on a host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|title |Title of the tiddler to retrieve |
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |Reference to callback function, see AdaptorCallbackSignature |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature with additional fields:
|context.tiddler |The retrieved tiddler object, with all the standard fields and the ServerAdaptorExtendedFields filled in |
{{{
Adaptor.getTiddlerList(context,userParams,callback,filter)
}}}
Gets a list of the tiddlers available on an adaptor opened to a workspace on a host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |reference to callback function, see AdaptorCallbackSignature |
|filter |optional string to select tiddlers returned in list, see TiddlerSelection |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature with additional fields:
|context.tiddlers |Array of tiddlers, with a minimum set of fields filled in, see below |
The tiddlers in the {{{context.tiddlers}}} array have the following minimum set of fields, although particular adaptors may choose to return additional information in further fields.
|title |Title of the tiddler (as used in [[Adaptor.getTiddler]]) |
{{{
Adaptor.getWorkspaceList(context,userParams,callback)
}}}
Gets a list of the workspaces available on a particular host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |Reference to callback function, see AdaptorCallbackSignature |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature with additional fields:
|context.workspaces |An array of information about each available workspace (see below) |
The entries in the {{{context.workspaces}}} array have the following minimum set of fields, although particular adaptors may choose to return additional information in further fields.
|title |Title of the workspace (as used in [[Adaptor.openWorkspace]]) |
{{{
Adaptor.openHost(host,context,userParams,callback)
}}}
Creates an adaptor for talking to a particular host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|host |URI of server |
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |Reference to callback function, see AdaptorCallbackSignature |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature.
{{{
Adaptor.openWorkspace(host,context,userParams,callback)
}}}
Opens a particular workspace in an adaptor that has already been opened on a host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|workspace |Name of workspace |
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |Reference to callback function, see AdaptorCallbackSignature |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature.
{{{
Adaptor.putTiddler(tiddler,context,userParams,callback)
}}}
Stores a named tiddler to an adaptor opened to a workspace on a host (see ServerAdaptorConcepts). This function uses the AsynchronousPattern.
''Parameters:''
|tiddler |The Tiddler to store |
|context |context object that is passed to the callback function |
|userParams |user settable object object that is passed on unchanged to the callback function |
|callback |Reference to callback function, see AdaptorCallbackSignature |
''Returns:''
|true |on success |
|string |an error message if there was an error issuing the request |
''Callback signature'' as per AdaptorCallbackSignature.
{{{
callback(context,userParams)
}}}
|userParams |userParams object (unchanged) as passed by the original caller |
context contains the following fields:
|context.status |True if original call was successful, false if there was an error |
|context.statusText |Error message if context.status is false |
|context.adpator |Reference to the adaptor object |
Additionally, context may contain the following fields, depending on the adaptor function originally called:
|context.workspaces |Array of workspaces, see [[Adaptor.getWorkspaceList]] |
|context.tiddler |Tiddler retrieved, see [[Adaptor.getTiddler]]|
|context.tiddlers |Array of Tiddlers retrieved, not all Tiddler fields filled in, see [[Adaptor.getTiddlerList]]|
|context.revisions |Array of revisions of the current Tiddler, not all Tiddler fields filled in, see [[Adaptor.getTiddlerRevisionList]] |
Asynchronous methods are used by the low level HttpFunctions, and by higher level mechanisms such as the ServerAdaptorMechanism.
The standard TiddlyWiki approach is illustrated with this example of a {{{procrastinate()}}} function that takes a string parameter which is then returned after 1 second by a callback function:
{{{
// Call an asynchronous function
function test()
{
// The context object is for storing information that you're going to need inside the callback function
var myContext = {
param1: "a string",
param2: {an: "object"},
param3: ["an","array"}
};
// Call the function including a reference to the callback function and it's context
procrastinate("hello tomorrow's world",myCallback,myContext);
}
// The callback function that gets invoked after 1 second
function myCallback(status,context,procrastinatedString)
{
displayMessage("Message from the past: " + procrastinatedString);
displayMessage("Message context: " + context.param1);
}
// The procrastinate function invokes a callback after 1 second with a specified string parameter
// procrastinatedString - the string to pass back to the callback function
// callback - the callback function
// context - a context object that is passed to the callback function
// Returns true if the request was issued or a string error message if it failed
function procrastinate(procrastinatedString,callback,context)
{
window.setInterval(callback,1000,true,context,procrastinatedString);
}
}}}
Asynchronous programming is necessary in several situations but is full of pitfalls for the unwary:
* On many browsers, {{{alert()}}} doesn't work reliably in some asynchronous callbacks
* It's very easy to miss errors by ignoring callback returns
One of the great strengths of TiddlyWiki is the way that its interface can be customised by editting various shadow tiddlers. However, a problem that has consistently emerged is the difficulty of reconciling the needs of authors, who need access to the full array of TiddlyWiki features, and the needs of ordinary readers, who generally benefit from seeing a restricted set of functionality more suited to their needs.
The new backstage area in release 2.2 offers a solution to this conundrum by providing a consistent way of accessing authoring functionality that is independent of the interface customisations (so, even if you blast away the contents of your PageTemplate, you can still access the backstage area).
The backstage area is only available when a TiddlyWiki is edittable - typically meaning that it's been opened off of a {{{file://}}} URL. It appears as an unobtrusive link in the topright corner of the page. Clicking it reveals the backstage toolbar consisting of commands like {{{saveChanges}}} and drop-down tasks like ImportTiddlers, SyncMacro, PluginManager and Tweak (which provides access to the new OptionsMacro).
|''URL:''|http://tiddlywiki.bidix.info/|
|''Description:''|Repository for BidiX's TiddlyWiki Extensions|
|''Author:''|BidiX|
|''URL:''|http://bob.mcelrath.org/plugins.html|
|''Description:''|Bob McElrath's Plugins|
|''Author:''|BobMcElrath|
HelloThere ServerConnectivity BackstageArea OtherNewFeatures
Download the [[full monty|index.html]] or just the [[empty version|empty.html]]
|''URL:''|http://gimcrackd.com/etc/src/|
|''Description:''|Gimcrack'd: Code and Other Oddments|
|''Author:''|ChrisKlimas|
Welcome to version <<version>> of TiddlyWiki, a reusable non-linear personal web notebook (see the [[main site|http://www.tiddlywiki.com/]] for more details).
@@This is beta code -- please test it and use it as much as you can, but be cautious about trusting it with important data@@
There shouldn't be any more major changes before the final release in the next few days, so this makes a good opportunity to test your plugins against the new core code. If you have any feedback or questions, please join the discussion in the [[TiddlyWikiDev Google group|http://groups.google.com/group/TiddlyWikiDev]].
|''URL:''|http://jackparke.googlepages.com/jtw.html|
|''Description:''|Plugins, Macros and Hacks|
|''Author:''|JackParker|
|''URL:''|http://tw.lewcid.org/|
|''Description:''|a repository of my extensions for TW|
|''Author:''|SaqImtiaz|
HelloThere
ServerConnectivity
BackstageArea
OtherNewFeatures
DownloadSoftware
|''URL:''|http://www.martinswiki.com/ |
|''Description:''|Martin Buddens's Plugins |
|''Author:''|MartinBudden |
/***
|''Name:''|MediaWikiAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data from MediaWikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#MediaWikiAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/MediaWikiAdaptorPlugin.js|
|''Version:''|0.5.3|
|''Date:''|Mar 17, 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|
MediaWiki REST documentation is at:
http://meta.wikimedia.org/w/api.php
http://meta.wikimedia.org/w/query.php
***/
//{{{
if(!version.extensions.MediaWikiAdaptorPlugin) {
version.extensions.MediaWikiAdaptorPlugin = {installed:true};
function MediaWikiAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
MediaWikiAdaptor.serverType = 'mediawiki';
MediaWikiAdaptor.serverParsingErrorMessage = "Error parsing result from server";
MediaWikiAdaptor.errorInFunctionMessage = "Error in function MediaWikiAdaptor.%0";
MediaWikiAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
MediaWikiAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
MediaWikiAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(-1) != '/')
host = host + '/';
return host;
};
MediaWikiAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
MediaWikiAdaptor.normalizedTitle = function(title)
{
var n = title.charAt(0).toUpperCase() + title.substr(1);
return n.replace(/\s/g,'_');
};
// Convert a MediaWiki timestamp in YYYY-MM-DDThh:mm:ssZ format into a JavaScript Date object
MediaWikiAdaptor.dateFromTimestamp = function(timestamp)
{
var dt = timestamp;
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)));
};
MediaWikiAdaptor.anyChild = function(obj)
{
for(var key in obj) {
return obj[key];
}
return null;
};
MediaWikiAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = MediaWikiAdaptor.fullHostName(host);
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
MediaWikiAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var workspaces = {
"media": -2, "special":-1,
"": 0, "talk":1,"use":2,"use talk":3,"meta":4,"meta talk":5,"image":6,"image talk":7,
"mediawiki":8,"mediawiki talk":9,"template":10,"template talk":11,"help":12,"help talk":13,
"category":14,"category talk":15};
this.workspace = workspace;
if(workspace) {
workspace = workspace.toLowerCase();
this.workspaceId = workspaces[workspace];
}
if(!this.workspaceId)
this.workspaceId = 0;
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
MediaWikiAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(context.workspace) {
context.status = true;
context.workspace = [{name:"Main",title:"Main"}];
if(context.callback)
window.setTimeout(context.callback,0,context,userParams);
return true;
}
var uriTemplate = '%0api.php?format=json&action=query&meta=siteinfo&siprop=namespaces';
var uri = uriTemplate.format([this.host]);
var req = MediaWikiAdaptor.doHttpGET(uri,MediaWikiAdaptor.getWorkspaceListCallback,context);
return typeof req == 'string' ? req : true;
};
MediaWikiAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,MediaWikiAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var namespaces = info.query.namespaces;
var list = [];
for(var i in namespaces) {
item = {};
item.title = namespaces[i]['*'];
item.name = item.title;
list.push(item);
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
// get a list of the tiddlers in the current workspace
MediaWikiAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
{
context = this.setContext(context,userParams,callback);
if(!context.tiddlerLimit)
context.tiddlerLimit = filter ? 100 : 50;
var limit = context.tiddlerLimit;
if(filter) {
var re = /\[(\w+)\[([ \w]+)\]\]/;
var match = re.exec(filter);
if(match) {
var filterParams = MediaWikiAdaptor.normalizedTitle(match[2]);
switch(match[1]) {
case 'tags':
context.responseType = 'pages';
var uriTemplate = '%0query.php?format=json&what=category&cpnamespace=0&cptitle=%3';
break;
case 'template':
context.responseType = 'query.embeddedin';
uriTemplate = '%0api.php?format=json&action=query&list=embeddedin&einamespace=0&eilimit=%2&titles=Template:%3';
break;
default:
break;
}
} else {
var list = [];
var params = filter.parseParams('anon',null,false);
for(var i=1; i<params.length; i++) {
var tiddler = new Tiddler(params[i].value);
tiddler.fields.workspaceId = this.workspaceId;
list.push(tiddler);
}
context.tiddlers = list;
context.status = true;
if(context.callback)
window.setTimeout(context.callback,0,context,context.userParams);
return true;
}
} else {
context.responseType = 'query.allpages';
uriTemplate = '%0api.php?format=json&action=query&list=allpages';
if(this.workspaceId != 0)
uriTemplate += '&apnamespace=%1';
if(limit)
uriTemplate += '&aplimit=%2';
}
var host = MediaWikiAdaptor.fullHostName(this.host);
var uri = uriTemplate.format([host,this.workspace,limit,filterParams]);
var req = MediaWikiAdaptor.doHttpGET(uri,MediaWikiAdaptor.getTiddlerListCallback,context);
return typeof req == 'string' ? req : true;
};
MediaWikiAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = MediaWikiAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
eval('var info=' + responseText);
var pages;
if(context.responseType == 'query.embeddedin')
pages = info.query.embeddedin;
else if(context.responseType == 'query.allpages')
pages = info.query.allpages;
else
pages = info.pages;
var list = [];
for(var i in pages) {
var tiddler = new Tiddler(pages[i].title);
tiddler.fields.workspaceId = pages[i].ns;
list.push(tiddler);
}
context.tiddlers = list;
} catch (ex) {
context.statusText = exceptionText(ex,MediaWikiAdaptor.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);
};
MediaWikiAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : MediaWikiAdaptor.fullHostName(tiddler.fields['server.host']);
if(host.match(/w\/$/)) {
host = host.replace(/w\/$/,'');
var uriTemplate = '%0wiki/%2';
} else {
uriTemplate = '%0index.php?title=%2';
}
info.uri = uriTemplate.format([host,this.workspace,tiddler.title]);
return info;
};
MediaWikiAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.title = title;
return this.getTiddlerInternal(context,userParams,callback);
};
MediaWikiAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.title = title;
context.revision = revision;
return this.getTiddlerInternal(context,userParams,callback);
};
// @internal
MediaWikiAdaptor.prototype.getTiddlerInternal = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var host = MediaWikiAdaptor.fullHostName(this.host);
if(context.revision) {
var uriTemplate = '%0api.php?format=json&action=query&prop=revisions&titles=%1&rvprop=content&rvstartid=%2&rvlimit=1';
} else {
uriTemplate = '%0api.php?format=json&action=query&prop=revisions&titles=%1&rvprop=content';
}
uri = uriTemplate.format([host,MediaWikiAdaptor.normalizedTitle(context.title),context.revision]);
context.tiddler = new Tiddler(context.title);
context.tiddler.fields.wikiformat = 'mediawiki';
context.tiddler.fields['server.host'] = MediaWikiAdaptor.minHostName(this.host);
var req = MediaWikiAdaptor.doHttpGET(uri,MediaWikiAdaptor.getTiddlerCallback,context);
return typeof req == 'string' ? req : true;
};
MediaWikiAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
eval('var info=' + responseText);
var page = MediaWikiAdaptor.anyChild(info.query.pages);
var revision = MediaWikiAdaptor.anyChild(page.revisions);
context.tiddler.text = revision['*'];
context.tiddler.fields['server.page.revision'] = String(revision['revid']);
} catch (ex) {
context.statusText = exceptionText(ex,MediaWikiAdaptor.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);
};
MediaWikiAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
// get a list of the revisions for a tiddler
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0api.php?format=json&action=query&prop=revisions&titles=%1&rvlimit=%2&rvprop=timestamp|user|comment';
if(!limit)
limit = 5;
var host = MediaWikiAdaptor.fullHostName(this.host);
var uri = uriTemplate.format([host,MediaWikiAdaptor.normalizedTitle(title),limit]);
var req = MediaWikiAdaptor.doHttpGET(uri,MediaWikiAdaptor.getTiddlerRevisionListCallback,context);
return typeof req == 'string' ? req : true;
};
MediaWikiAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
eval('var info=' + responseText);
var page = MediaWikiAdaptor.anyChild(info.query.pages);
var title = page.title;
var revisions = page.revisions;
var list = [];
for(var i in revisions) {
var tiddler = new Tiddler(title);
tiddler.modified = MediaWikiAdaptor.dateFromTimestamp(revisions[i].timestamp);
tiddler.modifier = revisions[i].user;
tiddler.fields.comment = revisions[i].comment;
tiddler.fields['server.page.id'] = MediaWikiAdaptor.normalizedTitle(title);
tiddler.fields['server.page.name'] = title;
tiddler.fields['server.page.revision'] = String(revisions[i].revid);
list.push(tiddler);
}
context.revisions = list;
} catch (ex) {
context.statusText = exceptionText(ex,MediaWikiAdaptor.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);
};
// MediaWikiAdaptor.prototype.putTiddler not supported
MediaWikiAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[MediaWikiAdaptor.serverType] = MediaWikiAdaptor;
} // end of 'install only once'
//}}}
/***
|''Name:''|MediaWikiFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[MediaWiki|http://meta.wikimedia.org/wiki/Help:Wikitext]] ([[WikiPedia|http://meta.wikipedia.org/]]) text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#MediaWikiFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/MediaWikiFormatterPlugin.js|
|''Version:''|0.4.1|
|''Date:''|Mar 20, 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|
|''Display instrumentation''|<<option chkDisplayInstrumentation>>|
|''Display empty template links:''|<<option chkMediaWikiDisplayEmptyTemplateLinks>>|
|''Allow zooming of thumbnail images''|<<option chkMediaWikiDisplayEnableThumbZoom>>|
|''List references''|<<option chkMediaWikiListReferences>>|
|''Display unsupported magic words''|<<option chkDisplayMediaWikiMagicWords>>|
This is the MediaWikiFormatterPlugin, which allows you to insert MediaWiki formated text into a TiddlyWiki.
The aim is not to fully emulate MediaWiki, but to allow you to work with MediaWiki content off-line and then resync the content with your MediaWiki later on, with the expectation that only minor edits will be required.
To use MediaWiki format in a Tiddler, tag the Tiddler with MediaWikiFormat or set the tiddler's {{{wikiformat}}} extended field to {{{mediawiki}}}.
!!!Issues
There are (at least) the following known issues:
# Not all styles from http://meta.wikimedia.org/wiki/MediaWiki:Common.css incorporated
## Styles for tables don't yet match Wikipedia styles.
## Styles for image galleries don't yet match Wikipedia styles.
# Anchors not yet supported.
!!!Not supported
# Template parser functions (also called colon functions) http://meta.wikimedia.org/wiki/ParserFunctions eg {{ #functionname: argument 1 | argument 2 | argument 3... }}
# Magic words and variables http://meta.wikimedia.org/wiki/Help:Magic_words eg {{{__TOC__}}}, {{CURRENTDAY}}, {{PAGENAME}}
# {{{^''}}} (italic at start of line) indents, makes italic and quotes with guilmot quote
!!!No plans to support
# Template substitution on save http://meta.wikimedia.org/wiki/Help:Substitution eg {{ subst: templatename }}
***/
//{{{
// Ensure that the MediaWikiFormatter Plugin is only installed once.
if(!version.extensions.MediaWikiFormatterPlugin) {
version.extensions.MediaWikiFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('MediaWikiFormatterPlugin requires TiddlyWiki 2.1 or later.');}
if(config.options.chkDisplayInstrumentation == undefined)
{config.options.chkDisplayInstrumentation = false;}
if(config.options.chkMediaWikiDisplayEmptyTemplateLinks == undefined)
{config.options.chkMediaWikiDisplayEmptyTemplateLinks = false;}
if(config.options.chkMediaWikiDisplayEnableThumbZoom == undefined)
{config.options.chkMediaWikiDisplayEnableThumbZoom = false;}
if(config.options.chkMediaWikiListReferences == undefined)
{config.options.chkMediaWikiListReferences = false;}
if(config.options.chkDisplayMediaWikiMagicWords == undefined)
{config.options.chkDisplayMediaWikiMagicWords = false;}
MediaWikiFormatter = {}; // 'namespace' for local functions
mwDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement2(out,'br');
};
MediaWikiFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
if((this.fields.wikiformat==config.parsers.mediaWikiFormatter.format) || this.isTagged(config.parsers.mediaWikiFormatter.formatTag)) {
this.links = [];
var tiddlerLinkRegExp = /\[\[(?::?([A-Za-z]{2,}:)?)(#?)([^\|\]]*?)(?:(\]\])|(\|(.*?)\]\]))/mg;
tiddlerLinkRegExp.lastIndex = 0;
var match = tiddlerLinkRegExp.exec(this.text);
while(match) {
if(!match[1] && !match[2])
this.links.pushUnique(match[3]);
match = tiddlerLinkRegExp.exec(this.text);
}
} else if(!this.isTagged('systemConfig')) {
MediaWikiFormatter.Tiddler_changed.apply(this,arguments);
return;
}
this.linksUpdated = true;
};
TiddlyWiki.prototype.getTemplates = function()
{
var results = [];
this.forEachTiddler(function(title,tiddler) {
if(tiddler.title.substr(0,9)=='Template:')
results.push(tiddler);
});
results.sort(function(a,b) {return a.title < b.title ? -1 : +1;});
return results;
};
TiddlyWiki.prototype.getMediaWikiArticles = function()
{
var results = [];
this.forEachTiddler(function(title,tiddler) {
if(!tiddler.isTagged('excludeLists') && tiddler.title.substr(0,9)!='Template:')
results.push(tiddler);
});
results.sort(function(a,b) {return a.title < b.title ? -1 : +1;});
return results;
};
config.macros.list.templates = {};
config.macros.list.templates.handler = function(params)
{
return store.getTemplates();
};
wikify = function(source,output,highlightRegExp,tiddler)
{
if(source && source != '') {
var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
w.linkCount = 0;
w.tableDepth = 0;
w.output = tiddler==null ? output : createTiddlyElement2(output,'p');
var time1,time0 = new Date();
w.subWikifyUnterm(w.output);
if(tiddler && config.options.chkDisplayInstrumentation) {
time1 = new Date();
var t = tiddler ? tiddler.title : source.substr(0,10);
displayMessage('Wikify "'+t+'" in ' + (time1-time0) + ' ms');
}
}
};
function createTiddlyElement2(parent,element)
{
var e = document.createElement(element);
parent.appendChild(e);
return e;
}
config.formatterHelpers.createElementAndWikify = function(w)
{
w.subWikifyTerm(createTiddlyElement2(w.output,this.element),this.termRegExp);
};
MediaWikiFormatter.hijackListAll = function ()
{
MediaWikiFormatter.oldListAll = config.macros.list.all.handler;
config.macros.list.all.handler = function(params) {
return store.getMediaWikiArticles();
};
};
MediaWikiFormatter.hijackListAll();
MediaWikiFormatter.normalizedTitle = function(title)
{
title = title.trim();
var n = title.charAt(0).toUpperCase() + title.substr(1);
return n.replace(/\s/g,'_');
};
MediaWikiFormatter.expandVariable = function(w,variable)
{
switch(variable) {
case 'PAGENAME':
createTiddlyText(w.output,w.tiddler.title);
w.nextMatch = lastIndex;
break;
default:
return false;
}
return true;
};
MediaWikiFormatter.getTemplateParams = function(text)
{
var params = {};
text += '|';
var pRegExp = /(?:([^\|]*)=)?([^\|]*)\|/mg;
var match = pRegExp.exec(text);
if(match) {
match = pRegExp.exec(text);
}
var i = 1;
while(match) {
if(match[1]) {
params[match[1]] = match[2];
} else {
params[i] = match[2];
i++;
}
match = pRegExp.exec(text);
}
return params;
};
MediaWikiFormatter.evaluateTemplateParserFunctions = function(text)
{
var fnRegExp = /\{\{#if:([^\|]*?)\|([^\|]*?)(?:\|(.*?))?\}\}/mg;
var t = '';
var fi = 0;
match = fnRegExp.exec(text);
while(match) {
displayMessage("m:"+match);
displayMessage("m0:"+match[0]);
displayMessage("m1:"+match[1]);
displayMessage("m2:"+match[2]);
displayMessage("m3:"+match[3]);
displayMessage("ss:"+text.substring(fi,match.index));
t += text.substring(fi,match.index);
var m = match[1] ? match[1].trim() : null;
if(m)
t += match[2];
else if(match[3])
t += match[3].trim();
fi = fnRegExp.lastIndex;
match = fnRegExp.exec(text);
}
t += text.substring(fi);
text = t == '' ? text : t;
displayMessage("text:"+text);
return text;
};
MediaWikiFormatter.expandTemplate = function(w,templateText,params)
{
var text = templateText;
text = text.replace(/<noinclude>((?:.|\n)*?)<\/noinclude>/mg,'');// remove text between noinclude tags
var includeOnlyRegExp = /<includeonly>((?:.|\n)*?)<\/includeonly>/mg;
var t = '';
var match = includeOnlyRegExp.exec(text);
while(match) {
t += match[1];
match = includeOnlyRegExp.exec(text);
}
text = t == '' ? text : t;
var paramsRegExp = /\{\{\{(.*?)(?:\|(.*?))?\}\}\}/mg;
t = '';
var pi = 0;
match = paramsRegExp.exec(text);
while(match) {
var name = match[1];
var val = params[name];
if(!val) {
val = match[2];
}
if(!val) {
val = '';//val = match[0];
}
t += text.substring(pi,match.index) + val;
pi = paramsRegExp.lastIndex;
match = paramsRegExp.exec(text);
}
return t == '' ? text : t;
/* //displayMessage("ss:"+text.substring(pi));
t += text.substring(pi);
t = MediaWikiFormatter.evaluateTemplateParserFunctions(t);
//{{#if: {{{perihelion|}}} | <tr><th>[[Perihelion|Perihelion distance]]:</th><td>{{{perihelion}}}</td></tr>}}
//{{#if:{{{symbol|}}} | {{{symbol}}} | }}
text = t == '' ? text : t;
displayMessage("t2:"+text);
return text;
*/
};
MediaWikiFormatter.endOfParams = function(w,text)
{
var p = 0;
var i = text.indexOf('|');
if(i==-1) {return -1;}
var n = text.indexOf('\n');
if(n!=-1 && n<i) {return -1;}
var b = text.indexOf('[[');
if(b!=-1 && b<i) {return -1;}
b = text.indexOf('{{');
while(b!=-1 && b<i) {
p += b;
text = text.substr(b);
var c = text.indexOf('}}');
p += c;
text = text.substr(c);
i = text.indexOf('|');
if(i==-1) {return -1;}
n = text.indexOf('\n');
if(n!=-1 && n<i) {return -1;}
b = text.indexOf('{{');
i = -1;
}
return i;
};
MediaWikiFormatter.readToDelim = function(w)
//!!! this is a bit rubish, needs doing properly.
{
var dRegExp = /\|/mg;
var sRegExp = /\[\[/mg;
var tRegExp = /\]\]/mg;
dRegExp.lastIndex = w.startMatch;
var dMatch = dRegExp.exec(w.source);
sRegExp.lastIndex = w.startMatch;
var sMatch = sRegExp.exec(w.source);
tRegExp.lastIndex = w.startMatch;
var tMatch = tRegExp.exec(w.source);
if(!tMatch) {
return false;
}
while(sMatch && sMatch.index<tMatch.index) {
if(dMatch && dMatch.index<sMatch.index) {
w.nextMatch = dRegExp.lastIndex;
w.matchLength = dMatch.index - w.startMatch;
return true;
}
tRegExp.lastIndex = sRegExp.lastIndex;
tMatch = tRegExp.exec(w.source);
w.nextMatch = tRegExp.lastIndex;
dRegExp.lastIndex = w.nextMatch;
dMatch = dRegExp.exec(w.source);
sRegExp.lastIndex = w.nextMatch;
sMatch = sRegExp.exec(w.source);
tRegExp.lastIndex = w.nextMatch;
tMatch = tRegExp.exec(w.source);
}
if(dMatch && dMatch.index<tMatch.index) {
w.nextMatch = dRegExp.lastIndex;
w.matchLength = dMatch.index - w.startMatch;
return true;
}
if(tMatch) {
w.nextMatch = tRegExp.lastIndex;
w.matchLength = tMatch.index - w.startMatch;
return false;
}
w.nextMatch = tRegExp.lastIndex;
w.matchLength = -1;
return false;
};
MediaWikiFormatter.getParams = function(w)
{
var params = [];
var i = 1;
w.startMatch = w.nextMatch;
var read = MediaWikiFormatter.readToDelim(w);
if(w.matchLength!=-1) {
params[i] = w.source.substr(w.startMatch,w.matchLength);
}
while(read) {
i++;
w.startMatch = w.nextMatch;
read = MediaWikiFormatter.readToDelim(w);
if(w.matchLength!=-1) {
params[i] = w.source.substr(w.startMatch,w.matchLength);
}
}
return params;
};
MediaWikiFormatter.setFromParams = function(w,p)
{
var r = {};
var re = /\s*(.*?)=(?:(?:"(.*?)")|(?:'(.*?)')|((?:\w|%|#)*))/mg;
var match = re.exec(p);
while(match)
{
var s = match[1].unDash();
if(match[2]) {
r[s] = match[2];
} else if(match[3]) {
r[s] = match[3];
} else {
r[s] = match[4];
}
match = re.exec(p);
}
return r;
};
MediaWikiFormatter.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.mediawiki = {};
config.mediawiki.formatters = [
{
name: 'mediaWikiHeading',
match: '^={2,6}(?!=)\\n?',
termRegExp: /(={2,6}\n?)/mg,
handler: function(w)
{
var output = w.output;
var e = createTiddlyElement2(output,'h' + w.matchLength);
var a = createTiddlyElement2(e,'a');
var t = w.tiddler ? MediaWikiFormatter.normalizedTitle(w.tiddler.title) + ':' : '';
var len = w.source.substr(w.nextMatch).indexOf('=');
a.setAttribute('name',t+MediaWikiFormatter.normalizedTitle(w.source.substr(w.nextMatch,len)));
w.subWikifyTerm(e,this.termRegExp);
}
},
{
name: 'mediaWikiTable',
match: '^\\{\\|', // ^{|
tableTerm: '\\n\\|\\}', // |}
rowStart: '\\n\\|\\-', // \n|-
cellStart: '\\n!|!!|\\|\\||\\n\\|', //\n! or !! or || or \n|
caption: '\\n\\|\\+',
rowTerm: null,
cellTerm: null,
inCellTerm: null,
tt: 0,
debug: null,
rowTermRegExp: null,
handler: function(w)
{
if(!this.rowTermRegExp) {
this.rowTerm = '(' + this.tableTerm +')|(' + this.rowStart + ')';
this.cellTerm = this.rowTerm + '|(' + this.cellStart + ')';
this.inCellTerm = '(' + this.match + ')|' + this.rowTerm + '|(' + this.cellStart + ')';
this.caption = '(' + this.caption + ')|' + this.cellTerm;
this.rowTermRegExp = new RegExp(this.rowTerm,'mg');
this.cellTermRegExp = new RegExp(this.cellTerm,'mg');
this.inCellTermRegExp = new RegExp(this.inCellTerm,'mg');
this.captionRegExp = new RegExp(this.caption,'mg');
}
this.captionRegExp.lastIndex = w.nextMatch;
var match = this.captionRegExp.exec(w.source);
if(!match) {return;}
var output = w.output;
var table = createTiddlyElement2(output,'table');
var rowContainer = table;
var i = w.source.indexOf('\n',w.nextMatch);
if(i>w.nextMatch) {
MediaWikiFormatter.setAttributesFromParams(table,w.source.substring(w.nextMatch,i));
w.nextMatch = i;
}
var rowCount = 0;
var eot = false;
if(match[1]) {
var caption = createTiddlyElement2(table,'caption');
w.nextMatch = this.captionRegExp.lastIndex;
var captionText = w.source.substring(w.nextMatch);
var n = captionText.indexOf('\n');
captionText = captionText.substr(0,n);
i = MediaWikiFormatter.endOfParams(w,captionText);
if(i!=-1) {
captionText = w.source.substr(w.nextMatch,i);
w.nextMatch += i+1;
}
if(caption != table.firstChild) {
table.insertBefore(caption,table.firstChild);
}
w.subWikify(caption,this.cellTerm);
w.nextMatch -= w.matchLength;
this.cellTermRegExp.lastIndex = w.nextMatch;
var match2 = this.cellTermRegExp.exec(w.source);
if(match2) {
if(match2[3]) {
eot = this.rowHandler(w,createTiddlyElement2(rowContainer,'tr'));
rowCount++;
}
}
} else if(match[3]) {
w.nextMatch = this.captionRegExp.lastIndex-match[3].length;
} else if(match[4]) {
w.nextMatch = this.captionRegExp.lastIndex-match[4].length;
eot = this.rowHandler(w,createTiddlyElement2(rowContainer,'tr'));
rowCount++;
}
this.rowTermRegExp.lastIndex = w.nextMatch;
match = this.rowTermRegExp.exec(w.source);
while(match && eot==false) {
if(match[1]) {
w.nextMatch = this.rowTermRegExp.lastIndex;
if(w.tableDepth==0) {
return;
}
} else if(match[2]) {
var rowElement = createTiddlyElement2(rowContainer,'tr');
w.nextMatch += match[2].length;
i = w.source.indexOf('\n',w.nextMatch);
if(i>w.nextMatch) {
MediaWikiFormatter.setAttributesFromParams(rowElement,w.source.substring(w.nextMatch,i));
w.nextMatch = i;
}
eot = this.rowHandler(w,rowElement);
}
rowCount++;
this.rowTermRegExp.lastIndex = w.nextMatch;
match = this.rowTermRegExp.exec(w.source);
}//# end while
if(w.tableDepth==0) {
w.nextMatch +=3;
}
},//# end handler
rowHandler: function(w,e)
{
var cell;
this.inCellTermRegExp.lastIndex = w.nextMatch;
var match = this.inCellTermRegExp.exec(w.source);
while(match) {
if(match[1]) {
w.tableDepth++;
w.subWikify(cell,this.tableTerm);
w.nextMatch = this.tt;
w.tableDepth--;
return false;
} else if(match[2]) {
this.tt = this.inCellTermRegExp.lastIndex;
return true;
} else if(match[3]) {
return false;
} else if(match[4]) {
var len = match[4].length;
cell = createTiddlyElement2(e,match[4].substr(len-1)=='!'?'th':'td');
w.nextMatch += len;
this.inCellTermRegExp.lastIndex = w.nextMatch;
var lookahead = this.inCellTermRegExp.exec(w.source);
if(!lookahead) {
return false;
}
var cellText = w.source.substr(w.nextMatch,lookahead.index-w.nextMatch);
var oldSource = w.source;
var i = MediaWikiFormatter.endOfParams(w,cellText);//cellText.indexOf('|');
if(i!=-1) {
cellText = cellText.replace(/^\+/mg,''); //!!hack until I fix this properly
MediaWikiFormatter.setAttributesFromParams(cell,cellText.substr(0,i-1));
cellText = cellText.substring(i+1);
}
cellText = cellText.replace(/^\s*/mg,'');
w.source = cellText;
w.nextMatch = 0;
w.subWikifyUnterm(cell);
w.source = oldSource;
w.nextMatch = lookahead.index;
}
this.inCellTermRegExp.lastIndex = w.nextMatch;
match = this.inCellTermRegExp.exec(w.source);
}//# end while
return false;
}//# end rowHandler
},
{
name: 'mediaWikiList',
match: '^[\\*#;:]+',
lookaheadRegExp: /(?:(?:(\*)|(#)|(;)|(:))+)(?: ?)/mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var stack = [w.output];
var currLevel = 0, currType = null;
var listType, itemType;
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
if(lookaheadMatch[1]) {
listType = 'ul';
itemType = 'li';
} else if(lookaheadMatch[2]) {
listType = 'ol';
itemType = 'li';
} else if(lookaheadMatch[3]) {
listType = 'dl';
itemType = 'dt';
} else if(lookaheadMatch[4]) {
listType = 'dl';
itemType = 'dd';
}
var listLevel = lookaheadMatch[0].length;
w.nextMatch += listLevel;
if(listLevel > currLevel) {
for(var i=currLevel; i<listLevel; i++) {
stack.push(createTiddlyElement2(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(createTiddlyElement2(stack[stack.length-1],listType));
}
currLevel = listLevel;
currType = listType;
var e = createTiddlyElement2(stack[stack.length-1],itemType);
var ci = w.source.indexOf(':',w.nextMatch);
var ni = w.source.indexOf('\n',w.nextMatch);
if(itemType=='dt' && (ni==-1 || (ci!=-1 && ci<ni))) {
w.subWikifyTerm(e,/(:)/mg);
w.nextMatch--;
} else {
w.subWikifyTerm(e,this.termRegExp);
}
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'mediaWikiRule',
match: '^----+$\\n?',
handler: function(w)
{
createTiddlyElement2(w.output,'hr');
}
},
{
name: 'mediaWikiLeadingSpaces',
match: '^ ',
lookaheadRegExp: /^ /mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var e = createTiddlyElement2(w.output,'pre');
while(true) {
w.subWikifyTerm(e,this.termRegExp);
createTiddlyElement2(e,'br');
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
w.nextMatch += lookaheadMatch[0].length;
} else {
break;
}
}
}
},
{
name: 'mediaWikiImage',
match: '\\[\\[(?:[Ii]mage|Bild):',
lookaheadRegExp: /\[\[(?:[Ii]mage|Bild):/mg,
defaultPx: 180,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var params = MediaWikiFormatter.getParams(w);
var src = params[1];
src = src.trim().replace(/ /mg,'_');
src = src.substr(0,1).toUpperCase() + src.substring(1);
var palign = null;
var ptitle = null;
var psrc = false;
var px = null;
var pthumb = false;
var pframed = false;
for(var i=2;i<params.length;i++) {
var p = params[i];
if(p=='right'||p=='left'||p=='center'||p=='none') {
palign = p;
} else if(p=='thumbnail'||p=='thumb') {
pthumb = true;
} else if(p=='framed') {
pframed = true;
} else if(/\d{1,4} ?px/.exec(p)) {
px = p.substr(0,p.length-2).trim();
} else {
ptitle = p;
}
}//#end for
if(pthumb) {
var output = w.output;
if(!palign) {
palign = 'right';
}
if(!px) {
px = 180;
}
psrc = px + 'px-' + src;
var t = createTiddlyElement(output,'div',null,'thumb'+(palign?' t'+palign:''));
var s = createTiddlyElement2(t,'div');
s.style['width'] = Number(px) + 2 + 'px';
var a = createTiddlyElement(s,'a',null,'internal');
if(config.options.chkMediaWikiDisplayEnableThumbZoom) {
a.href = src;
}
a.title = ptitle;
var img = createTiddlyElement2(a,'img');
img.src = 'images/' + psrc;
img.width = px;
img.longdesc = 'Image:' + src;
img.alt = ptitle;
var tc = createTiddlyElement(s,'div',null,'thumbcaption');
var oldSource = w.source; var oldMatch = w.nextMatch;
w.source = ptitle; w.nextMatch = 0;
w.subWikifyUnterm(tc);
w.source = oldSource; w.nextMatch = oldMatch;
if(config.options.chkMediaWikiDisplayEnableThumbZoom) {
var tm = createTiddlyElement(tc,'div',null,'magnify');
tm.style['float'] = 'right';
var ta = createTiddlyElement(tm,'a',null,'internal');
ta.title = 'Enlarge';
timg = createTiddlyElement2(ta,'img'); timg.src = 'magnify-clip.png'; timg.alt = 'Enlarge'; timg.width = '15'; timg.height = '11';
ta.href = src;
}
} else {
a = createTiddlyElement(w.output,'a',null,'image');
a.title = ptitle;
img = createTiddlyElement2(a,'img');
if(palign) {img.align = palign;}
img.src = px ? 'images/' + px + 'px-' + src : 'images/' + src;
if(px) {img.width = px;}
img.longdesc = 'Image:' + src;
img.alt = ptitle;
}
}
}//#end image handler
},
{
name: 'mediaWikiExplicitLink',
match: '\\[\\[',
lookaheadRegExp: /\[\[(?:([a-z]{2,3}:)?)(#?)([^\|\]]*?)(?:(\]\](\w*))|(\|(.*?)\]\]))/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
if(!lookaheadMatch[1]) {
var e;
var link = lookaheadMatch[3];
var text = link;
link = link.substr(0,1).toUpperCase() + link.substring(1);
if(lookaheadMatch[4]) {
if(lookaheadMatch[2]) {
var a = createTiddlyElement(w.output,'a');
var t = w.tiddler ? MediaWikiFormatter.normalizedTitle(w.tiddler.title) + ':' : '';
t = '#' + t + MediaWikiFormatter.normalizedTitle(link);
a.setAttribute('href',t);
a.title = '#' + MediaWikiFormatter.normalizedTitle(link);
createTiddlyText(a,'#'+link);
} else {
e = createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
if(lookaheadMatch[5]) {
text += lookaheadMatch[5];
}
createTiddlyText(e,text);
}
} else if(lookaheadMatch[6]) {
if(config.formatterHelpers.isExternalLink(link)) {
e = createExternalLink(w.output,link);
} else {
e = createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
}
var oldSource = w.source; var oldMatch = w.nextMatch;
w.source = lookaheadMatch[7].trim(); w.nextMatch = 0;
w.subWikifyUnterm(e);
w.source = oldSource; w.nextMatch = oldMatch;
}
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'mediaWikiTemplate',
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) {
var lastIndex = this.lookaheadRegExp.lastIndex;
var contents = lookaheadMatch[1];
if(MediaWikiFormatter.expandVariable(w,contents)) {
return;
}
var i = contents.indexOf('|');
var title = i==-1 ? contents : contents.substr(0,i);
title = title.trim().replace(/_/mg,' ');
title = 'Template:' + title.substr(0,1).toUpperCase() + title.substring(1);
var tiddler = store.fetchTiddler(title);
var oldSource = w.source;
if(tiddler) {
params = {};
if(i!=-1) {
params = MediaWikiFormatter.getTemplateParams(lookaheadMatch[1]);
}
w.source = MediaWikiFormatter.expandTemplate(w,tiddler.text,params);
w.nextMatch = 0;
w.subWikifyUnterm(w.output);
} else {
if(config.options.chkMediaWikiDisplayEmptyTemplateLinks) {
w.source = '[['+title+']]';
w.nextMatch = 0;
w.subWikifyUnterm(w.output);
}
}
w.source = oldSource;
w.nextMatch = lastIndex;
}
}
},
{
name: 'mediaWikiParagraph',
match: '\\n{2,}',
handler: function(w)
{
w.output = createTiddlyElement2(w.output,'p');
}
},
{
name: 'mediaWikiExplicitLineBreak',
match: '<br ?/?>',
handler: function(w)
{
createTiddlyElement2(w.output,'br');
}
},
{
name: 'mediaWikiExplicitLineBreakWithParams',
match: "<br(?:\\s*(?:(?:.*?)=[\"']?(?:.*?)[\"']?))*?\\s*/?>",
lookaheadRegExp: /<br((?:\s+(?:.*?)=["']?(?:.*?)["']?)*?)?\s*\/?>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e =createTiddlyElement2(w.output,'br');
if(lookaheadMatch[1]) {
MediaWikiFormatter.setAttributesFromParams(e,lookaheadMatch[1]);
}
w.nextMatch = this.lookaheadRegExp.lastIndex;// empty tag
}
}
},
{
name: 'mediaWikiTitledUrlLink',
match: '\\[' + config.textPrimitives.urlPattern + '(?:\\s+[^\\]]+)?' + '\\]',
handler: function(w)
{
var lookaheadRegExp = new RegExp('\\[(' + config.textPrimitives.urlPattern + ')(?:\\s+([^\[]+))?' + '\\]','mg');
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index==w.matchStart) {
var link = lookaheadMatch[1];
var s = createTiddlyElement2(w.output,'sup');
var e = createExternalLink(s,link);
if(lookaheadMatch[2]) {
var oldSource = w.source; var oldMatch = w.nextMatch;
w.source = lookaheadMatch[2].trim(); w.nextMatch = 0;
w.subWikifyUnterm(e);
w.source = oldSource; w.nextMatch = oldMatch;
} else {
w.linkCount++;
createTiddlyText(e,'['+w.linkCount+']');
}
w.nextMatch = lookaheadRegExp.lastIndex;
}
}
},
{
name: 'mediaWikiUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'mediaWikiBoldItalic',
match: "'''''",
termRegExp: /('''''|(?=\n))/mg,
element: 'strong',
handler: function(w)
{
var e = createTiddlyElement(w.output,this.element);
w.subWikifyTerm(createTiddlyElement(e,'em'),this.termRegExp);
}
},
{
name: 'mediaWikiBold',
match: "'''",
termRegExp: /('''|(?=\n))/mg,
element: 'strong',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiItalic',
match: "''",
termRegExp: /((?:''(?!'))|(?=\n))/mg,
element: 'em',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiUnderline',
match: '<u>',
termRegExp: /(<\/u>|(?=\n))/mg,
element: 'u',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiStrike',
match: '<s>',
termRegExp: /(<\/s>|(?=\n))/mg,
element: 'strike',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiBoldTag',
match: '<b>',
termRegExp: /(<\/b>|(?=\n))/mg,
element: 'b',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiItalicTag',
match: '<i>',
termRegExp: /(<\/i>|(?=\n))/mg,
element: 'i',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'mediaWikiTemplateParam',
match: '\\{\\{\\{',
lookaheadRegExp: /(\{\{\{(?:.|\n)*?\}\}\})/mg,
element: 'span',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'mediaWikiInsertReference',
match: '<ref[^/]*>',
lookaheadRegExp: /<ref(\s+(?:.*?)=["']?(?:.*?)["']?)?>([^<]*?)<\/ref>/mg,
handler: function(w)
{
if(config.browser.isIE) {
refRegExp = /<ref[^\/]*>((?:.|\n)*?)<\/ref>/mg;
refRegExp.lastIndex = w.matchStart;
var refMatch = refRegExp.exec(w.source);
if(refMatch && refMatch.index == w.matchStart) {
w.nextMatch = refRegExp.lastIndex;
return;
}
}
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var x = {id:'',value:''};
w.nextMatch = this.lookaheadRegExp.lastIndex;
if(!w.referenceCount) {
w.referenceCount = 0;
w.references = {};
}
var s = createTiddlyElement(w.output,'sup',null,'reference');
var a = createTiddlyElement2(s,'a');
var prefix = w.tiddler ? w.tiddler.title + ':' : '';
var name;
if(lookaheadMatch[1]) {
var r = MediaWikiFormatter.setFromParams(w,lookaheadMatch[1]);
name = r.name ? r.name.trim() : '';
name = name.replace(/ /g,'_');
s.id = prefix + '_ref-' + name;// + '_' + nameCount;(w.referenceCount+1);
if(!w.references[name]) {
w.references[name] = x;
w.references[name].id = w.referenceCount;
w.references[name].value = lookaheadMatch[2].trim();
}
} else {
w.references[w.referenceCount] = x;
w.references[w.referenceCount].id = w.referenceCount;
w.references[w.referenceCount].value = lookaheadMatch[2].trim();
name = w.referenceCount;
s.id = prefix + '_ref-' + w.referenceCount;
}
w.referenceCount++;
a.title = lookaheadMatch[2].trim();//mb, extra to wikipedia
a.href = '#' + prefix + '_note-' + name;
a.innerHTML = '['+w.referenceCount+']';
}
}
},
{
name: 'mediaWikiListReferences',
match: '<references ?/>',
lookaheadRegExp: /<references ?\/>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(config.options.chkMediaWikiListReferences && w.referenceCount) {
var ol = createTiddlyElement(w.output,'ol',null,'references');
var oldSource = w.source;
if(w.referenceCount>0) {
for(var i in w.references) {
var li = createTiddlyElement2(ol,'li');
var prefix = w.tiddler ? w.tiddler.title + ':' : '';
var b = createTiddlyElement2(li,'b');
var a = createTiddlyElement2(b,'a');
li.id = prefix + '_note-' + i;
a.href = '#' + prefix + '_ref-' + i;
a.innerHTML = '^';
w.source = w.references[i].value;
w.nextMatch = 0;
w.subWikifyUnterm(li);
}
}
w.source = oldSource;
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
},
{
name: 'mediaWikiRepeatReference',
match: '<ref[^/]*/>',
lookaheadRegExp: /<ref(\s+(?:.*?)=["'](?:.*?)["'])?\s*\/>/mg,
handler: function(w)
{
if(config.browser.isIE) {
refRegExp = /<ref.*?\/>/mg;
refRegExp.lastIndex = w.matchStart;
var refMatch = refRegExp.exec(w.source);
if(refMatch && refMatch.index == w.matchStart) {
w.nextMatch = refRegExp.lastIndex;
return;
}
}
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var x = {id:'',value:''};
w.nextMatch = this.lookaheadRegExp.lastIndex;
var s = createTiddlyElement(w.output,"sup",null,"reference");
var a = createTiddlyElement2(s,"a");
var prefix = w.tiddler ? w.tiddler.title : '';
if(lookaheadMatch[1]) {
var r = {};
r = MediaWikiFormatter.setFromParams(w,lookaheadMatch[1]);
var name = r.name ? r.name.trim() : '';
name = name.replace(/ /g,'_');
s.id = prefix + '_ref-' + name +'_' + (w.referenceCount+1);
var count = w.references && w.references[name] ? (w.references[name].id+1) : '?';
}
a.href = '#' + prefix + '_note-' + name;
a.innerHTML = '['+count+']';
a.title = name;
}
}//# end handler
},
{
name: 'mediaWikiHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
if(!config.browser.isIE)
createTiddlyElement(w.output,"span").innerHTML = w.matchText;
}
},
{
name: 'mediaWikiComment',
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: 'mediaWikiIncludeOnly',
match: '<includeonly>',
lookaheadRegExp: /<includeonly>((?:.|\n)*?)<\/includeonly>/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: 'mediaWikiNoWiki',
match: '<nowiki>',
lookaheadRegExp: /<nowiki>((?:.|\n)*?)<\/nowiki>/mg,
element: 'span',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'mediaWikiPreNoWiki',
match: '<pre>\s*<nowiki>',
lookaheadRegExp: /<pre>\s*<nowiki>((?:.|\n)*?)<\/nowiki>\s*<\/pre>/mg,
element: 'pre',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'mediaWikiPre',
match: '<pre>',
lookaheadRegExp: /<pre>((?:.|\n)*?)<\/pre>/mg,
element: 'pre',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'mediaWikiMagicWords',
match: '__',
lookaheadRegExp: /__([A-Z]*?)__/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
if(lookaheadMatch[1]=='NOTOC') {
} else if(config.options.chkDisplayMediaWikiMagicWords) {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'mediaWikiGallery',
match: '<gallery>',
lookaheadRegExp: /[Ii]mage:(.*?)\n/mg,
handler: function(w)
{
var table = createTiddlyElement(w.output,'table',null,'gallery');
table.cellspacing = '0';
table.cellpadding = '0';
var rowElem = createTiddlyElement2(table,'tr');
var col = 0;
this.lookaheadRegExp.lastIndex = w.matchStart;
var nM = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
var oldSource = w.source;
while(lookaheadMatch) {
nM += lookaheadMatch[1].length;
w.source = lookaheadMatch[1] +']]';//!! ]] is hack until getParams is working
w.nextMatch = 0;
var params = MediaWikiFormatter.getParams(w);
var src = params[1];
src = src.trim().replace(/ /mg,'_');
src = src.substr(0,1).toUpperCase() + src.substring(1);
var palign = 'right';
var psrc = '120px-'+src;
var px = 120;
var pframed = false;
ptitle = null;
for(var i=2;i<params.length;i++) {
var p = params[i];
if(p=='right'||p=='left'||p=='center'||p=='none') {
palign = p;
} else if(p=='framed') {
pframed = true;
} else if(/\d{1,4}px/.exec(p)) {
px = p.substr(0,p.length-2).trim();
psrc = px + 'px-' + src;
} else {
ptitle = p;
}
}//#end for
var td = createTiddlyElement2(rowElem,'td');
var gb = createTiddlyElement(td,'div',null,'gallerybox');
var t = createTiddlyElement(gb,'div',null,'thumb');
t.style['padding'] = '26px 0';
var a = createTiddlyElement2(t,'a');
if(config.options.chkMediaWikiDisplayEnableThumbZoom) {
a.href = src;
}
a.title = ptitle;
var img = createTiddlyElement2(a,'img');
img.src = psrc;
img.width = px;
img.alt = '';
var gt = createTiddlyElement(gb,'div',null,'gallerytext');
p = createTiddlyElement2(gt,'p');
var oldSource2 = w.source; var oldMatch = w.nextMatch;
w.source = ptitle; w.nextMatch = 0;
w.subWikifyUnterm(p);
w.source = oldSource2; w.nextMatch = oldMatch;
col++;
if(col>3) {
rowElem = createTiddlyElement2(table,'tr');
col = 0;
}
w.source = oldSource;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
w.nextMatch = nM + '<gallery>'.length*2+1+'Image:'.length;//!! hack
}
},
{
name: 'mediaWikiHtmlTag',
match: "<[a-zA-Z]{2,}(?:\\s*(?:(?:.*?)=[\"']?(?:.*?)[\"']?))*?>",
lookaheadRegExp: /<([a-zA-Z]{2,})((?:\s+(?:.*?)=["']?(?:.*?)["']?)*?)?\s*(\/)?>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e =createTiddlyElement2(w.output,lookaheadMatch[1]);
if(lookaheadMatch[2]) {
MediaWikiFormatter.setAttributesFromParams(e,lookaheadMatch[2]);
}
if(lookaheadMatch[3]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.subWikify(e,'</'+lookaheadMatch[1]+'>');
}
}
}
}
];
config.parsers.mediaWikiFormatter = new Formatter(config.mediawiki.formatters);
config.parsers.mediaWikiFormatter.format = 'mediawiki';
config.parsers.mediaWikiFormatter.formatTag = 'MediaWikiFormat';
} //# end of 'install only once'
//}}}
This walk-through shows you how to connect to Wikipedia and choose some articles to download.
# If necessary, DownloadSoftware and open it in your browser
# If the black backstage are isn't visible along the top of the screen, click on the 'backstage' button at the top right
# Choose 'import' from the backstage area
# In the task wizard that drops down, choose one of these predefined servers from the lower list:
## WikipediaIPstackServer - selects Wikipedia entries about wiki technology
## WikipediaImpressionistPaintersServer - selects Wikipedia entries about impression painters
## WikipediaWikiServer - selects Wikipedia entries about the Internet's IP stack technology
# Click the 'open' button
# When prompted for the workspace, leave the default of 'Main' and click the 'open' button
# After a pause, you should then see a list of the available tiddlers. Select the checkboxes by two or three and then click the 'import' button
# The tiddlers you have selected will be listed, first as italicised links to missing tiddlers, and then as bold links as the tiddlers are loaded in the background. Click on the links to open the tiddlers you selected
# Click on the grey bars to either side of the backstage drop-down to close it
# You should now be able to browse the Wikipedia articles that you imported
# If you click on a link to an article that has not been downloaded, it will be automatically retrieved from Wikipedia
|''URL:''|http://mptw.tiddlyspot.com/|
|''Description:''|a tiddlywiki distribution and plugins|
|''Author:''|SimonBaird|
TiddlyWiki has been improved in several other areas for release 2.2. Here are some of the highlights; see the full [[release note at tiddlywiki.org|http://trac.tiddlywiki.org/tiddlywiki/wiki/ReleaseNoteTwoPointTwo]] for more details.
!!! Usability
There's a slew of significant usability enhancements including:
* Popup previews of tiddler contents in the plugin manager, sync manager, and ImportTiddlers
* 'More' command to simplify tiddler toolbars
* "Yellow note" annotations to indicate the purpose of special tiddlers such as shadow tiddlers
* New {{{<<options>>}}} macro to allow access to the complete set of available configuration options
* New "size" and "execution time" columns in the plugin manager
* Improved NewTiddler and NewJournal macros that can accept custom fields
* Embolden tags in the tag listing that are also defined as tiddlers
!!! Performance
* New DomScrubbing feature to deal with memory leaks
* Revised storage format using {{{<PRE>}}} tags to permit whitespace and new lines to be preserved without requiring escaping
* Greatly enhanced animation engine that performs better on slower hardware
!!! Hackability
As usual, several of the new features are intended to make life easier for plugin writers and other TiddlyWiki hackers:
* New PluginLoadOrder mechanism for controlling the execution order of plugins
* Better startup timing instrumentation
* Rearranged shadow tiddlers into their own, unencoded store area
* Refactored {{{saveChanges()}}} to make it easier to add new save mechanisms
* Added paramifier for overriding current read-only state (eg, http://www.tiddlywiki.com/beta/#readOnly:no)
* ...and by popular request, we've started to reformat the TiddlyWiki source code to use the more conventional K&R layout standard
!!! Internationalisation
TiddlyWiki benefits from an extensive set of [[translations|http://trac.tiddlywiki.org/wiki/Translations]]. There are several enhancements in this release to make it easier to maintain translations.
|''URL:''|http://bradleymeck.tiddlyspot.com/|
|''Description:''|Resources that are Ripe for the Picking|
|''Author:''|BradleyMeck|
|''URL:''|http://solo.dc3.com/tw/|
|''Description:''|Bob Denny's extensions to TiddlyWiki|
|''Author:''|BobDenny|
With the ServerAdaptorMechanism, TiddlyWiki adopts a simple model for interacting with servers:
* //Server adaptors// are plugins that provide a standardised interface to a particular server architecture. As standard, TiddlyWiki provides the FileAdaptor for talking to static TiddlyWiki files but others are available for talking to popular wiki servers
* A //host// string identifies a particular server, usually by it's URL
* A //workspace// string identifies a particular compartment or storage area within a server, for instance the name of a wiki on a shared MediaWiki server
* A //title// identifies a tiddler within a particular workspace
Via the ServerAdaptorExtendedFields, particular tiddlers can have a connection to a particular server.
The ServerAdaptorMechanism uses ExtendedFields to store additional data with tiddlers that are associated with a server host. The standard fields are listed below, but particular adaptors will often add their own custom fields for their own purposes.
|!Field |!Description |!Status |!Example |
|server.type |The type of server adaptor associated with this tiddler |mandatory |eg "file", "socialtext" |
|server.host |The host server URL |mandatory |eg "http://www.socialtext.net/" |
|server.workspace |The workspace associated with this tiddler |optional |eg "stoss" |
|server.page.name |The full (human readable) name of the tiddler's page on the server |optional |eg "Socialtext Open Source Wiki" |
|server.page.id |The normalized form of the tiddler's page name on the server |optional |eg "socialtext_open_source_wiki" |
|server.page.revision |The revision of the page. Host dependent, but normally a number. Guaranteed to lexigraphically sort into chronological order |optional |eg "20070222050650" |
|wikiformat |The wikiformat of the tiddler |optional |eg "socialtext" |
See ServerAdaptorConcepts for the meanings of terms like host, workspace and adaptor.
TiddlyWiki's architecture for interacting with servers allows it to be plugged into a wide variety of servers. This is done through the addition of plugins containing custom server adaptors. Server adaptors are designed to allow for UseCases like importing tiddlers, loading missing tiddlers on the fly and synchronising changes with a server. Separate macros and core extensions implement such features by accessing the facilities provided by server adaptors.
Server adaptors are designed to use a familiar model akin to a device driver, adapting a standardised interface to whatever is required by the underlying server: [[WebDAV|http://en.wikipedia.org/wiki/Webdav]], ZiddlyWiki, [[MediaWiki|http://en.wikipedia.org/wiki/MediaWiki]], [[Socialtext|http://www.socialtext.com/]] or HTML scraping.
Many server architectures are [[REST|http://en.wikipedia.org/wiki/REST]] based, and TiddlyWiki server adaptors are particularly easy to create for common REST patterns. It is also possible to create TiddlyWiki server adaptors for severs with an [[XML-RPC|http://en.wikipedia.org/wiki/XML-RPC]] interface.
Server adaptors are registered by name in the global object {{{config.adaptors}}}. Each entry is a reference to an object constructor for that type of server adaptor. The adaptor object must implement the following methods:
* [[Adaptor.openHost]]
* [[Adaptor.openWorkspace]]
* [[Adaptor.getTiddler]]
* [[Adaptor.close]]
Additionally the adaptor may implement the following methods:
* [[Adaptor.getWorkspaceList]] (required to support the Import Tiddlers UseCase)
* [[Adaptor.getTiddlerList]] (required to support the Import Tiddlers UseCase)
* [[Adaptor.putTiddler]] (required to support the Sync UseCase)
* [[Adaptor.getTiddlerRevision]]
* [[Adaptor.getTiddlerRevisionList]]
The adaptor object is used through the life of a connection to a server; see ServerAdaptorConcepts for details. Many of the methods use an AsynchronousPattern of callbacks to deliver their results.
Custom formatters for the WikifierFormatterMechanism are often used alongside server adaptors to allow TiddlyWiki to display content in the native format of a server.
The new ServerAdaptorMechanism brings multiple pluggable server adaptors to TiddlyWiki. It ships with a simple adaptor that knows how to talk to other TiddlyWiki files, and we also have available plugins for several popular server architectures including [[Socialtext]], MediaWiki, [[JSPWiki]], [[TWiki]], [[ccTiddly]] and ZiddlyWiki.
Using these adaptors you can import content from any source and then later synchronise changes back to the server. You can also automatically retrieve missing tiddlers from a server. By combining a server adaptor with an appropriate custom wikifier, TiddlyWiki can display content in it's native format. So, for instance, you can import articles from Wikipedia and have them display properly despite using a different wiki syntax than plain TiddlyWiki.
This new functionality is deep and rich and will serve as the foundation for a new wave of applications that use TiddlyWiki as a personal content hub. One particular goal is to harmonise the client code for the various ServerSide versions of TiddlyWiki. Another important feature that is coming soon is to allow automated, non-interactive importing, exporting and synchronisation.
To try out the new functionality, first DownloadSoftware and then take a look at these walk-throughs:
* MediaWikiWalkthrough
* SocialtextWalkthrough
/***
|''Name:''|SharedRecordsAdaptorPlugin|
|''Description:''|Adaptor for Shared Record Server (http://www.sharedrecords.org/)|
|''Author:''|Jeremy Ruston (jeremy (at) osmosoft (dot) com)|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/verticals/sharedrecords/plugins/SharedRecordsAdaptorPlugin.js|
|''Version:''|0.2.1|
|''Date:''|Apr 15, 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|
***/
//{{{
if(!version.extensions.SharedRecordsAdaptorPlugin) {
version.extensions.SharedRecordsAdaptorPlugin = {installed:true};
function SharedRecordsAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
merge(SharedRecordsAdaptor,{
serverType: 'sharedrecords',
getTiddlersUrl: '%0%1_log.json',
viewTiddlersUrl: '%0%1.data',
putTiddlersUrl: '%0%1_log?max-sequence-number=%2&format=json',
notLoadedError: "SharedRecords data has not been loaded",
notFoundError: "SharedRecords tiddler not found",
jsonTag: '%0',
jsonTagSep: ',',
jsonEntry: '{"title":%0,"modified":"%1","modifier":%2,"created":"%3",\n"tags":[%4],"text":%5,\n"sharedRecords.recordUID":%6,"contentType":%7,"sharedRecords.sequenceNumber":%8}\n',
jsonWrapper: '{"tiddlers":[%0]}'
});
SharedRecordsAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
// Static method to create a Date() from a string in the format yyyy-MM-ddTHH:mm:ss.SSSz where z is the locale
SharedRecordsAdaptor.convertFromFullUTCISO1806 = function(dateString)
{
var theDate = new Date(Date.UTC(parseInt(dateString.substr(0,4),10),
parseInt(dateString.substr(5,2),10)-1,
parseInt(dateString.substr(8,2),10),
parseInt(dateString.substr(11,2),10),
parseInt(dateString.substr(14,2),10),
parseInt(dateString.substr(17,2), 10)));
return(theDate);
};
// Static method to convert string in ISO date format to a Date() object
SharedRecordsAdaptor.convertToFullUTCISO1806 = function(d)
{
return d.formatString("YYYY-0MM-0DDT0hh:0mm:0ss.000UTC");
};
SharedRecordsAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = host;
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
SharedRecordsAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.workspaces = [];
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
SharedRecordsAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.workspace = workspace;
var url = SharedRecordsAdaptor.getTiddlersUrl.format([this.host,this.workspace]);
var ret = loadRemoteFile(url,SharedRecordsAdaptor.openWorkspaceCallback,context);
return typeof(ret) == "string" ? ret : true;
};
SharedRecordsAdaptor.openWorkspaceCallback = function(status,context,responseText,url,xhr)
{
var adaptor = context.adaptor;
context.status = status;
if(!status) {
context.statusText = "Error reading file: " + xhr.statusText;
} else {
adaptor.serverData = eval("(" + responseText + ")");
}
context.callback(context,context.userParams);
};
SharedRecordsAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(!this.serverData)
return SharedRecordsAdaptor.notLoadedError;
context.tiddlers = [];
for(var t=0; t<this.serverData.tiddlers.length; t++) {
var serverTiddler = this.serverData.tiddlers[t];
var tiddler = new Tiddler(serverTiddler.title);
tiddler.text = serverTiddler.text;
tiddler.modified = SharedRecordsAdaptor.convertFromFullUTCISO1806(serverTiddler.modified);
tiddler.modifier = serverTiddler.modifier;
tiddler.fields['server.page.revision'] = String.zeroPad(10,serverTiddler['sharedRecords.sequenceNumber']);
tiddler.tags = serverTiddler.tags;
context.tiddlers.push(tiddler);
}
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
SharedRecordsAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : tiddler.fields['server.host'];
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
info.uri = SharedRecordsAdaptor.viewTiddlersUrl.format([host,workspace,tiddler.title]);
return info;
};
SharedRecordsAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(!this.serverData)
return SharedRecordsAdaptor.notLoadedError;
var t = this.serverData.tiddlers.findByField('title',title);
if(t != -1) {
var serverTiddler = this.serverData.tiddlers[t];
context.tiddler = new Tiddler(title);
context.tiddler.text = serverTiddler.text;
context.tiddler.modified = SharedRecordsAdaptor.convertFromFullUTCISO1806(serverTiddler.modified);
context.tiddler.modifier = serverTiddler.modifier;
context.tiddler.tags = serverTiddler.tags;
context.tiddler.fields['server.type'] = SharedRecordsAdaptor.serverType;
context.tiddler.fields['server.host'] = this.host;
context.tiddler.fields['server.workspace'] = this.workspace;
context.tiddler.fields['server.page.revision'] = String.zeroPad(10,serverTiddler['sharedRecords.sequenceNumber']);
context.tiddler.fields['content.type'] = serverTiddler.contentType;
context.status = true;
} else {
context.status = false;
context.statusText = SharedRecordsAdaptor.notFoundError;
}
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
SharedRecordsAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var jsonTags = [];
for(var tag=0; tag<tiddler.tags.length; tag++)
jsonTags.push(SharedRecordsAdaptor.jsonTag.format([tiddler.tags[tag].toJSONString()]));
var sequenceNumber = tiddler.fields['server.page.revision'];
sequenceNumber = sequenceNumber === undefined ? -1 : parseInt(sequenceNumber,10);
sequenceNumber = -1; // Just for the moment
var contentType = tiddler.fields['content.type'];
if(contentType === undefined)
contentType = 'text/html';
var jsonTiddler = SharedRecordsAdaptor.jsonEntry.format([
tiddler.title.toJSONString(),
SharedRecordsAdaptor.convertToFullUTCISO1806(tiddler.modified),
tiddler.modifier.toJSONString(),
SharedRecordsAdaptor.convertToFullUTCISO1806(tiddler.created),
jsonTags.join(SharedRecordsAdaptor.jsonTagSep),
tiddler.text.toJSONString(),
this.workspace.toJSONString(),
contentType.toJSONString(),
sequenceNumber
]);
var jsonRecord = SharedRecordsAdaptor.jsonWrapper.format([jsonTiddler]);
var url = SharedRecordsAdaptor.putTiddlersUrl.format([this.host,this.workspace,sequenceNumber]);
var r = doHttp("POST",
url,
jsonRecord,
null,null,null,
SharedRecordsAdaptor.putTiddlerCallback,context);
return typeof r == 'string' ? r : true;
};
SharedRecordsAdaptor.putTiddlerCallback = function(status,context,responseText,url,xhr)
{
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText + " (" + xhr.status + ")";
}
if(context.callback)
context.callback(context,context.userParams);
};
SharedRecordsAdaptor.prototype.close = function() {return true;};
config.adaptors[SharedRecordsAdaptor.serverType] = SharedRecordsAdaptor;
} //# end of 'install only once'
//}}}
|''Type:''|sharedrecords|
|''URL:''|http://sra.sharedrecords.org:8080/SRCDataStore/RESTServlet/|
|''Workspace:''|37105c154dd4956cc4e278a5b867a435b5250d19|
|''Description:''|SharedRecord's test server|
a reusable non-linear personal web notebook
http://www.tiddlywiki.com/beta/
/***
|''Name:''|SocialtextAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from Socialtext Wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com) and JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 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|
Socialtext REST documentation is at:
http://www.eu.socialtext.net/st-rest-docs/index.cgi?socialtext_rest_documentation
***/
//{{{
if(!version.extensions.SocialtextAdaptorPlugin) {
version.extensions.SocialtextAdaptorPlugin = {installed:true};
function SocialtextAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
SocialtextAdaptor.mimeType = 'text/x.socialtext-wiki';
SocialtextAdaptor.serverType = 'socialtext';
SocialtextAdaptor.serverParsingErrorMessage = "Error parsing result from server";
SocialtextAdaptor.errorInFunctionMessage = "Error in function SocialtextAdaptor.%0";
SocialtextAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
SocialtextAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(-1) != '/')
host = host + '/';
return host;
};
SocialtextAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
// Convert a page title to the normalized form used in uris
SocialtextAdaptor.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 Socialtext date in YYYY-MM-DD hh:mm format into a JavaScript Date object
SocialtextAdaptor.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)));
};
SocialtextAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = SocialtextAdaptor.fullHostName(host);
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
SocialtextAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.workspace = workspace;
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
SocialtextAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces';
var uri = uriTemplate.format([this.host]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getWorkspaceListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var item = {
title:info[i].title,
name:info[i].name,
modified:SocialtextAdaptor.dateFromEditTime(info[i].modified_time)
};
list.push(item);
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages?order=newest';//!! ? or ;
var uri = uriTemplate.format([this.host,this.workspace]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = String(info[i].revision_id);
list.push(tiddler);
}
context.tiddlers = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
uriTemplate = '%0%1/index.cgi?%2';
info.uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(tiddler.title)]);
return info;
};
SocialtextAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
return this.getTiddlerRevision(title,null,context,userParams,callback);
};
SocialtextAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// request the page in json format to get the page attributes
if(revision) {
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions/%3';
context.revision = revision;
} else {
uriTemplate = '%0data/workspaces/%1/pages/%2';
context.revision = null;
}
uri = uriTemplate.format([this.host,this.workspace,SocialtextAdaptor.normalizedTitle(title),revision]);
context.tiddler = new Tiddler(title);
context.tiddler.fields.wikiformat = 'socialtext';
context.tiddler.fields['server.host'] = SocialtextAdaptor.minHostName(this.host);
context.tiddler.fields['server.workspace'] = this.workspace;
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
if(status) {
try {
eval('var info=' + responseText);
context.tiddler.tags = info.tags;
context.tiddler.fields['server.page.id'] = info.page_id;
context.tiddler.fields['server.page.name'] = info.name;
context.tiddler.fields['server.page.revision'] = String(info.revision_id);
context.tiddler.modifier = info.last_editor;
context.tiddler.modified = SocialtextAdaptor.dateFromEditTime(info.last_edit_time);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.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;
}
var uriTemplate = context.revision ? '%0data/workspaces/%1/pages/%2/revisions/%3' : '%0data/workspaces/%1/pages/%2';
var host = SocialtextAdaptor.fullHostName(context.tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : context.tiddler.fields['server.workspace'];
uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(context.tiddler.title),context.revision]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback2,context,{'accept':SocialtextAdaptor.mimeType});
};
SocialtextAdaptor.getTiddlerCallback2 = function(status,context,responseText,uri,xhr)
{
context.tiddler.text = responseText;
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions?accept=application/json';
if(!limit)
limit = 5;
var uri = uriTemplate.format([this.host,this.workspace,SocialtextAdaptor.normalizedTitle(title),limit]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerRevisionListCallback,context);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = info[i].revision_id;
list.push(tiddler);
}
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);
};
SocialtextAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages/%2';
var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
//var req = doHttp('POST',uri,tiddler.text,SocialtextAdaptor.mimeType,null,null,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"});
var req = SocialtextAdaptor.doHttpPOST(uri,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,SocialtextAdaptor.mimeType);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.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);
};
SocialtextAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[SocialtextAdaptor.serverType] = SocialtextAdaptor;
} //# end of 'install only once'
//}}}
|''Type:''|socialtext|
|''URL:''|http://www.socialtext.net/|
|''Workspace:''|TiddlySandbox|
|''WorkspaceList:''|stoss [[Socialtext REST Documentation]] TiddlySandbox|
|''Description:''|Socialtext's public server|
/***
|''Name:''|SocialtextFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[Socialtext|http://www.socialtext.com/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/SocialtextFormatterPlugin.js|
|''Version:''|0.9.4|
|''Date:''|Jan 21, 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 the SocialtextFormatterPlugin, which allows you to insert Socialtext formated text into a TiddlyWiki.
The aim is not to fully emulate Socialtext, but to allow you to work with Socialtext content off-line and then resync the content with your Socialtext wiki later on, with the expectation that only minor edits will be required.
To use Socialtext format in a Tiddler, tag the Tiddler with SocialtextFormat or set the tiddler's {{{wikiformat}}} extended field to {{{socialtext}}}
Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
***/
//{{{
// Ensure that the SocialtextFormatter Plugin is only installed once.
if(!version.extensions.SocialtextFormatterPlugin) {
version.extensions.SocialtextFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('SocialtextFormatterPlugin requires TiddlyWiki 2.1 or later.');}
SocialtextFormatter = {}; // 'namespace' for local functions
wikify = function(source,output,highlightRegExp,tiddler)
{
if(source && source != '') {
var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
var out = output;
if(tiddler && (tiddler.isTagged(config.parsers.socialtextFormatter.formatTag) || (tiddler.fields.wikiformat==config.parsers.socialtextFormatter.format)) ) {
var d1 = createTiddlyElement(output,'div','content-display-body','content-section-visible');
var d2 = createTiddlyElement(d1,'div','wikipage');
out = createTiddlyElement(d2,'div',null,'wiki');
}
var time1,time0 = new Date();
w.subWikifyUnterm(out);
if(tiddler && config.options.chkDisplayInstrumentation) {
time1 = new Date();
var t = tiddler ? tiddler.title : source.substr(0,10);
displayMessage("Wikify '"+t+"' in " + (time1-time0) + " ms");
}
}
};
stDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement(out,'br');
};
SocialtextFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
if((this.fields.wikiformat==config.parsers.socialtextFormatter.format) || this.isTagged(config.parsers.socialtextFormatter.formatTag)) {
// update the links array, by checking for Socialtext format links
this.links = [];
var tiddlerLinkRegExp = /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg;
tiddlerLinkRegExp.lastIndex = 0;
var match = tiddlerLinkRegExp.exec(this.text);
while(match) {
var link = match[2];
this.links.pushUnique(link);
match = tiddlerLinkRegExp.exec(this.text);
}
}/* else {
return SocialtextFormatter.Tiddler_changed.apply(this,arguments);
}*/
this.linksUpdated = true;
};
SocialtextFormatter.wafl = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var lm2 = lookaheadMatch[2];
switch(lookaheadMatch[1]) {
case 'image':
var img = createTiddlyElement(w.output,'img');
img.src = w.tiddler.title + '/' + lm2;
createTiddlyText(img,lm2);
break;
case 'file':
var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var a = createTiddlyElement(s,'a');
a.href = w.tiddler.title + '/' + lm2;
createTiddlyText(a,lm2);
break;
case 'link':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createTiddlyElement(s,'a');
var t = w.tiddler ? w.tiddler.title + ':' : '';
a.setAttribute('href','#' + t + lm2);
a.title = 'section link';
createTiddlyText(a,lm2);
break;
case 'weblog':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var text = lm2;
var link = 'Weblog: ' + lm2;
createTiddlyText(createTiddlyLink(s,link,false,null,w.isStatic),text);
break;
case 'section':
a = createTiddlyElement(w.output,'a');// drop anchor
t = w.tiddler ? w.tiddler.title + ':' : '';
a.setAttribute('name',t + lm2);
break;
case 'date':
createTiddlyText(w.output,lm2);
break;
case 'user':
var oldSource = w.source;
w.source = lm2;
w.nextMatch = 0;
w.subWikifyUnterm(w.output);
w.source = oldSource;
break;
// Shortcut expansions - not strictly syntax
case 'google':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://www.google.com/search?q='+lm2);
createTiddlyText(a,lm2);
break;
case 'fedex':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://www.fedex.com/Tracking?tracknumbers='+lm2);
createTiddlyText(a,lm2);
break;
case 'map':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://maps.google.com/maps?q='+lm2);
createTiddlyText(a,lm2);
break;
case 'wikipedia':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://en.wikipedia.org/wiki/'+lm2);
createTiddlyText(a,lm2);
break;
case 'rt':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://rt.socialtext.net/Ticket/Display.html?id='+lm2);
createTiddlyText(a,lm2);
break;
case 'stcal':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'https://calendar.socialtext.net:445/view_t.php?timeb=1&id=3&date='+lm2);
createTiddlyText(a,lm2);
break;
case 'svn':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'https://repo.socialtext.net/listing.php?rev='+lm2+'sc=1');
createTiddlyText(a,lm2);
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);
}
};
SocialtextFormatter.presence = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var p = lookaheadMatch[1];
var text = lookaheadMatch[2];
var link;
var src;
if(p=='aim') {
link = 'aim:goim?screenname=' + text + '&message=hello';
src = 'http://big.oscar.aol.com/sleepleft?on_url=http://www.aim.com/remote/gr/MNB_online.gif&off_url=http://www.aim.com/remote/gr/MNB_offline.gif';
} else if(p=='yahoo'||p=='ymsgr') {
link = 'ymsgr:sendIM?'+text;
src = 'http://opi.yahoo.com/online?u=chrislondonbridge&f=.gif';
} else if(p=='skype'||p=='callto') {
link = 'callto:'+text;
src = 'http://goodies.skype.com/graphics/skypeme_btn_small_green.gif';
} else if(p=='asap') {
link = 'http://asap2.convoq.com/AsapLinks/Meet.aspx?l='+text;
src = 'http://asap2.convoq.com/AsapLinks/Presence.aspx?l='+text;
}
var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var a = createExternalLink(s,link);
var img = createTiddlyElement(a,'img');
createTiddlyText(a,text);
img.src = src;
img.border='0';
img.alt = '(' + lookaheadMatch[1] + ')';
if(p=='aim') {
img.width='11'; img.height='13';
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
};
config.formatterHelpers.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);
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
config.socialtext = {};
config.socialtext.formatters = [
{
name: 'socialtextHeading',
match: '^\\^{1,6} ?',
termRegExp: /(\n+)/mg,
handler: function(w)
{
var len = w.matchText.trim().length;
var e = createTiddlyElement(w.output,'h' + len);
var a = createTiddlyElement(e,'a');// drop anchor
var t = w.tiddler ? w.tiddler.title + ':' : '';
len = w.source.substr(w.nextMatch).indexOf('\n');
a.setAttribute('name',t+w.source.substr(w.nextMatch,len));
w.subWikifyTerm(e,this.termRegExp);
}
},
{
name: 'socialtextTable',
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;
}
// Cell
w.nextMatch--;
this.cellRegExp.lastIndex = w.nextMatch;
cellMatch = this.cellRegExp.exec(w.source);
}
return false;
}
},
{
name: 'socialtextList',
match: '^[\\*#]+ ',
lookaheadRegExp: /^([\*#])+ /mg,
termRegExp: /(\n+)/mg,
handler: function(w)
{
var stack = [w.output];
var currLevel = 0, currType = null;
var itemType = 'li';
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var listType = lookaheadMatch[1] == '*' ? 'ul' : 'ol';
var 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],itemType);
w.subWikifyTerm(e,this.termRegExp);
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'socialtextQuoteByLine',
match: '^>+',
lookaheadRegExp: /^>+/mg,
termRegExp: /(\n)/mg,
element: 'blockquote',
handler: function(w)
{
var stack = [w.output];
var currLevel = 0;
var newLevel = w.matchLength;
var i;
do {
if(newLevel > currLevel) {
for(i=currLevel; i<newLevel; i++) {
stack.push(createTiddlyElement(stack[stack.length-1],this.element));
}
} else if(newLevel < currLevel) {
for(i=currLevel; i>newLevel; i--) {
stack.pop();
}
}
currLevel = newLevel;
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
createTiddlyElement(stack[stack.length-1],'br');
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
if(matched) {
newLevel = lookaheadMatch[0].length;
w.nextMatch += newLevel;
}
} while(matched);
}
},
{
name: 'socialtextRule',
match: '^----+$\\n+',
handler: function(w)
{
createTiddlyElement(w.output,'hr');
}
},
{
name: 'socialtextPreformatted',
match: '^\\.pre\\s*\\n',
lookaheadRegExp: /^.pre\s*\n((?:.|\n)*?)\n.pre\s*\n/mg,
element: 'pre',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'socialtextHtml',
match: '^\\.html',
lookaheadRegExp: /\.html((?:.|\n)*?)\.html/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;
}
}
},
{
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: 'socialtextExplicitLink',
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[2];
var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
createTiddlyText(createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler),text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextExternalLink',
match: '(?:".*?" ?)?<[a-z]{2,8}:',
lookaheadRegExp: /(?:\"(.*?)\" ?)?<([a-z]{2,8}:.*?)>/mg,
imgRegExp: /\.(?:gif|ico|jpg|png)/g,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var link = lookaheadMatch[2];
var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
this.imgRegExp.lastIndex = 0;
if(this.imgRegExp.exec(link)) {
var img = createTiddlyElement(w.output,'img');
if(lookaheadMatch[1]) {
img.title = text;
}
img.alt = text;
img.src = link;
} else {
createTiddlyText(createExternalLink(w.output,link),text);
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'socialtextBold',
match: '\\*(?![\\s\\*])',
lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[$\s\|\._\-,])/mg,
termRegExp: /((?!\s)\*(?=[$\s\|\.\-_,]))/mg,
element: 'strong',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextItalic',
match: '_(?![\\s_])',
lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[$\s\|\.\*\-,])/mg,
termRegExp: /((?!\s)_(?=[$\s\|\.\*\-,]))/mg,
element: 'em',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextStrike',
match: '-(?![\\s\\-])',
lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[$\s\|\.\*_,])/mg,
termRegExp: /((?!\s)-(?=[$\s\|\.\*_,]))/mg,
element: 'del',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextMonoSpaced',
match: '`(?![\\s`])',
lookaheadRegExp: /`(?!\s)(?:.*?)(?!\s)`(?=[$\s\.\*\-_,])/mg,
termRegExp: /((?!\s)`(?=[$\s\.\*\-_,]))/mg,
element: 'tt',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextParagraph',
match: '\\n{2,}',
handler: function(w)
{
createTiddlyElement(w.output,'p');
}
},
{
name: 'socialtextLineBreak',
match: '\\n',
handler: function(w)
{
createTiddlyElement(w.output,'br');
}
},
{
name: 'socialtextNoWiki',
match: '\\{\\{',
lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
element: 'span',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'socialtextTrademark',
match: '\\{tm\\}',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = '™';
}
},
{
name: 'socialtextWafl',
match: '\\{(?:[a-z]{2,16}): ?.*?\\}',
lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
handler: SocialtextFormatter.wafl
},
{
name: 'socialtextPresence',
match: '(?:aim|yahoo|ymsgr|skype|callto|asap):\\w+',
lookaheadRegExp: /(aim|yahoo|ymsgr|skype|callto|asap):(\w+)/mg,
handler: SocialtextFormatter.presence
},
{
name: 'socialtextMailTo',
match: '[\\w\.]+@[\\w]+\.[\\w\.]+',
lookaheadRegExp: /([\w\.]+@[\w]+\.[\w\.]+)/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];
createTiddlyText(createExternalLink(w.output,'mailto:'+text),text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
}
];
config.parsers.socialtextFormatter = new Formatter(config.socialtext.formatters);
config.parsers.socialtextFormatter.format = 'socialtext';
config.parsers.socialtextFormatter.formatTag = 'SocialtextFormat';
} // end of 'install only once'
//}}}
This walk-through shows you how to connect to a Socialtext wiki server and choose some pages to download, and then to synchronise subsequent changes between TiddlyWiki and the server
# Socialtext have kindly set up a sandbox wiki for TiddlyWiki users on their servers. You'll need to register for the wiki in order to fully complete this walk-through
## Go to http://www.socialtext.net/TiddlySandbox
## Click on the 'register' link at the upper right
## Give your email address and choose a password as prompted
## (Socialtext won't spam you)
# If necessary, DownloadSoftware and open it in your browser
# If the black backstage are isn't visible along the top of the screen, click on the 'backstage' button at the top right
# Choose 'import' from the backstage area
# In the task wizard that drops down, choose the predefined server 'SocialtextDotNet'
# Click the 'open' button
# When prompted for the workspace, leave the default of 'TiddlySandbox' and click the 'open' button
# After a pause, you should then see a list of the available tiddlers. Select the checkboxes by two or three and then click the 'import' button
# The tiddlers you have selected will be listed, first as italicised links to missing tiddlers, and then as bold links as the tiddlers are loaded in the background. Click on the links to open the tiddlers you selected
# Click on the grey bars to either side of the backstage drop-down to close it
# You should now be able to browse the pages that you imported
# Note that if you click on a link to an article that has not been downloaded, it will be automatically retrieved from the server
# Edit one of the newly imported tiddlers and click 'done' to save changes'
# Choose 'sync' from the backstage area
# You should see a table showing the tiddlers that you've imported and their synchronisation status. It takes a few seconds to check in with the server to fully update the table. The tiddler you modified should be flagged as 'Changed while unplugged'
# Select the checkbox by the tiddler you modified (if necessary) and click the 'sync' button
# After synchronisation the status of the tiddler should have changed to 'Updated on server'
# Click on 'view' link for that tiddler and verify that the page has been modified on the server
# Edit the page directly from Socialtext (using the bright big 'edit' button at the upper left)
# Return to TiddlyWiki and sync again. You should be prompted to download the changes from the server
Note that this beta doesn't quite do the right thing when both the client and server versions of a tiddler have been changed. Sadly there's no magic bullet in that situation.
/***
|''Name:''|TWikiAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from TWikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#TWikiAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/TWikiAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 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|
TWiki REST documentation is at:
http://twiki.org/cgi-bin/view/TWiki04/TWikiScripts
''For debug:''
|''Default TWiki Server''|<<option txttwikiDefaultServer>>|
|''Default TWiki Web(workspace)''|<<option txttwikiDefaultWorkspace>>|
|''Default TWiki username''|<<option txttwikiUsername>>|
|''Default TWiki password''|<<option txttwikiPassword>>|
***/
//{{{
if(!config.options.txttwikiDefaultServer)
{config.options.txttwikiDefaultServer = 'twiki.org';}
if(!config.options.txttwikiDefaultWorkspace)
{config.options.txttwikiDefaultWorkspace = 'Main';}
if(!config.options.txttwikiUsername)
{config.options.txttwikiUsername = '';}
if(!config.options.txttwikiPassword)
{config.options.txttwikiPassword = '';}
//}}}
//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.TWikiAdaptorPlugin) {
version.extensions.TWikiAdaptorPlugin = {installed:true};
function TWikiAdaptor()
{
this.host = null;
this.workspace = null;
// for debug
this.username = config.options.txttwikiUsername;
this.password = config.options.txttwikiPassword;
return this;
}
TWikiAdaptor.serverType = 'twiki';
TWikiAdaptor.serverParsingErrorMessage = "Error parsing result from server";
TWikiAdaptor.errorInFunctionMessage = "Error in function TWikiAdaptor.%0";
TWikiAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
TWikiAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
TWikiAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(!host.match(/\/bin/) && !host.match(/\/cgi-bin/))
host = host.replace(/\/$/,'') + '/cgi-bin/';
if(host.substr(-1) != '/')
host = host + '/';
return host;
};
TWikiAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/cgi-bin\/$/,'').replace(/\/$/,'') : '';
};
TWikiAdaptor.normalizedTitle = function(title)
{
return title;
};
TWikiAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = TWikiAdaptor.fullHostName(host);
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
TWikiAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(workspace)
this.workspace = workspace;
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
TWikiAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
if(context.workspace) {
context.status = true;
context.workspace = [{name:context.workspace,title:context.workspace}];
if(context.callback)
window.setTimeout(context.callback,0,context,userParams);
return true;
}
var list = [];
list.push({title:"Main",name:"Main"});
list.push({title:"Sandbox",name:"Sandbox"});
context.workspaces = list;
context.status = true;
if(context && callback) {
window.setTimeout(callback,0,context,userParams);
}
return true;
};
TWikiAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,TWikiAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
list.push({title:info[i].title});
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
TWikiAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
{
context = this.setContext(context,userParams,callback);
var limit = context.tiddlerLimit ? context.tiddlerLimit : 50;
if(filter) {
var list = [];
var params = filter.parseParams('anon',null,false);
for(var i=1; i<params.length; i++) {
var tiddler = new Tiddler(params[i].value);
list.push(tiddler);
}
context.tiddlers = list;
context.status = true;
if(context.callback)
window.setTimeout(context.callback,0,context,context.userParams);
return true;
}
return "getTiddlerList not supported";
/*var uriTemplate = '';
var uri = uriTemplate.format([this.host,this.workspace]);
var req = TWikiAdaptor.doHttpGET(uri,TWikiAdaptor.getTiddlerListCallback);
return typeof req == 'string' ? req : true;*/
};
TWikiAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = TWikiAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
list = [];
context.tiddlers = list;
} catch (ex) {
context.statusText = exceptionText(ex,TWikiAdaptor.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);
};
TWikiAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var uriTemplate = '%0view/%1/%2';
info.uri = uriTemplate.format([this.host,this.workspace,tiddler.title]);
return info;
};
/*TWikiAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
return this.getTiddlerRevision(title,null,context,userParams,callback);
};*/
TWikiAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var host = TWikiAdaptor.fullHostName(this.host);
var uriTemplate = '%0view/%1/%2?raw=text';
var uri = uriTemplate.format([host,this.workspace,title]);
context.tiddler = new Tiddler(title);
context.tiddler.fields.wikiformat = 'twiki';
context.tiddler.fields['server.host'] = TWikiAdaptor.minHostName(host);
context.tiddler.fields['server.workspace'] = this.workspace;
var req = TWikiAdaptor.doHttpGET(uri,TWikiAdaptor.getTiddlerCallback,context);
return typeof req == 'string' ? req : true;
};
TWikiAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = responseText;
//<form><textarea readonly="readonly" wrap="virtual" rows="50" cols="80">
var contentRegExp = /<textarea.*?>((?:.|\n)*?)<\/textarea>/mg;
contentRegExp.lastIndex = 0;
var match = contentRegExp.exec(responseText);
if(match) {
content = match[1].htmlDecode();
}
context.tiddler.text = content;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
TWikiAdaptor.prototype.putTiddler = function(tiddler,context,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0save/%1/%2?text=%3';
var host = this.host ? this.host : TWikiApaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this.workspace ? this.workspace : tiddler.fields['server.workspace'];
var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
context.tiddler = tiddler;
context.tiddler.fields.wikiformat = 'twiki';
context.tiddler.fields['server.host'] = TWikiAdaptor.minHostName(this.host);
context.tiddler.fields['server.workspace'] = workspace;
var req = TWikiAdaptor.doHttpGET(uri,TWikiAdaptor.putTiddlerCallback,context,null,null,null,this.username,this.password);
return typeof req == 'string' ? req : true;
};
TWikiAdaptor.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);
};
TWikiAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[TWikiAdaptor.serverType] = TWikiAdaptor;
} //# end of 'install only once'
//}}}
/***
|''Name:''|TWikiFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[TWiki|http://twiki.org/cgi-bin/view/TWiki/TextFormattingRules]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#TWikiFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/TWikiFormatterPlugin.js|
|''Version:''|0.2.3|
|''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.3|
|''Display unsupported TWiki variables''|<<option chkDisplayTWikiVariables>>|
This the TWikiFormatterPlugin, which allows you to insert TWiki formated text into a TiddlyWiki.
The aim is not to fully emulate TWiki, but to allow you to work with TWiki content off-line and then resync the content with your TWiki later on, with the expectation that only minor edits will be required.
To use TWiki format in a Tiddler, tag the Tiddler with TWikiFormat or set the tiddler's {{{wikiformat}}} extended field to {{{twiki}}}.
Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
!!!Issues
There are (at least) the following known issues:
# Table code is incomplete.
## Table headings not yet supported.
# Anchors not yet supported.
# TWiki variables not supported
***/
//{{{
// Ensure that the TWikiFormatter Plugin is only installed once.
if(!version.extensions.TWikiFormatterPlugin) {
version.extensions.TWikiFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('TWikiFormatterPlugin requires TiddlyWiki 2.1 or later.');}
if(config.options.chkDisplayTWikiVariables == undefined)
{config.options.chkDisplayTWikiVariables = false;}
TWikiFormatter = {}; // 'namespace' for local functions
twDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement(out,'br');
};
TWikiFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
if((this.fields.wikiformat==config.parsers.twikiFormatter.format) || this.isTagged(config.parsers.twikiFormatter.formatTag)) {
this.links = [];
var tiddlerLinkRegExp = /\[\[(.*?)(?:\]\[(?:.*?))?\]\]/mg;
tiddlerLinkRegExp.lastIndex = 0;
var match = tiddlerLinkRegExp.exec(this.text);
while(match) {
this.links.pushUnique(match[1]);
match = tiddlerLinkRegExp.exec(this.text);
}
} else if(!this.isTagged('systemConfig')) {
TWikiFormatter.Tiddler_changed.apply(this,arguments);
return;
}
this.linksUpdated = true;
};
Tiddler.prototype.escapeLineBreaks = function()
{
var r = this.text.escapeLineBreaks();
if(this.isTagged(config.parsers.twikiFormatter.formatTag)) {
r = r.replace(/\x20\x20\x20/mg,'\\b \\b');
r = r.replace(/\x20\x20/mg,'\\b ');
}
return r;
};
config.textPrimitives.twikiLink = '(?:' +
config.textPrimitives.upperLetter + '+' + config.textPrimitives.lowerLetter + '+' +
config.textPrimitives.upperLetter + config.textPrimitives.anyLetter + '*)';
TWikiFormatter.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.formatterHelpers.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);
}
};
config.formatterHelpers.doubleCharFormat = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
//twDebug(w.output,'dcmt:'+w.matchText);
//twDebug(w.output,'lm:'+lookaheadMatch);
//twDebug(w.output,'lm0:'+lookaheadMatch[0]+' lm:'+lookaheadMatch[0].length);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart &&
lookaheadMatch[0].substr(lookaheadMatch[0].length-3,1) != ' ') {
var e = createTiddlyElement(w.output,this.element);
w.subWikifyTerm(createTiddlyElement(e,this.element2),this.termRegExp);
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
config.twikiFormatters = [
{
name: 'twikiTable',
match: '^\\|(?:[^\\n]*)\\|$',
lookaheadRegExp: /^\|([^\n]*)\|$/mg,
rowTermRegExp: /(\|$\n?)/mg,
cellRegExp: /(?:\|([^\n\|]*)\|)|(\|$\n?)/mg,
cellTermRegExp: /((?:\x20*)\|)/mg,
handler: function(w)
{
var table = createTiddlyElement(w.output,'table');
var rowContainer = table;//createTiddlyElement(table,'tbody');
var prevColumns = [];
var rowCount = 0;
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var rowClass = (rowCount&1) ? 'TD.odd' : 'TD.even';
if(rowCount==1) rowClass = 'TD.heading';
if(rowCount==3) rowClass = 'TD.third';
this.rowHandler(w,createTiddlyElement(rowContainer,'tr',null,rowClass),prevColumns);
rowCount++;
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
},
rowHandler: function(w,e,prevColumns)
{
var col = 0;
var colSpanCount = 1;
var prevCell = null;
this.cellRegExp.lastIndex = w.nextMatch;
var cellMatch = this.cellRegExp.exec(w.source);
while(cellMatch && cellMatch.index == w.nextMatch) {
if(cellMatch[1] == '^') {
// Rowspan
var last = prevColumns[col];
if(last) {
last.rowSpanCount++;
last.element.setAttribute('rowspan',last.rowSpanCount);
last.element.setAttribute('rowSpan',last.rowSpanCount); // Needed for IE
last.element.valign = 'center';
}
w.nextMatch = this.cellRegExp.lastIndex-1;
} else if(cellMatch[1] === '') {
// Colspan
colSpanCount++;
w.nextMatch = this.cellRegExp.lastIndex-1;
} else if(cellMatch[2]) {
// End of row
if(prevCell && colSpanCount > 1) {
prevCell.setAttribute('colspan',colSpanCount);
prevCell.setAttribute('colSpan',colSpanCount); // Needed for IE
}
w.nextMatch = this.cellRegExp.lastIndex;
break;
} else {
// Cell
w.nextMatch++;
var spaceLeft = false;
var chr = w.source.substr(w.nextMatch,1);
while(chr == ' ') {
spaceLeft = true;
w.nextMatch++;
chr = w.source.substr(w.nextMatch,1);
}
var cell = createTiddlyElement(e,'td');
prevCell = cell;
prevColumns[col] = {rowSpanCount:1, element:cell};
if(colSpanCount > 1) {
cell.setAttribute('colspan',colSpanCount);
cell.setAttribute('colSpan',colSpanCount); // Needed for IE
colSpanCount = 1;
}
w.subWikifyTerm(cell,this.cellTermRegExp);
if(w.matchText.substr(w.matchText.length-2,1) == ' ') {
// spaceRight
cell.align = spaceLeft ? 'center' : 'left';
} else if(spaceLeft) {
cell.align = 'right';
}
w.nextMatch--;
}
col++;
this.cellRegExp.lastIndex = w.nextMatch;
cellMatch = this.cellRegExp.exec(w.source);
}
}
},
{
name: 'twikiRule',
match: '^---+$\\n?',
handler: function(w)
{
createTiddlyElement(w.output,'hr');
}
},
{
//<h1><a name='TWiki_Text_Formatting'></a> TWiki Text Formatting </h1>
name: 'twikiHeading',
match: '^---[\\+#]{0,5}',
lookaheadRegExp: /^---[\+#]{0,5}(?:!!)? ?(.*?)\n/mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var h = createTiddlyElement(w.output,'h' + (w.matchLength-2));
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var a = createTiddlyElement(w.output,'a');
var prefix = w.tiddler ? w.tiddler.title : '';
var name = '#'+ prefix + lookaheadMatch[1];
name = name.replace(/ /g,'_');
a.name = name;
w.nextMatch = this.lookaheadRegExp.lastIndex - lookaheadMatch[1].length - 1;
w.subWikifyTerm(h,this.termRegExp);
}
}
},
{
name: 'twikiAnchor',
match: '^#' + config.textPrimitives.wikiLink + '\\s',
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 a = createTiddlyElement(w.output,'a');
var prefix = w.tiddler ? w.tiddler.title : '';
var name = '#'+ prefix + lookaheadMatch[1];
name = name.replace(/ /g,'_');
a.name = name;
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiDefinitionList',
match: '^ \\$ .+?:.+?\\n',
lookaheadRegExp: /^ \$ (.+?):(.+?)\n/mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
var li = createTiddlyElement(w.output,'dl');
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
w.nextMatch += 5;
w.subWikifyTerm(createTiddlyElement(li,'dt'),/(:)/mg);
w.subWikifyTerm(createTiddlyElement(li,'dd'),this.termRegExp);
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'twikiList',
match: '^(?: )+(?:(?:\\*)|(?:[1AaIi](?:\\.)?)) ',
lookaheadRegExp: /^(?: )+(?:(\*)|(?:([1AaIi])(\.)?)) /mg,
//termRegExp: /(\n\n|\n(?=(?: )+[\\*1AaIi]))/mg,
termRegExp: /(\n)/mg,
handler: function(w)
{
//twDebug(w.output,'mt:'+w.matchText);
var stack = [w.output];
var currLevel = 0;
var currType = null;
var listLevel, listType;
var itemType = 'li';
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
//twDebug(w.output,'lm0:'+lookaheadMatch[0]);
listType = 'ol';
listLevel = (lookaheadMatch[0].length-(lookaheadMatch[3]?3:2))/3;
var style = null;
if(lookaheadMatch[1]=='*') {
listType = 'ul';
} else if(lookaheadMatch[2]=='1') {
style = 'decimal';
} else if(lookaheadMatch[2]=='A') {
style = 'upper-alpha';
} else if(lookaheadMatch[2]=='a') {
style = 'lower-alpha';
} else if(lookaheadMatch[2]=='I') {
style = 'upper-roman';
} else if(lookaheadMatch[2]=='i') {
style = 'lower-roman';
}
w.nextMatch += lookaheadMatch[0].length;
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],itemType);
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: 'twikiNoAutoLink',
match: '^\\s*<noautolink>',
lookaheadRegExp: /\s*<noautolink>((?:.|\n)*?)<\/noautolink>/mg,
termRegExp: /(<\/noautolink>)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var autoLinkWikiWords = w.autoLinkWikiWords;
w.autoLinkWikiWords = false;
w.subWikifyTerm(w.output,this.termRegExp);
w.autoLinkWikiWords = autoLinkWikiWords;
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
},
{
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: 'twikiNotExplicitLink',
match: '!\\[\\[',
handler: function(w)
{
w.outputText(w.output,w.matchStart+1,w.nextMatch);
}
},
//[[WikiWord#NotThere]]
//[[#MyAnchor][Jump]]
//<a href='/cgi-bin/view/Sandbox/WebHome#Sandbox_Web_Site_Tools'> Sandbox Web Site Tools </a>
//<a href='/cgi-bin/view/Sandbox/MeetingMinutes' class='twikiLink'>MeetingMinutes</a>
{
name: 'twikiAnchorLink',
match: '\\[\\[(?:'+ config.textPrimitives.twikiLink +')?#',
lookaheadRegExp: /\[\[(.*?)?#(.*?)(?:\]\[(.*?))?\]\]/mg,
handler: function(w)
{
//twDebug(w.output,'al:'+w.matchText);
//twDebug(w.output,'lm:'+lookaheadMatch);
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
//twDebug(w.output,'lm0:'+lookaheadMatch[0]);
var a = createTiddlyElement(w.output,'a');
var prefix = w.tiddler ? w.tiddler.title : '';
var href = lookaheadMatch[1] ? lookaheadMatch[1] : '';
href += '#' + prefix + lookaheadMatch[2];
href = href.replace(/ /g,'_');
//twDebug(w.output,'hr:'+href);
a.href = href;
a.innerHTML = lookaheadMatch[3] ? lookaheadMatch[3] : lookaheadMatch[2];
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiExplicitLink',
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 = null;
var link = lookaheadMatch[1];
if (lookaheadMatch[2]) {
// titled bracketted link
var text = lookaheadMatch[2];
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
} else {
// simple bracketted link
text = link;
var s = text.indexOf(' ');
if(s!=-1) {
link = text.substring(0,s).trim();
if(config.formatterHelpers.isExternalLink(link)) {
e = createExternalLink(w.output,link);
text = text.substring(s+1).trim();
} else {
e = createTiddlyLink(w.output,text,false,null,w.isStatic,w.tiddler);
}
} else {
e = createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
}
}
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiNotWikiLink',
match: '(?:!|<nop>)' + config.textPrimitives.wikiLink,
handler: function(w)
{
w.outputText(w.output,w.matchStart+(w.matchText.substr(0,1)=='!'?1:5),w.nextMatch);
}
},
{
name: 'twikiWikiLink',
match: config.textPrimitives.twikiLink,
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;
}
}
if(w.autoLinkWikiWords == true || store.isShadowTiddler(w.matchText)) {
var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler);
w.outputText(link,w.matchStart,w.nextMatch);
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
},
{
name: 'twikiUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'twikiBoldByChar',
match: '\\*(?!\\s)',
lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=\W)/mg,
termRegExp: /((?!\s)\*(?=\W))/mg,
element: 'strong',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'twikiBoldTag',
match: '<b>',
termRegExp: /(<\/b>)/mg,
element: 'b',
handler: config.formatterHelpers.createElementAndWikify
},
{
name: 'twikiBoldItalicByChar',
match: '__(?!\\s)',
lookaheadRegExp: /__(?!\s)(?:.*?)(?!\s)__(?=\W)/mg,
termRegExp: /((?!\s)__(?=\W))/mg,
element: 'strong',
element2: 'em',
handler: config.formatterHelpers.doubleCharFormat
},
{
name: 'twikiItalicByChar',
match: '_(?![\\s|_])',
lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=\W)/mg,
termRegExp: /((?!\s)_(?=\W))/mg,
element: 'em',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'twikiBoldMonoSpacedByChar',
match: '==(?!\\s)',
lookaheadRegExp: /==(?!\s)(?:.*?)(?!\s)==(?=\W)/mg,
termRegExp: /((?!\s)==(?=\W))/mg,
element: 'strong',
element2: 'code',
handler: config.formatterHelpers.doubleCharFormat
},
{
name: 'twikiMonoSpacedByChar',
match: '=(?![\\s=])',
lookaheadRegExp: /=(?!\s)(?:.*?)(?!\s)=(?!\w|\'|\")/mg,
termRegExp: /((?!\s)=(?!\w|\'|\"))/mg,
element: 'code',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'twikiPreByChar',
match: '<pre>',
lookaheadRegExp: /<pre>((?:.|\n)*?)<\/pre>/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,'pre',null,null,lookaheadMatch[1]);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiVerbatimByChar',
match: '<verbatim>',
lookaheadRegExp: /\<verbatim>((?:.|\n)*?)<\/verbatim>/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',null,null,lookaheadMatch[1]);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiParagraph',
match: '\\n{2,}',
handler: function(w)
{
createTiddlyElement(w.output,'p');
}
},
{
name: 'twikiNop',
match: '<nop>',
handler: function(w)
{
w.outputText(w.output,w.matchStart+5,w.nextMatch);
}
},
{
name: 'twikiExplicitLineBreak',
match: '%BR%|<br ?/?>|<BR ?/?>',
handler: function(w)
{
createTiddlyElement(w.output,'br');
}
},
{
name: 'twikiColorByChar',
match: '%(?:YELLOW|ORANGE|RED|PINK|PURPLE|TEAL|NAVY|BLUE|AQUA|LIME|GREEN|OLIVE|MAROON|BROWN|BLACK|GRAY|SILVER|WHITE)%',
lookaheadRegExp: /%(YELLOW|ORANGE|RED|PINK|PURPLE|TEAL|NAVY|BLUE|AQUA|LIME|GREEN|OLIVE|MAROON|BROWN|BLACK|GRAY|SILVER|WHITE)/mg,
termRegExp: /(%ENDCOLOR%)/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,'span');
e.style.color = lookaheadMatch[1];
w.subWikifyTerm(e,this.termRegExp);
}
}
},
{
name: 'twikiVariable',
match: '(?:!)?%(?:<nop>)?[A-Z]+(?:\\{.*?\\})?%',
lookaheadRegExp: /(!)?%(<nop>)?([A-Z]+)(?:\{(.*?)\})?%/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
if(lookaheadMatch[1]) {
// ! - escape variable
w.outputText(w.output,w.matchStart+1,w.nextMatch);
} else if(lookaheadMatch[2]) {
//nop
var text = w.matchText.replace(/<nop>/g,'');
createTiddlyText(w.output,text);
} else {
// deal with variables by name here
if(lookaheadMatch[3]=='BB') {
createTiddlyElement(w.output,'br');
createTiddlyElement(w.output,'span').innerHTML = '•';
} else if(config.options.chkDisplayTWikiVariables) {
// just output the text of any variables that are not understood
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'twikiHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
},
{
name: 'twikiComment',
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: 'twikiHtmlTag',
match: "<(?:[a-zA-Z]{2,}|a)(?:\\s*(?:[a-zA-Z]*?=[\"']?[^>]*?[\"']?))*?>",
lookaheadRegExp: /<([a-zA-Z]+)((?:\s+[a-zA-Z]*?=["']?[^>\/\"\']*?["']?)*?)?\s*(\/)?>/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]) {
TWikiFormatter.setAttributesFromParams(e,lookaheadMatch[2]);
}
if(lookaheadMatch[3]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;// empty tag
} else {
w.subWikify(e,'</'+lookaheadMatch[1]+'>');
}
}
}
}
];
config.parsers.twikiFormatter = new Formatter(config.twikiFormatters);
config.parsers.twikiFormatter.format = 'twiki';
config.parsers.twikiFormatter.formatTag = 'TWikiFormat';
} // end of 'install only once'
//}}}
|''URL:''|http://tiddlystyles.com/|
|''URL:''|http://www.tiddlytools.com/|
|''Description:''|Small Tools for Big Ideas!|
|''Author:''|EricShulman|
|''URL:''|http://www.tiddlywiki.com/|
The current, non-Beta version of TiddlyWiki is at http://www.tiddlywiki.com
Here's how to try out the features in this new beta:
# Download a copy of this TiddlyWiki by right-clicking on [[this link|index.html]] or download an [[empty copy|empty.html]]
# Open it in your browser (at the moment, FireFox works best)
# Click on the 'backstage' link in the upper right
# Click on 'import'
# Select 'SocialtextDotNext' from the lower drop down list
# Click 'Open'
# Enter 'stoss' as the workspace name
# Click 'Open'
# Select some tiddlers and then scroll to the bottom and click 'import'
# Wait for the confirmation message to verify that the tiddlers have been imported
|''Description:''|Wikipedia articles containing IPstack template|
|''Type:''|mediawiki|
|''URL:''|http://www.wikipedia.org/w/|
|''Workspace:''|Main|
|''~TiddlerFilter:''|[template[IPstack]]|
|''Description:''|Wikipedia articles in the category "Impressionist painters"|
|''Type:''|mediawiki|
|''URL:''|http://www.wikipedia.org/w/|
|''Workspace:''|Main|
|''~TiddlerFilter:''|[tags[Impressionist_painters]]|
|''Description:''|Wikipedia articles in the category "Wiki"|
|''Type:''|mediawiki|
|''URL:''|http://www.wikipedia.org/w/|
|''Workspace:''|Main|
|''~TiddlerFilter:''|[tags[Wiki]]|
/***
|''Name:''|ZimbraAdaptorPlugin|
|''Description:''|Adaptor for Zimbra Collaboration Server (http://www.zimbra.com/)|
|''Author:''|Jeremy Ruston (jeremy (at) osmosoft (dot) com)|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/verticals/zimbra/plugins/ZimbraAdaptorPlugin.js|
|''Version:''|0.1.1|
|''Date:''|Apr 15, 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|
***/
//{{{
if(!version.extensions.ZimbraAdaptorPlugin) {
version.extensions.ZimbraAdaptorPlugin = {installed:true};
function ZimbraAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
merge(ZimbraAdaptor,{
serverType: 'zimbra',
getTiddlerListUrl: '%0service/home/%1/Notebook.rss',
viewTiddlerUrl: '%0service/home/%1/Notebook/%2',
getTiddlerUrl: '%0service/home/%1/Notebook/%2?fmt=native',
tiddlerTemplate: '<html>%0</html>'
});
ZimbraAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
ZimbraAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = host;
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
ZimbraAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.workspaces = [];
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
ZimbraAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.workspace = workspace;
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
ZimbraAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var url = ZimbraAdaptor.getTiddlerListUrl.format([this.host,this.workspace]);
var ret = loadRemoteFile(url,ZimbraAdaptor.getTiddlerListCallback,context);
return typeof(ret) == "string" ? ret : true;
};
ZimbraAdaptor.getTiddlerListCallback = function(status,context,responseText,url,xhr)
{
var adaptor = context.adaptor;
context.status = status;
if(!status) {
context.statusText = "Error reading file: " + xhr.statusText;
} else {
context.tiddlers = adaptor.readRss(responseText);
}
context.callback(context,context.userParams);
};
ZimbraAdaptor.prototype.readRss = function(rssText)
{
var tiddlers = [];
var xml = (new DOMParser()).parseFromString(rssText,"text/xml");
var root = xml.getElementsByTagName('rss')[0];
var channel = root.getElementsByTagName('channel')[0];
var items = channel.getElementsByTagName('item');
for(var t=0; t<items.length; t++) {
var title = items[t].getElementsByTagName('title')[0].firstChild.nodeValue;
var c = title.lastIndexOf(" ver ");
if(c != -1)
title = title.substr(0,c);
if(tiddlers.findByField("title",title) == null) {
var tiddler = new Tiddler(title);
var pubDate = items[t].getElementsByTagName('pubDate')[0].firstChild.nodeValue;
tiddler.modified = new Date(pubDate);
tiddlers.push(tiddler);
}
}
return tiddlers;
};
ZimbraAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : tiddler.fields['server.host'];
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
info.uri = ZimbraAdaptor.viewTiddlerUrl.format([host,workspace,encodeURI(tiddler.title)]);
return info;
};
ZimbraAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.title = title;
var url = ZimbraAdaptor.getTiddlerUrl.format([this.host,this.workspace,encodeURI(title)]);
var ret = loadRemoteFile(url,ZimbraAdaptor.getTiddlerCallback,context);
return typeof(ret) == "string" ? ret : true;
};
ZimbraAdaptor.getTiddlerCallback = function(status,context,responseText,url,xhr)
{
var adaptor = context.adaptor;
context.status = status;
if(!status) {
context.statusText = "Error reading file: " + xhr.statusText;
} else {
context.tiddler = new Tiddler(context.title);
context.tiddler.text = ZimbraAdaptor.tiddlerTemplate.format([responseText]);
context.tiddler.fields['server.type'] = ZimbraAdaptor.serverType;
context.tiddler.fields['server.host'] = adaptor.host;
context.tiddler.fields['server.workspace'] = adaptor.workspace;
}
context.callback(context,context.userParams);
};
ZimbraAdaptor.prototype.close = function() {return true;};
config.adaptors[ZimbraAdaptor.serverType] = ZimbraAdaptor;
} //# end of 'install only once'
//}}}
|''Type:''|zimbra|
|''URL:''|https://dogfood.zimbra.com/|
|''Description:''|Zimbra's dogfood server|
/***
|''Name:''|ccTiddlyAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from ccTiddly wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ccTiddlyAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ccTiddlyAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 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|
''For debug:''
|''Default ccTiddly username''|<<option txtccTiddlyUsername>>|
|''Default ccTiddly password''|<<option txtccTiddlyPassword>>|
***/
//{{{
if(!config.options.txtccTiddlyUsername)
{config.options.txtccTiddlyUsername = '';}
if(!config.options.txtccTiddlyPassword)
{config.options.txtccTiddlyPassword = '';}
//}}}
// Ensure that the plugin is only installed once.
if(!version.extensions.ccTiddlyAdaptorPlugin) {
version.extensions.ccTiddlyAdaptorPlugin = {installed:true};
function ccTiddlyAdaptor()
{
this.host = null;
this.workspace = null;
// for debug
this.username = config.options.txtccTiddlyUsername;
this.password = config.options.txtccTiddlyPassword;
return this;
}
ccTiddlyAdaptor.serverType = 'cctiddly';
ccTiddlyAdaptor.serverParsingErrorMessage = "Error parsing result from server";
ccTiddlyAdaptor.errorInFunctionMessage = "Error in function ccTiddlyAdaptor.%0";
ccTiddlyAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
ccTiddlyAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
return context;
};
ccTiddlyAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(-1) != '/')
host = host + '/';
return host;
};
ccTiddlyAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
ccTiddlyAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.host = ccTiddlyAdaptor.fullHostName(host);
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
ccTiddlyAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
this.workspace = workspace;
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
ccTiddlyAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var list = [];
list.push({title:"Main",name:"Main"});
context.workspaces = list;
if(context.callback) {
context.status = true;
window.setTimeout(context.callback,0,context,userParams);
}
return true;
};
ccTiddlyAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0msghandle.php?action=content';
var host = ccTiddlyAdaptor.fullHostName(this.host);
var uri = uriTemplate.format([host,this.workspace]);
var req = ccTiddlyAdaptor.doHttpGET(uri,ccTiddlyAdaptor.getTiddlerListCallback,context);
return typeof req == 'string' ? req : true;
};
ccTiddlyAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = ccTiddlyAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
list = [];
/*var titles = responseText.split('\n');
for(var i=0; i<titles.length; i++) {
var tiddler = new Tiddler(titles[i]);
list.push(tiddler);
}*/
if(list.length==0) {
list.push(new Tiddler('About')); //kludge until get support for listTiddlers in ccTiddly
}
context.tiddlers = list;
} catch (ex) {
context.statusText = exceptionText(ex,ccTiddlyAdaptor.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);
};
ccTiddlyAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var uriTemplate = '%0#%2';
var host = ccTiddlyAdaptor.fullHostName(this.host);
info.uri = uriTemplate.format([this.host,this.workspace,tiddler.title]);
return info;
};
ccTiddlyAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
return this.getTiddlerRevision(title,null,context,userParams,callback);
};
ccTiddlyAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
//title = encodeURIComponent(title);
var host = ccTiddlyAdaptor.fullHostName(this.host);
context.tiddler = new Tiddler(title);
context.tiddler.fields['server.host'] = ccTiddlyAdaptor.minHostName(host);
context.tiddler.fields['server.type'] = ccTiddlyAdaptor.serverType;
if(revision) {
var uriTemplate = '%0msghandle.php?action=revisionDisplay&title=%1&revision=%2';
var uri = uriTemplate.format([host,title,revision]);
var req = ccTiddlyAdaptor.doHttpGET(uri,ccTiddlyAdaptor.getTiddlerCallback2,context);
} else {
// first get the revision list
uriTemplate = '%0msghandle.php?action=revisionList&title=%1';
uri = uriTemplate.format([host,title]);
req = ccTiddlyAdaptor.doHttpGET(uri,ccTiddlyAdaptor.getTiddlerCallback1,context);
}
return typeof req == 'string' ? req : true;
};
ccTiddlyAdaptor.getTiddlerCallback1 = function(status,context,responseText,xhr)
{
context.status = false;
context.statusText = ccTiddlyAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
if(status) {
var revs = responseText.split('\n');
var parts = revs[0].split(' ');
var tiddlerRevision = parts[1];
// now get the latest revision
var uriTemplate = '%0msghandle.php?action=revisionDisplay&title=%1&revision=%2';
var host = ccTiddlyAdaptor.fullHostName(context.adaptor.host);
var uri = uriTemplate.format([host,context.tiddler.title,tiddlerRevision]);
var req = ccTiddlyAdaptor.doHttpGET(uri,ccTiddlyAdaptor.getTiddlerCallback2,context);
} else {
context.statusText = xhr.statusText;
if(context.callback)
context.callback(context,context.userParams);
}
};
ccTiddlyAdaptor.getTiddlerCallback2 = function(status,context,responseText,xhr)
{
context.status = false;
if(status) {
var x = responseText.split('\n');
try {
context.tiddler.text = x[2] ? x[2].unescapeLineBreaks().htmlDecode() : '';
context.tiddler.modifier = x[3];
if(x[4])
context.tiddler.created = Date.convertFromYYYYMMDDHHMM(x[4]);
if(x[5])
context.tiddler.modified = Date.convertFromYYYYMMDDHHMM(x[5]);
//context.tiddler.tags = x[6].join(' ');
} catch(ex) {
context.statusText = exceptionText(ex,ccTiddlyAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context);
return;
}
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ccTiddlyAdaptor.prototype.getTiddlerRevisionList = function(title,context,userParams,callback)
// get a list of the revisions for a page
{
context = this.setContext(context,userParams,callback);
title = encodeURIComponent(title);
var uriTemplate = '%0msghandle.php?action=revisionList&title=%1';
var host = ccTiddlyAdaptor.fullHostName(this.host);
var uri = uriTemplate.format([host,title]);
context.tiddler = new Tiddler(title);
context.tiddler.fields['server.host'] = ccTiddlyAdaptor.minHostName(host);
context.tiddler.fields['server.type'] = ccTiddlyAdaptor.serverType;
var req = ccTiddlyAdaptor.doHttpGET(uri,ccTiddlyAdaptor.getTiddlerRevisionListCallback,context);
};
ccTiddlyAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
list = [];
var r = responseText;
if(r != '-') {
var revs = r.split('\n');
var list = [];
for(var i=0; i<revs.length; i++) {
var parts = revs[i].split(' ');
if(parts.length>1) {
var tiddler = new Tiddler(context.tiddler.title);
tiddler.modified = Date.convertFromYYYYMMDDHHMM(parts[0]);
tiddler.fields['server.page.revision'] = String(parts[1]);
tiddler.fields['server.page.version'] = tiddler.fields['server.page.revision'];//!! here temporarily for compatibility
list.push(tiddler);
}
}
}
context.revisions = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
ccTiddlyAdaptor.prototype.putTiddler = function(tiddler,context,callback)
{
context = this.setContext(context,userParams,callback);
var title = encodeURIComponent(tiddler.title);
var host = this && this.host ? this.host : ccTiddlyAdaptor.fullHostName(tiddler.fields['server.host']);
var uriTemplate = '%0RPC2/';
var uri = uriTemplate.format([host,title]);
context.tiddler = tiddler;
context.tiddler.fields['server.host'] = ccTiddlyAdaptor.minHostName(host);
context.tiddler.fields['server.type'] = ccTiddlyAdaptor.serverType;
var req =doHttp('POST',uri,payload,null,this.username,this.password,ccTiddlyAdaptor.putTiddlerCallback,tiddler.text);
return typeof req == 'string' ? req : true;
};
ccTiddlyAdaptor.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);
};
ccTiddlyAdaptor.prototype.close = function() {return true;};
config.adaptors[ccTiddlyAdaptor.serverType] = ccTiddlyAdaptor;
} // end of 'install only once'
//}}}
Tiddlers tagged {{{systemServer}}} wrap up all the connection details of a particular server so that they can be accessed quickly.
A list of available {{{systemServer}}} tiddlers is presented at the start of the ImportTiddlers macro. Selecting one of them pre-selects the relevant fields in the wizard. After a successful import operation, ImportTiddlers also offers the opportunity to automatically create a {{{systemServer}}} tiddler with the details of the server that was used. {{{systemServer}}} tiddlers are also used by the [[syncing]] command.
Here's an example {{{systemServer}}} tiddler:
<<<
|''Description:''|My example server|
|''Type:''|mediawiki|
|''URL:''|http://www.myexampleserver.org/x/|
|''Workspace:''|Main|
|''~TiddlerFilter:''|[tags[important unpluggable]]|
<<<
The fields are as follows:
|!Field |!Description |!Status |
|Description |Brief description of the server |Optional |
|Type |Type of server connection eg {{{file}}} or {{{mediawiki}}} |Optional - defaults to {{{file}}} |
|URL |Host URL of the server |Mandatory |
|Workspace |Name of the workspace |Optional |
|TiddlerFilter |Specifies which tiddlers are to be imported |Optional |