Martin's wiki  Martin Budden's plugins and extensions for ~TiddlyWiki
Martin's wiki  Martin Budden's plugins and extensions for ~TiddlyWiki

Home
Welcome.

This is where I post TiddlyWiki macros, plugins and other extensions to make them available to other TiddlyWiki users.
Formatter PluginDescription
ExampleFormatterPluginExample empty formatter. You can use this as a template to write your own formatter
CreoleFormatterPluginAllows Tiddlers to use Creole text formatting
ConfluenceFormatterPluginAllows Tiddlers to use Confluence text formatting
JSPWikiFormatterPluginAllows Tiddlers to use JSPWiki text formatting
MediaWikiFormatterPluginAllows Tiddlers to use MediaWiki (WikiPedia) text formatting
PmWikiFormatterPluginAllows Tiddlers to use PmWiki text formatting
PBWikiFormatterPluginAllows Tiddlers to use PBWiki text formatting
SocialtextFormatterPluginAllows Tiddlers to use Socialtext text formatting
TracFormatterPluginAllows Tiddlers to use Trac text formatting
TWikiFormatterPluginAllows Tiddlers to use TWiki text formatting
WikispacesFormatterPluginAllows Tiddlers to use Wikispaces text formatting

Adaptor PluginDescription
ExampleAdaptorPluginExample empty adaptor. You can use this as a template to write your own adaptor
ccTiddlyAdaptorPluginAdaptor for moving and converting data to and from ccTiddly wikis
JSPWikiAdaptorPluginAdaptor for moving and converting data to and from JSP Wikis
MediaWikiAdaptorPluginAdaptor for moving and converting data from MediaWikis
SocialtextAdaptorPluginAdaptor for moving and converting data to and from Socialtext Wikis
TWikiAdaptorPluginAdaptor for moving and converting data to and from TWikis


PluginDescription
ExamplePluginExample empty plugin. You can use this as a template to write your own plugin
DisableWikiLinksPluginAllows you to disable TiddlyWiki's automatic linking of WikiWords
DisableStrikeThroughPluginAllows you to disable TiddlyWiki's strikethrough formatting
SHA-1UnwoundPluginFaster wersion of SHA-1 with unwound loops
CryptoTEAPluginTEA (Tiny Encryption Algorithm) and supporting Cryptographic functions
EncryptionCommandsPluginUse this in association with CryptoTEAPlugin to encrypt individual tiddlers


See http://solarsystem.tiddlypedia.com and http://nordic.tiddlypedia.com for examples of TiddlyWikis using Wikipedia format and content.

See Experimental for plugins under development.

© 2006,2007 Martin Budden
TiddlyWiki 2.4.0 (beta 2)

<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity:60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0em 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0em 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
.wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0em;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0em 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0em 1em;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0em 0.25em; padding:0em 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>
<!--}}}-->
To get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:
* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* MainMenu: The menu (usually on the left)
* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These InterfaceOptions for customising TiddlyWiki are saved in your browser

Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)

<<option txtUserName>>
<<option chkSaveBackups>> SaveBackups
<<option chkAutoSave>> AutoSave
<<option chkRegExpSearch>> RegExpSearch
<<option chkCaseSensitiveSearch>> CaseSensitiveSearch
<<option chkAnimate>> EnableAnimations

----
Also see AdvancedOptions
<<importTiddlers>>
/*{{{*/
#contentWrapper {display:block;}
#splashScreen {display:none;}
/*}}}*/
/***
|''Name:''|AdaptorCommandsPlugin|
|''Description:''|Commands to access hosted TiddlyWiki data|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#AdaptorCommandsPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/AdaptorCommandsPlugin.js |
|''Version:''|0.5.5|
|''Date:''|Aug 23, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.2.0|
***/

//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.AdaptorCommandsPlugin) {
version.extensions.AdaptorCommandsPlugin = {installed:true};
function getServerType(fields)
{
	if(!fields)
		return null;
	var serverType = fields['server.type'];
	if(!serverType)
		serverType = fields['wikiformat'];
	if(!serverType)
		serverType = config.defaultCustomFields['server.type'];
	return serverType;
}

function invokeAdaptor(fnName,param1,param2,context,userParams,callback,fields)
{
	var serverType = getServerType(fields);
	if(!serverType)
		return null;
	var adaptor = new config.adaptors[serverType];
	if(!adaptor)
		return false;
	if(!config.adaptors[serverType].prototype[fnName])
		return false;
	adaptor.openHost(fields['server.host']);
	adaptor.openWorkspace(fields['server.workspace']);
	if(param1)
		var ret = param2 ? adaptor[fnName](param1,param2,context,userParams,callback) : adaptor[fnName](param1,context,userParams,callback);
	else
		ret = adaptor[fnName](context,userParams,callback);
	//adaptor.close();
	//delete adaptor;
	return ret;
}

function isAdaptorFunctionSupported(fnName,fields)
{
	var serverType = getServerType(fields);
	if(!serverType || !config.adaptors[serverType])
		return false;
	var fn = config.adaptors[serverType].prototype[fnName];
	return fn ? true : false;
}

config.commands.getTiddler = {};
merge(config.commands.getTiddler,{
	text: "get",
	tooltip:"Download this tiddler",
	readOnlyText: "get",
	readOnlyTooltip: "Download this tiddler",
	done: "Tiddler downloaded"
	});

config.commands.getTiddler.isEnabled = function(tiddler)
{
	return isAdaptorFunctionSupported('getTiddler',tiddler.fields);
};

config.commands.getTiddler.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(tiddler) {
		var fields = tiddler.fields;
	} else {
		fields = String(document.getElementById(story.idPrefix + title).getAttribute("tiddlyFields"));
		fields = fields ? fields.decodeHashMap() : null;
	}
	return invokeAdaptor('getTiddler',title,null,null,null,config.commands.getTiddler.callback,fields);
};

config.commands.getTiddler.callback = function(context,userParams)
{
	if(context.status) {
		var tiddler = context.tiddler;
		store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
		story.refreshTiddler(tiddler.title,1,true);
		displayMessage(config.commands.getTiddler.done);
	} else {
		displayMessage(context.statusText);
	}
};

config.commands.putTiddler = {};
merge(config.commands.putTiddler,{
	text: "put",
	tooltip: "Upload this tiddler",
	hideReadOnly: true,
	done: "Tiddler uploaded"
	});

config.commands.putTiddler.isEnabled = function(tiddler)
{
	return tiddler && tiddler.isTouched() && isAdaptorFunctionSupported('putTiddler',tiddler.fields);
};

config.commands.putTiddler.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(!tiddler)
		return false;
	return invokeAdaptor('putTiddler',tiddler,null,null,null,config.commands.putTiddler.callback,tiddler.fields);
};

config.commands.putTiddler.callback = function(context,userParams)
{
	if(context.status) {
		store.fetchTiddler(context.title).clearChangeCount();
		displayMessage(config.commands.putTiddler.done);
	} else {
		displayMessage(context.statusText);
	}
};

config.commands.revisions = {};
merge(config.commands.revisions,{
	text: "revisions",
	tooltip: "View another revision of this tiddler",
	loading: "loading...",
	done: "Revision downloaded",
	revisionTooltip: "View this revision",
	popupNone: "No revisions"});

config.commands.revisions.isEnabled = function(tiddler)
{
	return isAdaptorFunctionSupported('getTiddlerRevisionList',tiddler.fields);
};

config.commands.revisions.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	userParams = {};
	userParams.tiddler = tiddler;
	userParams.src = src;
	userParams.dateFormat = 'YYYY mmm 0DD 0hh:0mm';
	var revisionLimit = 10;
	if(!invokeAdaptor('getTiddlerRevisionList',title,revisionLimit,null,userParams,config.commands.revisions.callback,tiddler.fields))
		return false;
	event.cancelBubble = true;
	if(event.stopPropagation)
		event.stopPropagation();
	return true;
};

config.commands.revisions.callback = function(context,userParams)
// The revisions are returned as tiddlers in the context.revisions array
{
	var revisions = context.revisions;
	popup = Popup.create(userParams.src);
	Popup.show(popup,false);
	if(revisions.length==0) {
		createTiddlyText(createTiddlyElement(popup,'li',null,'disabled'),config.commands.revisions.popupNone);
	} else {
		revisions.sort(function(a,b) {return a.modified < b.modified ? +1 : -1;});
		for(var i=0; i<revisions.length; i++) {
			var tiddler = revisions[i];
			var modified = tiddler.modified;
			var revision = tiddler.fields['server.page.revision'];
			var btn = createTiddlyButton(createTiddlyElement(popup,'li'),
					modified.formatString(userParams.dateFormat) + ' r:' + revision,
					config.commands.revisions.revisionTooltip,
					function() {
						config.commands.revisions.getTiddlerRevision(this.getAttribute('tiddlerTitle'),this.getAttribute('tiddlerModified'),this.getAttribute('tiddlerRevision'),this);
						return false;
						},
					'tiddlyLinkExisting tiddlyLink');
			btn.setAttribute('tiddlerTitle',userParams.tiddler.title);
			btn.setAttribute('tiddlerRevision',revision);
			btn.setAttribute('tiddlerModified',modified.convertToYYYYMMDDHHMM());
			if(userParams.tiddler.fields['server.page.revision'] == revision || (!userParams.tiddler.fields['server.page.revision'] && i==0))
				btn.className = 'revisionCurrent';
		}
	}
};

config.commands.revisions.getTiddlerRevision = function(title,modified,revision)
{
	var tiddler = store.fetchTiddler(title);
	var context = {};
	context.modified = modified;
	return invokeAdaptor('getTiddlerRevision',title,revision,context,null,config.commands.revisions.getTiddlerRevisionCallback,tiddler.fields);
};

config.commands.revisions.getTiddlerRevisionCallback = function(context,userParams)
{
	if(context.status) {
		var tiddler = context.tiddler;
		store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields);
		story.refreshTiddler(tiddler.title,1,true);
		displayMessage(config.commands.revisions.done);
	} else {
		displayMessage(context.statusText);
	}
};

config.commands.saveTiddlerAndPut = {};
merge(config.commands.saveTiddlerAndPut,{
	text: "done",
	tooltip: "Save this tiddler and upload",
	hideReadOnly: true,
	done: "Tiddler uploaded"
	});

config.commands.saveTiddlerAndPut.handler = function(event,src,title)
{
	var newTitle = story.saveTiddler(title,event.shiftKey);
	if(newTitle)
		story.displayTiddler(null,newTitle);
	return config.commands.putTiddler.handler(event,src,newTitle);
};

config.commands.saveTiddlerHosted = {};
merge(config.commands.saveTiddlerHosted,{
	text: "done",
	tooltip: "Save changes to this tiddler",
	hideReadOnly: true,
	done: "done"
	});
	
config.commands.saveTiddlerHosted.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(!tiddler)
		return false;
	return invokeAdaptor('saveTiddlerHosted',tiddler,null,null,null,config.commands.saveTiddlerHosted.callback,tiddler.fields);
};

config.commands.saveTiddlerHosted.callback = function(context,userParams)
{
	if(context.status) {
		displayMessage(config.commands.saveTiddlerHosted.done);
	} else {
		displayMessage(context.statusText);
	}
};
}//# end of 'install only once'
//}}}
/***
|''Name:''|AdaptorMacrosPlugin|
|''Description:''|Commands to access hosted TiddlyWiki data|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#AdaptorMacrosPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/AdaptorMacrosPlugin.js |
|''Version:''|0.3.8|
|''Date:''|Aug 23, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.2.0|
***/

//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.AdaptorMacrosPlugin) {
version.extensions.AdaptorMacrosPlugin = {installed:true};

// Return an array of tiddler titles that are in the given workspace on the host
TiddlyWiki.prototype.getHostedTiddlers = function(host,workspace)
{
	var results = [];
	if(!this.hostedTiddlers || !this.hostedTiddlers[host])
		return results;
	var tiddlers = this.hostedTiddlers[host][workspace];
	if(tiddlers) {
		for(var i=0; i<tiddlers.length; i++) {
			results.push(tiddlers[i].title);
		}
	}
	return results;
};

config.macros.viewTiddlerFields = {};
config.macros.viewTiddlerFields.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	if(tiddler instanceof Tiddler) {
		var value = '';
		var comma = '';
		for(i in tiddler.fields) {
			if (!i.match(/^temp[\._]/)) {
				value += comma + i + '=' + tiddler.fields[i];
				comma = ', ';
			}
		}
		if(tiddler.created)
			value += comma + 'created=' + tiddler.created.convertToYYYYMMDDHHMM();
		if(tiddler.modified)
			value += ', modified=' + tiddler.modified.convertToYYYYMMDDHHMM();
		if(tiddler.modifier)
			value += ', modifier=' + tiddler.modifier;
		value += ', touched=' + (tiddler.isTouched() ? 'true' : 'false');
		highlightify(value,place,highlightHack,tiddler);
	}
};

config.macros.list.updatedOffline = {};
config.macros.list.updatedOffline.handler = function(params)
{
	var results = [];
	store.forEachTiddler(function(title,tiddler) {
		if(tiddler.fields['server.host'] && tiddler.isTouched())
			results.push(tiddler);
		});
	results.sort();
	return results;
};

config.macros.list.workspaceTiddlers = {};
config.macros.list.workspaceTiddlers.prompt = "List Tiddlers in the workspace";
config.macros.list.workspaceTiddlers.handler = function(params,wikifier,paramString,tiddler)
{
	var customFields = getParam(params,'fields',false);
	if(!customFields)
		customFields = config.defaultCustomFields;
	return store.getHostedTiddlers(customFields['server.host'],customFields['server.workspace']);
};

config.macros.updateWorkspaceTiddlerList = {};
merge(config.macros.updateWorkspaceTiddlerList,{
	label: "update tiddler list",
	prompt: "Update list of tiddlers in workspace",
	done: "List updated"});

config.macros.updateWorkspaceTiddlerList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	params = paramString.parseParams('anon',null,true,false,false);
	var customFields = getParam(params,'fields',false);
	if(!customFields)
		customFields = String.encodeHashMap(config.defaultCustomFields);
	var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
	btn.setAttribute('customFields',customFields);
	btn.setAttribute('title',tiddler.title);
};

config.macros.updateWorkspaceTiddlerList.onClick = function(e)
{
	clearMessage();
	var customFields = this.getAttribute("customFields");
	var fields = customFields.decodeHashMap();
	var userParams = {host:fields['server.host'],workspace:fields['server.workspace'],title:this.getAttribute("title")};
	return invokeAdaptor('getTiddlerList',null,null,null,userParams,config.macros.updateWorkspaceTiddlerList.callback,fields);
};

config.macros.updateWorkspaceTiddlerList.callback = function(context,userParams)
{
	if(context.status) {
		if(!store.hostedTiddlers)
			store.hostedTiddlers = {};
		if(!store.hostedTiddlers[userParams.host])
			store.hostedTiddlers[userParams.host] = {};
		store.hostedTiddlers[userParams.host][userParams.workspace] = context.tiddlers;
		displayMessage(config.macros.updateWorkspaceTiddlerList.done);
		story.displayTiddler(null,userParams.title);
		story.refreshTiddler(userParams.title,1,true);
	} else {
		displayMessage(context.statusText);
	}
};


config.macros.updateWorkspaceList = {};
merge(config.macros.updateWorkspaceList,{
	label: "update workspace list",
	prompt: "Update list of workspaces",
	done: "List updated"});

config.macros.updateWorkspaceList.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
	params = paramString.parseParams('anon',null,true,false,false);
	var customFields = getParam(params,'fields',false);
	if(!customFields)
		customFields = String.encodeHashMap(config.defaultCustomFields);
	var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
	btn.setAttribute('customFields',customFields);
	btn.setAttribute('title',tiddler.title);
};

config.macros.updateWorkspaceList.onClick = function(e)
{
	clearMessage();
	var customFields = this.getAttribute("customFields");
	var fields = customFields.decodeHashMap();
	var userParams = {host:fields['server.host'],callback:config.macros.updateWorkspaceList.callback};
	return invokeAdaptor('getWorkspaceList',context,fields);
};

config.macros.updateWorkspaceList.callback = function(context,userParams)
{
	if(context.status) {
		displayMessage(config.macros.updateWorkspaceList.done);
		for(var i=0; i<context.workspaces.length; i++) {
			displayMessage("workspace:"+context.workspaces[i]);
		}
	} else {
		displayMessage(context.statusText);
	}
};

} // end of 'install only once'
//}}}
|!Adaptor Plugin|!Description|
|[[ExampleAdaptorPlugin]]|Example empty adaptor. You can use this as a template to write your own adaptor|
|[[ccTiddlyAdaptorPlugin]]|Adaptor for moving and converting data to and from ccTiddly wikis|
|[[JSPWikiAdaptorPlugin]]|Adaptor for moving and converting data to and from JSP Wikis|
|[[MediaWikiAdaptorPlugin]]|Adaptor for moving and converting data from MediaWikis|
|[[SocialtextAdaptorPlugin]]|Adaptor for moving and converting data to and from Socialtext Wikis|
|[[TWikiAdaptorPlugin]]|Adaptor for moving and converting data to and from TWikis|
|!Format|!Markup|!Example|
|Bold|{{{''Bold''}}} (2 single quotes)|''Bold''|
|Italic|{{{//Italic//}}}|//Italic//|
|Bold Italic|{{{''//Bold Italic//''}}}|''//Bold Italic//''|
|Underlined|{{{__Underline__}}}(2 underscores)|__Underlined__|
|Strikethough|{{{--Strikethrough--}}}<br />{{{--}}} replaced {{{==}}} for Stikethrough in TiddlyWiki 2.1|--Strikethrough--|
|Superscript|{{{Text^^Superscript^^}}}|Text^^Superscript^^|
|Subscript|{{{Text~~Subscript~~}}}|Text~~Subscript~~|
|Monospaced text|<html><code>{{{Monospaced}}}</code></html>|{{{Monospaced}}}|
|Monospaced multiline block|Put <html><code>{{{</code></html> and <html><code>}}}</code></html> on their own lines|<html><pre>{{{<br/>Monospaced<br/>Multi-line<br/>Block<br/>}}}</pre></html>|
|Highlight|{{{@@Highlight@@}}}|@@Highlight@@|
|Color|{{{@@color(green):green text@@}}}|@@color(green):green text@@ |
|~|{{{@@bgcolor(green):text@@}}}|@@bgcolor(green):text@@ |
|~|{{{@@bgcolor(#3399ff):text@@}}}|@@bgcolor(#3399ff):text@@|
|~|{{{@@bgcolor(#39f):text@@}}}|@@bgcolor(#39f):text@@|
|CSS Extended Highlights|{{{@@some css;Highlight@@}}}<br />For backwards compatibility, the following highlight syntax is also accepted:<br />{{{@@bgcolor(#ff0000):color(#ffffff):red coloured@@}}}|@@background-color:#ff0000;color:#ffffff;red coloured@@<br /><<slider AtEg ./atEg 'Extended example ...'>>|
|Custom CSS Class|<html><code>{{wrappingClass{Text that is now accentuated}}}</code></html><br />By default, the text is placed in a <span>. To use a <div> instead, insert a line break before the text (after the single {)<br />In the CSS:<br />{{{.wrappingClass {color: red;} }}}|Add .wrappingClass to StyleSheet|
|Any HTML|{{{<html><span>any</span><br />}}}<br />{{{<b>valid</b> <em>xhtml</em></html>}}}|<html><span>any</span><br /><b>valid</b> <em>xhtml</em></html>|
PageTemplate
|>|>|SiteTitle - SiteSubtitle|
|MainMenu|DefaultTiddlers<br /><br /><br /><br />ViewTemplate<br /><br />EditTemplate|SideBarOptions|
|~|~|OptionsPanel|
|~|~|AdvancedOptions|
|~|~|<<tiddler Configuration.SideBarTabs>>|

''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint

SiteUrl
SideBarTabs
|[[Timeline|TabTimeline]]|[[All|TabAll]]|[[Tags|TabTags]]|>|>|[[More|TabMore]] |
|>|>||[[Missing|TabMoreMissing]]|[[Orphans|TabMoreOrphans]]|[[Shadowed|TabMoreShadowed]]|
/***
|''Name:''|ConfluenceFormatterPlugin|
|''Description:''|Allows Tiddlers to use Confluence text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ConfluenceFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/ConfluenceFormatterPlugin.js |
|''Version:''|0.1.3|
|''Date:''|Dec 8, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

This is the ConfluenceFormatterPlugin, which allows you to insert [[Confluence|http://confluence.atlassian.com/renderer/notationhelp.action?section=all]] formated
text into a TiddlyWiki. See also http://confluence.atlassian.com/display/DOC/Confluence+Notation+Guide+Overview

The aim is not to fully emulate Confluence, but to allow you to work with Confluence content off-line
and then paste the content into your Confluence wiki later on, with the expectation that only minor
edits will be required.

To use Confluence format in a Tiddler, tag the Tiddler with ConfluenceFormat.  or set the tiddler's {{{wikiformat}}} extended field to {{{confluence}}}.

Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev

***/

//{{{
// Ensure that the ConfluenceFormatterPlugin is only installed once.
if(!version.extensions.ConfluenceFormatterPlugin) {
version.extensions.ConfluenceFormatterPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('ConfluenceFormatterPlugin requires TiddlyWiki 2.1 or later.');}

confluenceFormatter = {}; // 'namespace' for local functions

confluenceDebug = function(out,str)
{
	createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
	createTiddlyElement(out,'br');
};

confluenceFormatter.createSpan = function(w)
{
	createTiddlyElement(w.output,'span').innerHTML = this.text;
};

confluenceFormatter.macros = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
		var lm1 = lookaheadMatch[1];
		var lm2 = lookaheadMatch[2];
		switch(lm1) {
		case 'anchor':
			a = createTiddlyElement(w.output,'a');// drop anchor
			t = w.tiddler ? w.tiddler.title + ':' : '';
			a.setAttribute('name',t + lm2);
			break;
		case 'color':
			var e = createTiddlyElement(w.output,'span');
			e.style.color = lm2;
			w.subWikifyTerm(e,/(\{color\})/mg);
			return;
			break;
		case 'excerpt':
			break;
		case 'noformat':
		case 'code':
			break;
		case 'panel':
		case 'note':
		case 'warning':
		case 'info':
		case 'tip':
			var d = createTiddlyElement(w.output,'div');
			var dp = createTiddlyElement(d,'div',null,'informationMacroPadding');
			var t = createTiddlyElement(dp,'table',null,lm1+'Macro');
			t.cellpadding='5';t.width='85%';t.cellspacing='0';t.border='0';
			var tr = createTiddlyElement(t,'tr');
			var td  = createTiddlyElement(tr,'td');
			td.width='16';td.valign='top';
			var img = createTiddlyElement(td,'img');
			img.src='/confluence/images/icons/emoticons/forbidden.gif';
			img.width='16';img.height='16';img.align='absmiddle';img.alt='';img.border='0';
			td  = createTiddlyElement(tr,'td');
			confluenceFormatter.subWikify(w,td,lm2);//'*'+lm1+'*<br/><br/>';
			w.subWikifyTerm(td,new RegExp('(\{'+lm1+'\})','mg'));
			return;
			break;
		case 'section':
			// includes columns
			break;
		default:
			w.outputText(w.output,w.matchStart,w.nextMatch);
			return;
		}
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

confluenceFormatter.subWikify = function(w,out,src)
{
	var oldSource = w.source;
	var nextMatch = w.nextMatch;
	w.source = src;
	w.nextMatch = 0;
	w.subWikifyUnterm(out);
	w.source = oldSource;
	w.nextMatch = nextMatch;
};

confluenceFormatter.singleCharFormat = function(w)
{
	this.lookaheadRegExp.lastIndex = w.matchStart;
	var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
	if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[0].substr(lookaheadMatch[0].length-2,1) != ' ') {
		w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
		w.nextMatch = this.lookaheadRegExp.lastIndex;
	} else {
		w.outputText(w.output,w.matchStart,w.nextMatch);
	}
};

confluenceFormatter.setAttributesFromParams = function(e,p)
{
	var re = /\s*(.*?)=(?:(?:"(.*?)")|(?:'(.*?)')|((?:\w|%|#)*))/mg;
	var match = re.exec(p);
	while(match) {
		var s = match[1].unDash();
		if(s=='bgcolor') {
			s = 'backgroundColor';
		}
		try {
			if(match[2]) {
				e.setAttribute(s,match[2]);
			} else if(match[3]) {
				e.setAttribute(s,match[3]);
			} else {
				e.setAttribute(s,match[4]);
			}
		}
		catch(ex) {}
		match = re.exec(p);
	}
};

config.confluenceFormatters = [
{
	name: 'confluenceHeading',
	match: '^h[1-6](?:(?:\\(.*?\\))|(?:\\{.*?\\})|(?:\\[.*?\\]))?\\. ',
	lookaheadRegExp: /^h([1-6])(?:(?:\((.*?)\))|(?:\{(.*?)\})|(?:\[(.*?)\]))?\. /mg,
	termRegExp: /(\n)/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			w.subWikifyTerm(createTiddlyElement(w.output,'h'+lookaheadMatch[1]),this.termRegExp);
		}
	}
},
{
	name: 'confluenceTable',
	match: '^\\|(?:(?:.|\n)*)\\|$',
	lookaheadRegExp: /^\|(?:(?:.|\n)*)\|$/mg,
	cellRegExp: /(?:\|(?:[^\|]*)\|)(\n|$)?/mg,
	cellTermRegExp: /((?:\x20*)\|)/mg,
	handler: function(w)
	{
		var table = createTiddlyElement(w.output,'table');
		var rowContainer = createTiddlyElement(table,'tbody');
		var prevColumns = [];
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var r = this.rowHandler(w,createTiddlyElement(rowContainer,'tr'),prevColumns);
			if(!r) {
				w.nextMatch++;
				break;
			}
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	},
	rowHandler: function(w,e,prevColumns)
	{
		this.cellRegExp.lastIndex = w.nextMatch;
		var cellMatch = this.cellRegExp.exec(w.source);
		while(cellMatch && cellMatch.index == w.nextMatch) {
			w.nextMatch++;
			var cell = createTiddlyElement(e,'td');
			w.subWikifyTerm(cell,this.cellTermRegExp);
			if(cellMatch[1]) {
				// End of row
				w.nextMatch = this.cellRegExp.lastIndex;
				return true;
			} else {
				// Cell
				w.nextMatch--;
			}
			this.cellRegExp.lastIndex = w.nextMatch;
			cellMatch = this.cellRegExp.exec(w.source);
		}
		return false;
	}
},
{
	name: 'confluenceList',
	match: '^[#\\*\\-]+ ',
	lookaheadRegExp: /^(?:(#)|(\*)|(\-))+ /mg,
	termRegExp: /(\n)/mg,
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0, currType = null;
		var listLevel, listType;
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			var style = lookaheadMatch[3] ? 'square' : null;
			listType = lookaheadMatch[1] ? 'ol' : 'ul';
			listLevel = lookaheadMatch[0].length;
			w.nextMatch += listLevel;
			if(listLevel > currLevel){
				for(var i=currLevel; i<listLevel; i++) {
					stack.push(createTiddlyElement(stack[stack.length-1],listType));
				}
			} else if(listLevel < currLevel) {
				for(i=currLevel; i>listLevel; i--) {
					stack.pop();
				}
			} else if(listLevel == currLevel && listType != currType) {
				stack.pop();
				stack.push(createTiddlyElement(stack[stack.length-1],listType));
			}
			currLevel = listLevel;
			currType = listType;
			var e = createTiddlyElement(stack[stack.length-1],'li');
			e.style[config.browser.isIE ? 'list-style-type' : 'listStyleType'] = style;
			w.subWikifyTerm(e,this.termRegExp);
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	}
},
{
	name: 'confluenceBlockQuote',
	match: '^bq(?:(?:\\(.*?\\))|(?:\\{.*?\\})|(?:\\[.*?\\]))?\\. ',
	lookaheadRegExp: /^bq(?:(?:\((#?)(.*?)\))|(?:\{(.*?)\})|(?:\[(.*?)\]))?\. /mg,
	termRegExp: /(\n)/mg,
	element: 'blockquote',
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var e = createTiddlyElement(w.output,this.element);
			w.subWikifyTerm(e,this.termRegExp);
		}
	}
},
{
	name: 'confluenceQuote',
	match: '^{quote}\\n',
	termRegExp: /(^\{quote\}[\n|$])/mg,
	element: 'blockquote',
	handler: config.formatterHelpers.createElementAndWikify
},
{
	name: 'confluenceNoformat',
	match: '^{noformat}\\n',
	lookaheadRegExp: /\{noformat\}((?:.|\n)*?)\{noformat\}/mg,
	element: 'pre',
	handler: config.formatterHelpers.enclosedTextHelper
},
{
	name: 'confluenceRule',
	match: '^---+$\\n?',
	handler: function(w)
	{
		createTiddlyElement(w.output,'hr');
	}
},
{
	name: 'macro',
	match: '<<',
	lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
			invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
		}
	}
},
{
	name: 'confluenceExternalLink',
	match: '(?:".*?" ?):?[a-z]{2,8}:',
	lookaheadRegExp: /(?:\"(.*?)(?:\((.*?)\))?\" ?):?(.*?)(?=\s|$)/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[3];
			var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
			var e = createExternalLink(w.output,link);
			if(lookaheadMatch[2])
				e.title = lookaheadMatch[2];
			createTiddlyText(e,text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},
{
	name: 'confluenceUrlLink',
	match: config.textPrimitives.urlPattern,
	handler: function(w)
	{
		w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
	}
},
{
	name: 'confluenceExplicitLink',
	match: '\\[',
	lookaheadRegExp: /\[([^\|\]]*?)(?:(?:\])|(?:\|(.*?))\])/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
			var text = lookaheadMatch[1];
			var link = lookaheadMatch[2] ? lookaheadMatch[2] : text;
			var tip = lookaheadMatch[3] ? lookaheadMatch[3] : text;
			var e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
			confluenceFormatter.subWikify(w,e,text);
			//createTiddlyText(e,text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
	}
},
{
	name: 'confluenceImage',
	match: '!.*?!',
	lookaheadRegExp: /!(.*?)(?:\((.*?)\))?!/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var img = createTiddlyElement(w.output,'img');
			img.src = lookaheadMatch[1];
			if(lookaheadMatch[2]) {
				img.title = lookaheadMatch[2];
			}
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},
{
	name: 'confluenceBold',
	match: '\\*(?![\\s\\*])',
	lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[\s\._\-])/mg,
	termRegExp: /((?!\s)\*(?=[\s\.\-_]))/mg,
	element: 'strong',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceItalic',
	match: '_(?![\\s_])',
	lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[\s\.\*\-])/mg,
	termRegExp: /((?!\s)_(?=[\s\.\*\-]))/mg,
	element: 'em',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceUnderline',
	match: '\\+(?![\\s|\\+])',
	lookaheadRegExp: /\+(?!\s)(?:.*?)(?!\s)\+(?=\s)/mg,
	termRegExp: /((?!\s)\+(?=\s))/mg,
	element: 'u',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceStrike',
	match: '-(?![\\s\\-])',
	lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[\s\.\*_])/mg,
	termRegExp: /((?!\s)-(?=[\s\.\*_]))/mg,
	element: 'strike',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceSuperscript',
	match: '\\^(?![\\s|\\^])',
	lookaheadRegExp: /\^(?!\s)(?:.*?)(?!\s)\^(?=\s)/mg,
	termRegExp: /((?!\s)\^(?=\s))/mg,
	element: 'sup',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceSubscript',
	match: '~(?![\\s|~])',
	lookaheadRegExp: /~(?!\s)(?:.*?)(?!\s)~(?=\s)/mg,
	termRegExp: /((?!\s)~(?=\s))/mg,
	element: 'sub',
	handler: confluenceFormatter.singleCharFormat
},
{
	name: 'confluenceCitation',
	match: '\\?\\?',
	termRegExp: /(\?\?)/mg,
	element: 'cite',
	handler: config.formatterHelpers.createElementAndWikify
},
{
	name: 'confluenceMonospacedByChar',
	match: '\\{\\{',
	lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
	element: 'code',
	handler: config.formatterHelpers.enclosedTextHelper
},
{
	name: 'confluenceParagraph',
	match: '\\n{2,}',
	handler: function(w)
	{
		createTiddlyElement(w.output,'p');
	}
},
{
	name: 'confluenceExplicitLineBreak',
	match: '<br ?/?>|\\\\|\\n',
	handler: function(w)
	{
		createTiddlyElement(w.output,'br');
	}
},
{
	name: 'confluenceComment',
	match: '<!\\-\\-',
	lookaheadRegExp: /<!\-\-((?:.|\n)*?)\-\-!>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},
{
	name: 'confluenceMdash',
	match: '---',
	handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&mdash;';}
},
{
	name: 'confluenceNdash',
	match: '--',
	handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&ndash;';}
},
{
	name: 'confluenceTrademark',
	match: '\\(TM\\)',
	handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&trade;';}
},
{
	name: 'confluenceRegistered',
	match: '\\(R\\)',
	text: '&reg;',
	handler: confluenceFormatter.createSpan
	//handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&reg;';}
},
{
	name: 'confluenceCopyright',
	match: '\\(C\\)',
	handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&copy;';}
},
{
	name: 'confluenceElipsis',
	match: '\\.\\.\\.',
	handler: function(w) {createTiddlyElement(w.output,'span').innerHTML = '&hellip;';}
},
{
	name: 'confluenceMacros',
	match: '\\{(?:[a-z]{2,16})(?:: ?.*?)?\\}',
	lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
	handler: confluenceFormatter.macros
},
{
	name: 'confluenceHtmlEntitiesEncoding',
	match: '&#?[a-zA-Z0-9]{2,8};',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = w.matchText;
	}
},
{
	name: 'confluenceHtmlTag',
	match: "<(?:[a-zA-Z]{2,}|a)(?:\\s*(?:(?:.*?)=[\"']?(?:.*?)[\"']?))*?>",
	lookaheadRegExp: /<([a-zA-Z]+)((?:\s+(?:.*?)=["']?(?:.*?)["']?)*?)?\s*(\/)?>(?:\n?)/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var e =createTiddlyElement(w.output,lookaheadMatch[1]);
			if(lookaheadMatch[2]) {
				confluenceFormatter.setAttributesFromParams(e,lookaheadMatch[2]);
			}
			if(lookaheadMatch[3]) {
				w.nextMatch = this.lookaheadRegExp.lastIndex;// empty tag
			} else {
				w.subWikify(e,'</'+lookaheadMatch[1]+'>');
			}
		}
	}
}/*,
{
	name: 'confluenceMatchedQuotes',
	match: '(?=\s)"',
	lookaheadRegExp: /\"((?:.|\n)*?)\"/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			createTiddlyElement(w.output,'span').innerHTML = '&ldquo;' + lookaheadMatch[1] + '&rdquo;';
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
}*/
];

config.parsers.confluenceFormatter = new Formatter(config.confluenceFormatters);
config.parsers.confluenceFormatter.format = 'confluence';
config.parsers.confluenceFormatter.formatTag = 'ConfluenceFormat';
} // end of 'install only once'
//}}}
&copy; Martin Budden 2006,2007

This TiddlyWiki is published under a [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]].

This gives you the freedom to use it pretty much however you want, including for commercial purposes, as long as you keep the copyright notice. If you do use items from this page a link back to http://www.martinswiki.com/ is appreciated.
/***
|''Name:''|CreoleFormatterPlugin|
|''Description:''|Extension of TiddlyWiki syntax to support [[Creole|http://www.wikicreole.org/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#CreoleFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/CreoleFormatterPlugin.js |
|''Version:''|0.1.8|
|''Date:''|May 7, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

This is an early release of the CreoleFormatterPlugin, which extends the TiddlyWiki syntax to support Creole
text formatting. See [[testCreoleFormat]] for an example.

The Creole formatter is different from the other formatters in that Tiddlers are not required to be
tagged: instead the Creole format adds formatting that augments TiddlyWiki's format.

The Creole formatter adds the following:
# {{{**}}} for bold
# {{{=Heading 1=}}} with 1 to 6 equals signs for headings
# {{{[[link|title]]}}} format for links (rather than TW's {{{[[title|link]]}}}).

Since Creole augments rather than replaces TW's formatting there is a problem of how to resolve a prettyLink:
the formatter has some intelligence to determine if whether a link is a TW style link or a Creole style link.
Additionally a tiddler can be tagged 'titleThenLinkFormat' or 'linkThenTitleFormat' to force resolution one
way or the other.

See: http://www.wikicreole.org/wiki/Home

Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev

This is an early alpha release, with (at least) the following known issues:
# Creole image format not yet supported

***/

//{{{
// Ensure that the CreoleFormatterPlugin is only installed once.
if(!version.extensions.CreoleFormatterPlugin) {
version.extensions.CreoleFormatterPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1)) {
	alertAndThrow('CreoleFormatterPlugin requires TiddlyWiki 2.1 or later.');
}

creoleFormatter = {}; // 'namespace' for local functions

creoleFormatter.heading = {
	name: 'creoleHeading',
	match: '^={1,6}(?!=)',
	termRegExp: /(={0,6}\n+)/mg,
	handler: function(w) {w.subWikifyTerm(createTiddlyElement(w.output,'h' + w.matchLength),this.termRegExp);}
};

creoleFormatter.bold = {
	name: 'creoleBold',
	match: '\\*\\*',
	termRegExp: /(\*\*|(?=\n\n))/mg,
	element: 'strong',
	handler: config.formatterHelpers.createElementAndWikify
};

creoleFormatter.explicitLink = {
	name: 'creoleExplicitLink',
	match: '\\[\\[',
	lookaheadRegExp: /\[\[(.*?)(?:\|(.*?))?\]\]/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var e;
			var link = lookaheadMatch[1];
			var text = lookaheadMatch[2];
			if(text) {
				// both text and link defined, so try and workout which is which
				var wlRegExp = new RegExp(config.textPrimitives.wikiLink,'mg');
				wlRegExp.lastIndex = 0;
				if(w.tiddler.isTagged('titleThenLinkFormat')) {
					// format is [[text|link]]
					link = text;
					text = lookaheadMatch[1];
					e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else if(w.tiddler.isTagged('linkThenTitleFormat')) {
					// standard format is [[link|text]]
					e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else if(config.formatterHelpers.isExternalLink(link)) {
					e = createExternalLink(w.output,link);
				} else if(config.formatterHelpers.isExternalLink(text)) {
					link = text;
					text = lookaheadMatch[1];
					e = createExternalLink(w.output,link);
				} else if(store.tiddlerExists(link)) {
					e = createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else if(store.tiddlerExists(text)) {
					link = text;
					text = lookaheadMatch[1];
					e = createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else if(wlRegExp.exec(text)) {
					//text is a WikiWord, so assume its a tiddler link
					link = text;
					text = lookaheadMatch[1];
					e = createTiddlyLink(w.output,link,false,null,w.isStatic);
				} else {
					// assume standard link format
					e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
				}
			} else {
				text = link;
				e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
			}
			createTiddlyText(e,text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}//# end handler
};

creoleFormatter.replaceFormatters = function()
{
	// replace formatters where necessary
	for(var i=0; i<config.formatters.length; i++) {
		// replace formatters as required
		var name = config.formatters[i].name;
		if(name == 'prettyLink') {
			config.formatters[i] = creoleFormatter.explicitLink;
		} else if(name == 'italicByChar') {
			config.formatters[i].termRegExp = /(\/\/|(?=\n\n))/mg;
		} else if(name == 'list') {
			// require a space after the list character (required for '*' which otherwise clashes with bold
			config.formatters[i].match = '^[\\*#;:]+ ';
		}
	}
};
creoleFormatter.replaceFormatters();

// add new formatters
config.formatters.push(creoleFormatter.heading);
config.formatters.push(creoleFormatter.bold);

}// end of 'install only once'
//}}}
/***
|''Name:''|CryptoTEAPlugin|
|''Description:''|TEA (Tiny Encryption Algorithm) and supporting Cryptographic functions|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://martinswiki.com/#CryptoTEAPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/CryptoTEAPlugin.js |
|''Version:''|0.1.7|
|''Date:''|May 7, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.3|

Based on [[Movable Type Script|http://www.movable-type.co.uk/scripts/TEAblock.html]]
***/

//{{{
// Ensure that the Crypto TEA Plugin is only installed once.
if(!version.extensions.CryptoTEAPlugin) {
	version.extensions.CryptoTEAPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1) || (version.major == 2 && version.minor == 1 && version.revision <3 ))
	alertAndThrow('CryptoTEAPlugin requires TiddlyWiki 2.1.3 or later.');

Crypto.b64open =  "''Base64''\n/*{{{*/\n";
Crypto.b64close = "\n/*}}}*/\n''Base64''";
Crypto.b64code =  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
Crypto.salt = String.fromCharCode(138,200,184,222,198,210,113,77);
Crypto.iterationCount = 4;

Crypto.passphraseToKey = function(passphrase)
// Use an iterated SHA-1 hash of the salted passphrase as a reasonably good key
{
	postSalt = String.fromCharCode(23,160,248,216,146,5,102,239);
	var k = Crypto.sha1Str(Crypto.salt+passphrase+postSalt);
	for(var i = 1;i<Crypto.iterationCount;i++)
		k = Crypto.sha1(k,k.length);
	return k;
};

Crypto.base64armor = function(s)
{
	return Crypto.b64open + Crypto.base64encode(s) + Crypto.b64close;
};

Crypto.base64encode = function(s)
{
	b64code = Crypto.b64code;
	var line = '';
	var b64 = '';
	var maxLen4 = 60;
	var i;
	for(i=0;i<=s.length-3;i+=3) {
		if(line.length>maxLen4) {
			b64 += line + '\n';
			line = '';
		}
		line += b64code.charAt(s.charCodeAt(i)>>>2);
		line += b64code.charAt(((s.charCodeAt(i)&3)<<4) | (s.charCodeAt(i+1)>>>4));
		line += b64code.charAt(((s.charCodeAt(i+1)&0x0F)<< 2) | (s.charCodeAt(i+2)>>>6));
		line += b64code.charAt(s.charCodeAt(i+2)&0x3F);
	}
	if(i==s.length-1) {
		line += b64code.charAt(s.charCodeAt(i)>>>2);
		line += b64code.charAt((s.charCodeAt(i)&3)<<4);
		line += '==';
	} else if(i==s.length-2) {
		line += b64code.charAt(s.charCodeAt(i)>>>2);
		line += b64code.charAt(((s.charCodeAt(i)&3)<<4) | (s.charCodeAt(i+1)>>>4));
		line += b64code.charAt((s.charCodeAt(i+1)&0x0F)<<2);
		line += '=';
	}
	if(b64.length > maxLen4) {
		b64 += line + '\n';
		line = '';
	}
	b64 += line;
	return b64;
};

Crypto.base64decode = function(s)
{
	b64code = Crypto.b64code;
	var i;
	if((i=s.indexOf(Crypto.b64open)) >= 0)
		s = s.substring(i + Crypto.b64open.length,s.length);
	if((i=s.indexOf(Crypto.b64close)) >= 0)
		s = s.substring(0,i);
	for(i=0;i<s.length;i++) {
		if(b64code.indexOf(s.charAt(i)) != -1)
			break;
	}
	var j,c;
	var sg = 0;
	var n = 0;
	var b = new Array();
	var d = new Array();
	while(i<s.length) {
		for(j=0;j<4;) {
			if(i>=s.length) {
				if(j>0) {
					displayMessage('truncated');
					return b;
				}
				break;
			}
			c = b64code.indexOf(s.charAt(i));
			if(c>=0) {
				d[j++] = c;
			} else if(s.charAt(i)=='=') {
				d[j++] = 0;
				sg++;
			}
			i++;
		}
		if(j==4) {
			b[n++] = ((d[0]<<2) | (d[1]>>>4)) & 0xFF;
			if(sg<2) {
				b[n++] = ((d[1]<<4) | (d[2]>>>2)) & 0xFF;
				if(sg<1)
					b[n++] = ((d[2]<<6) | d[3]) & 0xFF;
			}
		}
	}
	var r = new Array(b.length);
	for(i=0;i<b.length;i++)
		r[i] = String.fromCharCode(b[i]);
	return r.join('');
};

Crypto.TEA = {};

Crypto.TEA.name = function()
{
	return 'TEA';
};

Crypto.TEA.base64encode = Crypto.base64armor;
Crypto.TEA.base64decode = Crypto.base64decode;

Crypto.TEA.encipher = function(v,k)
// Encrypt, using TEA, array v with key k
{
	if(v.length == 1) {
		v[1] = 0;
	}
	var n = v.length;
	var delta = 0x9E3779B9;
	var q = Math.floor(6+52/n);
	n--;
	var sum = 0;
	var z = v[n];
	var y,mx,e;
	while(q-- > 0) {
		sum += delta;
		e = sum>>>2 & 3;
		for(var p=0; p<n; p++) {
			y = v[p+1];
			mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
			z = v[p] += mx;
		}
		y = v[0];
		mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
		z = v[n] += mx;
	}
};

Crypto.TEA.decipher = function(v,k)
// Decrypt, using TEA, array v with key k
{
	var n = v.length;
	var delta = 0x9E3779B9;
	var sum = delta*Math.floor(6+52/n);
	n--;
	var y = v[0];
	var z,mx,e;
	while(sum != 0) {
		e = sum>>>2 & 3;
		for(var p=n; p>0; p--) {
			z = v[p-1];
			mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
			y = v[p] -= mx;
		}
		z = v[n];
		mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
		y = v[0] -= mx;
		sum -= delta;
	}
};

Crypto.TEA.encrypt = function(plaintext,passphrase)
// Encrypt the plaintext
{
	if(plaintext.length == 0)
		return('');// nothing to encrypt
	var v = Crypto.strToBe32s(plaintext);
	Crypto.TEA.encipher(v,Crypto.passphraseToKey(passphrase));
	return Crypto.be32sToStr(v);
};

Crypto.TEA.encryptPassphrase = function(passphrase)
// Encrypt the passphrase with itself
{
	if(passphrase.length == 0)
		return('');// nothing to encrypt
	var v = Crypto.strToBe32s(passphrase);
	Crypto.TEA.encipher(v,Crypto.passphraseToKey(passphrase));
	var s = Crypto.base64encode(Crypto.be32sToStr(v)).substr(0,20);
	return s.replace(/\+/g,'a').replace(/\//g,'a').replace(/=/g,'c');
};

Crypto.TEA.decrypt = function(ciphertext,passphrase)
// Decrypt ciphertext
{
	if(ciphertext.length == 0)
		return('');// nothing to decrypt
	var v = Crypto.strToBe32s(ciphertext);
	Crypto.TEA.decipher(v,Crypto.passphraseToKey(passphrase));
	var plaintext = Crypto.be32sToStr(v);
	if(plaintext.search(/\0/) != -1) {
		plaintext = plaintext.slice(0,plaintext.search(/\0/));
	}
	return plaintext;
};

} // end of 'install only once'
//}}}
[[Home]]
/***
|''Name:''|DisableStrikeThroughPlugin|
|''Description:''|Allows you to disable TiddlyWiki's automatic linking of WikiWords|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DisableStrikeThroughPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/DisableStrikeThroughPlugin.js |
|''Version:''|0.0.1|
|''Date:''|Feb 18, 2008|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

***/

//{{{
// Ensure that the DisableStrikeThroughPlugin is only installed once.
if(!version.extensions.DisableStrikeThroughPlugin) {
version.extensions.DisableStrikeThroughPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('DisableStrikeThroughPlugin requires TiddlyWiki 2.1 or newer.');}

DisableStrikeThroughPlugin = {};

DisableStrikeThroughPlugin.replaceFormatters = function()
{
	for(var i=0; i<config.formatters.length; i++) {
		var name = config.formatters[i].name;
		if(name == 'characterFormat') {
			config.formatters[i].match = "''|//|__|\\^\\^|~~|\\{\\{\\{";
			break;
		} else if(name == 'strikeByChar') {
			config.formatters.splice(i,1);
			break;
		}
	}
};
DisableStrikeThroughPlugin.replaceFormatters();

} // end of 'install only once'
//}}}
/***
|''Name:''|DisableWikiLinksPlugin|
|''Description:''|Allows you to disable TiddlyWiki's automatic linking of WikiWords|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DisableWikiLinksPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/DisableWikiLinksPlugin.js |
|''Version:''|0.1.3|
|''Date:''|Aug 5, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

|''Disable WikiLinks''|<<option chkDisableWikiLinks>>|

***/

//{{{
// Ensure that the DisableWikiLinksPlugin is only installed once.
if(!version.extensions.DisableWikiLinksPlugin) {
version.extensions.DisableWikiLinksPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('DisableWikiLinksPlugin requires TiddlyWiki 2.1 or newer.');}

if (config.options.chkDisableWikiLinks==undefined)
	{config.options.chkDisableWikiLinks = false;}

Tiddler.prototype.autoLinkWikiWords = function()
{
	if(config.options.chkDisableWikiLinks==true)
		{return false;}
	return !this.isTagged('systemConfig') && !this.isTagged('excludeMissing');
};

} // end of 'install only once'
//}}}
|!Format|!Markup|!Example|
|''Headings''|{{{!!Heading 2}}}<br />{{{!!!Heading 3}}}<br />{{{!!!!Heading 4}}}<br />{{{!!!!!Heading 5}}}<br /><br />Usually avoid Heading1 as Tiddler titles are nominally Heading1.|<html><h2>Heading 2</h2><h3>Heading 3</h3><h4>Heading 4</h4><h5>Heading 5</h5></html>|
|''Lists''|{{{*Bulleted list}}}|<html><ul><li>Bulleted List</li></ul></html>|
|~|{{{#Numbered list}}}|<html><ol><li>Numbered List</li></ol></html>|
|~|Definition list<br />{{{;Term}}}<br />{{{:definition}}}|<html><dl><dt>Term</dt><dd>definition</dd></dl></html>|
|~|Lists can be mixed and nested<br />{{{*}}}Bullet<br />{{{*#}}}Number<br />{{{*#;}}}Item<br />{{{*#:}}}Definition|<html><ul><li>Bullet<ol><li>Numbered<dl><dt></dt>Item<dd>Definition</dd></dl></li></ol></li></ul></html>|
|''Block quotes''|{{{>Blockquote}}}<br />{{{>>Nested quote}}}|<html><blockquote>Blockquote<blockquote>Nested<br/> quote</blockquote></blockquote></html>|
|~|{{{<<<}}}<br />{{{multi-line}}}<br />{{{blockquote}}}<br />{{{<<<}}}|<html><blockquote>multi-line<br/>blockquote</blockquote></html>|
|''Horizontal Rule''|{{{----}}} (4 dashes on a line of their own)|<html><hr></html>|
|''Links''|Any {{{WikiWord}}} creates a link to a tiddler (whether it exists or not).<br />Note that a WikiWord has to start with a capital letter and have a further mix of upper and lower case.|[[WikiWord]]|
|~|Manual link<br />{{{[[Table of Contents]]}}} (Especially for tiddlers with spaces in their titles)|[[Table of Contents]]|
|~|{{{[[Pretty Link|Link]]}}}|[[Pretty Link|Link]]|
|~|Automatic external link {{{http://www.tiddlywiki.com}}}|http://www.tiddlywiki.com|
|~|Pretty external link<br />{{{[[My Home Page|http://www.tiddlywiki.com]]}}}|[[My Home Page|http://www.tiddlywiki.com]]|
|~|OS Folder link<br />Windows Share: {{{file://///server/share}}}<br />Windows Local: {{{file:///c:/folder/file}}}<br />Un*x Local File: {{{file://folder/file}}}<br />Relative File: {{{[[folder/file]]}}}|file://///server/share <br />file:///c:/folder/file <br />file://folder/file <br /> [[folder/file]]|
|''Images''|{{{[img[favicon.ico]]}}}<br />Note that image files are always external to the TW file|[img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Right aligned<br />{{{[>img[favicon.ico]]}}}|[>img[http://www.tiddlywiki.com/favicon.ico]]|
|~|Left aligned<br />{{{[<img[favicon.ico]]}}}|[<img[http://www.tiddlywiki.com/favicon.ico]]|
|''Image Links''|{{{[img[fav.ico][TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][TiddlerName]]|
|~|{{{[img[fav.ico][Alias|TiddlerName]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][Alias|TiddlerName]]|
|~|{{{[img[fav.ico][http://www.aa.com]]}}}|[img[http://www.tiddlywiki.com/favicon.ico][http://www.tiddlywiki.com]]|
|~|>|also see ''Links'' and ''Images'' sections in this table|
|''Inline''<br />''Comments''|{{{Not shown: /% hidden comment %/}}}<br />Text between the markers will not be shown|Not shown:/% hidden text %/|
You can save a complete copy of this site as a TiddlyWiki on your local drive by right clicking on [[this link|index.html]]
and selecting //Save link as...// or //Save target as...//. You can choose where to save the file, and what to call it (but make sure that it's saved in HTML format and with an HTML extension).

@@There can be confusing and subtle differences between different browsers. Some points to watch:@@
* If you're using Windows XP Service Pack 2 or Windows Vista, check for known [[ServicePack2Problems|http://www.tiddlywiki.com/#ServicePack2Problems]] and [[VistaIssues|http://www.tiddlywiki.com/#VistaIssues]]
* Do ''not'' use the File/Save command in your browser to save TiddlyWiki, because of [[SaveUnpredictabilities|http://www.tiddlywiki.com/#SaveUnpredictabilities]].
* Make sure that you're saving in HTML (or "page source" format), not one of the new-fangled archive formats
/***
|''Name:''|EncryptionCommandsPlugin|
|''Description:''|Toolbar commands for cryptographic functions|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://martinswiki.com/#EncryptionCommandsPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/EncryptionCommandsPlugin.js |
|''Version:''|0.1.7|
|''Date:''|Feb 4, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.3|
|''Requires''|[[CryptoTEAPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/CryptoTEAPlugin.js ]]|

{{{<<tiddler EncryptionCommandsPluginDocumentation>>}}}
***/

//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.EncryptionCommandsPlugin) {
version.extensions.EncryptionCommandsPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1) || (version.major == 2 && version.minor == 1 && version.revision <3 ))
	alertAndThrow("EncryptionCommandsPlugin requires TiddlyWiki 2.1.3 or later.");

config.commands.editTiddler.isEnabled = function(tiddler)
{
	return tiddler.fields.encryption ? false : true;
};

config.commands.encryptTiddler = {
	hideReadOnly: true,
	hideShadow: true,
	encryptableTag: 'encryptable',
	base64Tag: 'base64',
	base64encode: null,
	encryption: null
};

merge(config.commands.encryptTiddler,{
	text: "encrypt",
	tooltip: "Encrypt this tiddler",
	passphrasePrompt: "Enter encryption passphrase"
});

config.commands.encryptTiddler.isEnabled = function(tiddler)
{
	return this.encryption &&
			!tiddler.isTagged('systemConfig') && !store.getValue(tiddler,'encryption') &&
			(tiddler.isTagged(this.encryptableTag) || tiddler.isTagged(this.base64Tag));
};

config.commands.encryptTiddler.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(!this.isEnabled(tiddler))
		return;
	if(tiddler.isTagged(this.base64Tag)) {
		tiddler.text = this.base64encode(tiddler.text);
		var name = 'base64';
	} else {
		if(!this.encryption || !this.encryption.encrypt)
			return;
		var passphrase = prompt(this.passphrasePrompt,'');
		if(!passphrase)
			return;
		if(this.encryption.encryptPassphrase) {
			store.setValue(tiddler,'passphrase',this.encryption.encryptPassphrase(passphrase));
		}
		var text = this.encryption.encrypt(tiddler.text,passphrase);
		tiddler.text = this.base64encode(text);
		name = this.encryption.name();
	}
	var i = tiddler.tags.indexOf(this.encryptableTag);
	if(i!=-1)
		tiddler.tags.splice(i,1);
	store.setValue(tiddler,'encryption',name);
	store.addTiddler(tiddler);
	story.saveTiddler(title,event.shiftKey);
	story.refreshTiddler(title,1,true);
};

config.commands.decryptTiddler = {
	hideReadOnly: true,
	hideShadow: true,
	encryptableTag: 'encryptable',
	base64Tag: 'base64',
	base64decode: null,
	encryption: null
};

// localization
merge(config.commands.decryptTiddler,{
	text: "decrypt",
	tooltip: "Decrypt this tiddler",
	passphrasePrompt: "Enter decryption passphrase",
	incorrectPassphrase: "Incorrect passphrase"
});

config.commands.decryptTiddler.isEnabled = function(tiddler)
{
	return store.getValue(tiddler,'encryption');
};

config.commands.decryptTiddler.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(!this.isEnabled(tiddler))
		return;
	if(store.getValue(tiddler,'encryption') == 'base64') {
		tiddler.text = this.base64decode(tiddler.text);
		var tag = 'base64';
	} else {
		var encryption = Crypto[store.getValue(tiddler,'encryption')];
		if(!encryption || !encryption.decrypt || !encryption.base64decode)
			return;
		var passphrase = prompt(this.passphrasePrompt,'');
		if(!passphrase)
			return;
		if(store.getValue(tiddler,'passphrase') && encryption.encryptPassphrase) {
			if(encryption.encryptPassphrase(passphrase)!=store.getValue(tiddler,'passphrase')) {
				displayMessage(config.commands.displayDecryptedTiddler.incorrectPassphrase);
				return;
			}
		}
		tiddler.text = encryption.decrypt(encryption.base64decode(tiddler.text),passphrase);
		tag = this.encryptableTag;
	}
	tiddler.tags.pushUnique(tag);
	store.setValue(tiddler,'encryption',null);
	store.setValue(tiddler,'passphrase',null);
	store.addTiddler(tiddler);
	story.saveTiddler(title,event.shiftKey);
	story.refreshTiddler(tiddler.title,1,true);
};

config.commands.displayDecryptedTiddler = {
	encryptedTag: 'encryption',
	base64Tag: 'base64',
	base64decode: null,
	encryption: null
};

// localization
merge(config.commands.displayDecryptedTiddler,{
	text: "display",
	tooltip: "Display this tiddler decrypted",
	passphrasePrompt: "Enter decryption passphrase",
	incorrectPassphrase: "Incorrect passphrase"
});

config.commands.displayDecryptedTiddler.isEnabled = function(tiddler)
{
	return this.base64decode && store.getValue(tiddler,'encryption');
};

config.commands.displayDecryptedTiddler.handler = function(event,src,title)
{
	var tiddler = store.fetchTiddler(title);
	if(!this.isEnabled(tiddler))
		return;
	if(tiddler.isTagged(this.base64Tag)) {
		var text = this.base64decode(tiddler.text);
	} else {
		var encryption = Crypto[store.getValue(tiddler,'encryption')];
		if(!encryption || !encryption.decrypt || !encryption.base64decode)
			return;
		var passphrase = prompt(this.passphrasePrompt,'');
		if(!passphrase)
			return;
		if(store.getValue(tiddler,'passphrase') && encryption.encryptPassphrase) {
			if(encryption.encryptPassphrase(passphrase)!=store.getValue(tiddler,'passphrase')) {
				displayMessage(config.commands.displayDecryptedTiddler.incorrectPassphrase);
				return;
			}
		}
		text = encryption.decrypt(encryption.base64decode(tiddler.text),passphrase);
	}
	var oldText = tiddler.text;
	tiddler.text = text;
	story.refreshTiddler(tiddler.title,DEFAULT_VIEW_TEMPLATE,true);
	tiddler.text = oldText;
};
//}}}

// //Setup
//{{{
encryptionCommandPluginUpdateViewTemplate = function()
{
	var title = 'ViewTemplate';
	var tiddler = store.fetchTiddler(title);
	if(!tiddler) {
		tiddler = new Tiddler();
		tiddler.title = title;
		tiddler.text = config.shadowTiddlers[title];
		tiddler.tags.pushUnique('excludeLists');
	}
	if(tiddler.text.indexOf('encryptTiddler') == -1) {
		tiddler.text = tiddler.text.replace("<div class='toolbar' macro='toolbar ","<div class='toolbar' macro='toolbar encryptTiddler displayDecryptedTiddler decryptTiddler ");
		store.addTiddler(tiddler);  
		store.setDirty(true);
	}
};

encryptionCommandPluginSetFunctions = function()
{
	config.commands.encryptTiddler.base64encode = Crypto.base64armor;
	config.commands.encryptTiddler.encryption = Crypto.TEA;
	config.commands.decryptTiddler.base64decode = Crypto.base64decode;
	config.commands.displayDecryptedTiddler.base64decode = Crypto.base64decode;
};

encryptionCommandPluginUpdateViewTemplate();
encryptionCommandPluginSetFunctions();
//}}}
} // end of 'install only once'
//}}}
 
/***
|''Name:''|ExampleAdaptorPlugin|
|''Description:''|Example Adaptor which can be used as a basis for creating a new Adaptor|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ExampleAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ExampleAdaptorPlugin.js|
|''Version:''|0.5.3|
|''Status:''|Not for release - this is a template for creating new adaptors|
|''Date:''|Mar 11, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|

To make this example into a real TiddlyWiki adaptor, you need to:

# Globally search and replace ExampleAdpator with the name of your adaptor
# Delete any functionality not supported by you host (for example, putTiddler may not be supported)
# Do the actions indicated by the !!TODO comments, namely:
## Set the values of the main variables, eg ExampleAdaptor.serverType etc
## Fill in the uri templates in the .prototype functions
## Parse the responseText returned in the Callback functions and put the results in the appropriate variables

***/

//{{{
if(!version.extensions.ExampleAdaptorPlugin) {
version.extensions.ExampleAdaptorPlugin = {installed:true};

function ExampleAdaptor()
{
	this.host = null;
	this.workspace = null;
	return this;
}

// !!TODO set the variables below
ExampleAdaptor.mimeType = 'text/x.';
ExampleAdaptor.serverType = 'example'; // MUST BE LOWER CASE
ExampleAdaptor.serverParsingErrorMessage = "Error parsing result from server";
ExampleAdaptor.errorInFunctionMessage = "Error in function ExampleAdaptor.%0";

ExampleAdaptor.prototype.setContext = function(context,userParams,callback)
{
	if(!context) context = {};
	context.userParams = userParams;
	if(callback) context.callback = callback;
	context.adaptor = this;
	if(!context.host)
		context.host = this.host;
	context.host = ExampleAdaptor.fullHostName(context.host);
	if(!context.workspace)
		context.workspace = this.workspace;
	return context;
};

ExampleAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};

ExampleAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
	return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};

ExampleAdaptor.fullHostName = function(host)
{
	if(!host)
		return '';
	if(!host.match(/:\/\//))
		host = 'http://' + host;
	if(host.substr(host.length-1) != '/')
		host = host + '/';
	return host;
};

ExampleAdaptor.minHostName = function(host)
{
	return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};

// Convert a page title to the normalized form used in uris
ExampleAdaptor.normalizedTitle = function(title)
{
	var n = title.toLowerCase();
	n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
	if(n.charAt(0)=='_')
		n = n.substr(1);
	return String(n);
};

// Convert a date in YYYY-MM-DD hh:mm format into a JavaScript Date object
ExampleAdaptor.dateFromEditTime = function(editTime)
{
	var dt = editTime;
	return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};

ExampleAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
	this.host = ExampleAdaptor.fullHostName(host);
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};

ExampleAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
	this.workspace = workspace;
	context = this.setContext(context,userParams,callback);
	if(context.callback) {
		context.status = true;
		window.setTimeout(function() {callback(context,userParams);},0);
	}
	return true;
};

ExampleAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
	var uriTemplate = '%0';
	var uri = uriTemplate.format([context.host]);
	var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getWorkspaceListCallback,context);
	return typeof req == 'string' ? req : true;
};

ExampleAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
	if(status) {
		try {
// !!TODO: parse the responseText here
			var list = [];
			var item = {
				title:'exampleTitle',
				name:'exampleName'
				};
			list.push(item);
		} catch (ex) {
			context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		context.workspaces = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

ExampleAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
	var uriTemplate = '%0%1';
	var uri = uriTemplate.format([context.host,context.workspace]);
	var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerListCallback,context);
	return typeof req == 'string' ? req : true;
};

ExampleAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
	if(status) {
		try {
// !!TODO: parse the responseText here
			var list = [];
			var tiddler = new Tiddler('example');
			list.push(tiddler);
		} catch (ex) {
			context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		context.tiddlers = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

ExampleAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
	var info = {};
	var host = this && this.host ? this.host : ExampleAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
// !!TODO set the uriTemplate
	uriTemplate = '%0%1%2';
	info.uri = uriTemplate.format([host,workspace,tiddler.title]);
	return info;
};

ExampleAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	if(revision)
		context.revision = revision;
	return this.getTiddler(title,context,userParams,callback);
};

ExampleAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	if(title)
		context.title = title;
	if(context.revision) {
// !!TODO set the uriTemplate
		var uriTemplate = '%0%1%2%3';
	} else {
// !!TODO set the uriTemplate
		uriTemplate = '%0%1%2';
	}
	uri = uriTemplate.format([context.host,context.workspace,ExampleAdaptor.normalizedTitle(title),context.revision]);

	context.tiddler = new Tiddler(title);
	context.tiddler.fields.wikiformat = 'exampleformat';
	context.tiddler.fields['server.type'] = ExampleAdaptor.serverType;
	context.tiddler.fields['server.host'] = ExampleAdaptor.minHostName(context.host);
	context.tiddler.fields['server.workspace'] = context.workspace;
	var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerCallback,context);
	return typeof req == 'string' ? req : true;
};

ExampleAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	context.statusText = ExampleAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
	if(status) {
		try {
// !!TODO: parse the responseText here
// !!TODO: fill in tiddler fields as available
			//context.tiddler.tags = ;
			//context.tiddler.fields['server.page.id'] = ;
			//context.tiddler.fields['server.page.name'] = ;
			//context.tiddler.fields['server.page.revision'] = String(...);
			//context.tiddler.modifier = ;
			//context.tiddler.modified = ExampleAdaptor.dateFromEditTime(...);
		} catch (ex) {
			context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
		if(context.callback)
			context.callback(context,context.userParams);
		return;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

ExampleAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
// !!TODO set the uriTemplate
	var uriTemplate = '%0%1%2';
	if(!limit)
		limit = 10;
	var uri = uriTemplate.format([context.host,context.workspace,ExampleAdaptor.normalizedTitle(title),limit]);
	var req = ExampleAdaptor.doHttpGET(uri,ExampleAdaptor.getTiddlerRevisionListCallback,context);
	return typeof req == 'string' ? req : true;
};

ExampleAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
	context.status = false;
	if(status) {
		var content = null;
		try {
// !!TODO: parse the responseText here
			var list = [];
			var tiddler = new Tiddler('example');
// !!TODO: fill in tiddler fields as available
			//tiddler.modified = ExampleAdaptor.dateFromEditTime();
			//tiddler.modifier = ;
			//tiddler.tags = ;
			//tiddler.fields['server.page.id'] = ;
			//tiddler.fields['server.page.name'] = ;
			//tiddler.fields['server.page.revision'] = ;
			list.push(tiddler);
		} catch (ex) {
			context.statusText = exceptionText(ex,ExampleAdaptor.serverParsingErrorMessage);
			if(context.callback)
				context.callback(context,context.userParams);
			return;
		}
		var sortField = 'server.page.revision';
		list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
		context.revisions = list;
		context.status = true;
	} else {
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

ExampleAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
	context = this.setContext(context,userParams,callback);
	context.title = tiddler.title;
// !!TODO set the uriTemplate
	var uriTemplate = '%0%1%2';
	var host = context.host ? context.host : ExampleAdaptor.fullHostName(tiddler.fields['server.host']);
	var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
	var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
	var req = ExampleAdaptor.doHttpPOST(uri,ExampleAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,ExampleAdaptor.mimeType);
	return typeof req == 'string' ? req : true;
};

ExampleAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
	if(status) {
		context.status = true;
	} else {
		context.status = false;
		context.statusText = xhr.statusText;
	}
	if(context.callback)
		context.callback(context,context.userParams);
};

ExampleAdaptor.prototype.close = function()
{
	return true;
};

config.adaptors[ExampleAdaptor.serverType] = ExampleAdaptor;
} //# end of 'install only once'
//}}}
/***
|''Name:''|ExampleFormatterPlugin|
|''Description:''|Example Formatter which can be used as a basis for creating a new Formatter. Allows Tiddlers to use [[example|http://www.example.com/wikitext]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#ExampleFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/ExampleFormatterPlugin.js |
|''Version:''|0.1.10|
|''Status:''|Not for release - this is a template for creating new formatters|
|''Date:''|Nov 5, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

To make this example into a real TiddlyWiki formatter, you need to:

# Globally search and replace ExampleAdpator with the name of your formatter
# Remove any format entries that are not required
# Change the existing format entries as required
# Add any new format entries that are required

***/

//{{{
// Ensure that the ExampleFormatterPlugin is only installed once.
if(!version.extensions.ExampleFormatterPlugin) {
version.extensions.ExampleFormatterPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1))
	{alertAndThrow('ExampleFormatterPlugin requires TiddlyWiki 2.1 or later.');}

exampleFormatter = {}; // 'namespace' for local functions

exampleDebug = function(out,str)
{
	createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
	createTiddlyElement(out,'br');
};

wikify = function(source,output,highlightRegExp,tiddler)
{
	if(source && source !== '') {
		var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
		w.output = tiddler ? createTiddlyElement(output,'p') : output;
		w.subWikifyUnterm(w.output);
	}
};

config.formatterHelpers.setAttributesFromParams = function(e,p)
{
	var re = /\s*(.*?)=(?:(?:"(.*?)")|(?:'(.*?)')|((?:\w|%|#)*))/mg;
	var match = re.exec(p);
	while(match) {
		var s = match[1].unDash();
		if(s=='bgcolor') {
			s = 'backgroundColor';
		}
		try {
			if(match[2]) {
				e.setAttribute(s,match[2]);
			} else if(match[3]) {
				e.setAttribute(s,match[3]);
			} else {
				e.setAttribute(s,match[4]);
			}
		}
		catch(ex) {}
		match = re.exec(p);
	}
};

config.exampleFormatters = [
{
	name: 'exampleHeading',
	match: '^={1,6}(?!=)',
	termRegExp: /(={0,6} *\n+)/mg,
	handler: function(w)
	{
		w.subWikifyTerm(createTiddlyElement(w.output,'h'+w.matchLength),this.termRegExp);
	}
},

{
	name: 'exampleList',
	match: '^[\\*#;:]+ ',
	lookaheadRegExp: /^([\*#;:])+ /mg,
	termRegExp: /(\n)/mg,
	handler: function(w)
	{
		var stack = [w.output];
		var currLevel = 0, currType = null;
		var listLevel, listType, itemType, baseType;
		w.nextMatch = w.matchStart;
		this.lookaheadRegExp.lastIndex = w.nextMatch;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
			switch(lookaheadMatch[1]) {
			case '*':
				listType = 'ul';
				itemType = 'li';
				break;
			case '#':
				listType = 'ol';
				itemType = 'li';
				break;
			case ';':
				listType = 'dl';
				itemType = 'dt';
				break;
			case ':':
				listType = 'dl';
				itemType = 'dd';
				break;
			default:
				break;
			}
			if(!baseType)
				baseType = listType;
			listLevel = lookaheadMatch[0].length;
			w.nextMatch += lookaheadMatch[0].length;
			var t;
			if(listLevel > currLevel) {
				for(t=currLevel; t<listLevel; t++) {
					var target = (currLevel == 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
					stack.push(createTiddlyElement(target,listType));
				}
			} else if(listType!=baseType && listLevel==1) {
				w.nextMatch -= lookaheadMatch[0].length;
				return;
			} else if(listLevel < currLevel) {
				for(t=currLevel; t>listLevel; t--)
					stack.pop();
			} else if(listLevel == currLevel && listType != currType) {
				stack.pop();
				stack.push(createTiddlyElement(stack[stack.length-1].lastChild,listType));
			}
			currLevel = listLevel;
			currType = listType;
			var e = createTiddlyElement(stack[stack.length-1],itemType);
			w.subWikifyTerm(e,this.termRegExp);
			this.lookaheadRegExp.lastIndex = w.nextMatch;
			lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		}
	}
},

{
	name: 'exampleRule',
	match: '^---+$\\n?',
	handler: function(w)
	{
		createTiddlyElement(w.output,'hr');
	}
},

{
	name: 'macro',
	match: '<<',
	lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
			invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
		}
	}
},

{
	name: 'exampleExplicitLink',
	match: '\\[\\[',
	lookaheadRegExp: /\[\[(.*?)(?:\|(.*?))?\]\]/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var link = lookaheadMatch[1];
			var text = lookaheadMatch[2] ? lookaheadMatch[2] : link;
			var e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic);
			createTiddlyText(e,text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'exampleNotWikiLink',
	match: '!' + config.textPrimitives.wikiLink,
	handler: function(w)
	{
		w.outputText(w.output,w.matchStart+1,w.nextMatch);
	}
},

{
	name: 'exampleWikiLink',
	match: config.textPrimitives.wikiLink,
	handler: function(w)
	{
		if(w.matchStart > 0) {
			var preRegExp = new RegExp(config.textPrimitives.anyLetter,'mg');
			preRegExp.lastIndex = w.matchStart-1;
			var preMatch = preRegExp.exec(w.source);
			if(preMatch.index == w.matchStart-1) {
				w.outputText(w.output,w.matchStart,w.nextMatch);
				return;
			}
		}
		var output = w.output;
		if(w.autoLinkWikiWords == true || store.isShadowTiddler(w.matchText)) {
			output = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic);
		}
		w.outputText(output,w.matchStart,w.nextMatch);
	}
},

{
	name: 'exampleUrlLink',
	match: config.textPrimitives.urlPattern,
	handler: function(w)
	{
		w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
	}
},

{
	name: 'exampleBold',
	match: '\\*\\*',
	termRegExp: /(\*\*|(?=\n\n))/mg,
	element: 'strong',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleItalic',
	match: '//',
	termRegExp: /(\/\/|(?=\n\n))/mg,
	element: 'em',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleUnderline',
	match: '__',
	termRegExp: /(__|(?=\n\n))/mg,
	element: 'u',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleStrikeBy',
	match: '--(?!\\s|$)',
	termRegExp: /((?!\s)--|(?=\n\n))/mg,
	element: 'strike',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleSuperscript',
	match: '\\^\\^',
	termRegExp: /(\^\^|(?=\n\n))/mg,
	element: 'sup',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleSubscript',
	match: '~~',
	termRegExp: /(~~|(?=\n\n))/mg,
	element: 'sub',
	handler: config.formatterHelpers.createElementAndWikify
},

{
	name: 'exampleMonospaced',
	match: '\\{\\{\\{',
	lookaheadRegExp: /\{\{\{((?:.|\n)*?)\}\}\}/mg,
	element: 'code',
	handler: config.formatterHelpers.enclosedTextHelper
},

{
	name: 'exampleParagraph',
	match: '\\n{2,}',
	handler: function(w)
	{
		w.output = createTiddlyElement(w.output,'p');
	}
},

{
	name: 'exampleLineBreak',
	match: '\\n|<br ?/?>',
	handler: function(w)
	{
		createTiddlyElement(w.output,'br');
	}
},

{
	name: 'exampleComment',
	match: '<!\\-\\-',
	lookaheadRegExp: /<!\-\-((?:.|\n)*?)\-\-!>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
},

{
	name: 'exampleHtmlEntitiesEncoding',
	match: '&#?[a-zA-Z0-9]{2,8};',
	handler: function(w)
	{
		createTiddlyElement(w.output,'span').innerHTML = w.matchText;
	}
},

{
	name: "html",
	match: "<[Hh][Tt][Mm][Ll]>",
	lookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\n)*?)<\/[Hh][Tt][Mm][Ll]>/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1];
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
}
];

config.parsers.exampleFormatter = new Formatter(config.exampleFormatters);
config.parsers.exampleFormatter.format = 'example';
config.parsers.exampleFormatter.formatTag = 'ExampleFormat';
} // end of 'install only once'
//}}}
/***
|''Name:''|ExamplePlugin|
|''Description:''|My Description|
|''Author:''|My Name|
|''Source:''|http://www.MyWebSite.com/#ExamplePlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MyDirectory/plugins/ExamplePlugin.js |
|''Version:''|0.0.1|
|''Status:''|Not for release - this is a template