Older blog entries for cdent (starting at number 79)

_tiddlywiki

Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
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]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#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]];}

.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]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#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 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.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:0 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 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding: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 0;}
.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 0 0 0.5em;}
.tab {margin:0 0 0 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 0 14em;}

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

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

.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:0 0.25em; padding:0 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:0 3px 0 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 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

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

.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;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding: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;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<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 excludeLists'></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]]

----

Syndicated 2012-03-13 15:32:07 from cdent

13 Mar 2012 (updated 13 Mar 2012 at 16:11 UTC) »

_tiddlywiki-app.js

//
// Please note:
//
// * This code is designed to be readable but for compactness it only includes brief comments. You can see fuller comments
//   in the project repository at https://github.com/TiddlyWiki/tiddlywiki
//
// * You should never need to modify this source code directly. TiddlyWiki is carefully designed to allow deep customisation
//   without changing the core code. Please consult the development group at http://groups.google.com/group/TiddlyWikiDev
//
// JSLint directives
/*global jQuery:false, version:false */
/*jslint bitwise:true, browser:true, confusion:true, eqeq:true, evil:true, forin:true, maxerr:100, plusplus:true, regexp:true, sloppy:true, sub:true, undef:true, unparam:true, vars:true, white:true */
//--
//-- Configuration repository
//--

// Miscellaneous options
var config = {
	numRssItems: 20, // Number of items in the RSS feed
	animDuration: 400, // Duration of UI animations in milliseconds
	cascadeFast: 20, // Speed for cascade animations (higher == slower)
	cascadeSlow: 60, // Speed for EasterEgg cascade animations
	cascadeDepth: 5, // Depth of cascade animation
	locale: "en" // W3C language tag
};

// Hashmap of alternative parsers for the wikifier
config.parsers = {};

// Adaptors
config.adaptors = {};
config.defaultAdaptor = null;

// Backstage tasks
config.tasks = {};

// Annotations
config.annotations = {};

// Custom fields to be automatically added to new tiddlers
config.defaultCustomFields = {};

// Messages
config.messages = {
	messageClose: {},
	dates: {},
	tiddlerPopup: {}
};

// Options that can be set in the options panel and/or cookies
config.options = {
	chkRegExpSearch: false,
	chkCaseSensitiveSearch: false,
	chkIncrementalSearch: true,
	chkAnimate: true,
	chkSaveBackups: true,
	chkAutoSave: false,
	chkGenerateAnRssFeed: false,
	chkSaveEmptyTemplate: false,
	chkOpenInNewWindow: true,
	chkToggleLinks: false,
	chkHttpReadOnly: false,
	chkForceMinorUpdate: false,
	chkConfirmDelete: true,
	chkInsertTabs: false,
	chkUsePreForStorage: true, // Whether to use 
 format for storage
	chkDisplayInstrumentation: true,
	txtBackupFolder: "",
	txtEditorFocus: "text",
	txtMainTab: "tabTimeline",
	txtMoreTab: "moreTabAll",
	txtMaxEditRows: "30",
	txtFileSystemCharSet: "UTF-8",
	txtTheme: ""
	};
config.optionsDesc = {};

config.optionsSource = {};

// Default tiddler templates
var DEFAULT_VIEW_TEMPLATE = 1;
var DEFAULT_EDIT_TEMPLATE = 2;
config.tiddlerTemplates = {
	1: "ViewTemplate",
	2: "EditTemplate"
};

// More messages (rather a legacy layout that should not really be like this)
config.views = {
	wikified: {
		tag: {}
	},
	editor: {
		tagChooser: {}
	}
};

// Backstage tasks
config.backstageTasks = ["save","importTask","tweak","plugins"];

// Extensions
config.extensions = {};

// Macros; each has a 'handler' member that is inserted later
config.macros = {
	today: {},
	version: {},
	search: {sizeTextbox: 15},
	tiddler: {},
	tag: {},
	tags: {},
	tagging: {},
	timeline: {},
	allTags: {},
	list: {
		all: {},
		missing: {},
		orphans: {},
		shadowed: {},
		touched: {},
		filter: {}
	},
	closeAll: {},
	permaview: {},
	saveChanges: {},
	slider: {},
	option: {},
	options: {},
	newTiddler: {},
	newJournal: {},
	tabs: {},
	gradient: {},
	message: {},
	view: {defaultView: "text"},
	edit: {},
	tagChooser: {},
	toolbar: {},
	plugins: {},
	refreshDisplay: {},
	importTiddlers: {},
	upgrade: {
		source: "http://tiddlywiki-releases.tiddlyspace.com/upgrade",
		backupExtension: "pre.core.upgrade"
	},
	sync: {},
	annotations: {}
};

// Commands supported by the toolbar macro
config.commands = {
	closeTiddler: {},
	closeOthers: {},
	editTiddler: {},
	saveTiddler: {hideReadOnly: true},
	cancelTiddler: {},
	deleteTiddler: {hideReadOnly: true},
	permalink: {},
	references: {type: "popup"},
	jump: {type: "popup"},
	syncing: {type: "popup"},
	fields: {type: "popup"}
};

// Control of macro parameter evaluation
config.evaluateMacroParameters = "all";

// Basic regular expressions
config.textPrimitives = {
	upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
	lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
	anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
	anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]"
};
if(!((new RegExp("[\u0150\u0170]","g")).test("\u0150"))) {
	config.textPrimitives = {
		upperLetter: "[A-Z\u00c0-\u00de]",
		lowerLetter: "[a-z0-9_\\-\u00df-\u00ff]",
		anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff]",
		anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff]"
	};
}
config.textPrimitives.sliceSeparator = "::";
config.textPrimitives.sectionSeparator = "##";
config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
config.textPrimitives.unWikiLink = "~";
config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
	config.textPrimitives.lowerLetter + "+" +
	config.textPrimitives.upperLetter +
	config.textPrimitives.anyLetter + "*)|(?:" +
	config.textPrimitives.upperLetter + "{2,}" +
	config.textPrimitives.lowerLetter + "+))";

config.textPrimitives.cssLookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssLookahead,"mg");

config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
	config.textPrimitives.brackettedLink + ")|(?:" +
	config.textPrimitives.urlPattern + ")","mg");
config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
	config.textPrimitives.titledBrackettedLink + ")|(?:" +
	config.textPrimitives.brackettedLink + ")|(?:" +
	config.textPrimitives.urlPattern + ")","mg");

config.glyphs = {
	currBrowser: null,
	browsers: [],
	codes: {}
};

//--
//-- Shadow tiddlers
//--

config.shadowTiddlers = {
	StyleSheet: "",
	MarkupPreHead: "",
	MarkupPostHead: "",
	MarkupPreBody: "",
	MarkupPostBody: "",
	TabTimeline: '>',
	TabAll: '>',
	TabTags: '>',
	TabMoreMissing: '>',
	TabMoreOrphans: '>',
	TabMoreShadowed: '>',
	AdvancedOptions: '>',
	PluginManager: '>',
	SystemSettings: '',
	ToolbarCommands: '|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|',
	WindowTitle: '> - >'
};

// Browser detection... In a very few places, there's nothing else for it but to know what browser we're using.
config.userAgent = navigator.userAgent.toLowerCase();
config.browser = {
	isIE: config.userAgent.indexOf("msie") != -1 && config.userAgent.indexOf("opera") == -1,
	isGecko: navigator.product == "Gecko" && config.userAgent.indexOf("WebKit") == -1,
	ieVersion: /MSIE (\d.\d)/i.exec(config.userAgent), // config.browser.ieVersion[1], if it exists, will be the IE version string, eg "6.0"
	isSafari: config.userAgent.indexOf("applewebkit") != -1,
	isBadSafari: !((new RegExp("[\u0150\u0170]","g")).test("\u0150")),
	firefoxDate: /gecko\/(\d{8})/i.exec(config.userAgent), // config.browser.firefoxDate[1], if it exists, will be Firefox release date as "YYYYMMDD"
	isOpera: config.userAgent.indexOf("opera") != -1,
	isChrome: config.userAgent.indexOf('chrome') > -1,
	isLinux: config.userAgent.indexOf("linux") != -1,
	isUnix: config.userAgent.indexOf("x11") != -1,
	isMac: config.userAgent.indexOf("mac") != -1,
	isWindows: config.userAgent.indexOf("win") != -1
};

merge(config.glyphs,{
	browsers: [
		function() {return config.browser.isIE;},
		function() {return true;}
		],
	codes: {
		downTriangle: ["\u25BC","\u25BE"],
		downArrow: ["\u2193","\u2193"],
		bentArrowLeft: ["\u2190","\u21A9"],
		bentArrowRight: ["\u2192","\u21AA"]
	}
});

//--
//-- Translateable strings
//--

// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone

merge(config.options,{
	txtUserName: "YourName"});

merge(config.tasks,{
	save: {text: "save", tooltip: "Save your changes to this TiddlyWiki"},
	importTask: {text: "import", tooltip: "Import tiddlers and plugins from other TiddlyWiki files and servers", content: '>'},
	tweak: {text: "tweak", tooltip: "Tweak the appearance and behaviour of TiddlyWiki", content: '>'},
	upgrade: {text: "upgrade", tooltip: "Upgrade TiddlyWiki core code", content: '>'},
	plugins: {text: "plugins", tooltip: "Manage installed plugins", content: '>'}
});

// Options that can be set in the options panel and/or cookies
merge(config.optionsDesc,{
	txtUserName: "Username for signing your edits",
	chkRegExpSearch: "Enable regular expressions for searches",
	chkCaseSensitiveSearch: "Case-sensitive searching",
	chkIncrementalSearch: "Incremental key-by-key searching",
	chkAnimate: "Enable animations",
	chkSaveBackups: "Keep backup file when saving changes",
	chkAutoSave: "Automatically save changes",
	chkGenerateAnRssFeed: "Generate an RSS feed when saving changes",
	chkSaveEmptyTemplate: "Generate an empty template when saving changes",
	chkOpenInNewWindow: "Open external links in a new window",
	chkToggleLinks: "Clicking on links to open tiddlers causes them to close",
	chkHttpReadOnly: "Hide editing features when viewed over HTTP",
	chkForceMinorUpdate: "Don't update modifier username and date when editing tiddlers",
	chkConfirmDelete: "Require confirmation before deleting tiddlers",
	chkInsertTabs: "Use the tab key to insert tab characters instead of moving between fields",
	txtBackupFolder: "Name of folder to use for backups",
	txtMaxEditRows: "Maximum number of rows in edit boxes",
	txtTheme: "Name of the theme to use",
	txtFileSystemCharSet: "Default character set for saving changes (Firefox/Mozilla only)"});

merge(config.messages,{
	customConfigError: "Problems were encountered loading plugins. See PluginManager for details",
	pluginError: "Error: %0",
	pluginDisabled: "Not executed because disabled via 'systemConfigDisable' tag",
	pluginForced: "Executed because forced via 'systemConfigForce' tag",
	pluginVersionError: "Not executed because this plugin needs a newer version of TiddlyWiki",
	nothingSelected: "Nothing is selected. You must select one or more items first",
	savedSnapshotError: "It appears that this TiddlyWiki has been incorrectly saved. Please see http://www.tiddlywiki.com/#Download for details",
	subtitleUnknown: "(unknown)",
	undefinedTiddlerToolTip: "The tiddler '%0' doesn't yet exist",
	shadowedTiddlerToolTip: "The tiddler '%0' doesn't yet exist, but has a pre-defined shadow value",
	tiddlerLinkTooltip: "%0 - %1, %2",
	externalLinkTooltip: "External link to %0",
	noTags: "There are no tagged tiddlers",
	notFileUrlError: "You need to save this TiddlyWiki to a file before you can save changes",
	cantSaveError: "It's not possible to save changes. Possible reasons include:\n- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)\n- the pathname to your TiddlyWiki file contains illegal characters\n- the TiddlyWiki HTML file has been moved or renamed",
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to save backup file",
	rssSaved: "RSS feed saved",
	rssFailed: "Failed to save RSS feed file",
	emptySaved: "Empty template saved",
	emptyFailed: "Failed to save empty template file",
	mainSaved: "Main TiddlyWiki file saved",
	mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
	macroError: "Error in macro >",
	macroErrorDetails: "Error while executing macro >:\n%1",
	missingMacro: "No such macro",
	overwriteWarning: "A tiddler named '%0' already exists. Choose OK to overwrite it",
	unsavedChangesWarning: "WARNING! There are unsaved changes in TiddlyWiki\n\nChoose OK to save\nChoose CANCEL to discard",
	confirmExit: "--------------------------------\n\nThere are unsaved changes in TiddlyWiki. If you continue you will lose those changes\n\n--------------------------------",
	saveInstructions: "SaveChanges",
	unsupportedTWFormat: "Unsupported TiddlyWiki format '%0'",
	tiddlerSaveError: "Error when saving tiddler '%0'",
	tiddlerLoadError: "Error when loading tiddler '%0'",
	wrongSaveFormat: "Cannot save with storage format '%0'. Using standard format for save.",
	invalidFieldName: "Invalid field name %0",
	fieldCannotBeChanged: "Field '%0' cannot be changed",
	loadingMissingTiddler: "Attempting to retrieve the tiddler '%0' from the '%1' server at:\n\n'%2' in the workspace '%3'",
	upgradeDone: "The upgrade to version %0 is now complete\n\nClick 'OK' to reload the newly upgraded TiddlyWiki",
	invalidCookie: "Invalid cookie '%0'"});

merge(config.messages.messageClose,{
	text: "close",
	tooltip: "close this message area"});

config.messages.backstage = {
	open: {text: "backstage", tooltip: "Open the backstage area to perform authoring and editing tasks"},
	close: {text: "close", tooltip: "Close the backstage area"},
	prompt: "backstage: ",
	decal: {
		edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
	}
};

config.messages.listView = {
	tiddlerTooltip: "Click for the full text of this tiddler",
	previewUnavailable: "(preview not available)"
};

config.messages.dates.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"];
config.messages.dates.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
// suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
		"th","th","th","th","th","th","th","th","th","th",
		"st","nd","rd","th","th","th","th","th","th","th",
		"st"];
config.messages.dates.am = "am";
config.messages.dates.pm = "pm";

merge(config.messages.tiddlerPopup,{
	});

merge(config.views.wikified.tag,{
	labelNoTags: "no tags",
	labelTags: "tags: ",
	openTag: "Open tag '%0'",
	tooltip: "Show tiddlers tagged with '%0'",
	openAllText: "Open all",
	openAllTooltip: "Open all of these tiddlers",
	popupNone: "No other tiddlers tagged with '%0'"});

merge(config.views.wikified,{
	defaultText: "The tiddler '%0' doesn't yet exist. Double-click to create it",
	defaultModifier: "(missing)",
	shadowModifier: "(built-in shadow tiddler)",
	dateFormat: "DD MMM YYYY",
	createdPrompt: "created"});

merge(config.views.editor,{
	tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
	defaultText: "Type the text for '%0'"});

merge(config.views.editor.tagChooser,{
	text: "tags",
	tooltip: "Choose existing tags to add to this tiddler",
	popupNone: "There are no tags defined",
	tagTooltip: "Add the tag '%0'"});

merge(config.messages,{
	sizeTemplates:
		[
		{unit: 1024*1024*1024, template: "%0\u00a0GB"},
		{unit: 1024*1024, template: "%0\u00a0MB"},
		{unit: 1024, template: "%0\u00a0KB"},
		{unit: 1, template: "%0\u00a0B"}
		]});

merge(config.macros.search,{
	label: "search",
	prompt: "Search this TiddlyWiki",
	placeholder: "",
	accessKey: "F",
	successMsg: "%0 tiddlers found matching %1",
	failureMsg: "No tiddlers found matching %0"});

merge(config.macros.tagging,{
	label: "tagging: ",
	labelNotTag: "not tagging",
	tooltip: "List of tiddlers tagged with '%0'"});

merge(config.macros.timeline,{
	dateFormat: "DD MMM YYYY"});

merge(config.macros.allTags,{
	tooltip: "Show tiddlers tagged with '%0'",
	noTags: "There are no tagged tiddlers"});

config.macros.list.all.prompt = "All tiddlers in alphabetical order";
config.macros.list.missing.prompt = "Tiddlers that have links to them but are not defined";
config.macros.list.orphans.prompt = "Tiddlers that are not linked to from any other tiddlers";
config.macros.list.shadowed.prompt = "Tiddlers shadowed with default contents";
config.macros.list.touched.prompt = "Tiddlers that have been modified locally";

merge(config.macros.closeAll,{
	label: "close all",
	prompt: "Close all displayed tiddlers (except any that are being edited)"});

merge(config.macros.permaview,{
	label: "permaview",
	prompt: "Link to an URL that retrieves all the currently displayed tiddlers"});

merge(config.macros.saveChanges,{
	label: "save changes",
	prompt: "Save all tiddlers to create a new TiddlyWiki",
	accessKey: "S"});

merge(config.macros.newTiddler,{
	label: "new tiddler",
	prompt: "Create a new tiddler",
	title: "New Tiddler",
	accessKey: "N"});

merge(config.macros.newJournal,{
	label: "new journal",
	prompt: "Create a new tiddler from the current date and time",
	accessKey: "J"});

merge(config.macros.options,{
	wizardTitle: "Tweak advanced options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "
Show unknown options", unknownDescription: "//(unknown)//", listViewTemplate: { columns: [ {name: 'Option', field: 'option', title: "Option", type: 'String'}, {name: 'Description', field: 'description', title: "Description", type: 'WikiText'}, {name: 'Name', field: 'name', title: "Name", type: 'String'} ], rowClasses: [ {className: 'lowlight', field: 'lowlight'} ]} }); merge(config.macros.plugins,{ wizardTitle: "Manage plugins", step1Title: "Currently loaded plugins", step1Html: "", // DO NOT TRANSLATE skippedText: "(This plugin has not been executed because it was added since startup)", noPluginText: "There are no plugins installed", confirmDeleteText: "Are you sure you want to delete these plugins:\n\n%0", removeLabel: "remove systemConfig tag", removePrompt: "Remove systemConfig tag", deleteLabel: "delete", deletePrompt: "Delete these tiddlers forever", listViewTemplate: { columns: [ {name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'}, {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Description', field: 'Description', title: "Description", type: 'String'}, {name: 'Version', field: 'Version', title: "Version", type: 'String'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'}, {name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'}, {name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"}, {name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'}, {name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"}, {name: 'Log', field: 'log', title: "Log", type: 'StringList'} ], rowClasses: [ {className: 'error', field: 'error'}, {className: 'warning', field: 'warning'} ]}, listViewTemplateReadOnly: { columns: [ {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Description', field: 'Description', title: "Description", type: 'String'}, {name: 'Version', field: 'Version', title: "Version", type: 'String'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"}, {name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'}, {name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"}, {name: 'Log', field: 'log', title: "Log", type: 'StringList'} ], rowClasses: [ {className: 'error', field: 'error'}, {className: 'warning', field: 'warning'} ]} }); merge(config.macros.toolbar,{ moreLabel: "more", morePrompt: "Show additional commands", lessLabel: "less", lessPrompt: "Hide additional commands", separator: "|" }); merge(config.macros.refreshDisplay,{ label: "refresh", prompt: "Redraw the entire TiddlyWiki display" }); merge(config.macros.importTiddlers,{ readOnlyWarning: "You cannot import into a read-only TiddlyWiki file. Try opening it from a file:// URL", wizardTitle: "Import tiddlers from another file or server", step1Title: "Step 1: Locate the server or TiddlyWiki file", step1Html: "Specify the type of the server:
Enter the URL or pathname here:
...or browse for a file:

...or select a pre-defined feed: ", openLabel: "open", openPrompt: "Open the connection to this file or server", statusOpenHost: "Opening the host", statusGetWorkspaceList: "Getting the list of available workspaces", step2Title: "Step 2: Choose the workspace", step2Html: "Enter a workspace name:
...or select a workspace: ", cancelLabel: "cancel", cancelPrompt: "Cancel this import", statusOpenWorkspace: "Opening the workspace", statusGetTiddlerList: "Getting the list of available tiddlers", errorGettingTiddlerList: "Error getting list of tiddlers, click Cancel to try again", errorGettingTiddlerListHttp404: "Error retrieving tiddlers from url, please ensure the url exists. Click Cancel to try again.", errorGettingTiddlerListHttp: "Error retrieving tiddlers from url, please ensure this url exists and is CORS enabled", errorGettingTiddlerListFile: "Error retrieving tiddlers from local file, please make sure the file is in the same directory as your TiddlyWiki. Click Cancel to try again.", step3Title: "Step 3: Choose the tiddlers to import", step3Html: "
Keep these tiddlers linked to this server so that you can synchronise subsequent changes
Save the details of this server in a 'systemServer' tiddler called: ", importLabel: "import", importPrompt: "Import these tiddlers", confirmOverwriteText: "Are you sure you want to overwrite these tiddlers:\n\n%0", step4Title: "Step 4: Importing %0 tiddler(s)", step4Html: "", // DO NOT TRANSLATE doneLabel: "done", donePrompt: "Close this wizard", statusDoingImport: "Importing tiddlers", statusDoneImport: "All tiddlers imported", systemServerNamePattern: "%2 on %1", systemServerNamePatternNoWorkspace: "%1", confirmOverwriteSaveTiddler: "The tiddler '%0' already exists. Click 'OK' to overwrite it with the details of this server, or 'Cancel' to leave it unchanged", serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nThis tiddler was automatically created to record the details of this server", serverSaveModifier: "(System)", listViewTemplate: { columns: [ {name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'}, {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'} ], rowClasses: [ ]} }); merge(config.macros.upgrade,{ wizardTitle: "Upgrade TiddlyWiki core code", step1Title: "Update or repair this TiddlyWiki to the latest release", step1Html: "You are about to upgrade to the latest release of the TiddlyWiki core code (from %1). Your content will be preserved across the upgrade.

Note that core upgrades have been known to interfere with older plugins. If you run into problems with the upgraded file, see http://www.tiddlywiki.org/wiki/CoreUpgrades", errorCantUpgrade: "Unable to upgrade this TiddlyWiki. You can only perform upgrades on TiddlyWiki files stored locally", errorNotSaved: "You must save changes before you can perform an upgrade", step2Title: "Confirm the upgrade details", step2Html_downgrade: "You are about to downgrade to TiddlyWiki version %0 from %1.

Downgrading to an earlier version of the core code is not recommended", step2Html_restore: "This TiddlyWiki appears to be already using the latest version of the core code (%0).

You can continue to upgrade anyway to ensure that the core code hasn't been corrupted or damaged", step2Html_upgrade: "You are about to upgrade to TiddlyWiki version %0 from %1", upgradeLabel: "upgrade", upgradePrompt: "Prepare for the upgrade process", statusPreparingBackup: "Preparing backup", statusSavingBackup: "Saving backup file", errorSavingBackup: "There was a problem saving the backup file", statusLoadingCore: "Loading core code", errorLoadingCore: "Error loading the core code", errorCoreFormat: "Error with the new core code", statusSavingCore: "Saving the new core code", statusReloadingCore: "Reloading the new core code", startLabel: "start", startPrompt: "Start the upgrade process", cancelLabel: "cancel", cancelPrompt: "Cancel the upgrade process", step3Title: "Upgrade cancelled", step3Html: "You have cancelled the upgrade process" }); merge(config.macros.annotations,{ }); merge(config.commands.closeTiddler,{ text: "close", tooltip: "Close this tiddler"}); merge(config.commands.closeOthers,{ text: "close others", tooltip: "Close all other tiddlers"}); merge(config.commands.editTiddler,{ text: "edit", tooltip: "Edit this tiddler", readOnlyText: "view", readOnlyTooltip: "View the source of this tiddler"}); merge(config.commands.saveTiddler,{ text: "done", tooltip: "Save changes to this tiddler"}); merge(config.commands.cancelTiddler,{ text: "cancel", tooltip: "Undo changes to this tiddler", warning: "Are you sure you want to abandon your changes to '%0'?", readOnlyText: "done", readOnlyTooltip: "View this tiddler normally"}); merge(config.commands.deleteTiddler,{ text: "delete", tooltip: "Delete this tiddler", warning: "Are you sure you want to delete '%0'?"}); merge(config.commands.permalink,{ text: "permalink", tooltip: "Permalink for this tiddler"}); merge(config.commands.references,{ text: "references", tooltip: "Show tiddlers that link to this one", popupNone: "No references"}); merge(config.commands.jump,{ text: "jump", tooltip: "Jump to another open tiddler"}); merge(config.commands.fields,{ text: "fields", tooltip: "Show the extended fields of this tiddler", emptyText: "There are no extended fields for this tiddler", listViewTemplate: { columns: [ {name: 'Field', field: 'field', title: "Field", type: 'String'}, {name: 'Value', field: 'value', title: "Value", type: 'String'} ], rowClasses: [ ], buttons: [ ]}}); merge(config.shadowTiddlers,{ DefaultTiddlers: "[[GettingStarted]]", MainMenu: "[[GettingStarted]]", SiteTitle: "My TiddlyWiki", SiteSubtitle: "a reusable non-linear personal web notebook", SiteUrl: "", SideBarOptions: '>>>>>>>', SideBarTabs: '>', TabMore: '>' }); merge(config.annotations,{ AdvancedOptions: "This shadow tiddler provides access to several advanced options", ColorPalette: "These values in this shadow tiddler determine the colour scheme of the ~TiddlyWiki user interface", DefaultTiddlers: "The tiddlers listed in this shadow tiddler will be automatically displayed when ~TiddlyWiki starts up", EditTemplate: "The HTML template in this shadow tiddler determines how tiddlers look while they are being edited", GettingStarted: "This shadow tiddler provides basic usage instructions", ImportTiddlers: "This shadow tiddler provides access to importing tiddlers", MainMenu: "This shadow tiddler is used as the contents of the main menu in the left-hand column of the screen", MarkupPreHead: "This tiddler is inserted at the top of the section of the TiddlyWiki HTML file", MarkupPostHead: "This tiddler is inserted at the bottom of the section of the TiddlyWiki HTML file", MarkupPreBody: "This tiddler is inserted at the top of the section of the TiddlyWiki HTML file", MarkupPostBody: "This tiddler is inserted at the end of the section of the TiddlyWiki HTML file immediately after the script block", OptionsPanel: "This shadow tiddler is used as the contents of the options panel slider in the right-hand sidebar", PageTemplate: "The HTML template in this shadow tiddler determines the overall ~TiddlyWiki layout", PluginManager: "This shadow tiddler provides access to the plugin manager", SideBarOptions: "This shadow tiddler is used as the contents of the option panel in the right-hand sidebar", SideBarTabs: "This shadow tiddler is used as the contents of the tabs panel in the right-hand sidebar", SiteSubtitle: "This shadow tiddler is used as the second part of the page title", SiteTitle: "This shadow tiddler is used as the first part of the page title", SiteUrl: "This shadow tiddler should be set to the full target URL for publication", StyleSheetColors: "This shadow tiddler contains CSS definitions related to the color of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler", StyleSheet: "This tiddler can contain custom CSS definitions", StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler", StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale", StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing", SystemSettings: "This tiddler is used to store configuration options for this TiddlyWiki document", TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar", TabMore: "This shadow tiddler contains the contents of the 'More' tab in the right-hand sidebar", TabMoreMissing: "This shadow tiddler contains the contents of the 'Missing' tab in the right-hand sidebar", TabMoreOrphans: "This shadow tiddler contains the contents of the 'Orphans' tab in the right-hand sidebar", TabMoreShadowed: "This shadow tiddler contains the contents of the 'Shadowed' tab in the right-hand sidebar", TabTags: "This shadow tiddler contains the contents of the 'Tags' tab in the right-hand sidebar", TabTimeline: "This shadow tiddler contains the contents of the 'Timeline' tab in the right-hand sidebar", ToolbarCommands: "This shadow tiddler determines which commands are shown in tiddler toolbars", ViewTemplate: "The HTML template in this shadow tiddler determines how tiddlers look" }); //-- //-- Paramifiers //-- function getParameters() { var p = null; if(window.location.hash) { p = decodeURIComponent(window.location.hash.substr(1)); if(config.browser.firefoxDate != null && config.browser.firefoxDate[1] 1) { last.element.setAttribute("colspan",colSpanCount); last.element.setAttribute("colSpan",colSpanCount); // Needed for IE colSpanCount = 1; } } w.nextMatch = this.cellRegExp.lastIndex-1; } else if(cellMatch[1] == ">") { // Colspan colSpanCount++; w.nextMatch = this.cellRegExp.lastIndex-1; } else if(cellMatch[2]) { // End of row if(prevCell && colSpanCount > 1) { prevCell.setAttribute("colspan",colSpanCount); prevCell.setAttribute("colSpan",colSpanCount); // Needed for IE } w.nextMatch = this.cellRegExp.lastIndex; break; } else { // Cell w.nextMatch++; var styles = config.formatterHelpers.inlineCssHelper(w); var spaceLeft = false; var chr = w.source.substr(w.nextMatch,1); while(chr == " ") { spaceLeft = true; w.nextMatch++; chr = w.source.substr(w.nextMatch,1); } var cell; if(chr == "!") { cell = createTiddlyElement(e,"th"); w.nextMatch++; } else { cell = createTiddlyElement(e,"td"); } prevCell = cell; prevColumns[col] = {rowSpanCount:1,element:cell}; if(colSpanCount > 1) { cell.setAttribute("colspan",colSpanCount); cell.setAttribute("colSpan",colSpanCount); // Needed for IE colSpanCount = 1; } config.formatterHelpers.applyCssHelper(cell,styles); w.subWikifyTerm(cell,this.cellTermRegExp); if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight cell.align = spaceLeft ? "center" : "left"; else if(spaceLeft) cell.align = "right"; w.nextMatch--; } col++; this.cellRegExp.lastIndex = w.nextMatch; cellMatch = this.cellRegExp.exec(w.source); } } }, { name: "heading", match: "^!{1,6}", termRegExp: /(\n)/mg, handler: function(w) { w.subWikifyTerm(createTiddlyElement(w.output,"h" + w.matchLength),this.termRegExp); } }, { name: "list", 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) { if(lookaheadMatch[1]) { listType = "ul"; itemType = "li"; } else if(lookaheadMatch[2]) { listType = "ol"; itemType = "li"; } else if(lookaheadMatch[3]) { listType = "dl"; itemType = "dt"; } else if(lookaheadMatch[4]) { listType = "dl"; itemType = "dd"; } if(!baseType) baseType = listType; listLevel = lookaheadMatch[0].length; w.nextMatch += lookaheadMatch[0].length; var t; if(listLevel > currLevel) { for(t=currLevel; tlistLevel; 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: "quoteByBlock", match: "^+", lookaheadRegExp: /^>+/mg, termRegExp: /(\n)/mg, element: "blockquote", handler: function(w) { var stack = [w.output]; var currLevel = 0; var newLevel = w.matchLength; var t,matched; do { if(newLevel > currLevel) { for(t=currLevel; tnewLevel; t--) stack.pop(); } currLevel = newLevel; w.subWikifyTerm(stack[stack.length-1],this.termRegExp); createTiddlyElement(stack[stack.length-1],"br"); this.lookaheadRegExp.lastIndex = w.nextMatch; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch; if(matched) { newLevel = lookaheadMatch[0].length; w.nextMatch += lookaheadMatch[0].length; } } while(matched); } }, { name: "rule", match: "^----+$\\n?|
\\n?", handler: function(w) { createTiddlyElement(w.output,"hr"); } }, { name: "monospacedByLine", match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|)\\n", element: "pre", handler: function(w) { switch(w.matchText) { case "/*{{{*/\n": // CSS this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\*\}\}\}\*\/$\n?)/mg; break; case "{{{\n": // monospaced block this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\f*\}\}\}$\n?)/mg; break; case "//{{{\n": // plugin this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\/\}\}\}$\n?)/mg; break; case "\n": //template this.lookaheadRegExp = /\n*((?:^[^\n]*\n)+?)(\n*^\f*$\n?)/mg; break; default: break; } config.formatterHelpers.enclosedTextHelper.call(this,w); } }, { name: "wikifyComment", match: "^(?:/\\*\\*\\*|\n)/mg); w.subWikifyTerm(w.output,termRegExp); } }, { name: "macro", match: "\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: "prettyLink", 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 text = lookaheadMatch[1]; if(lookaheadMatch[3]) { // Pretty bracketted link var link = lookaheadMatch[3]; e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link)) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler); } else { // Simple bracketted link e = createTiddlyLink(w.output,text,false,null,w.isStatic,w.tiddler); } createTiddlyText(e,text); w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "wikiLink", match: config.textPrimitives.unWikiLink+"?"+config.textPrimitives.wikiLink, handler: function(w) { if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink) { w.outputText(w.output,w.matchStart+1,w.nextMatch); return; } if(w.matchStart > 0) { var preRegExp = new RegExp(config.textPrimitives.anyLetterStrict,"mg"); preRegExp.lastIndex = w.matchStart-1; var preMatch = preRegExp.exec(w.source); if(preMatch.index == w.matchStart-1) { w.outputText(w.output,w.matchStart,w.nextMatch); return; } } if(w.autoLinkWikiWords || store.isShadowTiddler(w.matchText)) { var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler); w.outputText(link,w.matchStart,w.nextMatch); } else { w.outputText(w.output,w.matchStart,w.nextMatch); } } }, { name: "urlLink", match: config.textPrimitives.urlPattern, handler: function(w) { w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch); } }, { name: "image", match: "\\[[]?[Ii][Mm][Gg]\\[", lookaheadRegExp: /\[([?)[Ii][Mm][Gg]\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg, handler: function(w) { this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { var e = w.output; if(lookaheadMatch[5]) { var link = lookaheadMatch[5]; e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler); jQuery(e).addClass("imageLink"); } var img = createTiddlyElement(e,"img"); if(lookaheadMatch[1]) img.align = "left"; else if(lookaheadMatch[2]) img.align = "right"; if(lookaheadMatch[3]) { img.title = lookaheadMatch[3]; img.setAttribute("alt",lookaheadMatch[3]); } img.src = lookaheadMatch[4]; w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "html", 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) { createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1]; w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "commentByBlock", 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: "characterFormat", match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{", handler: function(w) { switch(w.matchText) { case "''": w.subWikifyTerm(w.output.appendChild(document.createElement("strong")),/('')/mg); break; case "//": w.subWikifyTerm(createTiddlyElement(w.output,"em"),/(\/\/)/mg); break; case "__": w.subWikifyTerm(createTiddlyElement(w.output,"u"),/(__)/mg); break; case "^^": w.subWikifyTerm(createTiddlyElement(w.output,"sup"),/(\^\^)/mg); break; case "~~": w.subWikifyTerm(createTiddlyElement(w.output,"sub"),/(~~)/mg); break; case "--": w.subWikifyTerm(createTiddlyElement(w.output,"strike"),/(--)/mg); break; case "{{{": var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg; lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]); w.nextMatch = lookaheadRegExp.lastIndex; } break; } } }, { name: "customFormat", match: "@@|\\{\\{", handler: function(w) { switch(w.matchText) { case "@@": var e = createTiddlyElement(w.output,"span"); var styles = config.formatterHelpers.inlineCssHelper(w); if(styles.length == 0) e.className = "marked"; else config.formatterHelpers.applyCssHelper(e,styles); w.subWikifyTerm(e,/(@@)/mg); break; case "{{": var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg; lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = lookaheadRegExp.exec(w.source); if(lookaheadMatch) { w.nextMatch = lookaheadRegExp.lastIndex; e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]); w.subWikifyTerm(e,/(\}\}\})/mg); } break; } } }, { name: "mdash", match: "--", handler: function(w) { createTiddlyElement(w.output,"span").innerHTML = "—"; } }, { name: "lineBreak", match: "\\n|
", handler: function(w) { createTiddlyElement(w.output,"br"); } }, { name: "rawText", match: "\"{3}|", lookaheadRegExp: /(?:\"{3}|)((?:.|\n)*?)(?:\"{3}|)/mg, handler: function(w) { this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { createTiddlyElement(w.output,"span",null,null,lookaheadMatch[1]); w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "htmlEntitiesEncoding", match: "(?:(?:?[a-zA-Z0-9]{2,8};|.)(?:?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|?[a-zA-Z0-9]{2,8};)", handler: function(w) { createTiddlyElement(w.output,"span").innerHTML = w.matchText; } } ]; //-- //-- Wikifier //-- function getParser(tiddler,format) { if(tiddler) { if(!format) format = tiddler.fields["wikiformat"]; var i; if(format) { for(i in config.parsers) { if(format == config.parsers[i].format) return config.parsers[i]; } } else { for(i in config.parsers) { if(tiddler.isTagged(config.parsers[i].formatTag)) return config.parsers[i]; } } } return formatter; } function Wikifier(source,formatter,highlightRegExp,tiddler) { this.source = source; this.output = null; this.formatter = formatter; this.nextMatch = 0; this.autoLinkWikiWords = tiddler && tiddler.autoLinkWikiWords() == false ? false : true; this.highlightRegExp = highlightRegExp; this.highlightMatch = null; this.isStatic = false; if(highlightRegExp) { highlightRegExp.lastIndex = 0; this.highlightMatch = highlightRegExp.exec(source); } this.tiddler = tiddler; } Wikifier.prototype.wikifyPlain = function() { var e = createTiddlyElement(document.body,"div"); e.style.display = "none"; this.subWikify(e); var text = jQuery(e).text(); jQuery(e).remove(); return text; }; Wikifier.prototype.subWikify = function(output,terminator) { try { if(terminator) this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg")); else this.subWikifyUnterm(output); } catch(ex) { showException(ex); } }; Wikifier.prototype.subWikifyUnterm = function(output) { var oldOutput = this.output; this.output = output; this.formatter.formatterRegExp.lastIndex = this.nextMatch; var formatterMatch = this.formatter.formatterRegExp.exec(this.source); while(formatterMatch) { // Output any text before the match if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); // Set the match parameters for the handler this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; var t; for(t=1; t this.nextMatch) this.outputText(this.output,this.nextMatch,terminatorMatch.index); this.matchText = terminatorMatch[1]; this.matchLength = terminatorMatch[1].length; this.matchStart = terminatorMatch.index; this.nextMatch = this.matchStart + this.matchLength; this.output = oldOutput; return; } if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; var t; for(t=1; t startPos) && (this.highlightMatch.index startPos) { createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index)); startPos = this.highlightMatch.index; } var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos); createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd)); startPos = highlightEnd; if(startPos >= this.highlightRegExp.lastIndex) this.highlightMatch = this.highlightRegExp.exec(this.source); } if(startPos 0) text = text.substr(0,limit); var wikifier = new Wikifier(text,formatter,null,tiddler); return wikifier.wikifyPlain(); } function highlightify(source,output,highlightRegExp,tiddler) { if(source) { var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler); wikifier.outputText(output,0,source.length); } } //-- //-- Macro definitions //-- function invokeMacro(place,macro,params,wikifier,tiddler) { try { var m = config.macros[macro]; if(m && m.handler) { var tiddlerElem = story.findContainingTiddler(place); window.tiddler = tiddlerElem ? store.getTiddler(tiddlerElem.getAttribute("tiddler")) : null; window.place = place; var allowEval = true; if(config.evaluateMacroParameters=="system") { if(!tiddler || tiddler.tags.indexOf("systemAllowEval") == -1) { allowEval = false; } } m.handler(place,macro,m.noPreParse?null:params.readMacroParams(!allowEval),wikifier,params,tiddler); } else { createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,config.messages.missingMacro])); } } catch(ex) { createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,ex.toString()])); } } config.macros.version.handler = function(place) { jQuery("").text(formatVersion()).appendTo(place); }; config.macros.today.handler = function(place,macroName,params) { var now = new Date(); var text = params[0] ? now.formatString(params[0].trim()) : now.toLocaleString(); jQuery("").text(text).appendTo(place); }; config.macros.list.template = ">"; config.macros.list.handler = function(place,macroName,params,wikifier,paramString) { var list = document.createElement("ul"); jQuery(list).attr({ refresh: "macro", macroName: macroName }).data("params", paramString); place.appendChild(list); this.refresh(list); }; config.macros.list.refresh = function(list) { var paramString = jQuery(list).data("params"); var params = paramString.readMacroParams(); var args = paramString.parseParams("anon", null, null)[0]; var type = args.anon ? args.anon[0] : "all"; jQuery(list).empty().addClass("list list-" + type); var template = args.template ? store.getTiddlerText(args.template[0]) : false; if(!template) { template = config.macros.list.template; } if(this[type].prompt) createTiddlyElement(list,"li",null,"listTitle",this[type].prompt); var results; if(this[type].handler) results = this[type].handler(params); var t; for(t = 0; t ").text(args.emptyMessage[0]).appendTo(list); } }; config.macros.list.all.handler = function(params) { return store.reverseLookup("tags","excludeLists",false,"title"); }; config.macros.list.missing.handler = function(params) { return store.getMissingLinks(); }; config.macros.list.orphans.handler = function(params) { return store.getOrphans(); }; config.macros.list.shadowed.handler = function(params) { return store.getShadowed(); }; config.macros.list.touched.handler = function(params) { return store.getTouched(); }; config.macros.list.filter.handler = function(params) { var filter = params[1]; var results = []; if(filter) { var tiddlers = store.filterTiddlers(filter); var t; for(t=0; t").attr("params", paramString). attr("macroName", macroName).appendTo(place)[0]; macro.refresh(container); }, refresh: function(container) { jQuery(container).attr("refresh", "macro").empty(); var paramString = jQuery(container).attr("params"); var args = paramString.parseParams("anon", null, null)[0]; var params = args.anon || []; var field = params[0] || "modified"; var prefix = field.charAt(0); var no_prefix_field = prefix === "-" || prefix === "+" ? field.substr(1, field.length) : field; var dateFormat = params[2] || this.dateFormat; var groupTemplate = macro.groupTemplate.format(no_prefix_field, dateFormat); groupTemplate = args.groupTemplate ? store.getTiddlerText(args.groupTemplate[0]) || groupTemplate : groupTemplate; var itemTemplate = macro.itemTemplate; itemTemplate = args.template ? store.getTiddlerText(args.template[0]) || itemTemplate : itemTemplate; var tiddlers = args.filter ? store.sortTiddlers(store.filterTiddlers(args.filter[0]), field) : store.reverseLookup("tags", "excludeLists", false, field); var lastGroup = "", ul; var last = params[1] ? tiddlers.length-Math.min(tiddlers.length,parseInt(params[1],10)) : 0; var t; for(t=tiddlers.length-1; t>=last; t--) { var tiddler = tiddlers[t]; var theGroup = wikifyPlainText(groupTemplate,0,tiddler); if(typeof(ul) == "undefined" || theGroup != lastGroup) { ul = document.createElement("ul"); jQuery(ul).addClass("timeline"); container.appendChild(ul); createTiddlyElement(ul,"li",null,"listTitle",theGroup); lastGroup = theGroup; } var item = createTiddlyElement(ul,"li",null,"listLink"); wikify(itemTemplate,item,null,tiddler); } }, groupTemplate: ">", itemTemplate: ">" }); config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var allowEval = true; var stack = config.macros.tiddler.tiddlerStack; if(stack.length > 0 && config.evaluateMacroParameters == "system") { // included tiddler and "system" evaluation required, so check tiddler tagged appropriately var title = stack[stack.length-1]; var pos = title.indexOf(config.textPrimitives.sectionSeparator); if(pos != -1) { title = title.substr(0,pos); // get the base tiddler title } var t = store.getTiddler(title); if(!t || t.tags.indexOf("systemAllowEval") == -1) { allowEval = false; } } params = paramString.parseParams("name",null,allowEval,false,true); var names = params[0]["name"]; var tiddlerName = names[0]; var className = names[1] || null; var args = params[0]["with"]; var wrapper = createTiddlyElement(place,"span",null,className,null,{ refresh: "content", tiddler: tiddlerName }); if(args!==undefined) wrapper.setAttribute("args","[["+args.join("]] [[")+"]]"); this.transclude(wrapper,tiddlerName,args); }; config.macros.tiddler.transclude = function(wrapper,tiddlerName,args) { var text = store.getTiddlerText(tiddlerName); if(!text) return; var stack = config.macros.tiddler.tiddlerStack; if(stack.indexOf(tiddlerName) !== -1) return; stack.push(tiddlerName); try { if(typeof args == "string") args = args.readBracketedList(); var n = args ? Math.min(args.length,9) : 0; var i; for(i=0; i> config.macros.gradient.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var panel = wikifier ? createTiddlyElement(place,"div",null,"gradient") : place; panel.style.position = "relative"; panel.style.overflow = "hidden"; panel.style.zIndex = "0"; if(wikifier) { var styles = config.formatterHelpers.inlineCssHelper(wikifier); config.formatterHelpers.applyCssHelper(panel,styles); } params = paramString.parseParams("color"); var locolors = [], hicolors = []; var t; for(t=2; t>"); if(document.all) { panel.style.height = "100%"; panel.style.width = "100%"; } }; config.macros.message.handler = function(place,macroName,params) { if(params[0]) { var names = params[0].split("."); var lookupMessage = function(root,nameIndex) { if(root[names[nameIndex]]) { if(nameIndex 50) return; if(config.macros.view.depth>0) { if (value==config.macros.view.values[config.macros.view.depth-1]) { return; } } config.macros.view.values[config.macros.view.depth] = value; config.macros.view.depth++; if(params[2]) value=params[2].unescapeLineBreaks().format([value]); wikify(value,place,highlightHack,tiddler); config.macros.view.depth--; config.macros.view.values[config.macros.view.depth] = null; }, date: function(value,place,params,wikifier,paramString,tiddler) { value = Date.convertFromYYYYMMDDHHMM(value); createTiddlyText(place,value.formatString(params[2] || config.views.wikified.dateFormat)); } }; config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler) { if((tiddler instanceof Tiddler) && params[0]) { var value = store.getValue(tiddler,params[0]); if(value) { var type = params[1] || config.macros.view.defaultView; var handler = config.macros.view.views[type]; if(handler) handler(value,place,params,wikifier,paramString,tiddler); } } }; config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var field = params[0]; var rows = params[1] || 0; var defVal = params[2] || ''; if((tiddler instanceof Tiddler) && field) { story.setDirty(tiddler.title,true); var e,v; if(field != "text" && !rows) { e = createTiddlyElement(null,"input",null,null,null,{ type: "text", edit: field, size: "40", autocomplete: "off" }); e.value = store.getValue(tiddler,field) || defVal; place.appendChild(e); } else { var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix"); var wrapper2 = createTiddlyElement(wrapper1,"div"); e = createTiddlyElement(wrapper2,"textarea"); e.value = v = store.getValue(tiddler,field) || defVal; rows = rows || 10; var lines = v.match(/\n/mg); var maxLines = Math.max(parseInt(config.options.txtMaxEditRows,10),5); if(lines != null && lines.length > rows) rows = lines.length + 5; rows = Math.min(rows,maxLines); e.setAttribute("rows",rows); e.setAttribute("edit",field); place.appendChild(wrapper1); } if(tiddler.isReadOnly()) { e.setAttribute("readOnly","readOnly"); jQuery(e).addClass("readOnly"); } return e; } }; config.macros.tagChooser.onClick = function(ev) { var e = ev || window.event; var lingo = config.views.editor.tagChooser; var popup = Popup.create(this); var tags = store.getTags(this.getAttribute("tags")); if(tags.length == 0) jQuery("
  • ").text(lingo.popupNone).appendTo(popup); var t; for(t=0; t 0) btn.setAttribute("params",tags.join("|")); btn.setAttribute("newFocus",newFocus); btn.setAttribute("newTemplate",getParam(params,"template",DEFAULT_EDIT_TEMPLATE)); if(customFields !== "") btn.setAttribute("customFields",customFields); var text = getParam(params,"text"); if(text !== undefined) btn.setAttribute("newText",text); return btn; }; config.macros.newTiddler.onClickNewTiddler = function() { var title = this.getAttribute("newTitle"); if(this.getAttribute("isJournal") == "true") { title = new Date().formatString(title.trim()); } var params = this.getAttribute("params"); var tags = params ? params.split("|") : []; var focus = this.getAttribute("newFocus"); var template = this.getAttribute("newTemplate"); var customFields = this.getAttribute("customFields"); if(!customFields && !store.isShadowTiddler(title)) customFields = String.encodeHashMap(config.defaultCustomFields); story.displayTiddler(null,title,template,false,null,null); var tiddlerElem = story.getTiddler(title); if(customFields) story.addCustomFields(tiddlerElem,customFields); var text = this.getAttribute("newText"); if(typeof text == "string" && story.getTiddlerField(title,"text")) story.getTiddlerField(title,"text").value = text.format([title]); var t; for(t=0;t 0) { story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch); txt.setAttribute("lastSearchText",txt.value); } }; config.macros.search.onClick = function(e) { config.macros.search.doSearch(this.nextSibling); return false; }; config.macros.search.onKeyPress = function(ev) { var me = config.macros.search; var e = ev || window.event; switch(e.keyCode) { case 9: // Tab return; case 13: // Ctrl-Enter case 10: // Ctrl-Enter on IE PC me.doSearch(this); break; case 27: // Escape this.value = ""; clearMessage(); break; } if(config.options.chkIncrementalSearch) { if(this.value.length > 2) { if(this.value != this.getAttribute("lastSearchText")) { if(me.timeout) { clearTimeout(me.timeout); } var txt = this; me.timeout = setTimeout(function() {me.doSearch(txt);},500); } } else { if(me.timeout) { clearTimeout(me.timeout); } } } }; config.macros.search.onFocus = function(e) { this.select(); }; //-- //-- Tabs macro //-- config.macros.tabs.handler = function(place,macroName,params) { var cookie = params[0]; var numTabs = (params.length-1)/3; var wrapper = createTiddlyElement(null,"div",null,"tabsetWrapper " + cookie); var tabset = createTiddlyElement(wrapper,"div",null,"tabset"); tabset.setAttribute("cookie",cookie); var validTab = false; var t; for(t=0; t": btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore); jQuery(btn).addClass("moreCommand"); var e = createTiddlyElement(place,"span",null,"moreCommand"); e.style.display = "none"; place = e; break; default: var className = ""; switch(c.substr(0,1)) { case "+": className = "defaultCommand"; c = c.substr(1); break; case "-": className = "cancelCommand"; c = c.substr(1); break; } if(config.commands[c]) { this.createCommand(place,c,tiddler,className); } else { this.customCommand(place,c,wikifier,tiddler); } break; } } }; // Overrideable function to extend toolbar handler config.macros.toolbar.customCommand = function(place,command,wikifier,tiddler) { }; //-- //-- Menu and toolbar commands //-- config.commands.closeTiddler.handler = function(event,src,title) { if(story.isDirty(title) && !readOnly) { if(!confirm(config.commands.cancelTiddler.warning.format([title]))) return false; } story.setDirty(title,false); story.closeTiddler(title,true); return false; }; config.commands.closeOthers.handler = function(event,src,title) { story.closeAllTiddlers(title); return false; }; config.commands.editTiddler.handler = function(event,src,title) { clearMessage(); var tiddlerElem = story.getTiddler(title); var fields = tiddlerElem.getAttribute("tiddlyFields"); story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,fields); var e = story.getTiddlerField(title,config.options.txtEditorFocus||"text"); if(e) { setCaretPosition(e,0); } return false; }; config.commands.saveTiddler.handler = function(event,src,title) { var newTitle = story.saveTiddler(title,event.shiftKey); if(newTitle) story.displayTiddler(null,newTitle); return false; }; config.commands.cancelTiddler.handler = function(event,src,title) { if(story.hasChanges(title) && !readOnly) { if(!confirm(this.warning.format([title]))) return false; } story.setDirty(title,false); story.displayTiddler(null,title); return false; }; config.commands.deleteTiddler.handler = function(event,src,title) { var deleteIt = true; if(config.options.chkConfirmDelete) deleteIt = confirm(this.warning.format([title])); if(deleteIt) { store.removeTiddler(title); story.closeTiddler(title,true); autoSaveChanges(); } return false; }; config.commands.permalink.handler = function(event,src,title) { var t = encodeURIComponent(String.encodeTiddlyLink(title)); if(window.location.hash != t) window.location.hash = t; return false; }; config.commands.references.handlePopup = function(popup,title) { var references = store.getReferringTiddlers(title); var c = false; var r; for(r=0; r 0) ListView.create(popup,items,this.listViewTemplate); else createTiddlyElement(popup,"div",null,null,this.emptyText); }; //-- //-- Tiddler() object //-- function Tiddler(title) { this.title = title; this.text = ""; this.creator = null; this.modifier = null; this.created = new Date(); this.modified = this.created; this.links = []; this.linksUpdated = false; this.tags = []; this.fields = {}; return this; } Tiddler.prototype.getLinks = function() { if(this.linksUpdated==false) this.changed(); return this.links; }; // Returns the fields that are inherited in string field:"value" field2:"value2" format Tiddler.prototype.getInheritedFields = function() { var f = {}; var i; for(i in this.fields) { if(i=="server.host" || i=="server.workspace" || i=="wikiformat"|| i=="server.type") { f[i] = this.fields[i]; } } return String.encodeHashMap(f); }; // Increment the changeCount of a tiddler Tiddler.prototype.incChangeCount = function() { var c = this.fields['changecount']; c = c ? parseInt(c,10) : 0; this.fields['changecount'] = String(c+1); }; // Clear the changeCount of a tiddler Tiddler.prototype.clearChangeCount = function() { if(this.fields['changecount']) { delete this.fields['changecount']; } }; Tiddler.prototype.doNotSave = function() { return this.fields['doNotSave']; }; // Returns true if the tiddler has been updated since the tiddler was created or downloaded Tiddler.prototype.isTouched = function() { var changecount = this.fields.changecount || 0; return changecount > 0; }; // Change the text and other attributes of a tiddler Tiddler.prototype.set = function(title,text,modifier,modified,tags,created,fields,creator) { this.assign(title,text,modifier,modified,tags,created,fields,creator); this.changed(); return this; }; // Change the text and other attributes of a tiddler without triggered a tiddler.changed() call Tiddler.prototype.assign = function(title,text,modifier,modified,tags,created,fields,creator) { if(title != undefined) this.title = title; if(text != undefined) this.text = text; if(modifier != undefined) this.modifier = modifier; if(modified != undefined) this.modified = modified; if(creator != undefined) this.creator = creator; if(created != undefined) this.created = created; if(fields != undefined) this.fields = fields; if(tags != undefined) this.tags = (typeof tags == "string") ? tags.readBracketedList() : tags; else if(this.tags == undefined) this.tags = []; return this; }; // Get the tags for a tiddler as a string (space delimited, using [[brackets]] for tags containing spaces) Tiddler.prototype.getTags = function() { return String.encodeTiddlyLinkList(this.tags); }; // Test if a tiddler carries a tag Tiddler.prototype.isTagged = function(tag) { return this.tags.indexOf(tag) != -1; }; // Static method to convert "\n" to newlines, "\s" to "\" Tiddler.unescapeLineBreaks = function(text) { return text ? text.unescapeLineBreaks() : ""; }; // Convert newlines to "\n", "\" to "\s" Tiddler.prototype.escapeLineBreaks = function() { return this.text.escapeLineBreaks(); }; // Updates the secondary information (like links[] array) after a change to a tiddler Tiddler.prototype.changed = function() { this.links = []; var text = this.text; // remove 'quoted' text before scanning tiddler source text = text.replace(/\/%((?:.|\n)*?)%\//g,""). replace(/\{{3}((?:.|\n)*?)\}{3}/g,""). replace(/"""((?:.|\n)*?)"""/g,""). replace(/((?:.|\n)*?)/g,""). replace(/\>((?:.|\n)*?)/g,""). replace(/
  • \n" : tiddler.text.escapeLineBreaks().htmlEncode() ]); } catch (ex) { throw exceptionText(ex,config.messages.tiddlerSaveError.format([tiddler.title])); } }; /*** |''Name''|TiddlyWebAdaptor| |''Description''|adaptor for interacting with TiddlyWeb| |''Author:''|FND| |''Contributors''|Chris Dent, Martin Budden| |''Version''|1.4.10| |''Status''|stable| |''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js| |''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/| |''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]| |''CoreVersion''|2.5| |''Keywords''|serverSide TiddlyWeb| !Notes This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]]. !To Do * createWorkspace * document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin) !Code ***/ //{{{ (function($) { var adaptor = config.adaptors.tiddlyweb = function() {}; adaptor.prototype = new AdaptorBase(); adaptor.serverType = "tiddlyweb"; adaptor.serverLabel = "TiddlyWeb"; adaptor.mimeType = "application/json"; adaptor.parsingErrorMessage = "Error parsing result from server"; adaptor.noBagErrorMessage = "no bag specified for tiddler"; adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename // retrieve current status (requires TiddlyWeb status plugin) adaptor.prototype.getStatus = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); var uriTemplate = "%0/status"; var uri = uriTemplate.format([context.host]); var req = httpReq("GET", uri, adaptor.getStatusCallback, context, null, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) { context.status = responseText ? status : false; try { context.statusText = xhr.statusText; } catch(exc) { // offline (Firefox) context.status = false; context.statusText = null; } context.httpStatus = xhr.status; if(context.status) { context.serverStatus = $.evalJSON(responseText); // XXX: error handling!? } if(context.callback) { context.callback(context, context.userParams); } }; // retrieve a list of workspaces adaptor.prototype.getWorkspaceList = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); context.workspaces = []; var uriTemplate = "%0/recipes"; // XXX: bags? var uri = uriTemplate.format([context.host]); var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback, context, { accept: adaptor.mimeType }, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(status) { try { var workspaces = $.evalJSON(responseText); } catch(ex) { context.status = false; // XXX: correct? context.statusText = exceptionText(ex, adaptor.parsingErrorMessage); if(context.callback) { context.callback(context, context.userParams); } return; } context.workspaces = workspaces.map(function(itm) { return { title: itm }; }); } if(context.callback) { context.callback(context, context.userParams); } }; // retrieve a list of tiddlers adaptor.prototype.getTiddlerList = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); var uriTemplate = "%0/%1/%2/tiddlers%3"; var params = context.filters ? "?" + context.filters : ""; if(context.format) { params = context.format + params; } var workspace = adaptor.resolveWorkspace(context.workspace); var uri = uriTemplate.format([context.host, workspace.type + "s", adaptor.normalizeTitle(workspace.name), params]); var req = httpReq("GET", uri, adaptor.getTiddlerListCallback, context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(status) { context.tiddlers = []; try { var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances } catch(ex) { context.status = false; // XXX: correct? context.statusText = exceptionText(ex, adaptor.parsingErrorMessage); if(context.callback) { context.callback(context, context.userParams); } return; } for(var i = 0; i /" revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/"); } revisions[i].title = to.title; } // add new revision var rev = $.extend({}, revisions[0]); $.each(newTiddler, function(i, item) { if(!$.isFunction(item)) { rev[i] = item; } }); rev.title = to.title; rev.created = rev.created.convertToYYYYMMDDHHMM(); rev.modified = new Date().convertToYYYYMMDDHHMM(); delete rev.fields.changecount; revisions.unshift(rev); if(to.workspace) { context.workspace = to.workspace; } else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag context.workspace = "bags/" + rev.bag; } var subCallback = function(context, userParams) { if(!context.status) { return callback(context, userParams); } context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler); }; return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback); }; var _deleteTiddler = function(context, userParams) { if(!context.status) { return callback(context, userParams); } $.extend(true, newTiddler, context.tiddler); context.callback = null; return self.deleteTiddler(oldTiddler, context, context.userParams, callback); }; callback = callback || function() {}; context = this.setContext(context, userParams); context.host = context.host || oldTiddler.fields["server.host"]; context.workspace = from.workspace || oldTiddler.fields["server.workspace"]; return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle); }; // delete an individual tiddler adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) { context = this.setContext(context, userParams, callback); context.title = tiddler.title; // XXX: not required!? var uriTemplate = "%0/bags/%1/tiddlers/%2"; var host = context.host || this.fullHostName(tiddler.fields["server.host"]); var bag = tiddler.fields["server.bag"]; if(!bag) { return adaptor.noBagErrorMessage; } var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag), adaptor.normalizeTitle(tiddler.title)]); var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler); var headers = etag ? { "If-Match": etag } : null; var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) { context.status = [204, 1223].contains(xhr.status); context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(context.callback) { context.callback(context, context.userParams); } }; // compare two revisions of a tiddler (requires TiddlyWeb differ plugin) adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) { context = this.setContext(context, userParams, callback); context.title = title; var tiddler = store.getTiddler(title); try { var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]); } catch(ex) { return adaptor.locationIDErrorMessage; } var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/"); var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef; var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null; var uriTemplate = "%0/diff?rev1=%1"; if(rev2) { uriTemplate += "&rev2=%2"; } if(context.format) { uriTemplate += "&format=%3"; } var host = context.host || this.fullHostName(tiddler.fields["server.host"]); var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1), adaptor.normalizeTitle(rev2), context.format]); if(rev2) { var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null, null, null, null, null, true); } else { var payload = { title: tiddler.title, text: tiddler.text, modifier: tiddler.modifier, tags: tiddler.tags, fields: $.extend({}, tiddler.fields) }; // XXX: missing attributes!? payload = $.toJSON(payload); req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context, null, payload, adaptor.mimeType, null, null, true); } return typeof req == "string" ? req : true; }; adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; context.uri = uri; if(status) { context.diff = responseText; } if(context.callback) { context.callback(context, context.userParams); } }; // generate tiddler information adaptor.prototype.generateTiddlerInfo = function(tiddler) { var info = {}; var uriTemplate = "%0/%1/%2/tiddlers/%3"; var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete? host = this.fullHostName(host); var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]); info.uri = uriTemplate.format([host, workspace.type + "s", adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(tiddler.title)]); return info; }; // create Tiddler instance from TiddlyWeb tiddler JSON adaptor.toTiddler = function(json, host) { var created = Date.convertFromYYYYMMDDHHMM(json.created); var modified = Date.convertFromYYYYMMDDHHMM(json.modified); var fields = json.fields; fields["server.type"] = adaptor.serverType; fields["server.host"] = AdaptorBase.minHostName(host); fields["server.bag"] = json.bag; fields["server.title"] = json.title; if(json.recipe) { fields["server.recipe"] = json.recipe; } if(json.type && json.type != "None") { fields["server.content-type"] = json.type; } fields["server.permissions"] = json.permissions.join(", "); fields["server.page.revision"] = json.revision; fields["server.workspace"] = "bags/" + json.bag; var tiddler = new Tiddler(json.title); tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags, created, json.fields, json.creator); return tiddler; }; adaptor.resolveWorkspace = function(workspace) { var components = workspace.split("/"); return { type: components[0] == "bags" ? "bag" : "recipe", name: components[1] || components[0] }; }; adaptor.generateETag = function(workspace, tiddler) { var revision = tiddler.fields["server.page.revision"]; var etag = revision == "false" ? null : tiddler.fields["server.etag"]; if(!etag && workspace.type == "bag") { if(typeof revision == "undefined") { revision = "0"; } else if(revision == "false") { return null; } etag = [adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(tiddler.title), revision].join("/"); etag = '"' + etag + '"'; } return etag; }; adaptor.normalizeTitle = function(title) { return encodeURIComponent(title); }; })(jQuery); /* * jQuery JSON Plugin * version: 1.3 * source: http://code.google.com/p/jquery-json/ * license: MIT (http://www.opensource.org/licenses/mit-license.php) */ (function($){function toIntegersAtLease(n) {return n 0) { tiddler.fields.changecount -= context.changecount; } plugin.reportSuccess("saved", tiddler); store.setDirty(false); } else { if(context.httpStatus == 412) { plugin.reportFailure("saveConflict", tiddler); } else { plugin.reportFailure("saveError", tiddler, context); } } }; plugin.removeTiddler = function(tiddler) { try { var adaptor = this.getTiddlerServerAdaptor(tiddler); } catch(ex) { return false; } var context = { host: tiddler.fields["server.host"], workspace: tiddler.fields["server.workspace"], tiddler: tiddler }; var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback); return req ? tiddler : false; }; plugin.removeTiddlerCallback = function(context, userParams) { var tiddler = context.tiddler; if(context.status) { if(tiddler.fields.deleted === "true") { store.deleteTiddler(tiddler.title); } else { plugin.reportFailure("deleteLocalError", tiddler); } plugin.reportSuccess("deleted", tiddler); store.setDirty(false); } else { plugin.reportFailure("deleteError", tiddler, context); } }; plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename? var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"]; return new config.adaptors[type](); }; plugin.reportSuccess = function(msg, tiddler) { displayMessage(plugin.locale[msg].format([tiddler.title])); }; plugin.reportFailure = function(msg, tiddler, context) { var desc = (context && context.httpStatus) ? context.statusText : plugin.locale.connectionError; displayMessage(plugin.locale[msg].format([tiddler.title, desc])); }; config.macros.saveToWeb = { // XXX: hijack existing sync macro? locale: { // TODO: merge with plugin.locale? btnLabel: "save to web", btnTooltip: "synchronize changes", btnAccessKey: null }, handler: function(place, macroName, params, wikifier, paramString, tiddler) { createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip, plugin.sync, null, null, this.locale.btnAccessKey); } }; window.saveChanges = function(onlyIfDirty, tiddlers) { plugin.sync(tiddlers); }; // override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility? TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method? var tiddler = this.fetchTiddler(title); if(tiddler) { tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"]; tiddler.text = plugin.locale.removedNotice; tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved? tiddler.fields.changecount = "1"; this.notify(title, true); this.setDirty(true); } }; // hijack ImportTiddlers wizard to handle cross-domain restrictions var _onOpen = config.macros.importTiddlers.onOpen; config.macros.importTiddlers.onOpen = function(ev) { var btn = $(resolveTarget(ev)); var url = btn.closest(".wizard").find("input[name=txtPath]").val(); if(window.location.protocol != "file:" && url.indexOf("://") != -1) { var host = url.split("/")[2]; var macro = config.macros.importTiddlers; if(host != window.location.host) { btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt); btn[0].onclick = macro.onCancel; $('<span/>').text(plugin.locale.hostError).insertAfter(btn); return false; } } return _onOpen.apply(this, arguments); }; })(jQuery); //}}} //-- //-- Backstage //-- // Backstage tasks config.tasks.save.action = saveChanges; var backstage = { area: null, toolbar: null, button: null, showButton: null, hideButton: null, cloak: null, panel: null, panelBody: null, panelFooter: null, currTabName: null, currTabElem: null, content: null, init: function() { var cmb = config.messages.backstage; this.area = document.getElementById("backstageArea"); this.toolbar = jQuery("#backstageToolbar").empty()[0]; this.button = jQuery("#backstageButton").empty()[0]; this.button.style.display = "block"; var t = cmb.open.text + " " + glyph("bentArrowLeft"); this.showButton = createTiddlyButton(this.button,t,cmb.open.tooltip, function(e) {backstage.show(); return false;},null,"backstageShow"); t = glyph("bentArrowRight") + " " + cmb.close.text; this.hideButton = createTiddlyButton(this.button,t,cmb.close.tooltip, function(e) {backstage.hide(); return false;},null,"backstageHide"); this.cloak = document.getElementById("backstageCloak"); this.panel = document.getElementById("backstagePanel"); this.panelFooter = createTiddlyElement(this.panel,"div",null,"backstagePanelFooter"); this.panelBody = createTiddlyElement(this.panel,"div",null,"backstagePanelBody"); this.cloak.onmousedown = function(e) {backstage.switchTab(null);}; createTiddlyText(this.toolbar,cmb.prompt); for(t=0; t<config t="" var="" taskname="config.backstageTasks[t];" console="" task="config.tasks[taskName];" handler="task.action" this="" :="" text="task.text" glyph="" btn="createTiddlyButton(this.toolbar,text,task.tooltip,handler,"backstageTab");" jquery="" document="" if="" else="" isvisible:="" function="" return="" false="" show:="" config="" backstage="" findwindowwidth="" p="[{style:" start:="" end:="" template:="" anim="" morpher="" true="" saveoption="" hide:="" c="function(element,properties)" onclickcommand:="" onclicktab:="" switch="" to="" a="" given="" tab="" or="" none="" null="" is="" passed="" switchtab:="" tabelem="null;" e="this.toolbar.firstChild;" while="" tabname="" wikify="" ispanelvisible:="" preparepanel:="" finddocheight="" showpanel:="" scroller="" hidepanel:="" atend:="" backstagetask="config.tasks[params[0]];" createtiddlybutton="" main="" params="null;" command="" line="" parameters="" store="null;" tiddlywiki="" storage="" story="null;" formatter="null;" default="" formatters="" for="" the="" wikifier="" animator="=" new="" animation="" engine="" readonly="false;" whether="" we="" in="" mode="" highlighthack="null;" embarrassing="" hack="" department="" hadconfirmexit="false;" don="" warn="" more="" than="" once="" safemode="false;" disable="" all="" plugins="" and="" cookies="" showbackstage="" include="" area="" installedplugins="[];" information="" filled="" when="" are="" executed="" startingup="false;" process="" of="" starting="" up="" plugininfo="" used="" pass="" loadplugins="" space="" total_tiddlers="-1;" ajaxreq="" datatype:="" url:="" success:="" host="window.location.protocol" window="" workspace="recipes/" status="" defaults="config.defaultCustomFields;" filter="?select=tag:excludeLists&type:!text/css&select=type:!text/html&select=type:!image/png&select=type:!image/jpg&select=type:!image/gif&select=type:!image/jpeg" time="0," start="0," total="50;" lazy_load_content="function(title)" data:="" i="0;" tids="" tid="config.adaptors.tiddlyweb.toTiddler(tids[i],"> -1) { var pc = 100 - Math.floor(((total_tiddlers - store.getTiddlers().length) / total_tiddlers) * 100); displayMessage(pc + "% of document loaded."); } start += total; time += 100; lazy_load_content(title); } }, }); }, time); } var success = function(json) { store = new TiddlyWiki({config:config}); invokeParamifier(params,"oninit"); story = new Story("tiddlerDisplay","tiddler"); jQuery("#contentWrapper").removeClass("loading"); for(var i = 0; i 0) { plugin.log.push(config.messages.pluginVersionError); return false; } } return true; } function isPluginEnabled(plugin) { if(plugin.tiddler.isTagged("systemConfigDisable")) { plugin.log.push(config.messages.pluginDisabled); return false; } return true; } </config>

    Syndicated 2012-03-13 13:35:34 (Updated 2012-03-13 15:39:26) from cdent

    _tiddlywiki-apps.js

    //
    // Please note:
    //
    // * This code is designed to be readable but for compactness it only includes brief comments. You can see fuller comments
    //   in the project repository at https://github.com/TiddlyWiki/tiddlywiki
    //
    // * You should never need to modify this source code directly. TiddlyWiki is carefully designed to allow deep customisation
    //   without changing the core code. Please consult the development group at http://groups.google.com/group/TiddlyWikiDev
    //
    // JSLint directives
    /*global jQuery:false, version:false */
    /*jslint bitwise:true, browser:true, confusion:true, eqeq:true, evil:true, forin:true, maxerr:100, plusplus:true, regexp:true, sloppy:true, sub:true, undef:true, unparam:true, vars:true, white:true */
    //--
    //-- Configuration repository
    //--
    
    // Miscellaneous options
    var config = {
    	numRssItems: 20, // Number of items in the RSS feed
    	animDuration: 400, // Duration of UI animations in milliseconds
    	cascadeFast: 20, // Speed for cascade animations (higher == slower)
    	cascadeSlow: 60, // Speed for EasterEgg cascade animations
    	cascadeDepth: 5, // Depth of cascade animation
    	locale: "en" // W3C language tag
    };
    
    // Hashmap of alternative parsers for the wikifier
    config.parsers = {};
    
    // Adaptors
    config.adaptors = {};
    config.defaultAdaptor = null;
    
    // Backstage tasks
    config.tasks = {};
    
    // Annotations
    config.annotations = {};
    
    // Custom fields to be automatically added to new tiddlers
    config.defaultCustomFields = {};
    
    // Messages
    config.messages = {
    	messageClose: {},
    	dates: {},
    	tiddlerPopup: {}
    };
    
    // Options that can be set in the options panel and/or cookies
    config.options = {
    	chkRegExpSearch: false,
    	chkCaseSensitiveSearch: false,
    	chkIncrementalSearch: true,
    	chkAnimate: true,
    	chkSaveBackups: true,
    	chkAutoSave: false,
    	chkGenerateAnRssFeed: false,
    	chkSaveEmptyTemplate: false,
    	chkOpenInNewWindow: true,
    	chkToggleLinks: false,
    	chkHttpReadOnly: false,
    	chkForceMinorUpdate: false,
    	chkConfirmDelete: true,
    	chkInsertTabs: false,
    	chkUsePreForStorage: true, // Whether to use 
     format for storage
    	chkDisplayInstrumentation: false,
    	txtBackupFolder: "",
    	txtEditorFocus: "text",
    	txtMainTab: "tabTimeline",
    	txtMoreTab: "moreTabAll",
    	txtMaxEditRows: "30",
    	txtFileSystemCharSet: "UTF-8",
    	txtTheme: ""
    	};
    config.optionsDesc = {};
    
    config.optionsSource = {};
    
    // Default tiddler templates
    var DEFAULT_VIEW_TEMPLATE = 1;
    var DEFAULT_EDIT_TEMPLATE = 2;
    config.tiddlerTemplates = {
    	1: "ViewTemplate",
    	2: "EditTemplate"
    };
    
    // More messages (rather a legacy layout that should not really be like this)
    config.views = {
    	wikified: {
    		tag: {}
    	},
    	editor: {
    		tagChooser: {}
    	}
    };
    
    // Backstage tasks
    config.backstageTasks = ["save","sync","importTask","tweak","plugins"];
    
    // Extensions
    config.extensions = {};
    
    // Macros; each has a 'handler' member that is inserted later
    config.macros = {
    	today: {},
    	version: {},
    	search: {sizeTextbox: 15},
    	tiddler: {},
    	tag: {},
    	tags: {},
    	tagging: {},
    	timeline: {},
    	allTags: {},
    	list: {
    		all: {},
    		missing: {},
    		orphans: {},
    		shadowed: {},
    		touched: {},
    		filter: {}
    	},
    	closeAll: {},
    	permaview: {},
    	saveChanges: {},
    	slider: {},
    	option: {},
    	options: {},
    	newTiddler: {},
    	newJournal: {},
    	tabs: {},
    	gradient: {},
    	message: {},
    	view: {defaultView: "text"},
    	edit: {},
    	tagChooser: {},
    	toolbar: {},
    	plugins: {},
    	refreshDisplay: {},
    	importTiddlers: {},
    	upgrade: {
    		source: "http://tiddlywiki-releases.tiddlyspace.com/upgrade",
    		backupExtension: "pre.core.upgrade"
    	},
    	sync: {},
    	annotations: {}
    };
    
    // Commands supported by the toolbar macro
    config.commands = {
    	closeTiddler: {},
    	closeOthers: {},
    	editTiddler: {},
    	saveTiddler: {hideReadOnly: true},
    	cancelTiddler: {},
    	deleteTiddler: {hideReadOnly: true},
    	permalink: {},
    	references: {type: "popup"},
    	jump: {type: "popup"},
    	syncing: {type: "popup"},
    	fields: {type: "popup"}
    };
    
    // Control of macro parameter evaluation
    config.evaluateMacroParameters = "all";
    
    // Basic regular expressions
    config.textPrimitives = {
    	upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
    	lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
    	anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
    	anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]"
    };
    if(!((new RegExp("[\u0150\u0170]","g")).test("\u0150"))) {
    	config.textPrimitives = {
    		upperLetter: "[A-Z\u00c0-\u00de]",
    		lowerLetter: "[a-z0-9_\\-\u00df-\u00ff]",
    		anyLetter:   "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff]",
    		anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff]"
    	};
    }
    config.textPrimitives.sliceSeparator = "::";
    config.textPrimitives.sectionSeparator = "##";
    config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
    config.textPrimitives.unWikiLink = "~";
    config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
    	config.textPrimitives.lowerLetter + "+" +
    	config.textPrimitives.upperLetter +
    	config.textPrimitives.anyLetter + "*)|(?:" +
    	config.textPrimitives.upperLetter + "{2,}" +
    	config.textPrimitives.lowerLetter + "+))";
    
    config.textPrimitives.cssLookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
    config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssLookahead,"mg");
    
    config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
    config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
    config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
    	config.textPrimitives.brackettedLink + ")|(?:" +
    	config.textPrimitives.urlPattern + ")","mg");
    config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
    	config.textPrimitives.titledBrackettedLink + ")|(?:" +
    	config.textPrimitives.brackettedLink + ")|(?:" +
    	config.textPrimitives.urlPattern + ")","mg");
    
    config.glyphs = {
    	currBrowser: null,
    	browsers: [],
    	codes: {}
    };
    
    //--
    //-- Shadow tiddlers
    //--
    
    config.shadowTiddlers = {
    	StyleSheet: "",
    	MarkupPreHead: "",
    	MarkupPostHead: "",
    	MarkupPreBody: "",
    	MarkupPostBody: "",
    	TabTimeline: '>',
    	TabAll: '>',
    	TabTags: '>',
    	TabMoreMissing: '>',
    	TabMoreOrphans: '>',
    	TabMoreShadowed: '>',
    	AdvancedOptions: '>',
    	PluginManager: '>',
    	SystemSettings: '',
    	ToolbarCommands: '|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|',
    	WindowTitle: '> - >'
    };
    
    // Browser detection... In a very few places, there's nothing else for it but to know what browser we're using.
    config.userAgent = navigator.userAgent.toLowerCase();
    config.browser = {
    	isIE: config.userAgent.indexOf("msie") != -1 && config.userAgent.indexOf("opera") == -1,
    	isGecko: navigator.product == "Gecko" && config.userAgent.indexOf("WebKit") == -1,
    	ieVersion: /MSIE (\d.\d)/i.exec(config.userAgent), // config.browser.ieVersion[1], if it exists, will be the IE version string, eg "6.0"
    	isSafari: config.userAgent.indexOf("applewebkit") != -1,
    	isBadSafari: !((new RegExp("[\u0150\u0170]","g")).test("\u0150")),
    	firefoxDate: /gecko\/(\d{8})/i.exec(config.userAgent), // config.browser.firefoxDate[1], if it exists, will be Firefox release date as "YYYYMMDD"
    	isOpera: config.userAgent.indexOf("opera") != -1,
    	isChrome: config.userAgent.indexOf('chrome') > -1,
    	isLinux: config.userAgent.indexOf("linux") != -1,
    	isUnix: config.userAgent.indexOf("x11") != -1,
    	isMac: config.userAgent.indexOf("mac") != -1,
    	isWindows: config.userAgent.indexOf("win") != -1
    };
    
    merge(config.glyphs,{
    	browsers: [
    		function() {return config.browser.isIE;},
    		function() {return true;}
    		],
    	codes: {
    		downTriangle: ["\u25BC","\u25BE"],
    		downArrow: ["\u2193","\u2193"],
    		bentArrowLeft: ["\u2190","\u21A9"],
    		bentArrowRight: ["\u2192","\u21AA"]
    	}
    });
    
    //--
    //-- Translateable strings
    //--
    
    // Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
    
    merge(config.options,{
    	txtUserName: "YourName"});
    
    merge(config.tasks,{
    	save: {text: "save", tooltip: "Save your changes to this TiddlyWiki"},
    	importTask: {text: "import", tooltip: "Import tiddlers and plugins from other TiddlyWiki files and servers", content: '>'},
    	tweak: {text: "tweak", tooltip: "Tweak the appearance and behaviour of TiddlyWiki", content: '>'},
    	upgrade: {text: "upgrade", tooltip: "Upgrade TiddlyWiki core code", content: '>'},
    	plugins: {text: "plugins", tooltip: "Manage installed plugins", content: '>'}
    });
    
    // Options that can be set in the options panel and/or cookies
    merge(config.optionsDesc,{
    	txtUserName: "Username for signing your edits",
    	chkRegExpSearch: "Enable regular expressions for searches",
    	chkCaseSensitiveSearch: "Case-sensitive searching",
    	chkIncrementalSearch: "Incremental key-by-key searching",
    	chkAnimate: "Enable animations",
    	chkSaveBackups: "Keep backup file when saving changes",
    	chkAutoSave: "Automatically save changes",
    	chkGenerateAnRssFeed: "Generate an RSS feed when saving changes",
    	chkSaveEmptyTemplate: "Generate an empty template when saving changes",
    	chkOpenInNewWindow: "Open external links in a new window",
    	chkToggleLinks: "Clicking on links to open tiddlers causes them to close",
    	chkHttpReadOnly: "Hide editing features when viewed over HTTP",
    	chkForceMinorUpdate: "Don't update modifier username and date when editing tiddlers",
    	chkConfirmDelete: "Require confirmation before deleting tiddlers",
    	chkInsertTabs: "Use the tab key to insert tab characters instead of moving between fields",
    	txtBackupFolder: "Name of folder to use for backups",
    	txtMaxEditRows: "Maximum number of rows in edit boxes",
    	txtTheme: "Name of the theme to use",
    	txtFileSystemCharSet: "Default character set for saving changes (Firefox/Mozilla only)"});
    
    merge(config.messages,{
    	customConfigError: "Problems were encountered loading plugins. See PluginManager for details",
    	pluginError: "Error: %0",
    	pluginDisabled: "Not executed because disabled via 'systemConfigDisable' tag",
    	pluginForced: "Executed because forced via 'systemConfigForce' tag",
    	pluginVersionError: "Not executed because this plugin needs a newer version of TiddlyWiki",
    	nothingSelected: "Nothing is selected. You must select one or more items first",
    	savedSnapshotError: "It appears that this TiddlyWiki has been incorrectly saved. Please see http://www.tiddlywiki.com/#Download for details",
    	subtitleUnknown: "(unknown)",
    	undefinedTiddlerToolTip: "The tiddler '%0' doesn't yet exist",
    	shadowedTiddlerToolTip: "The tiddler '%0' doesn't yet exist, but has a pre-defined shadow value",
    	tiddlerLinkTooltip: "%0 - %1, %2",
    	externalLinkTooltip: "External link to %0",
    	noTags: "There are no tagged tiddlers",
    	notFileUrlError: "You need to save this TiddlyWiki to a file before you can save changes",
    	cantSaveError: "It's not possible to save changes. Possible reasons include:\n- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)\n- the pathname to your TiddlyWiki file contains illegal characters\n- the TiddlyWiki HTML file has been moved or renamed",
    	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
    	backupSaved: "Backup saved",
    	backupFailed: "Failed to save backup file",
    	rssSaved: "RSS feed saved",
    	rssFailed: "Failed to save RSS feed file",
    	emptySaved: "Empty template saved",
    	emptyFailed: "Failed to save empty template file",
    	mainSaved: "Main TiddlyWiki file saved",
    	mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
    	macroError: "Error in macro >",
    	macroErrorDetails: "Error while executing macro >:\n%1",
    	missingMacro: "No such macro",
    	overwriteWarning: "A tiddler named '%0' already exists. Choose OK to overwrite it",
    	unsavedChangesWarning: "WARNING! There are unsaved changes in TiddlyWiki\n\nChoose OK to save\nChoose CANCEL to discard",
    	confirmExit: "--------------------------------\n\nThere are unsaved changes in TiddlyWiki. If you continue you will lose those changes\n\n--------------------------------",
    	saveInstructions: "SaveChanges",
    	unsupportedTWFormat: "Unsupported TiddlyWiki format '%0'",
    	tiddlerSaveError: "Error when saving tiddler '%0'",
    	tiddlerLoadError: "Error when loading tiddler '%0'",
    	wrongSaveFormat: "Cannot save with storage format '%0'. Using standard format for save.",
    	invalidFieldName: "Invalid field name %0",
    	fieldCannotBeChanged: "Field '%0' cannot be changed",
    	loadingMissingTiddler: "Attempting to retrieve the tiddler '%0' from the '%1' server at:\n\n'%2' in the workspace '%3'",
    	upgradeDone: "The upgrade to version %0 is now complete\n\nClick 'OK' to reload the newly upgraded TiddlyWiki",
    	invalidCookie: "Invalid cookie '%0'"});
    
    merge(config.messages.messageClose,{
    	text: "close",
    	tooltip: "close this message area"});
    
    config.messages.backstage = {
    	open: {text: "backstage", tooltip: "Open the backstage area to perform authoring and editing tasks"},
    	close: {text: "close", tooltip: "Close the backstage area"},
    	prompt: "backstage: ",
    	decal: {
    		edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
    	}
    };
    
    config.messages.listView = {
    	tiddlerTooltip: "Click for the full text of this tiddler",
    	previewUnavailable: "(preview not available)"
    };
    
    config.messages.dates.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"];
    config.messages.dates.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    // suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
    config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
    		"th","th","th","th","th","th","th","th","th","th",
    		"st","nd","rd","th","th","th","th","th","th","th",
    		"st"];
    config.messages.dates.am = "am";
    config.messages.dates.pm = "pm";
    
    merge(config.messages.tiddlerPopup,{
    	});
    
    merge(config.views.wikified.tag,{
    	labelNoTags: "no tags",
    	labelTags: "tags: ",
    	openTag: "Open tag '%0'",
    	tooltip: "Show tiddlers tagged with '%0'",
    	openAllText: "Open all",
    	openAllTooltip: "Open all of these tiddlers",
    	popupNone: "No other tiddlers tagged with '%0'"});
    
    merge(config.views.wikified,{
    	defaultText: "The tiddler '%0' doesn't yet exist. Double-click to create it",
    	defaultModifier: "(missing)",
    	shadowModifier: "(built-in shadow tiddler)",
    	dateFormat: "DD MMM YYYY",
    	createdPrompt: "created"});
    
    merge(config.views.editor,{
    	tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
    	defaultText: "Type the text for '%0'"});
    
    merge(config.views.editor.tagChooser,{
    	text: "tags",
    	tooltip: "Choose existing tags to add to this tiddler",
    	popupNone: "There are no tags defined",
    	tagTooltip: "Add the tag '%0'"});
    
    merge(config.messages,{
    	sizeTemplates:
    		[
    		{unit: 1024*1024*1024, template: "%0\u00a0GB"},
    		{unit: 1024*1024, template: "%0\u00a0MB"},
    		{unit: 1024, template: "%0\u00a0KB"},
    		{unit: 1, template: "%0\u00a0B"}
    		]});
    
    merge(config.macros.search,{
    	label: "search",
    	prompt: "Search this TiddlyWiki",
    	placeholder: "",
    	accessKey: "F",
    	successMsg: "%0 tiddlers found matching %1",
    	failureMsg: "No tiddlers found matching %0"});
    
    merge(config.macros.tagging,{
    	label: "tagging: ",
    	labelNotTag: "not tagging",
    	tooltip: "List of tiddlers tagged with '%0'"});
    
    merge(config.macros.timeline,{
    	dateFormat: "DD MMM YYYY"});
    
    merge(config.macros.allTags,{
    	tooltip: "Show tiddlers tagged with '%0'",
    	noTags: "There are no tagged tiddlers"});
    
    config.macros.list.all.prompt = "All tiddlers in alphabetical order";
    config.macros.list.missing.prompt = "Tiddlers that have links to them but are not defined";
    config.macros.list.orphans.prompt = "Tiddlers that are not linked to from any other tiddlers";
    config.macros.list.shadowed.prompt = "Tiddlers shadowed with default contents";
    config.macros.list.touched.prompt = "Tiddlers that have been modified locally";
    
    merge(config.macros.closeAll,{
    	label: "close all",
    	prompt: "Close all displayed tiddlers (except any that are being edited)"});
    
    merge(config.macros.permaview,{
    	label: "permaview",
    	prompt: "Link to an URL that retrieves all the currently displayed tiddlers"});
    
    merge(config.macros.saveChanges,{
    	label: "save changes",
    	prompt: "Save all tiddlers to create a new TiddlyWiki",
    	accessKey: "S"});
    
    merge(config.macros.newTiddler,{
    	label: "new tiddler",
    	prompt: "Create a new tiddler",
    	title: "New Tiddler",
    	accessKey: "N"});
    
    merge(config.macros.newJournal,{
    	label: "new journal",
    	prompt: "Create a new tiddler from the current date and time",
    	accessKey: "J"});
    
    merge(config.macros.options,{
    	wizardTitle: "Tweak advanced options",
    	step1Title: "These options are saved in cookies in your browser",
    	step1Html: "
    Show unknown options", unknownDescription: "//(unknown)//", listViewTemplate: { columns: [ {name: 'Option', field: 'option', title: "Option", type: 'String'}, {name: 'Description', field: 'description', title: "Description", type: 'WikiText'}, {name: 'Name', field: 'name', title: "Name", type: 'String'} ], rowClasses: [ {className: 'lowlight', field: 'lowlight'} ]} }); merge(config.macros.plugins,{ wizardTitle: "Manage plugins", step1Title: "Currently loaded plugins", step1Html: "", // DO NOT TRANSLATE skippedText: "(This plugin has not been executed because it was added since startup)", noPluginText: "There are no plugins installed", confirmDeleteText: "Are you sure you want to delete these plugins:\n\n%0", removeLabel: "remove systemConfig tag", removePrompt: "Remove systemConfig tag", deleteLabel: "delete", deletePrompt: "Delete these tiddlers forever", listViewTemplate: { columns: [ {name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'}, {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Description', field: 'Description', title: "Description", type: 'String'}, {name: 'Version', field: 'Version', title: "Version", type: 'String'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'}, {name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'}, {name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"}, {name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'}, {name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"}, {name: 'Log', field: 'log', title: "Log", type: 'StringList'} ], rowClasses: [ {className: 'error', field: 'error'}, {className: 'warning', field: 'warning'} ]}, listViewTemplateReadOnly: { columns: [ {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Description', field: 'Description', title: "Description", type: 'String'}, {name: 'Version', field: 'Version', title: "Version", type: 'String'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"}, {name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'}, {name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"}, {name: 'Log', field: 'log', title: "Log", type: 'StringList'} ], rowClasses: [ {className: 'error', field: 'error'}, {className: 'warning', field: 'warning'} ]} }); merge(config.macros.toolbar,{ moreLabel: "more", morePrompt: "Show additional commands", lessLabel: "less", lessPrompt: "Hide additional commands", separator: "|" }); merge(config.macros.refreshDisplay,{ label: "refresh", prompt: "Redraw the entire TiddlyWiki display" }); merge(config.macros.importTiddlers,{ readOnlyWarning: "You cannot import into a read-only TiddlyWiki file. Try opening it from a file:// URL", wizardTitle: "Import tiddlers from another file or server", step1Title: "Step 1: Locate the server or TiddlyWiki file", step1Html: "Specify the type of the server:
    Enter the URL or pathname here:
    ...or browse for a file:

    ...or select a pre-defined feed: ", openLabel: "open", openPrompt: "Open the connection to this file or server", statusOpenHost: "Opening the host", statusGetWorkspaceList: "Getting the list of available workspaces", step2Title: "Step 2: Choose the workspace", step2Html: "Enter a workspace name:
    ...or select a workspace: ", cancelLabel: "cancel", cancelPrompt: "Cancel this import", statusOpenWorkspace: "Opening the workspace", statusGetTiddlerList: "Getting the list of available tiddlers", errorGettingTiddlerList: "Error getting list of tiddlers, click Cancel to try again", errorGettingTiddlerListHttp404: "Error retrieving tiddlers from url, please ensure the url exists. Click Cancel to try again.", errorGettingTiddlerListHttp: "Error retrieving tiddlers from url, please ensure this url exists and is CORS enabled", errorGettingTiddlerListFile: "Error retrieving tiddlers from local file, please make sure the file is in the same directory as your TiddlyWiki. Click Cancel to try again.", step3Title: "Step 3: Choose the tiddlers to import", step3Html: "
    Keep these tiddlers linked to this server so that you can synchronise subsequent changes
    Save the details of this server in a 'systemServer' tiddler called: ", importLabel: "import", importPrompt: "Import these tiddlers", confirmOverwriteText: "Are you sure you want to overwrite these tiddlers:\n\n%0", step4Title: "Step 4: Importing %0 tiddler(s)", step4Html: "", // DO NOT TRANSLATE doneLabel: "done", donePrompt: "Close this wizard", statusDoingImport: "Importing tiddlers", statusDoneImport: "All tiddlers imported", systemServerNamePattern: "%2 on %1", systemServerNamePatternNoWorkspace: "%1", confirmOverwriteSaveTiddler: "The tiddler '%0' already exists. Click 'OK' to overwrite it with the details of this server, or 'Cancel' to leave it unchanged", serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nThis tiddler was automatically created to record the details of this server", serverSaveModifier: "(System)", listViewTemplate: { columns: [ {name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'}, {name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'}, {name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'}, {name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'} ], rowClasses: [ ]} }); merge(config.macros.upgrade,{ wizardTitle: "Upgrade TiddlyWiki core code", step1Title: "Update or repair this TiddlyWiki to the latest release", step1Html: "You are about to upgrade to the latest release of the TiddlyWiki core code (from %1). Your content will be preserved across the upgrade.

    Note that core upgrades have been known to interfere with older plugins. If you run into problems with the upgraded file, see http://www.tiddlywiki.org/wiki/CoreUpgrades", errorCantUpgrade: "Unable to upgrade this TiddlyWiki. You can only perform upgrades on TiddlyWiki files stored locally", errorNotSaved: "You must save changes before you can perform an upgrade", step2Title: "Confirm the upgrade details", step2Html_downgrade: "You are about to downgrade to TiddlyWiki version %0 from %1.

    Downgrading to an earlier version of the core code is not recommended", step2Html_restore: "This TiddlyWiki appears to be already using the latest version of the core code (%0).

    You can continue to upgrade anyway to ensure that the core code hasn't been corrupted or damaged", step2Html_upgrade: "You are about to upgrade to TiddlyWiki version %0 from %1", upgradeLabel: "upgrade", upgradePrompt: "Prepare for the upgrade process", statusPreparingBackup: "Preparing backup", statusSavingBackup: "Saving backup file", errorSavingBackup: "There was a problem saving the backup file", statusLoadingCore: "Loading core code", errorLoadingCore: "Error loading the core code", errorCoreFormat: "Error with the new core code", statusSavingCore: "Saving the new core code", statusReloadingCore: "Reloading the new core code", startLabel: "start", startPrompt: "Start the upgrade process", cancelLabel: "cancel", cancelPrompt: "Cancel the upgrade process", step3Title: "Upgrade cancelled", step3Html: "You have cancelled the upgrade process" }); merge(config.macros.annotations,{ }); merge(config.commands.closeTiddler,{ text: "close", tooltip: "Close this tiddler"}); merge(config.commands.closeOthers,{ text: "close others", tooltip: "Close all other tiddlers"}); merge(config.commands.editTiddler,{ text: "edit", tooltip: "Edit this tiddler", readOnlyText: "view", readOnlyTooltip: "View the source of this tiddler"}); merge(config.commands.saveTiddler,{ text: "done", tooltip: "Save changes to this tiddler"}); merge(config.commands.cancelTiddler,{ text: "cancel", tooltip: "Undo changes to this tiddler", warning: "Are you sure you want to abandon your changes to '%0'?", readOnlyText: "done", readOnlyTooltip: "View this tiddler normally"}); merge(config.commands.deleteTiddler,{ text: "delete", tooltip: "Delete this tiddler", warning: "Are you sure you want to delete '%0'?"}); merge(config.commands.permalink,{ text: "permalink", tooltip: "Permalink for this tiddler"}); merge(config.commands.references,{ text: "references", tooltip: "Show tiddlers that link to this one", popupNone: "No references"}); merge(config.commands.jump,{ text: "jump", tooltip: "Jump to another open tiddler"}); merge(config.commands.fields,{ text: "fields", tooltip: "Show the extended fields of this tiddler", emptyText: "There are no extended fields for this tiddler", listViewTemplate: { columns: [ {name: 'Field', field: 'field', title: "Field", type: 'String'}, {name: 'Value', field: 'value', title: "Value", type: 'String'} ], rowClasses: [ ], buttons: [ ]}}); merge(config.shadowTiddlers,{ DefaultTiddlers: "[[GettingStarted]]", MainMenu: "[[GettingStarted]]", SiteTitle: "My TiddlyWiki", SiteSubtitle: "a reusable non-linear personal web notebook", SiteUrl: "", SideBarOptions: '>>>>>>>', SideBarTabs: '>', TabMore: '>' }); merge(config.annotations,{ AdvancedOptions: "This shadow tiddler provides access to several advanced options", ColorPalette: "These values in this shadow tiddler determine the colour scheme of the ~TiddlyWiki user interface", DefaultTiddlers: "The tiddlers listed in this shadow tiddler will be automatically displayed when ~TiddlyWiki starts up", EditTemplate: "The HTML template in this shadow tiddler determines how tiddlers look while they are being edited", GettingStarted: "This shadow tiddler provides basic usage instructions", ImportTiddlers: "This shadow tiddler provides access to importing tiddlers", MainMenu: "This shadow tiddler is used as the contents of the main menu in the left-hand column of the screen", MarkupPreHead: "This tiddler is inserted at the top of the section of the TiddlyWiki HTML file", MarkupPostHead: "This tiddler is inserted at the bottom of the section of the TiddlyWiki HTML file", MarkupPreBody: "This tiddler is inserted at the top of the section of the TiddlyWiki HTML file", MarkupPostBody: "This tiddler is inserted at the end of the section of the TiddlyWiki HTML file immediately after the script block", OptionsPanel: "This shadow tiddler is used as the contents of the options panel slider in the right-hand sidebar", PageTemplate: "The HTML template in this shadow tiddler determines the overall ~TiddlyWiki layout", PluginManager: "This shadow tiddler provides access to the plugin manager", SideBarOptions: "This shadow tiddler is used as the contents of the option panel in the right-hand sidebar", SideBarTabs: "This shadow tiddler is used as the contents of the tabs panel in the right-hand sidebar", SiteSubtitle: "This shadow tiddler is used as the second part of the page title", SiteTitle: "This shadow tiddler is used as the first part of the page title", SiteUrl: "This shadow tiddler should be set to the full target URL for publication", StyleSheetColors: "This shadow tiddler contains CSS definitions related to the color of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler", StyleSheet: "This tiddler can contain custom CSS definitions", StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler", StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale", StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing", SystemSettings: "This tiddler is used to store configuration options for this TiddlyWiki document", TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar", TabMore: "This shadow tiddler contains the contents of the 'More' tab in the right-hand sidebar", TabMoreMissing: "This shadow tiddler contains the contents of the 'Missing' tab in the right-hand sidebar", TabMoreOrphans: "This shadow tiddler contains the contents of the 'Orphans' tab in the right-hand sidebar", TabMoreShadowed: "This shadow tiddler contains the contents of the 'Shadowed' tab in the right-hand sidebar", TabTags: "This shadow tiddler contains the contents of the 'Tags' tab in the right-hand sidebar", TabTimeline: "This shadow tiddler contains the contents of the 'Timeline' tab in the right-hand sidebar", ToolbarCommands: "This shadow tiddler determines which commands are shown in tiddler toolbars", ViewTemplate: "The HTML template in this shadow tiddler determines how tiddlers look" }); //-- //-- Paramifiers //-- function getParameters() { var p = null; if(window.location.hash) { p = decodeURIComponent(window.location.hash.substr(1)); if(config.browser.firefoxDate != null && config.browser.firefoxDate[1] 1) { last.element.setAttribute("colspan",colSpanCount); last.element.setAttribute("colSpan",colSpanCount); // Needed for IE colSpanCount = 1; } } w.nextMatch = this.cellRegExp.lastIndex-1; } else if(cellMatch[1] == ">") { // Colspan colSpanCount++; w.nextMatch = this.cellRegExp.lastIndex-1; } else if(cellMatch[2]) { // End of row if(prevCell && colSpanCount > 1) { prevCell.setAttribute("colspan",colSpanCount); prevCell.setAttribute("colSpan",colSpanCount); // Needed for IE } w.nextMatch = this.cellRegExp.lastIndex; break; } else { // Cell w.nextMatch++; var styles = config.formatterHelpers.inlineCssHelper(w); var spaceLeft = false; var chr = w.source.substr(w.nextMatch,1); while(chr == " ") { spaceLeft = true; w.nextMatch++; chr = w.source.substr(w.nextMatch,1); } var cell; if(chr == "!") { cell = createTiddlyElement(e,"th"); w.nextMatch++; } else { cell = createTiddlyElement(e,"td"); } prevCell = cell; prevColumns[col] = {rowSpanCount:1,element:cell}; if(colSpanCount > 1) { cell.setAttribute("colspan",colSpanCount); cell.setAttribute("colSpan",colSpanCount); // Needed for IE colSpanCount = 1; } config.formatterHelpers.applyCssHelper(cell,styles); w.subWikifyTerm(cell,this.cellTermRegExp); if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight cell.align = spaceLeft ? "center" : "left"; else if(spaceLeft) cell.align = "right"; w.nextMatch--; } col++; this.cellRegExp.lastIndex = w.nextMatch; cellMatch = this.cellRegExp.exec(w.source); } } }, { name: "heading", match: "^!{1,6}", termRegExp: /(\n)/mg, handler: function(w) { w.subWikifyTerm(createTiddlyElement(w.output,"h" + w.matchLength),this.termRegExp); } }, { name: "list", 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) { if(lookaheadMatch[1]) { listType = "ul"; itemType = "li"; } else if(lookaheadMatch[2]) { listType = "ol"; itemType = "li"; } else if(lookaheadMatch[3]) { listType = "dl"; itemType = "dt"; } else if(lookaheadMatch[4]) { listType = "dl"; itemType = "dd"; } if(!baseType) baseType = listType; listLevel = lookaheadMatch[0].length; w.nextMatch += lookaheadMatch[0].length; var t; if(listLevel > currLevel) { for(t=currLevel; tlistLevel; 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: "quoteByBlock", match: "^+", lookaheadRegExp: /^>+/mg, termRegExp: /(\n)/mg, element: "blockquote", handler: function(w) { var stack = [w.output]; var currLevel = 0; var newLevel = w.matchLength; var t,matched; do { if(newLevel > currLevel) { for(t=currLevel; tnewLevel; t--) stack.pop(); } currLevel = newLevel; w.subWikifyTerm(stack[stack.length-1],this.termRegExp); createTiddlyElement(stack[stack.length-1],"br"); this.lookaheadRegExp.lastIndex = w.nextMatch; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch; if(matched) { newLevel = lookaheadMatch[0].length; w.nextMatch += lookaheadMatch[0].length; } } while(matched); } }, { name: "rule", match: "^----+$\\n?|
    \\n?", handler: function(w) { createTiddlyElement(w.output,"hr"); } }, { name: "monospacedByLine", match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|)\\n", element: "pre", handler: function(w) { switch(w.matchText) { case "/*{{{*/\n": // CSS this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\*\}\}\}\*\/$\n?)/mg; break; case "{{{\n": // monospaced block this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\f*\}\}\}$\n?)/mg; break; case "//{{{\n": // plugin this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\/\}\}\}$\n?)/mg; break; case "\n": //template this.lookaheadRegExp = /\n*((?:^[^\n]*\n)+?)(\n*^\f*$\n?)/mg; break; default: break; } config.formatterHelpers.enclosedTextHelper.call(this,w); } }, { name: "wikifyComment", match: "^(?:/\\*\\*\\*|\n)/mg); w.subWikifyTerm(w.output,termRegExp); } }, { name: "macro", match: "\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: "prettyLink", 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 text = lookaheadMatch[1]; if(lookaheadMatch[3]) { // Pretty bracketted link var link = lookaheadMatch[3]; e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link)) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler); } else { // Simple bracketted link e = createTiddlyLink(w.output,text,false,null,w.isStatic,w.tiddler); } createTiddlyText(e,text); w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "wikiLink", match: config.textPrimitives.unWikiLink+"?"+config.textPrimitives.wikiLink, handler: function(w) { if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink) { w.outputText(w.output,w.matchStart+1,w.nextMatch); return; } if(w.matchStart > 0) { var preRegExp = new RegExp(config.textPrimitives.anyLetterStrict,"mg"); preRegExp.lastIndex = w.matchStart-1; var preMatch = preRegExp.exec(w.source); if(preMatch.index == w.matchStart-1) { w.outputText(w.output,w.matchStart,w.nextMatch); return; } } if(w.autoLinkWikiWords || store.isShadowTiddler(w.matchText)) { var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler); w.outputText(link,w.matchStart,w.nextMatch); } else { w.outputText(w.output,w.matchStart,w.nextMatch); } } }, { name: "urlLink", match: config.textPrimitives.urlPattern, handler: function(w) { w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch); } }, { name: "image", match: "\\[[]?[Ii][Mm][Gg]\\[", lookaheadRegExp: /\[([?)[Ii][Mm][Gg]\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg, handler: function(w) { this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { var e = w.output; if(lookaheadMatch[5]) { var link = lookaheadMatch[5]; e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler); jQuery(e).addClass("imageLink"); } var img = createTiddlyElement(e,"img"); if(lookaheadMatch[1]) img.align = "left"; else if(lookaheadMatch[2]) img.align = "right"; if(lookaheadMatch[3]) { img.title = lookaheadMatch[3]; img.setAttribute("alt",lookaheadMatch[3]); } img.src = lookaheadMatch[4]; w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "html", 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) { createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1]; w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "commentByBlock", 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: "characterFormat", match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{", handler: function(w) { switch(w.matchText) { case "''": w.subWikifyTerm(w.output.appendChild(document.createElement("strong")),/('')/mg); break; case "//": w.subWikifyTerm(createTiddlyElement(w.output,"em"),/(\/\/)/mg); break; case "__": w.subWikifyTerm(createTiddlyElement(w.output,"u"),/(__)/mg); break; case "^^": w.subWikifyTerm(createTiddlyElement(w.output,"sup"),/(\^\^)/mg); break; case "~~": w.subWikifyTerm(createTiddlyElement(w.output,"sub"),/(~~)/mg); break; case "--": w.subWikifyTerm(createTiddlyElement(w.output,"strike"),/(--)/mg); break; case "{{{": var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg; lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]); w.nextMatch = lookaheadRegExp.lastIndex; } break; } } }, { name: "customFormat", match: "@@|\\{\\{", handler: function(w) { switch(w.matchText) { case "@@": var e = createTiddlyElement(w.output,"span"); var styles = config.formatterHelpers.inlineCssHelper(w); if(styles.length == 0) e.className = "marked"; else config.formatterHelpers.applyCssHelper(e,styles); w.subWikifyTerm(e,/(@@)/mg); break; case "{{": var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg; lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = lookaheadRegExp.exec(w.source); if(lookaheadMatch) { w.nextMatch = lookaheadRegExp.lastIndex; e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]); w.subWikifyTerm(e,/(\}\}\})/mg); } break; } } }, { name: "mdash", match: "--", handler: function(w) { createTiddlyElement(w.output,"span").innerHTML = "—"; } }, { name: "lineBreak", match: "\\n|
    ", handler: function(w) { createTiddlyElement(w.output,"br"); } }, { name: "rawText", match: "\"{3}|", lookaheadRegExp: /(?:\"{3}|)((?:.|\n)*?)(?:\"{3}|)/mg, handler: function(w) { this.lookaheadRegExp.lastIndex = w.matchStart; var lookaheadMatch = this.lookaheadRegExp.exec(w.source); if(lookaheadMatch && lookaheadMatch.index == w.matchStart) { createTiddlyElement(w.output,"span",null,null,lookaheadMatch[1]); w.nextMatch = this.lookaheadRegExp.lastIndex; } } }, { name: "htmlEntitiesEncoding", match: "(?:(?:?[a-zA-Z0-9]{2,8};|.)(?:?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|?[a-zA-Z0-9]{2,8};)", handler: function(w) { createTiddlyElement(w.output,"span").innerHTML = w.matchText; } } ]; //-- //-- Wikifier //-- function getParser(tiddler,format) { if(tiddler) { if(!format) format = tiddler.fields["wikiformat"]; var i; if(format) { for(i in config.parsers) { if(format == config.parsers[i].format) return config.parsers[i]; } } else { for(i in config.parsers) { if(tiddler.isTagged(config.parsers[i].formatTag)) return config.parsers[i]; } } } return formatter; } function Wikifier(source,formatter,highlightRegExp,tiddler) { this.source = source; this.output = null; this.formatter = formatter; this.nextMatch = 0; this.autoLinkWikiWords = tiddler && tiddler.autoLinkWikiWords() == false ? false : true; this.highlightRegExp = highlightRegExp; this.highlightMatch = null; this.isStatic = false; if(highlightRegExp) { highlightRegExp.lastIndex = 0; this.highlightMatch = highlightRegExp.exec(source); } this.tiddler = tiddler; } Wikifier.prototype.wikifyPlain = function() { var e = createTiddlyElement(document.body,"div"); e.style.display = "none"; this.subWikify(e); var text = jQuery(e).text(); jQuery(e).remove(); return text; }; Wikifier.prototype.subWikify = function(output,terminator) { try { if(terminator) this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg")); else this.subWikifyUnterm(output); } catch(ex) { showException(ex); } }; Wikifier.prototype.subWikifyUnterm = function(output) { var oldOutput = this.output; this.output = output; this.formatter.formatterRegExp.lastIndex = this.nextMatch; var formatterMatch = this.formatter.formatterRegExp.exec(this.source); while(formatterMatch) { // Output any text before the match if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); // Set the match parameters for the handler this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; var t; for(t=1; t this.nextMatch) this.outputText(this.output,this.nextMatch,terminatorMatch.index); this.matchText = terminatorMatch[1]; this.matchLength = terminatorMatch[1].length; this.matchStart = terminatorMatch.index; this.nextMatch = this.matchStart + this.matchLength; this.output = oldOutput; return; } if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; var t; for(t=1; t startPos) && (this.highlightMatch.index startPos) { createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index)); startPos = this.highlightMatch.index; } var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos); createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd)); startPos = highlightEnd; if(startPos >= this.highlightRegExp.lastIndex) this.highlightMatch = this.highlightRegExp.exec(this.source); } if(startPos 0) text = text.substr(0,limit); var wikifier = new Wikifier(text,formatter,null,tiddler); return wikifier.wikifyPlain(); } function highlightify(source,output,highlightRegExp,tiddler) { if(source) { var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler); wikifier.outputText(output,0,source.length); } } //-- //-- Macro definitions //-- function invokeMacro(place,macro,params,wikifier,tiddler) { try { var m = config.macros[macro]; if(m && m.handler) { var tiddlerElem = story.findContainingTiddler(place); window.tiddler = tiddlerElem ? store.getTiddler(tiddlerElem.getAttribute("tiddler")) : null; window.place = place; var allowEval = true; if(config.evaluateMacroParameters=="system") { if(!tiddler || tiddler.tags.indexOf("systemAllowEval") == -1) { allowEval = false; } } m.handler(place,macro,m.noPreParse?null:params.readMacroParams(!allowEval),wikifier,params,tiddler); } else { createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,config.messages.missingMacro])); } } catch(ex) { createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,ex.toString()])); } } config.macros.version.handler = function(place) { jQuery("").text(formatVersion()).appendTo(place); }; config.macros.today.handler = function(place,macroName,params) { var now = new Date(); var text = params[0] ? now.formatString(params[0].trim()) : now.toLocaleString(); jQuery("").text(text).appendTo(place); }; config.macros.list.template = ">"; config.macros.list.handler = function(place,macroName,params,wikifier,paramString) { var list = document.createElement("ul"); jQuery(list).attr({ refresh: "macro", macroName: macroName }).data("params", paramString); place.appendChild(list); this.refresh(list); }; config.macros.list.refresh = function(list) { var paramString = jQuery(list).data("params"); var params = paramString.readMacroParams(); var args = paramString.parseParams("anon", null, null)[0]; var type = args.anon ? args.anon[0] : "all"; jQuery(list).empty().addClass("list list-" + type); var template = args.template ? store.getTiddlerText(args.template[0]) : false; if(!template) { template = config.macros.list.template; } if(this[type].prompt) createTiddlyElement(list,"li",null,"listTitle",this[type].prompt); var results; if(this[type].handler) results = this[type].handler(params); var t; for(t = 0; t ").text(args.emptyMessage[0]).appendTo(list); } }; config.macros.list.all.handler = function(params) { return store.reverseLookup("tags","excludeLists",false,"title"); }; config.macros.list.missing.handler = function(params) { return store.getMissingLinks(); }; config.macros.list.orphans.handler = function(params) { return store.getOrphans(); }; config.macros.list.shadowed.handler = function(params) { return store.getShadowed(); }; config.macros.list.touched.handler = function(params) { return store.getTouched(); }; config.macros.list.filter.handler = function(params) { var filter = params[1]; var results = []; if(filter) { var tiddlers = store.filterTiddlers(filter); var t; for(t=0; t").attr("params", paramString). attr("macroName", macroName).appendTo(place)[0]; macro.refresh(container); }, refresh: function(container) { jQuery(container).attr("refresh", "macro").empty(); var paramString = jQuery(container).attr("params"); var args = paramString.parseParams("anon", null, null)[0]; var params = args.anon || []; var field = params[0] || "modified"; var prefix = field.charAt(0); var no_prefix_field = prefix === "-" || prefix === "+" ? field.substr(1, field.length) : field; var dateFormat = params[2] || this.dateFormat; var groupTemplate = macro.groupTemplate.format(no_prefix_field, dateFormat); groupTemplate = args.groupTemplate ? store.getTiddlerText(args.groupTemplate[0]) || groupTemplate : groupTemplate; var itemTemplate = macro.itemTemplate; itemTemplate = args.template ? store.getTiddlerText(args.template[0]) || itemTemplate : itemTemplate; var tiddlers = args.filter ? store.sortTiddlers(store.filterTiddlers(args.filter[0]), field) : store.reverseLookup("tags", "excludeLists", false, field); var lastGroup = "", ul; var last = params[1] ? tiddlers.length-Math.min(tiddlers.length,parseInt(params[1],10)) : 0; var t; for(t=tiddlers.length-1; t>=last; t--) { var tiddler = tiddlers[t]; var theGroup = wikifyPlainText(groupTemplate,0,tiddler); if(typeof(ul) == "undefined" || theGroup != lastGroup) { ul = document.createElement("ul"); jQuery(ul).addClass("timeline"); container.appendChild(ul); createTiddlyElement(ul,"li",null,"listTitle",theGroup); lastGroup = theGroup; } var item = createTiddlyElement(ul,"li",null,"listLink"); wikify(itemTemplate,item,null,tiddler); } }, groupTemplate: ">", itemTemplate: ">" }); config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var allowEval = true; var stack = config.macros.tiddler.tiddlerStack; if(stack.length > 0 && config.evaluateMacroParameters == "system") { // included tiddler and "system" evaluation required, so check tiddler tagged appropriately var title = stack[stack.length-1]; var pos = title.indexOf(config.textPrimitives.sectionSeparator); if(pos != -1) { title = title.substr(0,pos); // get the base tiddler title } var t = store.getTiddler(title); if(!t || t.tags.indexOf("systemAllowEval") == -1) { allowEval = false; } } params = paramString.parseParams("name",null,allowEval,false,true); var names = params[0]["name"]; var tiddlerName = names[0]; var className = names[1] || null; var args = params[0]["with"]; var wrapper = createTiddlyElement(place,"span",null,className,null,{ refresh: "content", tiddler: tiddlerName }); if(args!==undefined) wrapper.setAttribute("args","[["+args.join("]] [[")+"]]"); this.transclude(wrapper,tiddlerName,args); }; config.macros.tiddler.transclude = function(wrapper,tiddlerName,args) { var text = store.getTiddlerText(tiddlerName); if(!text) return; var stack = config.macros.tiddler.tiddlerStack; if(stack.indexOf(tiddlerName) !== -1) return; stack.push(tiddlerName); try { if(typeof args == "string") args = args.readBracketedList(); var n = args ? Math.min(args.length,9) : 0; var i; for(i=0; i> config.macros.gradient.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var panel = wikifier ? createTiddlyElement(place,"div",null,"gradient") : place; panel.style.position = "relative"; panel.style.overflow = "hidden"; panel.style.zIndex = "0"; if(wikifier) { var styles = config.formatterHelpers.inlineCssHelper(wikifier); config.formatterHelpers.applyCssHelper(panel,styles); } params = paramString.parseParams("color"); var locolors = [], hicolors = []; var t; for(t=2; t>"); if(document.all) { panel.style.height = "100%"; panel.style.width = "100%"; } }; config.macros.message.handler = function(place,macroName,params) { if(params[0]) { var names = params[0].split("."); var lookupMessage = function(root,nameIndex) { if(root[names[nameIndex]]) { if(nameIndex 50) return; if(config.macros.view.depth>0) { if (value==config.macros.view.values[config.macros.view.depth-1]) { return; } } config.macros.view.values[config.macros.view.depth] = value; config.macros.view.depth++; if(params[2]) value=params[2].unescapeLineBreaks().format([value]); wikify(value,place,highlightHack,tiddler); config.macros.view.depth--; config.macros.view.values[config.macros.view.depth] = null; }, date: function(value,place,params,wikifier,paramString,tiddler) { value = Date.convertFromYYYYMMDDHHMM(value); createTiddlyText(place,value.formatString(params[2] || config.views.wikified.dateFormat)); } }; config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler) { if((tiddler instanceof Tiddler) && params[0]) { var value = store.getValue(tiddler,params[0]); if(value) { var type = params[1] || config.macros.view.defaultView; var handler = config.macros.view.views[type]; if(handler) handler(value,place,params,wikifier,paramString,tiddler); } } }; config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler) { var field = params[0]; var rows = params[1] || 0; var defVal = params[2] || ''; if((tiddler instanceof Tiddler) && field) { story.setDirty(tiddler.title,true); var e,v; if(field != "text" && !rows) { e = createTiddlyElement(null,"input",null,null,null,{ type: "text", edit: field, size: "40", autocomplete: "off" }); e.value = store.getValue(tiddler,field) || defVal; place.appendChild(e); } else { var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix"); var wrapper2 = createTiddlyElement(wrapper1,"div"); e = createTiddlyElement(wrapper2,"textarea"); e.value = v = store.getValue(tiddler,field) || defVal; rows = rows || 10; var lines = v.match(/\n/mg); var maxLines = Math.max(parseInt(config.options.txtMaxEditRows,10),5); if(lines != null && lines.length > rows) rows = lines.length + 5; rows = Math.min(rows,maxLines); e.setAttribute("rows",rows); e.setAttribute("edit",field); place.appendChild(wrapper1); } if(tiddler.isReadOnly()) { e.setAttribute("readOnly","readOnly"); jQuery(e).addClass("readOnly"); } return e; } }; config.macros.tagChooser.onClick = function(ev) { var e = ev || window.event; var lingo = config.views.editor.tagChooser; var popup = Popup.create(this); var tags = store.getTags(this.getAttribute("tags")); if(tags.length == 0) jQuery("
  • ").text(lingo.popupNone).appendTo(popup); var t; for(t=0; t 0) btn.setAttribute("params",tags.join("|")); btn.setAttribute("newFocus",newFocus); btn.setAttribute("newTemplate",getParam(params,"template",DEFAULT_EDIT_TEMPLATE)); if(customFields !== "") btn.setAttribute("customFields",customFields); var text = getParam(params,"text"); if(text !== undefined) btn.setAttribute("newText",text); return btn; }; config.macros.newTiddler.onClickNewTiddler = function() { var title = this.getAttribute("newTitle"); if(this.getAttribute("isJournal") == "true") { title = new Date().formatString(title.trim()); } var params = this.getAttribute("params"); var tags = params ? params.split("|") : []; var focus = this.getAttribute("newFocus"); var template = this.getAttribute("newTemplate"); var customFields = this.getAttribute("customFields"); if(!customFields && !store.isShadowTiddler(title)) customFields = String.encodeHashMap(config.defaultCustomFields); story.displayTiddler(null,title,template,false,null,null); var tiddlerElem = story.getTiddler(title); if(customFields) story.addCustomFields(tiddlerElem,customFields); var text = this.getAttribute("newText"); if(typeof text == "string" && story.getTiddlerField(title,"text")) story.getTiddlerField(title,"text").value = text.format([title]); var t; for(t=0;t 0) { story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch); txt.setAttribute("lastSearchText",txt.value); } }; config.macros.search.onClick = function(e) { config.macros.search.doSearch(this.nextSibling); return false; }; config.macros.search.onKeyPress = function(ev) { var me = config.macros.search; var e = ev || window.event; switch(e.keyCode) { case 9: // Tab return; case 13: // Ctrl-Enter case 10: // Ctrl-Enter on IE PC me.doSearch(this); break; case 27: // Escape this.value = ""; clearMessage(); break; } if(config.options.chkIncrementalSearch) { if(this.value.length > 2) { if(this.value != this.getAttribute("lastSearchText")) { if(me.timeout) { clearTimeout(me.timeout); } var txt = this; me.timeout = setTimeout(function() {me.doSearch(txt);},500); } } else { if(me.timeout) { clearTimeout(me.timeout); } } } }; config.macros.search.onFocus = function(e) { this.select(); }; //-- //-- Tabs macro //-- config.macros.tabs.handler = function(place,macroName,params) { var cookie = params[0]; var numTabs = (params.length-1)/3; var wrapper = createTiddlyElement(null,"div",null,"tabsetWrapper " + cookie); var tabset = createTiddlyElement(wrapper,"div",null,"tabset"); tabset.setAttribute("cookie",cookie); var validTab = false; var t; for(t=0; t": btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore); jQuery(btn).addClass("moreCommand"); var e = createTiddlyElement(place,"span",null,"moreCommand"); e.style.display = "none"; place = e; break; default: var className = ""; switch(c.substr(0,1)) { case "+": className = "defaultCommand"; c = c.substr(1); break; case "-": className = "cancelCommand"; c = c.substr(1); break; } if(config.commands[c]) { this.createCommand(place,c,tiddler,className); } else { this.customCommand(place,c,wikifier,tiddler); } break; } } }; // Overrideable function to extend toolbar handler config.macros.toolbar.customCommand = function(place,command,wikifier,tiddler) { }; //-- //-- Menu and toolbar commands //-- config.commands.closeTiddler.handler = function(event,src,title) { if(story.isDirty(title) && !readOnly) { if(!confirm(config.commands.cancelTiddler.warning.format([title]))) return false; } story.setDirty(title,false); story.closeTiddler(title,true); return false; }; config.commands.closeOthers.handler = function(event,src,title) { story.closeAllTiddlers(title); return false; }; config.commands.editTiddler.handler = function(event,src,title) { clearMessage(); var tiddlerElem = story.getTiddler(title); var fields = tiddlerElem.getAttribute("tiddlyFields"); story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,fields); var e = story.getTiddlerField(title,config.options.txtEditorFocus||"text"); if(e) { setCaretPosition(e,0); } return false; }; config.commands.saveTiddler.handler = function(event,src,title) { var newTitle = story.saveTiddler(title,event.shiftKey); if(newTitle) story.displayTiddler(null,newTitle); return false; }; config.commands.cancelTiddler.handler = function(event,src,title) { if(story.hasChanges(title) && !readOnly) { if(!confirm(this.warning.format([title]))) return false; } story.setDirty(title,false); story.displayTiddler(null,title); return false; }; config.commands.deleteTiddler.handler = function(event,src,title) { var deleteIt = true; if(config.options.chkConfirmDelete) deleteIt = confirm(this.warning.format([title])); if(deleteIt) { store.removeTiddler(title); story.closeTiddler(title,true); autoSaveChanges(); } return false; }; config.commands.permalink.handler = function(event,src,title) { var t = encodeURIComponent(String.encodeTiddlyLink(title)); if(window.location.hash != t) window.location.hash = t; return false; }; config.commands.references.handlePopup = function(popup,title) { var references = store.getReferringTiddlers(title); var c = false; var r; for(r=0; r 0) ListView.create(popup,items,this.listViewTemplate); else createTiddlyElement(popup,"div",null,null,this.emptyText); }; //-- //-- Tiddler() object //-- function Tiddler(title) { this.title = title; this.text = ""; this.creator = null; this.modifier = null; this.created = new Date(); this.modified = this.created; this.links = []; this.linksUpdated = false; this.tags = []; this.fields = {}; return this; } Tiddler.prototype.getLinks = function() { if(this.linksUpdated==false) this.changed(); return this.links; }; // Returns the fields that are inherited in string field:"value" field2:"value2" format Tiddler.prototype.getInheritedFields = function() { var f = {}; var i; for(i in this.fields) { if(i=="server.host" || i=="server.workspace" || i=="wikiformat"|| i=="server.type") { f[i] = this.fields[i]; } } return String.encodeHashMap(f); }; // Increment the changeCount of a tiddler Tiddler.prototype.incChangeCount = function() { var c = this.fields['changecount']; c = c ? parseInt(c,10) : 0; this.fields['changecount'] = String(c+1); }; // Clear the changeCount of a tiddler Tiddler.prototype.clearChangeCount = function() { if(this.fields['changecount']) { delete this.fields['changecount']; } }; Tiddler.prototype.doNotSave = function() { return this.fields['doNotSave']; }; // Returns true if the tiddler has been updated since the tiddler was created or downloaded Tiddler.prototype.isTouched = function() { var changecount = this.fields.changecount || 0; return changecount > 0; }; // Change the text and other attributes of a tiddler Tiddler.prototype.set = function(title,text,modifier,modified,tags,created,fields,creator) { this.assign(title,text,modifier,modified,tags,created,fields,creator); this.changed(); return this; }; // Change the text and other attributes of a tiddler without triggered a tiddler.changed() call Tiddler.prototype.assign = function(title,text,modifier,modified,tags,created,fields,creator) { if(title != undefined) this.title = title; if(text != undefined) this.text = text; if(modifier != undefined) this.modifier = modifier; if(modified != undefined) this.modified = modified; if(creator != undefined) this.creator = creator; if(created != undefined) this.created = created; if(fields != undefined) this.fields = fields; if(tags != undefined) this.tags = (typeof tags == "string") ? tags.readBracketedList() : tags; else if(this.tags == undefined) this.tags = []; return this; }; // Get the tags for a tiddler as a string (space delimited, using [[brackets]] for tags containing spaces) Tiddler.prototype.getTags = function() { return String.encodeTiddlyLinkList(this.tags); }; // Test if a tiddler carries a tag Tiddler.prototype.isTagged = function(tag) { return this.tags.indexOf(tag) != -1; }; // Static method to convert "\n" to newlines, "\s" to "\" Tiddler.unescapeLineBreaks = function(text) { return text ? text.unescapeLineBreaks() : ""; }; // Convert newlines to "\n", "\" to "\s" Tiddler.prototype.escapeLineBreaks = function() { return this.text.escapeLineBreaks(); }; // Updates the secondary information (like links[] array) after a change to a tiddler Tiddler.prototype.changed = function() { this.links = []; var text = this.text; // remove 'quoted' text before scanning tiddler source text = text.replace(/\/%((?:.|\n)*?)%\//g,""). replace(/\{{3}((?:.|\n)*?)\}{3}/g,""). replace(/"""((?:.|\n)*?)"""/g,""). replace(/((?:.|\n)*?)/g,""). replace(/\>((?:.|\n)*?)/g,""). replace(/
  • \n" : tiddler.text.escapeLineBreaks().htmlEncode() ]); } catch (ex) { throw exceptionText(ex,config.messages.tiddlerSaveError.format([tiddler.title])); } }; /*** |''Name''|TiddlyWebAdaptor| |''Description''|adaptor for interacting with TiddlyWeb| |''Author:''|FND| |''Contributors''|Chris Dent, Martin Budden| |''Version''|1.4.10| |''Status''|stable| |''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js| |''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/| |''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]| |''CoreVersion''|2.5| |''Keywords''|serverSide TiddlyWeb| !Notes This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]]. !To Do * createWorkspace * document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin) !Code ***/ //{{{ (function($) { var adaptor = config.adaptors.tiddlyweb = function() {}; adaptor.prototype = new AdaptorBase(); adaptor.serverType = "tiddlyweb"; adaptor.serverLabel = "TiddlyWeb"; adaptor.mimeType = "application/json"; adaptor.parsingErrorMessage = "Error parsing result from server"; adaptor.noBagErrorMessage = "no bag specified for tiddler"; adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename // retrieve current status (requires TiddlyWeb status plugin) adaptor.prototype.getStatus = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); var uriTemplate = "%0/status"; var uri = uriTemplate.format([context.host]); var req = httpReq("GET", uri, adaptor.getStatusCallback, context, null, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) { context.status = responseText ? status : false; try { context.statusText = xhr.statusText; } catch(exc) { // offline (Firefox) context.status = false; context.statusText = null; } context.httpStatus = xhr.status; if(context.status) { context.serverStatus = $.evalJSON(responseText); // XXX: error handling!? } if(context.callback) { context.callback(context, context.userParams); } }; // retrieve a list of workspaces adaptor.prototype.getWorkspaceList = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); context.workspaces = []; var uriTemplate = "%0/recipes"; // XXX: bags? var uri = uriTemplate.format([context.host]); var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback, context, { accept: adaptor.mimeType }, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(status) { try { var workspaces = $.evalJSON(responseText); } catch(ex) { context.status = false; // XXX: correct? context.statusText = exceptionText(ex, adaptor.parsingErrorMessage); if(context.callback) { context.callback(context, context.userParams); } return; } context.workspaces = workspaces.map(function(itm) { return { title: itm }; }); } if(context.callback) { context.callback(context, context.userParams); } }; // retrieve a list of tiddlers adaptor.prototype.getTiddlerList = function(context, userParams, callback) { context = this.setContext(context, userParams, callback); var uriTemplate = "%0/%1/%2/tiddlers%3"; var params = context.filters ? "?" + context.filters : ""; if(context.format) { params = context.format + params; } var workspace = adaptor.resolveWorkspace(context.workspace); var uri = uriTemplate.format([context.host, workspace.type + "s", adaptor.normalizeTitle(workspace.name), params]); var req = httpReq("GET", uri, adaptor.getTiddlerListCallback, context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(status) { context.tiddlers = []; try { var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances } catch(ex) { context.status = false; // XXX: correct? context.statusText = exceptionText(ex, adaptor.parsingErrorMessage); if(context.callback) { context.callback(context, context.userParams); } return; } for(var i = 0; i /" revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/"); } revisions[i].title = to.title; } // add new revision var rev = $.extend({}, revisions[0]); $.each(newTiddler, function(i, item) { if(!$.isFunction(item)) { rev[i] = item; } }); rev.title = to.title; rev.created = rev.created.convertToYYYYMMDDHHMM(); rev.modified = new Date().convertToYYYYMMDDHHMM(); delete rev.fields.changecount; revisions.unshift(rev); if(to.workspace) { context.workspace = to.workspace; } else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag context.workspace = "bags/" + rev.bag; } var subCallback = function(context, userParams) { if(!context.status) { return callback(context, userParams); } context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler); }; return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback); }; var _deleteTiddler = function(context, userParams) { if(!context.status) { return callback(context, userParams); } $.extend(true, newTiddler, context.tiddler); context.callback = null; return self.deleteTiddler(oldTiddler, context, context.userParams, callback); }; callback = callback || function() {}; context = this.setContext(context, userParams); context.host = context.host || oldTiddler.fields["server.host"]; context.workspace = from.workspace || oldTiddler.fields["server.workspace"]; return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle); }; // delete an individual tiddler adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) { context = this.setContext(context, userParams, callback); context.title = tiddler.title; // XXX: not required!? var uriTemplate = "%0/bags/%1/tiddlers/%2"; var host = context.host || this.fullHostName(tiddler.fields["server.host"]); var bag = tiddler.fields["server.bag"]; if(!bag) { return adaptor.noBagErrorMessage; } var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag), adaptor.normalizeTitle(tiddler.title)]); var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler); var headers = etag ? { "If-Match": etag } : null; var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers, null, null, null, null, true); return typeof req == "string" ? req : true; }; adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) { context.status = [204, 1223].contains(xhr.status); context.statusText = xhr.statusText; context.httpStatus = xhr.status; if(context.callback) { context.callback(context, context.userParams); } }; // compare two revisions of a tiddler (requires TiddlyWeb differ plugin) adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) { context = this.setContext(context, userParams, callback); context.title = title; var tiddler = store.getTiddler(title); try { var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]); } catch(ex) { return adaptor.locationIDErrorMessage; } var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/"); var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef; var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null; var uriTemplate = "%0/diff?rev1=%1"; if(rev2) { uriTemplate += "&rev2=%2"; } if(context.format) { uriTemplate += "&format=%3"; } var host = context.host || this.fullHostName(tiddler.fields["server.host"]); var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1), adaptor.normalizeTitle(rev2), context.format]); if(rev2) { var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null, null, null, null, null, true); } else { var payload = { title: tiddler.title, text: tiddler.text, modifier: tiddler.modifier, tags: tiddler.tags, fields: $.extend({}, tiddler.fields) }; // XXX: missing attributes!? payload = $.toJSON(payload); req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context, null, payload, adaptor.mimeType, null, null, true); } return typeof req == "string" ? req : true; }; adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) { context.status = status; context.statusText = xhr.statusText; context.httpStatus = xhr.status; context.uri = uri; if(status) { context.diff = responseText; } if(context.callback) { context.callback(context, context.userParams); } }; // generate tiddler information adaptor.prototype.generateTiddlerInfo = function(tiddler) { var info = {}; var uriTemplate = "%0/%1/%2/tiddlers/%3"; var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete? host = this.fullHostName(host); var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]); info.uri = uriTemplate.format([host, workspace.type + "s", adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(tiddler.title)]); return info; }; // create Tiddler instance from TiddlyWeb tiddler JSON adaptor.toTiddler = function(json, host) { var created = Date.convertFromYYYYMMDDHHMM(json.created); var modified = Date.convertFromYYYYMMDDHHMM(json.modified); var fields = json.fields; fields["server.type"] = adaptor.serverType; fields["server.host"] = AdaptorBase.minHostName(host); fields["server.bag"] = json.bag; fields["server.title"] = json.title; if(json.recipe) { fields["server.recipe"] = json.recipe; } if(json.type && json.type != "None") { fields["server.content-type"] = json.type; } fields["server.permissions"] = json.permissions.join(", "); fields["server.page.revision"] = json.revision; fields["server.workspace"] = "bags/" + json.bag; var tiddler = new Tiddler(json.title); tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags, created, json.fields, json.creator); return tiddler; }; adaptor.resolveWorkspace = function(workspace) { var components = workspace.split("/"); return { type: components[0] == "bags" ? "bag" : "recipe", name: components[1] || components[0] }; }; adaptor.generateETag = function(workspace, tiddler) { var revision = tiddler.fields["server.page.revision"]; var etag = revision == "false" ? null : tiddler.fields["server.etag"]; if(!etag && workspace.type == "bag") { if(typeof revision == "undefined") { revision = "0"; } else if(revision == "false") { return null; } etag = [adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(tiddler.title), revision].join("/"); etag = '"' + etag + '"'; } return etag; }; adaptor.normalizeTitle = function(title) { return encodeURIComponent(title); }; })(jQuery); /* * jQuery JSON Plugin * version: 1.3 * source: http://code.google.com/p/jquery-json/ * license: MIT (http://www.opensource.org/licenses/mit-license.php) */ (function($){function toIntegersAtLease(n) {return n 0) { tiddler.fields.changecount -= context.changecount; } plugin.reportSuccess("saved", tiddler); store.setDirty(false); } else { if(context.httpStatus == 412) { plugin.reportFailure("saveConflict", tiddler); } else { plugin.reportFailure("saveError", tiddler, context); } } }; plugin.removeTiddler = function(tiddler) { try { var adaptor = this.getTiddlerServerAdaptor(tiddler); } catch(ex) { return false; } var context = { host: tiddler.fields["server.host"], workspace: tiddler.fields["server.workspace"], tiddler: tiddler }; var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback); return req ? tiddler : false; }; plugin.removeTiddlerCallback = function(context, userParams) { var tiddler = context.tiddler; if(context.status) { if(tiddler.fields.deleted === "true") { store.deleteTiddler(tiddler.title); } else { plugin.reportFailure("deleteLocalError", tiddler); } plugin.reportSuccess("deleted", tiddler); store.setDirty(false); } else { plugin.reportFailure("deleteError", tiddler, context); } }; plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename? var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"]; return new config.adaptors[type](); }; plugin.reportSuccess = function(msg, tiddler) { displayMessage(plugin.locale[msg].format([tiddler.title])); }; plugin.reportFailure = function(msg, tiddler, context) { var desc = (context && context.httpStatus) ? context.statusText : plugin.locale.connectionError; displayMessage(plugin.locale[msg].format([tiddler.title, desc])); }; config.macros.saveToWeb = { // XXX: hijack existing sync macro? locale: { // TODO: merge with plugin.locale? btnLabel: "save to web", btnTooltip: "synchronize changes", btnAccessKey: null }, handler: function(place, macroName, params, wikifier, paramString, tiddler) { createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip, plugin.sync, null, null, this.locale.btnAccessKey); } }; window.saveChanges = function(onlyIfDirty, tiddlers) { plugin.sync(tiddlers); }; // override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility? TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method? var tiddler = this.fetchTiddler(title); if(tiddler) { tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"]; tiddler.text = plugin.locale.removedNotice; tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved? tiddler.fields.changecount = "1"; this.notify(title, true); this.setDirty(true); } }; // hijack ImportTiddlers wizard to handle cross-domain restrictions var _onOpen = config.macros.importTiddlers.onOpen; config.macros.importTiddlers.onOpen = function(ev) { var btn = $(resolveTarget(ev)); var url = btn.closest(".wizard").find("input[name=txtPath]").val(); if(window.location.protocol != "file:" && url.indexOf("://") != -1) { var host = url.split("/")[2]; var macro = config.macros.importTiddlers; if(host != window.location.host) { btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt); btn[0].onclick = macro.onCancel; $('<span/>').text(plugin.locale.hostError).insertAfter(btn); return false; } } return _onOpen.apply(this, arguments); }; })(jQuery); //}}} //-- //-- Backstage //-- // Backstage tasks config.tasks.save.action = saveChanges; var backstage = { area: null, toolbar: null, button: null, showButton: null, hideButton: null, cloak: null, panel: null, panelBody: null, panelFooter: null, currTabName: null, currTabElem: null, content: null, init: function() { var cmb = config.messages.backstage; this.area = document.getElementById("backstageArea"); this.toolbar = jQuery("#backstageToolbar").empty()[0]; this.button = jQuery("#backstageButton").empty()[0]; this.button.style.display = "block"; var t = cmb.open.text + " " + glyph("bentArrowLeft"); this.showButton = createTiddlyButton(this.button,t,cmb.open.tooltip, function(e) {backstage.show(); return false;},null,"backstageShow"); t = glyph("bentArrowRight") + " " + cmb.close.text; this.hideButton = createTiddlyButton(this.button,t,cmb.close.tooltip, function(e) {backstage.hide(); return false;},null,"backstageHide"); this.cloak = document.getElementById("backstageCloak"); this.panel = document.getElementById("backstagePanel"); this.panelFooter = createTiddlyElement(this.panel,"div",null,"backstagePanelFooter"); this.panelBody = createTiddlyElement(this.panel,"div",null,"backstagePanelBody"); this.cloak.onmousedown = function(e) {backstage.switchTab(null);}; createTiddlyText(this.toolbar,cmb.prompt); for(t=0; t<config t="" var="" taskname="config.backstageTasks[t];" console="" task="config.tasks[taskName];" handler="task.action" this="" :="" text="task.text" glyph="" btn="createTiddlyButton(this.toolbar,text,task.tooltip,handler,"backstageTab");" jquery="" document="" if="" else="" isvisible:="" function="" return="" false="" show:="" config="" backstage="" findwindowwidth="" p="[{style:" start:="" end:="" template:="" anim="" morpher="" true="" saveoption="" hide:="" c="function(element,properties)" onclickcommand:="" onclicktab:="" switch="" to="" a="" given="" tab="" or="" none="" null="" is="" passed="" switchtab:="" tabelem="null;" e="this.toolbar.firstChild;" while="" tabname="" wikify="" ispanelvisible:="" preparepanel:="" finddocheight="" showpanel:="" scroller="" hidepanel:="" atend:="" backstagetask="config.tasks[params[0]];" createtiddlybutton="" main="" params="null;" command="" line="" parameters="" store="null;" tiddlywiki="" storage="" story="null;" formatter="null;" default="" formatters="" for="" the="" wikifier="" animator="=" new="" animation="" engine="" readonly="false;" whether="" we="" in="" mode="" highlighthack="null;" embarrassing="" hack="" department="" hadconfirmexit="false;" don="" warn="" more="" than="" once="" safemode="false;" disable="" all="" plugins="" and="" cookies="" showbackstage="" include="" area="" installedplugins="[];" information="" filled="" when="" are="" executed="" startingup="false;" process="" of="" starting="" up="" plugininfo="" used="" pass="" loadplugins="" space="" total_tiddlers="-1;" ajaxreq="" datatype:="" url:="" success:="" host="window.location.protocol" window="" workspace="recipes/" status="" defaults="config.defaultCustomFields;" filter="?select=tag:excludeLists&type:!text/css&select=type:!text/html&select=type:!image/png&select=type:!image/jpg&select=type:!image/gif&select=type:!image/jpeg" time="0," start="0," total="50;" lazy_load_content="function(title)" data:="" i="0;" tids="" tid="config.adaptors.tiddlyweb.toTiddler(tids[i],"> -1) { var pc = 100 - Math.floor(((total_tiddlers - store.getTiddlers().length) / total_tiddlers) * 100); displayMessage(pc + "% of document loaded."); } start += total; time += 100; lazy_load_content(title); } }, }); }, time); } var success = function(json) { store = new TiddlyWiki({config:config}); invokeParamifier(params,"oninit"); story = new Story("tiddlerDisplay","tiddler"); jQuery("#contentWrapper").removeClass("loading"); for(var i = 0; i 0) { plugin.log.push(config.messages.pluginVersionError); return false; } } return true; } function isPluginEnabled(plugin) { if(plugin.tiddler.isTagged("systemConfigDisable")) { plugin.log.push(config.messages.pluginDisabled); return false; } return true; } </config>

    Syndicated 2012-03-13 13:31:46 (Updated 2012-03-13 13:32:01) from cdent

    13 Mar 2012 (updated 13 Mar 2012 at 19:13 UTC) »

    20120313

    At some point /_tiddlywiki stopped working, so will need to figure that out before making much more progress on TiddlyWikiNeeds.

    Turns out this is the result of the recent changes to fat in TiddlyWeb.

    Similar changes also needed (and done) in the TiddlySpaceFollowingPlugin



    I extracted the csrf protection code that bengillies wrote into its own plugin: tiddlywebplugins.csrf. The rationale is that TiddlyWeb is perfectly capable of supporting other apps that might want to do form POSTs, not just TiddlySpace.



    Both of the above changes are now in a new tiddlyspace 1.0.91, deployed on tiddlyspace.com.

    Syndicated 2012-03-13 11:16:28 (Updated 2012-03-13 18:31:12) from cdent

    minlog

    minlog

    Syndicated 2012-03-13 11:15:53 (Updated 2012-03-13 11:17:49) from cdent

    monkeypatch

    monkeypatch

    Here is some content

    Syndicated 2012-03-13 10:48:19 from cdent

    InlineJavaScriptPlugin

    NameInlineJavascriptPlugin
    Sourcehttp://www.TiddlyTools.com/#InlineJavascriptPlugin
    Documentationhttp://www.TiddlyTools.com/#InlineJavascriptPluginInfo
    Version1.9.6
    AuthorEric Shulman
    Licensehttp://www.TiddlyTools.com/#LegalStatements
    CoreVersion2.1
    Typeplugin
    DescriptionInsert Javascript executable code directly into your tiddler content.
    Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
    Documentation
    see InlineJavascriptPluginInfo
    Revisions
    2010.12.15 1.9.6 allow (but ignore) type="..." syntax
    please see InlineJavascriptPluginInfo for additional revision details
    2005.11.08 1.0.0 initial release
    Code
    version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 6, date: new Date(2010,12,15)};
    
    config.formatters.push( {
    	name: "inlineJavascript",
    	match: "\\<script",
    	lookahead: "\\<script(?: type=\\\"[^\\\"]*\\\")?(?: src=\\\"([^\\\"]*)\\\")?(?: label=\\\"([^\\\"]*)\\\")?(?: title=\\\"([^\\\"]*)\\\")?(?: key=\\\"([^\\\"]*)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
    	handler: function(w) {
    		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
    		lookaheadRegExp.lastIndex = w.matchStart;
    		var lookaheadMatch = lookaheadRegExp.exec(w.source)
    		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
    			var src=lookaheadMatch[1];
    			var label=lookaheadMatch[2];
    			var tip=lookaheadMatch[3];
    			var key=lookaheadMatch[4];
    			var show=lookaheadMatch[5];
    			var code=lookaheadMatch[6];
    			if (src) { // external script library
    				var script = document.createElement("script"); script.src = src;
    				document.body.appendChild(script); document.body.removeChild(script);
    			}
    			if (code) { // inline code
    				if (show) // display source in tiddler
    					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
    				if (label) { // create 'onclick' command link
    					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
    					var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
    					link.code="function _out(place,tiddler){"+fixup+"\n};_out(this,this.tiddler);"
    					link.tiddler=w.tiddler;
    					link.onclick=function(){
    						this.bufferedHTML="";
    						try{ var r=eval(this.code);
    							if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
    								var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
    							if(this.bufferedHTML.length)
    								s.innerHTML=this.bufferedHTML;
    							if((typeof(r)==="string")&&r.length) {
    								wikify(r,s,null,this.tiddler);
    								return false;
    							} else return r!==undefined?r:false;
    						} catch(e){alert(e.description||e.toString());return false;}
    					};
    					link.setAttribute("title",tip||"");
    					var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
    					URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
    					URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
    					link.setAttribute("href",URIcode);
    					link.style.cursor="pointer";
    					if (key) link.accessKey=key.substr(0,1); // single character only
    				}
    				else { // run script immediately
    					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
    					var c="function _out(place,tiddler){"+fixup+"\n};_out(w.output,w.tiddler);";
    					try	 { var out=eval(c); }
    					catch(e) { out=e.description?e.description:e.toString(); }
    					if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
    				}
    			}
    			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
    		}
    	}
    } )
    

    Backward-compatibility for TW2.1.x and earlier
    if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
    	if(limit > 0) text = text.substr(0,limit);
    	var wikifier = new Wikifier(text,formatter,null,tiddler);
    	return wikifier.wikifyPlain();
    }
    

    GLOBAL FUNCTION: $(...) 'shorthand' convenience syntax for document.getElementById()
    if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
    

    Syndicated 2012-03-13 10:43:58 from cdent

    TestForm2

    Tiddler Title:

    <script label="Create Tiddler" title="Create Tiddler from Inside Javascript" key="X">


    Create Tiddler based on User Input to HTML Form

    var myTitle;
    myTitle = document.getElementById("theTitle").value;
    myTitle = myTitle.trim();

    if (myTitle == || myTitle == 'none')
    {
    alert('Title is Empty\nMust Enter Title to Continue');
    }
    else
    {
    alert('Tiddler will be Titled "'+myTitle+'"');

    myText = "!"+myTitle+"\nHere is some content";

    var tid = new Tiddler(myTitle);
    tid.title = myTitle;
    tid.text = myText;
    tid.tags = new Array("tag1 tag2 tag3");
    tid.creator = config.extensions.tiddlyweb.username;
    tid.fields = merge({}, config.defaultCustomFields)
    tid = store.saveTiddler(tid);
    autoSaveChanges(null, [tid]);

    }


    Trim Function - Removes Leading & Trailing Spaces

    String.prototype.trim = function() {
    return this.replace(/(^\s*)|(\s*$)/g,"")
    }


    </script>

    Syndicated 2012-03-13 10:42:35 (Updated 2012-03-13 10:47:36) from cdent

    70 older entries...

    New Advogato Features

    New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

    Keep up with the latest Advogato features by reading the Advogato status blog.

    If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!